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