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