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