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