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