Added reviewed version of memcached_server_get_last_disconnect
[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 memcached_return rc= MEMCACHED_FAILURE;
3221
3222 if (pre_binary(memc) != MEMCACHED_SUCCESS)
3223 return TEST_SKIPPED;
3224
3225 /*
3226 * Make sure that we store the item on all servers
3227 * (master + replicas == number of servers)
3228 */
3229 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3230 memc->number_of_hosts - 1);
3231 assert(rc == MEMCACHED_SUCCESS);
3232 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memc->number_of_hosts - 1);
3233
3234 return rc;
3235 }
3236
3237 static memcached_return pre_replication_noblock(memcached_st *memc)
3238 {
3239 memcached_return rc= MEMCACHED_FAILURE;
3240 if (pre_replication(memc) == MEMCACHED_SUCCESS &&
3241 pre_nonblock(memc) == MEMCACHED_SUCCESS)
3242 rc= MEMCACHED_SUCCESS;
3243
3244 return rc;
3245 }
3246
3247 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3248 {
3249 free(mem);
3250 }
3251
3252 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3253 {
3254 void *ret= malloc(size);
3255 if (ret != NULL)
3256 memset(ret, 0xff, size);
3257
3258 return ret;
3259 }
3260
3261 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3262 {
3263 return realloc(mem, size);
3264 }
3265
3266 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3267 {
3268 return calloc(nelem, size);
3269 }
3270
3271 static memcached_return set_prefix(memcached_st *memc)
3272 {
3273 memcached_return rc;
3274 const char *key= "mine";
3275 char *value;
3276
3277 /* Make sure be default none exists */
3278 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3279 assert(rc == MEMCACHED_FAILURE);
3280
3281 /* Test a clean set */
3282 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3283 assert(rc == MEMCACHED_SUCCESS);
3284
3285 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3286 assert(memcmp(value, key, 4) == 0);
3287 assert(rc == MEMCACHED_SUCCESS);
3288
3289 /* Test that we can turn it off */
3290 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3291 assert(rc == MEMCACHED_SUCCESS);
3292
3293 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3294 assert(rc == MEMCACHED_FAILURE);
3295
3296 /* Now setup for main test */
3297 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3298 assert(rc == MEMCACHED_SUCCESS);
3299
3300 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3301 assert(rc == MEMCACHED_SUCCESS);
3302 assert(memcmp(value, key, 4) == 0);
3303
3304 /* Set to Zero, and then Set to something too large */
3305 {
3306 char long_key[255];
3307 memset(long_key, 0, 255);
3308
3309 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3310 assert(rc == MEMCACHED_SUCCESS);
3311
3312 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3313 assert(rc == MEMCACHED_FAILURE);
3314 assert(value == NULL);
3315
3316 /* Test a long key for failure */
3317 /* TODO, extend test to determine based on setting, what result should be */
3318 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3319 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3320 //assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3321 assert(rc == MEMCACHED_SUCCESS);
3322
3323 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3324 strcpy(long_key, "This is more then the allotted number of characters");
3325 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3326 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3327
3328 /* Test for a bad prefix, but with a short key */
3329 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3330 assert(rc == MEMCACHED_SUCCESS);
3331
3332 strcpy(long_key, "dog cat");
3333 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3334 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3335 }
3336
3337 return MEMCACHED_SUCCESS;
3338 }
3339
3340 #ifdef MEMCACHED_ENABLE_DEPRECATED
3341 static memcached_return deprecated_set_memory_alloc(memcached_st *memc)
3342 {
3343 void *test_ptr= NULL;
3344 void *cb_ptr= NULL;
3345 {
3346 memcached_malloc_function malloc_cb=
3347 (memcached_malloc_function)my_malloc;
3348 cb_ptr= *(void **)&malloc_cb;
3349 memcached_return rc;
3350
3351 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3352 assert(rc == MEMCACHED_SUCCESS);
3353 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3354 assert(rc == MEMCACHED_SUCCESS);
3355 assert(test_ptr == cb_ptr);
3356 }
3357
3358 {
3359 memcached_realloc_function realloc_cb=
3360 (memcached_realloc_function)my_realloc;
3361 cb_ptr= *(void **)&realloc_cb;
3362 memcached_return rc;
3363
3364 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3365 assert(rc == MEMCACHED_SUCCESS);
3366 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3367 assert(rc == MEMCACHED_SUCCESS);
3368 assert(test_ptr == cb_ptr);
3369 }
3370
3371 {
3372 memcached_free_function free_cb=
3373 (memcached_free_function)my_free;
3374 cb_ptr= *(void **)&free_cb;
3375 memcached_return rc;
3376
3377 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3378 assert(rc == MEMCACHED_SUCCESS);
3379 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3380 assert(rc == MEMCACHED_SUCCESS);
3381 assert(test_ptr == cb_ptr);
3382 }
3383 return MEMCACHED_SUCCESS;
3384 }
3385 #endif
3386
3387 static memcached_return set_memory_alloc(memcached_st *memc)
3388 {
3389 memcached_return rc;
3390 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3391 my_realloc, my_calloc);
3392 assert(rc == MEMCACHED_FAILURE);
3393
3394 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3395 my_realloc, my_calloc);
3396
3397 memcached_malloc_function mem_malloc;
3398 memcached_free_function mem_free;
3399 memcached_realloc_function mem_realloc;
3400 memcached_calloc_function mem_calloc;
3401 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3402 &mem_realloc, &mem_calloc);
3403
3404 assert(mem_malloc == my_malloc);
3405 assert(mem_realloc == my_realloc);
3406 assert(mem_calloc == my_calloc);
3407 assert(mem_free == my_free);
3408
3409 return MEMCACHED_SUCCESS;
3410 }
3411
3412 static memcached_return enable_consistent(memcached_st *memc)
3413 {
3414 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3415 memcached_hash hash;
3416 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3417 if (pre_hsieh(memc) != MEMCACHED_SUCCESS)
3418 return MEMCACHED_FAILURE;
3419
3420 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3421 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3422
3423 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3424 assert(hash == MEMCACHED_HASH_HSIEH);
3425
3426
3427 return MEMCACHED_SUCCESS;
3428 }
3429
3430 static memcached_return enable_cas(memcached_st *memc)
3431 {
3432 unsigned int set= 1;
3433
3434 memcached_version(memc);
3435
3436 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3437 || memc->hosts[0].minor_version > 2)
3438 {
3439 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3440
3441 return MEMCACHED_SUCCESS;
3442 }
3443
3444 return MEMCACHED_FAILURE;
3445 }
3446
3447 static memcached_return check_for_1_2_3(memcached_st *memc)
3448 {
3449 memcached_version(memc);
3450
3451 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3452 || memc->hosts[0].minor_version > 2)
3453 return MEMCACHED_SUCCESS;
3454
3455 return MEMCACHED_FAILURE;
3456 }
3457
3458 static memcached_return pre_unix_socket(memcached_st *memc)
3459 {
3460 memcached_return rc;
3461 struct stat buf;
3462
3463 memcached_server_list_free(memc->hosts);
3464 memc->hosts= NULL;
3465 memc->number_of_hosts= 0;
3466
3467 if (stat("/tmp/memcached.socket", &buf))
3468 return MEMCACHED_FAILURE;
3469
3470 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3471
3472 return rc;
3473 }
3474
3475 static memcached_return pre_nodelay(memcached_st *memc)
3476 {
3477 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3478 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3479
3480 return MEMCACHED_SUCCESS;
3481 }
3482
3483 static memcached_return pre_settimer(memcached_st *memc)
3484 {
3485 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3486 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3487
3488 return MEMCACHED_SUCCESS;
3489 }
3490
3491 static memcached_return poll_timeout(memcached_st *memc)
3492 {
3493 size_t timeout;
3494
3495 timeout= 100;
3496
3497 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3498
3499 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3500
3501 assert(timeout == 100);
3502
3503 return MEMCACHED_SUCCESS;
3504 }
3505
3506 static test_return_t noreply_test(memcached_st *memc)
3507 {
3508 memcached_return ret;
3509 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3510 assert(ret == MEMCACHED_SUCCESS);
3511 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3512 assert(ret == MEMCACHED_SUCCESS);
3513 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3514 assert(ret == MEMCACHED_SUCCESS);
3515 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3516 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3517 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3518
3519 for (int count=0; count < 5; ++count)
3520 {
3521 for (int x=0; x < 100; ++x)
3522 {
3523 char key[10];
3524 size_t len= (size_t)sprintf(key, "%d", x);
3525 switch (count)
3526 {
3527 case 0:
3528 ret=memcached_add(memc, key, len, key, len, 0, 0);
3529 break;
3530 case 1:
3531 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3532 break;
3533 case 2:
3534 ret=memcached_set(memc, key, len, key, len, 0, 0);
3535 break;
3536 case 3:
3537 ret=memcached_append(memc, key, len, key, len, 0, 0);
3538 break;
3539 case 4:
3540 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3541 break;
3542 default:
3543 assert(count);
3544 break;
3545 }
3546 assert(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3547 }
3548
3549 /*
3550 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3551 ** API and is _ONLY_ done this way to verify that the library works the
3552 ** way it is supposed to do!!!!
3553 */
3554 int no_msg=0;
3555 for (uint32_t x=0; x < memc->number_of_hosts; ++x)
3556 no_msg+=(int)(memc->hosts[x].cursor_active);
3557
3558 assert(no_msg == 0);
3559 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3560
3561 /*
3562 ** Now validate that all items was set properly!
3563 */
3564 for (int x=0; x < 100; ++x)
3565 {
3566 char key[10];
3567 size_t len= (size_t)sprintf(key, "%d", x);
3568 size_t length;
3569 uint32_t flags;
3570 char* value=memcached_get(memc, key, strlen(key),
3571 &length, &flags, &ret);
3572 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3573 switch (count)
3574 {
3575 case 0: /* FALLTHROUGH */
3576 case 1: /* FALLTHROUGH */
3577 case 2:
3578 assert(strncmp(value, key, len) == 0);
3579 assert(len == length);
3580 break;
3581 case 3:
3582 assert(length == len * 2);
3583 break;
3584 case 4:
3585 assert(length == len * 3);
3586 break;
3587 default:
3588 assert(count);
3589 break;
3590 }
3591 free(value);
3592 }
3593 }
3594
3595 /* Try setting an illegal cas value (should not return an error to
3596 * the caller (because we don't expect a return message from the server)
3597 */
3598 const char* keys[]= {"0"};
3599 size_t lengths[]= {1};
3600 size_t length;
3601 uint32_t flags;
3602 memcached_result_st results_obj;
3603 memcached_result_st *results;
3604 ret= memcached_mget(memc, keys, lengths, 1);
3605 assert(ret == MEMCACHED_SUCCESS);
3606
3607 results= memcached_result_create(memc, &results_obj);
3608 assert(results);
3609 results= memcached_fetch_result(memc, &results_obj, &ret);
3610 assert(results);
3611 assert(ret == MEMCACHED_SUCCESS);
3612 uint64_t cas= memcached_result_cas(results);
3613 memcached_result_free(&results_obj);
3614
3615 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3616 assert(ret == MEMCACHED_SUCCESS);
3617
3618 /*
3619 * The item will have a new cas value, so try to set it again with the old
3620 * value. This should fail!
3621 */
3622 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3623 assert(ret == MEMCACHED_SUCCESS);
3624 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3625 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3626 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3627 free(value);
3628
3629 return TEST_SUCCESS;
3630 }
3631
3632 static test_return_t analyzer_test(memcached_st *memc)
3633 {
3634 memcached_return rc;
3635 memcached_stat_st *memc_stat;
3636 memcached_analysis_st *report;
3637
3638 memc_stat= memcached_stat(memc, NULL, &rc);
3639 assert(rc == MEMCACHED_SUCCESS);
3640 assert(memc_stat);
3641
3642 report= memcached_analyze(memc, memc_stat, &rc);
3643 assert(rc == MEMCACHED_SUCCESS);
3644 assert(report);
3645
3646 free(report);
3647 memcached_stat_free(NULL, memc_stat);
3648
3649 return TEST_SUCCESS;
3650 }
3651
3652 /* Count the objects */
3653 static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),
3654 const char *key __attribute__((unused)),
3655 size_t key_length __attribute__((unused)),
3656 void *context)
3657 {
3658 uint32_t *counter= (uint32_t *)context;
3659
3660 *counter= *counter + 1;
3661
3662 return MEMCACHED_SUCCESS;
3663 }
3664
3665 static test_return_t dump_test(memcached_st *memc)
3666 {
3667 memcached_return rc;
3668 uint32_t counter= 0;
3669 memcached_dump_func callbacks[1];
3670 test_return_t main_rc;
3671
3672 callbacks[0]= &callback_dump_counter;
3673
3674 /* No support for Binary protocol yet */
3675 if (memc->flags & MEM_BINARY_PROTOCOL)
3676 return TEST_SUCCESS;
3677
3678 main_rc= set_test3(memc);
3679
3680 assert (main_rc == TEST_SUCCESS);
3681
3682 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
3683 assert(rc == MEMCACHED_SUCCESS);
3684
3685 /* We may have more then 32 if our previous flush has not completed */
3686 assert(counter >= 32);
3687
3688 return TEST_SUCCESS;
3689 }
3690
3691 #ifdef HAVE_LIBMEMCACHEDUTIL
3692 static void* connection_release(void *arg) {
3693 struct {
3694 memcached_pool_st* pool;
3695 memcached_st* mmc;
3696 } *resource= arg;
3697
3698 usleep(250);
3699 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
3700 return arg;
3701 }
3702
3703 static test_return_t connection_pool_test(memcached_st *memc)
3704 {
3705 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
3706 assert(pool != NULL);
3707 memcached_st* mmc[10];
3708 memcached_return rc;
3709
3710 for (int x= 0; x < 10; ++x) {
3711 mmc[x]= memcached_pool_pop(pool, false, &rc);
3712 assert(mmc[x] != NULL);
3713 assert(rc == MEMCACHED_SUCCESS);
3714 }
3715
3716 assert(memcached_pool_pop(pool, false, &rc) == NULL);
3717 assert(rc == MEMCACHED_SUCCESS);
3718
3719 pthread_t tid;
3720 struct {
3721 memcached_pool_st* pool;
3722 memcached_st* mmc;
3723 } item= { .pool = pool, .mmc = mmc[9] };
3724 pthread_create(&tid, NULL, connection_release, &item);
3725 mmc[9]= memcached_pool_pop(pool, true, &rc);
3726 assert(rc == MEMCACHED_SUCCESS);
3727 pthread_join(tid, NULL);
3728 assert(mmc[9] == item.mmc);
3729 const char *key= "key";
3730 size_t keylen= strlen(key);
3731
3732 // verify that I can do ops with all connections
3733 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
3734 assert(rc == MEMCACHED_SUCCESS);
3735
3736 for (unsigned int x= 0; x < 10; ++x) {
3737 uint64_t number_value;
3738 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
3739 assert(rc == MEMCACHED_SUCCESS);
3740 assert(number_value == (x+1));
3741 }
3742
3743 // Release them..
3744 for (int x= 0; x < 10; ++x)
3745 assert(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
3746
3747
3748 /* verify that I can set behaviors on the pool when I don't have all
3749 * of the connections in the pool. It should however be enabled
3750 * when I push the item into the pool
3751 */
3752 mmc[0]= memcached_pool_pop(pool, false, &rc);
3753 assert(mmc[0] != NULL);
3754
3755 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
3756 assert(rc == MEMCACHED_SUCCESS);
3757
3758 mmc[1]= memcached_pool_pop(pool, false, &rc);
3759 assert(mmc[1] != NULL);
3760
3761 assert(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3762 assert(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
3763 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3764
3765 mmc[0]= memcached_pool_pop(pool, false, &rc);
3766 assert(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3767 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3768
3769
3770 assert(memcached_pool_destroy(pool) == memc);
3771 return TEST_SUCCESS;
3772 }
3773 #endif
3774
3775 static test_return_t replication_set_test(memcached_st *memc)
3776 {
3777 memcached_return rc;
3778 memcached_st *memc_clone= memcached_clone(NULL, memc);
3779 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3780
3781 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
3782 assert(rc == MEMCACHED_SUCCESS);
3783
3784 /*
3785 ** We are using the quiet commands to store the replicas, so we need
3786 ** to ensure that all of them are processed before we can continue.
3787 ** In the test we go directly from storing the object to trying to
3788 ** receive the object from all of the different servers, so we
3789 ** could end up in a race condition (the memcached server hasn't yet
3790 ** processed the quiet command from the replication set when it process
3791 ** the request from the other client (created by the clone)). As a
3792 ** workaround for that we call memcached_quit to send the quit command
3793 ** to the server and wait for the response ;-) If you use the test code
3794 ** as an example for your own code, please note that you shouldn't need
3795 ** to do this ;-)
3796 */
3797 memcached_quit(memc);
3798
3799 /*
3800 ** "bubba" should now be stored on all of our servers. We don't have an
3801 ** easy to use API to address each individual server, so I'll just iterate
3802 ** through a bunch of "master keys" and I should most likely hit all of the
3803 ** servers...
3804 */
3805 for (int x= 'a'; x <= 'z'; ++x)
3806 {
3807 char key[2]= { [0]= (char)x };
3808 size_t len;
3809 uint32_t flags;
3810 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
3811 &len, &flags, &rc);
3812 assert(rc == MEMCACHED_SUCCESS);
3813 assert(val != NULL);
3814 free(val);
3815 }
3816
3817 memcached_free(memc_clone);
3818
3819 return TEST_SUCCESS;
3820 }
3821
3822 static test_return_t replication_get_test(memcached_st *memc)
3823 {
3824 memcached_return rc;
3825
3826 /*
3827 * Don't do the following in your code. I am abusing the internal details
3828 * within the library, and this is not a supported interface.
3829 * This is to verify correct behavior in the library
3830 */
3831 for (uint32_t host= 0; host < memc->number_of_hosts; ++host)
3832 {
3833 memcached_st *memc_clone= memcached_clone(NULL, memc);
3834 memc_clone->hosts[host].port= 0;
3835
3836 for (int x= 'a'; x <= 'z'; ++x)
3837 {
3838 char key[2]= { [0]= (char)x };
3839 size_t len;
3840 uint32_t flags;
3841 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
3842 &len, &flags, &rc);
3843 assert(rc == MEMCACHED_SUCCESS);
3844 assert(val != NULL);
3845 free(val);
3846 }
3847
3848 memcached_free(memc_clone);
3849 }
3850
3851 return TEST_SUCCESS;
3852 }
3853
3854 static test_return_t replication_mget_test(memcached_st *memc)
3855 {
3856 memcached_return rc;
3857 memcached_st *memc_clone= memcached_clone(NULL, memc);
3858 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3859
3860 const char *keys[]= { "bubba", "key1", "key2", "key3" };
3861 size_t len[]= { 5, 4, 4, 4 };
3862
3863 for (int x=0; x< 4; ++x)
3864 {
3865 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
3866 assert(rc == MEMCACHED_SUCCESS);
3867 }
3868
3869 /*
3870 ** We are using the quiet commands to store the replicas, so we need
3871 ** to ensure that all of them are processed before we can continue.
3872 ** In the test we go directly from storing the object to trying to
3873 ** receive the object from all of the different servers, so we
3874 ** could end up in a race condition (the memcached server hasn't yet
3875 ** processed the quiet command from the replication set when it process
3876 ** the request from the other client (created by the clone)). As a
3877 ** workaround for that we call memcached_quit to send the quit command
3878 ** to the server and wait for the response ;-) If you use the test code
3879 ** as an example for your own code, please note that you shouldn't need
3880 ** to do this ;-)
3881 */
3882 memcached_quit(memc);
3883
3884 /*
3885 * Don't do the following in your code. I am abusing the internal details
3886 * within the library, and this is not a supported interface.
3887 * This is to verify correct behavior in the library
3888 */
3889 memcached_result_st result_obj;
3890 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
3891 {
3892 memcached_st *new_clone= memcached_clone(NULL, memc);
3893 new_clone->hosts[host].port= 0;
3894
3895 for (int x= 'a'; x <= 'z'; ++x)
3896 {
3897 const char key[2]= { [0]= (const char)x };
3898
3899 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
3900 assert(rc == MEMCACHED_SUCCESS);
3901
3902 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
3903 assert(results);
3904
3905 int hits= 0;
3906 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
3907 {
3908 hits++;
3909 }
3910 assert(hits == 4);
3911 memcached_result_free(&result_obj);
3912 }
3913
3914 memcached_free(new_clone);
3915 }
3916
3917 memcached_free(memc_clone);
3918
3919 return TEST_SUCCESS;
3920 }
3921
3922 static test_return_t replication_delete_test(memcached_st *memc)
3923 {
3924 memcached_return rc;
3925 memcached_st *memc_clone= memcached_clone(NULL, memc);
3926 /* Delete the items from all of the servers except 1 */
3927 uint64_t repl= memcached_behavior_get(memc,
3928 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
3929 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
3930
3931 const char *keys[]= { "bubba", "key1", "key2", "key3" };
3932 size_t len[]= { 5, 4, 4, 4 };
3933
3934 for (int x=0; x< 4; ++x)
3935 {
3936 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
3937 assert(rc == MEMCACHED_SUCCESS);
3938 }
3939
3940 /*
3941 * Don't do the following in your code. I am abusing the internal details
3942 * within the library, and this is not a supported interface.
3943 * This is to verify correct behavior in the library
3944 */
3945 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
3946 for (uint32_t x= 0; x < (repl + 1); ++x)
3947 {
3948 memc_clone->hosts[hash].port= 0;
3949 if (++hash == memc_clone->number_of_hosts)
3950 hash= 0;
3951 }
3952
3953 memcached_result_st result_obj;
3954 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
3955 {
3956 for (int x= 'a'; x <= 'z'; ++x)
3957 {
3958 const char key[2]= { [0]= (const char)x };
3959
3960 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
3961 assert(rc == MEMCACHED_SUCCESS);
3962
3963 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
3964 assert(results);
3965
3966 int hits= 0;
3967 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
3968 {
3969 ++hits;
3970 }
3971 assert(hits == 4);
3972 memcached_result_free(&result_obj);
3973 }
3974 }
3975 memcached_free(memc_clone);
3976
3977 return TEST_SUCCESS;
3978 }
3979
3980 static void increment_request_id(uint16_t *id)
3981 {
3982 (*id)++;
3983 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
3984 *id= 0;
3985 }
3986
3987 static uint16_t *get_udp_request_ids(memcached_st *memc)
3988 {
3989 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
3990 assert(ids != NULL);
3991 unsigned int x;
3992
3993 for (x= 0; x < memc->number_of_hosts; x++)
3994 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
3995
3996 return ids;
3997 }
3998
3999 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4000 {
4001 unsigned int x;
4002 memcached_server_st *cur_server = memc->hosts;
4003 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4004
4005 for (x= 0; x < memc->number_of_hosts; x++)
4006 {
4007 assert(cur_server[x].cursor_active == 0);
4008 assert(cur_req_ids[x] == expected_req_ids[x]);
4009 }
4010 free(expected_req_ids);
4011 free(cur_req_ids);
4012
4013 return TEST_SUCCESS;
4014 }
4015
4016 /*
4017 ** There is a little bit of a hack here, instead of removing
4018 ** the servers, I just set num host to 0 and them add then new udp servers
4019 **/
4020 static memcached_return init_udp(memcached_st *memc)
4021 {
4022 memcached_version(memc);
4023 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4024 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
4025 || memc->hosts[0].micro_version < 6)
4026 return MEMCACHED_FAILURE;
4027
4028 uint32_t num_hosts= memc->number_of_hosts;
4029 unsigned int x= 0;
4030 memcached_server_st servers[num_hosts];
4031 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
4032 for (x= 0; x < num_hosts; x++)
4033 memcached_server_free(&memc->hosts[x]);
4034
4035 memc->number_of_hosts= 0;
4036 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4037 for (x= 0; x < num_hosts; x++)
4038 {
4039 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4040 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4041 }
4042
4043 return MEMCACHED_SUCCESS;
4044 }
4045
4046 static memcached_return binary_init_udp(memcached_st *memc)
4047 {
4048 pre_binary(memc);
4049 return init_udp(memc);
4050 }
4051
4052 /* Make sure that I cant add a tcp server to a udp client */
4053 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4054 {
4055 memcached_server_st server;
4056 memcached_server_clone(&server, &memc->hosts[0]);
4057 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4058 assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4059 return TEST_SUCCESS;
4060 }
4061
4062 /* Make sure that I cant add a udp server to a tcp client */
4063 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4064 {
4065 memcached_server_st server;
4066 memcached_server_clone(&server, &memc->hosts[0]);
4067 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4068
4069 memcached_st tcp_client;
4070 memcached_create(&tcp_client);
4071 assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4072 return TEST_SUCCESS;
4073 }
4074
4075 static test_return_t set_udp_behavior_test(memcached_st *memc)
4076 {
4077
4078 memcached_quit(memc);
4079 memc->number_of_hosts= 0;
4080 run_distribution(memc);
4081 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4082 assert(memc->flags & MEM_USE_UDP);
4083 assert(memc->flags & MEM_NOREPLY);;
4084
4085 assert(memc->number_of_hosts == 0);
4086
4087 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4088 assert(!(memc->flags & MEM_USE_UDP));
4089 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4090 assert(!(memc->flags & MEM_NOREPLY));
4091 return TEST_SUCCESS;
4092 }
4093
4094 static test_return_t udp_set_test(memcached_st *memc)
4095 {
4096 unsigned int x= 0;
4097 unsigned int num_iters= 1025; //request id rolls over at 1024
4098 for (x= 0; x < num_iters;x++)
4099 {
4100 memcached_return rc;
4101 const char *key= "foo";
4102 const char *value= "when we sanitize";
4103 uint16_t *expected_ids= get_udp_request_ids(memc);
4104 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
4105 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4106 rc= memcached_set(memc, key, strlen(key),
4107 value, strlen(value),
4108 (time_t)0, (uint32_t)0);
4109 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4110 /** NB, the check below assumes that if new write_ptr is less than
4111 * the original write_ptr that we have flushed. For large payloads, this
4112 * maybe an invalid assumption, but for the small payload we have it is OK
4113 */
4114 if (rc == MEMCACHED_SUCCESS ||
4115 memc->hosts[server_key].write_buffer_offset < init_offset)
4116 increment_request_id(&expected_ids[server_key]);
4117
4118 if (rc == MEMCACHED_SUCCESS)
4119 {
4120 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4121 }
4122 else
4123 {
4124 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4125 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4126 }
4127 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4128 }
4129 return TEST_SUCCESS;
4130 }
4131
4132 static test_return_t udp_buffered_set_test(memcached_st *memc)
4133 {
4134 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4135 return udp_set_test(memc);
4136 }
4137
4138 static test_return_t udp_set_too_big_test(memcached_st *memc)
4139 {
4140 memcached_return rc;
4141 const char *key= "bar";
4142 char value[MAX_UDP_DATAGRAM_LENGTH];
4143 uint16_t *expected_ids= get_udp_request_ids(memc);
4144 rc= memcached_set(memc, key, strlen(key),
4145 value, MAX_UDP_DATAGRAM_LENGTH,
4146 (time_t)0, (uint32_t)0);
4147 assert(rc == MEMCACHED_WRITE_FAILURE);
4148 return post_udp_op_check(memc,expected_ids);
4149 }
4150
4151 static test_return_t udp_delete_test(memcached_st *memc)
4152 {
4153 unsigned int x= 0;
4154 unsigned int num_iters= 1025; //request id rolls over at 1024
4155 for (x= 0; x < num_iters;x++)
4156 {
4157 memcached_return rc;
4158 const char *key= "foo";
4159 uint16_t *expected_ids=get_udp_request_ids(memc);
4160 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4161 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4162 rc= memcached_delete(memc, key, strlen(key), 0);
4163 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4164 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
4165 increment_request_id(&expected_ids[server_key]);
4166 if (rc == MEMCACHED_SUCCESS)
4167 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4168 else
4169 {
4170 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4171 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4172 }
4173 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4174 }
4175 return TEST_SUCCESS;
4176 }
4177
4178 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4179 {
4180 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4181 return udp_delete_test(memc);
4182 }
4183
4184 static test_return_t udp_verbosity_test(memcached_st *memc)
4185 {
4186 memcached_return rc;
4187 uint16_t *expected_ids= get_udp_request_ids(memc);
4188 unsigned int x;
4189 for (x= 0; x < memc->number_of_hosts;x++)
4190 increment_request_id(&expected_ids[x]);
4191
4192 rc= memcached_verbosity(memc,3);
4193 assert(rc == MEMCACHED_SUCCESS);
4194 return post_udp_op_check(memc,expected_ids);
4195 }
4196
4197 static test_return_t udp_quit_test(memcached_st *memc)
4198 {
4199 uint16_t *expected_ids= get_udp_request_ids(memc);
4200 memcached_quit(memc);
4201 return post_udp_op_check(memc, expected_ids);
4202 }
4203
4204 static test_return_t udp_flush_test(memcached_st *memc)
4205 {
4206 memcached_return rc;
4207 uint16_t *expected_ids= get_udp_request_ids(memc);
4208 unsigned int x;
4209 for (x= 0; x < memc->number_of_hosts;x++)
4210 increment_request_id(&expected_ids[x]);
4211
4212 rc= memcached_flush(memc,0);
4213 assert(rc == MEMCACHED_SUCCESS);
4214 return post_udp_op_check(memc,expected_ids);
4215 }
4216
4217 static test_return_t udp_incr_test(memcached_st *memc)
4218 {
4219 memcached_return rc;
4220 const char *key= "incr";
4221 const char *value= "1";
4222 rc= memcached_set(memc, key, strlen(key),
4223 value, strlen(value),
4224 (time_t)0, (uint32_t)0);
4225
4226 assert(rc == MEMCACHED_SUCCESS);
4227 uint16_t *expected_ids= get_udp_request_ids(memc);
4228 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4229 increment_request_id(&expected_ids[server_key]);
4230 uint64_t newvalue;
4231 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4232 assert(rc == MEMCACHED_SUCCESS);
4233 return post_udp_op_check(memc, expected_ids);
4234 }
4235
4236 static test_return_t udp_decr_test(memcached_st *memc)
4237 {
4238 memcached_return rc;
4239 const char *key= "decr";
4240 const char *value= "1";
4241 rc= memcached_set(memc, key, strlen(key),
4242 value, strlen(value),
4243 (time_t)0, (uint32_t)0);
4244
4245 assert(rc == MEMCACHED_SUCCESS);
4246 uint16_t *expected_ids= get_udp_request_ids(memc);
4247 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4248 increment_request_id(&expected_ids[server_key]);
4249 uint64_t newvalue;
4250 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4251 assert(rc == MEMCACHED_SUCCESS);
4252 return post_udp_op_check(memc, expected_ids);
4253 }
4254
4255
4256 static test_return_t udp_stat_test(memcached_st *memc)
4257 {
4258 memcached_stat_st * rv= NULL;
4259 memcached_return rc;
4260 char args[]= "";
4261 uint16_t *expected_ids = get_udp_request_ids(memc);
4262 rv = memcached_stat(memc, args, &rc);
4263 free(rv);
4264 assert(rc == MEMCACHED_NOT_SUPPORTED);
4265 return post_udp_op_check(memc, expected_ids);
4266 }
4267
4268 static test_return_t udp_version_test(memcached_st *memc)
4269 {
4270 memcached_return rc;
4271 uint16_t *expected_ids = get_udp_request_ids(memc);
4272 rc = memcached_version(memc);
4273 assert(rc == MEMCACHED_NOT_SUPPORTED);
4274 return post_udp_op_check(memc, expected_ids);
4275 }
4276
4277 static test_return_t udp_get_test(memcached_st *memc)
4278 {
4279 memcached_return rc;
4280 const char *key= "foo";
4281 size_t vlen;
4282 uint16_t *expected_ids = get_udp_request_ids(memc);
4283 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4284 assert(rc == MEMCACHED_NOT_SUPPORTED);
4285 assert(val == NULL);
4286 return post_udp_op_check(memc, expected_ids);
4287 }
4288
4289 static test_return_t udp_mixed_io_test(memcached_st *memc)
4290 {
4291 test_st current_op;
4292 test_st mixed_io_ops [] ={
4293 {"udp_set_test", 0, udp_set_test},
4294 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4295 {"udp_delete_test", 0, udp_delete_test},
4296 {"udp_verbosity_test", 0, udp_verbosity_test},
4297 {"udp_quit_test", 0, udp_quit_test},
4298 {"udp_flush_test", 0, udp_flush_test},
4299 {"udp_incr_test", 0, udp_incr_test},
4300 {"udp_decr_test", 0, udp_decr_test},
4301 {"udp_version_test", 0, udp_version_test}
4302 };
4303 unsigned int x= 0;
4304 for (x= 0; x < 500; x++)
4305 {
4306 current_op= mixed_io_ops[random() % 9];
4307 assert(current_op.function(memc) == TEST_SUCCESS);
4308 }
4309 return TEST_SUCCESS;
4310 }
4311
4312 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4313 {
4314 memcached_return expected_rc= MEMCACHED_FAILURE;
4315 #ifdef HAVE_HSIEH_HASH
4316 expected_rc= MEMCACHED_SUCCESS;
4317 #endif
4318 memcached_return rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4319 (uint64_t)MEMCACHED_HASH_HSIEH);
4320 assert(rc == expected_rc);
4321 return TEST_SUCCESS;
4322 }
4323
4324 static const char *list[]=
4325 {
4326 "apple",
4327 "beat",
4328 "carrot",
4329 "daikon",
4330 "eggplant",
4331 "flower",
4332 "green",
4333 "hide",
4334 "ick",
4335 "jack",
4336 "kick",
4337 "lime",
4338 "mushrooms",
4339 "nectarine",
4340 "orange",
4341 "peach",
4342 "quant",
4343 "ripen",
4344 "strawberry",
4345 "tang",
4346 "up",
4347 "volumne",
4348 "when",
4349 "yellow",
4350 "zip",
4351 NULL
4352 };
4353
4354 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4355 {
4356 uint32_t x;
4357 const char **ptr;
4358 uint32_t values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
4359 245758794U, 2550894432U, 121710495U, 3053817768U,
4360 1250994555U, 1862072655U, 2631955953U, 2951528551U,
4361 1451250070U, 2820856945U, 2060845566U, 3646985608U,
4362 2138080750U, 217675895U, 2230934345U, 1234361223U,
4363 3968582726U, 2455685270U, 1293568479U, 199067604U,
4364 2042482093U };
4365
4366
4367 for (ptr= list, x= 0; *ptr; ptr++, x++)
4368 {
4369 uint32_t hash_val;
4370
4371 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4372 assert(values[x] == hash_val);
4373 }
4374
4375 return TEST_SUCCESS;
4376 }
4377
4378 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4379 {
4380 uint32_t x;
4381 const char **ptr;
4382 uint32_t values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
4383 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
4384 7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
4385 17300U, 28156U, 9192U, 20484U, 16925U };
4386
4387 for (ptr= list, x= 0; *ptr; ptr++, x++)
4388 {
4389 uint32_t hash_val;
4390
4391 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4392 assert(values[x] == hash_val);
4393 }
4394
4395 return TEST_SUCCESS;
4396 }
4397
4398 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4399 {
4400 uint32_t x;
4401 const char **ptr;
4402 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4403 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4404 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4405 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4406 2815549194U, 2562818319U, 224996066U, 2680194749U,
4407 3035305390U, 246890365U, 2395624193U, 4145193337U,
4408 1801941682U };
4409
4410 for (ptr= list, x= 0; *ptr; ptr++, x++)
4411 {
4412 uint32_t hash_val;
4413
4414 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4415 assert(values[x] == hash_val);
4416 }
4417
4418 return TEST_SUCCESS;
4419 }
4420
4421 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4422 {
4423 uint32_t x;
4424 const char **ptr;
4425 uint32_t values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
4426 3647689787U, 3241528582U, 1669328060U, 2604311949U,
4427 734810122U, 1516407546U, 560948863U, 1767346780U,
4428 561034892U, 4156330026U, 3716417003U, 3475297030U,
4429 1518272172U, 227211583U, 3938128828U, 126112909U,
4430 3043416448U, 3131561933U, 1328739897U, 2455664041U,
4431 2272238452U };
4432
4433 for (ptr= list, x= 0; *ptr; ptr++, x++)
4434 {
4435 uint32_t hash_val;
4436
4437 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4438 assert(values[x] == hash_val);
4439 }
4440
4441 return TEST_SUCCESS;
4442 }
4443
4444 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4445 {
4446 uint32_t x;
4447 const char **ptr;
4448 uint32_t values[]= { 67176023U, 1190179409U, 2043204404U, 3221866419U,
4449 2567703427U, 3787535528U, 4147287986U, 3500475733U,
4450 344481048U, 3865235296U, 2181839183U, 119581266U,
4451 510234242U, 4248244304U, 1362796839U, 103389328U,
4452 1449620010U, 182962511U, 3554262370U, 3206747549U,
4453 1551306158U, 4127558461U, 1889140833U, 2774173721U,
4454 1180552018U };
4455
4456
4457 for (ptr= list, x= 0; *ptr; ptr++, x++)
4458 {
4459 uint32_t hash_val;
4460
4461 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4462 assert(values[x] == hash_val);
4463 }
4464
4465 return TEST_SUCCESS;
4466 }
4467
4468 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4469 {
4470 uint32_t x;
4471 const char **ptr;
4472 uint32_t values[]= { 280767167U, 2421315013U, 3072375666U, 855001899U,
4473 459261019U, 3521085446U, 18738364U, 1625305005U,
4474 2162232970U, 777243802U, 3323728671U, 132336572U,
4475 3654473228U, 260679466U, 1169454059U, 2698319462U,
4476 1062177260U, 235516991U, 2218399068U, 405302637U,
4477 1128467232U, 3579622413U, 2138539289U, 96429129U,
4478 2877453236U };
4479
4480 for (ptr= list, x= 0; *ptr; ptr++, x++)
4481 {
4482 uint32_t hash_val;
4483
4484 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4485 assert(values[x] == hash_val);
4486 }
4487
4488 return TEST_SUCCESS;
4489 }
4490
4491 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4492 {
4493 uint32_t x;
4494 const char **ptr;
4495 #ifdef HAVE_HSIEH_HASH
4496 uint32_t values[]= { 3738850110, 3636226060, 3821074029, 3489929160, 3485772682, 80540287,
4497 1805464076, 1895033657, 409795758, 979934958, 3634096985, 1284445480,
4498 2265380744, 707972988, 353823508, 1549198350, 1327930172, 9304163,
4499 4220749037, 2493964934, 2777873870, 2057831732, 1510213931, 2027828987,
4500 3395453351 };
4501 #else
4502 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 };
4503 #endif
4504
4505 for (ptr= list, x= 0; *ptr; ptr++, x++)
4506 {
4507 uint32_t hash_val;
4508
4509 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4510 assert(values[x] == hash_val);
4511 }
4512
4513 return TEST_SUCCESS;
4514 }
4515
4516 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4517 {
4518 uint32_t x;
4519 const char **ptr;
4520 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4521 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4522 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4523 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4524 2815549194U, 2562818319U, 224996066U, 2680194749U,
4525 3035305390U, 246890365U, 2395624193U, 4145193337U,
4526 1801941682U };
4527
4528 for (ptr= list, x= 0; *ptr; ptr++, x++)
4529 {
4530 uint32_t hash_val;
4531
4532 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4533 assert(values[x] == hash_val);
4534 }
4535
4536 return TEST_SUCCESS;
4537 }
4538
4539 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4540 {
4541 uint32_t x;
4542 const char **ptr;
4543 uint32_t values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U,
4544 3261968576U, 3515188778U, 4232909173U, 4288625128U,
4545 1812047395U, 3689182164U, 2502979932U, 1214050606U,
4546 2415988847U, 1494268927U, 1025545760U, 3920481083U,
4547 4153263658U, 3824871822U, 3072759809U, 798622255U,
4548 3065432577U, 1453328165U, 2691550971U, 3408888387U,
4549 2629893356U };
4550
4551
4552 for (ptr= list, x= 0; *ptr; ptr++, x++)
4553 {
4554 uint32_t hash_val;
4555
4556 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4557 assert(values[x] == hash_val);
4558 }
4559
4560 return TEST_SUCCESS;
4561 }
4562
4563 static test_return_t regression_bug_434484(memcached_st *memc)
4564 {
4565 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4566 return TEST_SKIPPED;
4567
4568 memcached_return ret;
4569 const char *key= "regression_bug_434484";
4570 size_t keylen= strlen(key);
4571
4572 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
4573 assert(ret == MEMCACHED_NOTSTORED);
4574
4575 size_t size= 2048 * 1024;
4576 void *data= calloc(1, size);
4577 assert(data != NULL);
4578 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
4579 assert(ret == MEMCACHED_E2BIG);
4580 free(data);
4581
4582 return TEST_SUCCESS;
4583 }
4584
4585 static test_return_t regression_bug_434843(memcached_st *memc)
4586 {
4587 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4588 return TEST_SKIPPED;
4589
4590 memcached_return rc;
4591 unsigned int counter= 0;
4592 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
4593
4594 /*
4595 * I only want to hit only _one_ server so I know the number of requests I'm
4596 * sending in the pipleine to the server. Let's try to do a multiget of
4597 * 10240 (that should satisfy most users don't you tink?)
4598 */
4599 uint32_t number_of_hosts= memc->number_of_hosts;
4600 memc->number_of_hosts= 1;
4601 const size_t max_keys= 10240;
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
4736
4737 /* Test memcached_server_get_last_disconnect
4738 * For a working server set, shall be NULL
4739 * For a set of non existing server, shall not be NULL
4740 */
4741 static test_return_t test_get_last_disconnect(memcached_st *memc)
4742 {
4743 memcached_return rc;
4744 memcached_server_st *disconnected_server;
4745
4746 /* With the working set of server */
4747 const char *key= "marmotte";
4748 const char *value= "milka";
4749
4750 rc= memcached_set(memc, key, strlen(key),
4751 value, strlen(value),
4752 (time_t)0, (uint32_t)0);
4753 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4754
4755 disconnected_server = memcached_server_get_last_disconnect(memc);
4756 assert(disconnected_server == NULL);
4757
4758 /* With a non existing server */
4759 memcached_st *mine;
4760 memcached_server_st *servers;
4761
4762 const char *server_list= "localhost:9";
4763
4764 servers= memcached_servers_parse(server_list);
4765 assert(servers);
4766 mine= memcached_create(NULL);
4767 rc= memcached_server_push(mine, servers);
4768 assert(rc == MEMCACHED_SUCCESS);
4769 memcached_server_list_free(servers);
4770 assert(mine);
4771
4772 rc= memcached_set(mine, key, strlen(key),
4773 value, strlen(value),
4774 (time_t)0, (uint32_t)0);
4775 assert(rc != MEMCACHED_SUCCESS);
4776
4777 disconnected_server = memcached_server_get_last_disconnect(mine);
4778 assert(disconnected_server != NULL);
4779 assert(disconnected_server->port == 9);
4780 assert(strncmp(disconnected_server->hostname,"localhost",9) == 0);
4781
4782 memcached_quit(mine);
4783 memcached_free(mine);
4784
4785 return TEST_SUCCESS;
4786 }
4787
4788
4789 test_st udp_setup_server_tests[] ={
4790 {"set_udp_behavior_test", 0, set_udp_behavior_test},
4791 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
4792 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
4793 {0, 0, 0}
4794 };
4795
4796 test_st upd_io_tests[] ={
4797 {"udp_set_test", 0, udp_set_test},
4798 {"udp_buffered_set_test", 0, udp_buffered_set_test},
4799 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4800 {"udp_delete_test", 0, udp_delete_test},
4801 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
4802 {"udp_verbosity_test", 0, udp_verbosity_test},
4803 {"udp_quit_test", 0, udp_quit_test},
4804 {"udp_flush_test", 0, udp_flush_test},
4805 {"udp_incr_test", 0, udp_incr_test},
4806 {"udp_decr_test", 0, udp_decr_test},
4807 {"udp_stat_test", 0, udp_stat_test},
4808 {"udp_version_test", 0, udp_version_test},
4809 {"udp_get_test", 0, udp_get_test},
4810 {"udp_mixed_io_test", 0, udp_mixed_io_test},
4811 {0, 0, 0}
4812 };
4813
4814 /* Clean the server before beginning testing */
4815 test_st tests[] ={
4816 {"flush", 0, flush_test },
4817 {"init", 0, init_test },
4818 {"allocation", 0, allocation_test },
4819 {"server_list_null_test", 0, server_list_null_test},
4820 {"server_unsort", 0, server_unsort_test},
4821 {"server_sort", 0, server_sort_test},
4822 {"server_sort2", 0, server_sort2_test},
4823 {"clone_test", 0, clone_test },
4824 {"connection_test", 0, connection_test},
4825 {"callback_test", 0, callback_test},
4826 {"behavior_test", 0, behavior_test},
4827 {"userdata_test", 0, userdata_test},
4828 {"error", 0, error_test },
4829 {"set", 0, set_test },
4830 {"set2", 0, set_test2 },
4831 {"set3", 0, set_test3 },
4832 {"dump", 1, dump_test},
4833 {"add", 1, add_test },
4834 {"replace", 1, replace_test },
4835 {"delete", 1, delete_test },
4836 {"get", 1, get_test },
4837 {"get2", 0, get_test2 },
4838 {"get3", 0, get_test3 },
4839 {"get4", 0, get_test4 },
4840 {"partial mget", 0, get_test5 },
4841 {"stats_servername", 0, stats_servername_test },
4842 {"increment", 0, increment_test },
4843 {"increment_with_initial", 1, increment_with_initial_test },
4844 {"decrement", 0, decrement_test },
4845 {"decrement_with_initial", 1, decrement_with_initial_test },
4846 {"quit", 0, quit_test },
4847 {"mget", 1, mget_test },
4848 {"mget_result", 1, mget_result_test },
4849 {"mget_result_alloc", 1, mget_result_alloc_test },
4850 {"mget_result_function", 1, mget_result_function },
4851 {"mget_end", 0, mget_end },
4852 {"get_stats", 0, get_stats },
4853 {"add_host_test", 0, add_host_test },
4854 {"add_host_test_1", 0, add_host_test1 },
4855 {"get_stats_keys", 0, get_stats_keys },
4856 {"behavior_test", 0, get_stats_keys },
4857 {"callback_test", 0, get_stats_keys },
4858 {"version_string_test", 0, version_string_test},
4859 {"bad_key", 1, bad_key_test },
4860 {"memcached_server_cursor", 1, memcached_server_cursor_test },
4861 {"read_through", 1, read_through },
4862 {"delete_through", 1, delete_through },
4863 {"noreply", 1, noreply_test},
4864 {"analyzer", 1, analyzer_test},
4865 #ifdef HAVE_LIBMEMCACHEDUTIL
4866 {"connectionpool", 1, connection_pool_test },
4867 #endif
4868 {"test_get_last_disconnect", 1, test_get_last_disconnect},
4869 {0, 0, 0}
4870 };
4871
4872 test_st async_tests[] ={
4873 {"add", 1, add_wrapper },
4874 {0, 0, 0}
4875 };
4876
4877 test_st string_tests[] ={
4878 {"string static with null", 0, string_static_null },
4879 {"string alloc with null", 0, string_alloc_null },
4880 {"string alloc with 1K", 0, string_alloc_with_size },
4881 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
4882 {"string append", 0, string_alloc_append },
4883 {"string append failure (too big)", 0, string_alloc_append_toobig },
4884 {0, 0, 0}
4885 };
4886
4887 test_st result_tests[] ={
4888 {"result static", 0, result_static},
4889 {"result alloc", 0, result_alloc},
4890 {0, 0, 0}
4891 };
4892
4893 test_st version_1_2_3[] ={
4894 {"append", 0, append_test },
4895 {"prepend", 0, prepend_test },
4896 {"cas", 0, cas_test },
4897 {"cas2", 0, cas2_test },
4898 {"append_binary", 0, append_binary_test },
4899 {0, 0, 0}
4900 };
4901
4902 test_st user_tests[] ={
4903 {"user_supplied_bug1", 0, user_supplied_bug1 },
4904 {"user_supplied_bug2", 0, user_supplied_bug2 },
4905 {"user_supplied_bug3", 0, user_supplied_bug3 },
4906 {"user_supplied_bug4", 0, user_supplied_bug4 },
4907 {"user_supplied_bug5", 1, user_supplied_bug5 },
4908 {"user_supplied_bug6", 1, user_supplied_bug6 },
4909 {"user_supplied_bug7", 1, user_supplied_bug7 },
4910 {"user_supplied_bug8", 1, user_supplied_bug8 },
4911 {"user_supplied_bug9", 1, user_supplied_bug9 },
4912 {"user_supplied_bug10", 1, user_supplied_bug10 },
4913 {"user_supplied_bug11", 1, user_supplied_bug11 },
4914 {"user_supplied_bug12", 1, user_supplied_bug12 },
4915 {"user_supplied_bug13", 1, user_supplied_bug13 },
4916 {"user_supplied_bug14", 1, user_supplied_bug14 },
4917 {"user_supplied_bug15", 1, user_supplied_bug15 },
4918 {"user_supplied_bug16", 1, user_supplied_bug16 },
4919 #ifndef __sun
4920 /*
4921 ** It seems to be something weird with the character sets..
4922 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
4923 ** guess I need to find out how this is supposed to work.. Perhaps I need
4924 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
4925 ** so just disable the code for now...).
4926 */
4927 {"user_supplied_bug17", 1, user_supplied_bug17 },
4928 #endif
4929 {"user_supplied_bug18", 1, user_supplied_bug18 },
4930 {"user_supplied_bug19", 1, user_supplied_bug19 },
4931 {"user_supplied_bug20", 1, user_supplied_bug20 },
4932 {"user_supplied_bug21", 1, user_supplied_bug21 },
4933 {0, 0, 0}
4934 };
4935
4936 test_st replication_tests[]= {
4937 {"set", 1, replication_set_test },
4938 {"get", 0, replication_get_test },
4939 {"mget", 0, replication_mget_test },
4940 {"delete", 0, replication_delete_test },
4941 {0, 0, 0}
4942 };
4943
4944 /*
4945 * The following test suite is used to verify that we don't introduce
4946 * regression bugs. If you want more information about the bug / test,
4947 * you should look in the bug report at
4948 * http://bugs.launchpad.net/libmemcached
4949 */
4950 test_st regression_tests[]= {
4951 {"lp:434484", 1, regression_bug_434484 },
4952 {"lp:434843", 1, regression_bug_434843 },
4953 {"lp:434843 buffered", 1, regression_bug_434843_buffered },
4954 {"lp:421108", 1, regression_bug_421108 },
4955 {"lp:442914", 1, regression_bug_442914 },
4956 {0, 0, 0}
4957 };
4958
4959 test_st generate_tests[] ={
4960 {"generate_pairs", 1, generate_pairs },
4961 {"generate_data", 1, generate_data },
4962 {"get_read", 0, get_read },
4963 {"delete_generate", 0, delete_generate },
4964 {"generate_buffer_data", 1, generate_buffer_data },
4965 {"delete_buffer", 0, delete_buffer_generate},
4966 {"generate_data", 1, generate_data },
4967 {"mget_read", 0, mget_read },
4968 {"mget_read_result", 0, mget_read_result },
4969 {"mget_read_function", 0, mget_read_function },
4970 {"cleanup", 1, cleanup_pairs },
4971 {"generate_large_pairs", 1, generate_large_pairs },
4972 {"generate_data", 1, generate_data },
4973 {"generate_buffer_data", 1, generate_buffer_data },
4974 {"cleanup", 1, cleanup_pairs },
4975 {0, 0, 0}
4976 };
4977
4978 test_st consistent_tests[] ={
4979 {"generate_pairs", 1, generate_pairs },
4980 {"generate_data", 1, generate_data },
4981 {"get_read", 0, get_read_count },
4982 {"cleanup", 1, cleanup_pairs },
4983 {0, 0, 0}
4984 };
4985
4986 test_st consistent_weighted_tests[] ={
4987 {"generate_pairs", 1, generate_pairs },
4988 {"generate_data", 1, generate_data_with_stats },
4989 {"get_read", 0, get_read_count },
4990 {"cleanup", 1, cleanup_pairs },
4991 {0, 0, 0}
4992 };
4993
4994 test_st hsieh_availability[] ={
4995 {"hsieh_avaibility_test",0,hsieh_avaibility_test},
4996 {0, 0, 0}
4997 };
4998
4999 test_st ketama_auto_eject_hosts[] ={
5000 {"auto_eject_hosts", 1, auto_eject_hosts },
5001 {0, 0, 0}
5002 };
5003
5004 test_st hash_tests[] ={
5005 {"md5", 0, md5_run },
5006 {"crc", 0, crc_run },
5007 {"fnv1_64", 0, fnv1_64_run },
5008 {"fnv1a_64", 0, fnv1a_64_run },
5009 {"fnv1_32", 0, fnv1_32_run },
5010 {"fnv1a_32", 0, fnv1a_32_run },
5011 {"hsieh", 0, hsieh_run },
5012 {"murmur", 0, murmur_run },
5013 {"jenkis", 0, jenkins_run },
5014 {0, 0, 0}
5015 };
5016
5017 collection_st collection[] ={
5018 {"hsieh_availability",0,0,hsieh_availability},
5019 {"udp_setup", init_udp, 0, udp_setup_server_tests},
5020 {"udp_io", init_udp, 0, upd_io_tests},
5021 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
5022 {"block", 0, 0, tests},
5023 {"binary", pre_binary, 0, tests},
5024 {"nonblock", pre_nonblock, 0, tests},
5025 {"nodelay", pre_nodelay, 0, tests},
5026 {"settimer", pre_settimer, 0, tests},
5027 {"md5", pre_md5, 0, tests},
5028 {"crc", pre_crc, 0, tests},
5029 {"hsieh", pre_hsieh, 0, tests},
5030 {"jenkins", pre_jenkins, 0, tests},
5031 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
5032 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
5033 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
5034 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
5035 {"ketama", pre_behavior_ketama, 0, tests},
5036 {"ketama_auto_eject_hosts", pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5037 {"unix_socket", pre_unix_socket, 0, tests},
5038 {"unix_socket_nodelay", pre_nodelay, 0, tests},
5039 {"poll_timeout", poll_timeout, 0, tests},
5040 {"gets", enable_cas, 0, tests},
5041 {"consistent", enable_consistent, 0, tests},
5042 #ifdef MEMCACHED_ENABLE_DEPRECATED
5043 {"deprecated_memory_allocators", deprecated_set_memory_alloc, 0, tests},
5044 #endif
5045 {"memory_allocators", set_memory_alloc, 0, tests},
5046 {"prefix", set_prefix, 0, tests},
5047 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
5048 {"string", 0, 0, string_tests},
5049 {"result", 0, 0, result_tests},
5050 {"async", pre_nonblock, 0, async_tests},
5051 {"async_binary", pre_nonblock_binary, 0, async_tests},
5052 {"user", 0, 0, user_tests},
5053 {"generate", 0, 0, generate_tests},
5054 {"generate_hsieh", pre_hsieh, 0, generate_tests},
5055 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
5056 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
5057 {"generate_md5", pre_md5, 0, generate_tests},
5058 {"generate_murmur", pre_murmur, 0, generate_tests},
5059 {"generate_jenkins", pre_jenkins, 0, generate_tests},
5060 {"generate_nonblock", pre_nonblock, 0, generate_tests},
5061 {"consistent_not", 0, 0, consistent_tests},
5062 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
5063 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5064 {"test_hashes", 0, 0, hash_tests},
5065 {"replication", pre_replication, 0, replication_tests},
5066 {"replication_noblock", pre_replication_noblock, 0, replication_tests},
5067 {"regression", 0, 0, regression_tests},
5068 {0, 0, 0, 0}
5069 };
5070
5071 #define SERVERS_TO_CREATE 5
5072
5073 /* Prototypes for functions we will pass to test framework */
5074 void *world_create(void);
5075 void world_destroy(void *p);
5076
5077 void *world_create(void)
5078 {
5079 server_startup_st *construct;
5080
5081 construct= calloc(sizeof(server_startup_st), 1);
5082 construct->count= SERVERS_TO_CREATE;
5083 construct->udp= 0;
5084 server_startup(construct);
5085
5086 return construct;
5087 }
5088
5089
5090 void world_destroy(void *p)
5091 {
5092 server_startup_st *construct= (server_startup_st *)p;
5093 memcached_server_st *servers= (memcached_server_st *)construct->servers;
5094 memcached_server_list_free(servers);
5095
5096 server_shutdown(construct);
5097 free(construct);
5098 }
5099
5100 void get_world(world_st *world)
5101 {
5102 world->collections= collection;
5103 world->create= world_create;
5104 world->destroy= world_destroy;
5105 }