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