Added get/set behavior functions to the C++ interface. Added a test to exercise the...
[m6w6/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 run_distribution(memc);
2852 for (int x= 0; x < 99; x++)
2853 {
2854 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2855 char *hostname = memc->hosts[server_idx].hostname;
2856 assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
2857 }
2858
2859 memcached_server_list_free(server_pool);
2860 memcached_free(memc);
2861
2862 return TEST_SUCCESS;
2863 }
2864
2865 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
2866 {
2867 (void) trash;
2868
2869 memcached_return rc;
2870 memcached_st *memc= memcached_create(NULL);
2871 assert(memc);
2872
2873
2874 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2875 assert(rc == MEMCACHED_SUCCESS);
2876
2877 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2878 assert(value == 1);
2879
2880 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2881 assert(rc == MEMCACHED_SUCCESS);
2882
2883 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2884 assert(value == MEMCACHED_HASH_MD5);
2885
2886
2887 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
2888 MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
2889
2890 memcached_server_st *server_pool;
2891 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");
2892 memcached_server_push(memc, server_pool);
2893
2894 FILE *fp;
2895 if ((fp = fopen("ketama_keys.txt", "w")))
2896 {
2897 // noop
2898 } else {
2899 printf("cannot write to file ketama_keys.txt");
2900 return TEST_FAILURE;
2901 }
2902
2903 for (int x= 0; x < 10000; x++)
2904 {
2905 char key[10];
2906 sprintf(key, "%d", x);
2907
2908 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2909 char *hostname = memc->hosts[server_idx].hostname;
2910 unsigned int port = memc->hosts[server_idx].port;
2911 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2912 }
2913 fclose(fp);
2914 memcached_server_list_free(server_pool);
2915 memcached_free(memc);
2916
2917 return TEST_SUCCESS;
2918 }
2919
2920
2921 static test_return_t result_static(memcached_st *memc)
2922 {
2923 memcached_result_st result;
2924 memcached_result_st *result_ptr;
2925
2926 result_ptr= memcached_result_create(memc, &result);
2927 assert(result.is_allocated == false);
2928 assert(result_ptr);
2929 memcached_result_free(&result);
2930
2931 return TEST_SUCCESS;
2932 }
2933
2934 static test_return_t result_alloc(memcached_st *memc)
2935 {
2936 memcached_result_st *result;
2937
2938 result= memcached_result_create(memc, NULL);
2939 assert(result);
2940 memcached_result_free(result);
2941
2942 return TEST_SUCCESS;
2943 }
2944
2945 static test_return_t string_static_null(memcached_st *memc)
2946 {
2947 memcached_string_st string;
2948 memcached_string_st *string_ptr;
2949
2950 string_ptr= memcached_string_create(memc, &string, 0);
2951 assert(string.is_allocated == false);
2952 assert(string_ptr);
2953 memcached_string_free(&string);
2954
2955 return TEST_SUCCESS;
2956 }
2957
2958 static test_return_t string_alloc_null(memcached_st *memc)
2959 {
2960 memcached_string_st *string;
2961
2962 string= memcached_string_create(memc, NULL, 0);
2963 assert(string);
2964 memcached_string_free(string);
2965
2966 return TEST_SUCCESS;
2967 }
2968
2969 static test_return_t string_alloc_with_size(memcached_st *memc)
2970 {
2971 memcached_string_st *string;
2972
2973 string= memcached_string_create(memc, NULL, 1024);
2974 assert(string);
2975 memcached_string_free(string);
2976
2977 return TEST_SUCCESS;
2978 }
2979
2980 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
2981 {
2982 memcached_string_st *string;
2983
2984 string= memcached_string_create(memc, NULL, SIZE_MAX);
2985 assert(string == NULL);
2986
2987 return TEST_SUCCESS;
2988 }
2989
2990 static test_return_t string_alloc_append(memcached_st *memc)
2991 {
2992 unsigned int x;
2993 char buffer[SMALL_STRING_LEN];
2994 memcached_string_st *string;
2995
2996 /* Ring the bell! */
2997 memset(buffer, 6, SMALL_STRING_LEN);
2998
2999 string= memcached_string_create(memc, NULL, 100);
3000 assert(string);
3001
3002 for (x= 0; x < 1024; x++)
3003 {
3004 memcached_return rc;
3005 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3006 assert(rc == MEMCACHED_SUCCESS);
3007 }
3008 memcached_string_free(string);
3009
3010 return TEST_SUCCESS;
3011 }
3012
3013 static test_return_t string_alloc_append_toobig(memcached_st *memc)
3014 {
3015 memcached_return rc;
3016 unsigned int x;
3017 char buffer[SMALL_STRING_LEN];
3018 memcached_string_st *string;
3019
3020 /* Ring the bell! */
3021 memset(buffer, 6, SMALL_STRING_LEN);
3022
3023 string= memcached_string_create(memc, NULL, 100);
3024 assert(string);
3025
3026 for (x= 0; x < 1024; x++)
3027 {
3028 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3029 assert(rc == MEMCACHED_SUCCESS);
3030 }
3031 rc= memcached_string_append(string, buffer, SIZE_MAX);
3032 assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
3033 memcached_string_free(string);
3034
3035 return TEST_SUCCESS;
3036 }
3037
3038 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
3039 {
3040 pairs_free(global_pairs);
3041
3042 return TEST_SUCCESS;
3043 }
3044
3045 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
3046 {
3047 unsigned long long x;
3048 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3049 global_count= GLOBAL_COUNT;
3050
3051 for (x= 0; x < global_count; x++)
3052 {
3053 global_keys[x]= global_pairs[x].key;
3054 global_keys_length[x]= global_pairs[x].key_length;
3055 }
3056
3057 return TEST_SUCCESS;
3058 }
3059
3060 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
3061 {
3062 unsigned long long x;
3063 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3064 global_count= GLOBAL2_COUNT;
3065
3066 for (x= 0; x < global_count; x++)
3067 {
3068 global_keys[x]= global_pairs[x].key;
3069 global_keys_length[x]= global_pairs[x].key_length;
3070 }
3071
3072 return TEST_SUCCESS;
3073 }
3074
3075 static test_return_t generate_data(memcached_st *memc)
3076 {
3077 execute_set(memc, global_pairs, global_count);
3078
3079 return TEST_SUCCESS;
3080 }
3081
3082 static test_return_t generate_data_with_stats(memcached_st *memc)
3083 {
3084 memcached_stat_st *stat_p;
3085 memcached_return rc;
3086 uint32_t host_index= 0;
3087 execute_set(memc, global_pairs, global_count);
3088
3089 //TODO: hosts used size stats
3090 stat_p= memcached_stat(memc, NULL, &rc);
3091 assert(stat_p);
3092
3093 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3094 {
3095 /* This test was changes so that "make test" would work properlly */
3096 #ifdef DEBUG
3097 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);
3098 #endif
3099 assert((unsigned long long)(stat_p + host_index)->bytes);
3100 }
3101
3102 memcached_stat_free(NULL, stat_p);
3103
3104 return TEST_SUCCESS;
3105 }
3106 static test_return_t generate_buffer_data(memcached_st *memc)
3107 {
3108 size_t latch= 0;
3109
3110 latch= 1;
3111 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3112 generate_data(memc);
3113
3114 return TEST_SUCCESS;
3115 }
3116
3117 static test_return_t get_read_count(memcached_st *memc)
3118 {
3119 unsigned int x;
3120 memcached_return rc;
3121 memcached_st *memc_clone;
3122
3123 memc_clone= memcached_clone(NULL, memc);
3124 assert(memc_clone);
3125
3126 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3127
3128 {
3129 char *return_value;
3130 size_t return_value_length;
3131 uint32_t flags;
3132 uint32_t count;
3133
3134 for (x= count= 0; x < global_count; x++)
3135 {
3136 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3137 &return_value_length, &flags, &rc);
3138 if (rc == MEMCACHED_SUCCESS)
3139 {
3140 count++;
3141 if (return_value)
3142 free(return_value);
3143 }
3144 }
3145 }
3146
3147 memcached_free(memc_clone);
3148
3149 return TEST_SUCCESS;
3150 }
3151
3152 static test_return_t get_read(memcached_st *memc)
3153 {
3154 unsigned int x;
3155 memcached_return rc;
3156
3157 {
3158 char *return_value;
3159 size_t return_value_length;
3160 uint32_t flags;
3161
3162 for (x= 0; x < global_count; x++)
3163 {
3164 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3165 &return_value_length, &flags, &rc);
3166 /*
3167 assert(return_value);
3168 assert(rc == MEMCACHED_SUCCESS);
3169 */
3170 if (rc == MEMCACHED_SUCCESS && return_value)
3171 free(return_value);
3172 }
3173 }
3174
3175 return TEST_SUCCESS;
3176 }
3177
3178 static test_return_t mget_read(memcached_st *memc)
3179 {
3180 memcached_return rc;
3181
3182 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3183 assert(rc == MEMCACHED_SUCCESS);
3184 assert(fetch_all_results(memc) == TEST_SUCCESS);
3185
3186 return TEST_SUCCESS;
3187 }
3188
3189 static test_return_t mget_read_result(memcached_st *memc)
3190 {
3191 memcached_return rc;
3192
3193 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3194 assert(rc == MEMCACHED_SUCCESS);
3195 /* Turn this into a help function */
3196 {
3197 memcached_result_st results_obj;
3198 memcached_result_st *results;
3199
3200 results= memcached_result_create(memc, &results_obj);
3201
3202 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3203 {
3204 assert(results);
3205 assert(rc == MEMCACHED_SUCCESS);
3206 }
3207
3208 memcached_result_free(&results_obj);
3209 }
3210
3211 return TEST_SUCCESS;
3212 }
3213
3214 static test_return_t mget_read_function(memcached_st *memc)
3215 {
3216 memcached_return rc;
3217 unsigned int counter;
3218 memcached_execute_function callbacks[1];
3219
3220 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3221 assert(rc == MEMCACHED_SUCCESS);
3222
3223 callbacks[0]= &callback_counter;
3224 counter= 0;
3225 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3226
3227 return TEST_SUCCESS;
3228 }
3229
3230 static test_return_t delete_generate(memcached_st *memc)
3231 {
3232 unsigned int x;
3233
3234 for (x= 0; x < global_count; x++)
3235 {
3236 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3237 }
3238
3239 return TEST_SUCCESS;
3240 }
3241
3242 static test_return_t delete_buffer_generate(memcached_st *memc)
3243 {
3244 size_t latch= 0;
3245 unsigned int x;
3246
3247 latch= 1;
3248 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3249
3250 for (x= 0; x < global_count; x++)
3251 {
3252 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3253 }
3254
3255 return TEST_SUCCESS;
3256 }
3257
3258 static test_return_t add_host_test1(memcached_st *memc)
3259 {
3260 unsigned int x;
3261 memcached_return rc;
3262 char servername[]= "0.example.com";
3263 memcached_server_st *servers;
3264
3265 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3266 assert(servers);
3267 assert(1 == memcached_server_list_count(servers));
3268
3269 for (x= 2; x < 20; x++)
3270 {
3271 char buffer[SMALL_STRING_LEN];
3272
3273 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
3274 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3275 &rc);
3276 assert(rc == MEMCACHED_SUCCESS);
3277 assert(x == memcached_server_list_count(servers));
3278 }
3279
3280 rc= memcached_server_push(memc, servers);
3281 assert(rc == MEMCACHED_SUCCESS);
3282 rc= memcached_server_push(memc, servers);
3283 assert(rc == MEMCACHED_SUCCESS);
3284
3285 memcached_server_list_free(servers);
3286
3287 return TEST_SUCCESS;
3288 }
3289
3290 static memcached_return pre_nonblock(memcached_st *memc)
3291 {
3292 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3293
3294 return MEMCACHED_SUCCESS;
3295 }
3296
3297 static memcached_return pre_nonblock_binary(memcached_st *memc)
3298 {
3299 memcached_return rc= MEMCACHED_FAILURE;
3300 memcached_st *memc_clone;
3301
3302 memc_clone= memcached_clone(NULL, memc);
3303 assert(memc_clone);
3304 // The memcached_version needs to be done on a clone, because the server
3305 // will not toggle protocol on an connection.
3306 memcached_version(memc_clone);
3307
3308 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3309 {
3310 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3311 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3312 assert(rc == MEMCACHED_SUCCESS);
3313 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3314 }
3315
3316 memcached_free(memc_clone);
3317 return rc;
3318 }
3319
3320 static memcached_return pre_murmur(memcached_st *memc)
3321 {
3322 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3323
3324 return MEMCACHED_SUCCESS;
3325 }
3326
3327 static memcached_return pre_jenkins(memcached_st *memc)
3328 {
3329 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3330
3331 return MEMCACHED_SUCCESS;
3332 }
3333
3334
3335 static memcached_return pre_md5(memcached_st *memc)
3336 {
3337 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3338
3339 return MEMCACHED_SUCCESS;
3340 }
3341
3342 static memcached_return pre_crc(memcached_st *memc)
3343 {
3344 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3345
3346 return MEMCACHED_SUCCESS;
3347 }
3348
3349 static memcached_return pre_hsieh(memcached_st *memc)
3350 {
3351 #ifdef HAVE_HSIEH_HASH
3352 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3353 return MEMCACHED_SUCCESS;
3354 #else
3355 (void) memc;
3356 return MEMCACHED_FAILURE;
3357 #endif
3358 }
3359
3360 static memcached_return pre_hash_fnv1_64(memcached_st *memc)
3361 {
3362 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
3363
3364 return MEMCACHED_SUCCESS;
3365 }
3366
3367 static memcached_return pre_hash_fnv1a_64(memcached_st *memc)
3368 {
3369 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3370
3371 return MEMCACHED_SUCCESS;
3372 }
3373
3374 static memcached_return pre_hash_fnv1_32(memcached_st *memc)
3375 {
3376 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3377
3378 return MEMCACHED_SUCCESS;
3379 }
3380
3381 static memcached_return pre_hash_fnv1a_32(memcached_st *memc)
3382 {
3383 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3384
3385 return MEMCACHED_SUCCESS;
3386 }
3387
3388 static memcached_return pre_behavior_ketama(memcached_st *memc)
3389 {
3390 memcached_return rc;
3391 uint64_t value;
3392
3393 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3394 assert(rc == MEMCACHED_SUCCESS);
3395
3396 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3397 assert(value == 1);
3398
3399 return MEMCACHED_SUCCESS;
3400 }
3401
3402 static memcached_return pre_behavior_ketama_weighted(memcached_st *memc)
3403 {
3404 memcached_return rc;
3405 uint64_t value;
3406
3407 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3408 assert(rc == MEMCACHED_SUCCESS);
3409
3410 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3411 assert(value == 1);
3412
3413 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3414 assert(rc == MEMCACHED_SUCCESS);
3415
3416 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3417 assert(value == MEMCACHED_HASH_MD5);
3418 return MEMCACHED_SUCCESS;
3419 }
3420
3421 static memcached_return pre_binary(memcached_st *memc)
3422 {
3423 memcached_return rc= MEMCACHED_FAILURE;
3424 memcached_st *memc_clone;
3425
3426 memc_clone= memcached_clone(NULL, memc);
3427 assert(memc_clone);
3428 // The memcached_version needs to be done on a clone, because the server
3429 // will not toggle protocol on an connection.
3430 memcached_version(memc_clone);
3431
3432 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3433 {
3434 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3435 assert(rc == MEMCACHED_SUCCESS);
3436 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3437 }
3438
3439 memcached_free(memc_clone);
3440
3441 return rc;
3442 }
3443
3444 static memcached_return pre_replication(memcached_st *memc)
3445 {
3446 if (pre_binary(memc) != MEMCACHED_SUCCESS)
3447 return MEMCACHED_FAILURE;
3448
3449 /*
3450 * Make sure that we store the item on all servers
3451 * (master + replicas == number of servers)
3452 */
3453 memcached_return rc;
3454 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3455 memc->number_of_hosts - 1);
3456 assert(rc == MEMCACHED_SUCCESS);
3457 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memc->number_of_hosts - 1);
3458
3459 return rc;
3460 }
3461
3462 static memcached_return pre_replication_noblock(memcached_st *memc)
3463 {
3464 memcached_return rc= MEMCACHED_FAILURE;
3465 if (pre_replication(memc) == MEMCACHED_SUCCESS &&
3466 pre_nonblock(memc) == MEMCACHED_SUCCESS)
3467 rc= MEMCACHED_SUCCESS;
3468
3469 return rc;
3470 }
3471
3472 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3473 {
3474 free(mem);
3475 }
3476
3477 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3478 {
3479 void *ret= malloc(size);
3480 if (ret != NULL)
3481 memset(ret, 0xff, size);
3482
3483 return ret;
3484 }
3485
3486 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3487 {
3488 return realloc(mem, size);
3489 }
3490
3491 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3492 {
3493 return calloc(nelem, size);
3494 }
3495
3496 static memcached_return set_prefix(memcached_st *memc)
3497 {
3498 memcached_return rc;
3499 const char *key= "mine";
3500 char *value;
3501
3502 /* Make sure be default none exists */
3503 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3504 assert(rc == MEMCACHED_FAILURE);
3505
3506 /* Test a clean set */
3507 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3508 assert(rc == MEMCACHED_SUCCESS);
3509
3510 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3511 assert(memcmp(value, key, 4) == 0);
3512 assert(rc == MEMCACHED_SUCCESS);
3513
3514 /* Test that we can turn it off */
3515 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3516 assert(rc == MEMCACHED_SUCCESS);
3517
3518 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3519 assert(rc == MEMCACHED_FAILURE);
3520
3521 /* Now setup for main test */
3522 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3523 assert(rc == MEMCACHED_SUCCESS);
3524
3525 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3526 assert(rc == MEMCACHED_SUCCESS);
3527 assert(memcmp(value, key, 4) == 0);
3528
3529 /* Set to Zero, and then Set to something too large */
3530 {
3531 char long_key[255];
3532 memset(long_key, 0, 255);
3533
3534 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3535 assert(rc == MEMCACHED_SUCCESS);
3536
3537 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3538 assert(rc == MEMCACHED_FAILURE);
3539 assert(value == NULL);
3540
3541 /* Test a long key for failure */
3542 /* TODO, extend test to determine based on setting, what result should be */
3543 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3544 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3545 //assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3546 assert(rc == MEMCACHED_SUCCESS);
3547
3548 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3549 strcpy(long_key, "This is more then the allotted number of characters");
3550 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3551 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3552
3553 /* Test for a bad prefix, but with a short key */
3554 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3555 assert(rc == MEMCACHED_SUCCESS);
3556
3557 strcpy(long_key, "dog cat");
3558 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3559 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3560 }
3561
3562 return MEMCACHED_SUCCESS;
3563 }
3564
3565 #ifdef MEMCACHED_ENABLE_DEPRECATED
3566 static memcached_return deprecated_set_memory_alloc(memcached_st *memc)
3567 {
3568 void *test_ptr= NULL;
3569 void *cb_ptr= NULL;
3570 {
3571 memcached_malloc_function malloc_cb=
3572 (memcached_malloc_function)my_malloc;
3573 cb_ptr= *(void **)&malloc_cb;
3574 memcached_return rc;
3575
3576 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3577 assert(rc == MEMCACHED_SUCCESS);
3578 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3579 assert(rc == MEMCACHED_SUCCESS);
3580 assert(test_ptr == cb_ptr);
3581 }
3582
3583 {
3584 memcached_realloc_function realloc_cb=
3585 (memcached_realloc_function)my_realloc;
3586 cb_ptr= *(void **)&realloc_cb;
3587 memcached_return rc;
3588
3589 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3590 assert(rc == MEMCACHED_SUCCESS);
3591 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3592 assert(rc == MEMCACHED_SUCCESS);
3593 assert(test_ptr == cb_ptr);
3594 }
3595
3596 {
3597 memcached_free_function free_cb=
3598 (memcached_free_function)my_free;
3599 cb_ptr= *(void **)&free_cb;
3600 memcached_return rc;
3601
3602 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3603 assert(rc == MEMCACHED_SUCCESS);
3604 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3605 assert(rc == MEMCACHED_SUCCESS);
3606 assert(test_ptr == cb_ptr);
3607 }
3608 return MEMCACHED_SUCCESS;
3609 }
3610 #endif
3611
3612 static memcached_return set_memory_alloc(memcached_st *memc)
3613 {
3614 memcached_return rc;
3615 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3616 my_realloc, my_calloc);
3617 assert(rc == MEMCACHED_FAILURE);
3618
3619 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3620 my_realloc, my_calloc);
3621
3622 memcached_malloc_function mem_malloc;
3623 memcached_free_function mem_free;
3624 memcached_realloc_function mem_realloc;
3625 memcached_calloc_function mem_calloc;
3626 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3627 &mem_realloc, &mem_calloc);
3628
3629 assert(mem_malloc == my_malloc);
3630 assert(mem_realloc == my_realloc);
3631 assert(mem_calloc == my_calloc);
3632 assert(mem_free == my_free);
3633
3634 return MEMCACHED_SUCCESS;
3635 }
3636
3637 static memcached_return enable_consistent(memcached_st *memc)
3638 {
3639 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3640 memcached_hash hash;
3641 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3642 if (pre_hsieh(memc) != MEMCACHED_SUCCESS)
3643 return MEMCACHED_FAILURE;
3644
3645 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3646 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3647
3648 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3649 assert(hash == MEMCACHED_HASH_HSIEH);
3650
3651
3652 return MEMCACHED_SUCCESS;
3653 }
3654
3655 static memcached_return enable_cas(memcached_st *memc)
3656 {
3657 unsigned int set= 1;
3658
3659 memcached_version(memc);
3660
3661 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3662 || memc->hosts[0].minor_version > 2)
3663 {
3664 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3665
3666 return MEMCACHED_SUCCESS;
3667 }
3668
3669 return MEMCACHED_FAILURE;
3670 }
3671
3672 static memcached_return check_for_1_2_3(memcached_st *memc)
3673 {
3674 memcached_version(memc);
3675
3676 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3677 || memc->hosts[0].minor_version > 2)
3678 return MEMCACHED_SUCCESS;
3679
3680 return MEMCACHED_FAILURE;
3681 }
3682
3683 static memcached_return pre_unix_socket(memcached_st *memc)
3684 {
3685 memcached_return rc;
3686 struct stat buf;
3687
3688 memcached_server_list_free(memc->hosts);
3689 memc->hosts= NULL;
3690 memc->number_of_hosts= 0;
3691
3692 if (stat("/tmp/memcached.socket", &buf))
3693 return MEMCACHED_FAILURE;
3694
3695 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3696
3697 return rc;
3698 }
3699
3700 static memcached_return pre_nodelay(memcached_st *memc)
3701 {
3702 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3703 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3704
3705 return MEMCACHED_SUCCESS;
3706 }
3707
3708 static memcached_return pre_settimer(memcached_st *memc)
3709 {
3710 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3711 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3712
3713 return MEMCACHED_SUCCESS;
3714 }
3715
3716 static memcached_return poll_timeout(memcached_st *memc)
3717 {
3718 size_t timeout;
3719
3720 timeout= 100;
3721
3722 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3723
3724 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3725
3726 assert(timeout == 100);
3727
3728 return MEMCACHED_SUCCESS;
3729 }
3730
3731 static test_return_t noreply_test(memcached_st *memc)
3732 {
3733 memcached_return ret;
3734 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3735 assert(ret == MEMCACHED_SUCCESS);
3736 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3737 assert(ret == MEMCACHED_SUCCESS);
3738 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3739 assert(ret == MEMCACHED_SUCCESS);
3740 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3741 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3742 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3743
3744 for (int count=0; count < 5; ++count)
3745 {
3746 for (int x=0; x < 100; ++x)
3747 {
3748 char key[10];
3749 size_t len= (size_t)sprintf(key, "%d", x);
3750 switch (count)
3751 {
3752 case 0:
3753 ret=memcached_add(memc, key, len, key, len, 0, 0);
3754 break;
3755 case 1:
3756 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3757 break;
3758 case 2:
3759 ret=memcached_set(memc, key, len, key, len, 0, 0);
3760 break;
3761 case 3:
3762 ret=memcached_append(memc, key, len, key, len, 0, 0);
3763 break;
3764 case 4:
3765 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3766 break;
3767 default:
3768 assert(count);
3769 break;
3770 }
3771 assert(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3772 }
3773
3774 /*
3775 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3776 ** API and is _ONLY_ done this way to verify that the library works the
3777 ** way it is supposed to do!!!!
3778 */
3779 int no_msg=0;
3780 for (uint32_t x=0; x < memc->number_of_hosts; ++x)
3781 no_msg+=(int)(memc->hosts[x].cursor_active);
3782
3783 assert(no_msg == 0);
3784 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3785
3786 /*
3787 ** Now validate that all items was set properly!
3788 */
3789 for (int x=0; x < 100; ++x)
3790 {
3791 char key[10];
3792 size_t len= (size_t)sprintf(key, "%d", x);
3793 size_t length;
3794 uint32_t flags;
3795 char* value=memcached_get(memc, key, strlen(key),
3796 &length, &flags, &ret);
3797 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3798 switch (count)
3799 {
3800 case 0: /* FALLTHROUGH */
3801 case 1: /* FALLTHROUGH */
3802 case 2:
3803 assert(strncmp(value, key, len) == 0);
3804 assert(len == length);
3805 break;
3806 case 3:
3807 assert(length == len * 2);
3808 break;
3809 case 4:
3810 assert(length == len * 3);
3811 break;
3812 default:
3813 assert(count);
3814 break;
3815 }
3816 free(value);
3817 }
3818 }
3819
3820 /* Try setting an illegal cas value (should not return an error to
3821 * the caller (because we don't expect a return message from the server)
3822 */
3823 const char* keys[]= {"0"};
3824 size_t lengths[]= {1};
3825 size_t length;
3826 uint32_t flags;
3827 memcached_result_st results_obj;
3828 memcached_result_st *results;
3829 ret= memcached_mget(memc, keys, lengths, 1);
3830 assert(ret == MEMCACHED_SUCCESS);
3831
3832 results= memcached_result_create(memc, &results_obj);
3833 assert(results);
3834 results= memcached_fetch_result(memc, &results_obj, &ret);
3835 assert(results);
3836 assert(ret == MEMCACHED_SUCCESS);
3837 uint64_t cas= memcached_result_cas(results);
3838 memcached_result_free(&results_obj);
3839
3840 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3841 assert(ret == MEMCACHED_SUCCESS);
3842
3843 /*
3844 * The item will have a new cas value, so try to set it again with the old
3845 * value. This should fail!
3846 */
3847 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3848 assert(ret == MEMCACHED_SUCCESS);
3849 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3850 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3851 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3852 free(value);
3853
3854 return TEST_SUCCESS;
3855 }
3856
3857 static test_return_t analyzer_test(memcached_st *memc)
3858 {
3859 memcached_return rc;
3860 memcached_stat_st *memc_stat;
3861 memcached_analysis_st *report;
3862
3863 memc_stat= memcached_stat(memc, NULL, &rc);
3864 assert(rc == MEMCACHED_SUCCESS);
3865 assert(memc_stat);
3866
3867 report= memcached_analyze(memc, memc_stat, &rc);
3868 assert(rc == MEMCACHED_SUCCESS);
3869 assert(report);
3870
3871 free(report);
3872 memcached_stat_free(NULL, memc_stat);
3873
3874 return TEST_SUCCESS;
3875 }
3876
3877 /* Count the objects */
3878 static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),
3879 const char *key __attribute__((unused)),
3880 size_t key_length __attribute__((unused)),
3881 void *context)
3882 {
3883 uint32_t *counter= (uint32_t *)context;
3884
3885 *counter= *counter + 1;
3886
3887 return MEMCACHED_SUCCESS;
3888 }
3889
3890 static test_return_t dump_test(memcached_st *memc)
3891 {
3892 memcached_return rc;
3893 uint32_t counter= 0;
3894 memcached_dump_func callbacks[1];
3895 test_return_t main_rc;
3896
3897 callbacks[0]= &callback_dump_counter;
3898
3899 /* No support for Binary protocol yet */
3900 if (memc->flags & MEM_BINARY_PROTOCOL)
3901 return TEST_SUCCESS;
3902
3903 main_rc= set_test3(memc);
3904
3905 assert (main_rc == TEST_SUCCESS);
3906
3907 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
3908 assert(rc == MEMCACHED_SUCCESS);
3909
3910 /* We may have more then 32 if our previous flush has not completed */
3911 assert(counter >= 32);
3912
3913 return TEST_SUCCESS;
3914 }
3915
3916 #ifdef HAVE_LIBMEMCACHEDUTIL
3917 static void* connection_release(void *arg) {
3918 struct {
3919 memcached_pool_st* pool;
3920 memcached_st* mmc;
3921 } *resource= arg;
3922
3923 usleep(250);
3924 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
3925 return arg;
3926 }
3927
3928 static test_return_t connection_pool_test(memcached_st *memc)
3929 {
3930 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
3931 assert(pool != NULL);
3932 memcached_st* mmc[10];
3933 memcached_return rc;
3934
3935 for (int x= 0; x < 10; ++x) {
3936 mmc[x]= memcached_pool_pop(pool, false, &rc);
3937 assert(mmc[x] != NULL);
3938 assert(rc == MEMCACHED_SUCCESS);
3939 }
3940
3941 assert(memcached_pool_pop(pool, false, &rc) == NULL);
3942 assert(rc == MEMCACHED_SUCCESS);
3943
3944 pthread_t tid;
3945 struct {
3946 memcached_pool_st* pool;
3947 memcached_st* mmc;
3948 } item= { .pool = pool, .mmc = mmc[9] };
3949 pthread_create(&tid, NULL, connection_release, &item);
3950 mmc[9]= memcached_pool_pop(pool, true, &rc);
3951 assert(rc == MEMCACHED_SUCCESS);
3952 pthread_join(tid, NULL);
3953 assert(mmc[9] == item.mmc);
3954 const char *key= "key";
3955 size_t keylen= strlen(key);
3956
3957 // verify that I can do ops with all connections
3958 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
3959 assert(rc == MEMCACHED_SUCCESS);
3960
3961 for (unsigned int x= 0; x < 10; ++x) {
3962 uint64_t number_value;
3963 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
3964 assert(rc == MEMCACHED_SUCCESS);
3965 assert(number_value == (x+1));
3966 }
3967
3968 // Release them..
3969 for (int x= 0; x < 10; ++x)
3970 assert(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
3971
3972
3973 /* verify that I can set behaviors on the pool when I don't have all
3974 * of the connections in the pool. It should however be enabled
3975 * when I push the item into the pool
3976 */
3977 mmc[0]= memcached_pool_pop(pool, false, &rc);
3978 assert(mmc[0] != NULL);
3979
3980 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
3981 assert(rc == MEMCACHED_SUCCESS);
3982
3983 mmc[1]= memcached_pool_pop(pool, false, &rc);
3984 assert(mmc[1] != NULL);
3985
3986 assert(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3987 assert(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
3988 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3989
3990 mmc[0]= memcached_pool_pop(pool, false, &rc);
3991 assert(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3992 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3993
3994
3995 assert(memcached_pool_destroy(pool) == memc);
3996 return TEST_SUCCESS;
3997 }
3998 #endif
3999
4000 static test_return_t replication_set_test(memcached_st *memc)
4001 {
4002 memcached_return rc;
4003 memcached_st *memc_clone= memcached_clone(NULL, memc);
4004 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4005
4006 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4007 assert(rc == MEMCACHED_SUCCESS);
4008
4009 /*
4010 ** We are using the quiet commands to store the replicas, so we need
4011 ** to ensure that all of them are processed before we can continue.
4012 ** In the test we go directly from storing the object to trying to
4013 ** receive the object from all of the different servers, so we
4014 ** could end up in a race condition (the memcached server hasn't yet
4015 ** processed the quiet command from the replication set when it process
4016 ** the request from the other client (created by the clone)). As a
4017 ** workaround for that we call memcached_quit to send the quit command
4018 ** to the server and wait for the response ;-) If you use the test code
4019 ** as an example for your own code, please note that you shouldn't need
4020 ** to do this ;-)
4021 */
4022 memcached_quit(memc);
4023
4024 /*
4025 ** "bubba" should now be stored on all of our servers. We don't have an
4026 ** easy to use API to address each individual server, so I'll just iterate
4027 ** through a bunch of "master keys" and I should most likely hit all of the
4028 ** servers...
4029 */
4030 for (int x= 'a'; x <= 'z'; ++x)
4031 {
4032 char key[2]= { [0]= (char)x };
4033 size_t len;
4034 uint32_t flags;
4035 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4036 &len, &flags, &rc);
4037 assert(rc == MEMCACHED_SUCCESS);
4038 assert(val != NULL);
4039 free(val);
4040 }
4041
4042 memcached_free(memc_clone);
4043
4044 return TEST_SUCCESS;
4045 }
4046
4047 static test_return_t replication_get_test(memcached_st *memc)
4048 {
4049 memcached_return rc;
4050
4051 /*
4052 * Don't do the following in your code. I am abusing the internal details
4053 * within the library, and this is not a supported interface.
4054 * This is to verify correct behavior in the library
4055 */
4056 for (uint32_t host= 0; host < memc->number_of_hosts; ++host)
4057 {
4058 memcached_st *memc_clone= memcached_clone(NULL, memc);
4059 memc_clone->hosts[host].port= 0;
4060
4061 for (int x= 'a'; x <= 'z'; ++x)
4062 {
4063 char key[2]= { [0]= (char)x };
4064 size_t len;
4065 uint32_t flags;
4066 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4067 &len, &flags, &rc);
4068 assert(rc == MEMCACHED_SUCCESS);
4069 assert(val != NULL);
4070 free(val);
4071 }
4072
4073 memcached_free(memc_clone);
4074 }
4075
4076 return TEST_SUCCESS;
4077 }
4078
4079 static test_return_t replication_mget_test(memcached_st *memc)
4080 {
4081 memcached_return rc;
4082 memcached_st *memc_clone= memcached_clone(NULL, memc);
4083 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4084
4085 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4086 size_t len[]= { 5, 4, 4, 4 };
4087
4088 for (int x=0; x< 4; ++x)
4089 {
4090 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4091 assert(rc == MEMCACHED_SUCCESS);
4092 }
4093
4094 /*
4095 ** We are using the quiet commands to store the replicas, so we need
4096 ** to ensure that all of them are processed before we can continue.
4097 ** In the test we go directly from storing the object to trying to
4098 ** receive the object from all of the different servers, so we
4099 ** could end up in a race condition (the memcached server hasn't yet
4100 ** processed the quiet command from the replication set when it process
4101 ** the request from the other client (created by the clone)). As a
4102 ** workaround for that we call memcached_quit to send the quit command
4103 ** to the server and wait for the response ;-) If you use the test code
4104 ** as an example for your own code, please note that you shouldn't need
4105 ** to do this ;-)
4106 */
4107 memcached_quit(memc);
4108
4109 /*
4110 * Don't do the following in your code. I am abusing the internal details
4111 * within the library, and this is not a supported interface.
4112 * This is to verify correct behavior in the library
4113 */
4114 memcached_result_st result_obj;
4115 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4116 {
4117 memcached_st *new_clone= memcached_clone(NULL, memc);
4118 new_clone->hosts[host].port= 0;
4119
4120 for (int x= 'a'; x <= 'z'; ++x)
4121 {
4122 const char key[2]= { [0]= (const char)x };
4123
4124 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4125 assert(rc == MEMCACHED_SUCCESS);
4126
4127 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4128 assert(results);
4129
4130 int hits= 0;
4131 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4132 {
4133 hits++;
4134 }
4135 assert(hits == 4);
4136 memcached_result_free(&result_obj);
4137 }
4138
4139 memcached_free(new_clone);
4140 }
4141
4142 memcached_free(memc_clone);
4143
4144 return TEST_SUCCESS;
4145 }
4146
4147 static test_return_t replication_delete_test(memcached_st *memc)
4148 {
4149 memcached_return rc;
4150 memcached_st *memc_clone= memcached_clone(NULL, memc);
4151 /* Delete the items from all of the servers except 1 */
4152 uint64_t repl= memcached_behavior_get(memc,
4153 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4154 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4155
4156 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4157 size_t len[]= { 5, 4, 4, 4 };
4158
4159 for (int x=0; x< 4; ++x)
4160 {
4161 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4162 assert(rc == MEMCACHED_SUCCESS);
4163 }
4164
4165 /*
4166 * Don't do the following in your code. I am abusing the internal details
4167 * within the library, and this is not a supported interface.
4168 * This is to verify correct behavior in the library
4169 */
4170 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4171 for (uint32_t x= 0; x < (repl + 1); ++x)
4172 {
4173 memc_clone->hosts[hash].port= 0;
4174 if (++hash == memc_clone->number_of_hosts)
4175 hash= 0;
4176 }
4177
4178 memcached_result_st result_obj;
4179 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4180 {
4181 for (int x= 'a'; x <= 'z'; ++x)
4182 {
4183 const char key[2]= { [0]= (const char)x };
4184
4185 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4186 assert(rc == MEMCACHED_SUCCESS);
4187
4188 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4189 assert(results);
4190
4191 int hits= 0;
4192 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4193 {
4194 ++hits;
4195 }
4196 assert(hits == 4);
4197 memcached_result_free(&result_obj);
4198 }
4199 }
4200 memcached_free(memc_clone);
4201
4202 return TEST_SUCCESS;
4203 }
4204
4205 static void increment_request_id(uint16_t *id)
4206 {
4207 (*id)++;
4208 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4209 *id= 0;
4210 }
4211
4212 static uint16_t *get_udp_request_ids(memcached_st *memc)
4213 {
4214 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
4215 assert(ids != NULL);
4216 unsigned int x;
4217
4218 for (x= 0; x < memc->number_of_hosts; x++)
4219 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
4220
4221 return ids;
4222 }
4223
4224 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4225 {
4226 unsigned int x;
4227 memcached_server_st *cur_server = memc->hosts;
4228 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4229
4230 for (x= 0; x < memc->number_of_hosts; x++)
4231 {
4232 assert(cur_server[x].cursor_active == 0);
4233 assert(cur_req_ids[x] == expected_req_ids[x]);
4234 }
4235 free(expected_req_ids);
4236 free(cur_req_ids);
4237
4238 return TEST_SUCCESS;
4239 }
4240
4241 /*
4242 ** There is a little bit of a hack here, instead of removing
4243 ** the servers, I just set num host to 0 and them add then new udp servers
4244 **/
4245 static memcached_return init_udp(memcached_st *memc)
4246 {
4247 memcached_version(memc);
4248 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4249 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
4250 || memc->hosts[0].micro_version < 6)
4251 return MEMCACHED_FAILURE;
4252
4253 uint32_t num_hosts= memc->number_of_hosts;
4254 unsigned int x= 0;
4255 memcached_server_st servers[num_hosts];
4256 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
4257 for (x= 0; x < num_hosts; x++)
4258 memcached_server_free(&memc->hosts[x]);
4259
4260 memc->number_of_hosts= 0;
4261 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4262 for (x= 0; x < num_hosts; x++)
4263 {
4264 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4265 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4266 }
4267
4268 return MEMCACHED_SUCCESS;
4269 }
4270
4271 static memcached_return binary_init_udp(memcached_st *memc)
4272 {
4273 pre_binary(memc);
4274 return init_udp(memc);
4275 }
4276
4277 /* Make sure that I cant add a tcp server to a udp client */
4278 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4279 {
4280 memcached_server_st server;
4281 memcached_server_clone(&server, &memc->hosts[0]);
4282 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4283 assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4284 return TEST_SUCCESS;
4285 }
4286
4287 /* Make sure that I cant add a udp server to a tcp client */
4288 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4289 {
4290 memcached_server_st server;
4291 memcached_server_clone(&server, &memc->hosts[0]);
4292 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4293
4294 memcached_st tcp_client;
4295 memcached_create(&tcp_client);
4296 assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4297 return TEST_SUCCESS;
4298 }
4299
4300 static test_return_t set_udp_behavior_test(memcached_st *memc)
4301 {
4302
4303 memcached_quit(memc);
4304 memc->number_of_hosts= 0;
4305 run_distribution(memc);
4306 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4307 assert(memc->flags & MEM_USE_UDP);
4308 assert(memc->flags & MEM_NOREPLY);;
4309
4310 assert(memc->number_of_hosts == 0);
4311
4312 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4313 assert(!(memc->flags & MEM_USE_UDP));
4314 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4315 assert(!(memc->flags & MEM_NOREPLY));
4316 return TEST_SUCCESS;
4317 }
4318
4319 static test_return_t udp_set_test(memcached_st *memc)
4320 {
4321 unsigned int x= 0;
4322 unsigned int num_iters= 1025; //request id rolls over at 1024
4323 for (x= 0; x < num_iters;x++)
4324 {
4325 memcached_return rc;
4326 const char *key= "foo";
4327 const char *value= "when we sanitize";
4328 uint16_t *expected_ids= get_udp_request_ids(memc);
4329 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
4330 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4331 rc= memcached_set(memc, key, strlen(key),
4332 value, strlen(value),
4333 (time_t)0, (uint32_t)0);
4334 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4335 /** NB, the check below assumes that if new write_ptr is less than
4336 * the original write_ptr that we have flushed. For large payloads, this
4337 * maybe an invalid assumption, but for the small payload we have it is OK
4338 */
4339 if (rc == MEMCACHED_SUCCESS ||
4340 memc->hosts[server_key].write_buffer_offset < init_offset)
4341 increment_request_id(&expected_ids[server_key]);
4342
4343 if (rc == MEMCACHED_SUCCESS)
4344 {
4345 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4346 }
4347 else
4348 {
4349 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4350 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4351 }
4352 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4353 }
4354 return TEST_SUCCESS;
4355 }
4356
4357 static test_return_t udp_buffered_set_test(memcached_st *memc)
4358 {
4359 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4360 return udp_set_test(memc);
4361 }
4362
4363 static test_return_t udp_set_too_big_test(memcached_st *memc)
4364 {
4365 memcached_return rc;
4366 const char *key= "bar";
4367 char value[MAX_UDP_DATAGRAM_LENGTH];
4368 uint16_t *expected_ids= get_udp_request_ids(memc);
4369 rc= memcached_set(memc, key, strlen(key),
4370 value, MAX_UDP_DATAGRAM_LENGTH,
4371 (time_t)0, (uint32_t)0);
4372 assert(rc == MEMCACHED_WRITE_FAILURE);
4373 return post_udp_op_check(memc,expected_ids);
4374 }
4375
4376 static test_return_t udp_delete_test(memcached_st *memc)
4377 {
4378 unsigned int x= 0;
4379 unsigned int num_iters= 1025; //request id rolls over at 1024
4380 for (x= 0; x < num_iters;x++)
4381 {
4382 memcached_return rc;
4383 const char *key= "foo";
4384 uint16_t *expected_ids=get_udp_request_ids(memc);
4385 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4386 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4387 rc= memcached_delete(memc, key, strlen(key), 0);
4388 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4389 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
4390 increment_request_id(&expected_ids[server_key]);
4391 if (rc == MEMCACHED_SUCCESS)
4392 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4393 else
4394 {
4395 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4396 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4397 }
4398 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4399 }
4400 return TEST_SUCCESS;
4401 }
4402
4403 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4404 {
4405 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4406 return udp_delete_test(memc);
4407 }
4408
4409 static test_return_t udp_verbosity_test(memcached_st *memc)
4410 {
4411 memcached_return rc;
4412 uint16_t *expected_ids= get_udp_request_ids(memc);
4413 unsigned int x;
4414 for (x= 0; x < memc->number_of_hosts;x++)
4415 increment_request_id(&expected_ids[x]);
4416
4417 rc= memcached_verbosity(memc,3);
4418 assert(rc == MEMCACHED_SUCCESS);
4419 return post_udp_op_check(memc,expected_ids);
4420 }
4421
4422 static test_return_t udp_quit_test(memcached_st *memc)
4423 {
4424 uint16_t *expected_ids= get_udp_request_ids(memc);
4425 memcached_quit(memc);
4426 return post_udp_op_check(memc, expected_ids);
4427 }
4428
4429 static test_return_t udp_flush_test(memcached_st *memc)
4430 {
4431 memcached_return rc;
4432 uint16_t *expected_ids= get_udp_request_ids(memc);
4433 unsigned int x;
4434 for (x= 0; x < memc->number_of_hosts;x++)
4435 increment_request_id(&expected_ids[x]);
4436
4437 rc= memcached_flush(memc,0);
4438 assert(rc == MEMCACHED_SUCCESS);
4439 return post_udp_op_check(memc,expected_ids);
4440 }
4441
4442 static test_return_t udp_incr_test(memcached_st *memc)
4443 {
4444 memcached_return rc;
4445 const char *key= "incr";
4446 const char *value= "1";
4447 rc= memcached_set(memc, key, strlen(key),
4448 value, strlen(value),
4449 (time_t)0, (uint32_t)0);
4450
4451 assert(rc == MEMCACHED_SUCCESS);
4452 uint16_t *expected_ids= get_udp_request_ids(memc);
4453 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4454 increment_request_id(&expected_ids[server_key]);
4455 uint64_t newvalue;
4456 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4457 assert(rc == MEMCACHED_SUCCESS);
4458 return post_udp_op_check(memc, expected_ids);
4459 }
4460
4461 static test_return_t udp_decr_test(memcached_st *memc)
4462 {
4463 memcached_return rc;
4464 const char *key= "decr";
4465 const char *value= "1";
4466 rc= memcached_set(memc, key, strlen(key),
4467 value, strlen(value),
4468 (time_t)0, (uint32_t)0);
4469
4470 assert(rc == MEMCACHED_SUCCESS);
4471 uint16_t *expected_ids= get_udp_request_ids(memc);
4472 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4473 increment_request_id(&expected_ids[server_key]);
4474 uint64_t newvalue;
4475 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4476 assert(rc == MEMCACHED_SUCCESS);
4477 return post_udp_op_check(memc, expected_ids);
4478 }
4479
4480
4481 static test_return_t udp_stat_test(memcached_st *memc)
4482 {
4483 memcached_stat_st * rv= NULL;
4484 memcached_return rc;
4485 char args[]= "";
4486 uint16_t *expected_ids = get_udp_request_ids(memc);
4487 rv = memcached_stat(memc, args, &rc);
4488 free(rv);
4489 assert(rc == MEMCACHED_NOT_SUPPORTED);
4490 return post_udp_op_check(memc, expected_ids);
4491 }
4492
4493 static test_return_t udp_version_test(memcached_st *memc)
4494 {
4495 memcached_return rc;
4496 uint16_t *expected_ids = get_udp_request_ids(memc);
4497 rc = memcached_version(memc);
4498 assert(rc == MEMCACHED_NOT_SUPPORTED);
4499 return post_udp_op_check(memc, expected_ids);
4500 }
4501
4502 static test_return_t udp_get_test(memcached_st *memc)
4503 {
4504 memcached_return rc;
4505 const char *key= "foo";
4506 size_t vlen;
4507 uint16_t *expected_ids = get_udp_request_ids(memc);
4508 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4509 assert(rc == MEMCACHED_NOT_SUPPORTED);
4510 assert(val == NULL);
4511 return post_udp_op_check(memc, expected_ids);
4512 }
4513
4514 static test_return_t udp_mixed_io_test(memcached_st *memc)
4515 {
4516 test_st current_op;
4517 test_st mixed_io_ops [] ={
4518 {"udp_set_test", 0, udp_set_test},
4519 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4520 {"udp_delete_test", 0, udp_delete_test},
4521 {"udp_verbosity_test", 0, udp_verbosity_test},
4522 {"udp_quit_test", 0, udp_quit_test},
4523 {"udp_flush_test", 0, udp_flush_test},
4524 {"udp_incr_test", 0, udp_incr_test},
4525 {"udp_decr_test", 0, udp_decr_test},
4526 {"udp_version_test", 0, udp_version_test}
4527 };
4528 unsigned int x= 0;
4529 for (x= 0; x < 500; x++)
4530 {
4531 current_op= mixed_io_ops[random() % 9];
4532 assert(current_op.function(memc) == TEST_SUCCESS);
4533 }
4534 return TEST_SUCCESS;
4535 }
4536
4537 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4538 {
4539 memcached_return expected_rc= MEMCACHED_FAILURE;
4540 #ifdef HAVE_HSIEH_HASH
4541 expected_rc= MEMCACHED_SUCCESS;
4542 #endif
4543 memcached_return rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4544 (uint64_t)MEMCACHED_HASH_HSIEH);
4545 assert(rc == expected_rc);
4546 return TEST_SUCCESS;
4547 }
4548
4549 static const char *list[]=
4550 {
4551 "apple",
4552 "beat",
4553 "carrot",
4554 "daikon",
4555 "eggplant",
4556 "flower",
4557 "green",
4558 "hide",
4559 "ick",
4560 "jack",
4561 "kick",
4562 "lime",
4563 "mushrooms",
4564 "nectarine",
4565 "orange",
4566 "peach",
4567 "quant",
4568 "ripen",
4569 "strawberry",
4570 "tang",
4571 "up",
4572 "volumne",
4573 "when",
4574 "yellow",
4575 "zip",
4576 NULL
4577 };
4578
4579 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4580 {
4581 uint32_t x;
4582 const char **ptr;
4583 uint32_t values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
4584 245758794U, 2550894432U, 121710495U, 3053817768U,
4585 1250994555U, 1862072655U, 2631955953U, 2951528551U,
4586 1451250070U, 2820856945U, 2060845566U, 3646985608U,
4587 2138080750U, 217675895U, 2230934345U, 1234361223U,
4588 3968582726U, 2455685270U, 1293568479U, 199067604U,
4589 2042482093U };
4590
4591
4592 for (ptr= list, x= 0; *ptr; ptr++, x++)
4593 {
4594 uint32_t hash_val;
4595
4596 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4597 assert(values[x] == hash_val);
4598 }
4599
4600 return TEST_SUCCESS;
4601 }
4602
4603 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4604 {
4605 uint32_t x;
4606 const char **ptr;
4607 uint32_t values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
4608 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
4609 7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
4610 17300U, 28156U, 9192U, 20484U, 16925U };
4611
4612 for (ptr= list, x= 0; *ptr; ptr++, x++)
4613 {
4614 uint32_t hash_val;
4615
4616 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4617 assert(values[x] == hash_val);
4618 }
4619
4620 return TEST_SUCCESS;
4621 }
4622
4623 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4624 {
4625 uint32_t x;
4626 const char **ptr;
4627 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4628 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4629 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4630 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4631 2815549194U, 2562818319U, 224996066U, 2680194749U,
4632 3035305390U, 246890365U, 2395624193U, 4145193337U,
4633 1801941682U };
4634
4635 for (ptr= list, x= 0; *ptr; ptr++, x++)
4636 {
4637 uint32_t hash_val;
4638
4639 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4640 assert(values[x] == hash_val);
4641 }
4642
4643 return TEST_SUCCESS;
4644 }
4645
4646 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4647 {
4648 uint32_t x;
4649 const char **ptr;
4650 uint32_t values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
4651 3647689787U, 3241528582U, 1669328060U, 2604311949U,
4652 734810122U, 1516407546U, 560948863U, 1767346780U,
4653 561034892U, 4156330026U, 3716417003U, 3475297030U,
4654 1518272172U, 227211583U, 3938128828U, 126112909U,
4655 3043416448U, 3131561933U, 1328739897U, 2455664041U,
4656 2272238452U };
4657
4658 for (ptr= list, x= 0; *ptr; ptr++, x++)
4659 {
4660 uint32_t hash_val;
4661
4662 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4663 assert(values[x] == hash_val);
4664 }
4665
4666 return TEST_SUCCESS;
4667 }
4668
4669 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4670 {
4671 uint32_t x;
4672 const char **ptr;
4673 uint32_t values[]= { 67176023U, 1190179409U, 2043204404U, 3221866419U,
4674 2567703427U, 3787535528U, 4147287986U, 3500475733U,
4675 344481048U, 3865235296U, 2181839183U, 119581266U,
4676 510234242U, 4248244304U, 1362796839U, 103389328U,
4677 1449620010U, 182962511U, 3554262370U, 3206747549U,
4678 1551306158U, 4127558461U, 1889140833U, 2774173721U,
4679 1180552018U };
4680
4681
4682 for (ptr= list, x= 0; *ptr; ptr++, x++)
4683 {
4684 uint32_t hash_val;
4685
4686 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4687 assert(values[x] == hash_val);
4688 }
4689
4690 return TEST_SUCCESS;
4691 }
4692
4693 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4694 {
4695 uint32_t x;
4696 const char **ptr;
4697 uint32_t values[]= { 280767167U, 2421315013U, 3072375666U, 855001899U,
4698 459261019U, 3521085446U, 18738364U, 1625305005U,
4699 2162232970U, 777243802U, 3323728671U, 132336572U,
4700 3654473228U, 260679466U, 1169454059U, 2698319462U,
4701 1062177260U, 235516991U, 2218399068U, 405302637U,
4702 1128467232U, 3579622413U, 2138539289U, 96429129U,
4703 2877453236U };
4704
4705 for (ptr= list, x= 0; *ptr; ptr++, x++)
4706 {
4707 uint32_t hash_val;
4708
4709 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4710 assert(values[x] == hash_val);
4711 }
4712
4713 return TEST_SUCCESS;
4714 }
4715
4716 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4717 {
4718 uint32_t x;
4719 const char **ptr;
4720 #ifdef HAVE_HSIEH_HASH
4721 uint32_t values[]= { 3738850110, 3636226060, 3821074029, 3489929160, 3485772682, 80540287,
4722 1805464076, 1895033657, 409795758, 979934958, 3634096985, 1284445480,
4723 2265380744, 707972988, 353823508, 1549198350, 1327930172, 9304163,
4724 4220749037, 2493964934, 2777873870, 2057831732, 1510213931, 2027828987,
4725 3395453351 };
4726 #else
4727 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 };
4728 #endif
4729
4730 for (ptr= list, x= 0; *ptr; ptr++, x++)
4731 {
4732 uint32_t hash_val;
4733
4734 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4735 assert(values[x] == hash_val);
4736 }
4737
4738 return TEST_SUCCESS;
4739 }
4740
4741 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4742 {
4743 uint32_t x;
4744 const char **ptr;
4745 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4746 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4747 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4748 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4749 2815549194U, 2562818319U, 224996066U, 2680194749U,
4750 3035305390U, 246890365U, 2395624193U, 4145193337U,
4751 1801941682U };
4752
4753 for (ptr= list, x= 0; *ptr; ptr++, x++)
4754 {
4755 uint32_t hash_val;
4756
4757 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4758 assert(values[x] == hash_val);
4759 }
4760
4761 return TEST_SUCCESS;
4762 }
4763
4764 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4765 {
4766 uint32_t x;
4767 const char **ptr;
4768 uint32_t values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U,
4769 3261968576U, 3515188778U, 4232909173U, 4288625128U,
4770 1812047395U, 3689182164U, 2502979932U, 1214050606U,
4771 2415988847U, 1494268927U, 1025545760U, 3920481083U,
4772 4153263658U, 3824871822U, 3072759809U, 798622255U,
4773 3065432577U, 1453328165U, 2691550971U, 3408888387U,
4774 2629893356U };
4775
4776
4777 for (ptr= list, x= 0; *ptr; ptr++, x++)
4778 {
4779 uint32_t hash_val;
4780
4781 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4782 assert(values[x] == hash_val);
4783 }
4784
4785 return TEST_SUCCESS;
4786 }
4787
4788
4789 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4790 {
4791 memcached_return rc;
4792 uint64_t value;
4793 int x;
4794 memcached_server_st *server_pool;
4795 memcached_st *memc;
4796
4797 (void)trash;
4798
4799 memc= memcached_create(NULL);
4800 assert(memc);
4801
4802 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4803 assert(rc == MEMCACHED_SUCCESS);
4804
4805 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4806 assert(value == 1);
4807
4808 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
4809 MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED) == MEMCACHED_SUCCESS);
4810
4811 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
4812 MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED);
4813
4814 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");
4815 memcached_server_push(memc, server_pool);
4816
4817 /* verify that the server list was parsed okay. */
4818 assert(memc->number_of_hosts == 8);
4819 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
4820 assert(server_pool[0].port == 11211);
4821 assert(server_pool[0].weight == 600);
4822 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
4823 assert(server_pool[2].port == 11211);
4824 assert(server_pool[2].weight == 200);
4825 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
4826 assert(server_pool[7].port == 11211);
4827 assert(server_pool[7].weight == 100);
4828
4829 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4830 * us test the boundary wraparound.
4831 */
4832 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4833
4834 /* verify the standard ketama set. */
4835 for (x= 0; x < 99; x++)
4836 {
4837 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4838 char *hostname = memc->hosts[server_idx].hostname;
4839 assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
4840 }
4841
4842 memcached_server_list_free(server_pool);
4843 memcached_free(memc);
4844
4845 return TEST_SUCCESS;
4846 }
4847
4848 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4849 {
4850 memcached_return rc;
4851 uint64_t value;
4852 int x;
4853 memcached_server_st *server_pool;
4854 memcached_st *memc;
4855
4856 (void)trash;
4857
4858 memc= memcached_create(NULL);
4859 assert(memc);
4860
4861 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4862 assert(rc == MEMCACHED_SUCCESS);
4863
4864 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4865 assert(value == 1);
4866
4867 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
4868 MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
4869
4870 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
4871 MEMCACHED_KETAMA_COMPAT_SPY);
4872
4873 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");
4874 memcached_server_push(memc, server_pool);
4875
4876 /* verify that the server list was parsed okay. */
4877 assert(memc->number_of_hosts == 8);
4878 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
4879 assert(server_pool[0].port == 11211);
4880 assert(server_pool[0].weight == 600);
4881 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
4882 assert(server_pool[2].port == 11211);
4883 assert(server_pool[2].weight == 200);
4884 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
4885 assert(server_pool[7].port == 11211);
4886 assert(server_pool[7].weight == 100);
4887
4888 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4889 * us test the boundary wraparound.
4890 */
4891 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4892
4893 /* verify the standard ketama set. */
4894 for (x= 0; x < 99; x++)
4895 {
4896 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
4897 char *hostname = memc->hosts[server_idx].hostname;
4898 assert(strcmp(hostname, ketama_test_cases_spy[x].server) == 0);
4899 }
4900
4901 memcached_server_list_free(server_pool);
4902 memcached_free(memc);
4903
4904 return TEST_SUCCESS;
4905 }
4906
4907 static test_return_t regression_bug_434484(memcached_st *memc)
4908 {
4909 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4910 return TEST_SKIPPED;
4911
4912 memcached_return ret;
4913 const char *key= "regression_bug_434484";
4914 size_t keylen= strlen(key);
4915
4916 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
4917 assert(ret == MEMCACHED_NOTSTORED);
4918
4919 size_t size= 2048 * 1024;
4920 void *data= calloc(1, size);
4921 assert(data != NULL);
4922 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
4923 assert(ret == MEMCACHED_E2BIG);
4924 free(data);
4925
4926 return TEST_SUCCESS;
4927 }
4928
4929 static test_return_t regression_bug_434843(memcached_st *memc)
4930 {
4931 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4932 return TEST_SKIPPED;
4933
4934 memcached_return rc;
4935 unsigned int counter= 0;
4936 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
4937
4938 /*
4939 * I only want to hit only _one_ server so I know the number of requests I'm
4940 * sending in the pipleine to the server. Let's try to do a multiget of
4941 * 1024 (that should satisfy most users don't you think?). Future versions
4942 * will include a mget_execute function call if you need a higher number.
4943 */
4944 uint32_t number_of_hosts= memc->number_of_hosts;
4945 memc->number_of_hosts= 1;
4946 const size_t max_keys= 1024;
4947 char **keys= calloc(max_keys, sizeof(char*));
4948 size_t *key_length=calloc(max_keys, sizeof(size_t));
4949
4950 for (int x= 0; x < (int)max_keys; ++x)
4951 {
4952 char k[251];
4953 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
4954 keys[x]= strdup(k);
4955 assert(keys[x] != NULL);
4956 }
4957
4958 /*
4959 * Run two times.. the first time we should have 100% cache miss,
4960 * and the second time we should have 100% cache hits
4961 */
4962 for (int y= 0; y < 2; ++y)
4963 {
4964 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
4965 assert(rc == MEMCACHED_SUCCESS);
4966 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
4967 if (y == 0)
4968 {
4969 /* The first iteration should give me a 100% cache miss. verify that*/
4970 assert(counter == 0);
4971 char blob[1024]= { 0 };
4972 for (int x= 0; x < (int)max_keys; ++x)
4973 {
4974 rc= memcached_add(memc, keys[x], key_length[x],
4975 blob, sizeof(blob), 0, 0);
4976 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4977 }
4978 }
4979 else
4980 {
4981 /* Verify that we received all of the key/value pairs */
4982 assert(counter == (unsigned int)max_keys);
4983 }
4984 }
4985
4986 /* Release allocated resources */
4987 for (size_t x= 0; x < max_keys; ++x)
4988 free(keys[x]);
4989 free(keys);
4990 free(key_length);
4991
4992 memc->number_of_hosts= number_of_hosts;
4993 return TEST_SUCCESS;
4994 }
4995
4996 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
4997 {
4998 memcached_return rc;
4999 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5000 assert(rc == MEMCACHED_SUCCESS);
5001
5002 return regression_bug_434843(memc);
5003 }
5004
5005 static test_return_t regression_bug_421108(memcached_st *memc)
5006 {
5007 memcached_return rc;
5008 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5009 assert(rc == MEMCACHED_SUCCESS);
5010
5011 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5012 assert(rc == MEMCACHED_SUCCESS);
5013 assert(bytes != NULL);
5014 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5015 "bytes_read", &rc);
5016 assert(rc == MEMCACHED_SUCCESS);
5017 assert(bytes_read != NULL);
5018
5019 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5020 "bytes_written", &rc);
5021 assert(rc == MEMCACHED_SUCCESS);
5022 assert(bytes_written != NULL);
5023
5024 assert(strcmp(bytes, bytes_read) != 0);
5025 assert(strcmp(bytes, bytes_written) != 0);
5026
5027 /* Release allocated resources */
5028 free(bytes);
5029 free(bytes_read);
5030 free(bytes_written);
5031 memcached_stat_free(NULL, memc_stat);
5032 return TEST_SUCCESS;
5033 }
5034
5035 /*
5036 * The test case isn't obvious so I should probably document why
5037 * it works the way it does. Bug 442914 was caused by a bug
5038 * in the logic in memcached_purge (it did not handle the case
5039 * where the number of bytes sent was equal to the watermark).
5040 * In this test case, create messages so that we hit that case
5041 * and then disable noreply mode and issue a new command to
5042 * verify that it isn't stuck. If we change the format for the
5043 * delete command or the watermarks, we need to update this
5044 * test....
5045 */
5046 static test_return_t regression_bug_442914(memcached_st *memc)
5047 {
5048 memcached_return rc;
5049 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5050 assert(rc == MEMCACHED_SUCCESS);
5051 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5052
5053 uint32_t number_of_hosts= memc->number_of_hosts;
5054 memc->number_of_hosts= 1;
5055
5056 char k[250];
5057 size_t len;
5058
5059 for (int x= 0; x < 250; ++x)
5060 {
5061 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5062 rc= memcached_delete(memc, k, len, 0);
5063 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5064 }
5065
5066 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
5067 rc= memcached_delete(memc, k, len, 0);
5068 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5069
5070 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5071 assert(rc == MEMCACHED_SUCCESS);
5072 rc= memcached_delete(memc, k, len, 0);
5073 assert(rc == MEMCACHED_NOTFOUND);
5074
5075 memc->number_of_hosts= number_of_hosts;
5076
5077 return TEST_SUCCESS;
5078 }
5079
5080 static test_return_t regression_bug_447342(memcached_st *memc)
5081 {
5082 if (memc->number_of_hosts < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5083 return TEST_SKIPPED;
5084
5085 memcached_return rc;
5086
5087 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5088 assert(rc == MEMCACHED_SUCCESS);
5089
5090 const size_t max_keys= 100;
5091 char **keys= calloc(max_keys, sizeof(char*));
5092 size_t *key_length=calloc(max_keys, sizeof(size_t));
5093
5094 for (int x= 0; x < (int)max_keys; ++x)
5095 {
5096 char k[251];
5097 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5098 keys[x]= strdup(k);
5099 assert(keys[x] != NULL);
5100 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5101 assert(rc == MEMCACHED_SUCCESS);
5102 }
5103
5104 /*
5105 ** We are using the quiet commands to store the replicas, so we need
5106 ** to ensure that all of them are processed before we can continue.
5107 ** In the test we go directly from storing the object to trying to
5108 ** receive the object from all of the different servers, so we
5109 ** could end up in a race condition (the memcached server hasn't yet
5110 ** processed the quiet command from the replication set when it process
5111 ** the request from the other client (created by the clone)). As a
5112 ** workaround for that we call memcached_quit to send the quit command
5113 ** to the server and wait for the response ;-) If you use the test code
5114 ** as an example for your own code, please note that you shouldn't need
5115 ** to do this ;-)
5116 */
5117 memcached_quit(memc);
5118
5119 /* Verify that all messages are stored, and we didn't stuff too much
5120 * into the servers
5121 */
5122 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5123 assert(rc == MEMCACHED_SUCCESS);
5124
5125 unsigned int counter= 0;
5126 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
5127 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5128 /* Verify that we received all of the key/value pairs */
5129 assert(counter == (unsigned int)max_keys);
5130
5131 memcached_quit(memc);
5132 /*
5133 * Don't do the following in your code. I am abusing the internal details
5134 * within the library, and this is not a supported interface.
5135 * This is to verify correct behavior in the library. Fake that two servers
5136 * are dead..
5137 */
5138 unsigned int port0= memc->hosts[0].port;
5139 unsigned int port2= memc->hosts[2].port;
5140 memc->hosts[0].port= 0;
5141 memc->hosts[2].port= 0;
5142
5143 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5144 assert(rc == MEMCACHED_SUCCESS);
5145
5146 counter= 0;
5147 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5148 assert(counter == (unsigned int)max_keys);
5149
5150 /* restore the memc handle */
5151 memc->hosts[0].port= port0;
5152 memc->hosts[2].port= port2;
5153
5154 memcached_quit(memc);
5155
5156 /* Remove half of the objects */
5157 for (int x= 0; x < (int)max_keys; ++x)
5158 if (x & 1)
5159 {
5160 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5161 assert(rc == MEMCACHED_SUCCESS);
5162 }
5163
5164 memcached_quit(memc);
5165 memc->hosts[0].port= 0;
5166 memc->hosts[2].port= 0;
5167
5168 /* now retry the command, this time we should have cache misses */
5169 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5170 assert(rc == MEMCACHED_SUCCESS);
5171
5172 counter= 0;
5173 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5174 assert(counter == (unsigned int)(max_keys >> 1));
5175
5176 /* Release allocated resources */
5177 for (size_t x= 0; x < max_keys; ++x)
5178 free(keys[x]);
5179 free(keys);
5180 free(key_length);
5181
5182 /* restore the memc handle */
5183 memc->hosts[0].port= port0;
5184 memc->hosts[2].port= port2;
5185 return TEST_SUCCESS;
5186 }
5187
5188 static test_return_t regression_bug_463297(memcached_st *memc)
5189 {
5190 memcached_st *memc_clone= memcached_clone(NULL, memc);
5191 assert(memc_clone != NULL);
5192 assert(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5193
5194 if (memc_clone->hosts[0].major_version > 1 ||
5195 (memc_clone->hosts[0].major_version == 1 &&
5196 memc_clone->hosts[0].minor_version > 2))
5197 {
5198 /* Binary protocol doesn't support deferred delete */
5199 memcached_st *bin_clone= memcached_clone(NULL, memc);
5200 assert(bin_clone != NULL);
5201 assert(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5202 assert(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5203 memcached_free(bin_clone);
5204
5205 memcached_quit(memc_clone);
5206
5207 /* If we know the server version, deferred delete should fail
5208 * with invalid arguments */
5209 assert(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5210
5211 /* If we don't know the server version, we should get a protocol error */
5212 memcached_return rc= memcached_delete(memc, "foo", 3, 1);
5213 /* but there is a bug in some of the memcached servers (1.4) that treats
5214 * the counter as noreply so it doesn't send the proper error message
5215 */
5216 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5217
5218 /* And buffered mode should be disabled and we should get protocol error */
5219 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5220 rc= memcached_delete(memc, "foo", 3, 1);
5221 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5222
5223 /* Same goes for noreply... */
5224 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5225 rc= memcached_delete(memc, "foo", 3, 1);
5226 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5227
5228 /* but a normal request should go through (and be buffered) */
5229 assert((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5230 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5231
5232 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5233 /* unbuffered noreply should be success */
5234 assert(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5235 /* unbuffered with reply should be not found... */
5236 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5237 assert(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5238 }
5239
5240 memcached_free(memc_clone);
5241 return TEST_SUCCESS;
5242 }
5243
5244
5245 /* Test memcached_server_get_last_disconnect
5246 * For a working server set, shall be NULL
5247 * For a set of non existing server, shall not be NULL
5248 */
5249 static test_return_t test_get_last_disconnect(memcached_st *memc)
5250 {
5251 memcached_return rc;
5252 memcached_server_st *disconnected_server;
5253
5254 /* With the working set of server */
5255 const char *key= "marmotte";
5256 const char *value= "milka";
5257
5258 rc= memcached_set(memc, key, strlen(key),
5259 value, strlen(value),
5260 (time_t)0, (uint32_t)0);
5261 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5262
5263 disconnected_server = memcached_server_get_last_disconnect(memc);
5264 assert(disconnected_server == NULL);
5265
5266 /* With a non existing server */
5267 memcached_st *mine;
5268 memcached_server_st *servers;
5269
5270 const char *server_list= "localhost:9";
5271
5272 servers= memcached_servers_parse(server_list);
5273 assert(servers);
5274 mine= memcached_create(NULL);
5275 rc= memcached_server_push(mine, servers);
5276 assert(rc == MEMCACHED_SUCCESS);
5277 memcached_server_list_free(servers);
5278 assert(mine);
5279
5280 rc= memcached_set(mine, key, strlen(key),
5281 value, strlen(value),
5282 (time_t)0, (uint32_t)0);
5283 assert(rc != MEMCACHED_SUCCESS);
5284
5285 disconnected_server = memcached_server_get_last_disconnect(mine);
5286 assert(disconnected_server != NULL);
5287 assert(disconnected_server->port == 9);
5288 assert(strncmp(disconnected_server->hostname,"localhost",9) == 0);
5289
5290 memcached_quit(mine);
5291 memcached_free(mine);
5292
5293 return TEST_SUCCESS;
5294 }
5295
5296 /*
5297 * This test ensures that the failure counter isn't incremented during
5298 * normal termination of the memcached instance.
5299 */
5300 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5301 {
5302 memcached_return rc;
5303
5304 /* Set value to force connection to the server */
5305 const char *key= "marmotte";
5306 const char *value= "milka";
5307
5308 /*
5309 * Please note that I'm abusing the internal structures in libmemcached
5310 * in a non-portable way and you shouldn't be doing this. I'm only
5311 * doing this in order to verify that the library works the way it should
5312 */
5313 uint32_t number_of_hosts= memc->number_of_hosts;
5314 memc->number_of_hosts= 1;
5315
5316 /* Ensure that we are connected to the server by setting a value */
5317 rc= memcached_set(memc, key, strlen(key),
5318 value, strlen(value),
5319 (time_t)0, (uint32_t)0);
5320 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5321
5322
5323 /* The test is to see that the memcached_quit doesn't increase the
5324 * the server failure conter, so let's ensure that it is zero
5325 * before sending quit
5326 */
5327 memc->hosts[0].server_failure_counter= 0;
5328
5329 memcached_quit(memc);
5330
5331 /* Verify that it memcached_quit didn't increment the failure counter
5332 * Please note that this isn't bullet proof, because an error could
5333 * occur...
5334 */
5335 assert(memc->hosts[0].server_failure_counter == 0);
5336
5337 /* restore the instance */
5338 memc->number_of_hosts= number_of_hosts;
5339
5340 return TEST_SUCCESS;
5341 }
5342
5343 test_st udp_setup_server_tests[] ={
5344 {"set_udp_behavior_test", 0, set_udp_behavior_test},
5345 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
5346 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
5347 {0, 0, 0}
5348 };
5349
5350 test_st upd_io_tests[] ={
5351 {"udp_set_test", 0, udp_set_test},
5352 {"udp_buffered_set_test", 0, udp_buffered_set_test},
5353 {"udp_set_too_big_test", 0, udp_set_too_big_test},
5354 {"udp_delete_test", 0, udp_delete_test},
5355 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
5356 {"udp_verbosity_test", 0, udp_verbosity_test},
5357 {"udp_quit_test", 0, udp_quit_test},
5358 {"udp_flush_test", 0, udp_flush_test},
5359 {"udp_incr_test", 0, udp_incr_test},
5360 {"udp_decr_test", 0, udp_decr_test},
5361 {"udp_stat_test", 0, udp_stat_test},
5362 {"udp_version_test", 0, udp_version_test},
5363 {"udp_get_test", 0, udp_get_test},
5364 {"udp_mixed_io_test", 0, udp_mixed_io_test},
5365 {0, 0, 0}
5366 };
5367
5368 /* Clean the server before beginning testing */
5369 test_st tests[] ={
5370 {"flush", 0, flush_test },
5371 {"init", 0, init_test },
5372 {"allocation", 0, allocation_test },
5373 {"server_list_null_test", 0, server_list_null_test},
5374 {"server_unsort", 0, server_unsort_test},
5375 {"server_sort", 0, server_sort_test},
5376 {"server_sort2", 0, server_sort2_test},
5377 {"clone_test", 0, clone_test },
5378 {"connection_test", 0, connection_test},
5379 {"callback_test", 0, callback_test},
5380 {"behavior_test", 0, behavior_test},
5381 {"userdata_test", 0, userdata_test},
5382 {"error", 0, error_test },
5383 {"set", 0, set_test },
5384 {"set2", 0, set_test2 },
5385 {"set3", 0, set_test3 },
5386 {"dump", 1, dump_test},
5387 {"add", 1, add_test },
5388 {"replace", 1, replace_test },
5389 {"delete", 1, delete_test },
5390 {"get", 1, get_test },
5391 {"get2", 0, get_test2 },
5392 {"get3", 0, get_test3 },
5393 {"get4", 0, get_test4 },
5394 {"partial mget", 0, get_test5 },
5395 {"stats_servername", 0, stats_servername_test },
5396 {"increment", 0, increment_test },
5397 {"increment_with_initial", 1, increment_with_initial_test },
5398 {"decrement", 0, decrement_test },
5399 {"decrement_with_initial", 1, decrement_with_initial_test },
5400 {"increment_by_key", 0, increment_by_key_test },
5401 {"increment_with_initial_by_key", 1, increment_with_initial_by_key_test },
5402 {"decrement_by_key", 0, decrement_by_key_test },
5403 {"decrement_with_initial_by_key", 1, decrement_with_initial_by_key_test },
5404 {"quit", 0, quit_test },
5405 {"mget", 1, mget_test },
5406 {"mget_result", 1, mget_result_test },
5407 {"mget_result_alloc", 1, mget_result_alloc_test },
5408 {"mget_result_function", 1, mget_result_function },
5409 {"mget_execute", 1, mget_execute },
5410 {"mget_end", 0, mget_end },
5411 {"get_stats", 0, get_stats },
5412 {"add_host_test", 0, add_host_test },
5413 {"add_host_test_1", 0, add_host_test1 },
5414 {"get_stats_keys", 0, get_stats_keys },
5415 {"behavior_test", 0, get_stats_keys },
5416 {"callback_test", 0, get_stats_keys },
5417 {"version_string_test", 0, version_string_test},
5418 {"bad_key", 1, bad_key_test },
5419 {"memcached_server_cursor", 1, memcached_server_cursor_test },
5420 {"read_through", 1, read_through },
5421 {"delete_through", 1, delete_through },
5422 {"noreply", 1, noreply_test},
5423 {"analyzer", 1, analyzer_test},
5424 #ifdef HAVE_LIBMEMCACHEDUTIL
5425 {"connectionpool", 1, connection_pool_test },
5426 #endif
5427 {"test_get_last_disconnect", 1, test_get_last_disconnect},
5428 {0, 0, 0}
5429 };
5430
5431 test_st async_tests[] ={
5432 {"add", 1, add_wrapper },
5433 {0, 0, 0}
5434 };
5435
5436 test_st string_tests[] ={
5437 {"string static with null", 0, string_static_null },
5438 {"string alloc with null", 0, string_alloc_null },
5439 {"string alloc with 1K", 0, string_alloc_with_size },
5440 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
5441 {"string append", 0, string_alloc_append },
5442 {"string append failure (too big)", 0, string_alloc_append_toobig },
5443 {0, 0, 0}
5444 };
5445
5446 test_st result_tests[] ={
5447 {"result static", 0, result_static},
5448 {"result alloc", 0, result_alloc},
5449 {0, 0, 0}
5450 };
5451
5452 test_st version_1_2_3[] ={
5453 {"append", 0, append_test },
5454 {"prepend", 0, prepend_test },
5455 {"cas", 0, cas_test },
5456 {"cas2", 0, cas2_test },
5457 {"append_binary", 0, append_binary_test },
5458 {0, 0, 0}
5459 };
5460
5461 test_st user_tests[] ={
5462 {"user_supplied_bug1", 0, user_supplied_bug1 },
5463 {"user_supplied_bug2", 0, user_supplied_bug2 },
5464 {"user_supplied_bug3", 0, user_supplied_bug3 },
5465 {"user_supplied_bug4", 0, user_supplied_bug4 },
5466 {"user_supplied_bug5", 1, user_supplied_bug5 },
5467 {"user_supplied_bug6", 1, user_supplied_bug6 },
5468 {"user_supplied_bug7", 1, user_supplied_bug7 },
5469 {"user_supplied_bug8", 1, user_supplied_bug8 },
5470 {"user_supplied_bug9", 1, user_supplied_bug9 },
5471 {"user_supplied_bug10", 1, user_supplied_bug10 },
5472 {"user_supplied_bug11", 1, user_supplied_bug11 },
5473 {"user_supplied_bug12", 1, user_supplied_bug12 },
5474 {"user_supplied_bug13", 1, user_supplied_bug13 },
5475 {"user_supplied_bug14", 1, user_supplied_bug14 },
5476 {"user_supplied_bug15", 1, user_supplied_bug15 },
5477 {"user_supplied_bug16", 1, user_supplied_bug16 },
5478 #ifndef __sun
5479 /*
5480 ** It seems to be something weird with the character sets..
5481 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5482 ** guess I need to find out how this is supposed to work.. Perhaps I need
5483 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5484 ** so just disable the code for now...).
5485 */
5486 {"user_supplied_bug17", 1, user_supplied_bug17 },
5487 #endif
5488 {"user_supplied_bug18", 1, user_supplied_bug18 },
5489 {"user_supplied_bug19", 1, user_supplied_bug19 },
5490 {"user_supplied_bug20", 1, user_supplied_bug20 },
5491 {"user_supplied_bug21", 1, user_supplied_bug21 },
5492 {"wrong_failure_counter_test", 1, wrong_failure_counter_test},
5493 {0, 0, 0}
5494 };
5495
5496 test_st replication_tests[]= {
5497 {"set", 1, replication_set_test },
5498 {"get", 0, replication_get_test },
5499 {"mget", 0, replication_mget_test },
5500 {"delete", 0, replication_delete_test },
5501 {0, 0, 0}
5502 };
5503
5504 /*
5505 * The following test suite is used to verify that we don't introduce
5506 * regression bugs. If you want more information about the bug / test,
5507 * you should look in the bug report at
5508 * http://bugs.launchpad.net/libmemcached
5509 */
5510 test_st regression_tests[]= {
5511 {"lp:434484", 1, regression_bug_434484 },
5512 {"lp:434843", 1, regression_bug_434843 },
5513 {"lp:434843 buffered", 1, regression_bug_434843_buffered },
5514 {"lp:421108", 1, regression_bug_421108 },
5515 {"lp:442914", 1, regression_bug_442914 },
5516 {"lp:447342", 1, regression_bug_447342 },
5517 {"lp:463297", 1, regression_bug_463297 },
5518 {0, 0, 0}
5519 };
5520
5521 test_st ketama_compatibility[]= {
5522 {"libmemcached", 1, ketama_compatibility_libmemcached },
5523 {"spymemcached", 1, ketama_compatibility_spymemcached },
5524 {0, 0, 0}
5525 };
5526
5527 test_st generate_tests[] ={
5528 {"generate_pairs", 1, generate_pairs },
5529 {"generate_data", 1, generate_data },
5530 {"get_read", 0, get_read },
5531 {"delete_generate", 0, delete_generate },
5532 {"generate_buffer_data", 1, generate_buffer_data },
5533 {"delete_buffer", 0, delete_buffer_generate},
5534 {"generate_data", 1, generate_data },
5535 {"mget_read", 0, mget_read },
5536 {"mget_read_result", 0, mget_read_result },
5537 {"mget_read_function", 0, mget_read_function },
5538 {"cleanup", 1, cleanup_pairs },
5539 {"generate_large_pairs", 1, generate_large_pairs },
5540 {"generate_data", 1, generate_data },
5541 {"generate_buffer_data", 1, generate_buffer_data },
5542 {"cleanup", 1, cleanup_pairs },
5543 {0, 0, 0}
5544 };
5545
5546 test_st consistent_tests[] ={
5547 {"generate_pairs", 1, generate_pairs },
5548 {"generate_data", 1, generate_data },
5549 {"get_read", 0, get_read_count },
5550 {"cleanup", 1, cleanup_pairs },
5551 {0, 0, 0}
5552 };
5553
5554 test_st consistent_weighted_tests[] ={
5555 {"generate_pairs", 1, generate_pairs },
5556 {"generate_data", 1, generate_data_with_stats },
5557 {"get_read", 0, get_read_count },
5558 {"cleanup", 1, cleanup_pairs },
5559 {0, 0, 0}
5560 };
5561
5562 test_st hsieh_availability[] ={
5563 {"hsieh_avaibility_test",0,hsieh_avaibility_test},
5564 {0, 0, 0}
5565 };
5566
5567 test_st ketama_auto_eject_hosts[] ={
5568 {"auto_eject_hosts", 1, auto_eject_hosts },
5569 {"output_ketama_weighted_keys", 1, output_ketama_weighted_keys },
5570 {0, 0, 0}
5571 };
5572
5573 test_st hash_tests[] ={
5574 {"md5", 0, md5_run },
5575 {"crc", 0, crc_run },
5576 {"fnv1_64", 0, fnv1_64_run },
5577 {"fnv1a_64", 0, fnv1a_64_run },
5578 {"fnv1_32", 0, fnv1_32_run },
5579 {"fnv1a_32", 0, fnv1a_32_run },
5580 {"hsieh", 0, hsieh_run },
5581 {"murmur", 0, murmur_run },
5582 {"jenkis", 0, jenkins_run },
5583 {0, 0, 0}
5584 };
5585
5586 collection_st collection[] ={
5587 {"hsieh_availability",0,0,hsieh_availability},
5588 {"udp_setup", init_udp, 0, udp_setup_server_tests},
5589 {"udp_io", init_udp, 0, upd_io_tests},
5590 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
5591 {"block", 0, 0, tests},
5592 {"binary", pre_binary, 0, tests},
5593 {"nonblock", pre_nonblock, 0, tests},
5594 {"nodelay", pre_nodelay, 0, tests},
5595 {"settimer", pre_settimer, 0, tests},
5596 {"md5", pre_md5, 0, tests},
5597 {"crc", pre_crc, 0, tests},
5598 {"hsieh", pre_hsieh, 0, tests},
5599 {"jenkins", pre_jenkins, 0, tests},
5600 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
5601 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
5602 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
5603 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
5604 {"ketama", pre_behavior_ketama, 0, tests},
5605 {"ketama_auto_eject_hosts", pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5606 {"unix_socket", pre_unix_socket, 0, tests},
5607 {"unix_socket_nodelay", pre_nodelay, 0, tests},
5608 {"poll_timeout", poll_timeout, 0, tests},
5609 {"gets", enable_cas, 0, tests},
5610 {"consistent", enable_consistent, 0, tests},
5611 #ifdef MEMCACHED_ENABLE_DEPRECATED
5612 {"deprecated_memory_allocators", deprecated_set_memory_alloc, 0, tests},
5613 #endif
5614 {"memory_allocators", set_memory_alloc, 0, tests},
5615 {"prefix", set_prefix, 0, tests},
5616 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
5617 {"string", 0, 0, string_tests},
5618 {"result", 0, 0, result_tests},
5619 {"async", pre_nonblock, 0, async_tests},
5620 {"async_binary", pre_nonblock_binary, 0, async_tests},
5621 {"user", 0, 0, user_tests},
5622 {"generate", 0, 0, generate_tests},
5623 {"generate_hsieh", pre_hsieh, 0, generate_tests},
5624 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
5625 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
5626 {"generate_md5", pre_md5, 0, generate_tests},
5627 {"generate_murmur", pre_murmur, 0, generate_tests},
5628 {"generate_jenkins", pre_jenkins, 0, generate_tests},
5629 {"generate_nonblock", pre_nonblock, 0, generate_tests},
5630 {"consistent_not", 0, 0, consistent_tests},
5631 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
5632 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5633 {"ketama_compat", 0, 0, ketama_compatibility},
5634 {"test_hashes", 0, 0, hash_tests},
5635 {"replication", pre_replication, 0, replication_tests},
5636 {"replication_noblock", pre_replication_noblock, 0, replication_tests},
5637 {"regression", 0, 0, regression_tests},
5638 {0, 0, 0, 0}
5639 };
5640
5641 #define SERVERS_TO_CREATE 5
5642
5643 /* Prototypes for functions we will pass to test framework */
5644 void *world_create(void);
5645 void world_destroy(void *p);
5646
5647 void *world_create(void)
5648 {
5649 server_startup_st *construct;
5650
5651 construct= calloc(sizeof(server_startup_st), 1);
5652 construct->count= SERVERS_TO_CREATE;
5653 construct->udp= 0;
5654 server_startup(construct);
5655
5656 return construct;
5657 }
5658
5659
5660 void world_destroy(void *p)
5661 {
5662 server_startup_st *construct= (server_startup_st *)p;
5663 memcached_server_st *servers= (memcached_server_st *)construct->servers;
5664 memcached_server_list_free(servers);
5665
5666 server_shutdown(construct);
5667 free(construct);
5668 }
5669
5670 void get_world(world_st *world)
5671 {
5672 world->collections= collection;
5673 world->create= world_create;
5674 world->destroy= world_destroy;
5675 }