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