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