mget with replication didn't work if you had a cache miss
[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 mget_execute(memcached_st *memc)
1453 {
1454 bool binary= false;
1455 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1456 binary= true;
1457
1458 /*
1459 * I only want to hit _one_ server so I know the number of requests I'm
1460 * sending in the pipeline.
1461 */
1462 uint32_t number_of_hosts= memc->number_of_hosts;
1463 memc->number_of_hosts= 1;
1464
1465 int max_keys= binary ? 20480 : 1;
1466
1467
1468 char **keys= calloc((size_t)max_keys, sizeof(char*));
1469 size_t *key_length=calloc((size_t)max_keys, sizeof(size_t));
1470
1471 /* First add all of the items.. */
1472 char blob[1024] = {0};
1473 memcached_return rc;
1474 for (int x= 0; x < max_keys; ++x)
1475 {
1476 char k[251];
1477 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
1478 keys[x]= strdup(k);
1479 assert(keys[x] != NULL);
1480 rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
1481 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1482 }
1483
1484 /* Try to get all of them with a large multiget */
1485 unsigned int counter= 0;
1486 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
1487 rc= memcached_mget_execute(memc, NULL, 0,
1488 (const char**)keys, key_length,
1489 (size_t)max_keys, callbacks, &counter, 1);
1490
1491 if (binary)
1492 {
1493 assert(rc == MEMCACHED_SUCCESS);
1494
1495 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1496 assert(rc == MEMCACHED_END);
1497
1498 /* Verify that we got all of the items */
1499 assert(counter == (unsigned int)max_keys);
1500 }
1501 else
1502 {
1503 assert(rc == MEMCACHED_NOT_SUPPORTED);
1504 assert(counter == 0);
1505 }
1506
1507 /* Release all allocated resources */
1508 for (int x= 0; x < max_keys; ++x)
1509 free(keys[x]);
1510 free(keys);
1511 free(key_length);
1512
1513 memc->number_of_hosts= number_of_hosts;
1514 return TEST_SUCCESS;
1515 }
1516
1517 static test_return_t get_stats_keys(memcached_st *memc)
1518 {
1519 char **list;
1520 char **ptr;
1521 memcached_stat_st memc_stat;
1522 memcached_return rc;
1523
1524 list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1525 assert(rc == MEMCACHED_SUCCESS);
1526 for (ptr= list; *ptr; ptr++)
1527 assert(*ptr);
1528 fflush(stdout);
1529
1530 free(list);
1531
1532 return TEST_SUCCESS;
1533 }
1534
1535 static test_return_t version_string_test(memcached_st *memc __attribute__((unused)))
1536 {
1537 const char *version_string;
1538
1539 version_string= memcached_lib_version();
1540
1541 assert(!strcmp(version_string, LIBMEMCACHED_VERSION_STRING));
1542
1543 return TEST_SUCCESS;
1544 }
1545
1546 static test_return_t get_stats(memcached_st *memc)
1547 {
1548 unsigned int x;
1549 char **list;
1550 char **ptr;
1551 memcached_return rc;
1552 memcached_stat_st *memc_stat;
1553
1554 memc_stat= memcached_stat(memc, NULL, &rc);
1555 assert(rc == MEMCACHED_SUCCESS);
1556
1557 assert(rc == MEMCACHED_SUCCESS);
1558 assert(memc_stat);
1559
1560 for (x= 0; x < memcached_server_count(memc); x++)
1561 {
1562 list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1563 assert(rc == MEMCACHED_SUCCESS);
1564 for (ptr= list; *ptr; ptr++);
1565
1566 free(list);
1567 }
1568
1569 memcached_stat_free(NULL, memc_stat);
1570
1571 return TEST_SUCCESS;
1572 }
1573
1574 static test_return_t add_host_test(memcached_st *memc)
1575 {
1576 unsigned int x;
1577 memcached_server_st *servers;
1578 memcached_return rc;
1579 char servername[]= "0.example.com";
1580
1581 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1582 assert(servers);
1583 assert(1 == memcached_server_list_count(servers));
1584
1585 for (x= 2; x < 20; x++)
1586 {
1587 char buffer[SMALL_STRING_LEN];
1588
1589 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1590 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1591 &rc);
1592 assert(rc == MEMCACHED_SUCCESS);
1593 assert(x == memcached_server_list_count(servers));
1594 }
1595
1596 rc= memcached_server_push(memc, servers);
1597 assert(rc == MEMCACHED_SUCCESS);
1598 rc= memcached_server_push(memc, servers);
1599 assert(rc == MEMCACHED_SUCCESS);
1600
1601 memcached_server_list_free(servers);
1602
1603 return TEST_SUCCESS;
1604 }
1605
1606 static memcached_return clone_test_callback(memcached_st *parent __attribute__((unused)), memcached_st *memc_clone __attribute__((unused)))
1607 {
1608 return MEMCACHED_SUCCESS;
1609 }
1610
1611 static memcached_return cleanup_test_callback(memcached_st *ptr __attribute__((unused)))
1612 {
1613 return MEMCACHED_SUCCESS;
1614 }
1615
1616 static test_return_t callback_test(memcached_st *memc)
1617 {
1618 /* Test User Data */
1619 {
1620 int x= 5;
1621 int *test_ptr;
1622 memcached_return rc;
1623
1624 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
1625 assert(rc == MEMCACHED_SUCCESS);
1626 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1627 assert(*test_ptr == x);
1628 }
1629
1630 /* Test Clone Callback */
1631 {
1632 memcached_clone_func clone_cb= (memcached_clone_func)clone_test_callback;
1633 void *clone_cb_ptr= *(void **)&clone_cb;
1634 void *temp_function= NULL;
1635 memcached_return rc;
1636
1637 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1638 clone_cb_ptr);
1639 assert(rc == MEMCACHED_SUCCESS);
1640 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1641 assert(temp_function == clone_cb_ptr);
1642 }
1643
1644 /* Test Cleanup Callback */
1645 {
1646 memcached_cleanup_func cleanup_cb=
1647 (memcached_cleanup_func)cleanup_test_callback;
1648 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1649 void *temp_function= NULL;
1650 memcached_return rc;
1651
1652 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1653 cleanup_cb_ptr);
1654 assert(rc == MEMCACHED_SUCCESS);
1655 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1656 assert(temp_function == cleanup_cb_ptr);
1657 }
1658
1659 return TEST_SUCCESS;
1660 }
1661
1662 /* We don't test the behavior itself, we test the switches */
1663 static test_return_t behavior_test(memcached_st *memc)
1664 {
1665 uint64_t value;
1666 uint32_t set= 1;
1667
1668 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1669 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1670 assert(value == 1);
1671
1672 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1673 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1674 assert(value == 1);
1675
1676 set= MEMCACHED_HASH_MD5;
1677 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1678 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1679 assert(value == MEMCACHED_HASH_MD5);
1680
1681 set= 0;
1682
1683 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1684 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1685 assert(value == 0);
1686
1687 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1688 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1689 assert(value == 0);
1690
1691 set= MEMCACHED_HASH_DEFAULT;
1692 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1693 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1694 assert(value == MEMCACHED_HASH_DEFAULT);
1695
1696 set= MEMCACHED_HASH_CRC;
1697 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1698 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1699 assert(value == MEMCACHED_HASH_CRC);
1700
1701 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1702 assert(value > 0);
1703
1704 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1705 assert(value > 0);
1706
1707 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
1708 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value + 1);
1709 assert((value + 1) == memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
1710 return TEST_SUCCESS;
1711 }
1712
1713 static test_return_t fetch_all_results(memcached_st *memc)
1714 {
1715 memcached_return rc= MEMCACHED_SUCCESS;
1716 char return_key[MEMCACHED_MAX_KEY];
1717 size_t return_key_length;
1718 char *return_value;
1719 size_t return_value_length;
1720 uint32_t flags;
1721
1722 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1723 &return_value_length, &flags, &rc)))
1724 {
1725 assert(return_value);
1726 assert(rc == MEMCACHED_SUCCESS);
1727 free(return_value);
1728 }
1729
1730 return ((rc == MEMCACHED_END) || (rc == MEMCACHED_SUCCESS)) ? TEST_SUCCESS : TEST_FAILURE;
1731 }
1732
1733 /* Test case provided by Cal Haldenbrand */
1734 static test_return_t user_supplied_bug1(memcached_st *memc)
1735 {
1736 unsigned int setter= 1;
1737 unsigned int x;
1738
1739 unsigned long long total= 0;
1740 uint32_t size= 0;
1741 char key[10];
1742 char randomstuff[6 * 1024];
1743 memcached_return rc;
1744
1745 memset(randomstuff, 0, 6 * 1024);
1746
1747 /* We just keep looking at the same values over and over */
1748 srandom(10);
1749
1750 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1751 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1752
1753
1754 /* add key */
1755 for (x= 0 ; total < 20 * 1024576 ; x++ )
1756 {
1757 unsigned int j= 0;
1758
1759 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
1760 memset(randomstuff, 0, 6 * 1024);
1761 assert(size < 6 * 1024); /* Being safe here */
1762
1763 for (j= 0 ; j < size ;j++)
1764 randomstuff[j] = (signed char) ((rand() % 26) + 97);
1765
1766 total += size;
1767 sprintf(key, "%d", x);
1768 rc = memcached_set(memc, key, strlen(key),
1769 randomstuff, strlen(randomstuff), 10, 0);
1770 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1771 /* If we fail, lets try again */
1772 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
1773 rc = memcached_set(memc, key, strlen(key),
1774 randomstuff, strlen(randomstuff), 10, 0);
1775 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1776 }
1777
1778 return TEST_SUCCESS;
1779 }
1780
1781 /* Test case provided by Cal Haldenbrand */
1782 static test_return_t user_supplied_bug2(memcached_st *memc)
1783 {
1784 int errors;
1785 unsigned int setter;
1786 unsigned int x;
1787 unsigned long long total;
1788
1789 setter= 1;
1790 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1791 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1792 #ifdef NOT_YET
1793 setter = 20 * 1024576;
1794 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1795 setter = 20 * 1024576;
1796 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1797 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1798 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1799
1800 for (x= 0, errors= 0, total= 0 ; total < 20 * 1024576 ; x++)
1801 #endif
1802
1803 for (x= 0, errors= 0, total= 0 ; total < 24576 ; x++)
1804 {
1805 memcached_return rc= MEMCACHED_SUCCESS;
1806 char buffer[SMALL_STRING_LEN];
1807 uint32_t flags= 0;
1808 size_t val_len= 0;
1809 char *getval;
1810
1811 memset(buffer, 0, SMALL_STRING_LEN);
1812
1813 snprintf(buffer, SMALL_STRING_LEN, "%u", x);
1814 getval= memcached_get(memc, buffer, strlen(buffer),
1815 &val_len, &flags, &rc);
1816 if (rc != MEMCACHED_SUCCESS)
1817 {
1818 if (rc == MEMCACHED_NOTFOUND)
1819 errors++;
1820 else
1821 {
1822 assert(rc);
1823 }
1824
1825 continue;
1826 }
1827 total+= val_len;
1828 errors= 0;
1829 free(getval);
1830 }
1831
1832 return TEST_SUCCESS;
1833 }
1834
1835 /* Do a large mget() over all the keys we think exist */
1836 #define KEY_COUNT 3000 // * 1024576
1837 static test_return_t user_supplied_bug3(memcached_st *memc)
1838 {
1839 memcached_return rc;
1840 unsigned int setter;
1841 unsigned int x;
1842 char **keys;
1843 size_t key_lengths[KEY_COUNT];
1844
1845 setter= 1;
1846 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1847 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1848 #ifdef NOT_YET
1849 setter = 20 * 1024576;
1850 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1851 setter = 20 * 1024576;
1852 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1853 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1854 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1855 #endif
1856
1857 keys= calloc(KEY_COUNT, sizeof(char *));
1858 assert(keys);
1859 for (x= 0; x < KEY_COUNT; x++)
1860 {
1861 char buffer[30];
1862
1863 snprintf(buffer, 30, "%u", x);
1864 keys[x]= strdup(buffer);
1865 key_lengths[x]= strlen(keys[x]);
1866 }
1867
1868 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
1869 assert(rc == MEMCACHED_SUCCESS);
1870
1871 assert(fetch_all_results(memc) == TEST_SUCCESS);
1872
1873 for (x= 0; x < KEY_COUNT; x++)
1874 free(keys[x]);
1875 free(keys);
1876
1877 return TEST_SUCCESS;
1878 }
1879
1880 /* Make sure we behave properly if server list has no values */
1881 static test_return_t user_supplied_bug4(memcached_st *memc)
1882 {
1883 memcached_return rc;
1884 const char *keys[]= {"fudge", "son", "food"};
1885 size_t key_length[]= {5, 3, 4};
1886 unsigned int x;
1887 uint32_t flags;
1888 char return_key[MEMCACHED_MAX_KEY];
1889 size_t return_key_length;
1890 char *return_value;
1891 size_t return_value_length;
1892
1893 /* Here we free everything before running a bunch of mget tests */
1894 {
1895 memcached_server_list_free(memc->hosts);
1896 memc->hosts= NULL;
1897 memc->number_of_hosts= 0;
1898 }
1899
1900
1901 /* We need to empty the server before continueing test */
1902 rc= memcached_flush(memc, 0);
1903 assert(rc == MEMCACHED_NO_SERVERS);
1904
1905 rc= memcached_mget(memc, keys, key_length, 3);
1906 assert(rc == MEMCACHED_NO_SERVERS);
1907
1908 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1909 &return_value_length, &flags, &rc)) != NULL)
1910 {
1911 assert(return_value);
1912 }
1913 assert(!return_value);
1914 assert(return_value_length == 0);
1915 assert(rc == MEMCACHED_NO_SERVERS);
1916
1917 for (x= 0; x < 3; x++)
1918 {
1919 rc= memcached_set(memc, keys[x], key_length[x],
1920 keys[x], key_length[x],
1921 (time_t)50, (uint32_t)9);
1922 assert(rc == MEMCACHED_NO_SERVERS);
1923 }
1924
1925 rc= memcached_mget(memc, keys, key_length, 3);
1926 assert(rc == MEMCACHED_NO_SERVERS);
1927
1928 x= 0;
1929 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1930 &return_value_length, &flags, &rc)))
1931 {
1932 assert(return_value);
1933 assert(rc == MEMCACHED_SUCCESS);
1934 assert(return_key_length == return_value_length);
1935 assert(!memcmp(return_value, return_key, return_value_length));
1936 free(return_value);
1937 x++;
1938 }
1939
1940 return TEST_SUCCESS;
1941 }
1942
1943 #define VALUE_SIZE_BUG5 1048064
1944 static test_return_t user_supplied_bug5(memcached_st *memc)
1945 {
1946 memcached_return rc;
1947 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
1948 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
1949 char return_key[MEMCACHED_MAX_KEY];
1950 size_t return_key_length;
1951 char *value;
1952 size_t value_length;
1953 uint32_t flags;
1954 unsigned int count;
1955 unsigned int x;
1956 char insert_data[VALUE_SIZE_BUG5];
1957
1958 for (x= 0; x < VALUE_SIZE_BUG5; x++)
1959 insert_data[x]= (signed char)rand();
1960
1961 memcached_flush(memc, 0);
1962 value= memcached_get(memc, keys[0], key_length[0],
1963 &value_length, &flags, &rc);
1964 assert(value == NULL);
1965 rc= memcached_mget(memc, keys, key_length, 4);
1966
1967 count= 0;
1968 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1969 &value_length, &flags, &rc)))
1970 count++;
1971 assert(count == 0);
1972
1973 for (x= 0; x < 4; x++)
1974 {
1975 rc= memcached_set(memc, keys[x], key_length[x],
1976 insert_data, VALUE_SIZE_BUG5,
1977 (time_t)0, (uint32_t)0);
1978 assert(rc == MEMCACHED_SUCCESS);
1979 }
1980
1981 for (x= 0; x < 10; x++)
1982 {
1983 value= memcached_get(memc, keys[0], key_length[0],
1984 &value_length, &flags, &rc);
1985 assert(value);
1986 free(value);
1987
1988 rc= memcached_mget(memc, keys, key_length, 4);
1989 count= 0;
1990 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1991 &value_length, &flags, &rc)))
1992 {
1993 count++;
1994 free(value);
1995 }
1996 assert(count == 4);
1997 }
1998
1999 return TEST_SUCCESS;
2000 }
2001
2002 static test_return_t user_supplied_bug6(memcached_st *memc)
2003 {
2004 memcached_return rc;
2005 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2006 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2007 char return_key[MEMCACHED_MAX_KEY];
2008 size_t return_key_length;
2009 char *value;
2010 size_t value_length;
2011 uint32_t flags;
2012 unsigned int count;
2013 unsigned int x;
2014 char insert_data[VALUE_SIZE_BUG5];
2015
2016 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2017 insert_data[x]= (signed char)rand();
2018
2019 memcached_flush(memc, 0);
2020 value= memcached_get(memc, keys[0], key_length[0],
2021 &value_length, &flags, &rc);
2022 assert(value == NULL);
2023 assert(rc == MEMCACHED_NOTFOUND);
2024 rc= memcached_mget(memc, keys, key_length, 4);
2025 assert(rc == MEMCACHED_SUCCESS);
2026
2027 count= 0;
2028 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2029 &value_length, &flags, &rc)))
2030 count++;
2031 assert(count == 0);
2032 assert(rc == MEMCACHED_END);
2033
2034 for (x= 0; x < 4; x++)
2035 {
2036 rc= memcached_set(memc, keys[x], key_length[x],
2037 insert_data, VALUE_SIZE_BUG5,
2038 (time_t)0, (uint32_t)0);
2039 assert(rc == MEMCACHED_SUCCESS);
2040 }
2041
2042 for (x= 0; x < 2; x++)
2043 {
2044 value= memcached_get(memc, keys[0], key_length[0],
2045 &value_length, &flags, &rc);
2046 assert(value);
2047 free(value);
2048
2049 rc= memcached_mget(memc, keys, key_length, 4);
2050 assert(rc == MEMCACHED_SUCCESS);
2051 count= 3;
2052 /* We test for purge of partial complete fetches */
2053 for (count= 3; count; count--)
2054 {
2055 value= memcached_fetch(memc, return_key, &return_key_length,
2056 &value_length, &flags, &rc);
2057 assert(rc == MEMCACHED_SUCCESS);
2058 assert(!(memcmp(value, insert_data, value_length)));
2059 assert(value_length);
2060 free(value);
2061 }
2062 }
2063
2064 return TEST_SUCCESS;
2065 }
2066
2067 static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused)))
2068 {
2069 memcached_return rc;
2070 memcached_st *mine;
2071 memcached_st *memc_clone;
2072
2073 memcached_server_st *servers;
2074 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";
2075
2076 servers= memcached_servers_parse(server_list);
2077 assert(servers);
2078
2079 mine= memcached_create(NULL);
2080 rc= memcached_server_push(mine, servers);
2081 assert(rc == MEMCACHED_SUCCESS);
2082 memcached_server_list_free(servers);
2083
2084 assert(mine);
2085 memc_clone= memcached_clone(NULL, mine);
2086
2087 memcached_quit(mine);
2088 memcached_quit(memc_clone);
2089
2090
2091 memcached_free(mine);
2092 memcached_free(memc_clone);
2093
2094 return TEST_SUCCESS;
2095 }
2096
2097 /* Test flag store/retrieve */
2098 static test_return_t user_supplied_bug7(memcached_st *memc)
2099 {
2100 memcached_return rc;
2101 const char *keys= "036790384900";
2102 size_t key_length= strlen(keys);
2103 char return_key[MEMCACHED_MAX_KEY];
2104 size_t return_key_length;
2105 char *value;
2106 size_t value_length;
2107 uint32_t flags;
2108 unsigned int x;
2109 char insert_data[VALUE_SIZE_BUG5];
2110
2111 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2112 insert_data[x]= (signed char)rand();
2113
2114 memcached_flush(memc, 0);
2115
2116 flags= 245;
2117 rc= memcached_set(memc, keys, key_length,
2118 insert_data, VALUE_SIZE_BUG5,
2119 (time_t)0, flags);
2120 assert(rc == MEMCACHED_SUCCESS);
2121
2122 flags= 0;
2123 value= memcached_get(memc, keys, key_length,
2124 &value_length, &flags, &rc);
2125 assert(flags == 245);
2126 assert(value);
2127 free(value);
2128
2129 rc= memcached_mget(memc, &keys, &key_length, 1);
2130
2131 flags= 0;
2132 value= memcached_fetch(memc, return_key, &return_key_length,
2133 &value_length, &flags, &rc);
2134 assert(flags == 245);
2135 assert(value);
2136 free(value);
2137
2138
2139 return TEST_SUCCESS;
2140 }
2141
2142 static test_return_t user_supplied_bug9(memcached_st *memc)
2143 {
2144 memcached_return rc;
2145 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2146 size_t key_length[3];
2147 unsigned int x;
2148 uint32_t flags;
2149 unsigned count= 0;
2150
2151 char return_key[MEMCACHED_MAX_KEY];
2152 size_t return_key_length;
2153 char *return_value;
2154 size_t return_value_length;
2155
2156
2157 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2158 key_length[1]= strlen("fudge&*@#");
2159 key_length[2]= strlen("for^#@&$not");
2160
2161
2162 for (x= 0; x < 3; x++)
2163 {
2164 rc= memcached_set(memc, keys[x], key_length[x],
2165 keys[x], key_length[x],
2166 (time_t)50, (uint32_t)9);
2167 assert(rc == MEMCACHED_SUCCESS);
2168 }
2169
2170 rc= memcached_mget(memc, keys, key_length, 3);
2171 assert(rc == MEMCACHED_SUCCESS);
2172
2173 /* We need to empty the server before continueing test */
2174 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2175 &return_value_length, &flags, &rc)) != NULL)
2176 {
2177 assert(return_value);
2178 free(return_value);
2179 count++;
2180 }
2181 assert(count == 3);
2182
2183 return TEST_SUCCESS;
2184 }
2185
2186 /* We are testing with aggressive timeout to get failures */
2187 static test_return_t user_supplied_bug10(memcached_st *memc)
2188 {
2189 const char *key= "foo";
2190 char *value;
2191 size_t value_length= 512;
2192 unsigned int x;
2193 size_t key_len= 3;
2194 memcached_return rc;
2195 unsigned int set= 1;
2196 memcached_st *mclone= memcached_clone(NULL, memc);
2197 int32_t timeout;
2198
2199 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2200 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2201 timeout= 2;
2202 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2203 (uint64_t)timeout);
2204
2205 value = (char*)malloc(value_length * sizeof(char));
2206
2207 for (x= 0; x < value_length; x++)
2208 value[x]= (char) (x % 127);
2209
2210 for (x= 1; x <= 100000; ++x)
2211 {
2212 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2213
2214 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2215 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2216
2217 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2218 x--;
2219 }
2220
2221 free(value);
2222 memcached_free(mclone);
2223
2224 return TEST_SUCCESS;
2225 }
2226
2227 /*
2228 We are looking failures in the async protocol
2229 */
2230 static test_return_t user_supplied_bug11(memcached_st *memc)
2231 {
2232 const char *key= "foo";
2233 char *value;
2234 size_t value_length= 512;
2235 unsigned int x;
2236 size_t key_len= 3;
2237 memcached_return rc;
2238 unsigned int set= 1;
2239 int32_t timeout;
2240 memcached_st *mclone= memcached_clone(NULL, memc);
2241
2242 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2243 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2244 timeout= -1;
2245 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2246 (size_t)timeout);
2247
2248 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2249
2250 assert(timeout == -1);
2251
2252 value = (char*)malloc(value_length * sizeof(char));
2253
2254 for (x= 0; x < value_length; x++)
2255 value[x]= (char) (x % 127);
2256
2257 for (x= 1; x <= 100000; ++x)
2258 {
2259 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2260 }
2261
2262 free(value);
2263 memcached_free(mclone);
2264
2265 return TEST_SUCCESS;
2266 }
2267
2268 /*
2269 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2270 */
2271 static test_return_t user_supplied_bug12(memcached_st *memc)
2272 {
2273 memcached_return rc;
2274 uint32_t flags;
2275 size_t value_length;
2276 char *value;
2277 uint64_t number_value;
2278
2279 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2280 &value_length, &flags, &rc);
2281 assert(value == NULL);
2282 assert(rc == MEMCACHED_NOTFOUND);
2283
2284 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2285 1, &number_value);
2286
2287 assert(value == NULL);
2288 /* The binary protocol will set the key if it doesn't exist */
2289 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2290 assert(rc == MEMCACHED_SUCCESS);
2291 else
2292 assert(rc == MEMCACHED_NOTFOUND);
2293
2294 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2295
2296 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2297 &value_length, &flags, &rc);
2298 assert(value);
2299 assert(rc == MEMCACHED_SUCCESS);
2300 free(value);
2301
2302 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2303 1, &number_value);
2304 assert(number_value == 2);
2305 assert(rc == MEMCACHED_SUCCESS);
2306
2307 return TEST_SUCCESS;
2308 }
2309
2310 /*
2311 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2312 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2313 */
2314 static test_return_t user_supplied_bug13(memcached_st *memc)
2315 {
2316 char key[] = "key34567890";
2317 char *overflow;
2318 memcached_return rc;
2319 size_t overflowSize;
2320
2321 char commandFirst[]= "set key34567890 0 0 ";
2322 char commandLast[] = " \r\n"; /* first line of command sent to server */
2323 size_t commandLength;
2324 size_t testSize;
2325
2326 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2327
2328 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2329
2330 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2331 {
2332 overflow= malloc(testSize);
2333 assert(overflow != NULL);
2334
2335 memset(overflow, 'x', testSize);
2336 rc= memcached_set(memc, key, strlen(key),
2337 overflow, testSize, 0, 0);
2338 assert(rc == MEMCACHED_SUCCESS);
2339 free(overflow);
2340 }
2341
2342 return TEST_SUCCESS;
2343 }
2344
2345
2346 /*
2347 Test values of many different sizes
2348 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2349 set key34567890 0 0 8169 \r\n
2350 is sent followed by buffer of size 8169, followed by 8169
2351 */
2352 static test_return_t user_supplied_bug14(memcached_st *memc)
2353 {
2354 size_t setter= 1;
2355 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2356 memcached_return rc;
2357 const char *key= "foo";
2358 char *value;
2359 size_t value_length= 18000;
2360 char *string;
2361 size_t string_length;
2362 uint32_t flags;
2363 unsigned int x;
2364 size_t current_length;
2365
2366 value = (char*)malloc(value_length);
2367 assert(value);
2368
2369 for (x= 0; x < value_length; x++)
2370 value[x] = (char) (x % 127);
2371
2372 for (current_length= 0; current_length < value_length; current_length++)
2373 {
2374 rc= memcached_set(memc, key, strlen(key),
2375 value, current_length,
2376 (time_t)0, (uint32_t)0);
2377 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2378
2379 string= memcached_get(memc, key, strlen(key),
2380 &string_length, &flags, &rc);
2381
2382 assert(rc == MEMCACHED_SUCCESS);
2383 assert(string_length == current_length);
2384 assert(!memcmp(string, value, string_length));
2385
2386 free(string);
2387 }
2388
2389 free(value);
2390
2391 return TEST_SUCCESS;
2392 }
2393
2394 /*
2395 Look for zero length value problems
2396 */
2397 static test_return_t user_supplied_bug15(memcached_st *memc)
2398 {
2399 uint32_t x;
2400 memcached_return rc;
2401 const char *key= "mykey";
2402 char *value;
2403 size_t length;
2404 uint32_t flags;
2405
2406 for (x= 0; x < 2; x++)
2407 {
2408 rc= memcached_set(memc, key, strlen(key),
2409 NULL, 0,
2410 (time_t)0, (uint32_t)0);
2411
2412 assert(rc == MEMCACHED_SUCCESS);
2413
2414 value= memcached_get(memc, key, strlen(key),
2415 &length, &flags, &rc);
2416
2417 assert(rc == MEMCACHED_SUCCESS);
2418 assert(value == NULL);
2419 assert(length == 0);
2420 assert(flags == 0);
2421
2422 value= memcached_get(memc, key, strlen(key),
2423 &length, &flags, &rc);
2424
2425 assert(rc == MEMCACHED_SUCCESS);
2426 assert(value == NULL);
2427 assert(length == 0);
2428 assert(flags == 0);
2429 }
2430
2431 return TEST_SUCCESS;
2432 }
2433
2434 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2435 static test_return_t user_supplied_bug16(memcached_st *memc)
2436 {
2437 memcached_return rc;
2438 const char *key= "mykey";
2439 char *value;
2440 size_t length;
2441 uint32_t flags;
2442
2443 rc= memcached_set(memc, key, strlen(key),
2444 NULL, 0,
2445 (time_t)0, UINT32_MAX);
2446
2447 assert(rc == MEMCACHED_SUCCESS);
2448
2449 value= memcached_get(memc, key, strlen(key),
2450 &length, &flags, &rc);
2451
2452 assert(rc == MEMCACHED_SUCCESS);
2453 assert(value == NULL);
2454 assert(length == 0);
2455 assert(flags == UINT32_MAX);
2456
2457 return TEST_SUCCESS;
2458 }
2459
2460 #ifndef __sun
2461 /* Check the validity of chinese key*/
2462 static test_return_t user_supplied_bug17(memcached_st *memc)
2463 {
2464 memcached_return rc;
2465 const char *key= "豆瓣";
2466 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2467 char *value2;
2468 size_t length;
2469 uint32_t flags;
2470
2471 rc= memcached_set(memc, key, strlen(key),
2472 value, strlen(value),
2473 (time_t)0, 0);
2474
2475 assert(rc == MEMCACHED_SUCCESS);
2476
2477 value2= memcached_get(memc, key, strlen(key),
2478 &length, &flags, &rc);
2479
2480 assert(length==strlen(value));
2481 assert(rc == MEMCACHED_SUCCESS);
2482 assert(memcmp(value, value2, length)==0);
2483 free(value2);
2484
2485 return TEST_SUCCESS;
2486 }
2487 #endif
2488
2489 /*
2490 From Andrei on IRC
2491 */
2492
2493 static test_return_t user_supplied_bug19(memcached_st *memc)
2494 {
2495 memcached_st *m;
2496 memcached_server_st *s;
2497 memcached_return res;
2498
2499 (void)memc;
2500
2501 m= memcached_create(NULL);
2502 memcached_server_add_with_weight(m, "localhost", 11311, 100);
2503 memcached_server_add_with_weight(m, "localhost", 11312, 100);
2504
2505 s= memcached_server_by_key(m, "a", 1, &res);
2506 memcached_server_free(s);
2507
2508 memcached_free(m);
2509
2510 return TEST_SUCCESS;
2511 }
2512
2513 /* CAS test from Andei */
2514 static test_return_t user_supplied_bug20(memcached_st *memc)
2515 {
2516 memcached_return status;
2517 memcached_result_st *result, result_obj;
2518 const char *key = "abc";
2519 size_t key_len = strlen("abc");
2520 const char *value = "foobar";
2521 size_t value_len = strlen(value);
2522
2523 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2524
2525 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2526 assert(status == MEMCACHED_SUCCESS);
2527
2528 status = memcached_mget(memc, &key, &key_len, 1);
2529 assert(status == MEMCACHED_SUCCESS);
2530
2531 result= memcached_result_create(memc, &result_obj);
2532 assert(result);
2533
2534 memcached_result_create(memc, &result_obj);
2535 result= memcached_fetch_result(memc, &result_obj, &status);
2536
2537 assert(result);
2538 assert(status == MEMCACHED_SUCCESS);
2539
2540 memcached_result_free(result);
2541
2542 return TEST_SUCCESS;
2543 }
2544
2545 #include "ketama_test_cases.h"
2546 static test_return_t user_supplied_bug18(memcached_st *trash)
2547 {
2548 memcached_return rc;
2549 uint64_t value;
2550 int x;
2551 memcached_server_st *server_pool;
2552 memcached_st *memc;
2553
2554 (void)trash;
2555
2556 memc= memcached_create(NULL);
2557 assert(memc);
2558
2559 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2560 assert(rc == MEMCACHED_SUCCESS);
2561
2562 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2563 assert(value == 1);
2564
2565 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2566 assert(rc == MEMCACHED_SUCCESS);
2567
2568 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2569 assert(value == MEMCACHED_HASH_MD5);
2570
2571 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");
2572 memcached_server_push(memc, server_pool);
2573
2574 /* verify that the server list was parsed okay. */
2575 assert(memc->number_of_hosts == 8);
2576 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2577 assert(server_pool[0].port == 11211);
2578 assert(server_pool[0].weight == 600);
2579 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2580 assert(server_pool[2].port == 11211);
2581 assert(server_pool[2].weight == 200);
2582 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2583 assert(server_pool[7].port == 11211);
2584 assert(server_pool[7].weight == 100);
2585
2586 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2587 * us test the boundary wraparound.
2588 */
2589 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2590
2591 /* verify the standard ketama set. */
2592 for (x= 0; x < 99; x++)
2593 {
2594 uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
2595 char *hostname = memc->hosts[server_idx].hostname;
2596 assert(strcmp(hostname, test_cases[x].server) == 0);
2597 }
2598
2599 memcached_server_list_free(server_pool);
2600 memcached_free(memc);
2601
2602 return TEST_SUCCESS;
2603 }
2604
2605 /* Large mget() of missing keys with binary proto
2606 *
2607 * If many binary quiet commands (such as getq's in an mget) fill the output
2608 * buffer and the server chooses not to respond, memcached_flush hangs. See
2609 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2610 */
2611
2612 /* sighandler_t function that always asserts false */
2613 static void fail(int unused __attribute__((unused)))
2614 {
2615 assert(0);
2616 }
2617
2618
2619 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2620 {
2621 memcached_return rc;
2622 unsigned int x;
2623 char **keys;
2624 size_t* key_lengths;
2625 void (*oldalarm)(int);
2626 memcached_st *memc_clone;
2627
2628 memc_clone= memcached_clone(NULL, memc);
2629 assert(memc_clone);
2630
2631 /* only binproto uses getq for mget */
2632 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2633
2634 /* empty the cache to ensure misses (hence non-responses) */
2635 rc= memcached_flush(memc_clone, 0);
2636 assert(rc == MEMCACHED_SUCCESS);
2637
2638 key_lengths= calloc(key_count, sizeof(size_t));
2639 keys= calloc(key_count, sizeof(char *));
2640 assert(keys);
2641 for (x= 0; x < key_count; x++)
2642 {
2643 char buffer[30];
2644
2645 snprintf(buffer, 30, "%u", x);
2646 keys[x]= strdup(buffer);
2647 key_lengths[x]= strlen(keys[x]);
2648 }
2649
2650 oldalarm= signal(SIGALRM, fail);
2651 alarm(5);
2652
2653 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
2654 assert(rc == MEMCACHED_SUCCESS);
2655
2656 alarm(0);
2657 signal(SIGALRM, oldalarm);
2658
2659 assert(fetch_all_results(memc) == TEST_SUCCESS);
2660
2661 for (x= 0; x < key_count; x++)
2662 free(keys[x]);
2663 free(keys);
2664 free(key_lengths);
2665
2666 memcached_free(memc_clone);
2667
2668 return TEST_SUCCESS;
2669 }
2670
2671 static memcached_return pre_binary(memcached_st *memc);
2672
2673 static test_return_t user_supplied_bug21(memcached_st *memc)
2674 {
2675 if (pre_binary(memc) != MEMCACHED_SUCCESS)
2676 return TEST_SKIPPED;
2677
2678 test_return_t rc;
2679
2680 /* should work as of r580 */
2681 rc= _user_supplied_bug21(memc, 10);
2682 assert(rc == TEST_SUCCESS);
2683
2684 /* should fail as of r580 */
2685 rc= _user_supplied_bug21(memc, 1000);
2686 assert(rc == TEST_SUCCESS);
2687
2688 return TEST_SUCCESS;
2689 }
2690
2691 static test_return_t auto_eject_hosts(memcached_st *trash)
2692 {
2693 (void) trash;
2694
2695 memcached_return rc;
2696 memcached_st *memc= memcached_create(NULL);
2697 assert(memc);
2698
2699 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2700 assert(rc == MEMCACHED_SUCCESS);
2701
2702 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2703 assert(value == 1);
2704
2705 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2706 assert(rc == MEMCACHED_SUCCESS);
2707
2708 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2709 assert(value == MEMCACHED_HASH_MD5);
2710
2711 /* server should be removed when in delay */
2712 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
2713 assert(rc == MEMCACHED_SUCCESS);
2714
2715 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
2716 assert(value == 1);
2717
2718 memcached_server_st *server_pool;
2719 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");
2720 memcached_server_push(memc, server_pool);
2721
2722 /* verify that the server list was parsed okay. */
2723 assert(memc->number_of_hosts == 8);
2724 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2725 assert(server_pool[0].port == 11211);
2726 assert(server_pool[0].weight == 600);
2727 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2728 assert(server_pool[2].port == 11211);
2729 assert(server_pool[2].weight == 200);
2730 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2731 assert(server_pool[7].port == 11211);
2732 assert(server_pool[7].weight == 100);
2733
2734 memc->hosts[2].next_retry = time(NULL) + 15;
2735 memc->next_distribution_rebuild= time(NULL) - 1;
2736
2737 for (int x= 0; x < 99; x++)
2738 {
2739 uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
2740 assert(server_idx != 2);
2741 }
2742
2743 /* and re-added when it's back. */
2744 memc->hosts[2].next_retry = time(NULL) - 1;
2745 memc->next_distribution_rebuild= time(NULL) - 1;
2746 run_distribution(memc);
2747 for (int x= 0; x < 99; x++)
2748 {
2749 uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
2750 char *hostname = memc->hosts[server_idx].hostname;
2751 assert(strcmp(hostname, test_cases[x].server) == 0);
2752 }
2753
2754 memcached_server_list_free(server_pool);
2755 memcached_free(memc);
2756
2757 return TEST_SUCCESS;
2758 }
2759
2760 static test_return_t result_static(memcached_st *memc)
2761 {
2762 memcached_result_st result;
2763 memcached_result_st *result_ptr;
2764
2765 result_ptr= memcached_result_create(memc, &result);
2766 assert(result.is_allocated == false);
2767 assert(result_ptr);
2768 memcached_result_free(&result);
2769
2770 return TEST_SUCCESS;
2771 }
2772
2773 static test_return_t result_alloc(memcached_st *memc)
2774 {
2775 memcached_result_st *result;
2776
2777 result= memcached_result_create(memc, NULL);
2778 assert(result);
2779 memcached_result_free(result);
2780
2781 return TEST_SUCCESS;
2782 }
2783
2784 static test_return_t string_static_null(memcached_st *memc)
2785 {
2786 memcached_string_st string;
2787 memcached_string_st *string_ptr;
2788
2789 string_ptr= memcached_string_create(memc, &string, 0);
2790 assert(string.is_allocated == false);
2791 assert(string_ptr);
2792 memcached_string_free(&string);
2793
2794 return TEST_SUCCESS;
2795 }
2796
2797 static test_return_t string_alloc_null(memcached_st *memc)
2798 {
2799 memcached_string_st *string;
2800
2801 string= memcached_string_create(memc, NULL, 0);
2802 assert(string);
2803 memcached_string_free(string);
2804
2805 return TEST_SUCCESS;
2806 }
2807
2808 static test_return_t string_alloc_with_size(memcached_st *memc)
2809 {
2810 memcached_string_st *string;
2811
2812 string= memcached_string_create(memc, NULL, 1024);
2813 assert(string);
2814 memcached_string_free(string);
2815
2816 return TEST_SUCCESS;
2817 }
2818
2819 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
2820 {
2821 memcached_string_st *string;
2822
2823 string= memcached_string_create(memc, NULL, SIZE_MAX);
2824 assert(string == NULL);
2825
2826 return TEST_SUCCESS;
2827 }
2828
2829 static test_return_t string_alloc_append(memcached_st *memc)
2830 {
2831 unsigned int x;
2832 char buffer[SMALL_STRING_LEN];
2833 memcached_string_st *string;
2834
2835 /* Ring the bell! */
2836 memset(buffer, 6, SMALL_STRING_LEN);
2837
2838 string= memcached_string_create(memc, NULL, 100);
2839 assert(string);
2840
2841 for (x= 0; x < 1024; x++)
2842 {
2843 memcached_return rc;
2844 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2845 assert(rc == MEMCACHED_SUCCESS);
2846 }
2847 memcached_string_free(string);
2848
2849 return TEST_SUCCESS;
2850 }
2851
2852 static test_return_t string_alloc_append_toobig(memcached_st *memc)
2853 {
2854 memcached_return rc;
2855 unsigned int x;
2856 char buffer[SMALL_STRING_LEN];
2857 memcached_string_st *string;
2858
2859 /* Ring the bell! */
2860 memset(buffer, 6, SMALL_STRING_LEN);
2861
2862 string= memcached_string_create(memc, NULL, 100);
2863 assert(string);
2864
2865 for (x= 0; x < 1024; x++)
2866 {
2867 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2868 assert(rc == MEMCACHED_SUCCESS);
2869 }
2870 rc= memcached_string_append(string, buffer, SIZE_MAX);
2871 assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
2872 memcached_string_free(string);
2873
2874 return TEST_SUCCESS;
2875 }
2876
2877 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
2878 {
2879 pairs_free(global_pairs);
2880
2881 return TEST_SUCCESS;
2882 }
2883
2884 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
2885 {
2886 unsigned long long x;
2887 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
2888 global_count= GLOBAL_COUNT;
2889
2890 for (x= 0; x < global_count; x++)
2891 {
2892 global_keys[x]= global_pairs[x].key;
2893 global_keys_length[x]= global_pairs[x].key_length;
2894 }
2895
2896 return TEST_SUCCESS;
2897 }
2898
2899 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
2900 {
2901 unsigned long long x;
2902 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
2903 global_count= GLOBAL2_COUNT;
2904
2905 for (x= 0; x < global_count; x++)
2906 {
2907 global_keys[x]= global_pairs[x].key;
2908 global_keys_length[x]= global_pairs[x].key_length;
2909 }
2910
2911 return TEST_SUCCESS;
2912 }
2913
2914 static test_return_t generate_data(memcached_st *memc)
2915 {
2916 execute_set(memc, global_pairs, global_count);
2917
2918 return TEST_SUCCESS;
2919 }
2920
2921 static test_return_t generate_data_with_stats(memcached_st *memc)
2922 {
2923 memcached_stat_st *stat_p;
2924 memcached_return rc;
2925 uint32_t host_index= 0;
2926 execute_set(memc, global_pairs, global_count);
2927
2928 //TODO: hosts used size stats
2929 stat_p= memcached_stat(memc, NULL, &rc);
2930 assert(stat_p);
2931
2932 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
2933 {
2934 /* This test was changes so that "make test" would work properlly */
2935 #ifdef DEBUG
2936 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);
2937 #endif
2938 assert((unsigned long long)(stat_p + host_index)->bytes);
2939 }
2940
2941 memcached_stat_free(NULL, stat_p);
2942
2943 return TEST_SUCCESS;
2944 }
2945 static test_return_t generate_buffer_data(memcached_st *memc)
2946 {
2947 size_t latch= 0;
2948
2949 latch= 1;
2950 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
2951 generate_data(memc);
2952
2953 return TEST_SUCCESS;
2954 }
2955
2956 static test_return_t get_read_count(memcached_st *memc)
2957 {
2958 unsigned int x;
2959 memcached_return rc;
2960 memcached_st *memc_clone;
2961
2962 memc_clone= memcached_clone(NULL, memc);
2963 assert(memc_clone);
2964
2965 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
2966
2967 {
2968 char *return_value;
2969 size_t return_value_length;
2970 uint32_t flags;
2971 uint32_t count;
2972
2973 for (x= count= 0; x < global_count; x++)
2974 {
2975 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
2976 &return_value_length, &flags, &rc);
2977 if (rc == MEMCACHED_SUCCESS)
2978 {
2979 count++;
2980 if (return_value)
2981 free(return_value);
2982 }
2983 }
2984 }
2985
2986 memcached_free(memc_clone);
2987
2988 return TEST_SUCCESS;
2989 }
2990
2991 static test_return_t get_read(memcached_st *memc)
2992 {
2993 unsigned int x;
2994 memcached_return rc;
2995
2996 {
2997 char *return_value;
2998 size_t return_value_length;
2999 uint32_t flags;
3000
3001 for (x= 0; x < global_count; x++)
3002 {
3003 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3004 &return_value_length, &flags, &rc);
3005 /*
3006 assert(return_value);
3007 assert(rc == MEMCACHED_SUCCESS);
3008 */
3009 if (rc == MEMCACHED_SUCCESS && return_value)
3010 free(return_value);
3011 }
3012 }
3013
3014 return TEST_SUCCESS;
3015 }
3016
3017 static test_return_t mget_read(memcached_st *memc)
3018 {
3019 memcached_return rc;
3020
3021 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3022 assert(rc == MEMCACHED_SUCCESS);
3023 assert(fetch_all_results(memc) == TEST_SUCCESS);
3024
3025 return TEST_SUCCESS;
3026 }
3027
3028 static test_return_t mget_read_result(memcached_st *memc)
3029 {
3030 memcached_return rc;
3031
3032 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3033 assert(rc == MEMCACHED_SUCCESS);
3034 /* Turn this into a help function */
3035 {
3036 memcached_result_st results_obj;
3037 memcached_result_st *results;
3038
3039 results= memcached_result_create(memc, &results_obj);
3040
3041 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3042 {
3043 assert(results);
3044 assert(rc == MEMCACHED_SUCCESS);
3045 }
3046
3047 memcached_result_free(&results_obj);
3048 }
3049
3050 return TEST_SUCCESS;
3051 }
3052
3053 static test_return_t mget_read_function(memcached_st *memc)
3054 {
3055 memcached_return rc;
3056 unsigned int counter;
3057 memcached_execute_function callbacks[1];
3058
3059 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3060 assert(rc == MEMCACHED_SUCCESS);
3061
3062 callbacks[0]= &callback_counter;
3063 counter= 0;
3064 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3065
3066 return TEST_SUCCESS;
3067 }
3068
3069 static test_return_t delete_generate(memcached_st *memc)
3070 {
3071 unsigned int x;
3072
3073 for (x= 0; x < global_count; x++)
3074 {
3075 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3076 }
3077
3078 return TEST_SUCCESS;
3079 }
3080
3081 static test_return_t delete_buffer_generate(memcached_st *memc)
3082 {
3083 size_t latch= 0;
3084 unsigned int x;
3085
3086 latch= 1;
3087 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3088
3089 for (x= 0; x < global_count; x++)
3090 {
3091 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3092 }
3093
3094 return TEST_SUCCESS;
3095 }
3096
3097 static test_return_t add_host_test1(memcached_st *memc)
3098 {
3099 unsigned int x;
3100 memcached_return rc;
3101 char servername[]= "0.example.com";
3102 memcached_server_st *servers;
3103
3104 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3105 assert(servers);
3106 assert(1 == memcached_server_list_count(servers));
3107
3108 for (x= 2; x < 20; x++)
3109 {
3110 char buffer[SMALL_STRING_LEN];
3111
3112 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
3113 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3114 &rc);
3115 assert(rc == MEMCACHED_SUCCESS);
3116 assert(x == memcached_server_list_count(servers));
3117 }
3118
3119 rc= memcached_server_push(memc, servers);
3120 assert(rc == MEMCACHED_SUCCESS);
3121 rc= memcached_server_push(memc, servers);
3122 assert(rc == MEMCACHED_SUCCESS);
3123
3124 memcached_server_list_free(servers);
3125
3126 return TEST_SUCCESS;
3127 }
3128
3129 static memcached_return pre_nonblock(memcached_st *memc)
3130 {
3131 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3132
3133 return MEMCACHED_SUCCESS;
3134 }
3135
3136 static memcached_return pre_nonblock_binary(memcached_st *memc)
3137 {
3138 memcached_return rc= MEMCACHED_FAILURE;
3139 memcached_st *memc_clone;
3140
3141 memc_clone= memcached_clone(NULL, memc);
3142 assert(memc_clone);
3143 // The memcached_version needs to be done on a clone, because the server
3144 // will not toggle protocol on an connection.
3145 memcached_version(memc_clone);
3146
3147 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3148 {
3149 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3150 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3151 assert(rc == MEMCACHED_SUCCESS);
3152 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3153 }
3154
3155 memcached_free(memc_clone);
3156 return rc;
3157 }
3158
3159 static memcached_return pre_murmur(memcached_st *memc)
3160 {
3161 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3162
3163 return MEMCACHED_SUCCESS;
3164 }
3165
3166 static memcached_return pre_jenkins(memcached_st *memc)
3167 {
3168 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3169
3170 return MEMCACHED_SUCCESS;
3171 }
3172
3173
3174 static memcached_return pre_md5(memcached_st *memc)
3175 {
3176 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3177
3178 return MEMCACHED_SUCCESS;
3179 }
3180
3181 static memcached_return pre_crc(memcached_st *memc)
3182 {
3183 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3184
3185 return MEMCACHED_SUCCESS;
3186 }
3187
3188 static memcached_return pre_hsieh(memcached_st *memc)
3189 {
3190 #ifdef HAVE_HSIEH_HASH
3191 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3192 return MEMCACHED_SUCCESS;
3193 #else
3194 (void) memc;
3195 return MEMCACHED_FAILURE;
3196 #endif
3197 }
3198
3199 static memcached_return pre_hash_fnv1_64(memcached_st *memc)
3200 {
3201 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
3202
3203 return MEMCACHED_SUCCESS;
3204 }
3205
3206 static memcached_return pre_hash_fnv1a_64(memcached_st *memc)
3207 {
3208 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3209
3210 return MEMCACHED_SUCCESS;
3211 }
3212
3213 static memcached_return pre_hash_fnv1_32(memcached_st *memc)
3214 {
3215 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3216
3217 return MEMCACHED_SUCCESS;
3218 }
3219
3220 static memcached_return pre_hash_fnv1a_32(memcached_st *memc)
3221 {
3222 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3223
3224 return MEMCACHED_SUCCESS;
3225 }
3226
3227 static memcached_return pre_behavior_ketama(memcached_st *memc)
3228 {
3229 memcached_return rc;
3230 uint64_t value;
3231
3232 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3233 assert(rc == MEMCACHED_SUCCESS);
3234
3235 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3236 assert(value == 1);
3237
3238 return MEMCACHED_SUCCESS;
3239 }
3240
3241 static memcached_return pre_behavior_ketama_weighted(memcached_st *memc)
3242 {
3243 memcached_return rc;
3244 uint64_t value;
3245
3246 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3247 assert(rc == MEMCACHED_SUCCESS);
3248
3249 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3250 assert(value == 1);
3251
3252 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3253 assert(rc == MEMCACHED_SUCCESS);
3254
3255 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3256 assert(value == MEMCACHED_HASH_MD5);
3257 return MEMCACHED_SUCCESS;
3258 }
3259
3260 static memcached_return pre_binary(memcached_st *memc)
3261 {
3262 memcached_return rc= MEMCACHED_FAILURE;
3263 memcached_st *memc_clone;
3264
3265 memc_clone= memcached_clone(NULL, memc);
3266 assert(memc_clone);
3267 // The memcached_version needs to be done on a clone, because the server
3268 // will not toggle protocol on an connection.
3269 memcached_version(memc_clone);
3270
3271 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3272 {
3273 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3274 assert(rc == MEMCACHED_SUCCESS);
3275 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3276 }
3277
3278 memcached_free(memc_clone);
3279
3280 return rc;
3281 }
3282
3283 static memcached_return pre_replication(memcached_st *memc)
3284 {
3285 if (pre_binary(memc) != MEMCACHED_SUCCESS)
3286 return MEMCACHED_FAILURE;
3287
3288 /*
3289 * Make sure that we store the item on all servers
3290 * (master + replicas == number of servers)
3291 */
3292 memcached_return rc;
3293 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3294 memc->number_of_hosts - 1);
3295 assert(rc == MEMCACHED_SUCCESS);
3296 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memc->number_of_hosts - 1);
3297
3298 return rc;
3299 }
3300
3301 static memcached_return pre_replication_noblock(memcached_st *memc)
3302 {
3303 memcached_return rc= MEMCACHED_FAILURE;
3304 if (pre_replication(memc) == MEMCACHED_SUCCESS &&
3305 pre_nonblock(memc) == MEMCACHED_SUCCESS)
3306 rc= MEMCACHED_SUCCESS;
3307
3308 return rc;
3309 }
3310
3311 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3312 {
3313 free(mem);
3314 }
3315
3316 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3317 {
3318 void *ret= malloc(size);
3319 if (ret != NULL)
3320 memset(ret, 0xff, size);
3321
3322 return ret;
3323 }
3324
3325 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3326 {
3327 return realloc(mem, size);
3328 }
3329
3330 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3331 {
3332 return calloc(nelem, size);
3333 }
3334
3335 static memcached_return set_prefix(memcached_st *memc)
3336 {
3337 memcached_return rc;
3338 const char *key= "mine";
3339 char *value;
3340
3341 /* Make sure be default none exists */
3342 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3343 assert(rc == MEMCACHED_FAILURE);
3344
3345 /* Test a clean set */
3346 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3347 assert(rc == MEMCACHED_SUCCESS);
3348
3349 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3350 assert(memcmp(value, key, 4) == 0);
3351 assert(rc == MEMCACHED_SUCCESS);
3352
3353 /* Test that we can turn it off */
3354 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3355 assert(rc == MEMCACHED_SUCCESS);
3356
3357 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3358 assert(rc == MEMCACHED_FAILURE);
3359
3360 /* Now setup for main test */
3361 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3362 assert(rc == MEMCACHED_SUCCESS);
3363
3364 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3365 assert(rc == MEMCACHED_SUCCESS);
3366 assert(memcmp(value, key, 4) == 0);
3367
3368 /* Set to Zero, and then Set to something too large */
3369 {
3370 char long_key[255];
3371 memset(long_key, 0, 255);
3372
3373 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3374 assert(rc == MEMCACHED_SUCCESS);
3375
3376 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3377 assert(rc == MEMCACHED_FAILURE);
3378 assert(value == NULL);
3379
3380 /* Test a long key for failure */
3381 /* TODO, extend test to determine based on setting, what result should be */
3382 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3383 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3384 //assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3385 assert(rc == MEMCACHED_SUCCESS);
3386
3387 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3388 strcpy(long_key, "This is more then the allotted number of characters");
3389 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3390 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3391
3392 /* Test for a bad prefix, but with a short key */
3393 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3394 assert(rc == MEMCACHED_SUCCESS);
3395
3396 strcpy(long_key, "dog cat");
3397 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3398 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3399 }
3400
3401 return MEMCACHED_SUCCESS;
3402 }
3403
3404 #ifdef MEMCACHED_ENABLE_DEPRECATED
3405 static memcached_return deprecated_set_memory_alloc(memcached_st *memc)
3406 {
3407 void *test_ptr= NULL;
3408 void *cb_ptr= NULL;
3409 {
3410 memcached_malloc_function malloc_cb=
3411 (memcached_malloc_function)my_malloc;
3412 cb_ptr= *(void **)&malloc_cb;
3413 memcached_return rc;
3414
3415 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3416 assert(rc == MEMCACHED_SUCCESS);
3417 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3418 assert(rc == MEMCACHED_SUCCESS);
3419 assert(test_ptr == cb_ptr);
3420 }
3421
3422 {
3423 memcached_realloc_function realloc_cb=
3424 (memcached_realloc_function)my_realloc;
3425 cb_ptr= *(void **)&realloc_cb;
3426 memcached_return rc;
3427
3428 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3429 assert(rc == MEMCACHED_SUCCESS);
3430 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3431 assert(rc == MEMCACHED_SUCCESS);
3432 assert(test_ptr == cb_ptr);
3433 }
3434
3435 {
3436 memcached_free_function free_cb=
3437 (memcached_free_function)my_free;
3438 cb_ptr= *(void **)&free_cb;
3439 memcached_return rc;
3440
3441 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3442 assert(rc == MEMCACHED_SUCCESS);
3443 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3444 assert(rc == MEMCACHED_SUCCESS);
3445 assert(test_ptr == cb_ptr);
3446 }
3447 return MEMCACHED_SUCCESS;
3448 }
3449 #endif
3450
3451 static memcached_return set_memory_alloc(memcached_st *memc)
3452 {
3453 memcached_return rc;
3454 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3455 my_realloc, my_calloc);
3456 assert(rc == MEMCACHED_FAILURE);
3457
3458 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3459 my_realloc, my_calloc);
3460
3461 memcached_malloc_function mem_malloc;
3462 memcached_free_function mem_free;
3463 memcached_realloc_function mem_realloc;
3464 memcached_calloc_function mem_calloc;
3465 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3466 &mem_realloc, &mem_calloc);
3467
3468 assert(mem_malloc == my_malloc);
3469 assert(mem_realloc == my_realloc);
3470 assert(mem_calloc == my_calloc);
3471 assert(mem_free == my_free);
3472
3473 return MEMCACHED_SUCCESS;
3474 }
3475
3476 static memcached_return enable_consistent(memcached_st *memc)
3477 {
3478 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3479 memcached_hash hash;
3480 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3481 if (pre_hsieh(memc) != MEMCACHED_SUCCESS)
3482 return MEMCACHED_FAILURE;
3483
3484 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3485 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3486
3487 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3488 assert(hash == MEMCACHED_HASH_HSIEH);
3489
3490
3491 return MEMCACHED_SUCCESS;
3492 }
3493
3494 static memcached_return enable_cas(memcached_st *memc)
3495 {
3496 unsigned int set= 1;
3497
3498 memcached_version(memc);
3499
3500 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3501 || memc->hosts[0].minor_version > 2)
3502 {
3503 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3504
3505 return MEMCACHED_SUCCESS;
3506 }
3507
3508 return MEMCACHED_FAILURE;
3509 }
3510
3511 static memcached_return check_for_1_2_3(memcached_st *memc)
3512 {
3513 memcached_version(memc);
3514
3515 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3516 || memc->hosts[0].minor_version > 2)
3517 return MEMCACHED_SUCCESS;
3518
3519 return MEMCACHED_FAILURE;
3520 }
3521
3522 static memcached_return pre_unix_socket(memcached_st *memc)
3523 {
3524 memcached_return rc;
3525 struct stat buf;
3526
3527 memcached_server_list_free(memc->hosts);
3528 memc->hosts= NULL;
3529 memc->number_of_hosts= 0;
3530
3531 if (stat("/tmp/memcached.socket", &buf))
3532 return MEMCACHED_FAILURE;
3533
3534 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3535
3536 return rc;
3537 }
3538
3539 static memcached_return pre_nodelay(memcached_st *memc)
3540 {
3541 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3542 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3543
3544 return MEMCACHED_SUCCESS;
3545 }
3546
3547 static memcached_return pre_settimer(memcached_st *memc)
3548 {
3549 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3550 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3551
3552 return MEMCACHED_SUCCESS;
3553 }
3554
3555 static memcached_return poll_timeout(memcached_st *memc)
3556 {
3557 size_t timeout;
3558
3559 timeout= 100;
3560
3561 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3562
3563 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3564
3565 assert(timeout == 100);
3566
3567 return MEMCACHED_SUCCESS;
3568 }
3569
3570 static test_return_t noreply_test(memcached_st *memc)
3571 {
3572 memcached_return ret;
3573 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3574 assert(ret == MEMCACHED_SUCCESS);
3575 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3576 assert(ret == MEMCACHED_SUCCESS);
3577 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3578 assert(ret == MEMCACHED_SUCCESS);
3579 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3580 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3581 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3582
3583 for (int count=0; count < 5; ++count)
3584 {
3585 for (int x=0; x < 100; ++x)
3586 {
3587 char key[10];
3588 size_t len= (size_t)sprintf(key, "%d", x);
3589 switch (count)
3590 {
3591 case 0:
3592 ret=memcached_add(memc, key, len, key, len, 0, 0);
3593 break;
3594 case 1:
3595 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3596 break;
3597 case 2:
3598 ret=memcached_set(memc, key, len, key, len, 0, 0);
3599 break;
3600 case 3:
3601 ret=memcached_append(memc, key, len, key, len, 0, 0);
3602 break;
3603 case 4:
3604 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3605 break;
3606 default:
3607 assert(count);
3608 break;
3609 }
3610 assert(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3611 }
3612
3613 /*
3614 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3615 ** API and is _ONLY_ done this way to verify that the library works the
3616 ** way it is supposed to do!!!!
3617 */
3618 int no_msg=0;
3619 for (uint32_t x=0; x < memc->number_of_hosts; ++x)
3620 no_msg+=(int)(memc->hosts[x].cursor_active);
3621
3622 assert(no_msg == 0);
3623 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3624
3625 /*
3626 ** Now validate that all items was set properly!
3627 */
3628 for (int x=0; x < 100; ++x)
3629 {
3630 char key[10];
3631 size_t len= (size_t)sprintf(key, "%d", x);
3632 size_t length;
3633 uint32_t flags;
3634 char* value=memcached_get(memc, key, strlen(key),
3635 &length, &flags, &ret);
3636 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3637 switch (count)
3638 {
3639 case 0: /* FALLTHROUGH */
3640 case 1: /* FALLTHROUGH */
3641 case 2:
3642 assert(strncmp(value, key, len) == 0);
3643 assert(len == length);
3644 break;
3645 case 3:
3646 assert(length == len * 2);
3647 break;
3648 case 4:
3649 assert(length == len * 3);
3650 break;
3651 default:
3652 assert(count);
3653 break;
3654 }
3655 free(value);
3656 }
3657 }
3658
3659 /* Try setting an illegal cas value (should not return an error to
3660 * the caller (because we don't expect a return message from the server)
3661 */
3662 const char* keys[]= {"0"};
3663 size_t lengths[]= {1};
3664 size_t length;
3665 uint32_t flags;
3666 memcached_result_st results_obj;
3667 memcached_result_st *results;
3668 ret= memcached_mget(memc, keys, lengths, 1);
3669 assert(ret == MEMCACHED_SUCCESS);
3670
3671 results= memcached_result_create(memc, &results_obj);
3672 assert(results);
3673 results= memcached_fetch_result(memc, &results_obj, &ret);
3674 assert(results);
3675 assert(ret == MEMCACHED_SUCCESS);
3676 uint64_t cas= memcached_result_cas(results);
3677 memcached_result_free(&results_obj);
3678
3679 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3680 assert(ret == MEMCACHED_SUCCESS);
3681
3682 /*
3683 * The item will have a new cas value, so try to set it again with the old
3684 * value. This should fail!
3685 */
3686 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3687 assert(ret == MEMCACHED_SUCCESS);
3688 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3689 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3690 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3691 free(value);
3692
3693 return TEST_SUCCESS;
3694 }
3695
3696 static test_return_t analyzer_test(memcached_st *memc)
3697 {
3698 memcached_return rc;
3699 memcached_stat_st *memc_stat;
3700 memcached_analysis_st *report;
3701
3702 memc_stat= memcached_stat(memc, NULL, &rc);
3703 assert(rc == MEMCACHED_SUCCESS);
3704 assert(memc_stat);
3705
3706 report= memcached_analyze(memc, memc_stat, &rc);
3707 assert(rc == MEMCACHED_SUCCESS);
3708 assert(report);
3709
3710 free(report);
3711 memcached_stat_free(NULL, memc_stat);
3712
3713 return TEST_SUCCESS;
3714 }
3715
3716 /* Count the objects */
3717 static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),
3718 const char *key __attribute__((unused)),
3719 size_t key_length __attribute__((unused)),
3720 void *context)
3721 {
3722 uint32_t *counter= (uint32_t *)context;
3723
3724 *counter= *counter + 1;
3725
3726 return MEMCACHED_SUCCESS;
3727 }
3728
3729 static test_return_t dump_test(memcached_st *memc)
3730 {
3731 memcached_return rc;
3732 uint32_t counter= 0;
3733 memcached_dump_func callbacks[1];
3734 test_return_t main_rc;
3735
3736 callbacks[0]= &callback_dump_counter;
3737
3738 /* No support for Binary protocol yet */
3739 if (memc->flags & MEM_BINARY_PROTOCOL)
3740 return TEST_SUCCESS;
3741
3742 main_rc= set_test3(memc);
3743
3744 assert (main_rc == TEST_SUCCESS);
3745
3746 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
3747 assert(rc == MEMCACHED_SUCCESS);
3748
3749 /* We may have more then 32 if our previous flush has not completed */
3750 assert(counter >= 32);
3751
3752 return TEST_SUCCESS;
3753 }
3754
3755 #ifdef HAVE_LIBMEMCACHEDUTIL
3756 static void* connection_release(void *arg) {
3757 struct {
3758 memcached_pool_st* pool;
3759 memcached_st* mmc;
3760 } *resource= arg;
3761
3762 usleep(250);
3763 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
3764 return arg;
3765 }
3766
3767 static test_return_t connection_pool_test(memcached_st *memc)
3768 {
3769 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
3770 assert(pool != NULL);
3771 memcached_st* mmc[10];
3772 memcached_return rc;
3773
3774 for (int x= 0; x < 10; ++x) {
3775 mmc[x]= memcached_pool_pop(pool, false, &rc);
3776 assert(mmc[x] != NULL);
3777 assert(rc == MEMCACHED_SUCCESS);
3778 }
3779
3780 assert(memcached_pool_pop(pool, false, &rc) == NULL);
3781 assert(rc == MEMCACHED_SUCCESS);
3782
3783 pthread_t tid;
3784 struct {
3785 memcached_pool_st* pool;
3786 memcached_st* mmc;
3787 } item= { .pool = pool, .mmc = mmc[9] };
3788 pthread_create(&tid, NULL, connection_release, &item);
3789 mmc[9]= memcached_pool_pop(pool, true, &rc);
3790 assert(rc == MEMCACHED_SUCCESS);
3791 pthread_join(tid, NULL);
3792 assert(mmc[9] == item.mmc);
3793 const char *key= "key";
3794 size_t keylen= strlen(key);
3795
3796 // verify that I can do ops with all connections
3797 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
3798 assert(rc == MEMCACHED_SUCCESS);
3799
3800 for (unsigned int x= 0; x < 10; ++x) {
3801 uint64_t number_value;
3802 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
3803 assert(rc == MEMCACHED_SUCCESS);
3804 assert(number_value == (x+1));
3805 }
3806
3807 // Release them..
3808 for (int x= 0; x < 10; ++x)
3809 assert(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
3810
3811
3812 /* verify that I can set behaviors on the pool when I don't have all
3813 * of the connections in the pool. It should however be enabled
3814 * when I push the item into the pool
3815 */
3816 mmc[0]= memcached_pool_pop(pool, false, &rc);
3817 assert(mmc[0] != NULL);
3818
3819 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
3820 assert(rc == MEMCACHED_SUCCESS);
3821
3822 mmc[1]= memcached_pool_pop(pool, false, &rc);
3823 assert(mmc[1] != NULL);
3824
3825 assert(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3826 assert(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
3827 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3828
3829 mmc[0]= memcached_pool_pop(pool, false, &rc);
3830 assert(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3831 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3832
3833
3834 assert(memcached_pool_destroy(pool) == memc);
3835 return TEST_SUCCESS;
3836 }
3837 #endif
3838
3839 static test_return_t replication_set_test(memcached_st *memc)
3840 {
3841 memcached_return rc;
3842 memcached_st *memc_clone= memcached_clone(NULL, memc);
3843 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3844
3845 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
3846 assert(rc == MEMCACHED_SUCCESS);
3847
3848 /*
3849 ** We are using the quiet commands to store the replicas, so we need
3850 ** to ensure that all of them are processed before we can continue.
3851 ** In the test we go directly from storing the object to trying to
3852 ** receive the object from all of the different servers, so we
3853 ** could end up in a race condition (the memcached server hasn't yet
3854 ** processed the quiet command from the replication set when it process
3855 ** the request from the other client (created by the clone)). As a
3856 ** workaround for that we call memcached_quit to send the quit command
3857 ** to the server and wait for the response ;-) If you use the test code
3858 ** as an example for your own code, please note that you shouldn't need
3859 ** to do this ;-)
3860 */
3861 memcached_quit(memc);
3862
3863 /*
3864 ** "bubba" should now be stored on all of our servers. We don't have an
3865 ** easy to use API to address each individual server, so I'll just iterate
3866 ** through a bunch of "master keys" and I should most likely hit all of the
3867 ** servers...
3868 */
3869 for (int x= 'a'; x <= 'z'; ++x)
3870 {
3871 char key[2]= { [0]= (char)x };
3872 size_t len;
3873 uint32_t flags;
3874 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
3875 &len, &flags, &rc);
3876 assert(rc == MEMCACHED_SUCCESS);
3877 assert(val != NULL);
3878 free(val);
3879 }
3880
3881 memcached_free(memc_clone);
3882
3883 return TEST_SUCCESS;
3884 }
3885
3886 static test_return_t replication_get_test(memcached_st *memc)
3887 {
3888 memcached_return rc;
3889
3890 /*
3891 * Don't do the following in your code. I am abusing the internal details
3892 * within the library, and this is not a supported interface.
3893 * This is to verify correct behavior in the library
3894 */
3895 for (uint32_t host= 0; host < memc->number_of_hosts; ++host)
3896 {
3897 memcached_st *memc_clone= memcached_clone(NULL, memc);
3898 memc_clone->hosts[host].port= 0;
3899
3900 for (int x= 'a'; x <= 'z'; ++x)
3901 {
3902 char key[2]= { [0]= (char)x };
3903 size_t len;
3904 uint32_t flags;
3905 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
3906 &len, &flags, &rc);
3907 assert(rc == MEMCACHED_SUCCESS);
3908 assert(val != NULL);
3909 free(val);
3910 }
3911
3912 memcached_free(memc_clone);
3913 }
3914
3915 return TEST_SUCCESS;
3916 }
3917
3918 static test_return_t replication_mget_test(memcached_st *memc)
3919 {
3920 memcached_return rc;
3921 memcached_st *memc_clone= memcached_clone(NULL, memc);
3922 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3923
3924 const char *keys[]= { "bubba", "key1", "key2", "key3" };
3925 size_t len[]= { 5, 4, 4, 4 };
3926
3927 for (int x=0; x< 4; ++x)
3928 {
3929 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
3930 assert(rc == MEMCACHED_SUCCESS);
3931 }
3932
3933 /*
3934 ** We are using the quiet commands to store the replicas, so we need
3935 ** to ensure that all of them are processed before we can continue.
3936 ** In the test we go directly from storing the object to trying to
3937 ** receive the object from all of the different servers, so we
3938 ** could end up in a race condition (the memcached server hasn't yet
3939 ** processed the quiet command from the replication set when it process
3940 ** the request from the other client (created by the clone)). As a
3941 ** workaround for that we call memcached_quit to send the quit command
3942 ** to the server and wait for the response ;-) If you use the test code
3943 ** as an example for your own code, please note that you shouldn't need
3944 ** to do this ;-)
3945 */
3946 memcached_quit(memc);
3947
3948 /*
3949 * Don't do the following in your code. I am abusing the internal details
3950 * within the library, and this is not a supported interface.
3951 * This is to verify correct behavior in the library
3952 */
3953 memcached_result_st result_obj;
3954 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
3955 {
3956 memcached_st *new_clone= memcached_clone(NULL, memc);
3957 new_clone->hosts[host].port= 0;
3958
3959 for (int x= 'a'; x <= 'z'; ++x)
3960 {
3961 const char key[2]= { [0]= (const char)x };
3962
3963 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
3964 assert(rc == MEMCACHED_SUCCESS);
3965
3966 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
3967 assert(results);
3968
3969 int hits= 0;
3970 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
3971 {
3972 hits++;
3973 }
3974 assert(hits == 4);
3975 memcached_result_free(&result_obj);
3976 }
3977
3978 memcached_free(new_clone);
3979 }
3980
3981 memcached_free(memc_clone);
3982
3983 return TEST_SUCCESS;
3984 }
3985
3986 static test_return_t replication_delete_test(memcached_st *memc)
3987 {
3988 memcached_return rc;
3989 memcached_st *memc_clone= memcached_clone(NULL, memc);
3990 /* Delete the items from all of the servers except 1 */
3991 uint64_t repl= memcached_behavior_get(memc,
3992 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
3993 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
3994
3995 const char *keys[]= { "bubba", "key1", "key2", "key3" };
3996 size_t len[]= { 5, 4, 4, 4 };
3997
3998 for (int x=0; x< 4; ++x)
3999 {
4000 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4001 assert(rc == MEMCACHED_SUCCESS);
4002 }
4003
4004 /*
4005 * Don't do the following in your code. I am abusing the internal details
4006 * within the library, and this is not a supported interface.
4007 * This is to verify correct behavior in the library
4008 */
4009 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4010 for (uint32_t x= 0; x < (repl + 1); ++x)
4011 {
4012 memc_clone->hosts[hash].port= 0;
4013 if (++hash == memc_clone->number_of_hosts)
4014 hash= 0;
4015 }
4016
4017 memcached_result_st result_obj;
4018 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4019 {
4020 for (int x= 'a'; x <= 'z'; ++x)
4021 {
4022 const char key[2]= { [0]= (const char)x };
4023
4024 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4025 assert(rc == MEMCACHED_SUCCESS);
4026
4027 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4028 assert(results);
4029
4030 int hits= 0;
4031 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4032 {
4033 ++hits;
4034 }
4035 assert(hits == 4);
4036 memcached_result_free(&result_obj);
4037 }
4038 }
4039 memcached_free(memc_clone);
4040
4041 return TEST_SUCCESS;
4042 }
4043
4044 static void increment_request_id(uint16_t *id)
4045 {
4046 (*id)++;
4047 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4048 *id= 0;
4049 }
4050
4051 static uint16_t *get_udp_request_ids(memcached_st *memc)
4052 {
4053 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
4054 assert(ids != NULL);
4055 unsigned int x;
4056
4057 for (x= 0; x < memc->number_of_hosts; x++)
4058 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
4059
4060 return ids;
4061 }
4062
4063 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4064 {
4065 unsigned int x;
4066 memcached_server_st *cur_server = memc->hosts;
4067 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4068
4069 for (x= 0; x < memc->number_of_hosts; x++)
4070 {
4071 assert(cur_server[x].cursor_active == 0);
4072 assert(cur_req_ids[x] == expected_req_ids[x]);
4073 }
4074 free(expected_req_ids);
4075 free(cur_req_ids);
4076
4077 return TEST_SUCCESS;
4078 }
4079
4080 /*
4081 ** There is a little bit of a hack here, instead of removing
4082 ** the servers, I just set num host to 0 and them add then new udp servers
4083 **/
4084 static memcached_return init_udp(memcached_st *memc)
4085 {
4086 memcached_version(memc);
4087 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4088 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
4089 || memc->hosts[0].micro_version < 6)
4090 return MEMCACHED_FAILURE;
4091
4092 uint32_t num_hosts= memc->number_of_hosts;
4093 unsigned int x= 0;
4094 memcached_server_st servers[num_hosts];
4095 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
4096 for (x= 0; x < num_hosts; x++)
4097 memcached_server_free(&memc->hosts[x]);
4098
4099 memc->number_of_hosts= 0;
4100 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4101 for (x= 0; x < num_hosts; x++)
4102 {
4103 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4104 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4105 }
4106
4107 return MEMCACHED_SUCCESS;
4108 }
4109
4110 static memcached_return binary_init_udp(memcached_st *memc)
4111 {
4112 pre_binary(memc);
4113 return init_udp(memc);
4114 }
4115
4116 /* Make sure that I cant add a tcp server to a udp client */
4117 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4118 {
4119 memcached_server_st server;
4120 memcached_server_clone(&server, &memc->hosts[0]);
4121 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4122 assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4123 return TEST_SUCCESS;
4124 }
4125
4126 /* Make sure that I cant add a udp server to a tcp client */
4127 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4128 {
4129 memcached_server_st server;
4130 memcached_server_clone(&server, &memc->hosts[0]);
4131 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4132
4133 memcached_st tcp_client;
4134 memcached_create(&tcp_client);
4135 assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4136 return TEST_SUCCESS;
4137 }
4138
4139 static test_return_t set_udp_behavior_test(memcached_st *memc)
4140 {
4141
4142 memcached_quit(memc);
4143 memc->number_of_hosts= 0;
4144 run_distribution(memc);
4145 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4146 assert(memc->flags & MEM_USE_UDP);
4147 assert(memc->flags & MEM_NOREPLY);;
4148
4149 assert(memc->number_of_hosts == 0);
4150
4151 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4152 assert(!(memc->flags & MEM_USE_UDP));
4153 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4154 assert(!(memc->flags & MEM_NOREPLY));
4155 return TEST_SUCCESS;
4156 }
4157
4158 static test_return_t udp_set_test(memcached_st *memc)
4159 {
4160 unsigned int x= 0;
4161 unsigned int num_iters= 1025; //request id rolls over at 1024
4162 for (x= 0; x < num_iters;x++)
4163 {
4164 memcached_return rc;
4165 const char *key= "foo";
4166 const char *value= "when we sanitize";
4167 uint16_t *expected_ids= get_udp_request_ids(memc);
4168 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
4169 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4170 rc= memcached_set(memc, key, strlen(key),
4171 value, strlen(value),
4172 (time_t)0, (uint32_t)0);
4173 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4174 /** NB, the check below assumes that if new write_ptr is less than
4175 * the original write_ptr that we have flushed. For large payloads, this
4176 * maybe an invalid assumption, but for the small payload we have it is OK
4177 */
4178 if (rc == MEMCACHED_SUCCESS ||
4179 memc->hosts[server_key].write_buffer_offset < init_offset)
4180 increment_request_id(&expected_ids[server_key]);
4181
4182 if (rc == MEMCACHED_SUCCESS)
4183 {
4184 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4185 }
4186 else
4187 {
4188 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4189 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4190 }
4191 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4192 }
4193 return TEST_SUCCESS;
4194 }
4195
4196 static test_return_t udp_buffered_set_test(memcached_st *memc)
4197 {
4198 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4199 return udp_set_test(memc);
4200 }
4201
4202 static test_return_t udp_set_too_big_test(memcached_st *memc)
4203 {
4204 memcached_return rc;
4205 const char *key= "bar";
4206 char value[MAX_UDP_DATAGRAM_LENGTH];
4207 uint16_t *expected_ids= get_udp_request_ids(memc);
4208 rc= memcached_set(memc, key, strlen(key),
4209 value, MAX_UDP_DATAGRAM_LENGTH,
4210 (time_t)0, (uint32_t)0);
4211 assert(rc == MEMCACHED_WRITE_FAILURE);
4212 return post_udp_op_check(memc,expected_ids);
4213 }
4214
4215 static test_return_t udp_delete_test(memcached_st *memc)
4216 {
4217 unsigned int x= 0;
4218 unsigned int num_iters= 1025; //request id rolls over at 1024
4219 for (x= 0; x < num_iters;x++)
4220 {
4221 memcached_return rc;
4222 const char *key= "foo";
4223 uint16_t *expected_ids=get_udp_request_ids(memc);
4224 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4225 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4226 rc= memcached_delete(memc, key, strlen(key), 0);
4227 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4228 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
4229 increment_request_id(&expected_ids[server_key]);
4230 if (rc == MEMCACHED_SUCCESS)
4231 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4232 else
4233 {
4234 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4235 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4236 }
4237 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4238 }
4239 return TEST_SUCCESS;
4240 }
4241
4242 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4243 {
4244 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4245 return udp_delete_test(memc);
4246 }
4247
4248 static test_return_t udp_verbosity_test(memcached_st *memc)
4249 {
4250 memcached_return rc;
4251 uint16_t *expected_ids= get_udp_request_ids(memc);
4252 unsigned int x;
4253 for (x= 0; x < memc->number_of_hosts;x++)
4254 increment_request_id(&expected_ids[x]);
4255
4256 rc= memcached_verbosity(memc,3);
4257 assert(rc == MEMCACHED_SUCCESS);
4258 return post_udp_op_check(memc,expected_ids);
4259 }
4260
4261 static test_return_t udp_quit_test(memcached_st *memc)
4262 {
4263 uint16_t *expected_ids= get_udp_request_ids(memc);
4264 memcached_quit(memc);
4265 return post_udp_op_check(memc, expected_ids);
4266 }
4267
4268 static test_return_t udp_flush_test(memcached_st *memc)
4269 {
4270 memcached_return rc;
4271 uint16_t *expected_ids= get_udp_request_ids(memc);
4272 unsigned int x;
4273 for (x= 0; x < memc->number_of_hosts;x++)
4274 increment_request_id(&expected_ids[x]);
4275
4276 rc= memcached_flush(memc,0);
4277 assert(rc == MEMCACHED_SUCCESS);
4278 return post_udp_op_check(memc,expected_ids);
4279 }
4280
4281 static test_return_t udp_incr_test(memcached_st *memc)
4282 {
4283 memcached_return rc;
4284 const char *key= "incr";
4285 const char *value= "1";
4286 rc= memcached_set(memc, key, strlen(key),
4287 value, strlen(value),
4288 (time_t)0, (uint32_t)0);
4289
4290 assert(rc == MEMCACHED_SUCCESS);
4291 uint16_t *expected_ids= get_udp_request_ids(memc);
4292 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4293 increment_request_id(&expected_ids[server_key]);
4294 uint64_t newvalue;
4295 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4296 assert(rc == MEMCACHED_SUCCESS);
4297 return post_udp_op_check(memc, expected_ids);
4298 }
4299
4300 static test_return_t udp_decr_test(memcached_st *memc)
4301 {
4302 memcached_return rc;
4303 const char *key= "decr";
4304 const char *value= "1";
4305 rc= memcached_set(memc, key, strlen(key),
4306 value, strlen(value),
4307 (time_t)0, (uint32_t)0);
4308
4309 assert(rc == MEMCACHED_SUCCESS);
4310 uint16_t *expected_ids= get_udp_request_ids(memc);
4311 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4312 increment_request_id(&expected_ids[server_key]);
4313 uint64_t newvalue;
4314 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4315 assert(rc == MEMCACHED_SUCCESS);
4316 return post_udp_op_check(memc, expected_ids);
4317 }
4318
4319
4320 static test_return_t udp_stat_test(memcached_st *memc)
4321 {
4322 memcached_stat_st * rv= NULL;
4323 memcached_return rc;
4324 char args[]= "";
4325 uint16_t *expected_ids = get_udp_request_ids(memc);
4326 rv = memcached_stat(memc, args, &rc);
4327 free(rv);
4328 assert(rc == MEMCACHED_NOT_SUPPORTED);
4329 return post_udp_op_check(memc, expected_ids);
4330 }
4331
4332 static test_return_t udp_version_test(memcached_st *memc)
4333 {
4334 memcached_return rc;
4335 uint16_t *expected_ids = get_udp_request_ids(memc);
4336 rc = memcached_version(memc);
4337 assert(rc == MEMCACHED_NOT_SUPPORTED);
4338 return post_udp_op_check(memc, expected_ids);
4339 }
4340
4341 static test_return_t udp_get_test(memcached_st *memc)
4342 {
4343 memcached_return rc;
4344 const char *key= "foo";
4345 size_t vlen;
4346 uint16_t *expected_ids = get_udp_request_ids(memc);
4347 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4348 assert(rc == MEMCACHED_NOT_SUPPORTED);
4349 assert(val == NULL);
4350 return post_udp_op_check(memc, expected_ids);
4351 }
4352
4353 static test_return_t udp_mixed_io_test(memcached_st *memc)
4354 {
4355 test_st current_op;
4356 test_st mixed_io_ops [] ={
4357 {"udp_set_test", 0, udp_set_test},
4358 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4359 {"udp_delete_test", 0, udp_delete_test},
4360 {"udp_verbosity_test", 0, udp_verbosity_test},
4361 {"udp_quit_test", 0, udp_quit_test},
4362 {"udp_flush_test", 0, udp_flush_test},
4363 {"udp_incr_test", 0, udp_incr_test},
4364 {"udp_decr_test", 0, udp_decr_test},
4365 {"udp_version_test", 0, udp_version_test}
4366 };
4367 unsigned int x= 0;
4368 for (x= 0; x < 500; x++)
4369 {
4370 current_op= mixed_io_ops[random() % 9];
4371 assert(current_op.function(memc) == TEST_SUCCESS);
4372 }
4373 return TEST_SUCCESS;
4374 }
4375
4376 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4377 {
4378 memcached_return expected_rc= MEMCACHED_FAILURE;
4379 #ifdef HAVE_HSIEH_HASH
4380 expected_rc= MEMCACHED_SUCCESS;
4381 #endif
4382 memcached_return rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4383 (uint64_t)MEMCACHED_HASH_HSIEH);
4384 assert(rc == expected_rc);
4385 return TEST_SUCCESS;
4386 }
4387
4388 static const char *list[]=
4389 {
4390 "apple",
4391 "beat",
4392 "carrot",
4393 "daikon",
4394 "eggplant",
4395 "flower",
4396 "green",
4397 "hide",
4398 "ick",
4399 "jack",
4400 "kick",
4401 "lime",
4402 "mushrooms",
4403 "nectarine",
4404 "orange",
4405 "peach",
4406 "quant",
4407 "ripen",
4408 "strawberry",
4409 "tang",
4410 "up",
4411 "volumne",
4412 "when",
4413 "yellow",
4414 "zip",
4415 NULL
4416 };
4417
4418 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4419 {
4420 uint32_t x;
4421 const char **ptr;
4422 uint32_t values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
4423 245758794U, 2550894432U, 121710495U, 3053817768U,
4424 1250994555U, 1862072655U, 2631955953U, 2951528551U,
4425 1451250070U, 2820856945U, 2060845566U, 3646985608U,
4426 2138080750U, 217675895U, 2230934345U, 1234361223U,
4427 3968582726U, 2455685270U, 1293568479U, 199067604U,
4428 2042482093U };
4429
4430
4431 for (ptr= list, x= 0; *ptr; ptr++, x++)
4432 {
4433 uint32_t hash_val;
4434
4435 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4436 assert(values[x] == hash_val);
4437 }
4438
4439 return TEST_SUCCESS;
4440 }
4441
4442 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4443 {
4444 uint32_t x;
4445 const char **ptr;
4446 uint32_t values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
4447 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
4448 7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
4449 17300U, 28156U, 9192U, 20484U, 16925U };
4450
4451 for (ptr= list, x= 0; *ptr; ptr++, x++)
4452 {
4453 uint32_t hash_val;
4454
4455 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4456 assert(values[x] == hash_val);
4457 }
4458
4459 return TEST_SUCCESS;
4460 }
4461
4462 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4463 {
4464 uint32_t x;
4465 const char **ptr;
4466 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4467 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4468 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4469 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4470 2815549194U, 2562818319U, 224996066U, 2680194749U,
4471 3035305390U, 246890365U, 2395624193U, 4145193337U,
4472 1801941682U };
4473
4474 for (ptr= list, x= 0; *ptr; ptr++, x++)
4475 {
4476 uint32_t hash_val;
4477
4478 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4479 assert(values[x] == hash_val);
4480 }
4481
4482 return TEST_SUCCESS;
4483 }
4484
4485 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4486 {
4487 uint32_t x;
4488 const char **ptr;
4489 uint32_t values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
4490 3647689787U, 3241528582U, 1669328060U, 2604311949U,
4491 734810122U, 1516407546U, 560948863U, 1767346780U,
4492 561034892U, 4156330026U, 3716417003U, 3475297030U,
4493 1518272172U, 227211583U, 3938128828U, 126112909U,
4494 3043416448U, 3131561933U, 1328739897U, 2455664041U,
4495 2272238452U };
4496
4497 for (ptr= list, x= 0; *ptr; ptr++, x++)
4498 {
4499 uint32_t hash_val;
4500
4501 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4502 assert(values[x] == hash_val);
4503 }
4504
4505 return TEST_SUCCESS;
4506 }
4507
4508 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4509 {
4510 uint32_t x;
4511 const char **ptr;
4512 uint32_t values[]= { 67176023U, 1190179409U, 2043204404U, 3221866419U,
4513 2567703427U, 3787535528U, 4147287986U, 3500475733U,
4514 344481048U, 3865235296U, 2181839183U, 119581266U,
4515 510234242U, 4248244304U, 1362796839U, 103389328U,
4516 1449620010U, 182962511U, 3554262370U, 3206747549U,
4517 1551306158U, 4127558461U, 1889140833U, 2774173721U,
4518 1180552018U };
4519
4520
4521 for (ptr= list, x= 0; *ptr; ptr++, x++)
4522 {
4523 uint32_t hash_val;
4524
4525 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4526 assert(values[x] == hash_val);
4527 }
4528
4529 return TEST_SUCCESS;
4530 }
4531
4532 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4533 {
4534 uint32_t x;
4535 const char **ptr;
4536 uint32_t values[]= { 280767167U, 2421315013U, 3072375666U, 855001899U,
4537 459261019U, 3521085446U, 18738364U, 1625305005U,
4538 2162232970U, 777243802U, 3323728671U, 132336572U,
4539 3654473228U, 260679466U, 1169454059U, 2698319462U,
4540 1062177260U, 235516991U, 2218399068U, 405302637U,
4541 1128467232U, 3579622413U, 2138539289U, 96429129U,
4542 2877453236U };
4543
4544 for (ptr= list, x= 0; *ptr; ptr++, x++)
4545 {
4546 uint32_t hash_val;
4547
4548 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4549 assert(values[x] == hash_val);
4550 }
4551
4552 return TEST_SUCCESS;
4553 }
4554
4555 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4556 {
4557 uint32_t x;
4558 const char **ptr;
4559 #ifdef HAVE_HSIEH_HASH
4560 uint32_t values[]= { 3738850110, 3636226060, 3821074029, 3489929160, 3485772682, 80540287,
4561 1805464076, 1895033657, 409795758, 979934958, 3634096985, 1284445480,
4562 2265380744, 707972988, 353823508, 1549198350, 1327930172, 9304163,
4563 4220749037, 2493964934, 2777873870, 2057831732, 1510213931, 2027828987,
4564 3395453351 };
4565 #else
4566 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 };
4567 #endif
4568
4569 for (ptr= list, x= 0; *ptr; ptr++, x++)
4570 {
4571 uint32_t hash_val;
4572
4573 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4574 assert(values[x] == hash_val);
4575 }
4576
4577 return TEST_SUCCESS;
4578 }
4579
4580 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4581 {
4582 uint32_t x;
4583 const char **ptr;
4584 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4585 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4586 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4587 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4588 2815549194U, 2562818319U, 224996066U, 2680194749U,
4589 3035305390U, 246890365U, 2395624193U, 4145193337U,
4590 1801941682U };
4591
4592 for (ptr= list, x= 0; *ptr; ptr++, x++)
4593 {
4594 uint32_t hash_val;
4595
4596 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4597 assert(values[x] == hash_val);
4598 }
4599
4600 return TEST_SUCCESS;
4601 }
4602
4603 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4604 {
4605 uint32_t x;
4606 const char **ptr;
4607 uint32_t values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U,
4608 3261968576U, 3515188778U, 4232909173U, 4288625128U,
4609 1812047395U, 3689182164U, 2502979932U, 1214050606U,
4610 2415988847U, 1494268927U, 1025545760U, 3920481083U,
4611 4153263658U, 3824871822U, 3072759809U, 798622255U,
4612 3065432577U, 1453328165U, 2691550971U, 3408888387U,
4613 2629893356U };
4614
4615
4616 for (ptr= list, x= 0; *ptr; ptr++, x++)
4617 {
4618 uint32_t hash_val;
4619
4620 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4621 assert(values[x] == hash_val);
4622 }
4623
4624 return TEST_SUCCESS;
4625 }
4626
4627 static test_return_t regression_bug_434484(memcached_st *memc)
4628 {
4629 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4630 return TEST_SKIPPED;
4631
4632 memcached_return ret;
4633 const char *key= "regression_bug_434484";
4634 size_t keylen= strlen(key);
4635
4636 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
4637 assert(ret == MEMCACHED_NOTSTORED);
4638
4639 size_t size= 2048 * 1024;
4640 void *data= calloc(1, size);
4641 assert(data != NULL);
4642 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
4643 assert(ret == MEMCACHED_E2BIG);
4644 free(data);
4645
4646 return TEST_SUCCESS;
4647 }
4648
4649 static test_return_t regression_bug_434843(memcached_st *memc)
4650 {
4651 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4652 return TEST_SKIPPED;
4653
4654 memcached_return rc;
4655 unsigned int counter= 0;
4656 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
4657
4658 /*
4659 * I only want to hit only _one_ server so I know the number of requests I'm
4660 * sending in the pipleine to the server. Let's try to do a multiget of
4661 * 1024 (that should satisfy most users don't you think?). Future versions
4662 * will include a mget_execute function call if you need a higher number.
4663 */
4664 uint32_t number_of_hosts= memc->number_of_hosts;
4665 memc->number_of_hosts= 1;
4666 const size_t max_keys= 1024;
4667 char **keys= calloc(max_keys, sizeof(char*));
4668 size_t *key_length=calloc(max_keys, sizeof(size_t));
4669
4670 for (int x= 0; x < (int)max_keys; ++x)
4671 {
4672 char k[251];
4673 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
4674 keys[x]= strdup(k);
4675 assert(keys[x] != NULL);
4676 }
4677
4678 /*
4679 * Run two times.. the first time we should have 100% cache miss,
4680 * and the second time we should have 100% cache hits
4681 */
4682 for (int y= 0; y < 2; ++y)
4683 {
4684 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
4685 assert(rc == MEMCACHED_SUCCESS);
4686 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
4687 if (y == 0)
4688 {
4689 /* The first iteration should give me a 100% cache miss. verify that*/
4690 assert(counter == 0);
4691 char blob[1024]= { 0 };
4692 for (int x= 0; x < (int)max_keys; ++x)
4693 {
4694 rc= memcached_add(memc, keys[x], key_length[x],
4695 blob, sizeof(blob), 0, 0);
4696 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4697 }
4698 }
4699 else
4700 {
4701 /* Verify that we received all of the key/value pairs */
4702 assert(counter == (unsigned int)max_keys);
4703 }
4704 }
4705
4706 /* Release allocated resources */
4707 for (size_t x= 0; x < max_keys; ++x)
4708 free(keys[x]);
4709 free(keys);
4710 free(key_length);
4711
4712 memc->number_of_hosts= number_of_hosts;
4713 return TEST_SUCCESS;
4714 }
4715
4716 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
4717 {
4718 memcached_return rc;
4719 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4720 assert(rc == MEMCACHED_SUCCESS);
4721
4722 return regression_bug_434843(memc);
4723 }
4724
4725 static test_return_t regression_bug_421108(memcached_st *memc)
4726 {
4727 memcached_return rc;
4728 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
4729 assert(rc == MEMCACHED_SUCCESS);
4730
4731 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
4732 assert(rc == MEMCACHED_SUCCESS);
4733 assert(bytes != NULL);
4734 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
4735 "bytes_read", &rc);
4736 assert(rc == MEMCACHED_SUCCESS);
4737 assert(bytes_read != NULL);
4738
4739 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
4740 "bytes_written", &rc);
4741 assert(rc == MEMCACHED_SUCCESS);
4742 assert(bytes_written != NULL);
4743
4744 assert(strcmp(bytes, bytes_read) != 0);
4745 assert(strcmp(bytes, bytes_written) != 0);
4746
4747 /* Release allocated resources */
4748 free(bytes);
4749 free(bytes_read);
4750 free(bytes_written);
4751 memcached_stat_free(NULL, memc_stat);
4752 return TEST_SUCCESS;
4753 }
4754
4755 /*
4756 * The test case isn't obvious so I should probably document why
4757 * it works the way it does. Bug 442914 was caused by a bug
4758 * in the logic in memcached_purge (it did not handle the case
4759 * where the number of bytes sent was equal to the watermark).
4760 * In this test case, create messages so that we hit that case
4761 * and then disable noreply mode and issue a new command to
4762 * verify that it isn't stuck. If we change the format for the
4763 * delete command or the watermarks, we need to update this
4764 * test....
4765 */
4766 static test_return_t regression_bug_442914(memcached_st *memc)
4767 {
4768 memcached_return rc;
4769 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4770 assert(rc == MEMCACHED_SUCCESS);
4771 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
4772
4773 uint32_t number_of_hosts= memc->number_of_hosts;
4774 memc->number_of_hosts= 1;
4775
4776 char k[250];
4777 size_t len;
4778
4779 for (int x= 0; x < 250; ++x)
4780 {
4781 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
4782 rc= memcached_delete(memc, k, len, 0);
4783 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4784 }
4785
4786 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
4787 rc= memcached_delete(memc, k, len, 0);
4788 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4789
4790 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
4791 assert(rc == MEMCACHED_SUCCESS);
4792 rc= memcached_delete(memc, k, len, 0);
4793 assert(rc == MEMCACHED_NOTFOUND);
4794
4795 memc->number_of_hosts= number_of_hosts;
4796
4797 return TEST_SUCCESS;
4798 }
4799
4800 static test_return_t regression_bug_447342(memcached_st *memc)
4801 {
4802 if (memc->number_of_hosts < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
4803 return TEST_SKIPPED;
4804
4805 memcached_return rc;
4806
4807 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
4808 assert(rc == MEMCACHED_SUCCESS);
4809
4810 const size_t max_keys= 100;
4811 char **keys= calloc(max_keys, sizeof(char*));
4812 size_t *key_length=calloc(max_keys, sizeof(size_t));
4813
4814 for (int x= 0; x < (int)max_keys; ++x)
4815 {
4816 char k[251];
4817 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
4818 keys[x]= strdup(k);
4819 assert(keys[x] != NULL);
4820 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
4821 assert(rc == MEMCACHED_SUCCESS);
4822 }
4823
4824 /*
4825 ** We are using the quiet commands to store the replicas, so we need
4826 ** to ensure that all of them are processed before we can continue.
4827 ** In the test we go directly from storing the object to trying to
4828 ** receive the object from all of the different servers, so we
4829 ** could end up in a race condition (the memcached server hasn't yet
4830 ** processed the quiet command from the replication set when it process
4831 ** the request from the other client (created by the clone)). As a
4832 ** workaround for that we call memcached_quit to send the quit command
4833 ** to the server and wait for the response ;-) If you use the test code
4834 ** as an example for your own code, please note that you shouldn't need
4835 ** to do this ;-)
4836 */
4837 memcached_quit(memc);
4838
4839 /* Verify that all messages are stored, and we didn't stuff too much
4840 * into the servers
4841 */
4842 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
4843 assert(rc == MEMCACHED_SUCCESS);
4844
4845 unsigned int counter= 0;
4846 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
4847 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
4848 /* Verify that we received all of the key/value pairs */
4849 assert(counter == (unsigned int)max_keys);
4850
4851 memcached_quit(memc);
4852 /*
4853 * Don't do the following in your code. I am abusing the internal details
4854 * within the library, and this is not a supported interface.
4855 * This is to verify correct behavior in the library. Fake that two servers
4856 * are dead..
4857 */
4858 unsigned int port0= memc->hosts[0].port;
4859 unsigned int port2= memc->hosts[2].port;
4860 memc->hosts[0].port= 0;
4861 memc->hosts[2].port= 0;
4862
4863 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
4864 assert(rc == MEMCACHED_SUCCESS);
4865
4866 counter= 0;
4867 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
4868 assert(counter == (unsigned int)max_keys);
4869
4870 /* restore the memc handle */
4871 memc->hosts[0].port= port0;
4872 memc->hosts[2].port= port2;
4873
4874 memcached_quit(memc);
4875
4876 /* Remove half of the objects */
4877 for (int x= 0; x < (int)max_keys; ++x)
4878 if (x & 1)
4879 {
4880 rc= memcached_delete(memc, keys[x], key_length[x], 0);
4881 assert(rc == MEMCACHED_SUCCESS);
4882 }
4883
4884 memcached_quit(memc);
4885 memc->hosts[0].port= 0;
4886 memc->hosts[2].port= 0;
4887
4888 /* now retry the command, this time we should have cache misses */
4889 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
4890 assert(rc == MEMCACHED_SUCCESS);
4891
4892 counter= 0;
4893 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
4894 assert(counter == (unsigned int)(max_keys >> 1));
4895
4896 /* Release allocated resources */
4897 for (size_t x= 0; x < max_keys; ++x)
4898 free(keys[x]);
4899 free(keys);
4900 free(key_length);
4901
4902 /* restore the memc handle */
4903 memc->hosts[0].port= port0;
4904 memc->hosts[2].port= port2;
4905 return TEST_SUCCESS;
4906 }
4907
4908 /* Test memcached_server_get_last_disconnect
4909 * For a working server set, shall be NULL
4910 * For a set of non existing server, shall not be NULL
4911 */
4912 static test_return_t test_get_last_disconnect(memcached_st *memc)
4913 {
4914 memcached_return rc;
4915 memcached_server_st *disconnected_server;
4916
4917 /* With the working set of server */
4918 const char *key= "marmotte";
4919 const char *value= "milka";
4920
4921 rc= memcached_set(memc, key, strlen(key),
4922 value, strlen(value),
4923 (time_t)0, (uint32_t)0);
4924 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4925
4926 disconnected_server = memcached_server_get_last_disconnect(memc);
4927 assert(disconnected_server == NULL);
4928
4929 /* With a non existing server */
4930 memcached_st *mine;
4931 memcached_server_st *servers;
4932
4933 const char *server_list= "localhost:9";
4934
4935 servers= memcached_servers_parse(server_list);
4936 assert(servers);
4937 mine= memcached_create(NULL);
4938 rc= memcached_server_push(mine, servers);
4939 assert(rc == MEMCACHED_SUCCESS);
4940 memcached_server_list_free(servers);
4941 assert(mine);
4942
4943 rc= memcached_set(mine, key, strlen(key),
4944 value, strlen(value),
4945 (time_t)0, (uint32_t)0);
4946 assert(rc != MEMCACHED_SUCCESS);
4947
4948 disconnected_server = memcached_server_get_last_disconnect(mine);
4949 assert(disconnected_server != NULL);
4950 assert(disconnected_server->port == 9);
4951 assert(strncmp(disconnected_server->hostname,"localhost",9) == 0);
4952
4953 memcached_quit(mine);
4954 memcached_free(mine);
4955
4956 return TEST_SUCCESS;
4957 }
4958
4959 /*
4960 * This test ensures that the failure counter isn't incremented during
4961 * normal termination of the memcached instance.
4962 */
4963 static test_return_t wrong_failure_counter_test(memcached_st *memc)
4964 {
4965 memcached_return rc;
4966
4967 /* Set value to force connection to the server */
4968 const char *key= "marmotte";
4969 const char *value= "milka";
4970
4971 /*
4972 * Please note that I'm abusing the internal structures in libmemcached
4973 * in a non-portable way and you shouldn't be doing this. I'm only
4974 * doing this in order to verify that the library works the way it should
4975 */
4976 uint32_t number_of_hosts= memc->number_of_hosts;
4977 memc->number_of_hosts= 1;
4978
4979 /* Ensure that we are connected to the server by setting a value */
4980 rc= memcached_set(memc, key, strlen(key),
4981 value, strlen(value),
4982 (time_t)0, (uint32_t)0);
4983 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4984
4985
4986 /* The test is to see that the memcached_quit doesn't increase the
4987 * the server failure conter, so let's ensure that it is zero
4988 * before sending quit
4989 */
4990 memc->hosts[0].server_failure_counter= 0;
4991
4992 memcached_quit(memc);
4993
4994 /* Verify that it memcached_quit didn't increment the failure counter
4995 * Please note that this isn't bullet proof, because an error could
4996 * occur...
4997 */
4998 assert(memc->hosts[0].server_failure_counter == 0);
4999
5000 /* restore the instance */
5001 memc->number_of_hosts= number_of_hosts;
5002
5003 return TEST_SUCCESS;
5004 }
5005
5006 test_st udp_setup_server_tests[] ={
5007 {"set_udp_behavior_test", 0, set_udp_behavior_test},
5008 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
5009 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
5010 {0, 0, 0}
5011 };
5012
5013 test_st upd_io_tests[] ={
5014 {"udp_set_test", 0, udp_set_test},
5015 {"udp_buffered_set_test", 0, udp_buffered_set_test},
5016 {"udp_set_too_big_test", 0, udp_set_too_big_test},
5017 {"udp_delete_test", 0, udp_delete_test},
5018 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
5019 {"udp_verbosity_test", 0, udp_verbosity_test},
5020 {"udp_quit_test", 0, udp_quit_test},
5021 {"udp_flush_test", 0, udp_flush_test},
5022 {"udp_incr_test", 0, udp_incr_test},
5023 {"udp_decr_test", 0, udp_decr_test},
5024 {"udp_stat_test", 0, udp_stat_test},
5025 {"udp_version_test", 0, udp_version_test},
5026 {"udp_get_test", 0, udp_get_test},
5027 {"udp_mixed_io_test", 0, udp_mixed_io_test},
5028 {0, 0, 0}
5029 };
5030
5031 /* Clean the server before beginning testing */
5032 test_st tests[] ={
5033 {"flush", 0, flush_test },
5034 {"init", 0, init_test },
5035 {"allocation", 0, allocation_test },
5036 {"server_list_null_test", 0, server_list_null_test},
5037 {"server_unsort", 0, server_unsort_test},
5038 {"server_sort", 0, server_sort_test},
5039 {"server_sort2", 0, server_sort2_test},
5040 {"clone_test", 0, clone_test },
5041 {"connection_test", 0, connection_test},
5042 {"callback_test", 0, callback_test},
5043 {"behavior_test", 0, behavior_test},
5044 {"userdata_test", 0, userdata_test},
5045 {"error", 0, error_test },
5046 {"set", 0, set_test },
5047 {"set2", 0, set_test2 },
5048 {"set3", 0, set_test3 },
5049 {"dump", 1, dump_test},
5050 {"add", 1, add_test },
5051 {"replace", 1, replace_test },
5052 {"delete", 1, delete_test },
5053 {"get", 1, get_test },
5054 {"get2", 0, get_test2 },
5055 {"get3", 0, get_test3 },
5056 {"get4", 0, get_test4 },
5057 {"partial mget", 0, get_test5 },
5058 {"stats_servername", 0, stats_servername_test },
5059 {"increment", 0, increment_test },
5060 {"increment_with_initial", 1, increment_with_initial_test },
5061 {"decrement", 0, decrement_test },
5062 {"decrement_with_initial", 1, decrement_with_initial_test },
5063 {"quit", 0, quit_test },
5064 {"mget", 1, mget_test },
5065 {"mget_result", 1, mget_result_test },
5066 {"mget_result_alloc", 1, mget_result_alloc_test },
5067 {"mget_result_function", 1, mget_result_function },
5068 {"mget_execute", 1, mget_execute },
5069 {"mget_end", 0, mget_end },
5070 {"get_stats", 0, get_stats },
5071 {"add_host_test", 0, add_host_test },
5072 {"add_host_test_1", 0, add_host_test1 },
5073 {"get_stats_keys", 0, get_stats_keys },
5074 {"behavior_test", 0, get_stats_keys },
5075 {"callback_test", 0, get_stats_keys },
5076 {"version_string_test", 0, version_string_test},
5077 {"bad_key", 1, bad_key_test },
5078 {"memcached_server_cursor", 1, memcached_server_cursor_test },
5079 {"read_through", 1, read_through },
5080 {"delete_through", 1, delete_through },
5081 {"noreply", 1, noreply_test},
5082 {"analyzer", 1, analyzer_test},
5083 #ifdef HAVE_LIBMEMCACHEDUTIL
5084 {"connectionpool", 1, connection_pool_test },
5085 #endif
5086 {"test_get_last_disconnect", 1, test_get_last_disconnect},
5087 {0, 0, 0}
5088 };
5089
5090 test_st async_tests[] ={
5091 {"add", 1, add_wrapper },
5092 {0, 0, 0}
5093 };
5094
5095 test_st string_tests[] ={
5096 {"string static with null", 0, string_static_null },
5097 {"string alloc with null", 0, string_alloc_null },
5098 {"string alloc with 1K", 0, string_alloc_with_size },
5099 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
5100 {"string append", 0, string_alloc_append },
5101 {"string append failure (too big)", 0, string_alloc_append_toobig },
5102 {0, 0, 0}
5103 };
5104
5105 test_st result_tests[] ={
5106 {"result static", 0, result_static},
5107 {"result alloc", 0, result_alloc},
5108 {0, 0, 0}
5109 };
5110
5111 test_st version_1_2_3[] ={
5112 {"append", 0, append_test },
5113 {"prepend", 0, prepend_test },
5114 {"cas", 0, cas_test },
5115 {"cas2", 0, cas2_test },
5116 {"append_binary", 0, append_binary_test },
5117 {0, 0, 0}
5118 };
5119
5120 test_st user_tests[] ={
5121 {"user_supplied_bug1", 0, user_supplied_bug1 },
5122 {"user_supplied_bug2", 0, user_supplied_bug2 },
5123 {"user_supplied_bug3", 0, user_supplied_bug3 },
5124 {"user_supplied_bug4", 0, user_supplied_bug4 },
5125 {"user_supplied_bug5", 1, user_supplied_bug5 },
5126 {"user_supplied_bug6", 1, user_supplied_bug6 },
5127 {"user_supplied_bug7", 1, user_supplied_bug7 },
5128 {"user_supplied_bug8", 1, user_supplied_bug8 },
5129 {"user_supplied_bug9", 1, user_supplied_bug9 },
5130 {"user_supplied_bug10", 1, user_supplied_bug10 },
5131 {"user_supplied_bug11", 1, user_supplied_bug11 },
5132 {"user_supplied_bug12", 1, user_supplied_bug12 },
5133 {"user_supplied_bug13", 1, user_supplied_bug13 },
5134 {"user_supplied_bug14", 1, user_supplied_bug14 },
5135 {"user_supplied_bug15", 1, user_supplied_bug15 },
5136 {"user_supplied_bug16", 1, user_supplied_bug16 },
5137 #ifndef __sun
5138 /*
5139 ** It seems to be something weird with the character sets..
5140 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5141 ** guess I need to find out how this is supposed to work.. Perhaps I need
5142 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5143 ** so just disable the code for now...).
5144 */
5145 {"user_supplied_bug17", 1, user_supplied_bug17 },
5146 #endif
5147 {"user_supplied_bug18", 1, user_supplied_bug18 },
5148 {"user_supplied_bug19", 1, user_supplied_bug19 },
5149 {"user_supplied_bug20", 1, user_supplied_bug20 },
5150 {"user_supplied_bug21", 1, user_supplied_bug21 },
5151 {"wrong_failure_counter_test", 1, wrong_failure_counter_test},
5152 {0, 0, 0}
5153 };
5154
5155 test_st replication_tests[]= {
5156 {"set", 1, replication_set_test },
5157 {"get", 0, replication_get_test },
5158 {"mget", 0, replication_mget_test },
5159 {"delete", 0, replication_delete_test },
5160 {0, 0, 0}
5161 };
5162
5163 /*
5164 * The following test suite is used to verify that we don't introduce
5165 * regression bugs. If you want more information about the bug / test,
5166 * you should look in the bug report at
5167 * http://bugs.launchpad.net/libmemcached
5168 */
5169 test_st regression_tests[]= {
5170 {"lp:434484", 1, regression_bug_434484 },
5171 {"lp:434843", 1, regression_bug_434843 },
5172 {"lp:434843 buffered", 1, regression_bug_434843_buffered },
5173 {"lp:421108", 1, regression_bug_421108 },
5174 {"lp:442914", 1, regression_bug_442914 },
5175 {"lp:447342", 1, regression_bug_447342 },
5176 {0, 0, 0}
5177 };
5178
5179 test_st generate_tests[] ={
5180 {"generate_pairs", 1, generate_pairs },
5181 {"generate_data", 1, generate_data },
5182 {"get_read", 0, get_read },
5183 {"delete_generate", 0, delete_generate },
5184 {"generate_buffer_data", 1, generate_buffer_data },
5185 {"delete_buffer", 0, delete_buffer_generate},
5186 {"generate_data", 1, generate_data },
5187 {"mget_read", 0, mget_read },
5188 {"mget_read_result", 0, mget_read_result },
5189 {"mget_read_function", 0, mget_read_function },
5190 {"cleanup", 1, cleanup_pairs },
5191 {"generate_large_pairs", 1, generate_large_pairs },
5192 {"generate_data", 1, generate_data },
5193 {"generate_buffer_data", 1, generate_buffer_data },
5194 {"cleanup", 1, cleanup_pairs },
5195 {0, 0, 0}
5196 };
5197
5198 test_st consistent_tests[] ={
5199 {"generate_pairs", 1, generate_pairs },
5200 {"generate_data", 1, generate_data },
5201 {"get_read", 0, get_read_count },
5202 {"cleanup", 1, cleanup_pairs },
5203 {0, 0, 0}
5204 };
5205
5206 test_st consistent_weighted_tests[] ={
5207 {"generate_pairs", 1, generate_pairs },
5208 {"generate_data", 1, generate_data_with_stats },
5209 {"get_read", 0, get_read_count },
5210 {"cleanup", 1, cleanup_pairs },
5211 {0, 0, 0}
5212 };
5213
5214 test_st hsieh_availability[] ={
5215 {"hsieh_avaibility_test",0,hsieh_avaibility_test},
5216 {0, 0, 0}
5217 };
5218
5219 test_st ketama_auto_eject_hosts[] ={
5220 {"auto_eject_hosts", 1, auto_eject_hosts },
5221 {0, 0, 0}
5222 };
5223
5224 test_st hash_tests[] ={
5225 {"md5", 0, md5_run },
5226 {"crc", 0, crc_run },
5227 {"fnv1_64", 0, fnv1_64_run },
5228 {"fnv1a_64", 0, fnv1a_64_run },
5229 {"fnv1_32", 0, fnv1_32_run },
5230 {"fnv1a_32", 0, fnv1a_32_run },
5231 {"hsieh", 0, hsieh_run },
5232 {"murmur", 0, murmur_run },
5233 {"jenkis", 0, jenkins_run },
5234 {0, 0, 0}
5235 };
5236
5237 collection_st collection[] ={
5238 {"hsieh_availability",0,0,hsieh_availability},
5239 {"udp_setup", init_udp, 0, udp_setup_server_tests},
5240 {"udp_io", init_udp, 0, upd_io_tests},
5241 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
5242 {"block", 0, 0, tests},
5243 {"binary", pre_binary, 0, tests},
5244 {"nonblock", pre_nonblock, 0, tests},
5245 {"nodelay", pre_nodelay, 0, tests},
5246 {"settimer", pre_settimer, 0, tests},
5247 {"md5", pre_md5, 0, tests},
5248 {"crc", pre_crc, 0, tests},
5249 {"hsieh", pre_hsieh, 0, tests},
5250 {"jenkins", pre_jenkins, 0, tests},
5251 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
5252 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
5253 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
5254 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
5255 {"ketama", pre_behavior_ketama, 0, tests},
5256 {"ketama_auto_eject_hosts", pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5257 {"unix_socket", pre_unix_socket, 0, tests},
5258 {"unix_socket_nodelay", pre_nodelay, 0, tests},
5259 {"poll_timeout", poll_timeout, 0, tests},
5260 {"gets", enable_cas, 0, tests},
5261 {"consistent", enable_consistent, 0, tests},
5262 #ifdef MEMCACHED_ENABLE_DEPRECATED
5263 {"deprecated_memory_allocators", deprecated_set_memory_alloc, 0, tests},
5264 #endif
5265 {"memory_allocators", set_memory_alloc, 0, tests},
5266 {"prefix", set_prefix, 0, tests},
5267 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
5268 {"string", 0, 0, string_tests},
5269 {"result", 0, 0, result_tests},
5270 {"async", pre_nonblock, 0, async_tests},
5271 {"async_binary", pre_nonblock_binary, 0, async_tests},
5272 {"user", 0, 0, user_tests},
5273 {"generate", 0, 0, generate_tests},
5274 {"generate_hsieh", pre_hsieh, 0, generate_tests},
5275 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
5276 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
5277 {"generate_md5", pre_md5, 0, generate_tests},
5278 {"generate_murmur", pre_murmur, 0, generate_tests},
5279 {"generate_jenkins", pre_jenkins, 0, generate_tests},
5280 {"generate_nonblock", pre_nonblock, 0, generate_tests},
5281 {"consistent_not", 0, 0, consistent_tests},
5282 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
5283 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5284 {"test_hashes", 0, 0, hash_tests},
5285 {"replication", pre_replication, 0, replication_tests},
5286 {"replication_noblock", pre_replication_noblock, 0, replication_tests},
5287 {"regression", 0, 0, regression_tests},
5288 {0, 0, 0, 0}
5289 };
5290
5291 #define SERVERS_TO_CREATE 5
5292
5293 /* Prototypes for functions we will pass to test framework */
5294 void *world_create(void);
5295 void world_destroy(void *p);
5296
5297 void *world_create(void)
5298 {
5299 server_startup_st *construct;
5300
5301 construct= calloc(sizeof(server_startup_st), 1);
5302 construct->count= SERVERS_TO_CREATE;
5303 construct->udp= 0;
5304 server_startup(construct);
5305
5306 return construct;
5307 }
5308
5309
5310 void world_destroy(void *p)
5311 {
5312 server_startup_st *construct= (server_startup_st *)p;
5313 memcached_server_st *servers= (memcached_server_st *)construct->servers;
5314 memcached_server_list_free(servers);
5315
5316 server_shutdown(construct);
5317 free(construct);
5318 }
5319
5320 void get_world(world_st *world)
5321 {
5322 world->collections= collection;
5323 world->create= world_create;
5324 world->destroy= world_destroy;
5325 }