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