Test cleanup
[awesomized/libmemcached] / tests / 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
39 /*
40 Sample test application.
41 */
42
43 #include "config.h"
44
45 #include <stdint.h>
46
47 #include <cassert>
48 #include <cstdio>
49 #include <cstdlib>
50 #include <cstring>
51 #include <ctime>
52 #include <memory>
53 #include <signal.h>
54 #include <sys/stat.h>
55 #include <sys/time.h>
56 #include <sys/types.h>
57 #include <unistd.h>
58
59 #include "libmemcached/common.h"
60
61 #include <libtest/server.h>
62
63 #include "clients/generator.h"
64 #include "clients/execute.h"
65
66 #define SMALL_STRING_LEN 1024
67
68 #include <libtest/test.h>
69 #include "tests/deprecated.h"
70 #include "tests/parser.h"
71 #include "tests/pool.h"
72 #include "tests/string.h"
73 #include "tests/replication.h"
74 #include "tests/basic.h"
75 #include "tests/error_conditions.h"
76 #include "tests/print.h"
77 #include "tests/virtual_buckets.h"
78
79
80 #ifdef HAVE_LIBMEMCACHEDUTIL
81 #include <pthread.h>
82 #include "libmemcached/memcached_util.h"
83 #endif
84
85 #include "hash_results.h"
86
87 #define GLOBAL_COUNT 10000
88 #define GLOBAL2_COUNT 100
89 #define SERVERS_TO_CREATE 5
90 static uint32_t global_count;
91
92 static pairs_st *global_pairs;
93 static const char *global_keys[GLOBAL_COUNT];
94 static size_t global_keys_length[GLOBAL_COUNT];
95
96 // Prototype
97 static test_return_t pre_binary(memcached_st *memc);
98
99
100 static test_return_t init_test(memcached_st *not_used)
101 {
102 memcached_st memc;
103 (void)not_used;
104
105 (void)memcached_create(&memc);
106 memcached_free(&memc);
107
108 return TEST_SUCCESS;
109 }
110
111 #define TEST_PORT_COUNT 7
112 in_port_t test_ports[TEST_PORT_COUNT];
113
114 static memcached_return_t server_display_function(const memcached_st *ptr,
115 const memcached_server_st *server,
116 void *context)
117 {
118 /* Do Nothing */
119 size_t bigger= *((size_t *)(context));
120 (void)ptr;
121 assert(bigger <= memcached_server_port(server));
122 *((size_t *)(context))= memcached_server_port(server);
123
124 return MEMCACHED_SUCCESS;
125 }
126
127 static memcached_return_t dump_server_information(const memcached_st *ptr,
128 const memcached_server_st *instance,
129 void *context)
130 {
131 /* Do Nothing */
132 FILE *stream= (FILE *)context;
133 (void)ptr;
134
135 fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n",
136 memcached_server_name(instance),
137 memcached_server_port(instance),
138 instance->major_version,
139 instance->minor_version,
140 instance->micro_version);
141
142 return MEMCACHED_SUCCESS;
143 }
144
145 static test_return_t server_sort_test(memcached_st *ptr)
146 {
147 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
148
149 memcached_return_t rc;
150 memcached_server_fn callbacks[1];
151 memcached_st *local_memc;
152 (void)ptr;
153
154 local_memc= memcached_create(NULL);
155 test_true(local_memc);
156 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
157
158 for (size_t x= 0; x < TEST_PORT_COUNT; x++)
159 {
160 test_ports[x]= (in_port_t)random() % 64000;
161 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
162 test_true(memcached_server_count(local_memc) == x + 1);
163 #if 0 // Rewrite
164 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
165 #endif
166 test_true(rc == MEMCACHED_SUCCESS);
167 }
168
169 callbacks[0]= server_display_function;
170 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
171
172
173 memcached_free(local_memc);
174
175 return TEST_SUCCESS;
176 }
177
178 static test_return_t server_sort2_test(memcached_st *ptr)
179 {
180 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
181 memcached_return_t rc;
182 memcached_server_fn callbacks[1];
183 memcached_st *local_memc;
184 memcached_server_instance_st instance;
185 (void)ptr;
186
187 local_memc= memcached_create(NULL);
188 test_true(local_memc);
189 rc= memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
190 test_true(rc == MEMCACHED_SUCCESS);
191
192 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0);
193 test_true(rc == MEMCACHED_SUCCESS);
194 instance= memcached_server_instance_by_position(local_memc, 0);
195 test_true(memcached_server_port(instance) == 43043);
196
197 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0);
198 test_true(rc == MEMCACHED_SUCCESS);
199
200 instance= memcached_server_instance_by_position(local_memc, 0);
201 test_true(memcached_server_port(instance) == 43042);
202
203 instance= memcached_server_instance_by_position(local_memc, 1);
204 test_true(memcached_server_port(instance) == 43043);
205
206 callbacks[0]= server_display_function;
207 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
208
209
210 memcached_free(local_memc);
211
212 return TEST_SUCCESS;
213 }
214
215 static test_return_t memcached_server_remove_test(memcached_st *ptr)
216 {
217 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";
218 (void)ptr;
219
220 memcached_st *memc= memcached(server_string, strlen(server_string));
221 test_true(memc);
222
223 memcached_server_fn callbacks[1];
224 callbacks[0]= server_print_callback;
225 memcached_server_cursor(memc, callbacks, NULL, 1);
226
227 memcached_free(memc);
228
229 return TEST_SUCCESS;
230 }
231
232 static memcached_return_t server_display_unsort_function(const memcached_st *ptr,
233 const memcached_server_st *server,
234 void *context)
235 {
236 /* Do Nothing */
237 uint32_t x= *((uint32_t *)(context));
238 (void)ptr;
239
240 if (! (test_ports[x] == server->port))
241 {
242 fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)server->port);
243 return MEMCACHED_FAILURE;
244 }
245
246 *((uint32_t *)(context))= ++x;
247
248 return MEMCACHED_SUCCESS;
249 }
250
251 static test_return_t server_unsort_test(memcached_st *ptr)
252 {
253 size_t counter= 0; /* Prime the value for the test_true in server_display_function */
254 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
255 memcached_return_t rc;
256 memcached_server_fn callbacks[1];
257 memcached_st *local_memc;
258 (void)ptr;
259
260 local_memc= memcached_create(NULL);
261 test_true(local_memc);
262
263 for (size_t x= 0; x < TEST_PORT_COUNT; x++)
264 {
265 test_ports[x]= (in_port_t)(random() % 64000);
266 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
267 test_true(memcached_server_count(local_memc) == x+1);
268 #if 0 // Rewrite
269 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
270 #endif
271 test_true(rc == MEMCACHED_SUCCESS);
272 }
273
274 callbacks[0]= server_display_unsort_function;
275 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
276
277 /* Now we sort old data! */
278 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
279 callbacks[0]= server_display_function;
280 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
281
282
283 memcached_free(local_memc);
284
285 return TEST_SUCCESS;
286 }
287
288 static test_return_t allocation_test(memcached_st *not_used)
289 {
290 (void)not_used;
291 memcached_st *memc;
292 memc= memcached_create(NULL);
293 test_true(memc);
294 memcached_free(memc);
295
296 return TEST_SUCCESS;
297 }
298
299 static test_return_t clone_test(memcached_st *memc)
300 {
301 /* All null? */
302 {
303 memcached_st *memc_clone;
304 memc_clone= memcached_clone(NULL, NULL);
305 test_true(memc_clone);
306 memcached_free(memc_clone);
307 }
308
309 /* Can we init from null? */
310 {
311 memcached_st *memc_clone;
312 memc_clone= memcached_clone(NULL, memc);
313 test_true(memc_clone);
314
315 { // Test allocators
316 test_true(memc_clone->allocators.free == memc->allocators.free);
317 test_true(memc_clone->allocators.malloc == memc->allocators.malloc);
318 test_true(memc_clone->allocators.realloc == memc->allocators.realloc);
319 test_true(memc_clone->allocators.calloc == memc->allocators.calloc);
320 }
321
322 test_true(memc_clone->connect_timeout == memc->connect_timeout);
323 test_true(memc_clone->delete_trigger == memc->delete_trigger);
324 test_true(memc_clone->distribution == memc->distribution);
325 { // Test all of the flags
326 test_true(memc_clone->flags.no_block == memc->flags.no_block);
327 test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
328 test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
329 test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
330 test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
331 test_true(memc_clone->flags.verify_key == memc->flags.verify_key);
332 test_true(memc_clone->ketama.weighted == memc->ketama.weighted);
333 test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
334 test_true(memc_clone->flags.hash_with_prefix_key == memc->flags.hash_with_prefix_key);
335 test_true(memc_clone->flags.no_reply == memc->flags.no_reply);
336 test_true(memc_clone->flags.use_udp == memc->flags.use_udp);
337 test_true(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
338 test_true(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
339 }
340 test_true(memc_clone->get_key_failure == memc->get_key_failure);
341 test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit));
342 test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
343 test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
344 test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
345 test_true(memc_clone->on_cleanup == memc->on_cleanup);
346 test_true(memc_clone->on_clone == memc->on_clone);
347 test_true(memc_clone->poll_timeout == memc->poll_timeout);
348 test_true(memc_clone->rcv_timeout == memc->rcv_timeout);
349 test_true(memc_clone->recv_size == memc->recv_size);
350 test_true(memc_clone->retry_timeout == memc->retry_timeout);
351 test_true(memc_clone->send_size == memc->send_size);
352 test_true(memc_clone->server_failure_limit == memc->server_failure_limit);
353 test_true(memc_clone->snd_timeout == memc->snd_timeout);
354 test_true(memc_clone->user_data == memc->user_data);
355
356 memcached_free(memc_clone);
357 }
358
359 /* Can we init from struct? */
360 {
361 memcached_st declared_clone;
362 memcached_st *memc_clone;
363 memset(&declared_clone, 0 , sizeof(memcached_st));
364 memc_clone= memcached_clone(&declared_clone, NULL);
365 test_true(memc_clone);
366 memcached_free(memc_clone);
367 }
368
369 /* Can we init from struct? */
370 {
371 memcached_st declared_clone;
372 memcached_st *memc_clone;
373 memset(&declared_clone, 0 , sizeof(memcached_st));
374 memc_clone= memcached_clone(&declared_clone, memc);
375 test_true(memc_clone);
376 memcached_free(memc_clone);
377 }
378
379 return TEST_SUCCESS;
380 }
381
382 static test_return_t userdata_test(memcached_st *memc)
383 {
384 void* foo= NULL;
385 test_true(memcached_set_user_data(memc, foo) == NULL);
386 test_true(memcached_get_user_data(memc) == foo);
387 test_true(memcached_set_user_data(memc, NULL) == foo);
388
389 return TEST_SUCCESS;
390 }
391
392 static test_return_t connection_test(memcached_st *memc)
393 {
394 memcached_return_t rc;
395
396 rc= memcached_server_add_with_weight(memc, "localhost", 0, 0);
397 test_true(rc == MEMCACHED_SUCCESS);
398
399 return TEST_SUCCESS;
400 }
401
402 static test_return_t error_test(memcached_st *memc)
403 {
404 uint32_t values[] = { 851992627U, 2337886783U, 3196981036U, 4001849190U,
405 982370485U, 1263635348U, 4242906218U, 3829656100U,
406 1891735253U, 334139633U, 2257084983U, 3088286104U,
407 13199785U, 2542027183U, 1097051614U, 199566778U,
408 2748246961U, 2465192557U, 1664094137U, 2405439045U,
409 1842224848U, 692413798U, 3479807801U, 919913813U,
410 4269430871U, 610793021U, 527273862U, 1437122909U,
411 2300930706U, 2943759320U, 674306647U, 2400528935U,
412 54481931U, 4186304426U, 1741088401U, 2979625118U,
413 4159057246U, 3425930182U, 2593724503U, 1868899624U,
414 1769812374U, 2302537950U, 1110330676U, 3365377466U,
415 1336171666U, 3021258493U, 3365377466U };
416
417 // You have updated the memcache_error messages but not updated docs/tests.
418 for (int rc= int(MEMCACHED_SUCCESS); rc < int(MEMCACHED_MAXIMUM_RETURN); ++rc)
419 {
420 uint32_t hash_val;
421 const char *msg= memcached_strerror(memc, memcached_return_t(rc));
422 hash_val= memcached_generate_hash_value(msg, strlen(msg),
423 MEMCACHED_HASH_JENKINS);
424 if (values[rc] != hash_val)
425 {
426 fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the error_test\n");
427 fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, memcached_return_t(rc)), hash_val);
428 }
429 test_true(values[rc] == hash_val);
430 }
431 test_true(MEMCACHED_MAXIMUM_RETURN == 46);
432
433 return TEST_SUCCESS;
434 }
435
436 static test_return_t set_test(memcached_st *memc)
437 {
438 memcached_return_t rc;
439 const char *key= "foo";
440 const char *value= "when we sanitize";
441
442 rc= memcached_set(memc, key, strlen(key),
443 value, strlen(value),
444 (time_t)0, (uint32_t)0);
445 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
446
447 return TEST_SUCCESS;
448 }
449
450 static test_return_t append_test(memcached_st *memc)
451 {
452 memcached_return_t rc;
453 const char *key= "fig";
454 const char *in_value= "we";
455 char *out_value= NULL;
456 size_t value_length;
457 uint32_t flags;
458
459 rc= memcached_flush(memc, 0);
460 test_true(rc == MEMCACHED_SUCCESS);
461
462 rc= memcached_set(memc, key, strlen(key),
463 in_value, strlen(in_value),
464 (time_t)0, (uint32_t)0);
465 test_true(rc == MEMCACHED_SUCCESS);
466
467 rc= memcached_append(memc, key, strlen(key),
468 " the", strlen(" the"),
469 (time_t)0, (uint32_t)0);
470 test_true(rc == MEMCACHED_SUCCESS);
471
472 rc= memcached_append(memc, key, strlen(key),
473 " people", strlen(" people"),
474 (time_t)0, (uint32_t)0);
475 test_true(rc == MEMCACHED_SUCCESS);
476
477 out_value= memcached_get(memc, key, strlen(key),
478 &value_length, &flags, &rc);
479 test_true(!memcmp(out_value, "we the people", strlen("we the people")));
480 test_true(strlen("we the people") == value_length);
481 test_true(rc == MEMCACHED_SUCCESS);
482 free(out_value);
483
484 return TEST_SUCCESS;
485 }
486
487 static test_return_t append_binary_test(memcached_st *memc)
488 {
489 memcached_return_t rc;
490 const char *key= "numbers";
491 uint32_t store_list[] = { 23, 56, 499, 98, 32847, 0 };
492 uint32_t *value;
493 size_t value_length;
494 uint32_t flags;
495 uint32_t x;
496
497 rc= memcached_flush(memc, 0);
498 test_true(rc == MEMCACHED_SUCCESS);
499
500 rc= memcached_set(memc,
501 key, strlen(key),
502 NULL, 0,
503 (time_t)0, (uint32_t)0);
504 test_true(rc == MEMCACHED_SUCCESS);
505
506 for (x= 0; store_list[x] ; x++)
507 {
508 rc= memcached_append(memc,
509 key, strlen(key),
510 (char *)&store_list[x], sizeof(uint32_t),
511 (time_t)0, (uint32_t)0);
512 test_true(rc == MEMCACHED_SUCCESS);
513 }
514
515 value= (uint32_t *)memcached_get(memc, key, strlen(key),
516 &value_length, &flags, &rc);
517 test_true((value_length == (sizeof(uint32_t) * x)));
518 test_true(rc == MEMCACHED_SUCCESS);
519
520 for (uint32_t counter= x, *ptr= value; counter; counter--)
521 {
522 test_true(*ptr == store_list[x - counter]);
523 ptr++;
524 }
525 free(value);
526
527 return TEST_SUCCESS;
528 }
529
530 static test_return_t cas2_test(memcached_st *memc)
531 {
532 memcached_return_t rc;
533 const char *keys[]= {"fudge", "son", "food"};
534 size_t key_length[]= {5, 3, 4};
535 const char *value= "we the people";
536 size_t value_length= strlen("we the people");
537 unsigned int x;
538 memcached_result_st results_obj;
539 memcached_result_st *results;
540 unsigned int set= 1;
541
542 rc= memcached_flush(memc, 0);
543 test_true(rc == MEMCACHED_SUCCESS);
544
545 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
546
547 for (x= 0; x < 3; x++)
548 {
549 rc= memcached_set(memc, keys[x], key_length[x],
550 keys[x], key_length[x],
551 (time_t)50, (uint32_t)9);
552 test_true(rc == MEMCACHED_SUCCESS);
553 }
554
555 rc= memcached_mget(memc, keys, key_length, 3);
556
557 results= memcached_result_create(memc, &results_obj);
558
559 results= memcached_fetch_result(memc, &results_obj, &rc);
560 test_true(results);
561 test_true(results->item_cas);
562 test_true(rc == MEMCACHED_SUCCESS);
563 test_true(memcached_result_cas(results));
564
565 test_true(!memcmp(value, "we the people", strlen("we the people")));
566 test_true(strlen("we the people") == value_length);
567 test_true(rc == MEMCACHED_SUCCESS);
568
569 memcached_result_free(&results_obj);
570
571 return TEST_SUCCESS;
572 }
573
574 static test_return_t cas_test(memcached_st *memc)
575 {
576 memcached_return_t rc;
577 const char *key= "fun";
578 size_t key_length= strlen(key);
579 const char *value= "we the people";
580 const char* keys[2] = { key, NULL };
581 size_t keylengths[2] = { strlen(key), 0 };
582 size_t value_length= strlen(value);
583 const char *value2= "change the value";
584 size_t value2_length= strlen(value2);
585
586 memcached_result_st results_obj;
587 memcached_result_st *results;
588 unsigned int set= 1;
589
590 rc= memcached_flush(memc, 0);
591 test_true(rc == MEMCACHED_SUCCESS);
592
593 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
594
595 rc= memcached_set(memc, key, strlen(key),
596 value, strlen(value),
597 (time_t)0, (uint32_t)0);
598 test_true(rc == MEMCACHED_SUCCESS);
599
600 rc= memcached_mget(memc, keys, keylengths, 1);
601
602 results= memcached_result_create(memc, &results_obj);
603
604 results= memcached_fetch_result(memc, &results_obj, &rc);
605 test_true(results);
606 test_true(rc == MEMCACHED_SUCCESS);
607 test_true(memcached_result_cas(results));
608 test_true(!memcmp(value, memcached_result_value(results), value_length));
609 test_true(strlen(memcached_result_value(results)) == value_length);
610 test_true(rc == MEMCACHED_SUCCESS);
611 uint64_t cas = memcached_result_cas(results);
612
613 #if 0
614 results= memcached_fetch_result(memc, &results_obj, &rc);
615 test_true(rc == MEMCACHED_END);
616 test_true(results == NULL);
617 #endif
618
619 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
620 test_true(rc == MEMCACHED_SUCCESS);
621
622 /*
623 * The item will have a new cas value, so try to set it again with the old
624 * value. This should fail!
625 */
626 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
627 test_true(rc == MEMCACHED_DATA_EXISTS);
628
629 memcached_result_free(&results_obj);
630
631 return TEST_SUCCESS;
632 }
633
634 static test_return_t prepend_test(memcached_st *memc)
635 {
636 memcached_return_t rc;
637 const char *key= "fig";
638 const char *value= "people";
639 char *out_value= NULL;
640 size_t value_length;
641 uint32_t flags;
642
643 rc= memcached_flush(memc, 0);
644 test_true(rc == MEMCACHED_SUCCESS);
645
646 rc= memcached_set(memc, key, strlen(key),
647 value, strlen(value),
648 (time_t)0, (uint32_t)0);
649 test_true(rc == MEMCACHED_SUCCESS);
650
651 rc= memcached_prepend(memc, key, strlen(key),
652 "the ", strlen("the "),
653 (time_t)0, (uint32_t)0);
654 test_true(rc == MEMCACHED_SUCCESS);
655
656 rc= memcached_prepend(memc, key, strlen(key),
657 "we ", strlen("we "),
658 (time_t)0, (uint32_t)0);
659 test_true(rc == MEMCACHED_SUCCESS);
660
661 out_value= memcached_get(memc, key, strlen(key),
662 &value_length, &flags, &rc);
663 test_true(!memcmp(out_value, "we the people", strlen("we the people")));
664 test_true(strlen("we the people") == value_length);
665 test_true(rc == MEMCACHED_SUCCESS);
666 free(out_value);
667
668 return TEST_SUCCESS;
669 }
670
671 /*
672 Set the value, then quit to make sure it is flushed.
673 Come back in and test that add fails.
674 */
675 static test_return_t add_test(memcached_st *memc)
676 {
677 memcached_return_t rc;
678 const char *key= "foo";
679 const char *value= "when we sanitize";
680 unsigned long long setting_value;
681
682 setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
683
684 rc= memcached_set(memc, key, strlen(key),
685 value, strlen(value),
686 (time_t)0, (uint32_t)0);
687 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
688 memcached_quit(memc);
689 rc= memcached_add(memc, key, strlen(key),
690 value, strlen(value),
691 (time_t)0, (uint32_t)0);
692
693 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
694 if (setting_value)
695 {
696 test_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
697 }
698 else
699 {
700 test_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_DATA_EXISTS);
701 }
702
703 return TEST_SUCCESS;
704 }
705
706 /*
707 ** There was a problem of leaking filedescriptors in the initial release
708 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
709 ** systems it seems that the kernel is slow on reclaiming the resources
710 ** because the connects starts to time out (the test doesn't do much
711 ** anyway, so just loop 10 iterations)
712 */
713 static test_return_t add_wrapper(memcached_st *memc)
714 {
715 unsigned int max= 10000;
716 #ifdef __sun
717 max= 10;
718 #endif
719 #ifdef __APPLE__
720 max= 10;
721 #endif
722
723 for (uint32_t x= 0; x < max; x++)
724 add_test(memc);
725
726 return TEST_SUCCESS;
727 }
728
729 static test_return_t replace_test(memcached_st *memc)
730 {
731 memcached_return_t rc;
732 const char *key= "foo";
733 const char *value= "when we sanitize";
734 const char *original= "first we insert some data";
735
736 rc= memcached_set(memc, key, strlen(key),
737 original, strlen(original),
738 (time_t)0, (uint32_t)0);
739 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
740
741 rc= memcached_replace(memc, key, strlen(key),
742 value, strlen(value),
743 (time_t)0, (uint32_t)0);
744 test_true(rc == MEMCACHED_SUCCESS);
745
746 return TEST_SUCCESS;
747 }
748
749 static test_return_t delete_test(memcached_st *memc)
750 {
751 memcached_return_t rc;
752 const char *key= "foo";
753 const char *value= "when we sanitize";
754
755 rc= memcached_set(memc, key, strlen(key),
756 value, strlen(value),
757 (time_t)0, (uint32_t)0);
758 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
759
760 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
761 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
762
763 return TEST_SUCCESS;
764 }
765
766 static test_return_t flush_test(memcached_st *memc)
767 {
768 memcached_return_t rc;
769
770 uint64_t query_id= memcached_query_id(memc);
771 rc= memcached_flush(memc, 0);
772 test_compare(rc, MEMCACHED_SUCCESS);
773 test_compare(query_id +1, memcached_query_id(memc));
774
775 return TEST_SUCCESS;
776 }
777
778 static memcached_return_t server_function(const memcached_st *ptr,
779 const memcached_server_st *server,
780 void *context)
781 {
782 (void)ptr; (void)server; (void)context;
783 /* Do Nothing */
784
785 return MEMCACHED_SUCCESS;
786 }
787
788 static test_return_t memcached_server_cursor_test(memcached_st *memc)
789 {
790 char context[10];
791 strncpy(context, "foo bad", sizeof(context));
792 memcached_server_fn callbacks[1];
793
794 callbacks[0]= server_function;
795 memcached_server_cursor(memc, callbacks, context, 1);
796 return TEST_SUCCESS;
797 }
798
799 static test_return_t bad_key_test(memcached_st *memc)
800 {
801 memcached_return_t rc;
802 const char *key= "foo bad";
803 char *string;
804 size_t string_length;
805 uint32_t flags;
806 memcached_st *memc_clone;
807 unsigned int set= 1;
808 size_t max_keylen= 0xffff;
809
810 // Just skip if we are in binary mode.
811 uint64_t query_id= memcached_query_id(memc);
812 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
813 return TEST_SKIPPED;
814 test_compare(query_id, memcached_query_id(memc)); // We should not increase the query_id for memcached_behavior_get()
815
816 memc_clone= memcached_clone(NULL, memc);
817 test_true(memc_clone);
818
819 query_id= memcached_query_id(memc_clone);
820 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
821 test_true(rc == MEMCACHED_SUCCESS);
822 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
823
824 /* All keys are valid in the binary protocol (except for length) */
825 if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 0)
826 {
827 query_id= memcached_query_id(memc_clone);
828 string= memcached_get(memc_clone, key, strlen(key),
829 &string_length, &flags, &rc);
830 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
831 test_true(string_length == 0);
832 test_true(!string);
833
834 set= 0;
835 query_id= memcached_query_id(memc_clone);
836 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
837 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
838 test_true(rc == MEMCACHED_SUCCESS);
839 string= memcached_get(memc_clone, key, strlen(key),
840 &string_length, &flags, &rc);
841 test_true(rc == MEMCACHED_NOTFOUND);
842 test_true(string_length == 0);
843 test_true(!string);
844
845 /* Test multi key for bad keys */
846 const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
847 size_t key_lengths[] = { 7, 7, 7 };
848 set= 1;
849 query_id= memcached_query_id(memc_clone);
850 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
851 test_true(rc == MEMCACHED_SUCCESS);
852 test_compare(query_id, memcached_query_id(memc_clone));
853
854 query_id= memcached_query_id(memc_clone);
855 rc= memcached_mget(memc_clone, keys, key_lengths, 3);
856 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
857 test_compare(query_id +1, memcached_query_id(memc_clone));
858
859 query_id= memcached_query_id(memc_clone);
860 rc= memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1);
861 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
862 test_compare(query_id +1, memcached_query_id(memc_clone));
863
864 max_keylen= 250;
865
866 /* The following test should be moved to the end of this function when the
867 memcached server is updated to allow max size length of the keys in the
868 binary protocol
869 */
870 rc= memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
871 test_true(rc == MEMCACHED_SUCCESS);
872
873 char *longkey= (char *)malloc(max_keylen + 1);
874 if (longkey != NULL)
875 {
876 memset(longkey, 'a', max_keylen + 1);
877 string= memcached_get(memc_clone, longkey, max_keylen,
878 &string_length, &flags, &rc);
879 test_true(rc == MEMCACHED_NOTFOUND);
880 test_true(string_length == 0);
881 test_true(!string);
882
883 string= memcached_get(memc_clone, longkey, max_keylen + 1,
884 &string_length, &flags, &rc);
885 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
886 test_true(string_length == 0);
887 test_true(!string);
888
889 free(longkey);
890 }
891 }
892
893 /* Make sure zero length keys are marked as bad */
894 set= 1;
895 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
896 test_true(rc == MEMCACHED_SUCCESS);
897 string= memcached_get(memc_clone, key, 0,
898 &string_length, &flags, &rc);
899 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
900 test_true(string_length == 0);
901 test_true(!string);
902
903 memcached_free(memc_clone);
904
905 return TEST_SUCCESS;
906 }
907
908 #define READ_THROUGH_VALUE "set for me"
909 static memcached_return_t read_through_trigger(memcached_st *memc,
910 char *key,
911 size_t key_length,
912 memcached_result_st *result)
913 {
914 (void)memc;(void)key;(void)key_length;
915 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
916 }
917
918 #ifndef __INTEL_COMPILER
919 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
920 #endif
921
922 static test_return_t read_through(memcached_st *memc)
923 {
924 memcached_return_t rc;
925 const char *key= "foo";
926 char *string;
927 size_t string_length;
928 uint32_t flags;
929 memcached_trigger_key_fn cb= (memcached_trigger_key_fn)read_through_trigger;
930
931 string= memcached_get(memc, key, strlen(key),
932 &string_length, &flags, &rc);
933
934 test_true(rc == MEMCACHED_NOTFOUND);
935 test_false(string_length);
936 test_false(string);
937
938 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, *(void **)&cb);
939 test_true(rc == MEMCACHED_SUCCESS);
940
941 string= memcached_get(memc, key, strlen(key),
942 &string_length, &flags, &rc);
943
944 test_true(rc == MEMCACHED_SUCCESS);
945 test_true(string_length == strlen(READ_THROUGH_VALUE));
946 test_strcmp(READ_THROUGH_VALUE, string);
947 free(string);
948
949 string= memcached_get(memc, key, strlen(key),
950 &string_length, &flags, &rc);
951
952 test_true(rc == MEMCACHED_SUCCESS);
953 test_true(string_length == strlen(READ_THROUGH_VALUE));
954 test_true(!strcmp(READ_THROUGH_VALUE, string));
955 free(string);
956
957 return TEST_SUCCESS;
958 }
959
960 static memcached_return_t delete_trigger(memcached_st *ptr,
961 const char *key,
962 size_t key_length)
963 {
964 (void)ptr;(void)key_length;
965 assert(key);
966
967 return MEMCACHED_SUCCESS;
968 }
969
970 static test_return_t delete_through(memcached_st *memc)
971 {
972 memcached_trigger_delete_key_fn callback;
973 memcached_return_t rc;
974
975 callback= (memcached_trigger_delete_key_fn)delete_trigger;
976
977 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, *(void**)&callback);
978 test_true(rc == MEMCACHED_SUCCESS);
979
980 return TEST_SUCCESS;
981 }
982
983 static test_return_t get_test(memcached_st *memc)
984 {
985 memcached_return_t rc;
986 const char *key= "foo";
987 char *string;
988 size_t string_length;
989 uint32_t flags;
990
991 uint64_t query_id= memcached_query_id(memc);
992 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
993 test_true(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
994 test_compare(query_id +1, memcached_query_id(memc));
995
996 string= memcached_get(memc, key, strlen(key),
997 &string_length, &flags, &rc);
998
999 test_true(rc == MEMCACHED_NOTFOUND);
1000 test_false(string_length);
1001 test_false(string);
1002
1003 return TEST_SUCCESS;
1004 }
1005
1006 static test_return_t get_test2(memcached_st *memc)
1007 {
1008 memcached_return_t rc;
1009 const char *key= "foo";
1010 const char *value= "when we sanitize";
1011 char *string;
1012 size_t string_length;
1013 uint32_t flags;
1014
1015 uint64_t query_id= memcached_query_id(memc);
1016 rc= memcached_set(memc, key, strlen(key),
1017 value, strlen(value),
1018 (time_t)0, (uint32_t)0);
1019 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1020 test_compare(query_id +1, memcached_query_id(memc));
1021
1022 query_id= memcached_query_id(memc);
1023 string= memcached_get(memc, key, strlen(key),
1024 &string_length, &flags, &rc);
1025 test_compare(query_id +1, memcached_query_id(memc));
1026
1027 test_true(string);
1028 test_true(rc == MEMCACHED_SUCCESS);
1029 test_true(string_length == strlen(value));
1030 test_memcmp(string, value, string_length);
1031
1032 free(string);
1033
1034 return TEST_SUCCESS;
1035 }
1036
1037 static test_return_t set_test2(memcached_st *memc)
1038 {
1039 memcached_return_t rc;
1040 const char *key= "foo";
1041 const char *value= "train in the brain";
1042 size_t value_length= strlen(value);
1043 unsigned int x;
1044
1045 for (x= 0; x < 10; x++)
1046 {
1047 rc= memcached_set(memc, key, strlen(key),
1048 value, value_length,
1049 (time_t)0, (uint32_t)0);
1050 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1051 }
1052
1053 return TEST_SUCCESS;
1054 }
1055
1056 static test_return_t set_test3(memcached_st *memc)
1057 {
1058 memcached_return_t rc;
1059 char *value;
1060 size_t value_length= 8191;
1061
1062 value = (char*)malloc(value_length);
1063 test_true(value);
1064
1065 for (uint32_t x= 0; x < value_length; x++)
1066 value[x] = (char) (x % 127);
1067
1068 /* The dump test relies on there being at least 32 items in memcached */
1069 for (uint32_t x= 0; x < 32; x++)
1070 {
1071 char key[16];
1072
1073 snprintf(key, sizeof(key), "foo%u", x);
1074
1075 uint64_t query_id= memcached_query_id(memc);
1076 rc= memcached_set(memc, key, strlen(key),
1077 value, value_length,
1078 (time_t)0, (uint32_t)0);
1079 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1080 test_compare(query_id +1, memcached_query_id(memc));
1081 }
1082
1083 free(value);
1084
1085 return TEST_SUCCESS;
1086 }
1087
1088 static test_return_t get_test3(memcached_st *memc)
1089 {
1090 memcached_return_t rc;
1091 const char *key= "foo";
1092 char *value;
1093 size_t value_length= 8191;
1094 char *string;
1095 size_t string_length;
1096 uint32_t flags;
1097 uint32_t x;
1098
1099 value = (char*)malloc(value_length);
1100 test_true(value);
1101
1102 for (x= 0; x < value_length; x++)
1103 value[x] = (char) (x % 127);
1104
1105 rc= memcached_set(memc, key, strlen(key),
1106 value, value_length,
1107 (time_t)0, (uint32_t)0);
1108 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1109
1110 string= memcached_get(memc, key, strlen(key),
1111 &string_length, &flags, &rc);
1112
1113 test_true(rc == MEMCACHED_SUCCESS);
1114 test_true(string);
1115 test_true(string_length == value_length);
1116 test_true(!memcmp(string, value, string_length));
1117
1118 free(string);
1119 free(value);
1120
1121 return TEST_SUCCESS;
1122 }
1123
1124 static test_return_t get_test4(memcached_st *memc)
1125 {
1126 memcached_return_t rc;
1127 const char *key= "foo";
1128 char *value;
1129 size_t value_length= 8191;
1130 char *string;
1131 size_t string_length;
1132 uint32_t flags;
1133 uint32_t x;
1134
1135 value = (char*)malloc(value_length);
1136 test_true(value);
1137
1138 for (x= 0; x < value_length; x++)
1139 value[x] = (char) (x % 127);
1140
1141 rc= memcached_set(memc, key, strlen(key),
1142 value, value_length,
1143 (time_t)0, (uint32_t)0);
1144 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1145
1146 for (x= 0; x < 10; x++)
1147 {
1148 string= memcached_get(memc, key, strlen(key),
1149 &string_length, &flags, &rc);
1150
1151 test_true(rc == MEMCACHED_SUCCESS);
1152 test_true(string);
1153 test_true(string_length == value_length);
1154 test_true(!memcmp(string, value, string_length));
1155 free(string);
1156 }
1157
1158 free(value);
1159
1160 return TEST_SUCCESS;
1161 }
1162
1163 /*
1164 * This test verifies that memcached_read_one_response doesn't try to
1165 * dereference a NIL-pointer if you issue a multi-get and don't read out all
1166 * responses before you execute a storage command.
1167 */
1168 static test_return_t get_test5(memcached_st *memc)
1169 {
1170 /*
1171 ** Request the same key twice, to ensure that we hash to the same server
1172 ** (so that we have multiple response values queued up) ;-)
1173 */
1174 const char *keys[]= { "key", "key" };
1175 size_t lengths[]= { 3, 3 };
1176 uint32_t flags;
1177 size_t rlen;
1178
1179 memcached_return_t rc= memcached_set(memc, keys[0], lengths[0],
1180 keys[0], lengths[0], 0, 0);
1181 test_true(rc == MEMCACHED_SUCCESS);
1182 rc= memcached_mget(memc, keys, lengths, 2);
1183
1184 memcached_result_st results_obj;
1185 memcached_result_st *results;
1186 results=memcached_result_create(memc, &results_obj);
1187 test_true(results);
1188 results=memcached_fetch_result(memc, &results_obj, &rc);
1189 test_true(results);
1190 memcached_result_free(&results_obj);
1191
1192 /* Don't read out the second result, but issue a set instead.. */
1193 rc= memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0);
1194 test_true(rc == MEMCACHED_SUCCESS);
1195
1196 char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
1197 &rlen, &flags, &rc);
1198 test_true(val == NULL);
1199 test_true(rc == MEMCACHED_NOTFOUND);
1200 val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
1201 test_true(val != NULL);
1202 test_true(rc == MEMCACHED_SUCCESS);
1203 free(val);
1204
1205 return TEST_SUCCESS;
1206 }
1207
1208 static test_return_t mget_end(memcached_st *memc)
1209 {
1210 const char *keys[]= { "foo", "foo2" };
1211 size_t lengths[]= { 3, 4 };
1212 const char *values[]= { "fjord", "41" };
1213
1214 memcached_return_t rc;
1215
1216 // Set foo and foo2
1217 for (int i= 0; i < 2; i++)
1218 {
1219 rc= memcached_set(memc, keys[i], lengths[i], values[i], strlen(values[i]),
1220 (time_t)0, (uint32_t)0);
1221 test_true(rc == MEMCACHED_SUCCESS);
1222 }
1223
1224 char *string;
1225 size_t string_length;
1226 uint32_t flags;
1227
1228 // retrieve both via mget
1229 rc= memcached_mget(memc, keys, lengths, 2);
1230 test_true(rc == MEMCACHED_SUCCESS);
1231
1232 char key[MEMCACHED_MAX_KEY];
1233 size_t key_length;
1234
1235 // this should get both
1236 for (int i = 0; i < 2; i++)
1237 {
1238 string= memcached_fetch(memc, key, &key_length, &string_length,
1239 &flags, &rc);
1240 test_true(rc == MEMCACHED_SUCCESS);
1241 int val = 0;
1242 if (key_length == 4)
1243 val= 1;
1244 test_true(string_length == strlen(values[val]));
1245 test_true(strncmp(values[val], string, string_length) == 0);
1246 free(string);
1247 }
1248
1249 // this should indicate end
1250 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1251 test_true(rc == MEMCACHED_END);
1252
1253 // now get just one
1254 rc= memcached_mget(memc, keys, lengths, 1);
1255 test_true(rc == MEMCACHED_SUCCESS);
1256
1257 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1258 test_true(key_length == lengths[0]);
1259 test_true(strncmp(keys[0], key, key_length) == 0);
1260 test_true(string_length == strlen(values[0]));
1261 test_true(strncmp(values[0], string, string_length) == 0);
1262 test_true(rc == MEMCACHED_SUCCESS);
1263 free(string);
1264
1265 // this should indicate end
1266 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1267 test_true(rc == MEMCACHED_END);
1268
1269 return TEST_SUCCESS;
1270 }
1271
1272 /* Do not copy the style of this code, I just access hosts to testthis function */
1273 static test_return_t stats_servername_test(memcached_st *memc)
1274 {
1275 memcached_return_t rc;
1276 memcached_stat_st memc_stat;
1277 memcached_server_instance_st instance=
1278 memcached_server_instance_by_position(memc, 0);
1279
1280 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
1281 if (memcached_get_sasl_callbacks(memc) != NULL)
1282 return TEST_SKIPPED;
1283 #endif
1284 rc= memcached_stat_servername(&memc_stat, NULL,
1285 memcached_server_name(instance),
1286 memcached_server_port(instance));
1287
1288 return TEST_SUCCESS;
1289 }
1290
1291 static test_return_t increment_test(memcached_st *memc)
1292 {
1293 uint64_t new_number;
1294 memcached_return_t rc;
1295 const char *key= "number";
1296 const char *value= "0";
1297
1298 rc= memcached_set(memc, key, strlen(key),
1299 value, strlen(value),
1300 (time_t)0, (uint32_t)0);
1301 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1302
1303 rc= memcached_increment(memc, key, strlen(key),
1304 1, &new_number);
1305 test_true(rc == MEMCACHED_SUCCESS);
1306 test_true(new_number == 1);
1307
1308 rc= memcached_increment(memc, key, strlen(key),
1309 1, &new_number);
1310 test_true(rc == MEMCACHED_SUCCESS);
1311 test_true(new_number == 2);
1312
1313 return TEST_SUCCESS;
1314 }
1315
1316 static test_return_t increment_with_initial_test(memcached_st *memc)
1317 {
1318 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1319 {
1320 uint64_t new_number;
1321 memcached_return_t rc;
1322 const char *key= "number";
1323 uint64_t initial= 0;
1324
1325 rc= memcached_increment_with_initial(memc, key, strlen(key),
1326 1, initial, 0, &new_number);
1327 test_true(rc == MEMCACHED_SUCCESS);
1328 test_true(new_number == initial);
1329
1330 rc= memcached_increment_with_initial(memc, key, strlen(key),
1331 1, initial, 0, &new_number);
1332 test_true(rc == MEMCACHED_SUCCESS);
1333 test_true(new_number == (initial + 1));
1334 }
1335 return TEST_SUCCESS;
1336 }
1337
1338 static test_return_t decrement_test(memcached_st *memc)
1339 {
1340 uint64_t new_number;
1341 memcached_return_t rc;
1342 const char *key= "number";
1343 const char *value= "3";
1344
1345 rc= memcached_set(memc, key, strlen(key),
1346 value, strlen(value),
1347 (time_t)0, (uint32_t)0);
1348 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1349
1350 rc= memcached_decrement(memc, key, strlen(key),
1351 1, &new_number);
1352 test_true(rc == MEMCACHED_SUCCESS);
1353 test_true(new_number == 2);
1354
1355 rc= memcached_decrement(memc, key, strlen(key),
1356 1, &new_number);
1357 test_true(rc == MEMCACHED_SUCCESS);
1358 test_true(new_number == 1);
1359
1360 return TEST_SUCCESS;
1361 }
1362
1363 static test_return_t decrement_with_initial_test(memcached_st *memc)
1364 {
1365 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1366 {
1367 uint64_t new_number;
1368 memcached_return_t rc;
1369 const char *key= "number";
1370 uint64_t initial= 3;
1371
1372 rc= memcached_decrement_with_initial(memc, key, strlen(key),
1373 1, initial, 0, &new_number);
1374 test_true(rc == MEMCACHED_SUCCESS);
1375 test_true(new_number == initial);
1376
1377 rc= memcached_decrement_with_initial(memc, key, strlen(key),
1378 1, initial, 0, &new_number);
1379 test_true(rc == MEMCACHED_SUCCESS);
1380 test_true(new_number == (initial - 1));
1381 }
1382 return TEST_SUCCESS;
1383 }
1384
1385 static test_return_t increment_by_key_test(memcached_st *memc)
1386 {
1387 uint64_t new_number;
1388 memcached_return_t rc;
1389 const char *master_key= "foo";
1390 const char *key= "number";
1391 const char *value= "0";
1392
1393 rc= memcached_set_by_key(memc, master_key, strlen(master_key),
1394 key, strlen(key),
1395 value, strlen(value),
1396 (time_t)0, (uint32_t)0);
1397 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1398
1399 rc= memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key),
1400 1, &new_number);
1401 test_true(rc == MEMCACHED_SUCCESS);
1402 test_true(new_number == 1);
1403
1404 rc= memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key),
1405 1, &new_number);
1406 test_true(rc == MEMCACHED_SUCCESS);
1407 test_true(new_number == 2);
1408
1409 return TEST_SUCCESS;
1410 }
1411
1412 static test_return_t increment_with_initial_by_key_test(memcached_st *memc)
1413 {
1414 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1415 {
1416 uint64_t new_number;
1417 memcached_return_t rc;
1418 const char *master_key= "foo";
1419 const char *key= "number";
1420 uint64_t initial= 0;
1421
1422 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1423 key, strlen(key),
1424 1, initial, 0, &new_number);
1425 test_true(rc == MEMCACHED_SUCCESS);
1426 test_true(new_number == initial);
1427
1428 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1429 key, strlen(key),
1430 1, initial, 0, &new_number);
1431 test_true(rc == MEMCACHED_SUCCESS);
1432 test_true(new_number == (initial + 1));
1433 }
1434 return TEST_SUCCESS;
1435 }
1436
1437 static test_return_t decrement_by_key_test(memcached_st *memc)
1438 {
1439 uint64_t new_number;
1440 memcached_return_t rc;
1441 const char *master_key= "foo";
1442 const char *key= "number";
1443 const char *value= "3";
1444
1445 rc= memcached_set_by_key(memc, master_key, strlen(master_key),
1446 key, strlen(key),
1447 value, strlen(value),
1448 (time_t)0, (uint32_t)0);
1449 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1450
1451 rc= memcached_decrement_by_key(memc, master_key, strlen(master_key),
1452 key, strlen(key),
1453 1, &new_number);
1454 test_true(rc == MEMCACHED_SUCCESS);
1455 test_true(new_number == 2);
1456
1457 rc= memcached_decrement_by_key(memc, master_key, strlen(master_key),
1458 key, strlen(key),
1459 1, &new_number);
1460 test_true(rc == MEMCACHED_SUCCESS);
1461 test_true(new_number == 1);
1462
1463 return TEST_SUCCESS;
1464 }
1465
1466 static test_return_t decrement_with_initial_by_key_test(memcached_st *memc)
1467 {
1468 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1469 {
1470 uint64_t new_number;
1471 memcached_return_t rc;
1472 const char *master_key= "foo";
1473 const char *key= "number";
1474 uint64_t initial= 3;
1475
1476 rc= memcached_decrement_with_initial_by_key(memc, master_key, strlen(master_key),
1477 key, strlen(key),
1478 1, initial, 0, &new_number);
1479 test_true(rc == MEMCACHED_SUCCESS);
1480 test_true(new_number == initial);
1481
1482 rc= memcached_decrement_with_initial_by_key(memc, master_key, strlen(master_key),
1483 key, strlen(key),
1484 1, initial, 0, &new_number);
1485 test_true(rc == MEMCACHED_SUCCESS);
1486 test_true(new_number == (initial - 1));
1487 }
1488 return TEST_SUCCESS;
1489 }
1490
1491 static test_return_t quit_test(memcached_st *memc)
1492 {
1493 memcached_return_t rc;
1494 const char *key= "fudge";
1495 const char *value= "sanford and sun";
1496
1497 rc= memcached_set(memc, key, strlen(key),
1498 value, strlen(value),
1499 (time_t)10, (uint32_t)3);
1500 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1501 memcached_quit(memc);
1502
1503 rc= memcached_set(memc, key, strlen(key),
1504 value, strlen(value),
1505 (time_t)50, (uint32_t)9);
1506 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1507
1508 return TEST_SUCCESS;
1509 }
1510
1511 static test_return_t mget_result_test(memcached_st *memc)
1512 {
1513 memcached_return_t rc;
1514 const char *keys[]= {"fudge", "son", "food"};
1515 size_t key_length[]= {5, 3, 4};
1516 unsigned int x;
1517
1518 memcached_result_st results_obj;
1519 memcached_result_st *results;
1520
1521 results= memcached_result_create(memc, &results_obj);
1522 test_true(results);
1523 test_true(&results_obj == results);
1524
1525 /* We need to empty the server before continueing test */
1526 rc= memcached_flush(memc, 0);
1527 test_true(rc == MEMCACHED_SUCCESS);
1528
1529 rc= memcached_mget(memc, keys, key_length, 3);
1530 test_true(rc == MEMCACHED_SUCCESS);
1531
1532 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1533 {
1534 test_true(results);
1535 }
1536
1537 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1538 test_true(!results);
1539 test_true(rc == MEMCACHED_END);
1540
1541 for (x= 0; x < 3; x++)
1542 {
1543 rc= memcached_set(memc, keys[x], key_length[x],
1544 keys[x], key_length[x],
1545 (time_t)50, (uint32_t)9);
1546 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1547 }
1548
1549 rc= memcached_mget(memc, keys, key_length, 3);
1550 test_true(rc == MEMCACHED_SUCCESS);
1551
1552 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1553 {
1554 test_true(results);
1555 test_true(&results_obj == results);
1556 test_true(rc == MEMCACHED_SUCCESS);
1557 test_true(memcached_result_key_length(results) == memcached_result_length(results));
1558 test_true(!memcmp(memcached_result_key_value(results),
1559 memcached_result_value(results),
1560 memcached_result_length(results)));
1561 }
1562
1563 memcached_result_free(&results_obj);
1564
1565 return TEST_SUCCESS;
1566 }
1567
1568 static test_return_t mget_result_alloc_test(memcached_st *memc)
1569 {
1570 memcached_return_t rc;
1571 const char *keys[]= {"fudge", "son", "food"};
1572 size_t key_length[]= {5, 3, 4};
1573 unsigned int x;
1574
1575 memcached_result_st *results;
1576
1577 /* We need to empty the server before continueing test */
1578 rc= memcached_flush(memc, 0);
1579 test_true(rc == MEMCACHED_SUCCESS);
1580
1581 rc= memcached_mget(memc, keys, key_length, 3);
1582 test_true(rc == MEMCACHED_SUCCESS);
1583
1584 while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL)
1585 {
1586 test_true(results);
1587 }
1588 test_true(!results);
1589 test_true(rc == MEMCACHED_END);
1590
1591 for (x= 0; x < 3; x++)
1592 {
1593 rc= memcached_set(memc, keys[x], key_length[x],
1594 keys[x], key_length[x],
1595 (time_t)50, (uint32_t)9);
1596 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1597 }
1598
1599 rc= memcached_mget(memc, keys, key_length, 3);
1600 test_true(rc == MEMCACHED_SUCCESS);
1601
1602 x= 0;
1603 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1604 {
1605 test_true(results);
1606 test_true(rc == MEMCACHED_SUCCESS);
1607 test_true(memcached_result_key_length(results) == memcached_result_length(results));
1608 test_true(!memcmp(memcached_result_key_value(results),
1609 memcached_result_value(results),
1610 memcached_result_length(results)));
1611 memcached_result_free(results);
1612 x++;
1613 }
1614
1615 return TEST_SUCCESS;
1616 }
1617
1618 /* Count the results */
1619 static memcached_return_t callback_counter(const memcached_st *ptr,
1620 memcached_result_st *result,
1621 void *context)
1622 {
1623 (void)ptr; (void)result;
1624 size_t *counter= (size_t *)context;
1625
1626 *counter= *counter + 1;
1627
1628 return MEMCACHED_SUCCESS;
1629 }
1630
1631 static test_return_t mget_result_function(memcached_st *memc)
1632 {
1633 memcached_return_t rc;
1634 const char *keys[]= {"fudge", "son", "food"};
1635 size_t key_length[]= {5, 3, 4};
1636 unsigned int x;
1637 size_t counter;
1638 memcached_execute_fn callbacks[1];
1639
1640 /* We need to empty the server before continueing test */
1641 rc= memcached_flush(memc, 0);
1642 for (x= 0; x < 3; x++)
1643 {
1644 rc= memcached_set(memc, keys[x], key_length[x],
1645 keys[x], key_length[x],
1646 (time_t)50, (uint32_t)9);
1647 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1648 }
1649
1650 rc= memcached_mget(memc, keys, key_length, 3);
1651 test_true(rc == MEMCACHED_SUCCESS);
1652
1653 callbacks[0]= &callback_counter;
1654 counter= 0;
1655 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1656
1657 test_true(counter == 3);
1658
1659 return TEST_SUCCESS;
1660 }
1661
1662 static test_return_t mget_test(memcached_st *memc)
1663 {
1664 memcached_return_t rc;
1665 const char *keys[]= {"fudge", "son", "food"};
1666 size_t key_length[]= {5, 3, 4};
1667 unsigned int x;
1668 uint32_t flags;
1669
1670 char return_key[MEMCACHED_MAX_KEY];
1671 size_t return_key_length;
1672 char *return_value;
1673 size_t return_value_length;
1674
1675 /* We need to empty the server before continueing test */
1676 rc= memcached_flush(memc, 0);
1677 test_true(rc == MEMCACHED_SUCCESS);
1678
1679 rc= memcached_mget(memc, keys, key_length, 3);
1680 test_true(rc == MEMCACHED_SUCCESS);
1681
1682 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1683 &return_value_length, &flags, &rc)) != NULL)
1684 {
1685 test_true(return_value);
1686 }
1687 test_true(!return_value);
1688 test_true(return_value_length == 0);
1689 test_true(rc == MEMCACHED_END);
1690
1691 for (x= 0; x < 3; x++)
1692 {
1693 rc= memcached_set(memc, keys[x], key_length[x],
1694 keys[x], key_length[x],
1695 (time_t)50, (uint32_t)9);
1696 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1697 }
1698
1699 rc= memcached_mget(memc, keys, key_length, 3);
1700 test_true(rc == MEMCACHED_SUCCESS);
1701
1702 x= 0;
1703 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1704 &return_value_length, &flags, &rc)))
1705 {
1706 test_true(return_value);
1707 test_true(rc == MEMCACHED_SUCCESS);
1708 test_true(return_key_length == return_value_length);
1709 test_true(!memcmp(return_value, return_key, return_value_length));
1710 free(return_value);
1711 x++;
1712 }
1713
1714 return TEST_SUCCESS;
1715 }
1716
1717 static test_return_t mget_execute(memcached_st *memc)
1718 {
1719 bool binary= false;
1720
1721 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1722 binary= true;
1723
1724 /*
1725 * I only want to hit _one_ server so I know the number of requests I'm
1726 * sending in the pipeline.
1727 */
1728 uint32_t number_of_hosts= memc->number_of_hosts;
1729 memc->number_of_hosts= 1;
1730
1731 size_t max_keys= 20480;
1732
1733
1734 char **keys= static_cast<char **>(calloc(max_keys, sizeof(char*)));
1735 size_t *key_length=static_cast<size_t *>(calloc(max_keys, sizeof(size_t)));
1736
1737 /* First add all of the items.. */
1738 char blob[1024] = {0};
1739 memcached_return_t rc;
1740
1741 for (size_t x= 0; x < max_keys; ++x)
1742 {
1743 char k[251];
1744
1745 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
1746 keys[x]= strdup(k);
1747 test_true(keys[x] != NULL);
1748 uint64_t query_id= memcached_query_id(memc);
1749 rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
1750 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1751 test_compare(query_id +1, memcached_query_id(memc));
1752 }
1753
1754 /* Try to get all of them with a large multiget */
1755 size_t counter= 0;
1756 memcached_execute_fn callbacks[]= { &callback_counter };
1757 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
1758 max_keys, callbacks, &counter, 1);
1759
1760 if (rc == MEMCACHED_SUCCESS)
1761 {
1762 test_true(binary);
1763 uint64_t query_id= memcached_query_id(memc);
1764 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1765 test_true(rc == MEMCACHED_END);
1766 test_compare(query_id, memcached_query_id(memc));
1767
1768 /* Verify that we got all of the items */
1769 test_true(counter == max_keys);
1770 }
1771 else if (rc == MEMCACHED_NOT_SUPPORTED)
1772 {
1773 test_true(counter == 0);
1774 }
1775 else
1776 {
1777 test_fail("note: this test functions differently when in binary mode");
1778 }
1779
1780 /* Release all allocated resources */
1781 for (size_t x= 0; x < max_keys; ++x)
1782 {
1783 free(keys[x]);
1784 }
1785 free(keys);
1786 free(key_length);
1787
1788 memc->number_of_hosts= number_of_hosts;
1789 return TEST_SUCCESS;
1790 }
1791
1792 #define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
1793
1794 static test_return_t key_setup(memcached_st *memc)
1795 {
1796 (void)memc;
1797
1798 if (pre_binary(memc) != TEST_SUCCESS)
1799 return TEST_SKIPPED;
1800
1801 global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
1802
1803 return TEST_SUCCESS;
1804 }
1805
1806 static test_return_t key_teardown(memcached_st *memc)
1807 {
1808 (void)memc;
1809 pairs_free(global_pairs);
1810
1811 return TEST_SUCCESS;
1812 }
1813
1814 static test_return_t block_add_regression(memcached_st *memc)
1815 {
1816 /* First add all of the items.. */
1817 for (size_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
1818 {
1819 memcached_return_t rc;
1820 char blob[1024] = {0};
1821
1822 rc= memcached_add_by_key(memc, "bob", 3, global_pairs[x].key, global_pairs[x].key_length, blob, sizeof(blob), 0, 0);
1823 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1824 }
1825
1826 return TEST_SUCCESS;
1827 }
1828
1829 static test_return_t binary_add_regression(memcached_st *memc)
1830 {
1831 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
1832 test_return_t rc= block_add_regression(memc);
1833 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 0);
1834 return rc;
1835 }
1836
1837 static test_return_t get_stats_keys(memcached_st *memc)
1838 {
1839 char **stat_list;
1840 char **ptr;
1841 memcached_stat_st memc_stat;
1842 memcached_return_t rc;
1843
1844 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1845 test_true(rc == MEMCACHED_SUCCESS);
1846 for (ptr= stat_list; *ptr; ptr++)
1847 test_true(*ptr);
1848
1849 free(stat_list);
1850
1851 return TEST_SUCCESS;
1852 }
1853
1854 static test_return_t version_string_test(memcached_st *memc)
1855 {
1856 const char *version_string;
1857 (void)memc;
1858
1859 version_string= memcached_lib_version();
1860
1861 test_true(!strcmp(version_string, LIBMEMCACHED_VERSION_STRING));
1862
1863 return TEST_SUCCESS;
1864 }
1865
1866 static test_return_t get_stats(memcached_st *memc)
1867 {
1868 char **stat_list;
1869 char **ptr;
1870 memcached_return_t rc;
1871 memcached_stat_st *memc_stat;
1872
1873 memc_stat= memcached_stat(memc, NULL, &rc);
1874 test_true(rc == MEMCACHED_SUCCESS);
1875
1876 test_true(rc == MEMCACHED_SUCCESS);
1877 test_true(memc_stat);
1878
1879 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
1880 {
1881 stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1882 test_true(rc == MEMCACHED_SUCCESS);
1883 for (ptr= stat_list; *ptr; ptr++);
1884
1885 free(stat_list);
1886 }
1887
1888 memcached_stat_free(NULL, memc_stat);
1889
1890 return TEST_SUCCESS;
1891 }
1892
1893 static test_return_t add_host_test(memcached_st *memc)
1894 {
1895 unsigned int x;
1896 memcached_server_st *servers;
1897 memcached_return_t rc;
1898 char servername[]= "0.example.com";
1899
1900 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1901 test_true(servers);
1902 test_true(1 == memcached_server_list_count(servers));
1903
1904 for (x= 2; x < 20; x++)
1905 {
1906 char buffer[SMALL_STRING_LEN];
1907
1908 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1909 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1910 &rc);
1911 test_true(rc == MEMCACHED_SUCCESS);
1912 test_true(x == memcached_server_list_count(servers));
1913 }
1914
1915 rc= memcached_server_push(memc, servers);
1916 test_true(rc == MEMCACHED_SUCCESS);
1917 rc= memcached_server_push(memc, servers);
1918 test_true(rc == MEMCACHED_SUCCESS);
1919
1920 memcached_server_list_free(servers);
1921
1922 return TEST_SUCCESS;
1923 }
1924
1925 static memcached_return_t clone_test_callback(memcached_st *parent, memcached_st *memc_clone)
1926 {
1927 (void)parent;(void)memc_clone;
1928 return MEMCACHED_SUCCESS;
1929 }
1930
1931 static memcached_return_t cleanup_test_callback(memcached_st *ptr)
1932 {
1933 (void)ptr;
1934 return MEMCACHED_SUCCESS;
1935 }
1936
1937 static test_return_t callback_test(memcached_st *memc)
1938 {
1939 /* Test User Data */
1940 {
1941 int x= 5;
1942 int *test_ptr;
1943 memcached_return_t rc;
1944
1945 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
1946 test_true(rc == MEMCACHED_SUCCESS);
1947 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1948 test_true(*test_ptr == x);
1949 }
1950
1951 /* Test Clone Callback */
1952 {
1953 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1954 void *clone_cb_ptr= *(void **)&clone_cb;
1955 void *temp_function= NULL;
1956 memcached_return_t rc;
1957
1958 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1959 clone_cb_ptr);
1960 test_true(rc == MEMCACHED_SUCCESS);
1961 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1962 test_true(temp_function == clone_cb_ptr);
1963 }
1964
1965 /* Test Cleanup Callback */
1966 {
1967 memcached_cleanup_fn cleanup_cb=
1968 (memcached_cleanup_fn)cleanup_test_callback;
1969 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1970 void *temp_function= NULL;
1971 memcached_return_t rc;
1972
1973 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1974 cleanup_cb_ptr);
1975 test_true(rc == MEMCACHED_SUCCESS);
1976 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1977 test_true(temp_function == cleanup_cb_ptr);
1978 }
1979
1980 return TEST_SUCCESS;
1981 }
1982
1983 /* We don't test the behavior itself, we test the switches */
1984 static test_return_t behavior_test(memcached_st *memc)
1985 {
1986 uint64_t value;
1987 uint32_t set= 1;
1988
1989 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1990 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1991 test_true(value == 1);
1992
1993 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1994 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1995 test_true(value == 1);
1996
1997 set= MEMCACHED_HASH_MD5;
1998 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1999 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
2000 test_true(value == MEMCACHED_HASH_MD5);
2001
2002 set= 0;
2003
2004 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2005 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
2006 test_true(value == 0);
2007
2008 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2009 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
2010 test_true(value == 0);
2011
2012 set= MEMCACHED_HASH_DEFAULT;
2013 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
2014 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
2015 test_true(value == MEMCACHED_HASH_DEFAULT);
2016
2017 set= MEMCACHED_HASH_CRC;
2018 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
2019 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
2020 test_true(value == MEMCACHED_HASH_CRC);
2021
2022 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2023 test_true(value > 0);
2024
2025 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2026 test_true(value > 0);
2027
2028 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
2029 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value + 1);
2030 test_true((value + 1) == memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
2031
2032 return TEST_SUCCESS;
2033 }
2034
2035 static test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
2036 {
2037 memcached_return_t rc;
2038 bool set= true;
2039
2040 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
2041 test_true(rc == MEMCACHED_DEPRECATED);
2042
2043 // Platform dependent
2044 #if 0
2045 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
2046 test_false(value);
2047 #endif
2048
2049 return TEST_SUCCESS;
2050 }
2051
2052
2053 static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
2054 {
2055 memcached_return_t rc;
2056 bool set= true;
2057 bool value;
2058
2059 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, set);
2060 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2061
2062 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
2063
2064 if (rc == MEMCACHED_SUCCESS)
2065 {
2066 test_true((bool)value == set);
2067 }
2068 else
2069 {
2070 test_false((bool)value == set);
2071 }
2072
2073 return TEST_SUCCESS;
2074 }
2075
2076
2077 static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
2078 {
2079 memcached_return_t rc;
2080 bool set= true;
2081 bool value;
2082
2083 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, set);
2084 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2085
2086 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
2087
2088 if (rc == MEMCACHED_SUCCESS)
2089 {
2090 test_true((bool)value == set);
2091 }
2092 else
2093 {
2094 test_false((bool)value == set);
2095 }
2096
2097 return TEST_SUCCESS;
2098 }
2099
2100 static test_return_t fetch_all_results(memcached_st *memc, size_t *keys_returned)
2101 {
2102 memcached_return_t rc= MEMCACHED_SUCCESS;
2103 char return_key[MEMCACHED_MAX_KEY];
2104 size_t return_key_length;
2105 char *return_value;
2106 size_t return_value_length;
2107 uint32_t flags;
2108
2109 *keys_returned= 0;
2110
2111 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2112 &return_value_length, &flags, &rc)))
2113 {
2114 test_true(return_value);
2115 test_true(rc == MEMCACHED_SUCCESS);
2116 free(return_value);
2117 *keys_returned= *keys_returned +1;
2118 }
2119
2120 test_true_got(rc == MEMCACHED_END || rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
2121
2122 return TEST_SUCCESS;
2123 }
2124
2125 /* Test case provided by Cal Haldenbrand */
2126 static test_return_t user_supplied_bug1(memcached_st *memc)
2127 {
2128 unsigned int setter= 1;
2129
2130 unsigned long long total= 0;
2131 uint32_t size= 0;
2132 char key[10];
2133 char randomstuff[6 * 1024];
2134 memcached_return_t rc;
2135
2136 memset(randomstuff, 0, 6 * 1024);
2137
2138 /* We just keep looking at the same values over and over */
2139 srandom(10);
2140
2141 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2142 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2143
2144
2145 /* add key */
2146 for (uint32_t x= 0 ; total < 20 * 1024576 ; x++ )
2147 {
2148 unsigned int j= 0;
2149
2150 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
2151 memset(randomstuff, 0, 6 * 1024);
2152 test_true(size < 6 * 1024); /* Being safe here */
2153
2154 for (j= 0 ; j < size ;j++)
2155 randomstuff[j] = (signed char) ((rand() % 26) + 97);
2156
2157 total += size;
2158 snprintf(key, sizeof(key), "%u", x);
2159 rc = memcached_set(memc, key, strlen(key),
2160 randomstuff, strlen(randomstuff), 10, 0);
2161 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2162 /* If we fail, lets try again */
2163 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
2164 rc = memcached_set(memc, key, strlen(key),
2165 randomstuff, strlen(randomstuff), 10, 0);
2166 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2167 }
2168
2169 return TEST_SUCCESS;
2170 }
2171
2172 /* Test case provided by Cal Haldenbrand */
2173 static test_return_t user_supplied_bug2(memcached_st *memc)
2174 {
2175 unsigned int setter;
2176 size_t total= 0;
2177
2178 setter= 1;
2179 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2180 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2181 #ifdef NOT_YET
2182 setter = 20 * 1024576;
2183 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2184 setter = 20 * 1024576;
2185 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2186 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2187 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2188
2189 for (x= 0, errors= 0; total < 20 * 1024576 ; x++)
2190 #endif
2191
2192 for (uint32_t x= 0, errors= 0; total < 24576 ; x++)
2193 {
2194 memcached_return_t rc= MEMCACHED_SUCCESS;
2195 char buffer[SMALL_STRING_LEN];
2196 uint32_t flags= 0;
2197 size_t val_len= 0;
2198 char *getval;
2199
2200 memset(buffer, 0, SMALL_STRING_LEN);
2201
2202 snprintf(buffer, sizeof(buffer), "%u", x);
2203 getval= memcached_get(memc, buffer, strlen(buffer),
2204 &val_len, &flags, &rc);
2205 if (rc != MEMCACHED_SUCCESS)
2206 {
2207 if (rc == MEMCACHED_NOTFOUND)
2208 errors++;
2209 else
2210 {
2211 test_true(rc);
2212 }
2213
2214 continue;
2215 }
2216 total+= val_len;
2217 errors= 0;
2218 free(getval);
2219 }
2220
2221 return TEST_SUCCESS;
2222 }
2223
2224 /* Do a large mget() over all the keys we think exist */
2225 #define KEY_COUNT 3000 // * 1024576
2226 static test_return_t user_supplied_bug3(memcached_st *memc)
2227 {
2228 memcached_return_t rc;
2229 unsigned int setter;
2230 unsigned int x;
2231 char **keys;
2232 size_t key_lengths[KEY_COUNT];
2233
2234 setter= 1;
2235 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2236 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2237 #ifdef NOT_YET
2238 setter = 20 * 1024576;
2239 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2240 setter = 20 * 1024576;
2241 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2242 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2243 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2244 #endif
2245
2246 keys= static_cast<char **>(calloc(KEY_COUNT, sizeof(char *)));
2247 test_true(keys);
2248 for (x= 0; x < KEY_COUNT; x++)
2249 {
2250 char buffer[30];
2251
2252 snprintf(buffer, 30, "%u", x);
2253 keys[x]= strdup(buffer);
2254 key_lengths[x]= strlen(keys[x]);
2255 }
2256
2257 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
2258 test_true(rc == MEMCACHED_SUCCESS);
2259
2260 size_t keys_returned;
2261 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
2262
2263 for (x= 0; x < KEY_COUNT; x++)
2264 free(keys[x]);
2265 free(keys);
2266
2267 return TEST_SUCCESS;
2268 }
2269
2270 /* Make sure we behave properly if server list has no values */
2271 static test_return_t user_supplied_bug4(memcached_st *memc)
2272 {
2273 memcached_return_t rc;
2274 const char *keys[]= {"fudge", "son", "food"};
2275 size_t key_length[]= {5, 3, 4};
2276 unsigned int x;
2277 uint32_t flags;
2278 char return_key[MEMCACHED_MAX_KEY];
2279 size_t return_key_length;
2280 char *return_value;
2281 size_t return_value_length;
2282
2283 /* Here we free everything before running a bunch of mget tests */
2284 memcached_servers_reset(memc);
2285
2286
2287 /* We need to empty the server before continueing test */
2288 rc= memcached_flush(memc, 0);
2289 test_compare(rc, MEMCACHED_NO_SERVERS);
2290
2291 rc= memcached_mget(memc, keys, key_length, 3);
2292 test_true(rc == MEMCACHED_NO_SERVERS);
2293
2294 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2295 &return_value_length, &flags, &rc)) != NULL)
2296 {
2297 test_true(return_value);
2298 }
2299 test_false(return_value);
2300 test_true(return_value_length == 0);
2301 test_true(rc == MEMCACHED_NO_SERVERS);
2302
2303 for (x= 0; x < 3; x++)
2304 {
2305 rc= memcached_set(memc, keys[x], key_length[x],
2306 keys[x], key_length[x],
2307 (time_t)50, (uint32_t)9);
2308 test_true(rc == MEMCACHED_NO_SERVERS);
2309 }
2310
2311 rc= memcached_mget(memc, keys, key_length, 3);
2312 test_true(rc == MEMCACHED_NO_SERVERS);
2313
2314 x= 0;
2315 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2316 &return_value_length, &flags, &rc)))
2317 {
2318 test_true(return_value);
2319 test_true(rc == MEMCACHED_SUCCESS);
2320 test_true(return_key_length == return_value_length);
2321 test_memcmp(return_value, return_key, return_value_length);
2322 free(return_value);
2323 x++;
2324 }
2325
2326 return TEST_SUCCESS;
2327 }
2328
2329 #define VALUE_SIZE_BUG5 1048064
2330 static test_return_t user_supplied_bug5(memcached_st *memc)
2331 {
2332 memcached_return_t rc;
2333 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2334 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2335 char return_key[MEMCACHED_MAX_KEY];
2336 size_t return_key_length;
2337 char *value;
2338 size_t value_length;
2339 uint32_t flags;
2340 unsigned int count;
2341 unsigned int x;
2342 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2343
2344 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2345 insert_data[x]= (signed char)rand();
2346
2347 memcached_flush(memc, 0);
2348 value= memcached_get(memc, keys[0], key_length[0],
2349 &value_length, &flags, &rc);
2350 test_true(value == NULL);
2351 rc= memcached_mget(memc, keys, key_length, 4);
2352
2353 count= 0;
2354 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2355 &value_length, &flags, &rc)))
2356 count++;
2357 test_true(count == 0);
2358
2359 for (x= 0; x < 4; x++)
2360 {
2361 rc= memcached_set(memc, keys[x], key_length[x],
2362 insert_data, VALUE_SIZE_BUG5,
2363 (time_t)0, (uint32_t)0);
2364 test_true(rc == MEMCACHED_SUCCESS);
2365 }
2366
2367 for (x= 0; x < 10; x++)
2368 {
2369 value= memcached_get(memc, keys[0], key_length[0],
2370 &value_length, &flags, &rc);
2371 test_true(value);
2372 free(value);
2373
2374 rc= memcached_mget(memc, keys, key_length, 4);
2375 count= 0;
2376 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2377 &value_length, &flags, &rc)))
2378 {
2379 count++;
2380 free(value);
2381 }
2382 test_true(count == 4);
2383 }
2384 delete [] insert_data;
2385
2386 return TEST_SUCCESS;
2387 }
2388
2389 static test_return_t user_supplied_bug6(memcached_st *memc)
2390 {
2391 memcached_return_t rc;
2392 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2393 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2394 char return_key[MEMCACHED_MAX_KEY];
2395 size_t return_key_length;
2396 char *value;
2397 size_t value_length;
2398 uint32_t flags;
2399 unsigned int count;
2400 unsigned int x;
2401 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2402
2403 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2404 insert_data[x]= (signed char)rand();
2405
2406 memcached_flush(memc, 0);
2407 value= memcached_get(memc, keys[0], key_length[0],
2408 &value_length, &flags, &rc);
2409 test_true(value == NULL);
2410 test_true(rc == MEMCACHED_NOTFOUND);
2411 rc= memcached_mget(memc, keys, key_length, 4);
2412 test_true(rc == MEMCACHED_SUCCESS);
2413
2414 count= 0;
2415 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2416 &value_length, &flags, &rc)))
2417 count++;
2418 test_true(count == 0);
2419 test_true(rc == MEMCACHED_END);
2420
2421 for (x= 0; x < 4; x++)
2422 {
2423 rc= memcached_set(memc, keys[x], key_length[x],
2424 insert_data, VALUE_SIZE_BUG5,
2425 (time_t)0, (uint32_t)0);
2426 test_true(rc == MEMCACHED_SUCCESS);
2427 }
2428
2429 for (x= 0; x < 2; x++)
2430 {
2431 value= memcached_get(memc, keys[0], key_length[0],
2432 &value_length, &flags, &rc);
2433 test_true(value);
2434 free(value);
2435
2436 rc= memcached_mget(memc, keys, key_length, 4);
2437 test_true(rc == MEMCACHED_SUCCESS);
2438 count= 3;
2439 /* We test for purge of partial complete fetches */
2440 for (count= 3; count; count--)
2441 {
2442 value= memcached_fetch(memc, return_key, &return_key_length,
2443 &value_length, &flags, &rc);
2444 test_true(rc == MEMCACHED_SUCCESS);
2445 test_true(!(memcmp(value, insert_data, value_length)));
2446 test_true(value_length);
2447 free(value);
2448 }
2449 }
2450 delete [] insert_data;
2451
2452 return TEST_SUCCESS;
2453 }
2454
2455 static test_return_t user_supplied_bug8(memcached_st *memc)
2456 {
2457 memcached_return_t rc;
2458 memcached_st *mine;
2459 memcached_st *memc_clone;
2460
2461 memcached_server_st *servers;
2462 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";
2463
2464 (void)memc;
2465 servers= memcached_servers_parse(server_list);
2466 test_true(servers);
2467
2468 mine= memcached_create(NULL);
2469 rc= memcached_server_push(mine, servers);
2470 test_true(rc == MEMCACHED_SUCCESS);
2471 memcached_server_list_free(servers);
2472
2473 test_true(mine);
2474 memc_clone= memcached_clone(NULL, mine);
2475
2476 memcached_quit(mine);
2477 memcached_quit(memc_clone);
2478
2479
2480 memcached_free(mine);
2481 memcached_free(memc_clone);
2482
2483 return TEST_SUCCESS;
2484 }
2485
2486 /* Test flag store/retrieve */
2487 static test_return_t user_supplied_bug7(memcached_st *memc)
2488 {
2489 const char *keys= "036790384900";
2490 size_t key_length= strlen(keys);
2491 char return_key[MEMCACHED_MAX_KEY];
2492 size_t return_key_length;
2493 char *value;
2494 size_t value_length;
2495 uint32_t flags;
2496 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2497
2498 for (unsigned int x= 0; x < VALUE_SIZE_BUG5; x++)
2499 insert_data[x]= (signed char)rand();
2500
2501 memcached_flush(memc, 0);
2502
2503 flags= 245;
2504 memcached_return_t rc= memcached_set(memc, keys, key_length,
2505 insert_data, VALUE_SIZE_BUG5,
2506 (time_t)0, flags);
2507 test_true(rc == MEMCACHED_SUCCESS);
2508
2509 flags= 0;
2510 value= memcached_get(memc, keys, key_length,
2511 &value_length, &flags, &rc);
2512 test_true(flags == 245);
2513 test_true(value);
2514 free(value);
2515
2516 rc= memcached_mget(memc, &keys, &key_length, 1);
2517
2518 flags= 0;
2519 value= memcached_fetch(memc, return_key, &return_key_length,
2520 &value_length, &flags, &rc);
2521 test_compare(245, flags);
2522 test_true(value);
2523 free(value);
2524 delete [] insert_data;
2525
2526
2527 return TEST_SUCCESS;
2528 }
2529
2530 static test_return_t user_supplied_bug9(memcached_st *memc)
2531 {
2532 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2533 size_t key_length[3];
2534 uint32_t flags;
2535 unsigned count= 0;
2536
2537 char return_key[MEMCACHED_MAX_KEY];
2538 size_t return_key_length;
2539 char *return_value;
2540 size_t return_value_length;
2541
2542
2543 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2544 key_length[1]= strlen("fudge&*@#");
2545 key_length[2]= strlen("for^#@&$not");
2546
2547
2548 for (unsigned int x= 0; x < 3; x++)
2549 {
2550 memcached_return_t rc;
2551 rc= memcached_set(memc, keys[x], key_length[x],
2552 keys[x], key_length[x],
2553 (time_t)50, (uint32_t)9);
2554 test_true(rc == MEMCACHED_SUCCESS);
2555 }
2556
2557 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
2558 test_true(rc == MEMCACHED_SUCCESS);
2559
2560 /* We need to empty the server before continueing test */
2561 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2562 &return_value_length, &flags, &rc)) != NULL)
2563 {
2564 test_true(return_value);
2565 free(return_value);
2566 count++;
2567 }
2568 test_true(count == 3);
2569
2570 return TEST_SUCCESS;
2571 }
2572
2573 /* We are testing with aggressive timeout to get failures */
2574 static test_return_t user_supplied_bug10(memcached_st *memc)
2575 {
2576 const char *key= "foo";
2577 char *value;
2578 size_t value_length= 512;
2579 unsigned int x;
2580 size_t key_len= 3;
2581 unsigned int set= 1;
2582 memcached_st *mclone= memcached_clone(NULL, memc);
2583 int32_t timeout;
2584
2585 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2586 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2587 timeout= 2;
2588 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2589 (uint64_t)timeout);
2590
2591 value = (char*)malloc(value_length * sizeof(char));
2592
2593 for (x= 0; x < value_length; x++)
2594 value[x]= (char) (x % 127);
2595
2596 for (x= 1; x <= 100000; ++x)
2597 {
2598 memcached_return_t rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2599
2600 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2601 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2602
2603 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2604 x--;
2605 }
2606
2607 free(value);
2608 memcached_free(mclone);
2609
2610 return TEST_SUCCESS;
2611 }
2612
2613 /*
2614 We are looking failures in the async protocol
2615 */
2616 static test_return_t user_supplied_bug11(memcached_st *memc)
2617 {
2618 const char *key= "foo";
2619 char *value;
2620 size_t value_length= 512;
2621 unsigned int x;
2622 size_t key_len= 3;
2623 memcached_return_t rc;
2624 unsigned int set= 1;
2625 int32_t timeout;
2626 memcached_st *mclone= memcached_clone(NULL, memc);
2627
2628 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2629 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2630 timeout= -1;
2631 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2632 (size_t)timeout);
2633
2634 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2635
2636 test_true(timeout == -1);
2637
2638 value = (char*)malloc(value_length * sizeof(char));
2639
2640 for (x= 0; x < value_length; x++)
2641 value[x]= (char) (x % 127);
2642
2643 for (x= 1; x <= 100000; ++x)
2644 {
2645 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2646 }
2647
2648 free(value);
2649 memcached_free(mclone);
2650
2651 return TEST_SUCCESS;
2652 }
2653
2654 /*
2655 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2656 */
2657 static test_return_t user_supplied_bug12(memcached_st *memc)
2658 {
2659 memcached_return_t rc;
2660 uint32_t flags;
2661 size_t value_length;
2662 char *value;
2663 uint64_t number_value;
2664
2665 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2666 &value_length, &flags, &rc);
2667 test_true(value == NULL);
2668 test_true(rc == MEMCACHED_NOTFOUND);
2669
2670 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2671 1, &number_value);
2672
2673 test_true(value == NULL);
2674 /* The binary protocol will set the key if it doesn't exist */
2675 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2676 {
2677 test_true(rc == MEMCACHED_SUCCESS);
2678 }
2679 else
2680 {
2681 test_true(rc == MEMCACHED_NOTFOUND);
2682 }
2683
2684 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2685
2686 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2687 &value_length, &flags, &rc);
2688 test_true(value);
2689 test_true(rc == MEMCACHED_SUCCESS);
2690 free(value);
2691
2692 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2693 1, &number_value);
2694 test_true(number_value == 2);
2695 test_true(rc == MEMCACHED_SUCCESS);
2696
2697 return TEST_SUCCESS;
2698 }
2699
2700 /*
2701 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2702 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2703 */
2704 static test_return_t user_supplied_bug13(memcached_st *memc)
2705 {
2706 char key[] = "key34567890";
2707 memcached_return_t rc;
2708 size_t overflowSize;
2709
2710 char commandFirst[]= "set key34567890 0 0 ";
2711 char commandLast[] = " \r\n"; /* first line of command sent to server */
2712 size_t commandLength;
2713 size_t testSize;
2714
2715 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2716
2717 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2718
2719 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2720 {
2721 char *overflow= new (std::nothrow) char[testSize];
2722 test_true(overflow);
2723
2724 memset(overflow, 'x', testSize);
2725 rc= memcached_set(memc, key, strlen(key),
2726 overflow, testSize, 0, 0);
2727 test_true(rc == MEMCACHED_SUCCESS);
2728 delete overflow;
2729 }
2730
2731 return TEST_SUCCESS;
2732 }
2733
2734
2735 /*
2736 Test values of many different sizes
2737 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2738 set key34567890 0 0 8169 \r\n
2739 is sent followed by buffer of size 8169, followed by 8169
2740 */
2741 static test_return_t user_supplied_bug14(memcached_st *memc)
2742 {
2743 size_t setter= 1;
2744 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2745 memcached_return_t rc;
2746 const char *key= "foo";
2747 char *value;
2748 size_t value_length= 18000;
2749 char *string;
2750 size_t string_length;
2751 uint32_t flags;
2752 unsigned int x;
2753 size_t current_length;
2754
2755 value = (char*)malloc(value_length);
2756 test_true(value);
2757
2758 for (x= 0; x < value_length; x++)
2759 value[x] = (char) (x % 127);
2760
2761 for (current_length= 0; current_length < value_length; current_length++)
2762 {
2763 rc= memcached_set(memc, key, strlen(key),
2764 value, current_length,
2765 (time_t)0, (uint32_t)0);
2766 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2767
2768 string= memcached_get(memc, key, strlen(key),
2769 &string_length, &flags, &rc);
2770
2771 test_true(rc == MEMCACHED_SUCCESS);
2772 test_true(string_length == current_length);
2773 test_true(!memcmp(string, value, string_length));
2774
2775 free(string);
2776 }
2777
2778 free(value);
2779
2780 return TEST_SUCCESS;
2781 }
2782
2783 /*
2784 Look for zero length value problems
2785 */
2786 static test_return_t user_supplied_bug15(memcached_st *memc)
2787 {
2788 uint32_t x;
2789 memcached_return_t rc;
2790 const char *key= "mykey";
2791 char *value;
2792 size_t length;
2793 uint32_t flags;
2794
2795 for (x= 0; x < 2; x++)
2796 {
2797 rc= memcached_set(memc, key, strlen(key),
2798 NULL, 0,
2799 (time_t)0, (uint32_t)0);
2800
2801 test_true(rc == MEMCACHED_SUCCESS);
2802
2803 value= memcached_get(memc, key, strlen(key),
2804 &length, &flags, &rc);
2805
2806 test_true(rc == MEMCACHED_SUCCESS);
2807 test_true(value == NULL);
2808 test_true(length == 0);
2809 test_true(flags == 0);
2810
2811 value= memcached_get(memc, key, strlen(key),
2812 &length, &flags, &rc);
2813
2814 test_true(rc == MEMCACHED_SUCCESS);
2815 test_true(value == NULL);
2816 test_true(length == 0);
2817 test_true(flags == 0);
2818 }
2819
2820 return TEST_SUCCESS;
2821 }
2822
2823 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2824 static test_return_t user_supplied_bug16(memcached_st *memc)
2825 {
2826 memcached_return_t rc;
2827 const char *key= "mykey";
2828 char *value;
2829 size_t length;
2830 uint32_t flags;
2831
2832 rc= memcached_set(memc, key, strlen(key),
2833 NULL, 0,
2834 (time_t)0, UINT32_MAX);
2835
2836 test_true(rc == MEMCACHED_SUCCESS);
2837
2838 value= memcached_get(memc, key, strlen(key),
2839 &length, &flags, &rc);
2840
2841 test_true(rc == MEMCACHED_SUCCESS);
2842 test_true(value == NULL);
2843 test_true(length == 0);
2844 test_true(flags == UINT32_MAX);
2845
2846 return TEST_SUCCESS;
2847 }
2848
2849 #if !defined(__sun) && !defined(__OpenBSD__)
2850 /* Check the validity of chinese key*/
2851 static test_return_t user_supplied_bug17(memcached_st *memc)
2852 {
2853 memcached_return_t rc;
2854 const char *key= "豆瓣";
2855 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2856 char *value2;
2857 size_t length;
2858 uint32_t flags;
2859
2860 rc= memcached_set(memc, key, strlen(key),
2861 value, strlen(value),
2862 (time_t)0, 0);
2863
2864 test_true(rc == MEMCACHED_SUCCESS);
2865
2866 value2= memcached_get(memc, key, strlen(key),
2867 &length, &flags, &rc);
2868
2869 test_true(length==strlen(value));
2870 test_true(rc == MEMCACHED_SUCCESS);
2871 test_true(memcmp(value, value2, length)==0);
2872 free(value2);
2873
2874 return TEST_SUCCESS;
2875 }
2876 #endif
2877
2878 /*
2879 From Andrei on IRC
2880 */
2881
2882 static test_return_t user_supplied_bug19(memcached_st *not_used)
2883 {
2884 memcached_st *memc;
2885 const memcached_server_st *server;
2886 memcached_return_t res;
2887
2888 (void)not_used;
2889
2890 memc= memcached_create(NULL);
2891 memcached_server_add_with_weight(memc, "localhost", 11311, 100);
2892 memcached_server_add_with_weight(memc, "localhost", 11312, 100);
2893
2894 server= memcached_server_by_key(memc, "a", 1, &res);
2895
2896 memcached_free(memc);
2897
2898 return TEST_SUCCESS;
2899 }
2900
2901 /* CAS test from Andei */
2902 static test_return_t user_supplied_bug20(memcached_st *memc)
2903 {
2904 memcached_return_t status;
2905 memcached_result_st *result, result_obj;
2906 const char *key = "abc";
2907 size_t key_len = strlen("abc");
2908 const char *value = "foobar";
2909 size_t value_len = strlen(value);
2910
2911 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2912
2913 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2914 test_true(status == MEMCACHED_SUCCESS);
2915
2916 status = memcached_mget(memc, &key, &key_len, 1);
2917 test_true(status == MEMCACHED_SUCCESS);
2918
2919 result= memcached_result_create(memc, &result_obj);
2920 test_true(result);
2921
2922 memcached_result_create(memc, &result_obj);
2923 result= memcached_fetch_result(memc, &result_obj, &status);
2924
2925 test_true(result);
2926 test_true(status == MEMCACHED_SUCCESS);
2927
2928 memcached_result_free(result);
2929
2930 return TEST_SUCCESS;
2931 }
2932
2933 #include "ketama_test_cases.h"
2934 static test_return_t user_supplied_bug18(memcached_st *trash)
2935 {
2936 memcached_return_t rc;
2937 uint64_t value;
2938 int x;
2939 memcached_server_st *server_pool;
2940 memcached_st *memc;
2941
2942 (void)trash;
2943
2944 memc= memcached_create(NULL);
2945 test_true(memc);
2946
2947 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2948 test_true(rc == MEMCACHED_SUCCESS);
2949
2950 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2951 test_true(value == 1);
2952
2953 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2954 test_true(rc == MEMCACHED_SUCCESS);
2955
2956 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2957 test_true(value == MEMCACHED_HASH_MD5);
2958
2959 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
2960 memcached_server_push(memc, server_pool);
2961
2962 /* verify that the server list was parsed okay. */
2963 test_true(memcached_server_count(memc) == 8);
2964 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2965 test_true(server_pool[0].port == 11211);
2966 test_true(server_pool[0].weight == 600);
2967 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2968 test_true(server_pool[2].port == 11211);
2969 test_true(server_pool[2].weight == 200);
2970 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2971 test_true(server_pool[7].port == 11211);
2972 test_true(server_pool[7].weight == 100);
2973
2974 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2975 * us test the boundary wraparound.
2976 */
2977 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
2978
2979 /* verify the standard ketama set. */
2980 for (x= 0; x < 99; x++)
2981 {
2982 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2983
2984 memcached_server_instance_st instance=
2985 memcached_server_instance_by_position(memc, server_idx);
2986
2987 const char *hostname = memcached_server_name(instance);
2988 test_strcmp(hostname, ketama_test_cases[x].server);
2989 }
2990
2991 memcached_server_list_free(server_pool);
2992 memcached_free(memc);
2993
2994 return TEST_SUCCESS;
2995 }
2996
2997 /* Large mget() of missing keys with binary proto
2998 *
2999 * If many binary quiet commands (such as getq's in an mget) fill the output
3000 * buffer and the server chooses not to respond, memcached_flush hangs. See
3001 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
3002 */
3003
3004 /* sighandler_t function that always asserts false */
3005 static void fail(int unused)
3006 {
3007 (void)unused;
3008 assert(0);
3009 }
3010
3011
3012 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
3013 {
3014 #ifdef WIN32
3015 (void)memc;
3016 (void)key_count;
3017 return TEST_SKIPPED;
3018 #else
3019 memcached_return_t rc;
3020 unsigned int x;
3021 char **keys;
3022 size_t* key_lengths;
3023 void (*oldalarm)(int);
3024 memcached_st *memc_clone;
3025
3026 memc_clone= memcached_clone(NULL, memc);
3027 test_true(memc_clone);
3028
3029 /* only binproto uses getq for mget */
3030 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3031
3032 /* empty the cache to ensure misses (hence non-responses) */
3033 rc= memcached_flush(memc_clone, 0);
3034 test_true(rc == MEMCACHED_SUCCESS);
3035
3036 key_lengths= new (std::nothrow) size_t[key_count];
3037 test_true(key_lengths);
3038 keys= static_cast<char **>(calloc(key_count, sizeof(char *)));
3039 test_true(keys);
3040 for (x= 0; x < key_count; x++)
3041 {
3042 char buffer[30];
3043
3044 snprintf(buffer, 30, "%u", x);
3045 keys[x]= strdup(buffer);
3046 key_lengths[x]= strlen(keys[x]);
3047 }
3048
3049 oldalarm= signal(SIGALRM, fail);
3050 alarm(5);
3051
3052 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
3053 test_true(rc == MEMCACHED_SUCCESS);
3054
3055 alarm(0);
3056 signal(SIGALRM, oldalarm);
3057
3058 size_t keys_returned;
3059 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3060
3061 for (x= 0; x < key_count; x++)
3062 free(keys[x]);
3063 free(keys);
3064 delete key_lengths;
3065
3066 memcached_free(memc_clone);
3067
3068 return TEST_SUCCESS;
3069 #endif
3070 }
3071
3072 static test_return_t user_supplied_bug21(memcached_st *memc)
3073 {
3074 test_return_t test_rc;
3075 test_rc= pre_binary(memc);
3076
3077 if (test_rc != TEST_SUCCESS)
3078 return test_rc;
3079
3080 test_return_t rc;
3081
3082 /* should work as of r580 */
3083 rc= _user_supplied_bug21(memc, 10);
3084 test_true(rc == TEST_SUCCESS);
3085
3086 /* should fail as of r580 */
3087 rc= _user_supplied_bug21(memc, 1000);
3088 test_true(rc == TEST_SUCCESS);
3089
3090 return TEST_SUCCESS;
3091 }
3092
3093 static test_return_t auto_eject_hosts(memcached_st *trash)
3094 {
3095 (void) trash;
3096 memcached_server_instance_st instance;
3097
3098 memcached_return_t rc;
3099 memcached_st *memc= memcached_create(NULL);
3100 test_true(memc);
3101
3102 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3103 test_true(rc == MEMCACHED_SUCCESS);
3104
3105 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3106 test_true(value == 1);
3107
3108 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3109 test_true(rc == MEMCACHED_SUCCESS);
3110
3111 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3112 test_true(value == MEMCACHED_HASH_MD5);
3113
3114 /* server should be removed when in delay */
3115 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
3116 test_true(rc == MEMCACHED_SUCCESS);
3117
3118 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
3119 test_true(value == 1);
3120
3121 memcached_server_st *server_pool;
3122 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
3123 memcached_server_push(memc, server_pool);
3124
3125 /* verify that the server list was parsed okay. */
3126 test_true(memcached_server_count(memc) == 8);
3127 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
3128 test_true(server_pool[0].port == 11211);
3129 test_true(server_pool[0].weight == 600);
3130 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
3131 test_true(server_pool[2].port == 11211);
3132 test_true(server_pool[2].weight == 200);
3133 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
3134 test_true(server_pool[7].port == 11211);
3135 test_true(server_pool[7].weight == 100);
3136
3137 instance= memcached_server_instance_by_position(memc, 2);
3138 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
3139 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3140
3141 /*
3142 This would not work if there were only two hosts.
3143 */
3144 for (size_t x= 0; x < 99; x++)
3145 {
3146 memcached_autoeject(memc);
3147 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3148 test_true(server_idx != 2);
3149 }
3150
3151 /* and re-added when it's back. */
3152 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
3153 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3154 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
3155 memc->distribution);
3156 for (size_t x= 0; x < 99; x++)
3157 {
3158 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3159 // We re-use instance from above.
3160 instance=
3161 memcached_server_instance_by_position(memc, server_idx);
3162 const char *hostname = memcached_server_name(instance);
3163 test_true(strcmp(hostname, ketama_test_cases[x].server) == 0);
3164 }
3165
3166 memcached_server_list_free(server_pool);
3167 memcached_free(memc);
3168
3169 return TEST_SUCCESS;
3170 }
3171
3172 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
3173 {
3174 (void) trash;
3175
3176 memcached_return_t rc;
3177 memcached_st *memc= memcached_create(NULL);
3178 test_true(memc);
3179
3180
3181 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3182 test_true(rc == MEMCACHED_SUCCESS);
3183
3184 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3185 test_true(value == 1);
3186
3187 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3188 test_true(rc == MEMCACHED_SUCCESS);
3189
3190 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3191 test_true(value == MEMCACHED_HASH_MD5);
3192
3193
3194 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
3195
3196 memcached_server_st *server_pool;
3197 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");
3198 memcached_server_push(memc, server_pool);
3199
3200 // @todo this needs to be refactored to actually test something.
3201 #if 0
3202 FILE *fp;
3203 if ((fp = fopen("ketama_keys.txt", "w")))
3204 {
3205 // noop
3206 } else {
3207 printf("cannot write to file ketama_keys.txt");
3208 return TEST_FAILURE;
3209 }
3210
3211 for (int x= 0; x < 10000; x++)
3212 {
3213 char key[10];
3214 snprintf(key, sizeof(key), "%d", x);
3215
3216 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3217 char *hostname = memc->hosts[server_idx].hostname;
3218 in_port_t port = memc->hosts[server_idx].port;
3219 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3220 memcached_server_instance_st instance=
3221 memcached_server_instance_by_position(memc, host_index);
3222 }
3223 fclose(fp);
3224 #endif
3225 memcached_server_list_free(server_pool);
3226 memcached_free(memc);
3227
3228 return TEST_SUCCESS;
3229 }
3230
3231
3232 static test_return_t result_static(memcached_st *memc)
3233 {
3234 memcached_result_st result;
3235 memcached_result_st *result_ptr;
3236
3237 result_ptr= memcached_result_create(memc, &result);
3238 test_true(result.options.is_allocated == false);
3239 test_true(memcached_is_initialized(&result) == true);
3240 test_true(result_ptr);
3241 test_true(result_ptr == &result);
3242
3243 memcached_result_free(&result);
3244
3245 test_true(result.options.is_allocated == false);
3246 test_true(memcached_is_initialized(&result) == false);
3247
3248 return TEST_SUCCESS;
3249 }
3250
3251 static test_return_t result_alloc(memcached_st *memc)
3252 {
3253 memcached_result_st *result_ptr;
3254
3255 result_ptr= memcached_result_create(memc, NULL);
3256 test_true(result_ptr);
3257 test_true(result_ptr->options.is_allocated == true);
3258 test_true(memcached_is_initialized(result_ptr) == true);
3259 memcached_result_free(result_ptr);
3260
3261 return TEST_SUCCESS;
3262 }
3263
3264 static test_return_t cleanup_pairs(memcached_st *memc)
3265 {
3266 (void)memc;
3267 pairs_free(global_pairs);
3268
3269 return TEST_SUCCESS;
3270 }
3271
3272 static test_return_t generate_pairs(memcached_st *memc)
3273 {
3274 (void)memc;
3275 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3276 global_count= GLOBAL_COUNT;
3277
3278 for (size_t x= 0; x < global_count; x++)
3279 {
3280 global_keys[x]= global_pairs[x].key;
3281 global_keys_length[x]= global_pairs[x].key_length;
3282 }
3283
3284 return TEST_SUCCESS;
3285 }
3286
3287 static test_return_t generate_large_pairs(memcached_st *memc)
3288 {
3289 (void)memc;
3290 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3291 global_count= GLOBAL2_COUNT;
3292
3293 for (size_t x= 0; x < global_count; x++)
3294 {
3295 global_keys[x]= global_pairs[x].key;
3296 global_keys_length[x]= global_pairs[x].key_length;
3297 }
3298
3299 return TEST_SUCCESS;
3300 }
3301
3302 static test_return_t generate_data(memcached_st *memc)
3303 {
3304 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3305
3306 test_true(check_execute == global_count);
3307
3308 return TEST_SUCCESS;
3309 }
3310
3311 static test_return_t generate_data_with_stats(memcached_st *memc)
3312 {
3313 memcached_stat_st *stat_p;
3314 memcached_return_t rc;
3315 uint32_t host_index= 0;
3316 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3317
3318 test_true(check_execute == global_count);
3319
3320 //TODO: hosts used size stats
3321 stat_p= memcached_stat(memc, NULL, &rc);
3322 test_true(stat_p);
3323
3324 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3325 {
3326 /* This test was changes so that "make test" would work properlly */
3327 #ifdef DEBUG
3328 memcached_server_instance_st instance=
3329 memcached_server_instance_by_position(memc, host_index);
3330
3331 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3332 #endif
3333 test_true((unsigned long long)(stat_p + host_index)->bytes);
3334 }
3335
3336 memcached_stat_free(NULL, stat_p);
3337
3338 return TEST_SUCCESS;
3339 }
3340 static test_return_t generate_buffer_data(memcached_st *memc)
3341 {
3342 size_t latch= 0;
3343
3344 latch= 1;
3345 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3346 generate_data(memc);
3347
3348 return TEST_SUCCESS;
3349 }
3350
3351 static test_return_t get_read_count(memcached_st *memc)
3352 {
3353 memcached_return_t rc;
3354 memcached_st *memc_clone;
3355
3356 memc_clone= memcached_clone(NULL, memc);
3357 test_true(memc_clone);
3358
3359 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3360
3361 {
3362 char *return_value;
3363 size_t return_value_length;
3364 uint32_t flags;
3365 uint32_t count;
3366
3367 for (size_t x= count= 0; x < global_count; x++)
3368 {
3369 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3370 &return_value_length, &flags, &rc);
3371 if (rc == MEMCACHED_SUCCESS)
3372 {
3373 count++;
3374 if (return_value)
3375 free(return_value);
3376 }
3377 }
3378 }
3379
3380 memcached_free(memc_clone);
3381
3382 return TEST_SUCCESS;
3383 }
3384
3385 static test_return_t get_read(memcached_st *memc)
3386 {
3387 memcached_return_t rc;
3388
3389 {
3390 char *return_value;
3391 size_t return_value_length;
3392 uint32_t flags;
3393
3394 for (size_t x= 0; x < global_count; x++)
3395 {
3396 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3397 &return_value_length, &flags, &rc);
3398 /*
3399 test_true(return_value);
3400 test_true(rc == MEMCACHED_SUCCESS);
3401 */
3402 if (rc == MEMCACHED_SUCCESS && return_value)
3403 free(return_value);
3404 }
3405 }
3406
3407 return TEST_SUCCESS;
3408 }
3409
3410 static test_return_t mget_read(memcached_st *memc)
3411 {
3412 memcached_return_t rc;
3413
3414 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3415 return TEST_SKIPPED;
3416
3417 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3418
3419 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3420
3421 // Go fetch the keys and test to see if all of them were returned
3422 {
3423 size_t keys_returned;
3424 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3425 char buffer[30];
3426 snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)keys_returned);
3427 test_true_got(global_count == keys_returned, buffer);
3428 }
3429
3430
3431 return TEST_SUCCESS;
3432 }
3433
3434 static test_return_t mget_read_result(memcached_st *memc)
3435 {
3436 memcached_return_t rc;
3437
3438 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3439 return TEST_SKIPPED;
3440
3441 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3442
3443 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3444
3445 /* Turn this into a help function */
3446 {
3447 memcached_result_st results_obj;
3448 memcached_result_st *results;
3449
3450 results= memcached_result_create(memc, &results_obj);
3451
3452 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3453 {
3454 test_true(results);
3455 test_true(rc == MEMCACHED_SUCCESS);
3456 }
3457
3458 memcached_result_free(&results_obj);
3459 }
3460
3461 return TEST_SUCCESS;
3462 }
3463
3464 static test_return_t mget_read_function(memcached_st *memc)
3465 {
3466 memcached_return_t rc;
3467 size_t counter;
3468 memcached_execute_fn callbacks[1];
3469
3470 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3471 return TEST_SKIPPED;
3472
3473 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3474
3475 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3476
3477 callbacks[0]= &callback_counter;
3478 counter= 0;
3479 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3480
3481 return TEST_SUCCESS;
3482 }
3483
3484 static test_return_t delete_generate(memcached_st *memc)
3485 {
3486 for (size_t x= 0; x < global_count; x++)
3487 {
3488 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3489 }
3490
3491 return TEST_SUCCESS;
3492 }
3493
3494 static test_return_t delete_buffer_generate(memcached_st *memc)
3495 {
3496 uint64_t latch= 0;
3497
3498 latch= 1;
3499 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3500
3501 for (size_t x= 0; x < global_count; x++)
3502 {
3503 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3504 }
3505
3506 return TEST_SUCCESS;
3507 }
3508
3509 static test_return_t add_host_test1(memcached_st *memc)
3510 {
3511 memcached_return_t rc;
3512 char servername[]= "0.example.com";
3513 memcached_server_st *servers;
3514
3515 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3516 test_true(servers);
3517 test_true(1 == memcached_server_list_count(servers));
3518
3519 for (size_t x= 2; x < 20; x++)
3520 {
3521 char buffer[SMALL_STRING_LEN];
3522
3523 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
3524 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3525 &rc);
3526 test_true(rc == MEMCACHED_SUCCESS);
3527 test_true(x == memcached_server_list_count(servers));
3528 }
3529
3530 rc= memcached_server_push(memc, servers);
3531 test_true(rc == MEMCACHED_SUCCESS);
3532 rc= memcached_server_push(memc, servers);
3533 test_true(rc == MEMCACHED_SUCCESS);
3534
3535 memcached_server_list_free(servers);
3536
3537 return TEST_SUCCESS;
3538 }
3539
3540 static test_return_t pre_nonblock(memcached_st *memc)
3541 {
3542 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3543
3544 return TEST_SUCCESS;
3545 }
3546
3547 static test_return_t pre_cork(memcached_st *memc)
3548 {
3549 memcached_return_t rc;
3550 bool set= true;
3551
3552 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
3553
3554 #ifdef __APPLE__
3555 return TEST_SKIPPED;
3556 #endif
3557
3558 if (rc == MEMCACHED_SUCCESS)
3559 return TEST_SUCCESS;
3560
3561 return TEST_SKIPPED;
3562 }
3563
3564 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3565 {
3566 test_return_t rc;
3567
3568 rc= pre_cork(memc);
3569
3570 #ifdef __APPLE__
3571 return TEST_SKIPPED;
3572 #endif
3573
3574 if (rc != TEST_SUCCESS)
3575 return rc;
3576
3577 return pre_nonblock(memc);
3578 }
3579
3580 static test_return_t pre_nonblock_binary(memcached_st *memc)
3581 {
3582 memcached_return_t rc= MEMCACHED_FAILURE;
3583 memcached_st *memc_clone;
3584
3585 memc_clone= memcached_clone(NULL, memc);
3586 test_true(memc_clone);
3587 // The memcached_version needs to be done on a clone, because the server
3588 // will not toggle protocol on an connection.
3589 memcached_version(memc_clone);
3590
3591 if (libmemcached_util_version_check(memc_clone, 1, 4, 4))
3592 {
3593 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3594 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3595 test_true(rc == MEMCACHED_SUCCESS);
3596 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3597 }
3598 else
3599 {
3600 return TEST_SKIPPED;
3601 }
3602
3603 memcached_free(memc_clone);
3604
3605 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3606 }
3607
3608 static test_return_t pre_murmur(memcached_st *memc)
3609 {
3610 #ifdef HAVE_MURMUR_HASH
3611 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3612 return TEST_SUCCESS;
3613 #else
3614 (void) memc;
3615 return TEST_SKIPPED;
3616 #endif
3617 }
3618
3619 static test_return_t pre_jenkins(memcached_st *memc)
3620 {
3621 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3622
3623 return TEST_SUCCESS;
3624 }
3625
3626
3627 static test_return_t pre_md5(memcached_st *memc)
3628 {
3629 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3630
3631 return TEST_SUCCESS;
3632 }
3633
3634 static test_return_t pre_crc(memcached_st *memc)
3635 {
3636 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3637
3638 return TEST_SUCCESS;
3639 }
3640
3641 static test_return_t pre_hsieh(memcached_st *memc)
3642 {
3643 #ifdef HAVE_HSIEH_HASH
3644 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3645 return TEST_SUCCESS;
3646 #else
3647 (void) memc;
3648 return TEST_SKIPPED;
3649 #endif
3650 }
3651
3652 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3653 {
3654 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3655
3656 return TEST_SUCCESS;
3657 }
3658
3659 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3660 {
3661 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3662
3663 return TEST_SUCCESS;
3664 }
3665
3666 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3667 {
3668 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3669
3670 return TEST_SUCCESS;
3671 }
3672
3673 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3674 {
3675 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3676
3677 return TEST_SUCCESS;
3678 }
3679
3680 static test_return_t pre_behavior_ketama(memcached_st *memc)
3681 {
3682 memcached_return_t rc;
3683 uint64_t value;
3684
3685 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3686 test_true(rc == MEMCACHED_SUCCESS);
3687
3688 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3689 test_true(value == 1);
3690
3691 return TEST_SUCCESS;
3692 }
3693
3694 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3695 {
3696 memcached_return_t rc;
3697 uint64_t value;
3698
3699 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3700 test_true(rc == MEMCACHED_SUCCESS);
3701
3702 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3703 test_true(value == 1);
3704
3705 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3706 test_true(rc == MEMCACHED_SUCCESS);
3707
3708 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3709 test_true(value == MEMCACHED_HASH_MD5);
3710
3711 return TEST_SUCCESS;
3712 }
3713
3714 /**
3715 @note This should be testing to see if the server really supports the binary protocol.
3716 */
3717 static test_return_t pre_binary(memcached_st *memc)
3718 {
3719 memcached_return_t rc= MEMCACHED_FAILURE;
3720
3721 if (libmemcached_util_version_check(memc, 1, 4, 4))
3722 {
3723 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3724 test_true(rc == MEMCACHED_SUCCESS);
3725 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3726 }
3727
3728 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3729 }
3730
3731 static test_return_t pre_sasl(memcached_st *memc)
3732 {
3733 memcached_return_t rc= MEMCACHED_FAILURE;
3734
3735 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
3736 const char *server= getenv("LIBMEMCACHED_TEST_SASL_SERVER");
3737 const char *user= getenv("LIBMEMCACHED_TEST_SASL_USERNAME");
3738 const char *pass= getenv("LIBMEMCACHED_TEST_SASL_PASSWORD");
3739
3740 if (server != NULL && user != NULL && pass != NULL)
3741 {
3742 memcached_server_st *servers= memcached_servers_parse(server);
3743 test_true(servers != NULL);
3744 memcached_servers_reset(memc);
3745 test_true(memcached_server_push(memc, servers) == MEMCACHED_SUCCESS);
3746 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3747 rc= memcached_set_sasl_auth_data(memc, user, pass);
3748 test_true(rc == MEMCACHED_SUCCESS);
3749 }
3750 #else
3751 (void)memc;
3752 #endif
3753
3754 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3755 }
3756
3757 static test_return_t pre_replication(memcached_st *memc)
3758 {
3759 test_return_t test_rc;
3760 test_rc= pre_binary(memc);
3761
3762 if (test_rc != TEST_SUCCESS)
3763 return test_rc;
3764
3765 /*
3766 * Make sure that we store the item on all servers
3767 * (master + replicas == number of servers)
3768 */
3769 memcached_return_t rc;
3770 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3771 memcached_server_count(memc) - 1);
3772 test_true(rc == MEMCACHED_SUCCESS);
3773 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3774
3775 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3776 }
3777
3778
3779 static test_return_t pre_replication_noblock(memcached_st *memc)
3780 {
3781 test_return_t rc;
3782
3783 rc= pre_replication(memc);
3784 if (rc != TEST_SUCCESS)
3785 return rc;
3786
3787 rc= pre_nonblock(memc);
3788
3789 return rc;
3790 }
3791
3792
3793 static void my_free(const memcached_st *ptr, void *mem, void *context)
3794 {
3795 (void)context;
3796 (void)ptr;
3797 #ifdef HARD_MALLOC_TESTS
3798 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3799 free(real_ptr);
3800 #else
3801 free(mem);
3802 #endif
3803 }
3804
3805
3806 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
3807 {
3808 (void)context;
3809 (void)ptr;
3810 #ifdef HARD_MALLOC_TESTS
3811 void *ret= malloc(size + 8);
3812 if (ret != NULL)
3813 {
3814 ret= (void*)((caddr_t)ret + 8);
3815 }
3816 #else
3817 void *ret= malloc(size);
3818 #endif
3819
3820 if (ret != NULL)
3821 {
3822 memset(ret, 0xff, size);
3823 }
3824
3825 return ret;
3826 }
3827
3828
3829 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *context)
3830 {
3831 (void)context;
3832 #ifdef HARD_MALLOC_TESTS
3833 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3834 void *nmem= realloc(real_ptr, size + 8);
3835
3836 void *ret= NULL;
3837 if (nmem != NULL)
3838 {
3839 ret= (void*)((caddr_t)nmem + 8);
3840 }
3841
3842 return ret;
3843 #else
3844 (void)ptr;
3845 return realloc(mem, size);
3846 #endif
3847 }
3848
3849
3850 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *context)
3851 {
3852 (void)context;
3853 #ifdef HARD_MALLOC_TESTS
3854 void *mem= my_malloc(ptr, nelem * size);
3855 if (mem)
3856 {
3857 memset(mem, 0, nelem * size);
3858 }
3859
3860 return mem;
3861 #else
3862 (void)ptr;
3863 return calloc(nelem, size);
3864 #endif
3865 }
3866
3867 static test_return_t set_prefix(memcached_st *memc)
3868 {
3869 memcached_return_t rc;
3870 const char *key= "mine";
3871 char *value;
3872
3873 /* Make sure be default none exists */
3874 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3875 test_true(rc == MEMCACHED_FAILURE);
3876
3877 /* Test a clean set */
3878 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3879 test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc));
3880
3881 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3882 test_true(value);
3883 test_true(memcmp(value, key, 4) == 0);
3884 test_true(rc == MEMCACHED_SUCCESS);
3885
3886 /* Test that we can turn it off */
3887 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3888 test_true(rc == MEMCACHED_SUCCESS);
3889
3890 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3891 test_false(value);
3892 test_true(rc == MEMCACHED_FAILURE);
3893
3894 /* Now setup for main test */
3895 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3896 test_true(rc == MEMCACHED_SUCCESS);
3897
3898 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3899 test_true(value);
3900 test_true(rc == MEMCACHED_SUCCESS);
3901 test_true(memcmp(value, key, 4) == 0);
3902
3903 /* Set to Zero, and then Set to something too large */
3904 {
3905 char long_key[255];
3906 memset(long_key, 0, 255);
3907
3908 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3909 test_true(rc == MEMCACHED_SUCCESS);
3910
3911 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3912 test_false(value);
3913 test_true(rc == MEMCACHED_FAILURE);
3914 test_true(value == NULL);
3915
3916 /* Test a long key for failure */
3917 /* TODO, extend test to determine based on setting, what result should be */
3918 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
3919 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3920 //test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3921 test_true(rc == MEMCACHED_SUCCESS);
3922
3923 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3924 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
3925 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3926 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3927
3928 /* Test for a bad prefix, but with a short key */
3929 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3930 test_true(rc == MEMCACHED_SUCCESS);
3931
3932 strncpy(long_key, "dog cat", sizeof(long_key));
3933 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3934 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3935 }
3936
3937 return TEST_SUCCESS;
3938 }
3939
3940
3941 #ifdef MEMCACHED_ENABLE_DEPRECATED
3942 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3943 {
3944 void *test_ptr= NULL;
3945 void *cb_ptr= NULL;
3946 {
3947 memcached_malloc_fn malloc_cb=
3948 (memcached_malloc_fn)my_malloc;
3949 cb_ptr= *(void **)&malloc_cb;
3950 memcached_return_t rc;
3951
3952 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3953 test_true(rc == MEMCACHED_SUCCESS);
3954 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3955 test_true(rc == MEMCACHED_SUCCESS);
3956 test_true(test_ptr == cb_ptr);
3957 }
3958
3959 {
3960 memcached_realloc_fn realloc_cb=
3961 (memcached_realloc_fn)my_realloc;
3962 cb_ptr= *(void **)&realloc_cb;
3963 memcached_return_t rc;
3964
3965 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3966 test_true(rc == MEMCACHED_SUCCESS);
3967 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3968 test_true(rc == MEMCACHED_SUCCESS);
3969 test_true(test_ptr == cb_ptr);
3970 }
3971
3972 {
3973 memcached_free_fn free_cb=
3974 (memcached_free_fn)my_free;
3975 cb_ptr= *(void **)&free_cb;
3976 memcached_return_t rc;
3977
3978 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3979 test_true(rc == MEMCACHED_SUCCESS);
3980 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3981 test_true(rc == MEMCACHED_SUCCESS);
3982 test_true(test_ptr == cb_ptr);
3983 }
3984
3985 return TEST_SUCCESS;
3986 }
3987 #endif
3988
3989
3990 static test_return_t set_memory_alloc(memcached_st *memc)
3991 {
3992 memcached_return_t rc;
3993 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3994 my_realloc, my_calloc, NULL);
3995 test_true(rc == MEMCACHED_FAILURE);
3996
3997 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3998 my_realloc, my_calloc, NULL);
3999
4000 memcached_malloc_fn mem_malloc;
4001 memcached_free_fn mem_free;
4002 memcached_realloc_fn mem_realloc;
4003 memcached_calloc_fn mem_calloc;
4004 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
4005 &mem_realloc, &mem_calloc);
4006
4007 test_true(mem_malloc == my_malloc);
4008 test_true(mem_realloc == my_realloc);
4009 test_true(mem_calloc == my_calloc);
4010 test_true(mem_free == my_free);
4011
4012 return TEST_SUCCESS;
4013 }
4014
4015 static test_return_t enable_consistent_crc(memcached_st *memc)
4016 {
4017 test_return_t rc;
4018 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4019 memcached_hash_t hash;
4020 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4021 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
4022 return rc;
4023
4024 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4025 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4026
4027 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4028
4029 if (hash != MEMCACHED_HASH_CRC)
4030 return TEST_SKIPPED;
4031
4032 return TEST_SUCCESS;
4033 }
4034
4035 static test_return_t enable_consistent_hsieh(memcached_st *memc)
4036 {
4037 test_return_t rc;
4038 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4039 memcached_hash_t hash;
4040 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4041 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
4042 return rc;
4043
4044 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4045 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4046
4047 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4048
4049 if (hash != MEMCACHED_HASH_HSIEH)
4050 return TEST_SKIPPED;
4051
4052
4053 return TEST_SUCCESS;
4054 }
4055
4056 static test_return_t enable_cas(memcached_st *memc)
4057 {
4058 unsigned int set= 1;
4059
4060 if (libmemcached_util_version_check(memc, 1, 2, 4))
4061 {
4062 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
4063
4064 return TEST_SUCCESS;
4065 }
4066
4067 return TEST_SKIPPED;
4068 }
4069
4070 static test_return_t check_for_1_2_3(memcached_st *memc)
4071 {
4072 memcached_version(memc);
4073
4074 memcached_server_instance_st instance=
4075 memcached_server_instance_by_position(memc, 0);
4076
4077 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
4078 || instance->minor_version > 2)
4079 {
4080 return TEST_SUCCESS;
4081 }
4082
4083 return TEST_SKIPPED;
4084 }
4085
4086 static test_return_t pre_unix_socket(memcached_st *memc)
4087 {
4088 memcached_return_t rc;
4089 struct stat buf;
4090
4091 memcached_servers_reset(memc);
4092
4093 if (stat("/tmp/memcached.socket", &buf))
4094 return TEST_SKIPPED;
4095
4096 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
4097
4098 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
4099 }
4100
4101 static test_return_t pre_nodelay(memcached_st *memc)
4102 {
4103 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4104 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4105
4106 return TEST_SUCCESS;
4107 }
4108
4109 static test_return_t pre_settimer(memcached_st *memc)
4110 {
4111 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4112 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4113
4114 return TEST_SUCCESS;
4115 }
4116
4117 static test_return_t poll_timeout(memcached_st *memc)
4118 {
4119 size_t timeout;
4120
4121 timeout= 100;
4122
4123 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4124
4125 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
4126
4127 test_true(timeout == 100);
4128
4129 return TEST_SUCCESS;
4130 }
4131
4132 static test_return_t noreply_test(memcached_st *memc)
4133 {
4134 memcached_return_t ret;
4135 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4136 test_true(ret == MEMCACHED_SUCCESS);
4137 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4138 test_true(ret == MEMCACHED_SUCCESS);
4139 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
4140 test_true(ret == MEMCACHED_SUCCESS);
4141 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
4142 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
4143 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
4144
4145 for (int count=0; count < 5; ++count)
4146 {
4147 for (size_t x= 0; x < 100; ++x)
4148 {
4149 char key[10];
4150 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4151 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4152
4153 size_t len= (size_t)check_length;
4154
4155 switch (count)
4156 {
4157 case 0:
4158 ret= memcached_add(memc, key, len, key, len, 0, 0);
4159 break;
4160 case 1:
4161 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4162 break;
4163 case 2:
4164 ret= memcached_set(memc, key, len, key, len, 0, 0);
4165 break;
4166 case 3:
4167 ret= memcached_append(memc, key, len, key, len, 0, 0);
4168 break;
4169 case 4:
4170 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4171 break;
4172 default:
4173 test_true(count);
4174 break;
4175 }
4176 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
4177 }
4178
4179 /*
4180 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4181 ** API and is _ONLY_ done this way to verify that the library works the
4182 ** way it is supposed to do!!!!
4183 */
4184 int no_msg=0;
4185 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4186 {
4187 memcached_server_instance_st instance=
4188 memcached_server_instance_by_position(memc, x);
4189 no_msg+=(int)(instance->cursor_active);
4190 }
4191
4192 test_true(no_msg == 0);
4193 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4194
4195 /*
4196 ** Now validate that all items was set properly!
4197 */
4198 for (size_t x= 0; x < 100; ++x)
4199 {
4200 char key[10];
4201
4202 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4203
4204 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4205
4206 size_t len= (size_t)check_length;
4207 size_t length;
4208 uint32_t flags;
4209 char* value=memcached_get(memc, key, strlen(key),
4210 &length, &flags, &ret);
4211 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4212 switch (count)
4213 {
4214 case 0: /* FALLTHROUGH */
4215 case 1: /* FALLTHROUGH */
4216 case 2:
4217 test_true(strncmp(value, key, len) == 0);
4218 test_true(len == length);
4219 break;
4220 case 3:
4221 test_true(length == len * 2);
4222 break;
4223 case 4:
4224 test_true(length == len * 3);
4225 break;
4226 default:
4227 test_true(count);
4228 break;
4229 }
4230 free(value);
4231 }
4232 }
4233
4234 /* Try setting an illegal cas value (should not return an error to
4235 * the caller (because we don't expect a return message from the server)
4236 */
4237 const char* keys[]= {"0"};
4238 size_t lengths[]= {1};
4239 size_t length;
4240 uint32_t flags;
4241 memcached_result_st results_obj;
4242 memcached_result_st *results;
4243 ret= memcached_mget(memc, keys, lengths, 1);
4244 test_true(ret == MEMCACHED_SUCCESS);
4245
4246 results= memcached_result_create(memc, &results_obj);
4247 test_true(results);
4248 results= memcached_fetch_result(memc, &results_obj, &ret);
4249 test_true(results);
4250 test_true(ret == MEMCACHED_SUCCESS);
4251 uint64_t cas= memcached_result_cas(results);
4252 memcached_result_free(&results_obj);
4253
4254 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4255 test_true(ret == MEMCACHED_SUCCESS);
4256
4257 /*
4258 * The item will have a new cas value, so try to set it again with the old
4259 * value. This should fail!
4260 */
4261 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4262 test_true(ret == MEMCACHED_SUCCESS);
4263 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4264 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4265 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4266 free(value);
4267
4268 return TEST_SUCCESS;
4269 }
4270
4271 static test_return_t analyzer_test(memcached_st *memc)
4272 {
4273 memcached_return_t rc;
4274 memcached_stat_st *memc_stat;
4275 memcached_analysis_st *report;
4276
4277 memc_stat= memcached_stat(memc, NULL, &rc);
4278 test_true(rc == MEMCACHED_SUCCESS);
4279 test_true(memc_stat);
4280
4281 report= memcached_analyze(memc, memc_stat, &rc);
4282 test_true(rc == MEMCACHED_SUCCESS);
4283 test_true(report);
4284
4285 free(report);
4286 memcached_stat_free(NULL, memc_stat);
4287
4288 return TEST_SUCCESS;
4289 }
4290
4291 /* Count the objects */
4292 static memcached_return_t callback_dump_counter(const memcached_st *ptr,
4293 const char *key,
4294 size_t key_length,
4295 void *context)
4296 {
4297 (void)ptr; (void)key; (void)key_length;
4298 size_t *counter= (size_t *)context;
4299
4300 *counter= *counter + 1;
4301
4302 return MEMCACHED_SUCCESS;
4303 }
4304
4305 static test_return_t dump_test(memcached_st *memc)
4306 {
4307 memcached_return_t rc;
4308 size_t counter= 0;
4309 memcached_dump_fn callbacks[1];
4310 test_return_t main_rc;
4311
4312 callbacks[0]= &callback_dump_counter;
4313
4314 /* No support for Binary protocol yet */
4315 if (memc->flags.binary_protocol)
4316 return TEST_SUCCESS;
4317
4318 main_rc= set_test3(memc);
4319
4320 test_true (main_rc == TEST_SUCCESS);
4321
4322 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4323 test_true(rc == MEMCACHED_SUCCESS);
4324
4325 /* We may have more then 32 if our previous flush has not completed */
4326 test_true(counter >= 32);
4327
4328 return TEST_SUCCESS;
4329 }
4330
4331 #ifdef HAVE_LIBMEMCACHEDUTIL
4332
4333 struct test_pool_context_st {
4334 memcached_pool_st* pool;
4335 memcached_st* mmc;
4336 };
4337
4338 static void* connection_release(void *arg)
4339 {
4340 test_pool_context_st *resource= static_cast<test_pool_context_st *>(arg);
4341
4342 usleep(250);
4343 // Release all of the memc we are holding
4344 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4345 return arg;
4346 }
4347
4348 #define POOL_SIZE 10
4349 static test_return_t connection_pool_test(memcached_st *memc)
4350 {
4351 memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE);
4352 test_true(pool != NULL);
4353 memcached_st *mmc[POOL_SIZE];
4354 memcached_return_t rc;
4355
4356 // Fill up our array that we will store the memc that are in the pool
4357 for (size_t x= 0; x < POOL_SIZE; ++x)
4358 {
4359 mmc[x]= memcached_pool_pop(pool, false, &rc);
4360 test_true(mmc[x] != NULL);
4361 test_true(rc == MEMCACHED_SUCCESS);
4362 }
4363
4364 // All memc should be gone
4365 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4366 test_true(rc == MEMCACHED_SUCCESS);
4367
4368 pthread_t tid;
4369 test_pool_context_st item= { pool, mmc[9] };
4370
4371 pthread_create(&tid, NULL, connection_release, &item);
4372 mmc[9]= memcached_pool_pop(pool, true, &rc);
4373 test_true(rc == MEMCACHED_SUCCESS);
4374 pthread_join(tid, NULL);
4375 test_true(mmc[9]);
4376 const char *key= "key";
4377 size_t keylen= strlen(key);
4378
4379 // verify that I can do ops with all connections
4380 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4381 test_true(rc == MEMCACHED_SUCCESS);
4382
4383 for (size_t x= 0; x < POOL_SIZE; ++x)
4384 {
4385 uint64_t number_value;
4386 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4387 test_true(rc == MEMCACHED_SUCCESS);
4388 test_true(number_value == (x+1));
4389 }
4390
4391 // Release them..
4392 for (size_t x= 0; x < POOL_SIZE; ++x)
4393 {
4394 test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4395 }
4396
4397
4398 /* verify that I can set behaviors on the pool when I don't have all
4399 * of the connections in the pool. It should however be enabled
4400 * when I push the item into the pool
4401 */
4402 mmc[0]= memcached_pool_pop(pool, false, &rc);
4403 test_true(mmc[0] != NULL);
4404
4405 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4406 test_true(rc == MEMCACHED_SUCCESS);
4407
4408 mmc[1]= memcached_pool_pop(pool, false, &rc);
4409 test_true(mmc[1] != NULL);
4410
4411 test_true(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4412 test_true(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4413 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4414
4415 mmc[0]= memcached_pool_pop(pool, false, &rc);
4416 test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4417 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4418
4419 test_true(memcached_pool_destroy(pool) == memc);
4420
4421 return TEST_SUCCESS;
4422 }
4423
4424 static test_return_t util_version_test(memcached_st *memc)
4425 {
4426 bool if_successful;
4427
4428 if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
4429 test_true(if_successful == true);
4430
4431 if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
4432
4433 // We expect failure
4434 if (if_successful)
4435 {
4436 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4437 fprintf(stderr, "\nDumping Server Information\n\n");
4438 memcached_server_fn callbacks[1];
4439
4440 callbacks[0]= dump_server_information;
4441 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
4442 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4443 }
4444 test_true(if_successful == false);
4445
4446 memcached_server_instance_st instance=
4447 memcached_server_instance_by_position(memc, 0);
4448
4449 memcached_version(memc);
4450
4451 // We only use one binary when we test, so this should be just fine.
4452 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
4453 test_true(if_successful == true);
4454
4455 if (instance->micro_version > 0)
4456 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
4457 else if (instance->minor_version > 0)
4458 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4459 else if (instance->major_version > 0)
4460 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
4461
4462 test_true(if_successful == true);
4463
4464 if (instance->micro_version > 0)
4465 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
4466 else if (instance->minor_version > 0)
4467 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4468 else if (instance->major_version > 0)
4469 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
4470
4471 test_true(if_successful == false);
4472
4473 return TEST_SUCCESS;
4474 }
4475
4476 static test_return_t ping_test(memcached_st *memc)
4477 {
4478 memcached_return_t rc;
4479 memcached_server_instance_st instance=
4480 memcached_server_instance_by_position(memc, 0);
4481
4482 // Test both the version that returns a code, and the one that does not.
4483 test_true(libmemcached_util_ping(memcached_server_name(instance),
4484 memcached_server_port(instance), NULL));
4485
4486 test_true(libmemcached_util_ping(memcached_server_name(instance),
4487 memcached_server_port(instance), &rc));
4488
4489 test_true(rc == MEMCACHED_SUCCESS);
4490
4491 return TEST_SUCCESS;
4492 }
4493 #endif
4494
4495
4496 #if 0
4497 static test_return_t hash_sanity_test (memcached_st *memc)
4498 {
4499 (void)memc;
4500
4501 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4502 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4503 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4504 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4505 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4506 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4507 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4508 #ifdef HAVE_HSIEH_HASH
4509 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4510 #endif
4511 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4512 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4513 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4514
4515 return TEST_SUCCESS;
4516 }
4517 #endif
4518
4519 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4520 {
4521 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4522 #ifdef HAVE_HSIEH_HASH
4523 expected_rc= MEMCACHED_SUCCESS;
4524 #endif
4525 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4526 (uint64_t)MEMCACHED_HASH_HSIEH);
4527 test_true(rc == expected_rc);
4528
4529 return TEST_SUCCESS;
4530 }
4531
4532 static test_return_t murmur_avaibility_test (memcached_st *memc)
4533 {
4534 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4535 #ifdef HAVE_MURMUR_HASH
4536 expected_rc= MEMCACHED_SUCCESS;
4537 #endif
4538 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4539 (uint64_t)MEMCACHED_HASH_MURMUR);
4540 test_true(rc == expected_rc);
4541
4542 return TEST_SUCCESS;
4543 }
4544
4545 static test_return_t one_at_a_time_run (memcached_st *memc)
4546 {
4547 uint32_t x;
4548 const char **ptr;
4549 (void)memc;
4550
4551 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4552 {
4553 uint32_t hash_val;
4554
4555 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT);
4556 test_true(one_at_a_time_values[x] == hash_val);
4557 }
4558
4559 return TEST_SUCCESS;
4560 }
4561
4562 static test_return_t md5_run (memcached_st *memc)
4563 {
4564 uint32_t x;
4565 const char **ptr;
4566 (void)memc;
4567
4568 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4569 {
4570 uint32_t hash_val;
4571
4572 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4573 test_true(md5_values[x] == hash_val);
4574 }
4575
4576 return TEST_SUCCESS;
4577 }
4578
4579 static test_return_t crc_run (memcached_st *memc)
4580 {
4581 uint32_t x;
4582 const char **ptr;
4583 (void)memc;
4584
4585 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4586 {
4587 uint32_t hash_val;
4588
4589 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4590 test_true(crc_values[x] == hash_val);
4591 }
4592
4593 return TEST_SUCCESS;
4594 }
4595
4596 static test_return_t fnv1_64_run (memcached_st *memc)
4597 {
4598 uint32_t x;
4599 const char **ptr;
4600 (void)memc;
4601
4602 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4603 {
4604 uint32_t hash_val;
4605
4606 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4607 test_true(fnv1_64_values[x] == hash_val);
4608 }
4609
4610 return TEST_SUCCESS;
4611 }
4612
4613 static test_return_t fnv1a_64_run (memcached_st *memc)
4614 {
4615 uint32_t x;
4616 const char **ptr;
4617 (void)memc;
4618
4619 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4620 {
4621 uint32_t hash_val;
4622
4623 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4624 test_true(fnv1a_64_values[x] == hash_val);
4625 }
4626
4627 return TEST_SUCCESS;
4628 }
4629
4630 static test_return_t fnv1_32_run (memcached_st *memc)
4631 {
4632 uint32_t x;
4633 const char **ptr;
4634 (void)memc;
4635
4636 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4637 {
4638 uint32_t hash_val;
4639
4640 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4641 test_true(fnv1_32_values[x] == hash_val);
4642 }
4643
4644 return TEST_SUCCESS;
4645 }
4646
4647 static test_return_t fnv1a_32_run (memcached_st *memc)
4648 {
4649 uint32_t x;
4650 const char **ptr;
4651 (void)memc;
4652
4653 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4654 {
4655 uint32_t hash_val;
4656
4657 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4658 test_true(fnv1a_32_values[x] == hash_val);
4659 }
4660
4661 return TEST_SUCCESS;
4662 }
4663
4664 static test_return_t hsieh_run (memcached_st *memc)
4665 {
4666 uint32_t x;
4667 const char **ptr;
4668 (void)memc;
4669
4670 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4671 {
4672 uint32_t hash_val;
4673
4674 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4675 test_true(hsieh_values[x] == hash_val);
4676 }
4677
4678 return TEST_SUCCESS;
4679 }
4680
4681 static test_return_t murmur_run (memcached_st *memc)
4682 {
4683 #ifdef WORDS_BIGENDIAN
4684 (void)murmur_values;
4685 return TEST_SKIPPED;
4686 #else
4687 uint32_t x;
4688 const char **ptr;
4689 (void)memc;
4690
4691 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4692 {
4693 uint32_t hash_val;
4694
4695 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4696 test_true(murmur_values[x] == hash_val);
4697 }
4698
4699 return TEST_SUCCESS;
4700 #endif
4701 }
4702
4703 static test_return_t jenkins_run (memcached_st *memc)
4704 {
4705 uint32_t x;
4706 const char **ptr;
4707 (void)memc;
4708
4709 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4710 {
4711 uint32_t hash_val;
4712
4713 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4714 test_true(jenkins_values[x] == hash_val);
4715 }
4716
4717 return TEST_SUCCESS;
4718 }
4719
4720 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *context)
4721 {
4722 (void)context;
4723 return libhashkit_md5(string, string_length);
4724 }
4725
4726 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *context)
4727 {
4728 (void)context;
4729 return libhashkit_crc32(string, string_length);
4730 }
4731
4732 static test_return_t memcached_get_hashkit_test (memcached_st *memc)
4733 {
4734 uint32_t x;
4735 const char **ptr;
4736 const hashkit_st *kit;
4737 hashkit_st new_kit;
4738 hashkit_return_t hash_rc;
4739
4740 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};
4741 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};
4742
4743 kit= memcached_get_hashkit(memc);
4744
4745 hashkit_clone(&new_kit, kit);
4746 hash_rc= hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL);
4747 test_true(hash_rc == HASHKIT_SUCCESS);
4748
4749 memcached_set_hashkit(memc, &new_kit);
4750
4751 /*
4752 Verify Setting the hash.
4753 */
4754 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4755 {
4756 uint32_t hash_val;
4757
4758 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4759 test_true(md5_values[x] == hash_val);
4760 }
4761
4762
4763 /*
4764 Now check memcached_st.
4765 */
4766 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4767 {
4768 uint32_t hash_val;
4769
4770 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4771 test_true(md5_hosts[x] == hash_val);
4772 }
4773
4774 hash_rc= hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL);
4775 test_true(hash_rc == HASHKIT_SUCCESS);
4776
4777 memcached_set_hashkit(memc, &new_kit);
4778
4779 /*
4780 Verify Setting the hash.
4781 */
4782 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4783 {
4784 uint32_t hash_val;
4785
4786 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4787 test_true(crc_values[x] == hash_val);
4788 }
4789
4790 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4791 {
4792 uint32_t hash_val;
4793
4794 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4795 test_true(crc_hosts[x] == hash_val);
4796 }
4797
4798 return TEST_SUCCESS;
4799 }
4800
4801 /*
4802 Test case adapted from John Gorman <johngorman2@gmail.com>
4803
4804 We are testing the error condition when we connect to a server via memcached_get()
4805 but find that the server is not available.
4806 */
4807 static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
4808 {
4809 (void)memc;
4810 memcached_st *tl_memc_h;
4811 memcached_server_st *servers;
4812
4813 const char *key= "MemcachedLives";
4814 size_t len;
4815 uint32_t flags;
4816 memcached_return rc;
4817 char *value;
4818
4819 // Create a handle.
4820 tl_memc_h= memcached_create(NULL);
4821 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4822 memcached_server_push(tl_memc_h, servers);
4823 memcached_server_list_free(servers);
4824
4825 // See if memcached is reachable.
4826 value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
4827
4828 test_false(value);
4829 test_true(len == 0);
4830 test_false(rc == MEMCACHED_SUCCESS);
4831
4832 memcached_free(tl_memc_h);
4833
4834 return TEST_SUCCESS;
4835 }
4836
4837 /*
4838 We connect to a server which exists, but search for a key that does not exist.
4839 */
4840 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
4841 {
4842 const char *key= "MemcachedKeyNotEXIST";
4843 size_t len;
4844 uint32_t flags;
4845 memcached_return rc;
4846 char *value;
4847
4848 // See if memcached is reachable.
4849 value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
4850
4851 test_false(value);
4852 test_true(len == 0);
4853 test_true(rc == MEMCACHED_NOTFOUND);
4854
4855 return TEST_SUCCESS;
4856 }
4857
4858 /*
4859 Test case adapted from John Gorman <johngorman2@gmail.com>
4860
4861 We are testing the error condition when we connect to a server via memcached_get_by_key()
4862 but find that the server is not available.
4863 */
4864 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
4865 {
4866 (void)memc;
4867 memcached_st *tl_memc_h;
4868 memcached_server_st *servers;
4869
4870 const char *key= "MemcachedLives";
4871 size_t len;
4872 uint32_t flags;
4873 memcached_return rc;
4874 char *value;
4875
4876 // Create a handle.
4877 tl_memc_h= memcached_create(NULL);
4878 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4879 memcached_server_push(tl_memc_h, servers);
4880 memcached_server_list_free(servers);
4881
4882 // See if memcached is reachable.
4883 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4884
4885 test_false(value);
4886 test_true(len == 0);
4887 test_false(rc == MEMCACHED_SUCCESS);
4888
4889 memcached_free(tl_memc_h);
4890
4891 return TEST_SUCCESS;
4892 }
4893
4894 /*
4895 We connect to a server which exists, but search for a key that does not exist.
4896 */
4897 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
4898 {
4899 const char *key= "MemcachedKeyNotEXIST";
4900 size_t len;
4901 uint32_t flags;
4902 memcached_return rc;
4903 char *value;
4904
4905 // See if memcached is reachable.
4906 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4907
4908 test_false(value);
4909 test_true(len == 0);
4910 test_true(rc == MEMCACHED_NOTFOUND);
4911
4912 return TEST_SUCCESS;
4913 }
4914
4915
4916 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4917 {
4918 memcached_return_t rc;
4919 uint64_t value;
4920 int x;
4921 memcached_server_st *server_pool;
4922 memcached_st *memc;
4923
4924 (void)trash;
4925
4926 memc= memcached_create(NULL);
4927 test_true(memc);
4928
4929 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4930 test_true(rc == MEMCACHED_SUCCESS);
4931
4932 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4933 test_true(value == 1);
4934
4935 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
4936 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
4937
4938
4939 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
4940 memcached_server_push(memc, server_pool);
4941
4942 /* verify that the server list was parsed okay. */
4943 test_true(memcached_server_count(memc) == 8);
4944 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4945 test_true(server_pool[0].port == 11211);
4946 test_true(server_pool[0].weight == 600);
4947 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4948 test_true(server_pool[2].port == 11211);
4949 test_true(server_pool[2].weight == 200);
4950 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4951 test_true(server_pool[7].port == 11211);
4952 test_true(server_pool[7].weight == 100);
4953
4954 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4955 * us test the boundary wraparound.
4956 */
4957 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
4958
4959 /* verify the standard ketama set. */
4960 for (x= 0; x < 99; x++)
4961 {
4962 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4963 memcached_server_instance_st instance=
4964 memcached_server_instance_by_position(memc, server_idx);
4965 const char *hostname = memcached_server_name(instance);
4966
4967 test_strcmp(hostname, ketama_test_cases[x].server);
4968 }
4969
4970 memcached_server_list_free(server_pool);
4971 memcached_free(memc);
4972
4973 return TEST_SUCCESS;
4974 }
4975
4976 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4977 {
4978 memcached_return_t rc;
4979 uint64_t value;
4980 memcached_server_st *server_pool;
4981 memcached_st *memc;
4982
4983 (void)trash;
4984
4985 memc= memcached_create(NULL);
4986 test_true(memc);
4987
4988 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4989 test_true(rc == MEMCACHED_SUCCESS);
4990
4991 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4992 test_true(value == 1);
4993
4994 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
4995 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
4996
4997 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
4998 assert(server_pool);
4999 memcached_server_push(memc, server_pool);
5000
5001 /* verify that the server list was parsed okay. */
5002 test_true(memcached_server_count(memc) == 8);
5003 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5004 test_true(server_pool[0].port == 11211);
5005 test_true(server_pool[0].weight == 600);
5006 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5007 test_true(server_pool[2].port == 11211);
5008 test_true(server_pool[2].weight == 200);
5009 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5010 test_true(server_pool[7].port == 11211);
5011 test_true(server_pool[7].weight == 100);
5012
5013 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5014 * us test the boundary wraparound.
5015 */
5016 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
5017
5018 /* verify the standard ketama set. */
5019 for (uint32_t x= 0; x < 99; x++)
5020 {
5021 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5022
5023 memcached_server_instance_st instance=
5024 memcached_server_instance_by_position(memc, server_idx);
5025
5026 const char *hostname= memcached_server_name(instance);
5027
5028 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5029 }
5030
5031 memcached_server_list_free(server_pool);
5032 memcached_free(memc);
5033
5034 return TEST_SUCCESS;
5035 }
5036
5037 static test_return_t regression_bug_434484(memcached_st *memc)
5038 {
5039 test_return_t test_rc;
5040 test_rc= pre_binary(memc);
5041
5042 if (test_rc != TEST_SUCCESS)
5043 return test_rc;
5044
5045 const char *key= "regression_bug_434484";
5046 size_t keylen= strlen(key);
5047
5048 memcached_return_t ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5049 test_true(ret == MEMCACHED_NOTSTORED);
5050
5051 size_t size= 2048 * 1024;
5052 char *data= (char*)calloc(1, size);
5053 test_true(data);
5054 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5055 test_true(ret == MEMCACHED_E2BIG);
5056 free(data);
5057
5058 return TEST_SUCCESS;
5059 }
5060
5061 static test_return_t regression_bug_434843(memcached_st *memc)
5062 {
5063 test_return_t test_rc;
5064 test_rc= pre_binary(memc);
5065
5066 if (test_rc != TEST_SUCCESS)
5067 return test_rc;
5068
5069 memcached_return_t rc;
5070 size_t counter= 0;
5071 memcached_execute_fn callbacks[]= { &callback_counter };
5072
5073 /*
5074 * I only want to hit only _one_ server so I know the number of requests I'm
5075 * sending in the pipleine to the server. Let's try to do a multiget of
5076 * 1024 (that should satisfy most users don't you think?). Future versions
5077 * will include a mget_execute function call if you need a higher number.
5078 */
5079 uint32_t number_of_hosts= memcached_server_count(memc);
5080 memc->number_of_hosts= 1;
5081 const size_t max_keys= 1024;
5082 char **keys= (char**)calloc(max_keys, sizeof(char*));
5083 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5084
5085 for (size_t x= 0; x < max_keys; ++x)
5086 {
5087 char k[251];
5088
5089 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5090 keys[x]= strdup(k);
5091 test_true(keys[x] != NULL);
5092 }
5093
5094 /*
5095 * Run two times.. the first time we should have 100% cache miss,
5096 * and the second time we should have 100% cache hits
5097 */
5098 for (size_t y= 0; y < 2; y++)
5099 {
5100 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5101 test_true(rc == MEMCACHED_SUCCESS);
5102 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5103
5104 if (y == 0)
5105 {
5106 /* The first iteration should give me a 100% cache miss. verify that*/
5107 char blob[1024]= { 0 };
5108
5109 test_true(counter == 0);
5110
5111 for (size_t x= 0; x < max_keys; ++x)
5112 {
5113 rc= memcached_add(memc, keys[x], key_length[x],
5114 blob, sizeof(blob), 0, 0);
5115 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5116 }
5117 }
5118 else
5119 {
5120 /* Verify that we received all of the key/value pairs */
5121 test_true(counter == max_keys);
5122 }
5123 }
5124
5125 /* Release allocated resources */
5126 for (size_t x= 0; x < max_keys; ++x)
5127 {
5128 free(keys[x]);
5129 }
5130 free(keys);
5131 free(key_length);
5132
5133 memc->number_of_hosts= number_of_hosts;
5134
5135 return TEST_SUCCESS;
5136 }
5137
5138 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5139 {
5140 memcached_return_t rc;
5141 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5142 test_true(rc == MEMCACHED_SUCCESS);
5143
5144 return regression_bug_434843(memc);
5145 }
5146
5147 static test_return_t regression_bug_421108(memcached_st *memc)
5148 {
5149 memcached_return_t rc;
5150 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5151 test_true(rc == MEMCACHED_SUCCESS);
5152
5153 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5154 test_true(rc == MEMCACHED_SUCCESS);
5155 test_true(bytes != NULL);
5156 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5157 "bytes_read", &rc);
5158 test_true(rc == MEMCACHED_SUCCESS);
5159 test_true(bytes_read != NULL);
5160
5161 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5162 "bytes_written", &rc);
5163 test_true(rc == MEMCACHED_SUCCESS);
5164 test_true(bytes_written != NULL);
5165
5166 test_true(strcmp(bytes, bytes_read) != 0);
5167 test_true(strcmp(bytes, bytes_written) != 0);
5168
5169 /* Release allocated resources */
5170 free(bytes);
5171 free(bytes_read);
5172 free(bytes_written);
5173 memcached_stat_free(NULL, memc_stat);
5174
5175 return TEST_SUCCESS;
5176 }
5177
5178 /*
5179 * The test case isn't obvious so I should probably document why
5180 * it works the way it does. Bug 442914 was caused by a bug
5181 * in the logic in memcached_purge (it did not handle the case
5182 * where the number of bytes sent was equal to the watermark).
5183 * In this test case, create messages so that we hit that case
5184 * and then disable noreply mode and issue a new command to
5185 * verify that it isn't stuck. If we change the format for the
5186 * delete command or the watermarks, we need to update this
5187 * test....
5188 */
5189 static test_return_t regression_bug_442914(memcached_st *memc)
5190 {
5191 memcached_return_t rc;
5192 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5193 test_true(rc == MEMCACHED_SUCCESS);
5194 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5195
5196 uint32_t number_of_hosts= memcached_server_count(memc);
5197 memc->number_of_hosts= 1;
5198
5199 char k[250];
5200 size_t len;
5201
5202 for (uint32_t x= 0; x < 250; ++x)
5203 {
5204 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5205 rc= memcached_delete(memc, k, len, 0);
5206 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5207 }
5208
5209 (void)snprintf(k, sizeof(k), "%037u", 251U);
5210 len= strlen(k);
5211
5212 rc= memcached_delete(memc, k, len, 0);
5213 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5214
5215 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5216 test_true(rc == MEMCACHED_SUCCESS);
5217 rc= memcached_delete(memc, k, len, 0);
5218 test_true(rc == MEMCACHED_NOTFOUND);
5219
5220 memc->number_of_hosts= number_of_hosts;
5221
5222 return TEST_SUCCESS;
5223 }
5224
5225 static test_return_t regression_bug_447342(memcached_st *memc)
5226 {
5227 memcached_server_instance_st instance_one;
5228 memcached_server_instance_st instance_two;
5229
5230 if (memcached_server_count(memc) < 3 || pre_replication(memc) != TEST_SUCCESS)
5231 return TEST_SKIPPED;
5232
5233 memcached_return_t rc;
5234
5235 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5236 test_true(rc == MEMCACHED_SUCCESS);
5237
5238 const size_t max_keys= 100;
5239 char **keys= (char**)calloc(max_keys, sizeof(char*));
5240 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5241
5242 for (size_t x= 0; x < max_keys; ++x)
5243 {
5244 char k[251];
5245
5246 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5247 keys[x]= strdup(k);
5248 test_true(keys[x] != NULL);
5249 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5250 test_true(rc == MEMCACHED_SUCCESS);
5251 }
5252
5253 /*
5254 ** We are using the quiet commands to store the replicas, so we need
5255 ** to ensure that all of them are processed before we can continue.
5256 ** In the test we go directly from storing the object to trying to
5257 ** receive the object from all of the different servers, so we
5258 ** could end up in a race condition (the memcached server hasn't yet
5259 ** processed the quiet command from the replication set when it process
5260 ** the request from the other client (created by the clone)). As a
5261 ** workaround for that we call memcached_quit to send the quit command
5262 ** to the server and wait for the response ;-) If you use the test code
5263 ** as an example for your own code, please note that you shouldn't need
5264 ** to do this ;-)
5265 */
5266 memcached_quit(memc);
5267
5268 /* Verify that all messages are stored, and we didn't stuff too much
5269 * into the servers
5270 */
5271 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5272 test_true(rc == MEMCACHED_SUCCESS);
5273
5274 size_t counter= 0;
5275 memcached_execute_fn callbacks[]= { &callback_counter };
5276 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5277 /* Verify that we received all of the key/value pairs */
5278 test_true(counter == max_keys);
5279
5280 memcached_quit(memc);
5281 /*
5282 * Don't do the following in your code. I am abusing the internal details
5283 * within the library, and this is not a supported interface.
5284 * This is to verify correct behavior in the library. Fake that two servers
5285 * are dead..
5286 */
5287 instance_one= memcached_server_instance_by_position(memc, 0);
5288 instance_two= memcached_server_instance_by_position(memc, 2);
5289 in_port_t port0= instance_one->port;
5290 in_port_t port2= instance_two->port;
5291
5292 ((memcached_server_write_instance_st)instance_one)->port= 0;
5293 ((memcached_server_write_instance_st)instance_two)->port= 0;
5294
5295 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5296 test_true(rc == MEMCACHED_SUCCESS);
5297
5298 counter= 0;
5299 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5300 test_true(counter == (unsigned int)max_keys);
5301
5302 /* restore the memc handle */
5303 ((memcached_server_write_instance_st)instance_one)->port= port0;
5304 ((memcached_server_write_instance_st)instance_two)->port= port2;
5305
5306 memcached_quit(memc);
5307
5308 /* Remove half of the objects */
5309 for (size_t x= 0; x < max_keys; ++x)
5310 {
5311 if (x & 1)
5312 {
5313 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5314 test_true(rc == MEMCACHED_SUCCESS);
5315 }
5316 }
5317
5318 memcached_quit(memc);
5319 ((memcached_server_write_instance_st)instance_one)->port= 0;
5320 ((memcached_server_write_instance_st)instance_two)->port= 0;
5321
5322 /* now retry the command, this time we should have cache misses */
5323 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5324 test_true(rc == MEMCACHED_SUCCESS);
5325
5326 counter= 0;
5327 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5328 test_true(counter == (unsigned int)(max_keys >> 1));
5329
5330 /* Release allocated resources */
5331 for (size_t x= 0; x < max_keys; ++x)
5332 {
5333 free(keys[x]);
5334 }
5335 free(keys);
5336 free(key_length);
5337
5338 /* restore the memc handle */
5339 ((memcached_server_write_instance_st)instance_one)->port= port0;
5340 ((memcached_server_write_instance_st)instance_two)->port= port2;
5341
5342 return TEST_SUCCESS;
5343 }
5344
5345 static test_return_t regression_bug_463297(memcached_st *memc)
5346 {
5347 memcached_st *memc_clone= memcached_clone(NULL, memc);
5348 test_true(memc_clone != NULL);
5349 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5350
5351 memcached_server_instance_st instance=
5352 memcached_server_instance_by_position(memc_clone, 0);
5353
5354 if (instance->major_version > 1 ||
5355 (instance->major_version == 1 &&
5356 instance->minor_version > 2))
5357 {
5358 /* Binary protocol doesn't support deferred delete */
5359 memcached_st *bin_clone= memcached_clone(NULL, memc);
5360 test_true(bin_clone != NULL);
5361 test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5362 test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5363 memcached_free(bin_clone);
5364
5365 memcached_quit(memc_clone);
5366
5367 /* If we know the server version, deferred delete should fail
5368 * with invalid arguments */
5369 test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5370
5371 /* If we don't know the server version, we should get a protocol error */
5372 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5373
5374 /* but there is a bug in some of the memcached servers (1.4) that treats
5375 * the counter as noreply so it doesn't send the proper error message
5376 */
5377 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5378
5379 /* And buffered mode should be disabled and we should get protocol error */
5380 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5381 rc= memcached_delete(memc, "foo", 3, 1);
5382 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5383
5384 /* Same goes for noreply... */
5385 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5386 rc= memcached_delete(memc, "foo", 3, 1);
5387 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5388
5389 /* but a normal request should go through (and be buffered) */
5390 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5391 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5392
5393 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5394 /* unbuffered noreply should be success */
5395 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5396 /* unbuffered with reply should be not found... */
5397 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5398 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5399 }
5400
5401 memcached_free(memc_clone);
5402 return TEST_SUCCESS;
5403 }
5404
5405
5406 /* Test memcached_server_get_last_disconnect
5407 * For a working server set, shall be NULL
5408 * For a set of non existing server, shall not be NULL
5409 */
5410 static test_return_t test_get_last_disconnect(memcached_st *memc)
5411 {
5412 memcached_return_t rc;
5413 memcached_server_instance_st disconnected_server;
5414
5415 /* With the working set of server */
5416 const char *key= "marmotte";
5417 const char *value= "milka";
5418
5419 memcached_reset_last_disconnected_server(memc);
5420 rc= memcached_set(memc, key, strlen(key),
5421 value, strlen(value),
5422 (time_t)0, (uint32_t)0);
5423 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5424
5425 disconnected_server = memcached_server_get_last_disconnect(memc);
5426 test_true(disconnected_server == NULL);
5427
5428 /* With a non existing server */
5429 memcached_st *mine;
5430 memcached_server_st *servers;
5431
5432 const char *server_list= "localhost:9";
5433
5434 servers= memcached_servers_parse(server_list);
5435 test_true(servers);
5436 mine= memcached_create(NULL);
5437 rc= memcached_server_push(mine, servers);
5438 test_true(rc == MEMCACHED_SUCCESS);
5439 memcached_server_list_free(servers);
5440 test_true(mine);
5441
5442 rc= memcached_set(mine, key, strlen(key),
5443 value, strlen(value),
5444 (time_t)0, (uint32_t)0);
5445 test_true(rc != MEMCACHED_SUCCESS);
5446
5447 disconnected_server= memcached_server_get_last_disconnect(mine);
5448 if (disconnected_server == NULL)
5449 {
5450 fprintf(stderr, "RC %s\n", memcached_strerror(mine, rc));
5451 abort();
5452 }
5453 test_true(disconnected_server != NULL);
5454 test_true(memcached_server_port(disconnected_server)== 9);
5455 test_true(strncmp(memcached_server_name(disconnected_server),"localhost",9) == 0);
5456
5457 memcached_quit(mine);
5458 memcached_free(mine);
5459
5460 return TEST_SUCCESS;
5461 }
5462
5463 static test_return_t test_verbosity(memcached_st *memc)
5464 {
5465 memcached_verbosity(memc, 3);
5466
5467 return TEST_SUCCESS;
5468 }
5469
5470 static test_return_t test_server_failure(memcached_st *memc)
5471 {
5472 memcached_st *local_memc;
5473 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
5474
5475 local_memc= memcached_create(NULL);
5476
5477 memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
5478 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
5479
5480 uint32_t server_count= memcached_server_count(local_memc);
5481
5482 test_true(server_count == 1);
5483
5484 // Disable the server
5485 instance= memcached_server_instance_by_position(local_memc, 0);
5486 ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
5487
5488 memcached_return_t rc;
5489 rc= memcached_set(local_memc, "foo", strlen("foo"),
5490 NULL, 0,
5491 (time_t)0, (uint32_t)0);
5492 test_true(rc == MEMCACHED_SERVER_MARKED_DEAD);
5493
5494 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5495 rc= memcached_set(local_memc, "foo", strlen("foo"),
5496 NULL, 0,
5497 (time_t)0, (uint32_t)0);
5498 test_true(rc == MEMCACHED_SUCCESS);
5499
5500
5501 memcached_free(local_memc);
5502
5503 return TEST_SUCCESS;
5504 }
5505
5506 static test_return_t test_cull_servers(memcached_st *memc)
5507 {
5508 uint32_t count = memcached_server_count(memc);
5509
5510 // Do not do this in your code, it is not supported.
5511 memc->servers[1].options.is_dead= true;
5512 memc->state.is_time_for_rebuild= true;
5513
5514 uint32_t new_count= memcached_server_count(memc);
5515 test_true(count == new_count);
5516
5517 #if 0
5518 test_true(count == new_count + 1 );
5519 #endif
5520
5521 return TEST_SUCCESS;
5522 }
5523
5524
5525 static memcached_return_t stat_printer(memcached_server_instance_st server,
5526 const char *key, size_t key_length,
5527 const char *value, size_t value_length,
5528 void *context)
5529 {
5530 (void)server;
5531 (void)context;
5532 (void)key;
5533 (void)key_length;
5534 (void)value;
5535 (void)value_length;
5536
5537 return MEMCACHED_SUCCESS;
5538 }
5539
5540 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5541 {
5542 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5543 test_true(rc == MEMCACHED_SUCCESS);
5544
5545 rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL);
5546 test_true(rc == MEMCACHED_SUCCESS);
5547
5548 rc= memcached_stat_execute(memc, "items", stat_printer, NULL);
5549 test_true(rc == MEMCACHED_SUCCESS);
5550
5551 rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL);
5552 test_true(rc == MEMCACHED_SUCCESS);
5553
5554 return TEST_SUCCESS;
5555 }
5556
5557 /*
5558 * This test ensures that the failure counter isn't incremented during
5559 * normal termination of the memcached instance.
5560 */
5561 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5562 {
5563 memcached_return_t rc;
5564 memcached_server_instance_st instance;
5565
5566 /* Set value to force connection to the server */
5567 const char *key= "marmotte";
5568 const char *value= "milka";
5569
5570 /*
5571 * Please note that I'm abusing the internal structures in libmemcached
5572 * in a non-portable way and you shouldn't be doing this. I'm only
5573 * doing this in order to verify that the library works the way it should
5574 */
5575 uint32_t number_of_hosts= memcached_server_count(memc);
5576 memc->number_of_hosts= 1;
5577
5578 /* Ensure that we are connected to the server by setting a value */
5579 rc= memcached_set(memc, key, strlen(key),
5580 value, strlen(value),
5581 (time_t)0, (uint32_t)0);
5582 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5583
5584
5585 instance= memcached_server_instance_by_position(memc, 0);
5586 /* The test is to see that the memcached_quit doesn't increase the
5587 * the server failure conter, so let's ensure that it is zero
5588 * before sending quit
5589 */
5590 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5591
5592 memcached_quit(memc);
5593
5594 /* Verify that it memcached_quit didn't increment the failure counter
5595 * Please note that this isn't bullet proof, because an error could
5596 * occur...
5597 */
5598 test_true(instance->server_failure_counter == 0);
5599
5600 /* restore the instance */
5601 memc->number_of_hosts= number_of_hosts;
5602
5603 return TEST_SUCCESS;
5604 }
5605
5606 /*
5607 * This tests ensures expected disconnections (for some behavior changes
5608 * for instance) do not wrongly increase failure counter
5609 */
5610 static test_return_t wrong_failure_counter_two_test(memcached_st *memc)
5611 {
5612 memcached_return rc;
5613
5614 memcached_st *memc_clone;
5615 memc_clone= memcached_clone(NULL, memc);
5616 test_true(memc_clone);
5617
5618 /* Set value to force connection to the server */
5619 const char *key= "marmotte";
5620 const char *value= "milka";
5621 char *string = NULL;
5622 size_t string_length;
5623 uint32_t flags;
5624
5625 rc= memcached_set(memc_clone, key, strlen(key),
5626 value, strlen(value),
5627 (time_t)0, (uint32_t)0);
5628 test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
5629
5630
5631 /* put failure limit to 1 */
5632 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5633 assert(rc == MEMCACHED_SUCCESS);
5634
5635 /* Put a retry timeout to effectively activate failure_limit effect */
5636 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1);
5637 assert(rc == MEMCACHED_SUCCESS);
5638
5639 /* change behavior that triggers memcached_quit()*/
5640 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5641 assert(rc == MEMCACHED_SUCCESS);
5642
5643
5644 /* Check if we still are connected */
5645 string= memcached_get(memc_clone, key, strlen(key),
5646 &string_length, &flags, &rc);
5647
5648 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
5649 test_true(string);
5650 free(string);
5651 memcached_free(memc_clone);
5652
5653 return TEST_SUCCESS;
5654 }
5655
5656
5657
5658
5659 /*
5660 * Test that ensures mget_execute does not end into recursive calls that finally fails
5661 */
5662 static test_return_t regression_bug_490486(memcached_st *memc)
5663 {
5664 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5665 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5666 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5667 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5668 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5669
5670 #ifdef __APPLE__
5671 return TEST_SKIPPED; // My MAC can't handle this test
5672 #endif
5673
5674 /*
5675 * I only want to hit _one_ server so I know the number of requests I'm
5676 * sending in the pipeline.
5677 */
5678 uint32_t number_of_hosts= memc->number_of_hosts;
5679 memc->number_of_hosts= 1;
5680 size_t max_keys= 20480;
5681
5682
5683 char **keys= (char **)calloc(max_keys, sizeof(char*));
5684 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5685
5686 /* First add all of the items.. */
5687 bool slept= false;
5688 char blob[1024]= { 0 };
5689 memcached_return rc;
5690 for (size_t x= 0; x < max_keys; ++x)
5691 {
5692 char k[251];
5693 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5694 keys[x]= strdup(k);
5695 assert(keys[x] != NULL);
5696 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5697 #ifdef __APPLE__
5698 if (rc == MEMCACHED_SERVER_MARKED_DEAD)
5699 {
5700 break; // We are out of business
5701 }
5702 #endif
5703 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT); // MEMCACHED_TIMEOUT <-- only observed on OSX
5704
5705 if (rc == MEMCACHED_TIMEOUT && slept == false)
5706 {
5707 x++;
5708 sleep(1);// We will try to sleep
5709 slept= true;
5710 }
5711 else if (rc == MEMCACHED_TIMEOUT && slept == true)
5712 {
5713 // We failed to send everything.
5714 break;
5715 }
5716 }
5717
5718 if (rc != MEMCACHED_SERVER_MARKED_DEAD)
5719 {
5720
5721 /* Try to get all of them with a large multiget */
5722 size_t counter= 0;
5723 memcached_execute_function callbacks[]= { &callback_counter };
5724 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5725 (size_t)max_keys, callbacks, &counter, 1);
5726
5727 assert(rc == MEMCACHED_SUCCESS);
5728 char* the_value= NULL;
5729 char the_key[MEMCACHED_MAX_KEY];
5730 size_t the_key_length;
5731 size_t the_value_length;
5732 uint32_t the_flags;
5733
5734 do {
5735 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5736
5737 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5738 {
5739 ++counter;
5740 free(the_value);
5741 }
5742
5743 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5744
5745
5746 assert(rc == MEMCACHED_END);
5747
5748 /* Verify that we got all of the items */
5749 assert(counter == max_keys);
5750 }
5751
5752 /* Release all allocated resources */
5753 for (size_t x= 0; x < max_keys; ++x)
5754 {
5755 free(keys[x]);
5756 }
5757 free(keys);
5758 free(key_length);
5759
5760 memc->number_of_hosts= number_of_hosts;
5761
5762 return TEST_SUCCESS;
5763 }
5764
5765 static test_return_t regression_bug_583031(memcached_st *unused)
5766 {
5767 (void)unused;
5768
5769 memcached_st *memc= memcached_create(NULL);
5770 assert(memc);
5771 memcached_server_add(memc, "10.2.3.4", 11211);
5772
5773 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
5774 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
5775 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
5776 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
5777 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5778 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
5779
5780 memcached_return_t rc;
5781 size_t length;
5782 uint32_t flags;
5783
5784 (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc);
5785
5786 test_true_got(rc == MEMCACHED_TIMEOUT || rc == MEMCACHED_ERRNO || rc == MEMCACHED_FAILURE, memcached_strerror(memc, rc));
5787
5788 memcached_free(memc);
5789
5790 return TEST_SUCCESS;
5791 }
5792
5793 static test_return_t regression_bug_581030(memcached_st *unused)
5794 {
5795 (void)unused;
5796
5797 #ifndef DEBUG
5798 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
5799 test_false(local_stat);
5800
5801 memcached_stat_free(NULL, NULL);
5802 #endif
5803
5804 return TEST_SUCCESS;
5805 }
5806
5807 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
5808 {
5809 fprintf(stderr, "Iteration #%u: ", it);
5810
5811 if(error == MEMCACHED_ERRNO)
5812 {
5813 fprintf(stderr, "system error %d from %s: %s\n",
5814 errno, what, strerror(errno));
5815 }
5816 else
5817 {
5818 fprintf(stderr, "error %d from %s: %s\n", error, what,
5819 memcached_strerror(mc, error));
5820 }
5821 }
5822
5823 #define TEST_CONSTANT_CREATION 200
5824
5825 static test_return_t regression_bug_(memcached_st *memc)
5826 {
5827 const char *remote_server;
5828 (void)memc;
5829
5830 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
5831 {
5832 return TEST_SKIPPED;
5833 }
5834
5835 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
5836 {
5837 memcached_st* mc= memcached_create(NULL);
5838 memcached_return rc;
5839
5840 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5841 if (rc != MEMCACHED_SUCCESS)
5842 {
5843 memcached_die(mc, rc, "memcached_behavior_set", x);
5844 }
5845
5846 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
5847 if (rc != MEMCACHED_SUCCESS)
5848 {
5849 memcached_die(mc, rc, "memcached_behavior_set", x);
5850 }
5851
5852 rc= memcached_server_add(mc, remote_server, 0);
5853 if (rc != MEMCACHED_SUCCESS)
5854 {
5855 memcached_die(mc, rc, "memcached_server_add", x);
5856 }
5857
5858 const char *set_key= "akey";
5859 const size_t set_key_len= strlen(set_key);
5860 const char *set_value= "a value";
5861 const size_t set_value_len= strlen(set_value);
5862
5863 if (rc == MEMCACHED_SUCCESS)
5864 {
5865 if (x > 0)
5866 {
5867 size_t get_value_len;
5868 char *get_value;
5869 uint32_t get_value_flags;
5870
5871 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
5872 &get_value_flags, &rc);
5873 if (rc != MEMCACHED_SUCCESS)
5874 {
5875 memcached_die(mc, rc, "memcached_get", x);
5876 }
5877 else
5878 {
5879
5880 if (x != 0 &&
5881 (get_value_len != set_value_len
5882 || 0!=strncmp(get_value, set_value, get_value_len)))
5883 {
5884 fprintf(stderr, "Values don't match?\n");
5885 rc= MEMCACHED_FAILURE;
5886 }
5887 free(get_value);
5888 }
5889 }
5890
5891 rc= memcached_set(mc,
5892 set_key, set_key_len,
5893 set_value, set_value_len,
5894 0, /* time */
5895 0 /* flags */
5896 );
5897 if (rc != MEMCACHED_SUCCESS)
5898 {
5899 memcached_die(mc, rc, "memcached_set", x);
5900 }
5901 }
5902
5903 memcached_quit(mc);
5904 memcached_free(mc);
5905
5906 if (rc != MEMCACHED_SUCCESS)
5907 {
5908 break;
5909 }
5910 }
5911
5912 return TEST_SUCCESS;
5913 }
5914
5915 /*
5916 * Test that the sasl authentication works. We cannot use the default
5917 * pool of servers, because that would require that all servers we want
5918 * to test supports SASL authentication, and that they use the default
5919 * creds.
5920 */
5921 static test_return_t sasl_auth_test(memcached_st *memc)
5922 {
5923 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
5924 memcached_return_t rc;
5925
5926 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5927 test_true(rc == MEMCACHED_SUCCESS);
5928 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_SUCCESS);
5929 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_SUCCESS);
5930 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_FAILURE);
5931 test_true((rc= memcached_destroy_sasl_auth_data(NULL)) == MEMCACHED_FAILURE);
5932 memcached_quit(memc);
5933
5934 rc= memcached_set_sasl_auth_data(memc,
5935 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
5936 getenv("LIBMEMCACHED_TEST_SASL_SERVER"));
5937 test_true(rc == MEMCACHED_SUCCESS);
5938
5939 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5940 test_true(rc == MEMCACHED_AUTH_FAILURE);
5941 test_true(memcached_destroy_sasl_auth_data(memc) == MEMCACHED_SUCCESS);
5942
5943 memcached_quit(memc);
5944 return TEST_SUCCESS;
5945 #else
5946 (void)memc;
5947 return TEST_FAILURE;
5948 #endif
5949 }
5950
5951 /* Clean the server before beginning testing */
5952 test_st tests[] ={
5953 {"util_version", 1, (test_callback_fn)util_version_test },
5954 {"flush", 0, (test_callback_fn)flush_test },
5955 {"init", 0, (test_callback_fn)init_test },
5956 {"allocation", 0, (test_callback_fn)allocation_test },
5957 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5958 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5959 {"server_sort", 0, (test_callback_fn)server_sort_test},
5960 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5961 {"memcached_server_remove", 0, (test_callback_fn)memcached_server_remove_test},
5962 {"clone_test", 0, (test_callback_fn)clone_test },
5963 {"connection_test", 0, (test_callback_fn)connection_test},
5964 {"callback_test", 0, (test_callback_fn)callback_test},
5965 {"userdata_test", 0, (test_callback_fn)userdata_test},
5966 {"error", 0, (test_callback_fn)error_test },
5967 {"set", 0, (test_callback_fn)set_test },
5968 {"set2", 0, (test_callback_fn)set_test2 },
5969 {"set3", 0, (test_callback_fn)set_test3 },
5970 {"dump", 1, (test_callback_fn)dump_test},
5971 {"add", 1, (test_callback_fn)add_test },
5972 {"replace", 1, (test_callback_fn)replace_test },
5973 {"delete", 1, (test_callback_fn)delete_test },
5974 {"get", 1, (test_callback_fn)get_test },
5975 {"get2", 0, (test_callback_fn)get_test2 },
5976 {"get3", 0, (test_callback_fn)get_test3 },
5977 {"get4", 0, (test_callback_fn)get_test4 },
5978 {"partial mget", 0, (test_callback_fn)get_test5 },
5979 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5980 {"increment", 0, (test_callback_fn)increment_test },
5981 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5982 {"decrement", 0, (test_callback_fn)decrement_test },
5983 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5984 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5985 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5986 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5987 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5988 {"quit", 0, (test_callback_fn)quit_test },
5989 {"mget", 1, (test_callback_fn)mget_test },
5990 {"mget_result", 1, (test_callback_fn)mget_result_test },
5991 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5992 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5993 {"mget_execute", 1, (test_callback_fn)mget_execute },
5994 {"mget_end", 0, (test_callback_fn)mget_end },
5995 {"get_stats", 0, (test_callback_fn)get_stats },
5996 {"add_host_test", 0, (test_callback_fn)add_host_test },
5997 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5998 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5999 {"version_string_test", 0, (test_callback_fn)version_string_test},
6000 {"bad_key", 1, (test_callback_fn)bad_key_test },
6001 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
6002 {"read_through", 1, (test_callback_fn)read_through },
6003 {"delete_through", 1, (test_callback_fn)delete_through },
6004 {"noreply", 1, (test_callback_fn)noreply_test},
6005 {"analyzer", 1, (test_callback_fn)analyzer_test},
6006 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
6007 {"memcached_pool_test", 1, (test_callback_fn)memcached_pool_test },
6008 {"ping", 1, (test_callback_fn)ping_test },
6009 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
6010 {"verbosity", 1, (test_callback_fn)test_verbosity},
6011 {"test_server_failure", 1, (test_callback_fn)test_server_failure},
6012 {"cull_servers", 1, (test_callback_fn)test_cull_servers},
6013 {"memcached_stat_execute", 1, (test_callback_fn)memcached_stat_execute_test},
6014 {0, 0, 0}
6015 };
6016
6017 test_st behavior_tests[] ={
6018 {"behavior_test", 0, (test_callback_fn)behavior_test},
6019 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_CORK_test},
6020 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
6021 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
6022 {0, 0, 0}
6023 };
6024
6025 test_st basic_tests[] ={
6026 {"init", 1, (test_callback_fn)basic_init_test},
6027 {"clone", 1, (test_callback_fn)basic_clone_test},
6028 {"reset", 1, (test_callback_fn)basic_reset_stack_test},
6029 {"reset heap", 1, (test_callback_fn)basic_reset_heap_test},
6030 {"reset stack clone", 1, (test_callback_fn)basic_reset_stack_clone_test},
6031 {"reset heap clone", 1, (test_callback_fn)basic_reset_heap_clone_test},
6032 {0, 0, 0}
6033 };
6034
6035 test_st regression_binary_vs_block[] ={
6036 {"block add", 1, (test_callback_fn)block_add_regression},
6037 {"binary add", 1, (test_callback_fn)binary_add_regression},
6038 {0, 0, 0}
6039 };
6040
6041 test_st async_tests[] ={
6042 {"add", 1, (test_callback_fn)add_wrapper },
6043 {0, 0, 0}
6044 };
6045
6046 test_st string_tests[] ={
6047 {"string static with null", 0, (test_callback_fn)string_static_null },
6048 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
6049 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
6050 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
6051 {"string append", 0, (test_callback_fn)string_alloc_append },
6052 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
6053 {"string_alloc_append_multiple", 0, (test_callback_fn)string_alloc_append_multiple },
6054 {0, 0, (test_callback_fn)0}
6055 };
6056
6057 test_st result_tests[] ={
6058 {"result static", 0, (test_callback_fn)result_static},
6059 {"result alloc", 0, (test_callback_fn)result_alloc},
6060 {0, 0, (test_callback_fn)0}
6061 };
6062
6063 test_st version_1_2_3[] ={
6064 {"append", 0, (test_callback_fn)append_test },
6065 {"prepend", 0, (test_callback_fn)prepend_test },
6066 {"cas", 0, (test_callback_fn)cas_test },
6067 {"cas2", 0, (test_callback_fn)cas2_test },
6068 {"append_binary", 0, (test_callback_fn)append_binary_test },
6069 {0, 0, (test_callback_fn)0}
6070 };
6071
6072 test_st user_tests[] ={
6073 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
6074 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
6075 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
6076 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
6077 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
6078 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
6079 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
6080 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
6081 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
6082 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
6083 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
6084 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
6085 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
6086 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
6087 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
6088 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
6089 #if !defined(__sun) && !defined(__OpenBSD__)
6090 /*
6091 ** It seems to be something weird with the character sets..
6092 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
6093 ** guess I need to find out how this is supposed to work.. Perhaps I need
6094 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
6095 ** so just disable the code for now...).
6096 */
6097 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
6098 #endif
6099 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
6100 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
6101 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
6102 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
6103 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
6104 {"wrong_failure_counter_two_test", 1, (test_callback_fn)wrong_failure_counter_two_test},
6105 {0, 0, (test_callback_fn)0}
6106 };
6107
6108 test_st replication_tests[]= {
6109 {"set", 1, (test_callback_fn)replication_set_test },
6110 {"get", 0, (test_callback_fn)replication_get_test },
6111 {"mget", 0, (test_callback_fn)replication_mget_test },
6112 {"delete", 0, (test_callback_fn)replication_delete_test },
6113 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
6114 {0, 0, (test_callback_fn)0}
6115 };
6116
6117 /*
6118 * The following test suite is used to verify that we don't introduce
6119 * regression bugs. If you want more information about the bug / test,
6120 * you should look in the bug report at
6121 * http://bugs.launchpad.net/libmemcached
6122 */
6123 test_st regression_tests[]= {
6124 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
6125 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
6126 {"lp:434843-buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
6127 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
6128 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
6129 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
6130 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
6131 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
6132 {"lp:583031", 1, (test_callback_fn)regression_bug_583031 },
6133 {"lp:?", 1, (test_callback_fn)regression_bug_ },
6134 {"lp:728286", 1, (test_callback_fn)regression_bug_728286 },
6135 {"lp:581030", 1, (test_callback_fn)regression_bug_581030 },
6136 {0, 0, (test_callback_fn)0}
6137 };
6138
6139 test_st sasl_auth_tests[]= {
6140 {"sasl_auth", 1, (test_callback_fn)sasl_auth_test },
6141 {0, 0, (test_callback_fn)0}
6142 };
6143
6144 test_st ketama_compatibility[]= {
6145 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
6146 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
6147 {0, 0, (test_callback_fn)0}
6148 };
6149
6150 test_st generate_tests[] ={
6151 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6152 {"generate_data", 1, (test_callback_fn)generate_data },
6153 {"get_read", 0, (test_callback_fn)get_read },
6154 {"delete_generate", 0, (test_callback_fn)delete_generate },
6155 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6156 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
6157 {"generate_data", 1, (test_callback_fn)generate_data },
6158 {"mget_read", 0, (test_callback_fn)mget_read },
6159 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
6160 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
6161 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6162 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
6163 {"generate_data", 1, (test_callback_fn)generate_data },
6164 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6165 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6166 {0, 0, (test_callback_fn)0}
6167 };
6168
6169 test_st consistent_tests[] ={
6170 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6171 {"generate_data", 1, (test_callback_fn)generate_data },
6172 {"get_read", 0, (test_callback_fn)get_read_count },
6173 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6174 {0, 0, (test_callback_fn)0}
6175 };
6176
6177 test_st consistent_weighted_tests[] ={
6178 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6179 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
6180 {"get_read", 0, (test_callback_fn)get_read_count },
6181 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6182 {0, 0, (test_callback_fn)0}
6183 };
6184
6185 test_st hsieh_availability[] ={
6186 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
6187 {0, 0, (test_callback_fn)0}
6188 };
6189
6190 test_st murmur_availability[] ={
6191 {"murmur_avaibility_test", 0, (test_callback_fn)murmur_avaibility_test},
6192 {0, 0, (test_callback_fn)0}
6193 };
6194
6195 #if 0
6196 test_st hash_sanity[] ={
6197 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
6198 {0, 0, (test_callback_fn)0}
6199 };
6200 #endif
6201
6202 test_st ketama_auto_eject_hosts[] ={
6203 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
6204 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
6205 {0, 0, (test_callback_fn)0}
6206 };
6207
6208 test_st hash_tests[] ={
6209 {"one_at_a_time_run", 0, (test_callback_fn)one_at_a_time_run },
6210 {"md5", 0, (test_callback_fn)md5_run },
6211 {"crc", 0, (test_callback_fn)crc_run },
6212 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
6213 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
6214 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
6215 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
6216 {"hsieh", 0, (test_callback_fn)hsieh_run },
6217 {"murmur", 0, (test_callback_fn)murmur_run },
6218 {"jenkis", 0, (test_callback_fn)jenkins_run },
6219 {"memcached_get_hashkit", 0, (test_callback_fn)memcached_get_hashkit_test },
6220 {0, 0, (test_callback_fn)0}
6221 };
6222
6223 test_st error_conditions[] ={
6224 {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
6225 {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
6226 {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
6227 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6228 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6229 {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn)memcached_increment_MEMCACHED_NO_SERVERS },
6230 {0, 0, (test_callback_fn)0}
6231 };
6232
6233
6234 test_st parser_tests[] ={
6235 {"behavior", 0, (test_callback_fn)behavior_parser_test },
6236 {"boolean_options", 0, (test_callback_fn)parser_boolean_options_test },
6237 {"configure_file", 0, (test_callback_fn)memcached_create_with_options_with_filename },
6238 {"distribtions", 0, (test_callback_fn)parser_distribution_test },
6239 {"hash", 0, (test_callback_fn)parser_hash_test },
6240 {"libmemcached_check_configuration", 0, (test_callback_fn)libmemcached_check_configuration_test },
6241 {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn)libmemcached_check_configuration_with_filename_test },
6242 {"number_options", 0, (test_callback_fn)parser_number_options_test },
6243 {"randomly generated options", 0, (test_callback_fn)random_statement_build_test },
6244 {"prefix_key", 0, (test_callback_fn)parser_key_prefix_test },
6245 {"server", 0, (test_callback_fn)server_test },
6246 {"bad server strings", 0, (test_callback_fn)servers_bad_test },
6247 {"server with weights", 0, (test_callback_fn)server_with_weight_test },
6248 {0, 0, (test_callback_fn)0}
6249 };
6250
6251 test_st virtual_bucket_tests[] ={
6252 {"basic", 0, (test_callback_fn)virtual_back_map },
6253 {0, 0, (test_callback_fn)0}
6254 };
6255
6256 collection_st collection[] ={
6257 #if 0
6258 {"hash_sanity", 0, 0, hash_sanity},
6259 #endif
6260 {"basic", 0, 0, basic_tests},
6261 {"hsieh_availability", 0, 0, hsieh_availability},
6262 {"murmur_availability", 0, 0, murmur_availability},
6263 {"block", 0, 0, tests},
6264 {"binary", (test_callback_fn)pre_binary, 0, tests},
6265 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
6266 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6267 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
6268 {"md5", (test_callback_fn)pre_md5, 0, tests},
6269 {"crc", (test_callback_fn)pre_crc, 0, tests},
6270 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
6271 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
6272 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
6273 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
6274 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
6275 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
6276 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
6277 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6278 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
6279 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6280 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
6281 {"gets", (test_callback_fn)enable_cas, 0, tests},
6282 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
6283 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
6284 #ifdef MEMCACHED_ENABLE_DEPRECATED
6285 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
6286 #endif
6287 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
6288 {"prefix", (test_callback_fn)set_prefix, 0, tests},
6289 {"sasl_auth", (test_callback_fn)pre_sasl, 0, sasl_auth_tests },
6290 {"sasl", (test_callback_fn)pre_sasl, 0, tests },
6291 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
6292 {"string", 0, 0, string_tests},
6293 {"result", 0, 0, result_tests},
6294 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
6295 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
6296 {"user", 0, 0, user_tests},
6297 {"generate", 0, 0, generate_tests},
6298 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
6299 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
6300 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
6301 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
6302 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
6303 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
6304 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
6305 // Too slow
6306 {"generate_corked", (test_callback_fn)pre_cork, 0, generate_tests},
6307 {"generate_corked_and_nonblock", (test_callback_fn)pre_cork_and_nonblock, 0, generate_tests},
6308 {"consistent_not", 0, 0, consistent_tests},
6309 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
6310 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6311 {"ketama_compat", 0, 0, ketama_compatibility},
6312 {"test_hashes", 0, 0, hash_tests},
6313 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
6314 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
6315 {"regression", 0, 0, regression_tests},
6316 {"behaviors", 0, 0, behavior_tests},
6317 {"regression_binary_vs_block", (test_callback_fn)key_setup, (test_callback_fn)key_teardown, regression_binary_vs_block},
6318 {"error_conditions", 0, 0, error_conditions},
6319 {"parser", 0, 0, parser_tests},
6320 {"virtual buckets", 0, 0, virtual_bucket_tests},
6321 {0, 0, 0, 0}
6322 };
6323
6324 #include "tests/libmemcached_world.h"
6325
6326 void get_world(world_st *world)
6327 {
6328 world->collections= collection;
6329
6330 world->create= (test_callback_create_fn)world_create;
6331 world->destroy= (test_callback_fn)world_destroy;
6332
6333 world->test.startup= (test_callback_fn)world_test_startup;
6334 world->test.flush= (test_callback_fn)world_flush;
6335 world->test.pre_run= (test_callback_fn)world_pre_run;
6336 world->test.post_run= (test_callback_fn)world_post_run;
6337 world->test.on_error= (test_callback_error_fn)world_on_error;
6338
6339 world->collection.startup= (test_callback_fn)world_container_startup;
6340 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
6341
6342 world->runner= &defualt_libmemcached_runner;
6343 }