merge upstream
[awesomized/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 static memcached_return deprecated_set_memory_alloc(memcached_st *memc)
3164 {
3165 void *test_ptr= NULL;
3166 void *cb_ptr= NULL;
3167 {
3168 memcached_malloc_function malloc_cb=
3169 (memcached_malloc_function)my_malloc;
3170 cb_ptr= *(void **)&malloc_cb;
3171 memcached_return rc;
3172
3173 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3174 assert(rc == MEMCACHED_SUCCESS);
3175 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3176 assert(rc == MEMCACHED_SUCCESS);
3177 assert(test_ptr == cb_ptr);
3178 }
3179
3180 {
3181 memcached_realloc_function realloc_cb=
3182 (memcached_realloc_function)my_realloc;
3183 cb_ptr= *(void **)&realloc_cb;
3184 memcached_return rc;
3185
3186 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3187 assert(rc == MEMCACHED_SUCCESS);
3188 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3189 assert(rc == MEMCACHED_SUCCESS);
3190 assert(test_ptr == cb_ptr);
3191 }
3192
3193 {
3194 memcached_free_function free_cb=
3195 (memcached_free_function)my_free;
3196 cb_ptr= *(void **)&free_cb;
3197 memcached_return rc;
3198
3199 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3200 assert(rc == MEMCACHED_SUCCESS);
3201 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3202 assert(rc == MEMCACHED_SUCCESS);
3203 assert(test_ptr == cb_ptr);
3204 }
3205 return MEMCACHED_SUCCESS;
3206 }
3207
3208 static memcached_return set_memory_alloc(memcached_st *memc)
3209 {
3210 memcached_return rc;
3211 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3212 my_realloc, my_calloc);
3213 assert(rc == MEMCACHED_FAILURE);
3214
3215 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3216 my_realloc, my_calloc);
3217
3218 memcached_malloc_function mem_malloc;
3219 memcached_free_function mem_free;
3220 memcached_realloc_function mem_realloc;
3221 memcached_calloc_function mem_calloc;
3222 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3223 &mem_realloc, &mem_calloc);
3224
3225 assert(mem_malloc == my_malloc);
3226 assert(mem_realloc == my_realloc);
3227 assert(mem_calloc == my_calloc);
3228 assert(mem_free == my_free);
3229
3230 return MEMCACHED_SUCCESS;
3231 }
3232
3233 static memcached_return enable_consistent(memcached_st *memc)
3234 {
3235 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3236 memcached_hash hash;
3237 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3238 if (pre_hsieh(memc) != MEMCACHED_SUCCESS)
3239 return MEMCACHED_FAILURE;
3240
3241 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3242 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3243
3244 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3245 assert(hash == MEMCACHED_HASH_HSIEH);
3246
3247
3248 return MEMCACHED_SUCCESS;
3249 }
3250
3251 static memcached_return enable_cas(memcached_st *memc)
3252 {
3253 unsigned int set= 1;
3254
3255 memcached_version(memc);
3256
3257 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3258 || memc->hosts[0].minor_version > 2)
3259 {
3260 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3261
3262 return MEMCACHED_SUCCESS;
3263 }
3264
3265 return MEMCACHED_FAILURE;
3266 }
3267
3268 static memcached_return check_for_1_2_3(memcached_st *memc)
3269 {
3270 memcached_version(memc);
3271
3272 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3273 || memc->hosts[0].minor_version > 2)
3274 return MEMCACHED_SUCCESS;
3275
3276 return MEMCACHED_FAILURE;
3277 }
3278
3279 static memcached_return pre_unix_socket(memcached_st *memc)
3280 {
3281 memcached_return rc;
3282 struct stat buf;
3283
3284 memcached_server_list_free(memc->hosts);
3285 memc->hosts= NULL;
3286 memc->number_of_hosts= 0;
3287
3288 if (stat("/tmp/memcached.socket", &buf))
3289 return MEMCACHED_FAILURE;
3290
3291 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3292
3293 return rc;
3294 }
3295
3296 static memcached_return pre_nodelay(memcached_st *memc)
3297 {
3298 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3299 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3300
3301 return MEMCACHED_SUCCESS;
3302 }
3303
3304 static memcached_return pre_settimer(memcached_st *memc)
3305 {
3306 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3307 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3308
3309 return MEMCACHED_SUCCESS;
3310 }
3311
3312 static memcached_return poll_timeout(memcached_st *memc)
3313 {
3314 int32_t timeout;
3315
3316 timeout= 100;
3317
3318 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3319
3320 timeout= (int32_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3321
3322 assert(timeout == 100);
3323
3324 return MEMCACHED_SUCCESS;
3325 }
3326
3327 static test_return noreply_test(memcached_st *memc)
3328 {
3329 memcached_return ret;
3330 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3331 assert(ret == MEMCACHED_SUCCESS);
3332 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3333 assert(ret == MEMCACHED_SUCCESS);
3334 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3335 assert(ret == MEMCACHED_SUCCESS);
3336 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3337 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3338 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3339
3340 for (int count=0; count < 5; ++count)
3341 {
3342 for (int x=0; x < 100; ++x)
3343 {
3344 char key[10];
3345 size_t len= sprintf(key, "%d", x);
3346 switch (count)
3347 {
3348 case 0:
3349 ret=memcached_add(memc, key, len, key, len, 0, 0);
3350 break;
3351 case 1:
3352 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3353 break;
3354 case 2:
3355 ret=memcached_set(memc, key, len, key, len, 0, 0);
3356 break;
3357 case 3:
3358 ret=memcached_append(memc, key, len, key, len, 0, 0);
3359 break;
3360 case 4:
3361 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3362 break;
3363 }
3364 assert(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3365 }
3366
3367 /*
3368 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3369 ** API and is _ONLY_ done this way to verify that the library works the
3370 ** way it is supposed to do!!!!
3371 */
3372 int no_msg=0;
3373 for (uint32_t x=0; x < memc->number_of_hosts; ++x)
3374 no_msg+=memc->hosts[x].cursor_active;
3375
3376 assert(no_msg == 0);
3377 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3378
3379 /*
3380 ** Now validate that all items was set properly!
3381 */
3382 for (int x=0; x < 100; ++x)
3383 {
3384 char key[10];
3385 size_t len= sprintf(key, "%d", x);
3386 size_t length;
3387 uint32_t flags;
3388 char* value=memcached_get(memc, key, strlen(key),
3389 &length, &flags, &ret);
3390 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3391 switch (count)
3392 {
3393 case 0: /* FALLTHROUGH */
3394 case 1: /* FALLTHROUGH */
3395 case 2:
3396 assert(strncmp(value, key, len) == 0);
3397 assert(len == length);
3398 break;
3399 case 3:
3400 assert(length == len * 2);
3401 break;
3402 case 4:
3403 assert(length == len * 3);
3404 break;
3405 }
3406 free(value);
3407 }
3408 }
3409
3410 /* Try setting an illegal cas value (should not return an error to
3411 * the caller (because we don't expect a return message from the server)
3412 */
3413 char* keys[]= {"0"};
3414 size_t lengths[]= {1};
3415 size_t length;
3416 uint32_t flags;
3417 memcached_result_st results_obj;
3418 memcached_result_st *results;
3419 ret= memcached_mget(memc, keys, lengths, 1);
3420 assert(ret == MEMCACHED_SUCCESS);
3421
3422 results= memcached_result_create(memc, &results_obj);
3423 assert(results);
3424 results= memcached_fetch_result(memc, &results_obj, &ret);
3425 assert(results);
3426 assert(ret == MEMCACHED_SUCCESS);
3427 uint64_t cas= memcached_result_cas(results);
3428 memcached_result_free(&results_obj);
3429
3430 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3431 assert(ret == MEMCACHED_SUCCESS);
3432
3433 /*
3434 * The item will have a new cas value, so try to set it again with the old
3435 * value. This should fail!
3436 */
3437 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3438 assert(ret == MEMCACHED_SUCCESS);
3439 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3440 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3441 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3442 free(value);
3443
3444 return TEST_SUCCESS;
3445 }
3446
3447 static test_return analyzer_test(memcached_st *memc)
3448 {
3449 memcached_return rc;
3450 memcached_stat_st *stat;
3451 memcached_analysis_st *report;
3452
3453 stat= memcached_stat(memc, NULL, &rc);
3454 assert(rc == MEMCACHED_SUCCESS);
3455 assert(stat);
3456
3457 report= memcached_analyze(memc, stat, &rc);
3458 assert(rc == MEMCACHED_SUCCESS);
3459 assert(report);
3460
3461 free(report);
3462 memcached_stat_free(NULL, stat);
3463
3464 return TEST_SUCCESS;
3465 }
3466
3467 /* Count the objects */
3468 static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),
3469 const char *key __attribute__((unused)),
3470 size_t key_length __attribute__((unused)),
3471 void *context)
3472 {
3473 uint32_t *counter= (uint32_t *)context;
3474
3475 *counter= *counter + 1;
3476
3477 return MEMCACHED_SUCCESS;
3478 }
3479
3480 static test_return dump_test(memcached_st *memc)
3481 {
3482 memcached_return rc;
3483 uint32_t counter= 0;
3484 memcached_dump_func callbacks[1];
3485 test_return main_rc;
3486
3487 callbacks[0]= &callback_dump_counter;
3488
3489 /* No support for Binary protocol yet */
3490 if (memc->flags & MEM_BINARY_PROTOCOL)
3491 return TEST_SUCCESS;
3492
3493 main_rc= set_test3(memc);
3494
3495 assert (main_rc == TEST_SUCCESS);
3496
3497 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
3498 assert(rc == MEMCACHED_SUCCESS);
3499
3500 /* We may have more then 32 if our previous flush has not completed */
3501 assert(counter >= 32);
3502
3503 return TEST_SUCCESS;
3504 }
3505
3506 #ifdef HAVE_LIBMEMCACHEDUTIL
3507 static void* connection_release(void *arg) {
3508 struct {
3509 memcached_pool_st* pool;
3510 memcached_st* mmc;
3511 } *resource= arg;
3512
3513 usleep(250);
3514 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
3515 return arg;
3516 }
3517
3518 static test_return connection_pool_test(memcached_st *memc)
3519 {
3520 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
3521 assert(pool != NULL);
3522 memcached_st* mmc[10];
3523 memcached_return rc;
3524
3525 for (int x= 0; x < 10; ++x) {
3526 mmc[x]= memcached_pool_pop(pool, false, &rc);
3527 assert(mmc[x] != NULL);
3528 assert(rc == MEMCACHED_SUCCESS);
3529 }
3530
3531 assert(memcached_pool_pop(pool, false, &rc) == NULL);
3532 assert(rc == MEMCACHED_SUCCESS);
3533
3534 pthread_t tid;
3535 struct {
3536 memcached_pool_st* pool;
3537 memcached_st* mmc;
3538 } item= { .pool = pool, .mmc = mmc[9] };
3539 pthread_create(&tid, NULL, connection_release, &item);
3540 mmc[9]= memcached_pool_pop(pool, true, &rc);
3541 assert(rc == MEMCACHED_SUCCESS);
3542 pthread_join(tid, NULL);
3543 assert(mmc[9] == item.mmc);
3544 const char *key= "key";
3545 size_t keylen= strlen(key);
3546
3547 // verify that I can do ops with all connections
3548 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
3549 assert(rc == MEMCACHED_SUCCESS);
3550
3551 for (unsigned int x= 0; x < 10; ++x) {
3552 uint64_t number_value;
3553 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
3554 assert(rc == MEMCACHED_SUCCESS);
3555 assert(number_value == (x+1));
3556 }
3557
3558 // Release them..
3559 for (int x= 0; x < 10; ++x)
3560 assert(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
3561
3562 assert(memcached_pool_destroy(pool) == memc);
3563 return TEST_SUCCESS;
3564 }
3565 #endif
3566
3567 static test_return replication_set_test(memcached_st *memc)
3568 {
3569 memcached_return rc;
3570 memcached_st *clone= memcached_clone(NULL, memc);
3571 memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3572
3573 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
3574 assert(rc == MEMCACHED_SUCCESS);
3575
3576 /*
3577 ** "bubba" should now be stored on all of our servers. We don't have an
3578 ** easy to use API to address each individual server, so I'll just iterate
3579 ** through a bunch of "master keys" and I should most likely hit all of the
3580 ** servers...
3581 */
3582 for (int x= 'a'; x <= 'z'; ++x)
3583 {
3584 char key[2]= { [0]= (char)x };
3585 size_t len;
3586 uint32_t flags;
3587 char *val= memcached_get_by_key(clone, key, 1, "bubba", 5,
3588 &len, &flags, &rc);
3589 assert(rc == MEMCACHED_SUCCESS);
3590 assert(val != NULL);
3591 free(val);
3592 }
3593
3594 memcached_free(clone);
3595
3596 return TEST_SUCCESS;
3597 }
3598
3599 static test_return replication_get_test(memcached_st *memc)
3600 {
3601 memcached_return rc;
3602
3603 /*
3604 * Don't do the following in your code. I am abusing the internal details
3605 * within the library, and this is not a supported interface.
3606 * This is to verify correct behavior in the library
3607 */
3608 for (int host= 0; host < memc->number_of_hosts; ++host) {
3609 memcached_st *clone= memcached_clone(NULL, memc);
3610 clone->hosts[host].port= 0;
3611
3612 for (int x= 'a'; x <= 'z'; ++x)
3613 {
3614 char key[2]= { [0]= (char)x };
3615 size_t len;
3616 uint32_t flags;
3617 char *val= memcached_get_by_key(clone, key, 1, "bubba", 5,
3618 &len, &flags, &rc);
3619 assert(rc == MEMCACHED_SUCCESS);
3620 assert(val != NULL);
3621 free(val);
3622 }
3623
3624 memcached_free(clone);
3625 }
3626
3627 return TEST_SUCCESS;
3628 }
3629
3630 static test_return replication_mget_test(memcached_st *memc)
3631 {
3632 memcached_return rc;
3633 memcached_st *clone= memcached_clone(NULL, memc);
3634 memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3635
3636 char *keys[]= { "bubba", "key1", "key2", "key3" };
3637 size_t len[]= { 5, 4, 4, 4 };
3638
3639 for (int x=0; x< 4; ++x)
3640 {
3641 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
3642 assert(rc == MEMCACHED_SUCCESS);
3643 }
3644
3645 /*
3646 * Don't do the following in your code. I am abusing the internal details
3647 * within the library, and this is not a supported interface.
3648 * This is to verify correct behavior in the library
3649 */
3650 memcached_result_st result_obj;
3651 for (int host= 0; host < clone->number_of_hosts; ++host) {
3652 memcached_st *clone= memcached_clone(NULL, memc);
3653 clone->hosts[host].port= 0;
3654
3655 for (int x= 'a'; x <= 'z'; ++x)
3656 {
3657 char key[2]= { [0]= (char)x };
3658
3659 rc= memcached_mget_by_key(clone, key, 1, keys, len, 4);
3660 assert(rc == MEMCACHED_SUCCESS);
3661
3662 memcached_result_st *results= memcached_result_create(clone, &result_obj);
3663 assert(results);
3664
3665 int hits= 0;
3666 while ((results= memcached_fetch_result(clone, &result_obj, &rc)) != NULL)
3667 {
3668 ++hits;
3669 }
3670 assert(hits == 4);
3671 memcached_result_free(&result_obj);
3672 }
3673
3674 memcached_free(clone);
3675 }
3676
3677 return TEST_SUCCESS;
3678 }
3679
3680 static test_return replication_delete_test(memcached_st *memc)
3681 {
3682 memcached_return rc;
3683 memcached_st *clone= memcached_clone(NULL, memc);
3684 /* Delete the items from all of the servers except 1 */
3685 uint64_t repl= memcached_behavior_get(memc,
3686 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
3687 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
3688
3689 char *keys[]= { "bubba", "key1", "key2", "key3" };
3690 size_t len[]= { 5, 4, 4, 4 };
3691
3692 for (int x=0; x< 4; ++x)
3693 {
3694 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
3695 assert(rc == MEMCACHED_SUCCESS);
3696 }
3697
3698 /*
3699 * Don't do the following in your code. I am abusing the internal details
3700 * within the library, and this is not a supported interface.
3701 * This is to verify correct behavior in the library
3702 */
3703 int hash= memcached_generate_hash(memc, keys[0], len[0]);
3704 for (int x= 0; x < (repl + 1); ++x) {
3705 clone->hosts[hash].port= 0;
3706 if (++hash == clone->number_of_hosts)
3707 hash= 0;
3708 }
3709
3710 memcached_result_st result_obj;
3711 for (int host= 0; host < clone->number_of_hosts; ++host) {
3712 for (int x= 'a'; x <= 'z'; ++x)
3713 {
3714 char key[2]= { [0]= (char)x };
3715
3716 rc= memcached_mget_by_key(clone, key, 1, keys, len, 4);
3717 assert(rc == MEMCACHED_SUCCESS);
3718
3719 memcached_result_st *results= memcached_result_create(clone, &result_obj);
3720 assert(results);
3721
3722 int hits= 0;
3723 while ((results= memcached_fetch_result(clone, &result_obj, &rc)) != NULL)
3724 {
3725 ++hits;
3726 }
3727 assert(hits == 4);
3728 memcached_result_free(&result_obj);
3729 }
3730 }
3731 memcached_free(clone);
3732
3733 return TEST_SUCCESS;
3734 }
3735
3736 static void increment_request_id(uint16_t *id)
3737 {
3738 (*id)++;
3739 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
3740 *id= 0;
3741 }
3742
3743 static uint16_t *get_udp_request_ids(memcached_st *memc)
3744 {
3745 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
3746 assert(ids != NULL);
3747 unsigned int x;
3748 for (x= 0; x < memc->number_of_hosts; x++)
3749 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
3750
3751 return ids;
3752 }
3753
3754 static test_return post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
3755 {
3756 unsigned int x;
3757 memcached_server_st *cur_server = memc->hosts;
3758 uint16_t *cur_req_ids = get_udp_request_ids(memc);
3759 for (x= 0; x < memc->number_of_hosts; x++)
3760 {
3761 assert(cur_server[x].cursor_active == 0);
3762 assert(cur_req_ids[x] == expected_req_ids[x]);
3763 }
3764 free(expected_req_ids);
3765 free(cur_req_ids);
3766 return TEST_SUCCESS;
3767 }
3768
3769 /*
3770 ** There is a little bit of a hack here, instead of removing
3771 ** the servers, I just set num host to 0 and them add then new udp servers
3772 **/
3773 static memcached_return init_udp(memcached_st *memc)
3774 {
3775 memcached_version(memc);
3776 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
3777 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
3778 || memc->hosts[0].micro_version < 6)
3779 return MEMCACHED_FAILURE;
3780
3781 uint32_t num_hosts= memc->number_of_hosts;
3782 unsigned int x= 0;
3783 memcached_server_st servers[num_hosts];
3784 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
3785 for (x= 0; x < num_hosts; x++)
3786 memcached_server_free(&memc->hosts[x]);
3787 memc->number_of_hosts= 0;
3788 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
3789 for (x= 0; x < num_hosts; x++)
3790 {
3791 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
3792 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3793 }
3794 return MEMCACHED_SUCCESS;
3795 }
3796
3797 static memcached_return binary_init_udp(memcached_st *memc)
3798 {
3799 pre_binary(memc);
3800 return init_udp(memc);
3801 }
3802
3803 /* Make sure that I cant add a tcp server to a udp client */
3804 static test_return add_tcp_server_udp_client_test(memcached_st *memc)
3805 {
3806 memcached_server_st server;
3807 memcached_server_clone(&server, &memc->hosts[0]);
3808 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
3809 assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
3810 return TEST_SUCCESS;
3811 }
3812
3813 /* Make sure that I cant add a udp server to a tcp client */
3814 static test_return add_udp_server_tcp_client_test(memcached_st *memc)
3815 {
3816 memcached_server_st server;
3817 memcached_server_clone(&server, &memc->hosts[0]);
3818 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
3819
3820 memcached_st tcp_client;
3821 memcached_create(&tcp_client);
3822 assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
3823 return TEST_SUCCESS;
3824 }
3825
3826 static test_return set_udp_behavior_test(memcached_st *memc)
3827 {
3828
3829 memcached_quit(memc);
3830 memc->number_of_hosts= 0;
3831 run_distribution(memc);
3832 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
3833 assert(memc->flags & MEM_USE_UDP);
3834 assert(memc->flags & MEM_NOREPLY);;
3835
3836 assert(memc->number_of_hosts == 0);
3837
3838 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
3839 assert(!(memc->flags & MEM_USE_UDP));
3840 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
3841 assert(!(memc->flags & MEM_NOREPLY));
3842 return TEST_SUCCESS;
3843 }
3844
3845 static test_return udp_set_test(memcached_st *memc)
3846 {
3847 unsigned int x= 0;
3848 unsigned int num_iters= 1025; //request id rolls over at 1024
3849 for (x= 0; x < num_iters;x++)
3850 {
3851 memcached_return rc;
3852 char *key= "foo";
3853 char *value= "when we sanitize";
3854 uint16_t *expected_ids= get_udp_request_ids(memc);
3855 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
3856 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
3857 rc= memcached_set(memc, key, strlen(key),
3858 value, strlen(value),
3859 (time_t)0, (uint32_t)0);
3860 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3861 /** NB, the check below assumes that if new write_ptr is less than
3862 * the original write_ptr that we have flushed. For large payloads, this
3863 * maybe an invalid assumption, but for the small payload we have it is OK
3864 */
3865 if (rc == MEMCACHED_SUCCESS ||
3866 memc->hosts[server_key].write_buffer_offset < init_offset)
3867 increment_request_id(&expected_ids[server_key]);
3868
3869 if (rc == MEMCACHED_SUCCESS)
3870 {
3871 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3872 }
3873 else
3874 {
3875 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
3876 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
3877 }
3878 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
3879 }
3880 return TEST_SUCCESS;
3881 }
3882
3883 static test_return udp_buffered_set_test(memcached_st *memc)
3884 {
3885 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3886 return udp_set_test(memc);
3887 }
3888
3889 static test_return udp_set_too_big_test(memcached_st *memc)
3890 {
3891 memcached_return rc;
3892 char *key= "bar";
3893 char value[MAX_UDP_DATAGRAM_LENGTH];
3894 uint16_t *expected_ids= get_udp_request_ids(memc);
3895 rc= memcached_set(memc, key, strlen(key),
3896 value, MAX_UDP_DATAGRAM_LENGTH,
3897 (time_t)0, (uint32_t)0);
3898 assert(rc == MEMCACHED_WRITE_FAILURE);
3899 return post_udp_op_check(memc,expected_ids);
3900 }
3901
3902 static test_return udp_delete_test(memcached_st *memc)
3903 {
3904 unsigned int x= 0;
3905 unsigned int num_iters= 1025; //request id rolls over at 1024
3906 for (x= 0; x < num_iters;x++)
3907 {
3908 memcached_return rc;
3909 char *key= "foo";
3910 uint16_t *expected_ids=get_udp_request_ids(memc);
3911 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3912 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
3913 rc= memcached_delete(memc, key, strlen(key), 0);
3914 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3915 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
3916 increment_request_id(&expected_ids[server_key]);
3917 if (rc == MEMCACHED_SUCCESS)
3918 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3919 else
3920 {
3921 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
3922 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
3923 }
3924 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
3925 }
3926 return TEST_SUCCESS;
3927 }
3928
3929 static test_return udp_buffered_delete_test(memcached_st *memc)
3930 {
3931 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3932 return udp_delete_test(memc);
3933 }
3934
3935 static test_return udp_verbosity_test(memcached_st *memc)
3936 {
3937 memcached_return rc;
3938 uint16_t *expected_ids= get_udp_request_ids(memc);
3939 unsigned int x;
3940 for (x= 0; x < memc->number_of_hosts;x++)
3941 increment_request_id(&expected_ids[x]);
3942
3943 rc= memcached_verbosity(memc,3);
3944 assert(rc == MEMCACHED_SUCCESS);
3945 return post_udp_op_check(memc,expected_ids);
3946 }
3947
3948 static test_return udp_quit_test(memcached_st *memc)
3949 {
3950 uint16_t *expected_ids= get_udp_request_ids(memc);
3951 memcached_quit(memc);
3952 return post_udp_op_check(memc, expected_ids);
3953 }
3954
3955 static test_return udp_flush_test(memcached_st *memc)
3956 {
3957 memcached_return rc;
3958 uint16_t *expected_ids= get_udp_request_ids(memc);
3959 unsigned int x;
3960 for (x= 0; x < memc->number_of_hosts;x++)
3961 increment_request_id(&expected_ids[x]);
3962
3963 rc= memcached_flush(memc,0);
3964 assert(rc == MEMCACHED_SUCCESS);
3965 return post_udp_op_check(memc,expected_ids);
3966 }
3967
3968 static test_return udp_incr_test(memcached_st *memc)
3969 {
3970 memcached_return rc;
3971 char *key= "incr";
3972 char *value= "1";
3973 rc= memcached_set(memc, key, strlen(key),
3974 value, strlen(value),
3975 (time_t)0, (uint32_t)0);
3976
3977 assert(rc == MEMCACHED_SUCCESS);
3978 uint16_t *expected_ids= get_udp_request_ids(memc);
3979 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3980 increment_request_id(&expected_ids[server_key]);
3981 uint64_t newvalue;
3982 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
3983 assert(rc == MEMCACHED_SUCCESS);
3984 return post_udp_op_check(memc, expected_ids);
3985 }
3986
3987 static test_return udp_decr_test(memcached_st *memc)
3988 {
3989 memcached_return rc;
3990 char *key= "decr";
3991 char *value= "1";
3992 rc= memcached_set(memc, key, strlen(key),
3993 value, strlen(value),
3994 (time_t)0, (uint32_t)0);
3995
3996 assert(rc == MEMCACHED_SUCCESS);
3997 uint16_t *expected_ids= get_udp_request_ids(memc);
3998 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3999 increment_request_id(&expected_ids[server_key]);
4000 uint64_t newvalue;
4001 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4002 assert(rc == MEMCACHED_SUCCESS);
4003 return post_udp_op_check(memc, expected_ids);
4004 }
4005
4006
4007 static test_return udp_stat_test(memcached_st *memc)
4008 {
4009 memcached_stat_st * rv= NULL;
4010 memcached_return rc;
4011 char args[]= "";
4012 uint16_t *expected_ids = get_udp_request_ids(memc);
4013 rv = memcached_stat(memc, args, &rc);
4014 free(rv);
4015 assert(rc == MEMCACHED_NOT_SUPPORTED);
4016 return post_udp_op_check(memc, expected_ids);
4017 }
4018
4019 static test_return udp_version_test(memcached_st *memc)
4020 {
4021 memcached_return rc;
4022 uint16_t *expected_ids = get_udp_request_ids(memc);
4023 rc = memcached_version(memc);
4024 assert(rc == MEMCACHED_NOT_SUPPORTED);
4025 return post_udp_op_check(memc, expected_ids);
4026 }
4027
4028 static test_return udp_get_test(memcached_st *memc)
4029 {
4030 memcached_return rc;
4031 char *key= "foo";
4032 size_t vlen;
4033 uint16_t *expected_ids = get_udp_request_ids(memc);
4034 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4035 assert(rc == MEMCACHED_NOT_SUPPORTED);
4036 assert(val == NULL);
4037 return post_udp_op_check(memc, expected_ids);
4038 }
4039
4040 static test_return udp_mixed_io_test(memcached_st *memc)
4041 {
4042 test_st current_op;
4043 test_st mixed_io_ops [] ={
4044 {"udp_set_test", 0, udp_set_test},
4045 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4046 {"udp_delete_test", 0, udp_delete_test},
4047 {"udp_verbosity_test", 0, udp_verbosity_test},
4048 {"udp_quit_test", 0, udp_quit_test},
4049 {"udp_flush_test", 0, udp_flush_test},
4050 {"udp_incr_test", 0, udp_incr_test},
4051 {"udp_decr_test", 0, udp_decr_test},
4052 {"udp_version_test", 0, udp_version_test}
4053 };
4054 unsigned int x= 0;
4055 for (x= 0; x < 500; x++)
4056 {
4057 current_op= mixed_io_ops[random() % 9];
4058 assert(current_op.function(memc) == TEST_SUCCESS);
4059 }
4060 return TEST_SUCCESS;
4061 }
4062
4063 static test_return hsieh_avaibility_test (memcached_st *memc)
4064 {
4065 memcached_return expected_rc= MEMCACHED_FAILURE;
4066 #ifdef HAVE_HSIEH_HASH
4067 expected_rc= MEMCACHED_SUCCESS;
4068 #endif
4069 memcached_return rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4070 (uint64_t)MEMCACHED_HASH_HSIEH);
4071 assert(rc == expected_rc);
4072 return TEST_SUCCESS;
4073 }
4074
4075 static char *list[]=
4076 {
4077 "apple",
4078 "beat",
4079 "carrot",
4080 "daikon",
4081 "eggplant",
4082 "flower",
4083 "green",
4084 "hide",
4085 "ick",
4086 "jack",
4087 "kick",
4088 "lime",
4089 "mushrooms",
4090 "nectarine",
4091 "orange",
4092 "peach",
4093 "quant",
4094 "ripen",
4095 "strawberry",
4096 "tang",
4097 "up",
4098 "volumne",
4099 "when",
4100 "yellow",
4101 "zip",
4102 NULL
4103 };
4104
4105 static test_return md5_run (memcached_st *memc __attribute__((unused)))
4106 {
4107 uint32_t x;
4108 char **ptr;
4109 uint32_t values[]= { 3195025439, 2556848621, 3724893440, 3332385401, 245758794, 2550894432,
4110 121710495, 3053817768, 1250994555, 1862072655, 2631955953, 2951528551,
4111 1451250070, 2820856945, 2060845566, 3646985608, 2138080750, 217675895,
4112 2230934345, 1234361223, 3968582726, 2455685270, 1293568479, 199067604,
4113 2042482093 };
4114
4115
4116 for (ptr= list, x= 0; *ptr; ptr++, x++)
4117 {
4118 uint32_t hash_val;
4119
4120 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4121 assert(values[x] == hash_val);
4122 }
4123
4124 return TEST_SUCCESS;
4125 }
4126
4127 static test_return crc_run (memcached_st *memc __attribute__((unused)))
4128 {
4129 uint32_t x;
4130 char **ptr;
4131 uint32_t values[]= { 10542, 22009, 14526, 19510, 19432, 10199, 20634, 9369, 11511, 10362,
4132 7893, 31289, 11313, 9354, 7621, 30628, 15218, 25967, 2695, 9380,
4133 17300, 28156, 9192, 20484, 16925 };
4134
4135 for (ptr= list, x= 0; *ptr; ptr++, x++)
4136 {
4137 uint32_t hash_val;
4138
4139 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4140 assert(values[x] == hash_val);
4141 }
4142
4143 return TEST_SUCCESS;
4144 }
4145
4146 static test_return fnv1_64_run (memcached_st *memc __attribute__((unused)))
4147 {
4148 uint32_t x;
4149 char **ptr;
4150 uint32_t values[]= { 473199127, 4148981457, 3971873300, 3257986707, 1722477987, 2991193800,
4151 4147007314, 3633179701, 1805162104, 3503289120, 3395702895, 3325073042,
4152 2345265314, 3340346032, 2722964135, 1173398992, 2815549194, 2562818319,
4153 224996066, 2680194749, 3035305390, 246890365, 2395624193, 4145193337,
4154 1801941682 };
4155
4156 for (ptr= list, x= 0; *ptr; ptr++, x++)
4157 {
4158 uint32_t hash_val;
4159
4160 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4161 assert(values[x] == hash_val);
4162 }
4163
4164 return TEST_SUCCESS;
4165 }
4166
4167 static test_return fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4168 {
4169 uint32_t x;
4170 char **ptr;
4171 uint32_t values[]= { 1488911807, 2500855813, 1510099634, 1390325195, 3647689787, 3241528582,
4172 1669328060, 2604311949, 734810122, 1516407546, 560948863, 1767346780,
4173 561034892, 4156330026, 3716417003, 3475297030, 1518272172, 227211583,
4174 3938128828, 126112909, 3043416448, 3131561933, 1328739897, 2455664041,
4175 2272238452 };
4176
4177 for (ptr= list, x= 0; *ptr; ptr++, x++)
4178 {
4179 uint32_t hash_val;
4180
4181 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4182 assert(values[x] == hash_val);
4183 }
4184
4185 return TEST_SUCCESS;
4186 }
4187
4188 static test_return fnv1_32_run (memcached_st *memc __attribute__((unused)))
4189 {
4190 uint32_t x;
4191 char **ptr;
4192 uint32_t values[]= { 67176023, 1190179409, 2043204404, 3221866419, 2567703427, 3787535528, 4147287986,
4193 3500475733, 344481048, 3865235296, 2181839183, 119581266, 510234242, 4248244304,
4194 1362796839, 103389328, 1449620010, 182962511, 3554262370, 3206747549, 1551306158,
4195 4127558461, 1889140833, 2774173721, 1180552018 };
4196
4197
4198 for (ptr= list, x= 0; *ptr; ptr++, x++)
4199 {
4200 uint32_t hash_val;
4201
4202 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4203 assert(values[x] == hash_val);
4204 }
4205
4206 return TEST_SUCCESS;
4207 }
4208
4209 static test_return fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4210 {
4211 uint32_t x;
4212 char **ptr;
4213 uint32_t values[]= { 280767167, 2421315013, 3072375666, 855001899, 459261019, 3521085446, 18738364,
4214 1625305005, 2162232970, 777243802, 3323728671, 132336572, 3654473228, 260679466,
4215 1169454059, 2698319462, 1062177260, 235516991, 2218399068, 405302637, 1128467232,
4216 3579622413, 2138539289, 96429129, 2877453236 };
4217
4218 for (ptr= list, x= 0; *ptr; ptr++, x++)
4219 {
4220 uint32_t hash_val;
4221
4222 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4223 assert(values[x] == hash_val);
4224 }
4225
4226 return TEST_SUCCESS;
4227 }
4228
4229 static test_return hsieh_run (memcached_st *memc __attribute__((unused)))
4230 {
4231 uint32_t x;
4232 char **ptr;
4233 #ifdef HAVE_HSIEH_HASH
4234 uint32_t values[]= { 3738850110, 3636226060, 3821074029, 3489929160, 3485772682, 80540287,
4235 1805464076, 1895033657, 409795758, 979934958, 3634096985, 1284445480,
4236 2265380744, 707972988, 353823508, 1549198350, 1327930172, 9304163,
4237 4220749037, 2493964934, 2777873870, 2057831732, 1510213931, 2027828987,
4238 3395453351 };
4239 #else
4240 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 };
4241 #endif
4242
4243 for (ptr= list, x= 0; *ptr; ptr++, x++)
4244 {
4245 uint32_t hash_val;
4246
4247 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4248 assert(values[x] == hash_val);
4249 }
4250
4251 return TEST_SUCCESS;
4252 }
4253
4254 static test_return murmur_run (memcached_st *memc __attribute__((unused)))
4255 {
4256 uint32_t x;
4257 char **ptr;
4258 uint32_t values[]= { 473199127, 4148981457, 3971873300, 3257986707, 1722477987, 2991193800,
4259 4147007314, 3633179701, 1805162104, 3503289120, 3395702895, 3325073042,
4260 2345265314, 3340346032, 2722964135, 1173398992, 2815549194, 2562818319,
4261 224996066, 2680194749, 3035305390, 246890365, 2395624193, 4145193337,
4262 1801941682 };
4263
4264 for (ptr= list, x= 0; *ptr; ptr++, x++)
4265 {
4266 uint32_t hash_val;
4267
4268 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4269 assert(values[x] == hash_val);
4270 }
4271
4272 return TEST_SUCCESS;
4273 }
4274
4275 static test_return jenkins_run (memcached_st *memc __attribute__((unused)))
4276 {
4277 uint32_t x;
4278 char **ptr;
4279 uint32_t values[]= { 1442444624, 4253821186, 1885058256, 2120131735, 3261968576, 3515188778,
4280 4232909173, 4288625128, 1812047395, 3689182164, 2502979932, 1214050606,
4281 2415988847, 1494268927, 1025545760, 3920481083, 4153263658, 3824871822,
4282 3072759809, 798622255, 3065432577, 1453328165, 2691550971, 3408888387,
4283 2629893356 };
4284
4285
4286 for (ptr= list, x= 0; *ptr; ptr++, x++)
4287 {
4288 uint32_t hash_val;
4289
4290 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4291 assert(values[x] == hash_val);
4292 }
4293
4294 return TEST_SUCCESS;
4295 }
4296
4297 test_st udp_setup_server_tests[] ={
4298 {"set_udp_behavior_test", 0, set_udp_behavior_test},
4299 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
4300 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
4301 {0, 0, 0}
4302 };
4303
4304 test_st upd_io_tests[] ={
4305 {"udp_set_test", 0, udp_set_test},
4306 {"udp_buffered_set_test", 0, udp_buffered_set_test},
4307 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4308 {"udp_delete_test", 0, udp_delete_test},
4309 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
4310 {"udp_verbosity_test", 0, udp_verbosity_test},
4311 {"udp_quit_test", 0, udp_quit_test},
4312 {"udp_flush_test", 0, udp_flush_test},
4313 {"udp_incr_test", 0, udp_incr_test},
4314 {"udp_decr_test", 0, udp_decr_test},
4315 {"udp_stat_test", 0, udp_stat_test},
4316 {"udp_version_test", 0, udp_version_test},
4317 {"udp_get_test", 0, udp_get_test},
4318 {"udp_mixed_io_test", 0, udp_mixed_io_test},
4319 {0, 0, 0}
4320 };
4321
4322 /* Clean the server before beginning testing */
4323 test_st tests[] ={
4324 {"flush", 0, flush_test },
4325 {"init", 0, init_test },
4326 {"allocation", 0, allocation_test },
4327 {"server_list_null_test", 0, server_list_null_test},
4328 {"server_unsort", 0, server_unsort_test},
4329 {"server_sort", 0, server_sort_test},
4330 {"server_sort2", 0, server_sort2_test},
4331 {"clone_test", 0, clone_test },
4332 {"connection_test", 0, connection_test},
4333 {"callback_test", 0, callback_test},
4334 {"behavior_test", 0, behavior_test},
4335 {"userdata_test", 0, userdata_test},
4336 {"error", 0, error_test },
4337 {"set", 0, set_test },
4338 {"set2", 0, set_test2 },
4339 {"set3", 0, set_test3 },
4340 {"dump", 1, dump_test},
4341 {"add", 1, add_test },
4342 {"replace", 1, replace_test },
4343 {"delete", 1, delete_test },
4344 {"get", 1, get_test },
4345 {"get2", 0, get_test2 },
4346 {"get3", 0, get_test3 },
4347 {"get4", 0, get_test4 },
4348 {"partial mget", 0, get_test5 },
4349 {"stats_servername", 0, stats_servername_test },
4350 {"increment", 0, increment_test },
4351 {"increment_with_initial", 1, increment_with_initial_test },
4352 {"decrement", 0, decrement_test },
4353 {"decrement_with_initial", 1, decrement_with_initial_test },
4354 {"quit", 0, quit_test },
4355 {"mget", 1, mget_test },
4356 {"mget_result", 1, mget_result_test },
4357 {"mget_result_alloc", 1, mget_result_alloc_test },
4358 {"mget_result_function", 1, mget_result_function },
4359 {"get_stats", 0, get_stats },
4360 {"add_host_test", 0, add_host_test },
4361 {"add_host_test_1", 0, add_host_test1 },
4362 {"get_stats_keys", 0, get_stats_keys },
4363 {"behavior_test", 0, get_stats_keys },
4364 {"callback_test", 0, get_stats_keys },
4365 {"version_string_test", 0, version_string_test},
4366 {"bad_key", 1, bad_key_test },
4367 {"memcached_server_cursor", 1, memcached_server_cursor_test },
4368 {"read_through", 1, read_through },
4369 {"delete_through", 1, delete_through },
4370 {"noreply", 1, noreply_test},
4371 {"analyzer", 1, analyzer_test},
4372 #ifdef HAVE_LIBMEMCACHEDUTIL
4373 {"connectionpool", 1, connection_pool_test },
4374 #endif
4375 {0, 0, 0}
4376 };
4377
4378 test_st async_tests[] ={
4379 {"add", 1, add_wrapper },
4380 {0, 0, 0}
4381 };
4382
4383 test_st string_tests[] ={
4384 {"string static with null", 0, string_static_null },
4385 {"string alloc with null", 0, string_alloc_null },
4386 {"string alloc with 1K", 0, string_alloc_with_size },
4387 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
4388 {"string append", 0, string_alloc_append },
4389 {"string append failure (too big)", 0, string_alloc_append_toobig },
4390 {0, 0, 0}
4391 };
4392
4393 test_st result_tests[] ={
4394 {"result static", 0, result_static},
4395 {"result alloc", 0, result_alloc},
4396 {0, 0, 0}
4397 };
4398
4399 test_st version_1_2_3[] ={
4400 {"append", 0, append_test },
4401 {"prepend", 0, prepend_test },
4402 {"cas", 0, cas_test },
4403 {"cas2", 0, cas2_test },
4404 {"append_binary", 0, append_binary_test },
4405 {0, 0, 0}
4406 };
4407
4408 test_st user_tests[] ={
4409 {"user_supplied_bug1", 0, user_supplied_bug1 },
4410 {"user_supplied_bug2", 0, user_supplied_bug2 },
4411 {"user_supplied_bug3", 0, user_supplied_bug3 },
4412 {"user_supplied_bug4", 0, user_supplied_bug4 },
4413 {"user_supplied_bug5", 1, user_supplied_bug5 },
4414 {"user_supplied_bug6", 1, user_supplied_bug6 },
4415 {"user_supplied_bug7", 1, user_supplied_bug7 },
4416 {"user_supplied_bug8", 1, user_supplied_bug8 },
4417 {"user_supplied_bug9", 1, user_supplied_bug9 },
4418 {"user_supplied_bug10", 1, user_supplied_bug10 },
4419 {"user_supplied_bug11", 1, user_supplied_bug11 },
4420 {"user_supplied_bug12", 1, user_supplied_bug12 },
4421 {"user_supplied_bug13", 1, user_supplied_bug13 },
4422 {"user_supplied_bug14", 1, user_supplied_bug14 },
4423 {"user_supplied_bug15", 1, user_supplied_bug15 },
4424 {"user_supplied_bug16", 1, user_supplied_bug16 },
4425 #ifndef __sun
4426 /*
4427 ** It seems to be something weird with the character sets..
4428 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
4429 ** guess I need to find out how this is supposed to work.. Perhaps I need
4430 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
4431 ** so just disable the code for now...).
4432 */
4433 {"user_supplied_bug17", 1, user_supplied_bug17 },
4434 #endif
4435 {"user_supplied_bug18", 1, user_supplied_bug18 },
4436 {"user_supplied_bug19", 1, user_supplied_bug19 },
4437 {"user_supplied_bug20", 1, user_supplied_bug20 },
4438 {0, 0, 0}
4439 };
4440
4441 test_st replication_tests[]= {
4442 {"set", 1, replication_set_test },
4443 {"get", 0, replication_get_test },
4444 {"mget", 0, replication_mget_test },
4445 {"delete", 0, replication_delete_test },
4446 {0, 0, 0}
4447 };
4448
4449 test_st generate_tests[] ={
4450 {"generate_pairs", 1, generate_pairs },
4451 {"generate_data", 1, generate_data },
4452 {"get_read", 0, get_read },
4453 {"delete_generate", 0, delete_generate },
4454 {"generate_buffer_data", 1, generate_buffer_data },
4455 {"delete_buffer", 0, delete_buffer_generate},
4456 {"generate_data", 1, generate_data },
4457 {"mget_read", 0, mget_read },
4458 {"mget_read_result", 0, mget_read_result },
4459 {"mget_read_function", 0, mget_read_function },
4460 {"cleanup", 1, cleanup_pairs },
4461 {"generate_large_pairs", 1, generate_large_pairs },
4462 {"generate_data", 1, generate_data },
4463 {"generate_buffer_data", 1, generate_buffer_data },
4464 {"cleanup", 1, cleanup_pairs },
4465 {0, 0, 0}
4466 };
4467
4468 test_st consistent_tests[] ={
4469 {"generate_pairs", 1, generate_pairs },
4470 {"generate_data", 1, generate_data },
4471 {"get_read", 0, get_read_count },
4472 {"cleanup", 1, cleanup_pairs },
4473 {0, 0, 0}
4474 };
4475
4476 test_st consistent_weighted_tests[] ={
4477 {"generate_pairs", 1, generate_pairs },
4478 {"generate_data", 1, generate_data_with_stats },
4479 {"get_read", 0, get_read_count },
4480 {"cleanup", 1, cleanup_pairs },
4481 {0, 0, 0}
4482 };
4483
4484 test_st hsieh_availability[] ={
4485 {"hsieh_avaibility_test",0,hsieh_avaibility_test},
4486 {0, 0, 0}
4487 };
4488
4489 test_st ketama_auto_eject_hosts[] ={
4490 {"auto_eject_hosts", 1, auto_eject_hosts },
4491 {0, 0, 0}
4492 };
4493
4494 test_st hash_tests[] ={
4495 {"md5", 0, md5_run },
4496 {"crc", 0, crc_run },
4497 {"fnv1_64", 0, fnv1_64_run },
4498 {"fnv1a_64", 0, fnv1a_64_run },
4499 {"fnv1_32", 0, fnv1_32_run },
4500 {"fnv1a_32", 0, fnv1a_32_run },
4501 {"hsieh", 0, hsieh_run },
4502 {"murmur", 0, murmur_run },
4503 {"jenkis", 0, jenkins_run },
4504 {0, 0, 0}
4505 };
4506
4507 collection_st collection[] ={
4508 {"hsieh_availability",0,0,hsieh_availability},
4509 {"udp_setup", init_udp, 0, udp_setup_server_tests},
4510 {"udp_io", init_udp, 0, upd_io_tests},
4511 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
4512 {"block", 0, 0, tests},
4513 {"binary", pre_binary, 0, tests},
4514 {"nonblock", pre_nonblock, 0, tests},
4515 {"nodelay", pre_nodelay, 0, tests},
4516 {"settimer", pre_settimer, 0, tests},
4517 {"md5", pre_md5, 0, tests},
4518 {"crc", pre_crc, 0, tests},
4519 {"hsieh", pre_hsieh, 0, tests},
4520 {"jenkins", pre_jenkins, 0, tests},
4521 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
4522 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
4523 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
4524 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
4525 {"ketama", pre_behavior_ketama, 0, tests},
4526 {"ketama_auto_eject_hosts", pre_behavior_ketama, 0, ketama_auto_eject_hosts},
4527 {"unix_socket", pre_unix_socket, 0, tests},
4528 {"unix_socket_nodelay", pre_nodelay, 0, tests},
4529 {"poll_timeout", poll_timeout, 0, tests},
4530 {"gets", enable_cas, 0, tests},
4531 {"consistent", enable_consistent, 0, tests},
4532 {"deprecated_memory_allocators", deprecated_set_memory_alloc, 0, tests},
4533 {"memory_allocators", set_memory_alloc, 0, tests},
4534 {"prefix", set_prefix, 0, tests},
4535 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
4536 {"string", 0, 0, string_tests},
4537 {"result", 0, 0, result_tests},
4538 {"async", pre_nonblock, 0, async_tests},
4539 {"async_binary", pre_nonblock_binary, 0, async_tests},
4540 {"user", 0, 0, user_tests},
4541 {"generate", 0, 0, generate_tests},
4542 {"generate_hsieh", pre_hsieh, 0, generate_tests},
4543 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
4544 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
4545 {"generate_md5", pre_md5, 0, generate_tests},
4546 {"generate_murmur", pre_murmur, 0, generate_tests},
4547 {"generate_jenkins", pre_jenkins, 0, generate_tests},
4548 {"generate_nonblock", pre_nonblock, 0, generate_tests},
4549 {"consistent_not", 0, 0, consistent_tests},
4550 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
4551 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
4552 {"test_hashes", 0, 0, hash_tests},
4553 {"replication", pre_replication, 0, replication_tests},
4554 {0, 0, 0, 0}
4555 };
4556
4557 #define SERVERS_TO_CREATE 5
4558
4559 /* Prototypes for functions we will pass to test framework */
4560 void *world_create(void);
4561 void world_destroy(void *p);
4562
4563 void *world_create(void)
4564 {
4565 server_startup_st *construct;
4566
4567 construct= (server_startup_st *)malloc(sizeof(server_startup_st));
4568 memset(construct, 0, sizeof(server_startup_st));
4569 construct->count= SERVERS_TO_CREATE;
4570 construct->udp= 0;
4571 server_startup(construct);
4572
4573 return construct;
4574 }
4575
4576
4577 void world_destroy(void *p)
4578 {
4579 server_startup_st *construct= (server_startup_st *)p;
4580 memcached_server_st *servers= (memcached_server_st *)construct->servers;
4581 memcached_server_list_free(servers);
4582
4583 server_shutdown(construct);
4584 free(construct);
4585 }
4586
4587 void get_world(world_st *world)
4588 {
4589 world->collections= collection;
4590 world->create= world_create;
4591 world->destroy= world_destroy;
4592 }