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