Remove assert
[m6w6/libmemcached] / tests / libmemcached-1.0 / mem_functions.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Libmemcached library
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2006-2009 Brian Aker All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38 #include <config.h>
39 #include <libtest/test.hpp>
40
41 #if defined(HAVE_LIBUUID) && HAVE_LIBUUID
42 #include <uuid/uuid.h>
43 #endif
44
45 /*
46 Test cases
47 */
48
49 #include <libmemcached-1.0/memcached.h>
50 #include <libmemcached/is.h>
51 #include <libmemcached/server_instance.h>
52
53 #include <libhashkit-1.0/hashkit.h>
54
55 #include <cerrno>
56 #include <memory>
57 #include <pthread.h>
58 #include <semaphore.h>
59 #include <signal.h>
60 #include <sys/stat.h>
61 #include <sys/time.h>
62 #include <sys/types.h>
63 #include <unistd.h>
64
65 #include <iostream>
66
67 #include <libtest/server.h>
68
69 #include "clients/generator.h"
70
71 #define SMALL_STRING_LEN 1024
72
73 #include <libtest/test.hpp>
74
75 using namespace libtest;
76
77 #include <libmemcached/util.h>
78
79 #include "tests/hash_results.h"
80
81 #include "tests/libmemcached-1.0/callback_counter.h"
82 #include "tests/libmemcached-1.0/fetch_all_results.h"
83 #include "tests/libmemcached-1.0/mem_functions.h"
84 #include "tests/libmemcached-1.0/setup_and_teardowns.h"
85 #include "tests/print.h"
86 #include "tests/debug.h"
87
88 #define UUID_STRING_MAXLENGTH 36
89
90 struct keys_st {
91 public:
92 keys_st(size_t arg)
93 {
94 init(arg, UUID_STRING_MAXLENGTH);
95 }
96
97 keys_st(size_t arg, size_t padding)
98 {
99 init(arg, padding);
100 }
101
102 void init(size_t arg, size_t padding)
103 {
104 _lengths.resize(arg);
105 _keys.resize(arg);
106
107 for (size_t x= 0; x < _keys.size(); x++)
108 {
109 libtest::vchar_t key_buffer;
110 key_buffer.resize(padding +1);
111 memset(&key_buffer[0], 'x', padding);
112
113 if (HAVE_LIBUUID)
114 {
115 #if defined(HAVE_LIBUUID) && HAVE_LIBUUID
116 uuid_t out;
117 uuid_generate(out);
118
119 uuid_unparse(out, &key_buffer[0]);
120 _keys[x]= strdup(&key_buffer[0]);
121 (_keys[x])[UUID_STRING_MAXLENGTH]= 'x';
122 #endif
123 }
124 else // We just use a number and pad the string if UUID is not available
125 {
126 char int_buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
127 int key_length= snprintf(int_buffer, sizeof(int_buffer), "%u", uint32_t(x));
128 memcpy(&key_buffer[0], int_buffer, key_length);
129 _keys[x]= strdup(&key_buffer[0]);
130 }
131 _lengths[x]= padding;
132 }
133 }
134
135 ~keys_st()
136 {
137 for (libtest::vchar_ptr_t::iterator iter= _keys.begin();
138 iter != _keys.end();
139 iter++)
140 {
141 ::free(*iter);
142 }
143 }
144
145 libtest::vchar_ptr_t::iterator begin()
146 {
147 return _keys.begin();
148 }
149
150 libtest::vchar_ptr_t::iterator end()
151 {
152 return _keys.end();
153 }
154
155 size_t size() const
156 {
157 return _keys.size();
158 }
159
160 std::vector<size_t>& lengths()
161 {
162 return _lengths;
163 }
164
165 libtest::vchar_ptr_t& keys()
166 {
167 return _keys;
168 }
169
170 size_t* lengths_ptr()
171 {
172 return &_lengths[0];
173 }
174
175 char** keys_ptr()
176 {
177 return &_keys[0];
178 }
179
180 char* key_at(size_t arg)
181 {
182 return _keys[arg];
183 }
184
185 size_t length_at(size_t arg)
186 {
187 return _lengths[arg];
188 }
189
190 private:
191 libtest::vchar_ptr_t _keys;
192 std::vector<size_t> _lengths;
193 };
194
195 static memcached_return_t return_value_based_on_buffering(memcached_st *memc)
196 {
197 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS))
198 {
199 return MEMCACHED_BUFFERED;
200 }
201
202 return MEMCACHED_SUCCESS;
203 }
204
205 static memcached_st * create_single_instance_memcached(const memcached_st *original_memc, const char *options)
206 {
207 /*
208 If no options are given, copy over at least the binary flag.
209 */
210 char options_buffer[1024]= { 0 };
211 if (options == NULL)
212 {
213 if (memcached_is_binary(original_memc))
214 {
215 snprintf(options_buffer, sizeof(options_buffer), "--BINARY");
216 }
217 }
218
219 /*
220 * I only want to hit _one_ server so I know the number of requests I'm
221 * sending in the pipeline.
222 */
223 memcached_server_instance_st instance= memcached_server_instance_by_position(original_memc, 0);
224
225 char server_string[1024];
226 int server_string_length;
227 if (instance->type == MEMCACHED_CONNECTION_UNIX_SOCKET)
228 {
229 if (options)
230 {
231 server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\" %s",
232 memcached_server_name(instance), options);
233 }
234 else
235 {
236 server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\"",
237 memcached_server_name(instance));
238 }
239 }
240 else
241 {
242 if (options)
243 {
244 server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d %s",
245 memcached_server_name(instance), int(memcached_server_port(instance)),
246 options);
247 }
248 else
249 {
250 server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d",
251 memcached_server_name(instance), int(memcached_server_port(instance)));
252 }
253 }
254
255 if (server_string_length <= 0)
256 {
257 return NULL;
258 }
259
260 char errror_buffer[1024];
261 if (memcached_failed(libmemcached_check_configuration(server_string, server_string_length, errror_buffer, sizeof(errror_buffer))))
262 {
263 Error << "Failed to parse (" << server_string << ") " << errror_buffer;
264 return NULL;
265 }
266
267 return memcached(server_string, server_string_length);
268 }
269
270
271 test_return_t init_test(memcached_st *not_used)
272 {
273 memcached_st memc;
274 (void)not_used;
275
276 (void)memcached_create(&memc);
277 memcached_free(&memc);
278
279 return TEST_SUCCESS;
280 }
281
282 #define TEST_PORT_COUNT 7
283 in_port_t test_ports[TEST_PORT_COUNT];
284
285 static memcached_return_t server_display_function(const memcached_st *ptr,
286 const memcached_server_st *server,
287 void *context)
288 {
289 /* Do Nothing */
290 size_t bigger= *((size_t *)(context));
291 (void)ptr;
292 fatal_assert(bigger <= memcached_server_port(server));
293 *((size_t *)(context))= memcached_server_port(server);
294
295 return MEMCACHED_SUCCESS;
296 }
297
298 static memcached_return_t dump_server_information(const memcached_st *ptr,
299 const memcached_server_st *instance,
300 void *context)
301 {
302 /* Do Nothing */
303 FILE *stream= (FILE *)context;
304 (void)ptr;
305
306 fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n",
307 memcached_server_name(instance),
308 memcached_server_port(instance),
309 instance->major_version,
310 instance->minor_version,
311 instance->micro_version);
312
313 return MEMCACHED_SUCCESS;
314 }
315
316 test_return_t server_sort_test(memcached_st *ptr)
317 {
318 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
319
320 memcached_return_t rc;
321 memcached_server_fn callbacks[1];
322 memcached_st *local_memc;
323 (void)ptr;
324
325 local_memc= memcached_create(NULL);
326 test_true(local_memc);
327 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
328
329 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
330 {
331 test_ports[x]= (in_port_t)random() % 64000;
332 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
333 test_compare(memcached_server_count(local_memc), x +1);
334 #if 0 // Rewrite
335 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
336 #endif
337 test_compare(MEMCACHED_SUCCESS, rc);
338 }
339
340 callbacks[0]= server_display_function;
341 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
342
343
344 memcached_free(local_memc);
345
346 return TEST_SUCCESS;
347 }
348
349 test_return_t server_sort2_test(memcached_st *ptr)
350 {
351 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
352 memcached_server_fn callbacks[1];
353 memcached_st *local_memc;
354 memcached_server_instance_st instance;
355 (void)ptr;
356
357 local_memc= memcached_create(NULL);
358 test_true(local_memc);
359 test_compare(MEMCACHED_SUCCESS,
360 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1));
361
362 test_compare(MEMCACHED_SUCCESS,
363 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0));
364 instance= memcached_server_instance_by_position(local_memc, 0);
365 test_compare(in_port_t(43043), memcached_server_port(instance));
366
367 test_compare(MEMCACHED_SUCCESS,
368 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0));
369
370 instance= memcached_server_instance_by_position(local_memc, 0);
371 test_compare(in_port_t(43042), memcached_server_port(instance));
372
373 instance= memcached_server_instance_by_position(local_memc, 1);
374 test_compare(in_port_t(43043), memcached_server_port(instance));
375
376 callbacks[0]= server_display_function;
377 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
378
379
380 memcached_free(local_memc);
381
382 return TEST_SUCCESS;
383 }
384
385 test_return_t memcached_server_remove_test(memcached_st*)
386 {
387 const char *server_string= "--server=localhost:4444 --server=localhost:4445 --server=localhost:4446 --server=localhost:4447 --server=localhost --server=memcache1.memcache.bk.sapo.pt:11211 --server=memcache1.memcache.bk.sapo.pt:11212 --server=memcache1.memcache.bk.sapo.pt:11213 --server=memcache1.memcache.bk.sapo.pt:11214 --server=memcache2.memcache.bk.sapo.pt:11211 --server=memcache2.memcache.bk.sapo.pt:11212 --server=memcache2.memcache.bk.sapo.pt:11213 --server=memcache2.memcache.bk.sapo.pt:11214";
388 char buffer[BUFSIZ];
389
390 test_compare(MEMCACHED_SUCCESS,
391 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
392 memcached_st *memc= memcached(server_string, strlen(server_string));
393 test_true(memc);
394
395 memcached_server_fn callbacks[1];
396 callbacks[0]= server_print_callback;
397 memcached_server_cursor(memc, callbacks, NULL, 1);
398
399 memcached_free(memc);
400
401 return TEST_SUCCESS;
402 }
403
404 static memcached_return_t server_display_unsort_function(const memcached_st*,
405 const memcached_server_st *server,
406 void *context)
407 {
408 /* Do Nothing */
409 uint32_t x= *((uint32_t *)(context));
410
411 if (! (test_ports[x] == server->port))
412 {
413 fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)server->port);
414 return MEMCACHED_FAILURE;
415 }
416
417 *((uint32_t *)(context))= ++x;
418
419 return MEMCACHED_SUCCESS;
420 }
421
422 test_return_t server_unsort_test(memcached_st *ptr)
423 {
424 size_t counter= 0; /* Prime the value for the test_true in server_display_function */
425 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
426 memcached_server_fn callbacks[1];
427 memcached_st *local_memc;
428 (void)ptr;
429
430 local_memc= memcached_create(NULL);
431 test_true(local_memc);
432
433 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
434 {
435 test_ports[x]= (in_port_t)(random() % 64000);
436 test_compare(MEMCACHED_SUCCESS,
437 memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0));
438 test_compare(memcached_server_count(local_memc), x +1);
439 #if 0 // Rewrite
440 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
441 #endif
442 }
443
444 callbacks[0]= server_display_unsort_function;
445 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
446
447 /* Now we sort old data! */
448 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
449 callbacks[0]= server_display_function;
450 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
451
452
453 memcached_free(local_memc);
454
455 return TEST_SUCCESS;
456 }
457
458 test_return_t allocation_test(memcached_st *not_used)
459 {
460 (void)not_used;
461 memcached_st *memc;
462 memc= memcached_create(NULL);
463 test_true(memc);
464 memcached_free(memc);
465
466 return TEST_SUCCESS;
467 }
468
469 test_return_t clone_test(memcached_st *memc)
470 {
471 /* All null? */
472 {
473 memcached_st *memc_clone;
474 memc_clone= memcached_clone(NULL, NULL);
475 test_true(memc_clone);
476 memcached_free(memc_clone);
477 }
478
479 /* Can we init from null? */
480 {
481 memcached_st *memc_clone;
482 memc_clone= memcached_clone(NULL, memc);
483 test_true(memc_clone);
484
485 { // Test allocators
486 test_true(memc_clone->allocators.free == memc->allocators.free);
487 test_true(memc_clone->allocators.malloc == memc->allocators.malloc);
488 test_true(memc_clone->allocators.realloc == memc->allocators.realloc);
489 test_true(memc_clone->allocators.calloc == memc->allocators.calloc);
490 }
491
492 test_true(memc_clone->connect_timeout == memc->connect_timeout);
493 test_true(memc_clone->delete_trigger == memc->delete_trigger);
494 test_true(memc_clone->distribution == memc->distribution);
495 { // Test all of the flags
496 test_true(memc_clone->flags.no_block == memc->flags.no_block);
497 test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
498 test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
499 test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
500 test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
501 test_true(memc_clone->flags.verify_key == memc->flags.verify_key);
502 test_true(memc_clone->ketama.weighted == memc->ketama.weighted);
503 test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
504 test_true(memc_clone->flags.hash_with_namespace == memc->flags.hash_with_namespace);
505 test_true(memc_clone->flags.reply == memc->flags.reply);
506 test_true(memc_clone->flags.use_udp == memc->flags.use_udp);
507 test_true(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
508 test_true(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
509 }
510 test_true(memc_clone->get_key_failure == memc->get_key_failure);
511 test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit));
512 test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
513 test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
514 test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
515 test_true(memc_clone->on_cleanup == memc->on_cleanup);
516 test_true(memc_clone->on_clone == memc->on_clone);
517 test_true(memc_clone->poll_timeout == memc->poll_timeout);
518 test_true(memc_clone->rcv_timeout == memc->rcv_timeout);
519 test_true(memc_clone->recv_size == memc->recv_size);
520 test_true(memc_clone->retry_timeout == memc->retry_timeout);
521 test_true(memc_clone->send_size == memc->send_size);
522 test_true(memc_clone->server_failure_limit == memc->server_failure_limit);
523 test_true(memc_clone->snd_timeout == memc->snd_timeout);
524 test_true(memc_clone->user_data == memc->user_data);
525
526 memcached_free(memc_clone);
527 }
528
529 /* Can we init from struct? */
530 {
531 memcached_st declared_clone;
532 memcached_st *memc_clone;
533 memset(&declared_clone, 0 , sizeof(memcached_st));
534 memc_clone= memcached_clone(&declared_clone, NULL);
535 test_true(memc_clone);
536 memcached_free(memc_clone);
537 }
538
539 /* Can we init from struct? */
540 {
541 memcached_st declared_clone;
542 memcached_st *memc_clone;
543 memset(&declared_clone, 0 , sizeof(memcached_st));
544 memc_clone= memcached_clone(&declared_clone, memc);
545 test_true(memc_clone);
546 memcached_free(memc_clone);
547 }
548
549 return TEST_SUCCESS;
550 }
551
552 test_return_t userdata_test(memcached_st *memc)
553 {
554 void* foo= NULL;
555 test_false(memcached_set_user_data(memc, foo));
556 test_true(memcached_get_user_data(memc) == foo);
557 test_true(memcached_set_user_data(memc, NULL) == foo);
558
559 return TEST_SUCCESS;
560 }
561
562 test_return_t connection_test(memcached_st *memc)
563 {
564 test_compare(MEMCACHED_SUCCESS,
565 memcached_server_add_with_weight(memc, "localhost", 0, 0));
566
567 return TEST_SUCCESS;
568 }
569
570 test_return_t libmemcached_string_behavior_test(memcached_st *)
571 {
572 for (int x= MEMCACHED_BEHAVIOR_NO_BLOCK; x < int(MEMCACHED_BEHAVIOR_MAX); ++x)
573 {
574 test_true(libmemcached_string_behavior(memcached_behavior_t(x)));
575 }
576 test_compare(37, int(MEMCACHED_BEHAVIOR_MAX));
577
578 return TEST_SUCCESS;
579 }
580
581 test_return_t libmemcached_string_distribution_test(memcached_st *)
582 {
583 for (int x= MEMCACHED_DISTRIBUTION_MODULA; x < int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX); ++x)
584 {
585 test_true(libmemcached_string_distribution(memcached_server_distribution_t(x)));
586 }
587 test_compare(7, int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX));
588
589 return TEST_SUCCESS;
590 }
591
592 test_return_t memcached_return_t_TEST(memcached_st *memc)
593 {
594 uint32_t values[] = { 851992627U, 2337886783U, 4109241422U, 4001849190U,
595 982370485U, 1263635348U, 4242906218U, 3829656100U,
596 1891735253U, 334139633U, 2257084983U, 3351789013U,
597 13199785U, 2542027183U, 1097051614U, 199566778U,
598 2748246961U, 2465192557U, 1664094137U, 2405439045U,
599 1842224848U, 692413798U, 3479807801U, 919913813U,
600 4269430871U, 610793021U, 527273862U, 1437122909U,
601 2300930706U, 2943759320U, 674306647U, 2400528935U,
602 54481931U, 4186304426U, 1741088401U, 2979625118U,
603 4159057246U, 3425930182U, 2593724503U, 1868899624U,
604 1769812374U, 2302537950U, 1110330676U, 3365377466U,
605 1336171666U, 3021258493U, 2334992265U, 3861994737U,
606 3582734124U, 3365377466U };
607
608 // You have updated the memcache_error messages but not updated docs/tests.
609 for (int rc= int(MEMCACHED_SUCCESS); rc < int(MEMCACHED_MAXIMUM_RETURN); ++rc)
610 {
611 uint32_t hash_val;
612 const char *msg= memcached_strerror(memc, memcached_return_t(rc));
613 hash_val= memcached_generate_hash_value(msg, strlen(msg),
614 MEMCACHED_HASH_JENKINS);
615 if (values[rc] != hash_val)
616 {
617 fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the memcached_return_t_TEST\n");
618 fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, memcached_return_t(rc)), hash_val);
619 }
620 test_compare(values[rc], hash_val);
621 }
622 test_compare(49, int(MEMCACHED_MAXIMUM_RETURN));
623
624 return TEST_SUCCESS;
625 }
626
627 test_return_t set_test(memcached_st *memc)
628 {
629 memcached_return_t rc= memcached_set(memc,
630 test_literal_param("foo"),
631 test_literal_param("when we sanitize"),
632 time_t(0), (uint32_t)0);
633 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
634
635 return TEST_SUCCESS;
636 }
637
638 test_return_t append_test(memcached_st *memc)
639 {
640 memcached_return_t rc;
641 const char *in_value= "we";
642 size_t value_length;
643 uint32_t flags;
644
645 test_compare(MEMCACHED_SUCCESS,
646 memcached_flush(memc, 0));
647
648 test_compare(MEMCACHED_SUCCESS,
649 memcached_set(memc,
650 test_literal_param(__func__),
651 in_value, strlen(in_value),
652 time_t(0), uint32_t(0)));
653
654 test_compare(MEMCACHED_SUCCESS,
655 memcached_append(memc,
656 test_literal_param(__func__),
657 " the", strlen(" the"),
658 time_t(0), uint32_t(0)));
659
660 test_compare(MEMCACHED_SUCCESS,
661 memcached_append(memc,
662 test_literal_param(__func__),
663 " people", strlen(" people"),
664 time_t(0), uint32_t(0)));
665
666 char *out_value= memcached_get(memc,
667 test_literal_param(__func__),
668 &value_length, &flags, &rc);
669 test_memcmp(out_value, "we the people", strlen("we the people"));
670 test_compare(strlen("we the people"), value_length);
671 test_compare(MEMCACHED_SUCCESS, rc);
672 free(out_value);
673
674 return TEST_SUCCESS;
675 }
676
677 test_return_t append_binary_test(memcached_st *memc)
678 {
679 uint32_t store_list[] = { 23, 56, 499, 98, 32847, 0 };
680
681 test_compare(MEMCACHED_SUCCESS,
682 memcached_flush(memc, 0));
683
684 test_compare(MEMCACHED_SUCCESS,
685 memcached_set(memc,
686 test_literal_param(__func__),
687 NULL, 0,
688 time_t(0), uint32_t(0)));
689
690 size_t count= 0;
691 for (uint32_t x= 0; store_list[x] ; x++)
692 {
693 test_compare(MEMCACHED_SUCCESS,
694 memcached_append(memc,
695 test_literal_param(__func__),
696 (char *)&store_list[x], sizeof(uint32_t),
697 time_t(0), uint32_t(0)));
698 count++;
699 }
700
701 size_t value_length;
702 uint32_t flags;
703 memcached_return_t rc;
704 uint32_t *value= (uint32_t *)memcached_get(memc,
705 test_literal_param(__func__),
706 &value_length, &flags, &rc);
707 test_compare(value_length, sizeof(uint32_t) * count);
708 test_compare(MEMCACHED_SUCCESS, rc);
709
710 for (uint32_t counter= count, *ptr= value; counter; counter--)
711 {
712 test_compare(*ptr, store_list[count - counter]);
713 ptr++;
714 }
715 free(value);
716
717 return TEST_SUCCESS;
718 }
719
720 test_return_t memcached_mget_mixed_memcached_get_TEST(memcached_st *memc)
721 {
722 keys_st keys(200);
723
724 for (libtest::vchar_ptr_t::iterator iter= keys.begin();
725 iter != keys.end();
726 iter++)
727 {
728 test_compare(MEMCACHED_SUCCESS,
729 memcached_set(memc,
730 (*iter), 36,
731 NULL, 0,
732 time_t(0), uint32_t(0)));
733 }
734
735 for (ptrdiff_t loop= 0; loop < 20; loop++)
736 {
737 if (random() %2)
738 {
739 test_compare(MEMCACHED_SUCCESS,
740 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
741
742 memcached_result_st *results= memcached_result_create(memc, NULL);
743 test_true(results);
744
745 size_t result_count= 0;
746 memcached_return_t rc;
747 while (memcached_fetch_result(memc, results, &rc))
748 {
749 result_count++;
750 }
751 test_compare(keys.size(), result_count);
752 }
753 else
754 {
755 int which_key= random() %keys.size();
756 size_t value_length;
757 uint32_t flags;
758 memcached_return_t rc;
759 char *out_value= memcached_get(memc, keys.key_at(which_key), keys.length_at(which_key),
760 &value_length, &flags, &rc);
761 test_compare(MEMCACHED_SUCCESS, rc);
762 test_null(out_value);
763 test_zero(value_length);
764 test_zero(flags);
765 }
766 }
767
768 return TEST_SUCCESS;
769 }
770
771 test_return_t cas2_test(memcached_st *memc)
772 {
773 const char *keys[]= {"fudge", "son", "food"};
774 size_t key_length[]= {5, 3, 4};
775 const char *value= "we the people";
776 size_t value_length= strlen("we the people");
777
778 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
779
780 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
781
782 for (uint32_t x= 0; x < 3; x++)
783 {
784 test_compare(MEMCACHED_SUCCESS,
785 memcached_set(memc, keys[x], key_length[x],
786 keys[x], key_length[x],
787 time_t(50), uint32_t(9)));
788 }
789
790 test_compare(MEMCACHED_SUCCESS,
791 memcached_mget(memc, keys, key_length, 3));
792
793 memcached_result_st *results= memcached_result_create(memc, NULL);
794 test_true(results);
795
796 memcached_return_t rc;
797 results= memcached_fetch_result(memc, results, &rc);
798 test_true(results);
799 test_true(results->item_cas);
800 test_compare(MEMCACHED_SUCCESS, rc);
801 test_true(memcached_result_cas(results));
802
803 test_memcmp(value, "we the people", strlen("we the people"));
804 test_compare(strlen("we the people"), value_length);
805 test_compare(MEMCACHED_SUCCESS, rc);
806
807 memcached_result_free(results);
808
809 return TEST_SUCCESS;
810 }
811
812 test_return_t cas_test(memcached_st *memc)
813 {
814 const char* keys[2] = { __func__, NULL };
815 size_t keylengths[2] = { strlen(__func__), 0 };
816
817 memcached_result_st results_obj;
818
819 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
820
821 test_skip(true, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
822
823 test_compare(MEMCACHED_SUCCESS,
824 memcached_set(memc,
825 test_literal_param(__func__),
826 test_literal_param("we the people"),
827 (time_t)0, (uint32_t)0));
828
829 test_compare(MEMCACHED_SUCCESS,
830 memcached_mget(memc, keys, keylengths, 1));
831
832 memcached_result_st *results= memcached_result_create(memc, &results_obj);
833 test_true(results);
834
835 memcached_return_t rc;
836 results= memcached_fetch_result(memc, &results_obj, &rc);
837 test_true(results);
838 test_compare(MEMCACHED_SUCCESS, rc);
839 test_true(memcached_result_cas(results));
840 test_memcmp("we the people", memcached_result_value(results), test_literal_param_size("we the people"));
841 test_compare(test_literal_param_size("we the people"),
842 strlen(memcached_result_value(results)));
843
844 uint64_t cas= memcached_result_cas(results);
845
846 #if 0
847 results= memcached_fetch_result(memc, &results_obj, &rc);
848 test_true(rc == MEMCACHED_END);
849 test_true(results == NULL);
850 #endif
851
852 test_compare(MEMCACHED_SUCCESS,
853 memcached_cas(memc,
854 test_literal_param(__func__),
855 test_literal_param("change the value"),
856 0, 0, cas));
857
858 /*
859 * The item will have a new cas value, so try to set it again with the old
860 * value. This should fail!
861 */
862 test_compare(MEMCACHED_DATA_EXISTS,
863 memcached_cas(memc,
864 test_literal_param(__func__),
865 test_literal_param("change the value"),
866 0, 0, cas));
867
868 memcached_result_free(&results_obj);
869
870 return TEST_SUCCESS;
871 }
872
873
874 test_return_t prepend_test(memcached_st *memc)
875 {
876 const char *key= "fig";
877 const char *value= "people";
878
879 test_compare(MEMCACHED_SUCCESS,
880 memcached_flush(memc, 0));
881
882 test_compare(MEMCACHED_SUCCESS,
883 memcached_set(memc, key, strlen(key),
884 value, strlen(value),
885 time_t(0), uint32_t(0)));
886
887 test_compare(MEMCACHED_SUCCESS,
888 memcached_prepend(memc, key, strlen(key),
889 "the ", strlen("the "),
890 time_t(0), uint32_t(0)));
891
892 test_compare(MEMCACHED_SUCCESS,
893 memcached_prepend(memc, key, strlen(key),
894 "we ", strlen("we "),
895 time_t(0), uint32_t(0)));
896
897 size_t value_length;
898 uint32_t flags;
899 memcached_return_t rc;
900 char *out_value= memcached_get(memc, key, strlen(key),
901 &value_length, &flags, &rc);
902 test_memcmp(out_value, "we the people", strlen("we the people"));
903 test_compare(strlen("we the people"), value_length);
904 test_compare(MEMCACHED_SUCCESS, rc);
905 free(out_value);
906
907 return TEST_SUCCESS;
908 }
909
910 /*
911 Set the value, then quit to make sure it is flushed.
912 Come back in and test that add fails.
913 */
914 test_return_t add_test(memcached_st *memc)
915 {
916 test_compare_hint(return_value_based_on_buffering(memc),
917 memcached_set(memc,
918 test_literal_param(__func__),
919 test_literal_param("when we sanitize"),
920 time_t(0), uint32_t(0)),
921 memcached_last_error_message(memc));
922
923 memcached_quit(memc);
924
925 test_compare_hint(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_DATA_EXISTS : MEMCACHED_NOTSTORED,
926 memcached_add(memc,
927 test_literal_param(__func__),
928 test_literal_param("try something else"),
929 time_t(0), uint32_t(0)),
930 memcached_last_error_message(memc));
931
932 return TEST_SUCCESS;
933 }
934
935 /*
936 ** There was a problem of leaking filedescriptors in the initial release
937 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
938 ** systems it seems that the kernel is slow on reclaiming the resources
939 ** because the connects starts to time out (the test doesn't do much
940 ** anyway, so just loop 10 iterations)
941 */
942 test_return_t add_wrapper(memcached_st *memc)
943 {
944 unsigned int max= 10000;
945 #ifdef __sun
946 max= 10;
947 #endif
948 #ifdef __APPLE__
949 max= 10;
950 #endif
951
952 for (uint32_t x= 0; x < max; x++)
953 add_test(memc);
954
955 return TEST_SUCCESS;
956 }
957
958 test_return_t replace_test(memcached_st *memc)
959 {
960 test_compare(return_value_based_on_buffering(memc),
961 memcached_set(memc,
962 test_literal_param(__func__),
963 test_literal_param("when we sanitize"),
964 time_t(0), uint32_t(0)));
965
966 test_compare(MEMCACHED_SUCCESS,
967 memcached_replace(memc,
968 test_literal_param(__func__),
969 test_literal_param("first we insert some data"),
970 time_t(0), uint32_t(0)));
971
972 return TEST_SUCCESS;
973 }
974
975 test_return_t delete_test(memcached_st *memc)
976 {
977 test_compare(return_value_based_on_buffering(memc),
978 memcached_set(memc,
979 test_literal_param(__func__),
980 test_literal_param("when we sanitize"),
981 time_t(0), uint32_t(0)));
982
983 test_compare_hint(return_value_based_on_buffering(memc),
984 memcached_delete(memc,
985 test_literal_param(__func__),
986 time_t(0)),
987 memcached_last_error_message(memc));
988
989 return TEST_SUCCESS;
990 }
991
992 test_return_t flush_test(memcached_st *memc)
993 {
994 uint64_t query_id= memcached_query_id(memc);
995 test_compare(MEMCACHED_SUCCESS,
996 memcached_flush(memc, 0));
997 test_compare(query_id +1, memcached_query_id(memc));
998
999 return TEST_SUCCESS;
1000 }
1001
1002 static memcached_return_t server_function(const memcached_st *,
1003 const memcached_server_st *,
1004 void *)
1005 {
1006 /* Do Nothing */
1007 return MEMCACHED_SUCCESS;
1008 }
1009
1010 test_return_t memcached_server_cursor_test(memcached_st *memc)
1011 {
1012 char context[10];
1013 strncpy(context, "foo bad", sizeof(context));
1014 memcached_server_fn callbacks[1];
1015
1016 callbacks[0]= server_function;
1017 memcached_server_cursor(memc, callbacks, context, 1);
1018 return TEST_SUCCESS;
1019 }
1020
1021 test_return_t bad_key_test(memcached_st *memc)
1022 {
1023 memcached_return_t rc;
1024 const char *key= "foo bad";
1025 uint32_t flags;
1026
1027 uint64_t query_id= memcached_query_id(memc);
1028
1029 // Just skip if we are in binary mode.
1030 test_skip(false, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1031
1032 test_compare(query_id, memcached_query_id(memc)); // We should not increase the query_id for memcached_behavior_get()
1033
1034 memcached_st *memc_clone= memcached_clone(NULL, memc);
1035 test_true(memc_clone);
1036
1037 query_id= memcached_query_id(memc_clone);
1038 test_compare(MEMCACHED_SUCCESS,
1039 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
1040 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
1041
1042 /* All keys are valid in the binary protocol (except for length) */
1043 if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == false)
1044 {
1045 uint64_t before_query_id= memcached_query_id(memc_clone);
1046 {
1047 size_t string_length;
1048 char *string= memcached_get(memc_clone, key, strlen(key),
1049 &string_length, &flags, &rc);
1050 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1051 test_zero(string_length);
1052 test_false(string);
1053 }
1054 test_compare(before_query_id +1, memcached_query_id(memc_clone));
1055
1056 query_id= memcached_query_id(memc_clone);
1057 test_compare(MEMCACHED_SUCCESS,
1058 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, false));
1059 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
1060 {
1061 size_t string_length;
1062 char *string= memcached_get(memc_clone, key, strlen(key),
1063 &string_length, &flags, &rc);
1064 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1065 test_zero(string_length);
1066 test_false(string);
1067 }
1068
1069 /* Test multi key for bad keys */
1070 const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
1071 size_t key_lengths[] = { 7, 7, 7 };
1072 query_id= memcached_query_id(memc_clone);
1073 test_compare(MEMCACHED_SUCCESS,
1074 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
1075 test_compare(query_id, memcached_query_id(memc_clone));
1076
1077 query_id= memcached_query_id(memc_clone);
1078 test_compare(MEMCACHED_BAD_KEY_PROVIDED,
1079 memcached_mget(memc_clone, keys, key_lengths, 3));
1080 test_compare(query_id +1, memcached_query_id(memc_clone));
1081
1082 query_id= memcached_query_id(memc_clone);
1083 // Grouping keys are not required to follow normal key behaviors
1084 test_compare(MEMCACHED_SUCCESS,
1085 memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1));
1086 test_compare(query_id +1, memcached_query_id(memc_clone));
1087
1088 /* The following test should be moved to the end of this function when the
1089 memcached server is updated to allow max size length of the keys in the
1090 binary protocol
1091 */
1092 test_compare(MEMCACHED_SUCCESS,
1093 memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_NAMESPACE, NULL));
1094
1095 libtest::vchar_t longkey;
1096 {
1097 libtest::vchar_t::iterator it= longkey.begin();
1098 longkey.insert(it, MEMCACHED_MAX_KEY, 'a');
1099 }
1100
1101 test_compare(longkey.size(), size_t(MEMCACHED_MAX_KEY));
1102 {
1103 size_t string_length;
1104 // We subtract 1
1105 test_null(memcached_get(memc_clone, &longkey[0], longkey.size() -1, &string_length, &flags, &rc));
1106 test_compare(MEMCACHED_NOTFOUND, rc);
1107 test_zero(string_length);
1108
1109 test_null(memcached_get(memc_clone, &longkey[0], longkey.size(), &string_length, &flags, &rc));
1110 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1111 test_zero(string_length);
1112 }
1113 }
1114
1115 /* Make sure zero length keys are marked as bad */
1116 {
1117 test_compare(MEMCACHED_SUCCESS,
1118 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
1119 size_t string_length;
1120 char *string= memcached_get(memc_clone, key, 0,
1121 &string_length, &flags, &rc);
1122 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1123 test_zero(string_length);
1124 test_false(string);
1125 }
1126
1127 memcached_free(memc_clone);
1128
1129 return TEST_SUCCESS;
1130 }
1131
1132 #define READ_THROUGH_VALUE "set for me"
1133 static memcached_return_t read_through_trigger(memcached_st *memc,
1134 char *key,
1135 size_t key_length,
1136 memcached_result_st *result)
1137 {
1138 (void)memc;(void)key;(void)key_length;
1139 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
1140 }
1141
1142 #ifndef __INTEL_COMPILER
1143 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
1144 #endif
1145
1146 test_return_t read_through(memcached_st *memc)
1147 {
1148 memcached_trigger_key_fn cb= (memcached_trigger_key_fn)read_through_trigger;
1149
1150 size_t string_length;
1151 uint32_t flags;
1152 memcached_return_t rc;
1153 char *string= memcached_get(memc,
1154 test_literal_param(__func__),
1155 &string_length, &flags, &rc);
1156
1157 test_compare(MEMCACHED_NOTFOUND, rc);
1158 test_false(string_length);
1159 test_false(string);
1160
1161 test_compare(MEMCACHED_SUCCESS,
1162 memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, *(void **)&cb));
1163
1164 string= memcached_get(memc,
1165 test_literal_param(__func__),
1166 &string_length, &flags, &rc);
1167
1168 test_compare(MEMCACHED_SUCCESS, rc);
1169 test_compare(string_length, sizeof(READ_THROUGH_VALUE) -1);
1170 test_true(string[sizeof(READ_THROUGH_VALUE) -1] == 0);
1171 test_strcmp(READ_THROUGH_VALUE, string);
1172 free(string);
1173
1174 string= memcached_get(memc,
1175 test_literal_param(__func__),
1176 &string_length, &flags, &rc);
1177
1178 test_compare(MEMCACHED_SUCCESS, rc);
1179 test_true(string);
1180 test_compare(string_length, sizeof(READ_THROUGH_VALUE) -1);
1181 test_true(string[sizeof(READ_THROUGH_VALUE) -1] == 0);
1182 test_strcmp(READ_THROUGH_VALUE, string);
1183 free(string);
1184
1185 return TEST_SUCCESS;
1186 }
1187
1188 test_return_t get_test(memcached_st *memc)
1189 {
1190 uint64_t query_id= memcached_query_id(memc);
1191 memcached_return_t rc= memcached_delete(memc,
1192 test_literal_param(__func__),
1193 time_t(0));
1194 test_true_hint(rc == MEMCACHED_BUFFERED or rc == MEMCACHED_NOTFOUND, memcached_last_error_message(memc));
1195 test_compare(query_id +1, memcached_query_id(memc));
1196
1197 size_t string_length;
1198 uint32_t flags;
1199 char *string= memcached_get(memc,
1200 test_literal_param(__func__),
1201 &string_length, &flags, &rc);
1202
1203 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_last_error_message(memc));
1204 test_false(string_length);
1205 test_false(string);
1206
1207 return TEST_SUCCESS;
1208 }
1209
1210 test_return_t get_test2(memcached_st *memc)
1211 {
1212 const char *value= "when we sanitize";
1213
1214 uint64_t query_id= memcached_query_id(memc);
1215 test_compare(return_value_based_on_buffering(memc),
1216 memcached_set(memc,
1217 test_literal_param(__func__),
1218 value, strlen(value),
1219 time_t(0), uint32_t(0)));
1220 test_compare(query_id +1, memcached_query_id(memc));
1221
1222 query_id= memcached_query_id(memc);
1223 test_true(query_id);
1224
1225 uint32_t flags;
1226 size_t string_length;
1227 memcached_return_t rc;
1228 char *string= memcached_get(memc,
1229 test_literal_param(__func__),
1230 &string_length, &flags, &rc);
1231 test_compare(query_id +1, memcached_query_id(memc));
1232
1233 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
1234 test_compare_got(MEMCACHED_SUCCESS, memcached_last_error(memc), memcached_last_error_message(memc));
1235 test_true(string);
1236 test_compare(strlen(value), string_length);
1237 test_memcmp(string, value, string_length);
1238
1239 free(string);
1240
1241 return TEST_SUCCESS;
1242 }
1243
1244 test_return_t set_test2(memcached_st *memc)
1245 {
1246 for (uint32_t x= 0; x < 10; x++)
1247 {
1248 test_compare(return_value_based_on_buffering(memc),
1249 memcached_set(memc,
1250 test_literal_param("foo"),
1251 test_literal_param("train in the brain"),
1252 time_t(0), uint32_t(0)));
1253 }
1254
1255 return TEST_SUCCESS;
1256 }
1257
1258 test_return_t set_test3(memcached_st *memc)
1259 {
1260 size_t value_length= 8191;
1261
1262 libtest::vchar_t value;
1263 value.reserve(value_length);
1264 for (uint32_t x= 0; x < value_length; x++)
1265 {
1266 value.push_back(char(x % 127));
1267 }
1268
1269 /* The dump test relies on there being at least 32 items in memcached */
1270 for (uint32_t x= 0; x < 32; x++)
1271 {
1272 char key[16];
1273
1274 snprintf(key, sizeof(key), "foo%u", x);
1275
1276 uint64_t query_id= memcached_query_id(memc);
1277 test_compare_hint(return_value_based_on_buffering(memc),
1278 memcached_set(memc, key, strlen(key),
1279 &value[0], value.size(),
1280 time_t(0), uint32_t(0)),
1281 memcached_last_error_message(memc));
1282 test_compare(query_id +1, memcached_query_id(memc));
1283 }
1284
1285 return TEST_SUCCESS;
1286 }
1287
1288 test_return_t get_test3(memcached_st *memc)
1289 {
1290 size_t value_length= 8191;
1291
1292 libtest::vchar_t value;
1293 value.reserve(value_length);
1294 for (uint32_t x= 0; x < value_length; x++)
1295 {
1296 value.push_back(char(x % 127));
1297 }
1298
1299 test_compare_hint(return_value_based_on_buffering(memc),
1300 memcached_set(memc,
1301 test_literal_param(__func__),
1302 &value[0], value.size(),
1303 time_t(0), uint32_t(0)),
1304 memcached_last_error_message(memc));
1305
1306 size_t string_length;
1307 uint32_t flags;
1308 memcached_return_t rc;
1309 char *string= memcached_get(memc,
1310 test_literal_param(__func__),
1311 &string_length, &flags, &rc);
1312
1313 test_compare(MEMCACHED_SUCCESS, rc);
1314 test_true(string);
1315 test_compare(value.size(), string_length);
1316 test_memcmp(string, &value[0], string_length);
1317
1318 free(string);
1319
1320 return TEST_SUCCESS;
1321 }
1322
1323 test_return_t get_test4(memcached_st *memc)
1324 {
1325 size_t value_length= 8191;
1326
1327 libtest::vchar_t value;
1328 value.reserve(value_length);
1329 for (uint32_t x= 0; x < value_length; x++)
1330 {
1331 value.push_back(char(x % 127));
1332 }
1333
1334 test_compare_hint(return_value_based_on_buffering(memc),
1335 memcached_set(memc,
1336 test_literal_param(__func__),
1337 &value[0], value.size(),
1338 time_t(0), uint32_t(0)),
1339 memcached_last_error_message(memc));
1340
1341 for (uint32_t x= 0; x < 10; x++)
1342 {
1343 uint32_t flags;
1344 size_t string_length;
1345 memcached_return_t rc;
1346 char *string= memcached_get(memc,
1347 test_literal_param(__func__),
1348 &string_length, &flags, &rc);
1349
1350 test_compare(MEMCACHED_SUCCESS, rc);
1351 test_true(string);
1352 test_compare(value.size(), string_length);
1353 test_memcmp(string, &value[0], string_length);
1354 free(string);
1355 }
1356
1357 return TEST_SUCCESS;
1358 }
1359
1360 /*
1361 * This test verifies that memcached_read_one_response doesn't try to
1362 * dereference a NIL-pointer if you issue a multi-get and don't read out all
1363 * responses before you execute a storage command.
1364 */
1365 test_return_t get_test5(memcached_st *memc)
1366 {
1367 /*
1368 ** Request the same key twice, to ensure that we hash to the same server
1369 ** (so that we have multiple response values queued up) ;-)
1370 */
1371 const char *keys[]= { "key", "key" };
1372 size_t lengths[]= { 3, 3 };
1373 uint32_t flags;
1374 size_t rlen;
1375
1376 test_compare_hint(return_value_based_on_buffering(memc),
1377 memcached_set(memc, keys[0], lengths[0],
1378 keys[0], lengths[0],
1379 time_t(0), uint32_t(0)),
1380 memcached_last_error_message(memc));
1381 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, keys, lengths, test_array_length(keys)));
1382
1383 memcached_result_st results_obj;
1384 memcached_result_st *results= memcached_result_create(memc, &results_obj);
1385 test_true(results);
1386
1387 memcached_return_t rc;
1388 results= memcached_fetch_result(memc, &results_obj, &rc);
1389 test_true(results);
1390
1391 memcached_result_free(&results_obj);
1392
1393 /* Don't read out the second result, but issue a set instead.. */
1394 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0));
1395
1396 char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
1397 &rlen, &flags, &rc);
1398 test_false(val);
1399 test_compare(MEMCACHED_NOTFOUND, rc);
1400 val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
1401 test_true(val);
1402 test_compare(MEMCACHED_SUCCESS, rc);
1403 free(val);
1404
1405 return TEST_SUCCESS;
1406 }
1407
1408 test_return_t mget_end(memcached_st *memc)
1409 {
1410 const char *keys[]= { "foo", "foo2" };
1411 size_t lengths[]= { 3, 4 };
1412 const char *values[]= { "fjord", "41" };
1413
1414 // Set foo and foo2
1415 for (size_t x= 0; x < test_array_length(keys); x++)
1416 {
1417 test_compare(MEMCACHED_SUCCESS,
1418 memcached_set(memc,
1419 keys[x], lengths[x],
1420 values[x], strlen(values[x]),
1421 time_t(0), uint32_t(0)));
1422 }
1423
1424 char *string;
1425 size_t string_length;
1426 uint32_t flags;
1427
1428 // retrieve both via mget
1429 test_compare(MEMCACHED_SUCCESS,
1430 memcached_mget(memc,
1431 keys, lengths,
1432 test_array_length(keys)));
1433
1434 char key[MEMCACHED_MAX_KEY];
1435 size_t key_length;
1436 memcached_return_t rc;
1437
1438 // this should get both
1439 for (size_t x= 0; x < test_array_length(keys); x++)
1440 {
1441 string= memcached_fetch(memc, key, &key_length, &string_length,
1442 &flags, &rc);
1443 test_compare(MEMCACHED_SUCCESS, rc);
1444 int val = 0;
1445 if (key_length == 4)
1446 {
1447 val= 1;
1448 }
1449
1450 test_compare(string_length, strlen(values[val]));
1451 test_true(strncmp(values[val], string, string_length) == 0);
1452 free(string);
1453 }
1454
1455 // this should indicate end
1456 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1457 test_compare(MEMCACHED_END, rc);
1458 test_null(string);
1459
1460 // now get just one
1461 test_compare(MEMCACHED_SUCCESS,
1462 memcached_mget(memc, keys, lengths, 1));
1463
1464 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1465 test_compare(key_length, lengths[0]);
1466 test_true(strncmp(keys[0], key, key_length) == 0);
1467 test_compare(string_length, strlen(values[0]));
1468 test_true(strncmp(values[0], string, string_length) == 0);
1469 test_compare(MEMCACHED_SUCCESS, rc);
1470 free(string);
1471
1472 // this should indicate end
1473 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1474 test_compare(MEMCACHED_END, rc);
1475 test_null(string);
1476
1477 return TEST_SUCCESS;
1478 }
1479
1480 /* Do not copy the style of this code, I just access hosts to testthis function */
1481 test_return_t stats_servername_test(memcached_st *memc)
1482 {
1483 memcached_stat_st memc_stat;
1484 memcached_server_instance_st instance=
1485 memcached_server_instance_by_position(memc, 0);
1486
1487 if (LIBMEMCACHED_WITH_SASL_SUPPORT and memcached_get_sasl_callbacks(memc))
1488 {
1489 return TEST_SKIPPED;
1490 }
1491
1492 test_compare(MEMCACHED_SUCCESS, memcached_stat_servername(&memc_stat, NULL,
1493 memcached_server_name(instance),
1494 memcached_server_port(instance)));
1495
1496 return TEST_SUCCESS;
1497 }
1498
1499 test_return_t increment_test(memcached_st *memc)
1500 {
1501 uint64_t new_number;
1502
1503 test_compare(MEMCACHED_SUCCESS,
1504 memcached_set(memc,
1505 test_literal_param("number"),
1506 test_literal_param("0"),
1507 (time_t)0, (uint32_t)0));
1508
1509 test_compare(MEMCACHED_SUCCESS,
1510 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1511 test_compare(uint64_t(1), new_number);
1512
1513 test_compare(MEMCACHED_SUCCESS,
1514 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1515 test_compare(uint64_t(2), new_number);
1516
1517 return TEST_SUCCESS;
1518 }
1519
1520 test_return_t increment_with_initial_test(memcached_st *memc)
1521 {
1522 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1523
1524 uint64_t new_number;
1525 uint64_t initial= 0;
1526
1527 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1528
1529 test_compare(MEMCACHED_SUCCESS,
1530 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1531 test_compare(new_number, initial);
1532
1533 test_compare(MEMCACHED_SUCCESS,
1534 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1535 test_compare(new_number, (initial +1));
1536
1537 return TEST_SUCCESS;
1538 }
1539
1540 test_return_t decrement_test(memcached_st *memc)
1541 {
1542 test_compare(return_value_based_on_buffering(memc),
1543 memcached_set(memc,
1544 test_literal_param(__func__),
1545 test_literal_param("3"),
1546 time_t(0), uint32_t(0)));
1547 // Make sure we flush the value we just set
1548 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1549
1550 uint64_t new_number;
1551 test_compare(MEMCACHED_SUCCESS,
1552 memcached_decrement(memc,
1553 test_literal_param(__func__),
1554 1, &new_number));
1555 test_compare(uint64_t(2), new_number);
1556
1557 test_compare(MEMCACHED_SUCCESS,
1558 memcached_decrement(memc,
1559 test_literal_param(__func__),
1560 1, &new_number));
1561 test_compare(uint64_t(1), new_number);
1562
1563 return TEST_SUCCESS;
1564 }
1565
1566 test_return_t decrement_with_initial_test(memcached_st *memc)
1567 {
1568 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1569
1570 uint64_t initial= 3;
1571
1572 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1573
1574 uint64_t new_number;
1575 test_compare(MEMCACHED_SUCCESS,
1576 memcached_decrement_with_initial(memc,
1577 test_literal_param(__func__),
1578 1, initial,
1579 0, &new_number));
1580 test_compare(new_number, initial);
1581
1582 test_compare(MEMCACHED_SUCCESS,
1583 memcached_decrement_with_initial(memc,
1584 test_literal_param(__func__),
1585 1, initial,
1586 0, &new_number));
1587 test_compare(new_number, (initial - 1));
1588
1589 return TEST_SUCCESS;
1590 }
1591
1592 test_return_t increment_by_key_test(memcached_st *memc)
1593 {
1594 const char *master_key= "foo";
1595 const char *key= "number";
1596 const char *value= "0";
1597
1598 test_compare(return_value_based_on_buffering(memc),
1599 memcached_set_by_key(memc, master_key, strlen(master_key),
1600 key, strlen(key),
1601 value, strlen(value),
1602 time_t(0), uint32_t(0)));
1603
1604 // Make sure we flush the value we just set
1605 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1606
1607 uint64_t new_number;
1608 test_compare(MEMCACHED_SUCCESS,
1609 memcached_increment_by_key(memc, master_key, strlen(master_key),
1610 key, strlen(key), 1, &new_number));
1611 test_compare(uint64_t(1), new_number);
1612
1613 test_compare(MEMCACHED_SUCCESS,
1614 memcached_increment_by_key(memc, master_key, strlen(master_key),
1615 key, strlen(key), 1, &new_number));
1616 test_compare(uint64_t(2), new_number);
1617
1618 return TEST_SUCCESS;
1619 }
1620
1621 test_return_t increment_with_initial_by_key_test(memcached_st *memc)
1622 {
1623 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1624
1625 uint64_t new_number;
1626 const char *master_key= "foo";
1627 const char *key= "number";
1628 uint64_t initial= 0;
1629
1630 test_compare(MEMCACHED_SUCCESS,
1631 memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1632 key, strlen(key),
1633 1, initial, 0, &new_number));
1634 test_compare(new_number, initial);
1635
1636 test_compare(MEMCACHED_SUCCESS,
1637 memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1638 key, strlen(key),
1639 1, initial, 0, &new_number));
1640 test_compare(new_number, (initial +1));
1641
1642 return TEST_SUCCESS;
1643 }
1644
1645 test_return_t decrement_by_key_test(memcached_st *memc)
1646 {
1647 uint64_t new_number;
1648 const char *value= "3";
1649
1650 test_compare(return_value_based_on_buffering(memc),
1651 memcached_set_by_key(memc,
1652 test_literal_param("foo"),
1653 test_literal_param("number"),
1654 value, strlen(value),
1655 (time_t)0, (uint32_t)0));
1656
1657 test_compare(MEMCACHED_SUCCESS,
1658 memcached_decrement_by_key(memc,
1659 test_literal_param("foo"),
1660 test_literal_param("number"),
1661 1, &new_number));
1662 test_compare(uint64_t(2), new_number);
1663
1664 test_compare(MEMCACHED_SUCCESS,
1665 memcached_decrement_by_key(memc,
1666 test_literal_param("foo"),
1667 test_literal_param("number"),
1668 1, &new_number));
1669 test_compare(uint64_t(1), new_number);
1670
1671 return TEST_SUCCESS;
1672 }
1673
1674 test_return_t decrement_with_initial_by_key_test(memcached_st *memc)
1675 {
1676 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1677
1678 uint64_t new_number;
1679 uint64_t initial= 3;
1680
1681 test_compare(MEMCACHED_SUCCESS,
1682 memcached_decrement_with_initial_by_key(memc,
1683 test_literal_param("foo"),
1684 test_literal_param("number"),
1685 1, initial, 0, &new_number));
1686 test_compare(new_number, initial);
1687
1688 test_compare(MEMCACHED_SUCCESS,
1689 memcached_decrement_with_initial_by_key(memc,
1690 test_literal_param("foo"),
1691 test_literal_param("number"),
1692 1, initial, 0, &new_number));
1693 test_compare(new_number, (initial - 1));
1694
1695 return TEST_SUCCESS;
1696 }
1697 test_return_t binary_increment_with_prefix_test(memcached_st *memc)
1698 {
1699 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1700
1701 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)"namespace:"));
1702
1703 test_compare(return_value_based_on_buffering(memc),
1704 memcached_set(memc,
1705 test_literal_param("number"),
1706 test_literal_param("0"),
1707 (time_t)0, (uint32_t)0));
1708
1709 uint64_t new_number;
1710 test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
1711 test_literal_param("number"),
1712 1, &new_number));
1713 test_compare(uint64_t(1), new_number);
1714
1715 test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
1716 test_literal_param("number"),
1717 1, &new_number));
1718 test_compare(uint64_t(2), new_number);
1719
1720 return TEST_SUCCESS;
1721 }
1722
1723 test_return_t quit_test(memcached_st *memc)
1724 {
1725 const char *value= "sanford and sun";
1726
1727 test_compare(return_value_based_on_buffering(memc),
1728 memcached_set(memc,
1729 test_literal_param(__func__),
1730 value, strlen(value),
1731 (time_t)10, (uint32_t)3));
1732 memcached_quit(memc);
1733
1734 test_compare(return_value_based_on_buffering(memc),
1735 memcached_set(memc,
1736 test_literal_param(__func__),
1737 value, strlen(value),
1738 (time_t)50, (uint32_t)9));
1739
1740 return TEST_SUCCESS;
1741 }
1742
1743 test_return_t mget_result_test(memcached_st *memc)
1744 {
1745 const char *keys[]= {"fudge", "son", "food"};
1746 size_t key_length[]= {5, 3, 4};
1747
1748 memcached_result_st results_obj;
1749 memcached_result_st *results;
1750
1751 results= memcached_result_create(memc, &results_obj);
1752 test_true(results);
1753 test_true(&results_obj == results);
1754
1755 /* We need to empty the server before continueing test */
1756 test_compare(MEMCACHED_SUCCESS,
1757 memcached_flush(memc, 0));
1758
1759 test_compare(MEMCACHED_SUCCESS,
1760 memcached_mget(memc, keys, key_length, 3));
1761
1762 memcached_return_t rc;
1763 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1764 {
1765 test_true(results);
1766 }
1767
1768 while ((results= memcached_fetch_result(memc, &results_obj, &rc))) { test_true(false); /* We should never see a value returned */ };
1769 test_false(results);
1770 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1771
1772 for (uint32_t x= 0; x < 3; x++)
1773 {
1774 rc= memcached_set(memc, keys[x], key_length[x],
1775 keys[x], key_length[x],
1776 (time_t)50, (uint32_t)9);
1777 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
1778 }
1779
1780 test_compare(MEMCACHED_SUCCESS,
1781 memcached_mget(memc, keys, key_length, 3));
1782
1783 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1784 {
1785 test_true(results);
1786 test_true(&results_obj == results);
1787 test_compare(MEMCACHED_SUCCESS, rc);
1788 test_memcmp(memcached_result_key_value(results),
1789 memcached_result_value(results),
1790 memcached_result_length(results));
1791 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1792 }
1793
1794 memcached_result_free(&results_obj);
1795
1796 return TEST_SUCCESS;
1797 }
1798
1799 test_return_t mget_result_alloc_test(memcached_st *memc)
1800 {
1801 const char *keys[]= {"fudge", "son", "food"};
1802 size_t key_length[]= {5, 3, 4};
1803
1804 memcached_result_st *results;
1805
1806 /* We need to empty the server before continueing test */
1807 test_compare(MEMCACHED_SUCCESS,
1808 memcached_flush(memc, 0));
1809
1810 test_compare(MEMCACHED_SUCCESS,
1811 memcached_mget(memc, keys, key_length, 3));
1812
1813 memcached_return_t rc;
1814 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1815 {
1816 test_true(results);
1817 }
1818 test_false(results);
1819 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1820
1821 for (uint32_t x= 0; x < 3; x++)
1822 {
1823 rc= memcached_set(memc, keys[x], key_length[x],
1824 keys[x], key_length[x],
1825 (time_t)50, (uint32_t)9);
1826 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
1827 }
1828
1829 test_compare(MEMCACHED_SUCCESS,
1830 memcached_mget(memc, keys, key_length, 3));
1831
1832 uint32_t x= 0;
1833 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1834 {
1835 test_true(results);
1836 test_compare(MEMCACHED_SUCCESS, rc);
1837 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1838 test_memcmp(memcached_result_key_value(results),
1839 memcached_result_value(results),
1840 memcached_result_length(results));
1841 memcached_result_free(results);
1842 x++;
1843 }
1844
1845 return TEST_SUCCESS;
1846 }
1847
1848 test_return_t mget_result_function(memcached_st *memc)
1849 {
1850 const char *keys[]= {"fudge", "son", "food"};
1851 size_t key_length[]= {5, 3, 4};
1852 size_t counter;
1853 memcached_execute_fn callbacks[1];
1854
1855 for (uint32_t x= 0; x < 3; x++)
1856 {
1857 test_compare(return_value_based_on_buffering(memc),
1858 memcached_set(memc, keys[x], key_length[x],
1859 keys[x], key_length[x],
1860 time_t(50), uint32_t(9)));
1861 }
1862 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1863 memcached_quit(memc);
1864
1865 test_compare(MEMCACHED_SUCCESS,
1866 memcached_mget(memc, keys, key_length, 3));
1867
1868 callbacks[0]= &callback_counter;
1869 counter= 0;
1870
1871 test_compare(MEMCACHED_SUCCESS,
1872 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1873
1874 test_compare(size_t(3), counter);
1875
1876 return TEST_SUCCESS;
1877 }
1878
1879 test_return_t mget_test(memcached_st *memc)
1880 {
1881 const char *keys[]= {"fudge", "son", "food"};
1882 size_t key_length[]= {5, 3, 4};
1883
1884 char return_key[MEMCACHED_MAX_KEY];
1885 size_t return_key_length;
1886 char *return_value;
1887 size_t return_value_length;
1888
1889 test_compare(MEMCACHED_SUCCESS,
1890 memcached_mget(memc, keys, key_length, 3));
1891
1892 uint32_t flags;
1893 memcached_return_t rc;
1894 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1895 &return_value_length, &flags, &rc)))
1896 {
1897 test_true(return_value);
1898 }
1899 test_false(return_value);
1900 test_zero(return_value_length);
1901 test_compare(MEMCACHED_NOTFOUND, rc);
1902
1903 for (uint32_t x= 0; x < 3; x++)
1904 {
1905 rc= memcached_set(memc, keys[x], key_length[x],
1906 keys[x], key_length[x],
1907 (time_t)50, (uint32_t)9);
1908 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
1909 }
1910 test_compare(MEMCACHED_SUCCESS,
1911 memcached_mget(memc, keys, key_length, 3));
1912
1913 uint32_t x= 0;
1914 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1915 &return_value_length, &flags, &rc)))
1916 {
1917 test_true(return_value);
1918 test_compare(MEMCACHED_SUCCESS, rc);
1919 if (not memc->_namespace)
1920 {
1921 test_compare(return_key_length, return_value_length);
1922 test_memcmp(return_value, return_key, return_value_length);
1923 }
1924 free(return_value);
1925 x++;
1926 }
1927
1928 return TEST_SUCCESS;
1929 }
1930
1931 test_return_t mget_execute(memcached_st *original_memc)
1932 {
1933 test_skip(true, memcached_behavior_get(original_memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1934
1935 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
1936 test_true(memc);
1937
1938 keys_st keys(20480);
1939
1940 /* First add all of the items.. */
1941 char blob[1024] = {0};
1942
1943 for (size_t x= 0; x < keys.size(); ++x)
1944 {
1945 uint64_t query_id= memcached_query_id(memc);
1946 memcached_return_t rc= memcached_add(memc,
1947 keys.key_at(x), keys.length_at(x),
1948 blob, sizeof(blob),
1949 0, 0);
1950 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED,
1951 memcached_strerror(NULL, rc));
1952 test_compare(query_id +1, memcached_query_id(memc));
1953 }
1954
1955 /* Try to get all of them with a large multiget */
1956 size_t counter= 0;
1957 memcached_execute_fn callbacks[]= { &callback_counter };
1958 test_compare(MEMCACHED_SUCCESS,
1959 memcached_mget_execute(memc,
1960 keys.keys_ptr(), keys.lengths_ptr(),
1961 keys.size(), callbacks, &counter, 1));
1962
1963 {
1964 uint64_t query_id= memcached_query_id(memc);
1965 test_compare(MEMCACHED_SUCCESS,
1966 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1967 test_compare(query_id, memcached_query_id(memc));
1968
1969 /* Verify that we got all of the items */
1970 test_compare(keys.size(), counter);
1971 }
1972
1973 memcached_free(memc);
1974
1975 return TEST_SUCCESS;
1976 }
1977
1978 #define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
1979 static pairs_st *global_pairs;
1980
1981 test_return_t key_setup(memcached_st *memc)
1982 {
1983 test_skip(TEST_SUCCESS, pre_binary(memc));
1984
1985 global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
1986
1987 return TEST_SUCCESS;
1988 }
1989
1990 test_return_t key_teardown(memcached_st *)
1991 {
1992 pairs_free(global_pairs);
1993
1994 return TEST_SUCCESS;
1995 }
1996
1997 test_return_t block_add_regression(memcached_st *memc)
1998 {
1999 /* First add all of the items.. */
2000 for (ptrdiff_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
2001 {
2002 char blob[1024] = {0};
2003
2004 memcached_return_t rc= memcached_add_by_key(memc, "bob", 3, global_pairs[x].key, global_pairs[x].key_length, blob, sizeof(blob), 0, 0);
2005 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE, memcached_strerror(NULL, rc));
2006 }
2007
2008 return TEST_SUCCESS;
2009 }
2010
2011 test_return_t binary_add_regression(memcached_st *memc)
2012 {
2013 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
2014 test_return_t rc= block_add_regression(memc);
2015
2016 return rc;
2017 }
2018
2019 test_return_t get_stats_keys(memcached_st *memc)
2020 {
2021 char **stat_list;
2022 char **ptr;
2023 memcached_stat_st memc_stat;
2024 memcached_return_t rc;
2025
2026 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
2027 test_compare(MEMCACHED_SUCCESS, rc);
2028 for (ptr= stat_list; *ptr; ptr++)
2029 test_true(*ptr);
2030
2031 free(stat_list);
2032
2033 return TEST_SUCCESS;
2034 }
2035
2036 test_return_t version_string_test(memcached_st *)
2037 {
2038 test_strcmp(LIBMEMCACHED_VERSION_STRING, memcached_lib_version());
2039
2040 return TEST_SUCCESS;
2041 }
2042
2043 test_return_t get_stats(memcached_st *memc)
2044 {
2045 memcached_return_t rc;
2046
2047 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
2048 test_compare(MEMCACHED_SUCCESS, rc);
2049 test_true(memc_stat);
2050
2051 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
2052 {
2053 char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
2054 test_compare(MEMCACHED_SUCCESS, rc);
2055 for (char **ptr= stat_list; *ptr; ptr++) {};
2056
2057 free(stat_list);
2058 }
2059
2060 memcached_stat_free(NULL, memc_stat);
2061
2062 return TEST_SUCCESS;
2063 }
2064
2065 test_return_t add_host_test(memcached_st *memc)
2066 {
2067 char servername[]= "0.example.com";
2068
2069 memcached_return_t rc;
2070 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
2071 test_compare(1U, memcached_server_list_count(servers));
2072
2073 for (unsigned int x= 2; x < 20; x++)
2074 {
2075 char buffer[SMALL_STRING_LEN];
2076
2077 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
2078 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
2079 &rc);
2080 test_compare(MEMCACHED_SUCCESS, rc);
2081 test_compare(x, memcached_server_list_count(servers));
2082 }
2083
2084 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2085 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2086
2087 memcached_server_list_free(servers);
2088
2089 return TEST_SUCCESS;
2090 }
2091
2092 test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc)
2093 {
2094 memcached_return_t rc;
2095
2096 const char *key= "not_found";
2097 size_t key_length= test_literal_param_size("not_found");
2098
2099 test_compare(MEMCACHED_SUCCESS,
2100 memcached_mget(memc, &key, &key_length, 1));
2101
2102 memcached_result_st *result= memcached_fetch_result(memc, NULL, &rc);
2103 test_null(result);
2104 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
2105
2106 memcached_result_free(result);
2107
2108 return TEST_SUCCESS;
2109 }
2110
2111 static memcached_return_t clone_test_callback(memcached_st *, memcached_st *)
2112 {
2113 return MEMCACHED_SUCCESS;
2114 }
2115
2116 static memcached_return_t cleanup_test_callback(memcached_st *)
2117 {
2118 return MEMCACHED_SUCCESS;
2119 }
2120
2121 test_return_t callback_test(memcached_st *memc)
2122 {
2123 /* Test User Data */
2124 {
2125 int x= 5;
2126 int *test_ptr;
2127 memcached_return_t rc;
2128
2129 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x));
2130 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
2131 test_true(*test_ptr == x);
2132 }
2133
2134 /* Test Clone Callback */
2135 {
2136 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
2137 void *clone_cb_ptr= *(void **)&clone_cb;
2138 void *temp_function= NULL;
2139
2140 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, clone_cb_ptr));
2141 memcached_return_t rc;
2142 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
2143 test_true(temp_function == clone_cb_ptr);
2144 test_compare(MEMCACHED_SUCCESS, rc);
2145 }
2146
2147 /* Test Cleanup Callback */
2148 {
2149 memcached_cleanup_fn cleanup_cb= (memcached_cleanup_fn)cleanup_test_callback;
2150 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
2151 void *temp_function= NULL;
2152 memcached_return_t rc;
2153
2154 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, cleanup_cb_ptr));
2155 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
2156 test_true(temp_function == cleanup_cb_ptr);
2157 }
2158
2159 return TEST_SUCCESS;
2160 }
2161
2162 /* We don't test the behavior itself, we test the switches */
2163 test_return_t behavior_test(memcached_st *memc)
2164 {
2165 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
2166 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
2167
2168 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
2169 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
2170
2171 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_MD5);
2172 test_compare(uint64_t(MEMCACHED_HASH_MD5), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
2173
2174 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
2175 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
2176
2177 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
2178 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
2179
2180 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_DEFAULT);
2181 test_compare(uint64_t(MEMCACHED_HASH_DEFAULT), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
2182
2183 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_CRC);
2184 test_compare(uint64_t(MEMCACHED_HASH_CRC), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
2185
2186 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
2187
2188 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
2189
2190 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
2191 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value +1);
2192 test_compare((value +1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
2193
2194 return TEST_SUCCESS;
2195 }
2196
2197 test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
2198 {
2199 test_compare(MEMCACHED_DEPRECATED,
2200 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, true));
2201
2202 // Platform dependent
2203 #if 0
2204 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
2205 test_false(value);
2206 #endif
2207
2208 return TEST_SUCCESS;
2209 }
2210
2211
2212 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
2213 {
2214 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, true);
2215 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2216
2217 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
2218
2219 if (memcached_success(rc))
2220 {
2221 test_true(value);
2222 }
2223 else
2224 {
2225 test_false(value);
2226 }
2227
2228 return TEST_SUCCESS;
2229 }
2230
2231
2232 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
2233 {
2234 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, true);
2235 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2236
2237 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
2238
2239 if (memcached_success(rc))
2240 {
2241 test_true(value);
2242 }
2243 else
2244 {
2245 test_false(value);
2246 }
2247
2248 return TEST_SUCCESS;
2249 }
2250
2251 /* Make sure we behave properly if server list has no values */
2252 test_return_t user_supplied_bug4(memcached_st *memc)
2253 {
2254 const char *keys[]= {"fudge", "son", "food"};
2255 size_t key_length[]= {5, 3, 4};
2256
2257 /* Here we free everything before running a bunch of mget tests */
2258 memcached_servers_reset(memc);
2259
2260
2261 /* We need to empty the server before continueing test */
2262 test_compare(MEMCACHED_NO_SERVERS,
2263 memcached_flush(memc, 0));
2264
2265 test_compare(MEMCACHED_NO_SERVERS,
2266 memcached_mget(memc, keys, key_length, 3));
2267
2268 {
2269 unsigned int keys_returned;
2270 memcached_return_t rc;
2271 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, rc));
2272 test_compare(MEMCACHED_NOTFOUND, rc);
2273 test_zero(keys_returned);
2274 }
2275
2276 for (uint32_t x= 0; x < 3; x++)
2277 {
2278 test_compare(MEMCACHED_NO_SERVERS,
2279 memcached_set(memc, keys[x], key_length[x],
2280 keys[x], key_length[x],
2281 (time_t)50, (uint32_t)9));
2282 }
2283
2284 test_compare(MEMCACHED_NO_SERVERS,
2285 memcached_mget(memc, keys, key_length, 3));
2286
2287 {
2288 char *return_value;
2289 char return_key[MEMCACHED_MAX_KEY];
2290 memcached_return_t rc;
2291 size_t return_key_length;
2292 size_t return_value_length;
2293 uint32_t flags;
2294 uint32_t x= 0;
2295 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2296 &return_value_length, &flags, &rc)))
2297 {
2298 test_true(return_value);
2299 test_compare(MEMCACHED_SUCCESS, rc);
2300 test_true(return_key_length == return_value_length);
2301 test_memcmp(return_value, return_key, return_value_length);
2302 free(return_value);
2303 x++;
2304 }
2305 }
2306
2307 return TEST_SUCCESS;
2308 }
2309
2310 #define VALUE_SIZE_BUG5 1048064
2311 test_return_t user_supplied_bug5(memcached_st *memc)
2312 {
2313 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2314 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2315 char *value;
2316 size_t value_length;
2317 uint32_t flags;
2318 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2319
2320 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2321 {
2322 insert_data[x]= (signed char)rand();
2323 }
2324
2325 test_compare(MEMCACHED_SUCCESS,
2326 memcached_flush(memc, 0));
2327
2328 memcached_return_t rc;
2329 test_null(memcached_get(memc, keys[0], key_length[0], &value_length, &flags, &rc));
2330 test_compare(MEMCACHED_SUCCESS,
2331 memcached_mget(memc, keys, key_length, 4));
2332
2333 unsigned int count;
2334 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, rc));
2335 test_compare(MEMCACHED_NOTFOUND, rc);
2336 test_zero(count);
2337
2338 for (uint32_t x= 0; x < 4; x++)
2339 {
2340 test_compare(MEMCACHED_SUCCESS,
2341 memcached_set(memc, keys[x], key_length[x],
2342 insert_data, VALUE_SIZE_BUG5,
2343 (time_t)0, (uint32_t)0));
2344 }
2345
2346 for (uint32_t x= 0; x < 10; x++)
2347 {
2348 value= memcached_get(memc, keys[0], key_length[0],
2349 &value_length, &flags, &rc);
2350 test_compare(rc, MEMCACHED_SUCCESS);
2351 test_true(value);
2352 ::free(value);
2353
2354 test_compare(MEMCACHED_SUCCESS,
2355 memcached_mget(memc, keys, key_length, 4));
2356
2357 test_compare(TEST_SUCCESS, fetch_all_results(memc, count));
2358 test_compare(4U, count);
2359 }
2360 delete [] insert_data;
2361
2362 return TEST_SUCCESS;
2363 }
2364
2365 test_return_t user_supplied_bug6(memcached_st *memc)
2366 {
2367 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2368 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2369 char return_key[MEMCACHED_MAX_KEY];
2370 size_t return_key_length;
2371 char *value;
2372 size_t value_length;
2373 uint32_t flags;
2374 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2375
2376 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2377 {
2378 insert_data[x]= (signed char)rand();
2379 }
2380
2381 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
2382
2383 test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc, keys, test_array_length(keys)));
2384
2385 // We will now confirm that memcached_mget() returns success, but we will
2386 // then check to make sure that no actual keys are returned.
2387 test_compare(MEMCACHED_SUCCESS,
2388 memcached_mget(memc, keys, key_length, 4));
2389
2390 memcached_return_t rc;
2391 uint32_t count= 0;
2392 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2393 &value_length, &flags, &rc)))
2394 {
2395 count++;
2396 }
2397 test_zero(count);
2398 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
2399
2400 for (uint32_t x= 0; x < test_array_length(keys); x++)
2401 {
2402 test_compare(MEMCACHED_SUCCESS,
2403 memcached_set(memc, keys[x], key_length[x],
2404 insert_data, VALUE_SIZE_BUG5,
2405 (time_t)0, (uint32_t)0));
2406 }
2407 test_compare(TEST_SUCCESS, confirm_keys_exist(memc, keys, test_array_length(keys)));
2408
2409 for (uint32_t x= 0; x < 2; x++)
2410 {
2411 value= memcached_get(memc, keys[0], key_length[0],
2412 &value_length, &flags, &rc);
2413 test_true(value);
2414 free(value);
2415
2416 test_compare(MEMCACHED_SUCCESS,
2417 memcached_mget(memc, keys, key_length, 4));
2418 /* We test for purge of partial complete fetches */
2419 for (count= 3; count; count--)
2420 {
2421 value= memcached_fetch(memc, return_key, &return_key_length,
2422 &value_length, &flags, &rc);
2423 test_compare(MEMCACHED_SUCCESS, rc);
2424 test_memcmp(value, insert_data, value_length);
2425 test_true(value_length);
2426 free(value);
2427 }
2428 }
2429 delete [] insert_data;
2430
2431 return TEST_SUCCESS;
2432 }
2433
2434 test_return_t user_supplied_bug8(memcached_st *)
2435 {
2436 memcached_return_t rc;
2437 memcached_st *mine;
2438 memcached_st *memc_clone;
2439
2440 memcached_server_st *servers;
2441 const char *server_list= "memcache1.memcache.bk.sapo.pt:11211, memcache1.memcache.bk.sapo.pt:11212, memcache1.memcache.bk.sapo.pt:11213, memcache1.memcache.bk.sapo.pt:11214, memcache2.memcache.bk.sapo.pt:11211, memcache2.memcache.bk.sapo.pt:11212, memcache2.memcache.bk.sapo.pt:11213, memcache2.memcache.bk.sapo.pt:11214";
2442
2443 servers= memcached_servers_parse(server_list);
2444 test_true(servers);
2445
2446 mine= memcached_create(NULL);
2447 rc= memcached_server_push(mine, servers);
2448 test_compare(MEMCACHED_SUCCESS, rc);
2449 memcached_server_list_free(servers);
2450
2451 test_true(mine);
2452 memc_clone= memcached_clone(NULL, mine);
2453
2454 memcached_quit(mine);
2455 memcached_quit(memc_clone);
2456
2457
2458 memcached_free(mine);
2459 memcached_free(memc_clone);
2460
2461 return TEST_SUCCESS;
2462 }
2463
2464 /* Test flag store/retrieve */
2465 test_return_t user_supplied_bug7(memcached_st *memc)
2466 {
2467 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2468 test_true(insert_data);
2469
2470 for (size_t x= 0; x < VALUE_SIZE_BUG5; x++)
2471 {
2472 insert_data[x]= (signed char)rand();
2473 }
2474
2475 memcached_flush(memc, 0);
2476
2477 const char *keys= "036790384900";
2478 size_t key_length= strlen(keys);
2479 test_compare_hint(MEMCACHED_SUCCESS, memcached_set(memc, keys, key_length,
2480 insert_data, VALUE_SIZE_BUG5,
2481 time_t(0), 245U),
2482 memcached_last_error_message(memc));
2483
2484 memcached_return_t rc;
2485 size_t value_length;
2486 uint32_t flags= 0;
2487 char *value= memcached_get(memc, keys, key_length,
2488 &value_length, &flags, &rc);
2489 test_compare(245U, flags);
2490 test_true(value);
2491 free(value);
2492
2493 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, &keys, &key_length, 1));
2494
2495 char return_key[MEMCACHED_MAX_KEY];
2496 size_t return_key_length;
2497 flags= 0;
2498 value= memcached_fetch(memc, return_key, &return_key_length,
2499 &value_length, &flags, &rc);
2500 test_compare(uint32_t(245), flags);
2501 test_true(value);
2502 free(value);
2503 delete [] insert_data;
2504
2505
2506 return TEST_SUCCESS;
2507 }
2508
2509 test_return_t user_supplied_bug9(memcached_st *memc)
2510 {
2511 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2512 size_t key_length[3];
2513 uint32_t flags;
2514 unsigned count= 0;
2515
2516 char return_key[MEMCACHED_MAX_KEY];
2517 size_t return_key_length;
2518 char *return_value;
2519 size_t return_value_length;
2520
2521
2522 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2523 key_length[1]= strlen("fudge&*@#");
2524 key_length[2]= strlen("for^#@&$not");
2525
2526
2527 for (unsigned int x= 0; x < 3; x++)
2528 {
2529 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
2530 keys[x], key_length[x],
2531 (time_t)50, (uint32_t)9);
2532 test_compare(MEMCACHED_SUCCESS, rc);
2533 }
2534
2535 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
2536 test_compare(MEMCACHED_SUCCESS, rc);
2537
2538 /* We need to empty the server before continueing test */
2539 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2540 &return_value_length, &flags, &rc)) != NULL)
2541 {
2542 test_true(return_value);
2543 free(return_value);
2544 count++;
2545 }
2546 test_compare(3U, count);
2547
2548 return TEST_SUCCESS;
2549 }
2550
2551 /* We are testing with aggressive timeout to get failures */
2552 test_return_t user_supplied_bug10(memcached_st *memc)
2553 {
2554 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
2555
2556 size_t value_length= 512;
2557 unsigned int set= 1;
2558 memcached_st *mclone= memcached_clone(NULL, memc);
2559
2560 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2561 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2562 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, uint64_t(0));
2563
2564 libtest::vchar_t value;
2565 value.reserve(value_length);
2566 for (uint32_t x= 0; x < value_length; x++)
2567 {
2568 value.push_back(char(x % 127));
2569 }
2570
2571 for (unsigned int x= 1; x <= 100000; ++x)
2572 {
2573 memcached_return_t rc= memcached_set(mclone,
2574 test_literal_param("foo"),
2575 &value[0], value.size(),
2576 0, 0);
2577
2578 test_true_got((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE
2579 or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED),
2580 memcached_strerror(NULL, rc));
2581
2582 if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
2583 {
2584 x--;
2585 }
2586 }
2587
2588 memcached_free(mclone);
2589
2590 return TEST_SUCCESS;
2591 }
2592
2593 /*
2594 We are looking failures in the async protocol
2595 */
2596 test_return_t user_supplied_bug11(memcached_st *memc)
2597 {
2598 memcached_st *mclone= memcached_clone(NULL, memc);
2599
2600 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, true);
2601 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2602 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, size_t(-1));
2603
2604 test_compare(-1, int32_t(memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT)));
2605
2606
2607 libtest::vchar_t value;
2608 value.reserve(512);
2609 for (unsigned int x= 0; x < 512; x++)
2610 {
2611 value.push_back(char(x % 127));
2612 }
2613
2614 for (unsigned int x= 1; x <= 100000; ++x)
2615 {
2616 memcached_return_t rc= memcached_set(mclone, test_literal_param("foo"), &value[0], value.size(), 0, 0);
2617 (void)rc;
2618 }
2619
2620 memcached_free(mclone);
2621
2622 return TEST_SUCCESS;
2623 }
2624
2625 /*
2626 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2627 */
2628 test_return_t user_supplied_bug12(memcached_st *memc)
2629 {
2630 memcached_return_t rc;
2631 uint32_t flags;
2632 size_t value_length;
2633 char *value;
2634 uint64_t number_value;
2635
2636 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2637 &value_length, &flags, &rc);
2638 test_null(value);
2639 test_compare(MEMCACHED_NOTFOUND, rc);
2640
2641 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2642 1, &number_value);
2643 test_null(value);
2644 /* The binary protocol will set the key if it doesn't exist */
2645 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2646 {
2647 test_compare(MEMCACHED_SUCCESS, rc);
2648 }
2649 else
2650 {
2651 test_compare(MEMCACHED_NOTFOUND, rc);
2652 }
2653
2654 test_compare(MEMCACHED_SUCCESS,
2655 memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0));
2656
2657 value= memcached_get(memc, "autoincrement", strlen("autoincrement"), &value_length, &flags, &rc);
2658 test_true(value);
2659 free(value);
2660
2661 test_compare(MEMCACHED_SUCCESS,
2662 memcached_increment(memc, "autoincrement", strlen("autoincrement"), 1, &number_value));
2663 test_compare(2UL, number_value);
2664
2665 return TEST_SUCCESS;
2666 }
2667
2668 /*
2669 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2670 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2671 */
2672 test_return_t user_supplied_bug13(memcached_st *memc)
2673 {
2674 char key[] = "key34567890";
2675
2676 char commandFirst[]= "set key34567890 0 0 ";
2677 char commandLast[] = " \r\n"; /* first line of command sent to server */
2678 size_t commandLength;
2679
2680 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2681
2682 size_t overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2683
2684 for (size_t testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2685 {
2686 char *overflow= new (std::nothrow) char[testSize];
2687 test_true(overflow);
2688
2689 memset(overflow, 'x', testSize);
2690 test_compare(MEMCACHED_SUCCESS,
2691 memcached_set(memc, key, strlen(key),
2692 overflow, testSize, 0, 0));
2693 delete [] overflow;
2694 }
2695
2696 return TEST_SUCCESS;
2697 }
2698
2699
2700 /*
2701 Test values of many different sizes
2702 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2703 set key34567890 0 0 8169 \r\n
2704 is sent followed by buffer of size 8169, followed by 8169
2705 */
2706 test_return_t user_supplied_bug14(memcached_st *memc)
2707 {
2708 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2709
2710 libtest::vchar_t value;
2711 value.reserve(18000);
2712 for (ptrdiff_t x= 0; x < 18000; x++)
2713 {
2714 value.push_back((char) (x % 127));
2715 }
2716
2717 for (size_t current_length= 1; current_length < value.size(); current_length++)
2718 {
2719 memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
2720 &value[0], current_length,
2721 (time_t)0, (uint32_t)0);
2722 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
2723
2724 size_t string_length;
2725 uint32_t flags;
2726 char *string= memcached_get(memc, test_literal_param("foo"),
2727 &string_length, &flags, &rc);
2728
2729 test_compare(MEMCACHED_SUCCESS, rc);
2730 test_compare(string_length, current_length);
2731 char buffer[1024];
2732 snprintf(buffer, sizeof(buffer), "%u", uint32_t(string_length));
2733 test_memcmp_hint(string, &value[0], string_length, buffer);
2734
2735 free(string);
2736 }
2737
2738 return TEST_SUCCESS;
2739 }
2740
2741 /*
2742 Look for zero length value problems
2743 */
2744 test_return_t user_supplied_bug15(memcached_st *memc)
2745 {
2746 for (uint32_t x= 0; x < 2; x++)
2747 {
2748 memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
2749 NULL, 0,
2750 (time_t)0, (uint32_t)0);
2751
2752 test_compare(MEMCACHED_SUCCESS, rc);
2753
2754 size_t length;
2755 uint32_t flags;
2756 char *value= memcached_get(memc, test_literal_param("mykey"),
2757 &length, &flags, &rc);
2758
2759 test_compare(MEMCACHED_SUCCESS, rc);
2760 test_false(value);
2761 test_zero(length);
2762 test_zero(flags);
2763
2764 value= memcached_get(memc, test_literal_param("mykey"),
2765 &length, &flags, &rc);
2766
2767 test_compare(MEMCACHED_SUCCESS, rc);
2768 test_null(value);
2769 test_zero(length);
2770 test_zero(flags);
2771 }
2772
2773 return TEST_SUCCESS;
2774 }
2775
2776 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2777 test_return_t user_supplied_bug16(memcached_st *memc)
2778 {
2779 test_compare_hint(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("mykey"),
2780 NULL, 0,
2781 (time_t)0, UINT32_MAX),
2782 memcached_last_error_message(memc));
2783
2784
2785 size_t length;
2786 uint32_t flags;
2787 memcached_return_t rc;
2788 char *value= memcached_get(memc, test_literal_param("mykey"),
2789 &length, &flags, &rc);
2790
2791 test_compare(MEMCACHED_SUCCESS, rc);
2792 test_null(value);
2793 test_zero(length);
2794 test_compare(flags, UINT32_MAX);
2795
2796 return TEST_SUCCESS;
2797 }
2798
2799 #if !defined(__sun) && !defined(__OpenBSD__)
2800 /* Check the validity of chinese key*/
2801 test_return_t user_supplied_bug17(memcached_st *memc)
2802 {
2803 const char *key= "豆瓣";
2804 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2805 memcached_return_t rc= memcached_set(memc, key, strlen(key),
2806 value, strlen(value),
2807 (time_t)0, 0);
2808
2809 test_compare(MEMCACHED_SUCCESS, rc);
2810
2811 size_t length;
2812 uint32_t flags;
2813 char *value2= memcached_get(memc, key, strlen(key),
2814 &length, &flags, &rc);
2815
2816 test_true(length==strlen(value));
2817 test_compare(MEMCACHED_SUCCESS, rc);
2818 test_memcmp(value, value2, length);
2819 free(value2);
2820
2821 return TEST_SUCCESS;
2822 }
2823 #endif
2824
2825 /*
2826 From Andrei on IRC
2827 */
2828
2829 test_return_t user_supplied_bug19(memcached_st *)
2830 {
2831 memcached_return_t res;
2832
2833 memcached_st *memc= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
2834
2835 const memcached_server_st *server= memcached_server_by_key(memc, "a", 1, &res);
2836 test_true(server);
2837
2838 memcached_free(memc);
2839
2840 return TEST_SUCCESS;
2841 }
2842
2843 /* CAS test from Andei */
2844 test_return_t user_supplied_bug20(memcached_st *memc)
2845 {
2846 const char *key= "abc";
2847 size_t key_len= strlen("abc");
2848
2849 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
2850
2851 test_compare(MEMCACHED_SUCCESS,
2852 memcached_set(memc,
2853 test_literal_param("abc"),
2854 test_literal_param("foobar"),
2855 (time_t)0, (uint32_t)0));
2856
2857 test_compare(MEMCACHED_SUCCESS,
2858 memcached_mget(memc, &key, &key_len, 1));
2859
2860 memcached_result_st result_obj;
2861 memcached_result_st *result= memcached_result_create(memc, &result_obj);
2862 test_true(result);
2863
2864 memcached_result_create(memc, &result_obj);
2865 memcached_return_t status;
2866 result= memcached_fetch_result(memc, &result_obj, &status);
2867
2868 test_true(result);
2869 test_compare(MEMCACHED_SUCCESS, status);
2870
2871 memcached_result_free(result);
2872
2873 return TEST_SUCCESS;
2874 }
2875
2876 /* Large mget() of missing keys with binary proto
2877 *
2878 * If many binary quiet commands (such as getq's in an mget) fill the output
2879 * buffer and the server chooses not to respond, memcached_flush hangs. See
2880 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2881 */
2882
2883 /* sighandler_t function that always asserts false */
2884 static void fail(int)
2885 {
2886 fatal_assert(0);
2887 }
2888
2889
2890 test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2891 {
2892 #ifdef WIN32
2893 (void)memc;
2894 (void)key_count;
2895 return TEST_SKIPPED;
2896 #else
2897 void (*oldalarm)(int);
2898
2899 memcached_st *memc_clone= memcached_clone(NULL, memc);
2900 test_true(memc_clone);
2901
2902 /* only binproto uses getq for mget */
2903 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
2904
2905 /* empty the cache to ensure misses (hence non-responses) */
2906 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
2907
2908 keys_st keys(key_count);
2909
2910 oldalarm= signal(SIGALRM, fail);
2911 alarm(5);
2912
2913 test_compare_got(MEMCACHED_SUCCESS,
2914 memcached_mget(memc_clone, keys.keys_ptr(), keys.lengths_ptr(), keys.size()),
2915 memcached_last_error_message(memc_clone));
2916
2917 alarm(0);
2918 signal(SIGALRM, oldalarm);
2919
2920 memcached_return_t rc;
2921 uint32_t flags;
2922 char return_key[MEMCACHED_MAX_KEY];
2923 size_t return_key_length;
2924 char *return_value;
2925 size_t return_value_length;
2926 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2927 &return_value_length, &flags, &rc)))
2928 {
2929 test_false(return_value); // There are no keys to fetch, so the value should never be returned
2930 }
2931 test_compare(MEMCACHED_NOTFOUND, rc);
2932 test_zero(return_value_length);
2933 test_zero(return_key_length);
2934 test_false(return_key[0]);
2935 test_false(return_value);
2936
2937 memcached_free(memc_clone);
2938
2939 return TEST_SUCCESS;
2940 #endif
2941 }
2942
2943 test_return_t user_supplied_bug21(memcached_st *memc)
2944 {
2945 test_skip(TEST_SUCCESS, pre_binary(memc));
2946
2947 /* should work as of r580 */
2948 test_compare(TEST_SUCCESS,
2949 _user_supplied_bug21(memc, 10));
2950
2951 /* should fail as of r580 */
2952 test_compare(TEST_SUCCESS,
2953 _user_supplied_bug21(memc, 1000));
2954
2955 return TEST_SUCCESS;
2956 }
2957
2958 test_return_t output_ketama_weighted_keys(memcached_st *)
2959 {
2960 memcached_st *memc= memcached_create(NULL);
2961 test_true(memc);
2962
2963
2964 test_compare(MEMCACHED_SUCCESS,
2965 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
2966
2967 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2968 test_compare(value, uint64_t(1));
2969
2970 test_compare(MEMCACHED_SUCCESS,
2971 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
2972
2973 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2974 test_true(value == MEMCACHED_HASH_MD5);
2975
2976
2977 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2978
2979 memcached_server_st *server_pool;
2980 server_pool = memcached_servers_parse("10.0.1.1:11211,10.0.1.2:11211,10.0.1.3:11211,10.0.1.4:11211,10.0.1.5:11211,10.0.1.6:11211,10.0.1.7:11211,10.0.1.8:11211,192.168.1.1:11211,192.168.100.1:11211");
2981 memcached_server_push(memc, server_pool);
2982
2983 // @todo this needs to be refactored to actually test something.
2984 #if 0
2985 FILE *fp;
2986 if ((fp = fopen("ketama_keys.txt", "w")))
2987 {
2988 // noop
2989 } else {
2990 printf("cannot write to file ketama_keys.txt");
2991 return TEST_FAILURE;
2992 }
2993
2994 for (int x= 0; x < 10000; x++)
2995 {
2996 char key[10];
2997 snprintf(key, sizeof(key), "%d", x);
2998
2999 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3000 char *hostname = memc->hosts[server_idx].hostname;
3001 in_port_t port = memc->hosts[server_idx].port;
3002 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3003 memcached_server_instance_st instance=
3004 memcached_server_instance_by_position(memc, host_index);
3005 }
3006 fclose(fp);
3007 #endif
3008 memcached_server_list_free(server_pool);
3009 memcached_free(memc);
3010
3011 return TEST_SUCCESS;
3012 }
3013
3014
3015 test_return_t result_static(memcached_st *memc)
3016 {
3017 memcached_result_st result;
3018 memcached_result_st *result_ptr= memcached_result_create(memc, &result);
3019 test_false(result.options.is_allocated);
3020 test_true(memcached_is_initialized(&result));
3021 test_true(result_ptr);
3022 test_true(result_ptr == &result);
3023
3024 memcached_result_free(&result);
3025
3026 test_false(result.options.is_allocated);
3027 test_false(memcached_is_initialized(&result));
3028
3029 return TEST_SUCCESS;
3030 }
3031
3032 test_return_t result_alloc(memcached_st *memc)
3033 {
3034 memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
3035 test_true(result_ptr);
3036 test_true(result_ptr->options.is_allocated);
3037 test_true(memcached_is_initialized(result_ptr));
3038 memcached_result_free(result_ptr);
3039
3040 return TEST_SUCCESS;
3041 }
3042
3043
3044 test_return_t add_host_test1(memcached_st *memc)
3045 {
3046 memcached_return_t rc;
3047 char servername[]= "0.example.com";
3048
3049 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3050 test_true(servers);
3051 test_compare(1U, memcached_server_list_count(servers));
3052
3053 for (uint32_t x= 2; x < 20; x++)
3054 {
3055 char buffer[SMALL_STRING_LEN];
3056
3057 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
3058 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3059 &rc);
3060 test_compare(MEMCACHED_SUCCESS, rc);
3061 test_compare(x, memcached_server_list_count(servers));
3062 }
3063
3064 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
3065 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
3066
3067 memcached_server_list_free(servers);
3068
3069 return TEST_SUCCESS;
3070 }
3071
3072
3073 static void my_free(const memcached_st *ptr, void *mem, void *context)
3074 {
3075 (void)context;
3076 (void)ptr;
3077 #ifdef HARD_MALLOC_TESTS
3078 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3079 free(real_ptr);
3080 #else
3081 free(mem);
3082 #endif
3083 }
3084
3085
3086 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
3087 {
3088 (void)context;
3089 (void)ptr;
3090 #ifdef HARD_MALLOC_TESTS
3091 void *ret= malloc(size + 8);
3092 if (ret != NULL)
3093 {
3094 ret= (void*)((caddr_t)ret + 8);
3095 }
3096 #else
3097 void *ret= malloc(size);
3098 #endif
3099
3100 if (ret != NULL)
3101 {
3102 memset(ret, 0xff, size);
3103 }
3104
3105 return ret;
3106 }
3107
3108
3109 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
3110 {
3111 #ifdef HARD_MALLOC_TESTS
3112 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3113 void *nmem= realloc(real_ptr, size + 8);
3114
3115 void *ret= NULL;
3116 if (nmem != NULL)
3117 {
3118 ret= (void*)((caddr_t)nmem + 8);
3119 }
3120
3121 return ret;
3122 #else
3123 (void)ptr;
3124 return realloc(mem, size);
3125 #endif
3126 }
3127
3128
3129 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
3130 {
3131 #ifdef HARD_MALLOC_TESTS
3132 void *mem= my_malloc(ptr, nelem * size);
3133 if (mem)
3134 {
3135 memset(mem, 0, nelem * size);
3136 }
3137
3138 return mem;
3139 #else
3140 (void)ptr;
3141 return calloc(nelem, size);
3142 #endif
3143 }
3144
3145 test_return_t selection_of_namespace_tests(memcached_st *memc)
3146 {
3147 memcached_return_t rc;
3148 const char *key= "mine";
3149 char *value;
3150
3151 /* Make sure be default none exists */
3152 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3153 test_null(value);
3154 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3155
3156 /* Test a clean set */
3157 test_compare(MEMCACHED_SUCCESS,
3158 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3159
3160 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3161 test_true(value);
3162 test_memcmp(value, key, 4);
3163 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3164
3165 /* Test that we can turn it off */
3166 test_compare(MEMCACHED_SUCCESS,
3167 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
3168
3169 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3170 test_null(value);
3171 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3172
3173 /* Now setup for main test */
3174 test_compare(MEMCACHED_SUCCESS,
3175 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3176
3177 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3178 test_true(value);
3179 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3180 test_memcmp(value, key, 4);
3181
3182 /* Set to Zero, and then Set to something too large */
3183 {
3184 char long_key[255];
3185 memset(long_key, 0, 255);
3186
3187 test_compare(MEMCACHED_SUCCESS,
3188 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
3189
3190 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3191 test_null(value);
3192 test_compare(MEMCACHED_SUCCESS, rc);
3193
3194 /* Test a long key for failure */
3195 /* TODO, extend test to determine based on setting, what result should be */
3196 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
3197 test_compare(MEMCACHED_SUCCESS,
3198 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3199
3200 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3201 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
3202 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3203 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3204
3205 /* Test for a bad prefix, but with a short key */
3206 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
3207 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
3208
3209 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3210 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "dog cat"));
3211 }
3212
3213 return TEST_SUCCESS;
3214 }
3215
3216 test_return_t set_namespace(memcached_st *memc)
3217 {
3218 memcached_return_t rc;
3219 const char *key= "mine";
3220 char *value;
3221
3222 // Make sure we default to a null namespace
3223 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3224 test_null(value);
3225 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3226
3227 /* Test a clean set */
3228 test_compare(MEMCACHED_SUCCESS,
3229 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3230
3231 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3232 test_true(value);
3233 test_memcmp(value, key, 4);
3234 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3235
3236 return TEST_SUCCESS;
3237 }
3238
3239 test_return_t set_namespace_and_binary(memcached_st *memc)
3240 {
3241 test_return_if(pre_binary(memc));
3242 test_return_if(set_namespace(memc));
3243
3244 return TEST_SUCCESS;
3245 }
3246
3247 #ifdef MEMCACHED_ENABLE_DEPRECATED
3248 test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3249 {
3250 void *test_ptr= NULL;
3251 void *cb_ptr= NULL;
3252 {
3253 memcached_malloc_fn malloc_cb= (memcached_malloc_fn)my_malloc;
3254 cb_ptr= *(void **)&malloc_cb;
3255 memcached_return_t rc;
3256
3257 test_compare(MEMCACHED_SUCCESS,
3258 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
3259 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3260 test_compare(MEMCACHED_SUCCESS, rc);
3261 test_true(test_ptr == cb_ptr);
3262 }
3263
3264 {
3265 memcached_realloc_fn realloc_cb=
3266 (memcached_realloc_fn)my_realloc;
3267 cb_ptr= *(void **)&realloc_cb;
3268 memcached_return_t rc;
3269
3270 test_compare(MEMCACHED_SUCCESS,
3271 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
3272 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3273 test_compare(MEMCACHED_SUCCESS, rc);
3274 test_true(test_ptr == cb_ptr);
3275 }
3276
3277 {
3278 memcached_free_fn free_cb=
3279 (memcached_free_fn)my_free;
3280 cb_ptr= *(void **)&free_cb;
3281 memcached_return_t rc;
3282
3283 test_compare(MEMCACHED_SUCCESS,
3284 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
3285 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3286 test_compare(MEMCACHED_SUCCESS, rc);
3287 test_true(test_ptr == cb_ptr);
3288 }
3289
3290 return TEST_SUCCESS;
3291 }
3292 #endif
3293
3294
3295 test_return_t set_memory_alloc(memcached_st *memc)
3296 {
3297 test_compare(MEMCACHED_INVALID_ARGUMENTS,
3298 memcached_set_memory_allocators(memc, NULL, my_free,
3299 my_realloc, my_calloc, NULL));
3300
3301 test_compare(MEMCACHED_SUCCESS,
3302 memcached_set_memory_allocators(memc, my_malloc, my_free,
3303 my_realloc, my_calloc, NULL));
3304
3305 memcached_malloc_fn mem_malloc;
3306 memcached_free_fn mem_free;
3307 memcached_realloc_fn mem_realloc;
3308 memcached_calloc_fn mem_calloc;
3309 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3310 &mem_realloc, &mem_calloc);
3311
3312 test_true(mem_malloc == my_malloc);
3313 test_true(mem_realloc == my_realloc);
3314 test_true(mem_calloc == my_calloc);
3315 test_true(mem_free == my_free);
3316
3317 return TEST_SUCCESS;
3318 }
3319
3320 test_return_t enable_consistent_crc(memcached_st *memc)
3321 {
3322 test_return_t rc;
3323 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3324 memcached_hash_t hash;
3325 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3326 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3327 return rc;
3328
3329 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3330 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3331
3332 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3333
3334 if (hash != MEMCACHED_HASH_CRC)
3335 return TEST_SKIPPED;
3336
3337 return TEST_SUCCESS;
3338 }
3339
3340 test_return_t enable_consistent_hsieh(memcached_st *memc)
3341 {
3342 test_return_t rc;
3343 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3344 memcached_hash_t hash;
3345 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3346 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3347 {
3348 return rc;
3349 }
3350
3351 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3352 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3353
3354 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3355
3356 if (hash != MEMCACHED_HASH_HSIEH)
3357 return TEST_SKIPPED;
3358
3359
3360 return TEST_SUCCESS;
3361 }
3362
3363 test_return_t enable_cas(memcached_st *memc)
3364 {
3365 unsigned int set= 1;
3366
3367 if (libmemcached_util_version_check(memc, 1, 2, 4))
3368 {
3369 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3370
3371 return TEST_SUCCESS;
3372 }
3373
3374 return TEST_SKIPPED;
3375 }
3376
3377 test_return_t check_for_1_2_3(memcached_st *memc)
3378 {
3379 memcached_version(memc);
3380
3381 memcached_server_instance_st instance=
3382 memcached_server_instance_by_position(memc, 0);
3383
3384 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3385 or instance->minor_version > 2)
3386 {
3387 return TEST_SUCCESS;
3388 }
3389
3390 return TEST_SKIPPED;
3391 }
3392
3393 test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc)
3394 {
3395 const uint64_t timeout= 100; // Not using, just checking that it sets
3396
3397 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3398
3399 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
3400
3401 return TEST_SUCCESS;
3402 }
3403
3404 test_return_t noreply_test(memcached_st *memc)
3405 {
3406 test_compare(MEMCACHED_SUCCESS,
3407 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
3408 test_compare(MEMCACHED_SUCCESS,
3409 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3410 test_compare(MEMCACHED_SUCCESS,
3411 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
3412 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
3413 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
3414 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS));
3415
3416 memcached_return_t ret;
3417 for (int count= 0; count < 5; ++count)
3418 {
3419 for (size_t x= 0; x < 100; ++x)
3420 {
3421 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
3422 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3423 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3424
3425 size_t len= (size_t)check_length;
3426
3427 switch (count)
3428 {
3429 case 0:
3430 ret= memcached_add(memc, key, len, key, len, 0, 0);
3431 break;
3432 case 1:
3433 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3434 break;
3435 case 2:
3436 ret= memcached_set(memc, key, len, key, len, 0, 0);
3437 break;
3438 case 3:
3439 ret= memcached_append(memc, key, len, key, len, 0, 0);
3440 break;
3441 case 4:
3442 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3443 break;
3444 default:
3445 test_true(count);
3446 break;
3447 }
3448 test_true_got(ret == MEMCACHED_SUCCESS or ret == MEMCACHED_BUFFERED,
3449 memcached_strerror(NULL, ret));
3450 }
3451
3452 /*
3453 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3454 ** API and is _ONLY_ done this way to verify that the library works the
3455 ** way it is supposed to do!!!!
3456 */
3457 #if 0
3458 int no_msg=0;
3459 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
3460 {
3461 memcached_server_instance_st instance=
3462 memcached_server_instance_by_position(memc, x);
3463 no_msg+=(int)(instance->cursor_active);
3464 }
3465
3466 test_true(no_msg == 0);
3467 #endif
3468 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
3469
3470 /*
3471 ** Now validate that all items was set properly!
3472 */
3473 for (size_t x= 0; x < 100; ++x)
3474 {
3475 char key[10];
3476
3477 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3478
3479 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3480
3481 size_t len= (size_t)check_length;
3482 size_t length;
3483 uint32_t flags;
3484 char* value=memcached_get(memc, key, strlen(key),
3485 &length, &flags, &ret);
3486 test_true_got(ret == MEMCACHED_SUCCESS && value != NULL, memcached_strerror(NULL, ret));
3487 switch (count)
3488 {
3489 case 0: /* FALLTHROUGH */
3490 case 1: /* FALLTHROUGH */
3491 case 2:
3492 test_true(strncmp(value, key, len) == 0);
3493 test_true(len == length);
3494 break;
3495 case 3:
3496 test_true(length == len * 2);
3497 break;
3498 case 4:
3499 test_true(length == len * 3);
3500 break;
3501 default:
3502 test_true(count);
3503 break;
3504 }
3505 free(value);
3506 }
3507 }
3508
3509 /* Try setting an illegal cas value (should not return an error to
3510 * the caller (because we don't expect a return message from the server)
3511 */
3512 const char* keys[]= {"0"};
3513 size_t lengths[]= {1};
3514 size_t length;
3515 uint32_t flags;
3516 memcached_result_st results_obj;
3517 memcached_result_st *results;
3518 test_compare(MEMCACHED_SUCCESS,
3519 memcached_mget(memc, keys, lengths, 1));
3520
3521 results= memcached_result_create(memc, &results_obj);
3522 test_true(results);
3523 results= memcached_fetch_result(memc, &results_obj, &ret);
3524 test_true(results);
3525 test_compare(MEMCACHED_SUCCESS, ret);
3526 uint64_t cas= memcached_result_cas(results);
3527 memcached_result_free(&results_obj);
3528
3529 test_compare(MEMCACHED_SUCCESS,
3530 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3531
3532 /*
3533 * The item will have a new cas value, so try to set it again with the old
3534 * value. This should fail!
3535 */
3536 test_compare(MEMCACHED_SUCCESS,
3537 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3538 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3539 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3540 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
3541 free(value);
3542
3543 return TEST_SUCCESS;
3544 }
3545
3546 test_return_t analyzer_test(memcached_st *memc)
3547 {
3548 memcached_analysis_st *report;
3549 memcached_return_t rc;
3550
3551 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3552 test_compare(MEMCACHED_SUCCESS, rc);
3553 test_true(memc_stat);
3554
3555 report= memcached_analyze(memc, memc_stat, &rc);
3556 test_compare(MEMCACHED_SUCCESS, rc);
3557 test_true(report);
3558
3559 free(report);
3560 memcached_stat_free(NULL, memc_stat);
3561
3562 return TEST_SUCCESS;
3563 }
3564
3565 test_return_t util_version_test(memcached_st *memc)
3566 {
3567 test_compare_hint(MEMCACHED_SUCCESS, memcached_version(memc), memcached_last_error_message(memc));
3568 test_true(libmemcached_util_version_check(memc, 0, 0, 0));
3569
3570 bool if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
3571
3572 // We expect failure
3573 if (if_successful)
3574 {
3575 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3576 fprintf(stderr, "\nDumping Server Information\n\n");
3577 memcached_server_fn callbacks[1];
3578
3579 callbacks[0]= dump_server_information;
3580 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
3581 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3582 }
3583 test_true(if_successful == false);
3584
3585 memcached_server_instance_st instance=
3586 memcached_server_instance_by_position(memc, 0);
3587
3588 memcached_version(memc);
3589
3590 // We only use one binary when we test, so this should be just fine.
3591 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
3592 test_true(if_successful == true);
3593
3594 if (instance->micro_version > 0)
3595 {
3596 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
3597 }
3598 else if (instance->minor_version > 0)
3599 {
3600 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
3601 }
3602 else if (instance->major_version > 0)
3603 {
3604 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
3605 }
3606
3607 test_true(if_successful == true);
3608
3609 if (instance->micro_version > 0)
3610 {
3611 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
3612 }
3613 else if (instance->minor_version > 0)
3614 {
3615 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
3616 }
3617 else if (instance->major_version > 0)
3618 {
3619 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
3620 }
3621
3622 test_true(if_successful == false);
3623
3624 return TEST_SUCCESS;
3625 }
3626
3627 test_return_t getpid_connection_failure_test(memcached_st *memc)
3628 {
3629 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3630 memcached_return_t rc;
3631 memcached_server_instance_st instance=
3632 memcached_server_instance_by_position(memc, 0);
3633
3634 // Test both the version that returns a code, and the one that does not.
3635 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3636 memcached_server_port(instance) -1, NULL) == -1);
3637
3638 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3639 memcached_server_port(instance) -1, &rc) == -1);
3640 test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(memc, rc));
3641
3642 return TEST_SUCCESS;
3643 }
3644
3645
3646 test_return_t getpid_test(memcached_st *memc)
3647 {
3648 memcached_return_t rc;
3649 memcached_server_instance_st instance=
3650 memcached_server_instance_by_position(memc, 0);
3651
3652 // Test both the version that returns a code, and the one that does not.
3653 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3654 memcached_server_port(instance), NULL) > -1);
3655
3656 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3657 memcached_server_port(instance), &rc) > -1);
3658 test_compare(MEMCACHED_SUCCESS, rc);
3659
3660 return TEST_SUCCESS;
3661 }
3662
3663 test_return_t ping_test(memcached_st *memc)
3664 {
3665 memcached_return_t rc;
3666 memcached_server_instance_st instance=
3667 memcached_server_instance_by_position(memc, 0);
3668
3669 // Test both the version that returns a code, and the one that does not.
3670 test_true(libmemcached_util_ping(memcached_server_name(instance),
3671 memcached_server_port(instance), NULL));
3672
3673 test_true(libmemcached_util_ping(memcached_server_name(instance),
3674 memcached_server_port(instance), &rc));
3675
3676 test_compare(MEMCACHED_SUCCESS, rc);
3677
3678 return TEST_SUCCESS;
3679 }
3680
3681
3682 #if 0
3683 test_return_t hash_sanity_test (memcached_st *memc)
3684 {
3685 (void)memc;
3686
3687 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
3688 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
3689 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
3690 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
3691 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
3692 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
3693 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
3694 #ifdef HAVE_HSIEH_HASH
3695 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
3696 #endif
3697 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
3698 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
3699 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
3700
3701 return TEST_SUCCESS;
3702 }
3703 #endif
3704
3705 test_return_t hsieh_avaibility_test (memcached_st *memc)
3706 {
3707 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3708
3709 test_compare(MEMCACHED_SUCCESS,
3710 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
3711 (uint64_t)MEMCACHED_HASH_HSIEH));
3712
3713 return TEST_SUCCESS;
3714 }
3715
3716 test_return_t murmur_avaibility_test (memcached_st *memc)
3717 {
3718 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3719
3720 test_compare(MEMCACHED_SUCCESS,
3721 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
3722
3723 return TEST_SUCCESS;
3724 }
3725
3726 test_return_t one_at_a_time_run (memcached_st *)
3727 {
3728 uint32_t x;
3729 const char **ptr;
3730
3731 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3732 {
3733 test_compare(one_at_a_time_values[x],
3734 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT));
3735 }
3736
3737 return TEST_SUCCESS;
3738 }
3739
3740 test_return_t md5_run (memcached_st *)
3741 {
3742 uint32_t x;
3743 const char **ptr;
3744
3745 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3746 {
3747 test_compare(md5_values[x],
3748 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5));
3749 }
3750
3751 return TEST_SUCCESS;
3752 }
3753
3754 test_return_t crc_run (memcached_st *)
3755 {
3756 uint32_t x;
3757 const char **ptr;
3758
3759 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3760 {
3761 test_compare(crc_values[x],
3762 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC));
3763 }
3764
3765 return TEST_SUCCESS;
3766 }
3767
3768 test_return_t fnv1_64_run (memcached_st *)
3769 {
3770 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1_64));
3771
3772 uint32_t x;
3773 const char **ptr;
3774
3775 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3776 {
3777 test_compare(fnv1_64_values[x],
3778 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64));
3779 }
3780
3781 return TEST_SUCCESS;
3782 }
3783
3784 test_return_t fnv1a_64_run (memcached_st *)
3785 {
3786 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1A_64));
3787
3788 uint32_t x;
3789 const char **ptr;
3790
3791 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3792 {
3793 test_compare(fnv1a_64_values[x],
3794 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64));
3795 }
3796
3797 return TEST_SUCCESS;
3798 }
3799
3800 test_return_t fnv1_32_run (memcached_st *)
3801 {
3802 uint32_t x;
3803 const char **ptr;
3804
3805 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3806 {
3807 test_compare(fnv1_32_values[x],
3808 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32));
3809 }
3810
3811 return TEST_SUCCESS;
3812 }
3813
3814 test_return_t fnv1a_32_run (memcached_st *)
3815 {
3816 uint32_t x;
3817 const char **ptr;
3818
3819 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3820 {
3821 test_compare(fnv1a_32_values[x],
3822 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32));
3823 }
3824
3825 return TEST_SUCCESS;
3826 }
3827
3828 test_return_t hsieh_run (memcached_st *)
3829 {
3830 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3831
3832 uint32_t x;
3833 const char **ptr;
3834
3835 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3836 {
3837 test_compare(hsieh_values[x],
3838 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH));
3839 }
3840
3841 return TEST_SUCCESS;
3842 }
3843
3844 test_return_t murmur_run (memcached_st *)
3845 {
3846 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3847
3848 #ifdef WORDS_BIGENDIAN
3849 (void)murmur_values;
3850 return TEST_SKIPPED;
3851 #else
3852 uint32_t x;
3853 const char **ptr;
3854
3855 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3856 {
3857 test_compare(murmur_values[x],
3858 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR));
3859 }
3860
3861 return TEST_SUCCESS;
3862 #endif
3863 }
3864
3865 test_return_t jenkins_run (memcached_st *)
3866 {
3867 uint32_t x;
3868 const char **ptr;
3869
3870 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3871 {
3872 test_compare(jenkins_values[x],
3873 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS));
3874 }
3875
3876 return TEST_SUCCESS;
3877 }
3878
3879 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *)
3880 {
3881 return libhashkit_md5(string, string_length);
3882 }
3883
3884 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *)
3885 {
3886 return libhashkit_crc32(string, string_length);
3887 }
3888
3889 test_return_t memcached_get_hashkit_test (memcached_st *)
3890 {
3891 uint32_t x;
3892 const char **ptr;
3893 hashkit_st new_kit;
3894
3895 memcached_st *memc= memcached(test_literal_param("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5 --DISTRIBUTION=modula"));
3896
3897 uint32_t md5_hosts[]= {4U, 1U, 0U, 1U, 4U, 2U, 0U, 3U, 0U, 0U, 3U, 1U, 0U, 0U, 1U, 3U, 0U, 0U, 0U, 3U, 1U, 0U, 4U, 4U, 3U};
3898 uint32_t crc_hosts[]= {2U, 4U, 1U, 0U, 2U, 4U, 4U, 4U, 1U, 2U, 3U, 4U, 3U, 4U, 1U, 3U, 3U, 2U, 0U, 0U, 0U, 1U, 2U, 4U, 0U};
3899
3900 const hashkit_st *kit= memcached_get_hashkit(memc);
3901
3902 hashkit_clone(&new_kit, kit);
3903 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL));
3904
3905 memcached_set_hashkit(memc, &new_kit);
3906
3907 /*
3908 Verify Setting the hash.
3909 */
3910 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3911 {
3912 uint32_t hash_val;
3913
3914 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3915 test_compare_got(md5_values[x], hash_val, *ptr);
3916 }
3917
3918
3919 /*
3920 Now check memcached_st.
3921 */
3922 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3923 {
3924 uint32_t hash_val;
3925
3926 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3927 test_compare_got(md5_hosts[x], hash_val, *ptr);
3928 }
3929
3930 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL));
3931
3932 memcached_set_hashkit(memc, &new_kit);
3933
3934 /*
3935 Verify Setting the hash.
3936 */
3937 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3938 {
3939 uint32_t hash_val;
3940
3941 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3942 test_true(crc_values[x] == hash_val);
3943 }
3944
3945 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3946 {
3947 uint32_t hash_val;
3948
3949 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3950 test_compare(crc_hosts[x], hash_val);
3951 }
3952
3953 memcached_free(memc);
3954
3955 return TEST_SUCCESS;
3956 }
3957
3958 /*
3959 Test case adapted from John Gorman <johngorman2@gmail.com>
3960
3961 We are testing the error condition when we connect to a server via memcached_get()
3962 but find that the server is not available.
3963 */
3964 test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
3965 {
3966 size_t len;
3967 uint32_t flags;
3968 memcached_return rc;
3969
3970 // Create a handle.
3971 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
3972
3973 // See if memcached is reachable.
3974 char *value= memcached_get(tl_memc_h,
3975 test_literal_param(__func__),
3976 &len, &flags, &rc);
3977
3978 test_false(value);
3979 test_zero(len);
3980 test_true(memcached_failed(rc));
3981
3982 memcached_free(tl_memc_h);
3983
3984 return TEST_SUCCESS;
3985 }
3986
3987 /*
3988 We connect to a server which exists, but search for a key that does not exist.
3989 */
3990 test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
3991 {
3992 size_t len;
3993 uint32_t flags;
3994 memcached_return rc;
3995
3996 // See if memcached is reachable.
3997 char *value= memcached_get(memc,
3998 test_literal_param(__func__),
3999 &len, &flags, &rc);
4000
4001 test_false(value);
4002 test_zero(len);
4003 test_compare(MEMCACHED_NOTFOUND, rc);
4004
4005 return TEST_SUCCESS;
4006 }
4007
4008 /*
4009 Test case adapted from John Gorman <johngorman2@gmail.com>
4010
4011 We are testing the error condition when we connect to a server via memcached_get_by_key()
4012 but find that the server is not available.
4013 */
4014 test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *)
4015 {
4016 size_t len;
4017 uint32_t flags;
4018 memcached_return rc;
4019
4020 // Create a handle.
4021 memcached_st *tl_memc_h= memcached_create(NULL);
4022 memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4023 memcached_server_push(tl_memc_h, servers);
4024 memcached_server_list_free(servers);
4025
4026 // See if memcached is reachable.
4027 char *value= memcached_get_by_key(tl_memc_h,
4028 test_literal_param(__func__), // Key
4029 test_literal_param(__func__), // Value
4030 &len, &flags, &rc);
4031
4032 test_false(value);
4033 test_zero(len);
4034 test_true(memcached_failed(rc));
4035
4036 memcached_free(tl_memc_h);
4037
4038 return TEST_SUCCESS;
4039 }
4040
4041 /*
4042 We connect to a server which exists, but search for a key that does not exist.
4043 */
4044 test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
4045 {
4046 size_t len;
4047 uint32_t flags;
4048 memcached_return rc;
4049
4050 // See if memcached is reachable.
4051 char *value= memcached_get_by_key(memc,
4052 test_literal_param(__func__), // Key
4053 test_literal_param(__func__), // Value
4054 &len, &flags, &rc);
4055
4056 test_false(value);
4057 test_zero(len);
4058 test_compare(MEMCACHED_NOTFOUND, rc);
4059
4060 return TEST_SUCCESS;
4061 }
4062
4063 test_return_t regression_bug_434484(memcached_st *memc)
4064 {
4065 test_skip(TEST_SUCCESS, pre_binary(memc));
4066
4067 test_compare(MEMCACHED_NOTSTORED,
4068 memcached_append(memc,
4069 test_literal_param(__func__), // Key
4070 test_literal_param(__func__), // Value
4071 0, 0));
4072
4073 libtest::vchar_t data;
4074 data.resize(2048 * 1024);
4075 test_compare(MEMCACHED_E2BIG,
4076 memcached_set(memc,
4077 test_literal_param(__func__), // Key
4078 &data[0], data.size(), 0, 0));
4079
4080 return TEST_SUCCESS;
4081 }
4082
4083 test_return_t regression_bug_434843(memcached_st *original_memc)
4084 {
4085 test_skip(TEST_SUCCESS, pre_binary(original_memc));
4086
4087 memcached_return_t rc;
4088 size_t counter= 0;
4089 memcached_execute_fn callbacks[]= { &callback_counter };
4090
4091 /*
4092 * I only want to hit only _one_ server so I know the number of requests I'm
4093 * sending in the pipleine to the server. Let's try to do a multiget of
4094 * 1024 (that should satisfy most users don't you think?). Future versions
4095 * will include a mget_execute function call if you need a higher number.
4096 */
4097 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
4098
4099 keys_st keys(1024);
4100
4101 /*
4102 * Run two times.. the first time we should have 100% cache miss,
4103 * and the second time we should have 100% cache hits
4104 */
4105 for (ptrdiff_t y= 0; y < 2; y++)
4106 {
4107 test_compare(MEMCACHED_SUCCESS,
4108 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4109
4110 // One the first run we should get a NOT_FOUND, but on the second some data
4111 // should be returned.
4112 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
4113 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4114
4115 if (y == 0)
4116 {
4117 /* The first iteration should give me a 100% cache miss. verify that*/
4118 char blob[1024]= { 0 };
4119
4120 test_false(counter);
4121
4122 for (size_t x= 0; x < keys.size(); ++x)
4123 {
4124 rc= memcached_add(memc,
4125 keys.key_at(x), keys.length_at(x),
4126 blob, sizeof(blob), 0, 0);
4127 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4128 }
4129 }
4130 else
4131 {
4132 /* Verify that we received all of the key/value pairs */
4133 test_compare(counter, keys.size());
4134 }
4135 }
4136
4137 memcached_free(memc);
4138
4139 return TEST_SUCCESS;
4140 }
4141
4142 test_return_t regression_bug_434843_buffered(memcached_st *memc)
4143 {
4144 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
4145
4146 return regression_bug_434843(memc);
4147 }
4148
4149 test_return_t regression_bug_421108(memcached_st *memc)
4150 {
4151 memcached_return_t rc;
4152 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
4153 test_compare(MEMCACHED_SUCCESS, rc);
4154
4155 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
4156 test_compare(MEMCACHED_SUCCESS, rc);
4157 test_true(bytes_str);
4158 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
4159 "bytes_read", &rc);
4160 test_compare(MEMCACHED_SUCCESS, rc);
4161 test_true(bytes_read_str);
4162
4163 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
4164 "bytes_written", &rc);
4165 test_compare(MEMCACHED_SUCCESS, rc);
4166 test_true(bytes_written_str);
4167
4168 unsigned long long bytes= strtoull(bytes_str, 0, 10);
4169 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
4170 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
4171
4172 test_true(bytes != bytes_read);
4173 test_true(bytes != bytes_written);
4174
4175 /* Release allocated resources */
4176 free(bytes_str);
4177 free(bytes_read_str);
4178 free(bytes_written_str);
4179 memcached_stat_free(NULL, memc_stat);
4180
4181 return TEST_SUCCESS;
4182 }
4183
4184 /*
4185 * The test case isn't obvious so I should probably document why
4186 * it works the way it does. Bug 442914 was caused by a bug
4187 * in the logic in memcached_purge (it did not handle the case
4188 * where the number of bytes sent was equal to the watermark).
4189 * In this test case, create messages so that we hit that case
4190 * and then disable noreply mode and issue a new command to
4191 * verify that it isn't stuck. If we change the format for the
4192 * delete command or the watermarks, we need to update this
4193 * test....
4194 */
4195 test_return_t regression_bug_442914(memcached_st *original_memc)
4196 {
4197 test_skip(original_memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
4198
4199 memcached_st* memc= create_single_instance_memcached(original_memc, "--NOREPLY --TCP-NODELAY");
4200
4201 for (uint32_t x= 0; x < 250; ++x)
4202 {
4203 char key[250];
4204 size_t len= (size_t)snprintf(key, sizeof(key), "%0250u", x);
4205 memcached_return_t rc= memcached_delete(memc, key, len, 0);
4206 char error_buffer[2048]= { 0 };
4207 snprintf(error_buffer, sizeof(error_buffer), "%s key: %s", memcached_last_error_message(memc), key);
4208 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, error_buffer);
4209 }
4210
4211 // Delete, and then delete again to look for not found
4212 {
4213 char key[250];
4214 size_t len= snprintf(key, sizeof(key), "%037u", 251U);
4215 memcached_return_t rc= memcached_delete(memc, key, len, 0);
4216 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
4217
4218 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, false));
4219 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, key, len, 0));
4220 }
4221
4222 memcached_free(memc);
4223
4224 return TEST_SUCCESS;
4225 }
4226
4227 test_return_t regression_bug_447342(memcached_st *memc)
4228 {
4229 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
4230 {
4231 return TEST_SKIPPED;
4232 }
4233
4234 test_compare(MEMCACHED_SUCCESS,
4235 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
4236
4237 keys_st keys(100);
4238
4239 for (size_t x= 0; x < keys.size(); ++x)
4240 {
4241 test_compare(MEMCACHED_SUCCESS,
4242 memcached_set(memc,
4243 keys.key_at(x), keys.length_at(x), // Keys
4244 keys.key_at(x), keys.length_at(x), // Values
4245 0, 0));
4246 }
4247
4248 /*
4249 ** We are using the quiet commands to store the replicas, so we need
4250 ** to ensure that all of them are processed before we can continue.
4251 ** In the test we go directly from storing the object to trying to
4252 ** receive the object from all of the different servers, so we
4253 ** could end up in a race condition (the memcached server hasn't yet
4254 ** processed the quiet command from the replication set when it process
4255 ** the request from the other client (created by the clone)). As a
4256 ** workaround for that we call memcached_quit to send the quit command
4257 ** to the server and wait for the response ;-) If you use the test code
4258 ** as an example for your own code, please note that you shouldn't need
4259 ** to do this ;-)
4260 */
4261 memcached_quit(memc);
4262
4263 /* Verify that all messages are stored, and we didn't stuff too much
4264 * into the servers
4265 */
4266 test_compare(MEMCACHED_SUCCESS,
4267 memcached_mget(memc,
4268 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4269
4270 unsigned int counter= 0;
4271 memcached_execute_fn callbacks[]= { &callback_counter };
4272 test_compare(MEMCACHED_SUCCESS,
4273 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4274
4275 /* Verify that we received all of the key/value pairs */
4276 test_compare(counter, keys.size());
4277
4278 memcached_quit(memc);
4279 /*
4280 * Don't do the following in your code. I am abusing the internal details
4281 * within the library, and this is not a supported interface.
4282 * This is to verify correct behavior in the library. Fake that two servers
4283 * are dead..
4284 */
4285 memcached_server_instance_st instance_one= memcached_server_instance_by_position(memc, 0);
4286 memcached_server_instance_st instance_two= memcached_server_instance_by_position(memc, 2);
4287 in_port_t port0= instance_one->port;
4288 in_port_t port2= instance_two->port;
4289
4290 ((memcached_server_write_instance_st)instance_one)->port= 0;
4291 ((memcached_server_write_instance_st)instance_two)->port= 0;
4292
4293 test_compare(MEMCACHED_SUCCESS,
4294 memcached_mget(memc,
4295 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4296
4297 counter= 0;
4298 test_compare(MEMCACHED_SUCCESS,
4299 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4300 test_compare(counter, keys.size());
4301
4302 /* restore the memc handle */
4303 ((memcached_server_write_instance_st)instance_one)->port= port0;
4304 ((memcached_server_write_instance_st)instance_two)->port= port2;
4305
4306 memcached_quit(memc);
4307
4308 /* Remove half of the objects */
4309 for (size_t x= 0; x < keys.size(); ++x)
4310 {
4311 if (x & 1)
4312 {
4313 test_compare(MEMCACHED_SUCCESS,
4314 memcached_delete(memc, keys.key_at(x), keys.length_at(x), 0));
4315 }
4316 }
4317
4318 memcached_quit(memc);
4319 ((memcached_server_write_instance_st)instance_one)->port= 0;
4320 ((memcached_server_write_instance_st)instance_two)->port= 0;
4321
4322 /* now retry the command, this time we should have cache misses */
4323 test_compare(MEMCACHED_SUCCESS,
4324 memcached_mget(memc,
4325 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4326
4327 counter= 0;
4328 test_compare(MEMCACHED_SUCCESS,
4329 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4330 test_compare(counter, (unsigned int)(keys.size() >> 1));
4331
4332 /* restore the memc handle */
4333 ((memcached_server_write_instance_st)instance_one)->port= port0;
4334 ((memcached_server_write_instance_st)instance_two)->port= port2;
4335
4336 return TEST_SUCCESS;
4337 }
4338
4339 test_return_t regression_bug_463297(memcached_st *memc)
4340 {
4341 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc, "foo", 3, 1));
4342
4343 // Since we blocked timed delete, this test is no longer valid.
4344 #if 0
4345 memcached_st *memc_clone= memcached_clone(NULL, memc);
4346 test_true(memc_clone);
4347 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
4348
4349 memcached_server_instance_st instance=
4350 memcached_server_instance_by_position(memc_clone, 0);
4351
4352 if (instance->major_version > 1 ||
4353 (instance->major_version == 1 &&
4354 instance->minor_version > 2))
4355 {
4356 /* Binary protocol doesn't support deferred delete */
4357 memcached_st *bin_clone= memcached_clone(NULL, memc);
4358 test_true(bin_clone);
4359 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4360 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
4361 memcached_free(bin_clone);
4362
4363 memcached_quit(memc_clone);
4364
4365 /* If we know the server version, deferred delete should fail
4366 * with invalid arguments */
4367 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
4368
4369 /* If we don't know the server version, we should get a protocol error */
4370 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
4371
4372 /* but there is a bug in some of the memcached servers (1.4) that treats
4373 * the counter as noreply so it doesn't send the proper error message
4374 */
4375 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4376
4377 /* And buffered mode should be disabled and we should get protocol error */
4378 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
4379 rc= memcached_delete(memc, "foo", 3, 1);
4380 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4381
4382 /* Same goes for noreply... */
4383 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
4384 rc= memcached_delete(memc, "foo", 3, 1);
4385 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4386
4387 /* but a normal request should go through (and be buffered) */
4388 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
4389 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
4390
4391 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
4392 /* unbuffered noreply should be success */
4393 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
4394 /* unbuffered with reply should be not found... */
4395 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
4396 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
4397 }
4398
4399 memcached_free(memc_clone);
4400 #endif
4401
4402 return TEST_SUCCESS;
4403 }
4404
4405
4406 /* Test memcached_server_get_last_disconnect
4407 * For a working server set, shall be NULL
4408 * For a set of non existing server, shall not be NULL
4409 */
4410 test_return_t test_get_last_disconnect(memcached_st *memc)
4411 {
4412 memcached_return_t rc;
4413 memcached_server_instance_st disconnected_server;
4414
4415 /* With the working set of server */
4416 const char *key= "marmotte";
4417 const char *value= "milka";
4418
4419 memcached_reset_last_disconnected_server(memc);
4420 test_false(memc->last_disconnected_server);
4421 rc= memcached_set(memc, key, strlen(key),
4422 value, strlen(value),
4423 (time_t)0, (uint32_t)0);
4424 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4425
4426 disconnected_server = memcached_server_get_last_disconnect(memc);
4427 test_false(disconnected_server);
4428
4429 /* With a non existing server */
4430 memcached_st *mine;
4431 memcached_server_st *servers;
4432
4433 const char *server_list= "localhost:9";
4434
4435 servers= memcached_servers_parse(server_list);
4436 test_true(servers);
4437 mine= memcached_create(NULL);
4438 rc= memcached_server_push(mine, servers);
4439 test_compare(MEMCACHED_SUCCESS, rc);
4440 memcached_server_list_free(servers);
4441 test_true(mine);
4442
4443 rc= memcached_set(mine, key, strlen(key),
4444 value, strlen(value),
4445 (time_t)0, (uint32_t)0);
4446 test_true(memcached_failed(rc));
4447
4448 disconnected_server= memcached_server_get_last_disconnect(mine);
4449 test_true_got(disconnected_server, memcached_strerror(mine, rc));
4450 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
4451 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
4452
4453 memcached_quit(mine);
4454 memcached_free(mine);
4455
4456 return TEST_SUCCESS;
4457 }
4458
4459 test_return_t test_multiple_get_last_disconnect(memcached_st *)
4460 {
4461 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
4462 char buffer[BUFSIZ];
4463
4464 test_compare(MEMCACHED_SUCCESS,
4465 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
4466
4467 memcached_st *memc= memcached(server_string, strlen(server_string));
4468 test_true(memc);
4469
4470 // We will just use the error strings as our keys
4471 uint32_t counter= 100;
4472 while (--counter)
4473 {
4474 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
4475 {
4476 const char *msg= memcached_strerror(memc, memcached_return_t(x));
4477 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
4478 test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
4479
4480 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
4481 test_true(disconnected_server);
4482 test_strcmp("localhost", memcached_server_name(disconnected_server));
4483 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
4484
4485 if (random() % 2)
4486 {
4487 memcached_reset_last_disconnected_server(memc);
4488 }
4489 }
4490 }
4491
4492 memcached_free(memc);
4493
4494 return TEST_SUCCESS;
4495 }
4496
4497 test_return_t test_verbosity(memcached_st *memc)
4498 {
4499 memcached_verbosity(memc, 3);
4500
4501 return TEST_SUCCESS;
4502 }
4503
4504
4505 static memcached_return_t stat_printer(memcached_server_instance_st server,
4506 const char *key, size_t key_length,
4507 const char *value, size_t value_length,
4508 void *context)
4509 {
4510 (void)server;
4511 (void)context;
4512 (void)key;
4513 (void)key_length;
4514 (void)value;
4515 (void)value_length;
4516
4517 return MEMCACHED_SUCCESS;
4518 }
4519
4520 test_return_t memcached_stat_execute_test(memcached_st *memc)
4521 {
4522 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
4523 test_compare(MEMCACHED_SUCCESS, rc);
4524
4525 test_compare(MEMCACHED_SUCCESS,
4526 memcached_stat_execute(memc, "slabs", stat_printer, NULL));
4527
4528 test_compare(MEMCACHED_SUCCESS,
4529 memcached_stat_execute(memc, "items", stat_printer, NULL));
4530
4531 test_compare(MEMCACHED_SUCCESS,
4532 memcached_stat_execute(memc, "sizes", stat_printer, NULL));
4533
4534 return TEST_SUCCESS;
4535 }
4536
4537 /*
4538 * This test ensures that the failure counter isn't incremented during
4539 * normal termination of the memcached instance.
4540 */
4541 test_return_t wrong_failure_counter_test(memcached_st *original_memc)
4542 {
4543 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4544
4545 /* Ensure that we are connected to the server by setting a value */
4546 memcached_return_t rc= memcached_set(memc,
4547 test_literal_param(__func__), // Key
4548 test_literal_param(__func__), // Value
4549 time_t(0), uint32_t(0));
4550 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
4551
4552
4553 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4554
4555 /* The test is to see that the memcached_quit doesn't increase the
4556 * the server failure conter, so let's ensure that it is zero
4557 * before sending quit
4558 */
4559 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
4560
4561 memcached_quit(memc);
4562
4563 /* Verify that it memcached_quit didn't increment the failure counter
4564 * Please note that this isn't bullet proof, because an error could
4565 * occur...
4566 */
4567 test_zero(instance->server_failure_counter);
4568
4569 memcached_free(memc);
4570
4571 return TEST_SUCCESS;
4572 }
4573
4574 /*
4575 * This tests ensures expected disconnections (for some behavior changes
4576 * for instance) do not wrongly increase failure counter
4577 */
4578 test_return_t wrong_failure_counter_two_test(memcached_st *memc)
4579 {
4580 /* Set value to force connection to the server */
4581 const char *key= "marmotte";
4582 const char *value= "milka";
4583
4584 test_compare_hint(MEMCACHED_SUCCESS,
4585 memcached_set(memc, key, strlen(key),
4586 value, strlen(value),
4587 (time_t)0, (uint32_t)0),
4588 memcached_last_error_message(memc));
4589
4590
4591 /* put failure limit to 1 */
4592 test_compare(MEMCACHED_SUCCESS,
4593 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, true));
4594
4595 /* Put a retry timeout to effectively activate failure_limit effect */
4596 test_compare(MEMCACHED_SUCCESS,
4597 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, true));
4598
4599 /* change behavior that triggers memcached_quit()*/
4600 test_compare(MEMCACHED_SUCCESS,
4601 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true));
4602
4603
4604 /* Check if we still are connected */
4605 uint32_t flags;
4606 size_t string_length;
4607 memcached_return rc;
4608 char *string= memcached_get(memc, key, strlen(key),
4609 &string_length, &flags, &rc);
4610
4611 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
4612 test_true(string);
4613 free(string);
4614
4615 return TEST_SUCCESS;
4616 }
4617
4618
4619 /*
4620 * Test that ensures mget_execute does not end into recursive calls that finally fails
4621 */
4622 test_return_t regression_bug_490486(memcached_st *original_memc)
4623 {
4624
4625 #ifdef __APPLE__
4626 return TEST_SKIPPED; // My MAC can't handle this test
4627 #endif
4628
4629 test_skip(TEST_SUCCESS, pre_binary(original_memc));
4630
4631 /*
4632 * I only want to hit _one_ server so I know the number of requests I'm
4633 * sending in the pipeline.
4634 */
4635 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL --POLL-TIMEOUT=1000 --REMOVE-FAILED-SERVERS=1 --RETRY-TIMEOUT=3600");
4636 test_true(memc);
4637
4638 keys_st keys(20480);
4639
4640 /* First add all of the items.. */
4641 char blob[1024]= { 0 };
4642 for (size_t x= 0; x < keys.size(); ++x)
4643 {
4644 memcached_return rc= memcached_set(memc,
4645 keys.key_at(x), keys.length_at(x),
4646 blob, sizeof(blob), 0, 0);
4647 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
4648 }
4649
4650 {
4651
4652 /* Try to get all of them with a large multiget */
4653 size_t counter= 0;
4654 memcached_execute_function callbacks[]= { &callback_counter };
4655 memcached_return_t rc= memcached_mget_execute(memc,
4656 keys.keys_ptr(), keys.lengths_ptr(), keys.size(),
4657 callbacks, &counter, 1);
4658 test_compare(MEMCACHED_SUCCESS, rc);
4659
4660 char* the_value= NULL;
4661 char the_key[MEMCACHED_MAX_KEY];
4662 size_t the_key_length;
4663 size_t the_value_length;
4664 uint32_t the_flags;
4665
4666 do {
4667 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
4668
4669 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
4670 {
4671 ++counter;
4672 free(the_value);
4673 }
4674
4675 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
4676
4677
4678 test_compare(MEMCACHED_END, rc);
4679
4680 /* Verify that we got all of the items */
4681 test_compare(counter, keys.size());
4682 }
4683
4684 memcached_free(memc);
4685
4686 return TEST_SUCCESS;
4687 }
4688
4689 test_return_t regression_bug_583031(memcached_st *)
4690 {
4691 memcached_st *memc= memcached_create(NULL);
4692 test_true(memc);
4693 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
4694
4695 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
4696 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
4697 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4698 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4699 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4700 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
4701
4702 memcached_return_t rc;
4703 size_t length;
4704 uint32_t flags;
4705
4706 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
4707 test_false(value);
4708 test_zero(length);
4709
4710 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
4711
4712 memcached_free(memc);
4713
4714 return TEST_SUCCESS;
4715 }
4716
4717 test_return_t regression_bug_581030(memcached_st *)
4718 {
4719 #ifndef DEBUG
4720 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
4721 test_false(local_stat);
4722
4723 memcached_stat_free(NULL, NULL);
4724 #endif
4725
4726 return TEST_SUCCESS;
4727 }
4728
4729 #define regression_bug_655423_COUNT 6000
4730 test_return_t regression_bug_655423(memcached_st *memc)
4731 {
4732 memcached_st *clone= memcached_clone(NULL, memc);
4733 memc= NULL; // Just to make sure it is not used
4734 test_true(clone);
4735 char payload[100];
4736
4737 #ifdef __APPLE__
4738 return TEST_SKIPPED;
4739 #endif
4740
4741 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4742 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
4743 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4744 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
4745
4746 memset(payload, int('x'), sizeof(payload));
4747
4748 keys_st keys(regression_bug_655423_COUNT);
4749
4750 for (size_t x= 0; x < keys.size(); x++)
4751 {
4752 test_compare(MEMCACHED_SUCCESS, memcached_set(clone,
4753 keys.key_at(x),
4754 keys.length_at(x),
4755 payload, sizeof(payload), 0, 0));
4756 }
4757
4758 for (size_t x= 0; x < keys.size(); x++)
4759 {
4760 size_t value_length;
4761 memcached_return_t rc;
4762 char *value= memcached_get(clone,
4763 keys.key_at(x),
4764 keys.length_at(x),
4765 &value_length, NULL, &rc);
4766
4767 if (rc == MEMCACHED_NOTFOUND)
4768 {
4769 test_false(value);
4770 test_zero(value_length);
4771 continue;
4772 }
4773
4774 test_compare(MEMCACHED_SUCCESS, rc);
4775 test_true(value);
4776 test_compare(100LLU, value_length);
4777 free(value);
4778 }
4779
4780 test_compare(MEMCACHED_SUCCESS,
4781 memcached_mget(clone,
4782 keys.keys_ptr(), keys.lengths_ptr(),
4783 keys.size()));
4784
4785 uint32_t count= 0;
4786 memcached_result_st *result= NULL;
4787 while ((result= memcached_fetch_result(clone, result, NULL)))
4788 {
4789 test_compare(size_t(100), memcached_result_length(result));
4790 count++;
4791 }
4792
4793 test_true(count > 100); // If we don't get back atleast this, something is up
4794
4795 memcached_free(clone);
4796
4797 return TEST_SUCCESS;
4798 }
4799
4800 /*
4801 * Test that ensures that buffered set to not trigger problems during io_flush
4802 */
4803 #define regression_bug_490520_COUNT 200480
4804 test_return_t regression_bug_490520(memcached_st *original_memc)
4805 {
4806 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4807
4808 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
4809 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
4810 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4811 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
4812 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
4813
4814 /* First add all of the items.. */
4815 char blob[3333] = {0};
4816 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
4817 {
4818 char key[251];
4819 int key_length= snprintf(key, sizeof(key), "0200%u", x);
4820
4821 memcached_return rc= memcached_set(memc, key, key_length, blob, sizeof(blob), 0, 0);
4822 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
4823 }
4824
4825 memcached_free(memc);
4826
4827 return TEST_SUCCESS;
4828 }
4829
4830
4831 test_return_t regression_bug_854604(memcached_st *)
4832 {
4833 char buffer[1024];
4834
4835 test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
4836
4837 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
4838
4839 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
4840 test_compare(buffer[0], 0);
4841
4842 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
4843 test_true(strlen(buffer));
4844
4845 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
4846 test_true(strlen(buffer));
4847
4848 return TEST_SUCCESS;
4849 }
4850
4851 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
4852 {
4853 fprintf(stderr, "Iteration #%u: ", it);
4854
4855 if (error == MEMCACHED_ERRNO)
4856 {
4857 fprintf(stderr, "system error %d from %s: %s\n",
4858 errno, what, strerror(errno));
4859 }
4860 else
4861 {
4862 fprintf(stderr, "error %d from %s: %s\n", error, what,
4863 memcached_strerror(mc, error));
4864 }
4865 }
4866
4867 #define TEST_CONSTANT_CREATION 200
4868
4869 test_return_t regression_bug_(memcached_st *memc)
4870 {
4871 const char *remote_server;
4872 (void)memc;
4873
4874 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
4875 {
4876 return TEST_SKIPPED;
4877 }
4878
4879 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
4880 {
4881 memcached_st* mc= memcached_create(NULL);
4882 memcached_return rc;
4883
4884 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
4885 if (rc != MEMCACHED_SUCCESS)
4886 {
4887 memcached_die(mc, rc, "memcached_behavior_set", x);
4888 }
4889
4890 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
4891 if (rc != MEMCACHED_SUCCESS)
4892 {
4893 memcached_die(mc, rc, "memcached_behavior_set", x);
4894 }
4895
4896 rc= memcached_server_add(mc, remote_server, 0);
4897 if (rc != MEMCACHED_SUCCESS)
4898 {
4899 memcached_die(mc, rc, "memcached_server_add", x);
4900 }
4901
4902 const char *set_key= "akey";
4903 const size_t set_key_len= strlen(set_key);
4904 const char *set_value= "a value";
4905 const size_t set_value_len= strlen(set_value);
4906
4907 if (rc == MEMCACHED_SUCCESS)
4908 {
4909 if (x > 0)
4910 {
4911 size_t get_value_len;
4912 char *get_value;
4913 uint32_t get_value_flags;
4914
4915 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
4916 &get_value_flags, &rc);
4917 if (rc != MEMCACHED_SUCCESS)
4918 {
4919 memcached_die(mc, rc, "memcached_get", x);
4920 }
4921 else
4922 {
4923
4924 if (x != 0 &&
4925 (get_value_len != set_value_len
4926 || 0!=strncmp(get_value, set_value, get_value_len)))
4927 {
4928 fprintf(stderr, "Values don't match?\n");
4929 rc= MEMCACHED_FAILURE;
4930 }
4931 free(get_value);
4932 }
4933 }
4934
4935 rc= memcached_set(mc,
4936 set_key, set_key_len,
4937 set_value, set_value_len,
4938 0, /* time */
4939 0 /* flags */
4940 );
4941 if (rc != MEMCACHED_SUCCESS)
4942 {
4943 memcached_die(mc, rc, "memcached_set", x);
4944 }
4945 }
4946
4947 memcached_quit(mc);
4948 memcached_free(mc);
4949
4950 if (rc != MEMCACHED_SUCCESS)
4951 {
4952 break;
4953 }
4954 }
4955
4956 return TEST_SUCCESS;
4957 }
4958
4959 test_return_t kill_HUP_TEST(memcached_st *original_memc)
4960 {
4961 memcached_st *memc= create_single_instance_memcached(original_memc, 0);
4962 test_true(memc);
4963
4964 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4965
4966 pid_t pid;
4967 test_true((pid= libmemcached_util_getpid(memcached_server_name(instance),
4968 memcached_server_port(instance), NULL)) > -1);
4969
4970
4971 test_compare(MEMCACHED_SUCCESS,
4972 memcached_set(memc,
4973 test_literal_param(__func__), // Keys
4974 test_literal_param(__func__), // Values
4975 0, 0));
4976 test_true_got(kill(pid, SIGHUP) == 0, strerror(errno));
4977
4978 test_compare(MEMCACHED_SUCCESS,
4979 memcached_set(memc,
4980 test_literal_param(__func__), // Keys
4981 test_literal_param(__func__), // Values
4982 0, 0));
4983
4984 memcached_free(memc);
4985
4986 return TEST_SUCCESS;
4987 }