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