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