Added test for randomized reads
[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 run_distribution(memc);
2860 for (int x= 0; x < 99; x++)
2861 {
2862 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2863 char *hostname = memc->hosts[server_idx].hostname;
2864 test_truth(strcmp(hostname, ketama_test_cases[x].server) == 0);
2865 }
2866
2867 memcached_server_list_free(server_pool);
2868 memcached_free(memc);
2869
2870 return TEST_SUCCESS;
2871 }
2872
2873 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
2874 {
2875 (void) trash;
2876
2877 memcached_return rc;
2878 memcached_st *memc= memcached_create(NULL);
2879 test_truth(memc);
2880
2881
2882 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2883 test_truth(rc == MEMCACHED_SUCCESS);
2884
2885 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2886 test_truth(value == 1);
2887
2888 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2889 test_truth(rc == MEMCACHED_SUCCESS);
2890
2891 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2892 test_truth(value == MEMCACHED_HASH_MD5);
2893
2894
2895 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
2896 MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
2897
2898 memcached_server_st *server_pool;
2899 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");
2900 memcached_server_push(memc, server_pool);
2901
2902 FILE *fp;
2903 if ((fp = fopen("ketama_keys.txt", "w")))
2904 {
2905 // noop
2906 } else {
2907 printf("cannot write to file ketama_keys.txt");
2908 return TEST_FAILURE;
2909 }
2910
2911 for (int x= 0; x < 10000; x++)
2912 {
2913 char key[10];
2914 sprintf(key, "%d", x);
2915
2916 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2917 char *hostname = memc->hosts[server_idx].hostname;
2918 unsigned int port = memc->hosts[server_idx].port;
2919 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2920 }
2921 fclose(fp);
2922 memcached_server_list_free(server_pool);
2923 memcached_free(memc);
2924
2925 return TEST_SUCCESS;
2926 }
2927
2928
2929 static test_return_t result_static(memcached_st *memc)
2930 {
2931 memcached_result_st result;
2932 memcached_result_st *result_ptr;
2933
2934 result_ptr= memcached_result_create(memc, &result);
2935 test_truth(result.is_allocated == false);
2936 test_truth(result_ptr);
2937 memcached_result_free(&result);
2938
2939 return TEST_SUCCESS;
2940 }
2941
2942 static test_return_t result_alloc(memcached_st *memc)
2943 {
2944 memcached_result_st *result;
2945
2946 result= memcached_result_create(memc, NULL);
2947 test_truth(result);
2948 memcached_result_free(result);
2949
2950 return TEST_SUCCESS;
2951 }
2952
2953 static test_return_t string_static_null(memcached_st *memc)
2954 {
2955 memcached_string_st string;
2956 memcached_string_st *string_ptr;
2957
2958 string_ptr= memcached_string_create(memc, &string, 0);
2959 test_truth(string.is_allocated == false);
2960 test_truth(string_ptr);
2961 memcached_string_free(&string);
2962
2963 return TEST_SUCCESS;
2964 }
2965
2966 static test_return_t string_alloc_null(memcached_st *memc)
2967 {
2968 memcached_string_st *string;
2969
2970 string= memcached_string_create(memc, NULL, 0);
2971 test_truth(string);
2972 memcached_string_free(string);
2973
2974 return TEST_SUCCESS;
2975 }
2976
2977 static test_return_t string_alloc_with_size(memcached_st *memc)
2978 {
2979 memcached_string_st *string;
2980
2981 string= memcached_string_create(memc, NULL, 1024);
2982 test_truth(string);
2983 memcached_string_free(string);
2984
2985 return TEST_SUCCESS;
2986 }
2987
2988 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
2989 {
2990 memcached_string_st *string;
2991
2992 string= memcached_string_create(memc, NULL, SIZE_MAX);
2993 test_truth(string == NULL);
2994
2995 return TEST_SUCCESS;
2996 }
2997
2998 static test_return_t string_alloc_append(memcached_st *memc)
2999 {
3000 unsigned int x;
3001 char buffer[SMALL_STRING_LEN];
3002 memcached_string_st *string;
3003
3004 /* Ring the bell! */
3005 memset(buffer, 6, SMALL_STRING_LEN);
3006
3007 string= memcached_string_create(memc, NULL, 100);
3008 test_truth(string);
3009
3010 for (x= 0; x < 1024; x++)
3011 {
3012 memcached_return rc;
3013 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3014 test_truth(rc == MEMCACHED_SUCCESS);
3015 }
3016 memcached_string_free(string);
3017
3018 return TEST_SUCCESS;
3019 }
3020
3021 static test_return_t string_alloc_append_toobig(memcached_st *memc)
3022 {
3023 memcached_return rc;
3024 unsigned int x;
3025 char buffer[SMALL_STRING_LEN];
3026 memcached_string_st *string;
3027
3028 /* Ring the bell! */
3029 memset(buffer, 6, SMALL_STRING_LEN);
3030
3031 string= memcached_string_create(memc, NULL, 100);
3032 test_truth(string);
3033
3034 for (x= 0; x < 1024; x++)
3035 {
3036 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3037 test_truth(rc == MEMCACHED_SUCCESS);
3038 }
3039 rc= memcached_string_append(string, buffer, SIZE_MAX);
3040 test_truth(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
3041 memcached_string_free(string);
3042
3043 return TEST_SUCCESS;
3044 }
3045
3046 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
3047 {
3048 pairs_free(global_pairs);
3049
3050 return TEST_SUCCESS;
3051 }
3052
3053 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
3054 {
3055 unsigned long long x;
3056 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3057 global_count= GLOBAL_COUNT;
3058
3059 for (x= 0; x < global_count; x++)
3060 {
3061 global_keys[x]= global_pairs[x].key;
3062 global_keys_length[x]= global_pairs[x].key_length;
3063 }
3064
3065 return TEST_SUCCESS;
3066 }
3067
3068 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
3069 {
3070 unsigned long long x;
3071 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3072 global_count= GLOBAL2_COUNT;
3073
3074 for (x= 0; x < global_count; x++)
3075 {
3076 global_keys[x]= global_pairs[x].key;
3077 global_keys_length[x]= global_pairs[x].key_length;
3078 }
3079
3080 return TEST_SUCCESS;
3081 }
3082
3083 static test_return_t generate_data(memcached_st *memc)
3084 {
3085 execute_set(memc, global_pairs, global_count);
3086
3087 return TEST_SUCCESS;
3088 }
3089
3090 static test_return_t generate_data_with_stats(memcached_st *memc)
3091 {
3092 memcached_stat_st *stat_p;
3093 memcached_return rc;
3094 uint32_t host_index= 0;
3095 execute_set(memc, global_pairs, global_count);
3096
3097 //TODO: hosts used size stats
3098 stat_p= memcached_stat(memc, NULL, &rc);
3099 test_truth(stat_p);
3100
3101 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3102 {
3103 /* This test was changes so that "make test" would work properlly */
3104 #ifdef DEBUG
3105 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);
3106 #endif
3107 test_truth((unsigned long long)(stat_p + host_index)->bytes);
3108 }
3109
3110 memcached_stat_free(NULL, stat_p);
3111
3112 return TEST_SUCCESS;
3113 }
3114 static test_return_t generate_buffer_data(memcached_st *memc)
3115 {
3116 size_t latch= 0;
3117
3118 latch= 1;
3119 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3120 generate_data(memc);
3121
3122 return TEST_SUCCESS;
3123 }
3124
3125 static test_return_t get_read_count(memcached_st *memc)
3126 {
3127 unsigned int x;
3128 memcached_return rc;
3129 memcached_st *memc_clone;
3130
3131 memc_clone= memcached_clone(NULL, memc);
3132 test_truth(memc_clone);
3133
3134 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3135
3136 {
3137 char *return_value;
3138 size_t return_value_length;
3139 uint32_t flags;
3140 uint32_t count;
3141
3142 for (x= count= 0; x < global_count; x++)
3143 {
3144 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3145 &return_value_length, &flags, &rc);
3146 if (rc == MEMCACHED_SUCCESS)
3147 {
3148 count++;
3149 if (return_value)
3150 free(return_value);
3151 }
3152 }
3153 }
3154
3155 memcached_free(memc_clone);
3156
3157 return TEST_SUCCESS;
3158 }
3159
3160 static test_return_t get_read(memcached_st *memc)
3161 {
3162 unsigned int x;
3163 memcached_return rc;
3164
3165 {
3166 char *return_value;
3167 size_t return_value_length;
3168 uint32_t flags;
3169
3170 for (x= 0; x < global_count; x++)
3171 {
3172 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3173 &return_value_length, &flags, &rc);
3174 /*
3175 test_truth(return_value);
3176 test_truth(rc == MEMCACHED_SUCCESS);
3177 */
3178 if (rc == MEMCACHED_SUCCESS && return_value)
3179 free(return_value);
3180 }
3181 }
3182
3183 return TEST_SUCCESS;
3184 }
3185
3186 static test_return_t mget_read(memcached_st *memc)
3187 {
3188 memcached_return rc;
3189
3190 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3191 test_truth(rc == MEMCACHED_SUCCESS);
3192 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
3193
3194 return TEST_SUCCESS;
3195 }
3196
3197 static test_return_t mget_read_result(memcached_st *memc)
3198 {
3199 memcached_return rc;
3200
3201 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3202 test_truth(rc == MEMCACHED_SUCCESS);
3203 /* Turn this into a help function */
3204 {
3205 memcached_result_st results_obj;
3206 memcached_result_st *results;
3207
3208 results= memcached_result_create(memc, &results_obj);
3209
3210 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3211 {
3212 test_truth(results);
3213 test_truth(rc == MEMCACHED_SUCCESS);
3214 }
3215
3216 memcached_result_free(&results_obj);
3217 }
3218
3219 return TEST_SUCCESS;
3220 }
3221
3222 static test_return_t mget_read_function(memcached_st *memc)
3223 {
3224 memcached_return rc;
3225 unsigned int counter;
3226 memcached_execute_function callbacks[1];
3227
3228 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3229 test_truth(rc == MEMCACHED_SUCCESS);
3230
3231 callbacks[0]= &callback_counter;
3232 counter= 0;
3233 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3234
3235 return TEST_SUCCESS;
3236 }
3237
3238 static test_return_t delete_generate(memcached_st *memc)
3239 {
3240 unsigned int x;
3241
3242 for (x= 0; x < global_count; x++)
3243 {
3244 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3245 }
3246
3247 return TEST_SUCCESS;
3248 }
3249
3250 static test_return_t delete_buffer_generate(memcached_st *memc)
3251 {
3252 size_t latch= 0;
3253 unsigned int x;
3254
3255 latch= 1;
3256 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3257
3258 for (x= 0; x < global_count; x++)
3259 {
3260 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3261 }
3262
3263 return TEST_SUCCESS;
3264 }
3265
3266 static test_return_t add_host_test1(memcached_st *memc)
3267 {
3268 unsigned int x;
3269 memcached_return rc;
3270 char servername[]= "0.example.com";
3271 memcached_server_st *servers;
3272
3273 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3274 test_truth(servers);
3275 test_truth(1 == memcached_server_list_count(servers));
3276
3277 for (x= 2; x < 20; x++)
3278 {
3279 char buffer[SMALL_STRING_LEN];
3280
3281 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
3282 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3283 &rc);
3284 test_truth(rc == MEMCACHED_SUCCESS);
3285 test_truth(x == memcached_server_list_count(servers));
3286 }
3287
3288 rc= memcached_server_push(memc, servers);
3289 test_truth(rc == MEMCACHED_SUCCESS);
3290 rc= memcached_server_push(memc, servers);
3291 test_truth(rc == MEMCACHED_SUCCESS);
3292
3293 memcached_server_list_free(servers);
3294
3295 return TEST_SUCCESS;
3296 }
3297
3298 static memcached_return pre_nonblock(memcached_st *memc)
3299 {
3300 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3301
3302 return MEMCACHED_SUCCESS;
3303 }
3304
3305 static memcached_return pre_nonblock_binary(memcached_st *memc)
3306 {
3307 memcached_return rc= MEMCACHED_FAILURE;
3308 memcached_st *memc_clone;
3309
3310 memc_clone= memcached_clone(NULL, memc);
3311 assert(memc_clone);
3312 // The memcached_version needs to be done on a clone, because the server
3313 // will not toggle protocol on an connection.
3314 memcached_version(memc_clone);
3315
3316 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3317 {
3318 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3319 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3320 assert(rc == MEMCACHED_SUCCESS);
3321 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3322 }
3323
3324 memcached_free(memc_clone);
3325 return rc;
3326 }
3327
3328 static memcached_return pre_murmur(memcached_st *memc)
3329 {
3330 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3331
3332 return MEMCACHED_SUCCESS;
3333 }
3334
3335 static memcached_return pre_jenkins(memcached_st *memc)
3336 {
3337 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3338
3339 return MEMCACHED_SUCCESS;
3340 }
3341
3342
3343 static memcached_return pre_md5(memcached_st *memc)
3344 {
3345 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3346
3347 return MEMCACHED_SUCCESS;
3348 }
3349
3350 static memcached_return pre_crc(memcached_st *memc)
3351 {
3352 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3353
3354 return MEMCACHED_SUCCESS;
3355 }
3356
3357 static memcached_return pre_hsieh(memcached_st *memc)
3358 {
3359 #ifdef HAVE_HSIEH_HASH
3360 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3361 return MEMCACHED_SUCCESS;
3362 #else
3363 (void) memc;
3364 return MEMCACHED_FAILURE;
3365 #endif
3366 }
3367
3368 static memcached_return pre_hash_fnv1_64(memcached_st *memc)
3369 {
3370 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
3371
3372 return MEMCACHED_SUCCESS;
3373 }
3374
3375 static memcached_return pre_hash_fnv1a_64(memcached_st *memc)
3376 {
3377 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3378
3379 return MEMCACHED_SUCCESS;
3380 }
3381
3382 static memcached_return pre_hash_fnv1_32(memcached_st *memc)
3383 {
3384 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3385
3386 return MEMCACHED_SUCCESS;
3387 }
3388
3389 static memcached_return pre_hash_fnv1a_32(memcached_st *memc)
3390 {
3391 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3392
3393 return MEMCACHED_SUCCESS;
3394 }
3395
3396 static memcached_return pre_behavior_ketama(memcached_st *memc)
3397 {
3398 memcached_return rc;
3399 uint64_t value;
3400
3401 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3402 assert(rc == MEMCACHED_SUCCESS);
3403
3404 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3405 assert(value == 1);
3406
3407 return MEMCACHED_SUCCESS;
3408 }
3409
3410 static memcached_return pre_behavior_ketama_weighted(memcached_st *memc)
3411 {
3412 memcached_return rc;
3413 uint64_t value;
3414
3415 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3416 assert(rc == MEMCACHED_SUCCESS);
3417
3418 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3419 assert(value == 1);
3420
3421 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3422 assert(rc == MEMCACHED_SUCCESS);
3423
3424 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3425 assert(value == MEMCACHED_HASH_MD5);
3426 return MEMCACHED_SUCCESS;
3427 }
3428
3429 static memcached_return pre_binary(memcached_st *memc)
3430 {
3431 memcached_return rc= MEMCACHED_FAILURE;
3432 memcached_st *memc_clone;
3433
3434 memc_clone= memcached_clone(NULL, memc);
3435 assert(memc_clone);
3436 // The memcached_version needs to be done on a clone, because the server
3437 // will not toggle protocol on an connection.
3438 memcached_version(memc_clone);
3439
3440 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3441 {
3442 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3443 assert(rc == MEMCACHED_SUCCESS);
3444 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3445 }
3446
3447 memcached_free(memc_clone);
3448
3449 return rc;
3450 }
3451
3452 static memcached_return pre_replication(memcached_st *memc)
3453 {
3454 if (pre_binary(memc) != MEMCACHED_SUCCESS)
3455 return MEMCACHED_FAILURE;
3456
3457 /*
3458 * Make sure that we store the item on all servers
3459 * (master + replicas == number of servers)
3460 */
3461 memcached_return rc;
3462 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3463 memc->number_of_hosts - 1);
3464 assert(rc == MEMCACHED_SUCCESS);
3465 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memc->number_of_hosts - 1);
3466
3467 return rc;
3468 }
3469
3470 static memcached_return pre_replication_noblock(memcached_st *memc)
3471 {
3472 memcached_return rc= MEMCACHED_FAILURE;
3473 if (pre_replication(memc) == MEMCACHED_SUCCESS &&
3474 pre_nonblock(memc) == MEMCACHED_SUCCESS)
3475 rc= MEMCACHED_SUCCESS;
3476
3477 return rc;
3478 }
3479
3480 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3481 {
3482 free(mem);
3483 }
3484
3485 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3486 {
3487 void *ret= malloc(size);
3488 if (ret != NULL)
3489 memset(ret, 0xff, size);
3490
3491 return ret;
3492 }
3493
3494 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3495 {
3496 return realloc(mem, size);
3497 }
3498
3499 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3500 {
3501 return calloc(nelem, size);
3502 }
3503
3504 static memcached_return set_prefix(memcached_st *memc)
3505 {
3506 memcached_return rc;
3507 const char *key= "mine";
3508 char *value;
3509
3510 /* Make sure be default none exists */
3511 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3512 assert(rc == MEMCACHED_FAILURE);
3513
3514 /* Test a clean set */
3515 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3516 assert(rc == MEMCACHED_SUCCESS);
3517
3518 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3519 assert(memcmp(value, key, 4) == 0);
3520 assert(rc == MEMCACHED_SUCCESS);
3521
3522 /* Test that we can turn it off */
3523 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3524 assert(rc == MEMCACHED_SUCCESS);
3525
3526 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3527 assert(rc == MEMCACHED_FAILURE);
3528
3529 /* Now setup for main test */
3530 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3531 assert(rc == MEMCACHED_SUCCESS);
3532
3533 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3534 assert(rc == MEMCACHED_SUCCESS);
3535 assert(memcmp(value, key, 4) == 0);
3536
3537 /* Set to Zero, and then Set to something too large */
3538 {
3539 char long_key[255];
3540 memset(long_key, 0, 255);
3541
3542 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3543 assert(rc == MEMCACHED_SUCCESS);
3544
3545 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3546 assert(rc == MEMCACHED_FAILURE);
3547 assert(value == NULL);
3548
3549 /* Test a long key for failure */
3550 /* TODO, extend test to determine based on setting, what result should be */
3551 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3552 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3553 //assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3554 assert(rc == MEMCACHED_SUCCESS);
3555
3556 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3557 strcpy(long_key, "This is more then the allotted number of characters");
3558 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3559 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3560
3561 /* Test for a bad prefix, but with a short key */
3562 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3563 assert(rc == MEMCACHED_SUCCESS);
3564
3565 strcpy(long_key, "dog cat");
3566 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3567 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3568 }
3569
3570 return MEMCACHED_SUCCESS;
3571 }
3572
3573 #ifdef MEMCACHED_ENABLE_DEPRECATED
3574 static memcached_return deprecated_set_memory_alloc(memcached_st *memc)
3575 {
3576 void *test_ptr= NULL;
3577 void *cb_ptr= NULL;
3578 {
3579 memcached_malloc_function malloc_cb=
3580 (memcached_malloc_function)my_malloc;
3581 cb_ptr= *(void **)&malloc_cb;
3582 memcached_return rc;
3583
3584 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3585 assert(rc == MEMCACHED_SUCCESS);
3586 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3587 assert(rc == MEMCACHED_SUCCESS);
3588 assert(test_ptr == cb_ptr);
3589 }
3590
3591 {
3592 memcached_realloc_function realloc_cb=
3593 (memcached_realloc_function)my_realloc;
3594 cb_ptr= *(void **)&realloc_cb;
3595 memcached_return rc;
3596
3597 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3598 assert(rc == MEMCACHED_SUCCESS);
3599 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3600 assert(rc == MEMCACHED_SUCCESS);
3601 assert(test_ptr == cb_ptr);
3602 }
3603
3604 {
3605 memcached_free_function free_cb=
3606 (memcached_free_function)my_free;
3607 cb_ptr= *(void **)&free_cb;
3608 memcached_return rc;
3609
3610 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3611 assert(rc == MEMCACHED_SUCCESS);
3612 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3613 assert(rc == MEMCACHED_SUCCESS);
3614 assert(test_ptr == cb_ptr);
3615 }
3616 return MEMCACHED_SUCCESS;
3617 }
3618 #endif
3619
3620 static memcached_return set_memory_alloc(memcached_st *memc)
3621 {
3622 memcached_return rc;
3623 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3624 my_realloc, my_calloc);
3625 assert(rc == MEMCACHED_FAILURE);
3626
3627 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3628 my_realloc, my_calloc);
3629
3630 memcached_malloc_function mem_malloc;
3631 memcached_free_function mem_free;
3632 memcached_realloc_function mem_realloc;
3633 memcached_calloc_function mem_calloc;
3634 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3635 &mem_realloc, &mem_calloc);
3636
3637 assert(mem_malloc == my_malloc);
3638 assert(mem_realloc == my_realloc);
3639 assert(mem_calloc == my_calloc);
3640 assert(mem_free == my_free);
3641
3642 return MEMCACHED_SUCCESS;
3643 }
3644
3645 static memcached_return enable_consistent(memcached_st *memc)
3646 {
3647 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3648 memcached_hash hash;
3649 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3650 if (pre_hsieh(memc) != MEMCACHED_SUCCESS)
3651 return MEMCACHED_FAILURE;
3652
3653 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3654 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3655
3656 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3657 assert(hash == MEMCACHED_HASH_HSIEH);
3658
3659
3660 return MEMCACHED_SUCCESS;
3661 }
3662
3663 static memcached_return enable_cas(memcached_st *memc)
3664 {
3665 unsigned int set= 1;
3666
3667 memcached_version(memc);
3668
3669 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3670 || memc->hosts[0].minor_version > 2)
3671 {
3672 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3673
3674 return MEMCACHED_SUCCESS;
3675 }
3676
3677 return MEMCACHED_FAILURE;
3678 }
3679
3680 static memcached_return check_for_1_2_3(memcached_st *memc)
3681 {
3682 memcached_version(memc);
3683
3684 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3685 || memc->hosts[0].minor_version > 2)
3686 return MEMCACHED_SUCCESS;
3687
3688 return MEMCACHED_FAILURE;
3689 }
3690
3691 static memcached_return pre_unix_socket(memcached_st *memc)
3692 {
3693 memcached_return rc;
3694 struct stat buf;
3695
3696 memcached_server_list_free(memc->hosts);
3697 memc->hosts= NULL;
3698 memc->number_of_hosts= 0;
3699
3700 if (stat("/tmp/memcached.socket", &buf))
3701 return MEMCACHED_FAILURE;
3702
3703 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3704
3705 return rc;
3706 }
3707
3708 static memcached_return pre_nodelay(memcached_st *memc)
3709 {
3710 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3711 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3712
3713 return MEMCACHED_SUCCESS;
3714 }
3715
3716 static memcached_return pre_settimer(memcached_st *memc)
3717 {
3718 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3719 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3720
3721 return MEMCACHED_SUCCESS;
3722 }
3723
3724 static memcached_return poll_timeout(memcached_st *memc)
3725 {
3726 size_t timeout;
3727
3728 timeout= 100;
3729
3730 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3731
3732 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3733
3734 assert(timeout == 100);
3735
3736 return MEMCACHED_SUCCESS;
3737 }
3738
3739 static test_return_t noreply_test(memcached_st *memc)
3740 {
3741 memcached_return ret;
3742 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3743 test_truth(ret == MEMCACHED_SUCCESS);
3744 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3745 test_truth(ret == MEMCACHED_SUCCESS);
3746 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3747 test_truth(ret == MEMCACHED_SUCCESS);
3748 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3749 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3750 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3751
3752 for (int count=0; count < 5; ++count)
3753 {
3754 for (int x=0; x < 100; ++x)
3755 {
3756 char key[10];
3757 size_t len= (size_t)sprintf(key, "%d", x);
3758 switch (count)
3759 {
3760 case 0:
3761 ret=memcached_add(memc, key, len, key, len, 0, 0);
3762 break;
3763 case 1:
3764 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3765 break;
3766 case 2:
3767 ret=memcached_set(memc, key, len, key, len, 0, 0);
3768 break;
3769 case 3:
3770 ret=memcached_append(memc, key, len, key, len, 0, 0);
3771 break;
3772 case 4:
3773 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3774 break;
3775 default:
3776 test_truth(count);
3777 break;
3778 }
3779 test_truth(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3780 }
3781
3782 /*
3783 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3784 ** API and is _ONLY_ done this way to verify that the library works the
3785 ** way it is supposed to do!!!!
3786 */
3787 int no_msg=0;
3788 for (uint32_t x=0; x < memc->number_of_hosts; ++x)
3789 no_msg+=(int)(memc->hosts[x].cursor_active);
3790
3791 test_truth(no_msg == 0);
3792 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3793
3794 /*
3795 ** Now validate that all items was set properly!
3796 */
3797 for (int x=0; x < 100; ++x)
3798 {
3799 char key[10];
3800 size_t len= (size_t)sprintf(key, "%d", x);
3801 size_t length;
3802 uint32_t flags;
3803 char* value=memcached_get(memc, key, strlen(key),
3804 &length, &flags, &ret);
3805 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
3806 switch (count)
3807 {
3808 case 0: /* FALLTHROUGH */
3809 case 1: /* FALLTHROUGH */
3810 case 2:
3811 test_truth(strncmp(value, key, len) == 0);
3812 test_truth(len == length);
3813 break;
3814 case 3:
3815 test_truth(length == len * 2);
3816 break;
3817 case 4:
3818 test_truth(length == len * 3);
3819 break;
3820 default:
3821 test_truth(count);
3822 break;
3823 }
3824 free(value);
3825 }
3826 }
3827
3828 /* Try setting an illegal cas value (should not return an error to
3829 * the caller (because we don't expect a return message from the server)
3830 */
3831 const char* keys[]= {"0"};
3832 size_t lengths[]= {1};
3833 size_t length;
3834 uint32_t flags;
3835 memcached_result_st results_obj;
3836 memcached_result_st *results;
3837 ret= memcached_mget(memc, keys, lengths, 1);
3838 test_truth(ret == MEMCACHED_SUCCESS);
3839
3840 results= memcached_result_create(memc, &results_obj);
3841 test_truth(results);
3842 results= memcached_fetch_result(memc, &results_obj, &ret);
3843 test_truth(results);
3844 test_truth(ret == MEMCACHED_SUCCESS);
3845 uint64_t cas= memcached_result_cas(results);
3846 memcached_result_free(&results_obj);
3847
3848 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3849 test_truth(ret == MEMCACHED_SUCCESS);
3850
3851 /*
3852 * The item will have a new cas value, so try to set it again with the old
3853 * value. This should fail!
3854 */
3855 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3856 test_truth(ret == MEMCACHED_SUCCESS);
3857 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3858 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3859 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
3860 free(value);
3861
3862 return TEST_SUCCESS;
3863 }
3864
3865 static test_return_t analyzer_test(memcached_st *memc)
3866 {
3867 memcached_return rc;
3868 memcached_stat_st *memc_stat;
3869 memcached_analysis_st *report;
3870
3871 memc_stat= memcached_stat(memc, NULL, &rc);
3872 test_truth(rc == MEMCACHED_SUCCESS);
3873 test_truth(memc_stat);
3874
3875 report= memcached_analyze(memc, memc_stat, &rc);
3876 test_truth(rc == MEMCACHED_SUCCESS);
3877 test_truth(report);
3878
3879 free(report);
3880 memcached_stat_free(NULL, memc_stat);
3881
3882 return TEST_SUCCESS;
3883 }
3884
3885 /* Count the objects */
3886 static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),
3887 const char *key __attribute__((unused)),
3888 size_t key_length __attribute__((unused)),
3889 void *context)
3890 {
3891 uint32_t *counter= (uint32_t *)context;
3892
3893 *counter= *counter + 1;
3894
3895 return MEMCACHED_SUCCESS;
3896 }
3897
3898 static test_return_t dump_test(memcached_st *memc)
3899 {
3900 memcached_return rc;
3901 uint32_t counter= 0;
3902 memcached_dump_func callbacks[1];
3903 test_return_t main_rc;
3904
3905 callbacks[0]= &callback_dump_counter;
3906
3907 /* No support for Binary protocol yet */
3908 if (memc->flags & MEM_BINARY_PROTOCOL)
3909 return TEST_SUCCESS;
3910
3911 main_rc= set_test3(memc);
3912
3913 test_truth (main_rc == TEST_SUCCESS);
3914
3915 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
3916 test_truth(rc == MEMCACHED_SUCCESS);
3917
3918 /* We may have more then 32 if our previous flush has not completed */
3919 test_truth(counter >= 32);
3920
3921 return TEST_SUCCESS;
3922 }
3923
3924 #ifdef HAVE_LIBMEMCACHEDUTIL
3925 static void* connection_release(void *arg)
3926 {
3927 struct {
3928 memcached_pool_st* pool;
3929 memcached_st* mmc;
3930 } *resource= arg;
3931
3932 usleep(250);
3933 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
3934 return arg;
3935 }
3936
3937 static test_return_t connection_pool_test(memcached_st *memc)
3938 {
3939 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
3940 test_truth(pool != NULL);
3941 memcached_st* mmc[10];
3942 memcached_return rc;
3943
3944 for (int x= 0; x < 10; ++x) {
3945 mmc[x]= memcached_pool_pop(pool, false, &rc);
3946 test_truth(mmc[x] != NULL);
3947 test_truth(rc == MEMCACHED_SUCCESS);
3948 }
3949
3950 test_truth(memcached_pool_pop(pool, false, &rc) == NULL);
3951 test_truth(rc == MEMCACHED_SUCCESS);
3952
3953 pthread_t tid;
3954 struct {
3955 memcached_pool_st* pool;
3956 memcached_st* mmc;
3957 } item= { .pool = pool, .mmc = mmc[9] };
3958 pthread_create(&tid, NULL, connection_release, &item);
3959 mmc[9]= memcached_pool_pop(pool, true, &rc);
3960 test_truth(rc == MEMCACHED_SUCCESS);
3961 pthread_join(tid, NULL);
3962 test_truth(mmc[9] == item.mmc);
3963 const char *key= "key";
3964 size_t keylen= strlen(key);
3965
3966 // verify that I can do ops with all connections
3967 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
3968 test_truth(rc == MEMCACHED_SUCCESS);
3969
3970 for (unsigned int x= 0; x < 10; ++x) {
3971 uint64_t number_value;
3972 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
3973 test_truth(rc == MEMCACHED_SUCCESS);
3974 test_truth(number_value == (x+1));
3975 }
3976
3977 // Release them..
3978 for (int x= 0; x < 10; ++x)
3979 test_truth(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
3980
3981
3982 /* verify that I can set behaviors on the pool when I don't have all
3983 * of the connections in the pool. It should however be enabled
3984 * when I push the item into the pool
3985 */
3986 mmc[0]= memcached_pool_pop(pool, false, &rc);
3987 test_truth(mmc[0] != NULL);
3988
3989 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
3990 test_truth(rc == MEMCACHED_SUCCESS);
3991
3992 mmc[1]= memcached_pool_pop(pool, false, &rc);
3993 test_truth(mmc[1] != NULL);
3994
3995 test_truth(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3996 test_truth(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
3997 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3998
3999 mmc[0]= memcached_pool_pop(pool, false, &rc);
4000 test_truth(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4001 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4002
4003
4004 test_truth(memcached_pool_destroy(pool) == memc);
4005 return TEST_SUCCESS;
4006 }
4007 #endif
4008
4009 static test_return_t replication_set_test(memcached_st *memc)
4010 {
4011 memcached_return rc;
4012 memcached_st *memc_clone= memcached_clone(NULL, memc);
4013 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4014
4015 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4016 test_truth(rc == MEMCACHED_SUCCESS);
4017
4018 /*
4019 ** We are using the quiet commands to store the replicas, so we need
4020 ** to ensure that all of them are processed before we can continue.
4021 ** In the test we go directly from storing the object to trying to
4022 ** receive the object from all of the different servers, so we
4023 ** could end up in a race condition (the memcached server hasn't yet
4024 ** processed the quiet command from the replication set when it process
4025 ** the request from the other client (created by the clone)). As a
4026 ** workaround for that we call memcached_quit to send the quit command
4027 ** to the server and wait for the response ;-) If you use the test code
4028 ** as an example for your own code, please note that you shouldn't need
4029 ** to do this ;-)
4030 */
4031 memcached_quit(memc);
4032
4033 /*
4034 ** "bubba" should now be stored on all of our servers. We don't have an
4035 ** easy to use API to address each individual server, so I'll just iterate
4036 ** through a bunch of "master keys" and I should most likely hit all of the
4037 ** servers...
4038 */
4039 for (int x= 'a'; x <= 'z'; ++x)
4040 {
4041 char key[2]= { [0]= (char)x };
4042 size_t len;
4043 uint32_t flags;
4044 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4045 &len, &flags, &rc);
4046 test_truth(rc == MEMCACHED_SUCCESS);
4047 test_truth(val != NULL);
4048 free(val);
4049 }
4050
4051 memcached_free(memc_clone);
4052
4053 return TEST_SUCCESS;
4054 }
4055
4056 static test_return_t replication_get_test(memcached_st *memc)
4057 {
4058 memcached_return rc;
4059
4060 /*
4061 * Don't do the following in your code. I am abusing the internal details
4062 * within the library, and this is not a supported interface.
4063 * This is to verify correct behavior in the library
4064 */
4065 for (uint32_t host= 0; host < memc->number_of_hosts; ++host)
4066 {
4067 memcached_st *memc_clone= memcached_clone(NULL, memc);
4068 memc_clone->hosts[host].port= 0;
4069
4070 for (int x= 'a'; x <= 'z'; ++x)
4071 {
4072 char key[2]= { [0]= (char)x };
4073 size_t len;
4074 uint32_t flags;
4075 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4076 &len, &flags, &rc);
4077 test_truth(rc == MEMCACHED_SUCCESS);
4078 test_truth(val != NULL);
4079 free(val);
4080 }
4081
4082 memcached_free(memc_clone);
4083 }
4084
4085 return TEST_SUCCESS;
4086 }
4087
4088 static test_return_t replication_mget_test(memcached_st *memc)
4089 {
4090 memcached_return rc;
4091 memcached_st *memc_clone= memcached_clone(NULL, memc);
4092 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4093
4094 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4095 size_t len[]= { 5, 4, 4, 4 };
4096
4097 for (int x=0; x< 4; ++x)
4098 {
4099 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4100 test_truth(rc == MEMCACHED_SUCCESS);
4101 }
4102
4103 /*
4104 ** We are using the quiet commands to store the replicas, so we need
4105 ** to ensure that all of them are processed before we can continue.
4106 ** In the test we go directly from storing the object to trying to
4107 ** receive the object from all of the different servers, so we
4108 ** could end up in a race condition (the memcached server hasn't yet
4109 ** processed the quiet command from the replication set when it process
4110 ** the request from the other client (created by the clone)). As a
4111 ** workaround for that we call memcached_quit to send the quit command
4112 ** to the server and wait for the response ;-) If you use the test code
4113 ** as an example for your own code, please note that you shouldn't need
4114 ** to do this ;-)
4115 */
4116 memcached_quit(memc);
4117
4118 /*
4119 * Don't do the following in your code. I am abusing the internal details
4120 * within the library, and this is not a supported interface.
4121 * This is to verify correct behavior in the library
4122 */
4123 memcached_result_st result_obj;
4124 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4125 {
4126 memcached_st *new_clone= memcached_clone(NULL, memc);
4127 new_clone->hosts[host].port= 0;
4128
4129 for (int x= 'a'; x <= 'z'; ++x)
4130 {
4131 const char key[2]= { [0]= (const char)x };
4132
4133 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4134 test_truth(rc == MEMCACHED_SUCCESS);
4135
4136 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4137 test_truth(results);
4138
4139 int hits= 0;
4140 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4141 {
4142 hits++;
4143 }
4144 test_truth(hits == 4);
4145 memcached_result_free(&result_obj);
4146 }
4147
4148 memcached_free(new_clone);
4149 }
4150
4151 memcached_free(memc_clone);
4152
4153 return TEST_SUCCESS;
4154 }
4155
4156 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4157 {
4158 memcached_result_st result_obj;
4159 memcached_return rc;
4160 memcached_st *memc_clone= memcached_clone(NULL, memc);
4161 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4162 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4163
4164 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4165 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4166
4167 for (int x=0; x< 7; ++x)
4168 {
4169 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4170 test_truth(rc == MEMCACHED_SUCCESS);
4171 }
4172
4173 memcached_quit(memc);
4174
4175 for (int x=0; x< 7; ++x) {
4176 const char key[2]= { [0]= (const char)x };
4177
4178 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4179 test_truth(rc == MEMCACHED_SUCCESS);
4180
4181 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4182 test_truth(results);
4183
4184 int hits= 0;
4185 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4186 {
4187 ++hits;
4188 }
4189 test_truth(hits == 7);
4190 memcached_result_free(&result_obj);
4191 }
4192 memcached_free(memc_clone);
4193 return TEST_SUCCESS;
4194 }
4195
4196 static test_return_t replication_delete_test(memcached_st *memc)
4197 {
4198 memcached_return rc;
4199 memcached_st *memc_clone= memcached_clone(NULL, memc);
4200 /* Delete the items from all of the servers except 1 */
4201 uint64_t repl= memcached_behavior_get(memc,
4202 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4203 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4204
4205 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4206 size_t len[]= { 5, 4, 4, 4 };
4207
4208 for (int x=0; x< 4; ++x)
4209 {
4210 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4211 test_truth(rc == MEMCACHED_SUCCESS);
4212 }
4213
4214 /*
4215 * Don't do the following in your code. I am abusing the internal details
4216 * within the library, and this is not a supported interface.
4217 * This is to verify correct behavior in the library
4218 */
4219 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4220 for (uint32_t x= 0; x < (repl + 1); ++x)
4221 {
4222 memc_clone->hosts[hash].port= 0;
4223 if (++hash == memc_clone->number_of_hosts)
4224 hash= 0;
4225 }
4226
4227 memcached_result_st result_obj;
4228 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4229 {
4230 for (int x= 'a'; x <= 'z'; ++x)
4231 {
4232 const char key[2]= { [0]= (const char)x };
4233
4234 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4235 test_truth(rc == MEMCACHED_SUCCESS);
4236
4237 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4238 test_truth(results);
4239
4240 int hits= 0;
4241 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4242 {
4243 ++hits;
4244 }
4245 test_truth(hits == 4);
4246 memcached_result_free(&result_obj);
4247 }
4248 }
4249 memcached_free(memc_clone);
4250
4251 return TEST_SUCCESS;
4252 }
4253
4254 static void increment_request_id(uint16_t *id)
4255 {
4256 (*id)++;
4257 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4258 *id= 0;
4259 }
4260
4261 static uint16_t *get_udp_request_ids(memcached_st *memc)
4262 {
4263 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
4264 assert(ids != NULL);
4265 unsigned int x;
4266
4267 for (x= 0; x < memc->number_of_hosts; x++)
4268 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
4269
4270 return ids;
4271 }
4272
4273 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4274 {
4275 unsigned int x;
4276 memcached_server_st *cur_server = memc->hosts;
4277 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4278
4279 for (x= 0; x < memc->number_of_hosts; x++)
4280 {
4281 test_truth(cur_server[x].cursor_active == 0);
4282 test_truth(cur_req_ids[x] == expected_req_ids[x]);
4283 }
4284 free(expected_req_ids);
4285 free(cur_req_ids);
4286
4287 return TEST_SUCCESS;
4288 }
4289
4290 /*
4291 ** There is a little bit of a hack here, instead of removing
4292 ** the servers, I just set num host to 0 and them add then new udp servers
4293 **/
4294 static memcached_return init_udp(memcached_st *memc)
4295 {
4296 memcached_version(memc);
4297 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4298 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
4299 || memc->hosts[0].micro_version < 6)
4300 return MEMCACHED_FAILURE;
4301
4302 uint32_t num_hosts= memc->number_of_hosts;
4303 unsigned int x= 0;
4304 memcached_server_st servers[num_hosts];
4305 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
4306 for (x= 0; x < num_hosts; x++)
4307 memcached_server_free(&memc->hosts[x]);
4308
4309 memc->number_of_hosts= 0;
4310 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4311 for (x= 0; x < num_hosts; x++)
4312 {
4313 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4314 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4315 }
4316
4317 return MEMCACHED_SUCCESS;
4318 }
4319
4320 static memcached_return binary_init_udp(memcached_st *memc)
4321 {
4322 pre_binary(memc);
4323 return init_udp(memc);
4324 }
4325
4326 /* Make sure that I cant add a tcp server to a udp client */
4327 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4328 {
4329 memcached_server_st server;
4330 memcached_server_clone(&server, &memc->hosts[0]);
4331 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4332 test_truth(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4333 return TEST_SUCCESS;
4334 }
4335
4336 /* Make sure that I cant add a udp server to a tcp client */
4337 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4338 {
4339 memcached_server_st server;
4340 memcached_server_clone(&server, &memc->hosts[0]);
4341 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4342
4343 memcached_st tcp_client;
4344 memcached_create(&tcp_client);
4345 test_truth(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4346 return TEST_SUCCESS;
4347 }
4348
4349 static test_return_t set_udp_behavior_test(memcached_st *memc)
4350 {
4351
4352 memcached_quit(memc);
4353 memc->number_of_hosts= 0;
4354 run_distribution(memc);
4355 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4356 test_truth(memc->flags & MEM_USE_UDP);
4357 test_truth(memc->flags & MEM_NOREPLY);;
4358
4359 test_truth(memc->number_of_hosts == 0);
4360
4361 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4362 test_truth(!(memc->flags & MEM_USE_UDP));
4363 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4364 test_truth(!(memc->flags & MEM_NOREPLY));
4365 return TEST_SUCCESS;
4366 }
4367
4368 static test_return_t udp_set_test(memcached_st *memc)
4369 {
4370 unsigned int x= 0;
4371 unsigned int num_iters= 1025; //request id rolls over at 1024
4372 for (x= 0; x < num_iters;x++)
4373 {
4374 memcached_return rc;
4375 const char *key= "foo";
4376 const char *value= "when we sanitize";
4377 uint16_t *expected_ids= get_udp_request_ids(memc);
4378 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
4379 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4380 rc= memcached_set(memc, key, strlen(key),
4381 value, strlen(value),
4382 (time_t)0, (uint32_t)0);
4383 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4384 /** NB, the check below assumes that if new write_ptr is less than
4385 * the original write_ptr that we have flushed. For large payloads, this
4386 * maybe an invalid assumption, but for the small payload we have it is OK
4387 */
4388 if (rc == MEMCACHED_SUCCESS ||
4389 memc->hosts[server_key].write_buffer_offset < init_offset)
4390 increment_request_id(&expected_ids[server_key]);
4391
4392 if (rc == MEMCACHED_SUCCESS)
4393 {
4394 test_truth(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4395 }
4396 else
4397 {
4398 test_truth(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4399 test_truth(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4400 }
4401 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4402 }
4403 return TEST_SUCCESS;
4404 }
4405
4406 static test_return_t udp_buffered_set_test(memcached_st *memc)
4407 {
4408 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4409 return udp_set_test(memc);
4410 }
4411
4412 static test_return_t udp_set_too_big_test(memcached_st *memc)
4413 {
4414 memcached_return rc;
4415 const char *key= "bar";
4416 char value[MAX_UDP_DATAGRAM_LENGTH];
4417 uint16_t *expected_ids= get_udp_request_ids(memc);
4418 rc= memcached_set(memc, key, strlen(key),
4419 value, MAX_UDP_DATAGRAM_LENGTH,
4420 (time_t)0, (uint32_t)0);
4421 test_truth(rc == MEMCACHED_WRITE_FAILURE);
4422 return post_udp_op_check(memc,expected_ids);
4423 }
4424
4425 static test_return_t udp_delete_test(memcached_st *memc)
4426 {
4427 unsigned int x= 0;
4428 unsigned int num_iters= 1025; //request id rolls over at 1024
4429 for (x= 0; x < num_iters;x++)
4430 {
4431 memcached_return rc;
4432 const char *key= "foo";
4433 uint16_t *expected_ids=get_udp_request_ids(memc);
4434 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4435 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4436 rc= memcached_delete(memc, key, strlen(key), 0);
4437 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4438 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
4439 increment_request_id(&expected_ids[server_key]);
4440 if (rc == MEMCACHED_SUCCESS)
4441 {
4442 test_truth(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4443 }
4444 else
4445 {
4446 test_truth(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4447 test_truth(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4448 }
4449 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4450 }
4451 return TEST_SUCCESS;
4452 }
4453
4454 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4455 {
4456 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4457 return udp_delete_test(memc);
4458 }
4459
4460 static test_return_t udp_verbosity_test(memcached_st *memc)
4461 {
4462 memcached_return rc;
4463 uint16_t *expected_ids= get_udp_request_ids(memc);
4464 unsigned int x;
4465 for (x= 0; x < memc->number_of_hosts;x++)
4466 increment_request_id(&expected_ids[x]);
4467
4468 rc= memcached_verbosity(memc,3);
4469 test_truth(rc == MEMCACHED_SUCCESS);
4470 return post_udp_op_check(memc,expected_ids);
4471 }
4472
4473 static test_return_t udp_quit_test(memcached_st *memc)
4474 {
4475 uint16_t *expected_ids= get_udp_request_ids(memc);
4476 memcached_quit(memc);
4477 return post_udp_op_check(memc, expected_ids);
4478 }
4479
4480 static test_return_t udp_flush_test(memcached_st *memc)
4481 {
4482 memcached_return rc;
4483 uint16_t *expected_ids= get_udp_request_ids(memc);
4484 unsigned int x;
4485 for (x= 0; x < memc->number_of_hosts;x++)
4486 increment_request_id(&expected_ids[x]);
4487
4488 rc= memcached_flush(memc,0);
4489 test_truth(rc == MEMCACHED_SUCCESS);
4490 return post_udp_op_check(memc,expected_ids);
4491 }
4492
4493 static test_return_t udp_incr_test(memcached_st *memc)
4494 {
4495 memcached_return rc;
4496 const char *key= "incr";
4497 const char *value= "1";
4498 rc= memcached_set(memc, key, strlen(key),
4499 value, strlen(value),
4500 (time_t)0, (uint32_t)0);
4501
4502 test_truth(rc == MEMCACHED_SUCCESS);
4503 uint16_t *expected_ids= get_udp_request_ids(memc);
4504 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4505 increment_request_id(&expected_ids[server_key]);
4506 uint64_t newvalue;
4507 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4508 test_truth(rc == MEMCACHED_SUCCESS);
4509 return post_udp_op_check(memc, expected_ids);
4510 }
4511
4512 static test_return_t udp_decr_test(memcached_st *memc)
4513 {
4514 memcached_return rc;
4515 const char *key= "decr";
4516 const char *value= "1";
4517 rc= memcached_set(memc, key, strlen(key),
4518 value, strlen(value),
4519 (time_t)0, (uint32_t)0);
4520
4521 test_truth(rc == MEMCACHED_SUCCESS);
4522 uint16_t *expected_ids= get_udp_request_ids(memc);
4523 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4524 increment_request_id(&expected_ids[server_key]);
4525 uint64_t newvalue;
4526 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4527 test_truth(rc == MEMCACHED_SUCCESS);
4528 return post_udp_op_check(memc, expected_ids);
4529 }
4530
4531
4532 static test_return_t udp_stat_test(memcached_st *memc)
4533 {
4534 memcached_stat_st * rv= NULL;
4535 memcached_return rc;
4536 char args[]= "";
4537 uint16_t *expected_ids = get_udp_request_ids(memc);
4538 rv = memcached_stat(memc, args, &rc);
4539 free(rv);
4540 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4541 return post_udp_op_check(memc, expected_ids);
4542 }
4543
4544 static test_return_t udp_version_test(memcached_st *memc)
4545 {
4546 memcached_return rc;
4547 uint16_t *expected_ids = get_udp_request_ids(memc);
4548 rc = memcached_version(memc);
4549 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4550 return post_udp_op_check(memc, expected_ids);
4551 }
4552
4553 static test_return_t udp_get_test(memcached_st *memc)
4554 {
4555 memcached_return rc;
4556 const char *key= "foo";
4557 size_t vlen;
4558 uint16_t *expected_ids = get_udp_request_ids(memc);
4559 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4560 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4561 test_truth(val == NULL);
4562 return post_udp_op_check(memc, expected_ids);
4563 }
4564
4565 static test_return_t udp_mixed_io_test(memcached_st *memc)
4566 {
4567 test_st current_op;
4568 test_st mixed_io_ops [] ={
4569 {"udp_set_test", 0, udp_set_test},
4570 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4571 {"udp_delete_test", 0, udp_delete_test},
4572 {"udp_verbosity_test", 0, udp_verbosity_test},
4573 {"udp_quit_test", 0, udp_quit_test},
4574 {"udp_flush_test", 0, udp_flush_test},
4575 {"udp_incr_test", 0, udp_incr_test},
4576 {"udp_decr_test", 0, udp_decr_test},
4577 {"udp_version_test", 0, udp_version_test}
4578 };
4579 unsigned int x= 0;
4580 for (x= 0; x < 500; x++)
4581 {
4582 current_op= mixed_io_ops[random() % 9];
4583 test_truth(current_op.function(memc) == TEST_SUCCESS);
4584 }
4585 return TEST_SUCCESS;
4586 }
4587
4588 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4589 {
4590 memcached_return expected_rc= MEMCACHED_FAILURE;
4591 #ifdef HAVE_HSIEH_HASH
4592 expected_rc= MEMCACHED_SUCCESS;
4593 #endif
4594 memcached_return rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4595 (uint64_t)MEMCACHED_HASH_HSIEH);
4596 test_truth(rc == expected_rc);
4597 return TEST_SUCCESS;
4598 }
4599
4600 static const char *list[]=
4601 {
4602 "apple",
4603 "beat",
4604 "carrot",
4605 "daikon",
4606 "eggplant",
4607 "flower",
4608 "green",
4609 "hide",
4610 "ick",
4611 "jack",
4612 "kick",
4613 "lime",
4614 "mushrooms",
4615 "nectarine",
4616 "orange",
4617 "peach",
4618 "quant",
4619 "ripen",
4620 "strawberry",
4621 "tang",
4622 "up",
4623 "volumne",
4624 "when",
4625 "yellow",
4626 "zip",
4627 NULL
4628 };
4629
4630 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4631 {
4632 uint32_t x;
4633 const char **ptr;
4634 uint32_t values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
4635 245758794U, 2550894432U, 121710495U, 3053817768U,
4636 1250994555U, 1862072655U, 2631955953U, 2951528551U,
4637 1451250070U, 2820856945U, 2060845566U, 3646985608U,
4638 2138080750U, 217675895U, 2230934345U, 1234361223U,
4639 3968582726U, 2455685270U, 1293568479U, 199067604U,
4640 2042482093U };
4641
4642
4643 for (ptr= list, x= 0; *ptr; ptr++, x++)
4644 {
4645 uint32_t hash_val;
4646
4647 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4648 test_truth(values[x] == hash_val);
4649 }
4650
4651 return TEST_SUCCESS;
4652 }
4653
4654 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4655 {
4656 uint32_t x;
4657 const char **ptr;
4658 uint32_t values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
4659 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
4660 7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
4661 17300U, 28156U, 9192U, 20484U, 16925U };
4662
4663 for (ptr= list, x= 0; *ptr; ptr++, x++)
4664 {
4665 uint32_t hash_val;
4666
4667 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4668 assert(values[x] == hash_val);
4669 }
4670
4671 return TEST_SUCCESS;
4672 }
4673
4674 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4675 {
4676 uint32_t x;
4677 const char **ptr;
4678 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4679 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4680 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4681 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4682 2815549194U, 2562818319U, 224996066U, 2680194749U,
4683 3035305390U, 246890365U, 2395624193U, 4145193337U,
4684 1801941682U };
4685
4686 for (ptr= list, x= 0; *ptr; ptr++, x++)
4687 {
4688 uint32_t hash_val;
4689
4690 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4691 assert(values[x] == hash_val);
4692 }
4693
4694 return TEST_SUCCESS;
4695 }
4696
4697 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4698 {
4699 uint32_t x;
4700 const char **ptr;
4701 uint32_t values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
4702 3647689787U, 3241528582U, 1669328060U, 2604311949U,
4703 734810122U, 1516407546U, 560948863U, 1767346780U,
4704 561034892U, 4156330026U, 3716417003U, 3475297030U,
4705 1518272172U, 227211583U, 3938128828U, 126112909U,
4706 3043416448U, 3131561933U, 1328739897U, 2455664041U,
4707 2272238452U };
4708
4709 for (ptr= list, x= 0; *ptr; ptr++, x++)
4710 {
4711 uint32_t hash_val;
4712
4713 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4714 assert(values[x] == hash_val);
4715 }
4716
4717 return TEST_SUCCESS;
4718 }
4719
4720 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4721 {
4722 uint32_t x;
4723 const char **ptr;
4724 uint32_t values[]= { 67176023U, 1190179409U, 2043204404U, 3221866419U,
4725 2567703427U, 3787535528U, 4147287986U, 3500475733U,
4726 344481048U, 3865235296U, 2181839183U, 119581266U,
4727 510234242U, 4248244304U, 1362796839U, 103389328U,
4728 1449620010U, 182962511U, 3554262370U, 3206747549U,
4729 1551306158U, 4127558461U, 1889140833U, 2774173721U,
4730 1180552018U };
4731
4732
4733 for (ptr= list, x= 0; *ptr; ptr++, x++)
4734 {
4735 uint32_t hash_val;
4736
4737 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4738 assert(values[x] == hash_val);
4739 }
4740
4741 return TEST_SUCCESS;
4742 }
4743
4744 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4745 {
4746 uint32_t x;
4747 const char **ptr;
4748 uint32_t values[]= { 280767167U, 2421315013U, 3072375666U, 855001899U,
4749 459261019U, 3521085446U, 18738364U, 1625305005U,
4750 2162232970U, 777243802U, 3323728671U, 132336572U,
4751 3654473228U, 260679466U, 1169454059U, 2698319462U,
4752 1062177260U, 235516991U, 2218399068U, 405302637U,
4753 1128467232U, 3579622413U, 2138539289U, 96429129U,
4754 2877453236U };
4755
4756 for (ptr= list, x= 0; *ptr; ptr++, x++)
4757 {
4758 uint32_t hash_val;
4759
4760 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4761 assert(values[x] == hash_val);
4762 }
4763
4764 return TEST_SUCCESS;
4765 }
4766
4767 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4768 {
4769 uint32_t x;
4770 const char **ptr;
4771 #ifdef HAVE_HSIEH_HASH
4772 uint32_t values[]= { 3738850110, 3636226060, 3821074029, 3489929160, 3485772682, 80540287,
4773 1805464076, 1895033657, 409795758, 979934958, 3634096985, 1284445480,
4774 2265380744, 707972988, 353823508, 1549198350, 1327930172, 9304163,
4775 4220749037, 2493964934, 2777873870, 2057831732, 1510213931, 2027828987,
4776 3395453351 };
4777 #else
4778 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 };
4779 #endif
4780
4781 for (ptr= list, x= 0; *ptr; ptr++, x++)
4782 {
4783 uint32_t hash_val;
4784
4785 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4786 assert(values[x] == hash_val);
4787 }
4788
4789 return TEST_SUCCESS;
4790 }
4791
4792 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4793 {
4794 uint32_t x;
4795 const char **ptr;
4796 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4797 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4798 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4799 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4800 2815549194U, 2562818319U, 224996066U, 2680194749U,
4801 3035305390U, 246890365U, 2395624193U, 4145193337U,
4802 1801941682U };
4803
4804 for (ptr= list, x= 0; *ptr; ptr++, x++)
4805 {
4806 uint32_t hash_val;
4807
4808 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4809 assert(values[x] == hash_val);
4810 }
4811
4812 return TEST_SUCCESS;
4813 }
4814
4815 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4816 {
4817 uint32_t x;
4818 const char **ptr;
4819 uint32_t values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U,
4820 3261968576U, 3515188778U, 4232909173U, 4288625128U,
4821 1812047395U, 3689182164U, 2502979932U, 1214050606U,
4822 2415988847U, 1494268927U, 1025545760U, 3920481083U,
4823 4153263658U, 3824871822U, 3072759809U, 798622255U,
4824 3065432577U, 1453328165U, 2691550971U, 3408888387U,
4825 2629893356U };
4826
4827
4828 for (ptr= list, x= 0; *ptr; ptr++, x++)
4829 {
4830 uint32_t hash_val;
4831
4832 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4833 assert(values[x] == hash_val);
4834 }
4835
4836 return TEST_SUCCESS;
4837 }
4838
4839
4840 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4841 {
4842 memcached_return rc;
4843 uint64_t value;
4844 int x;
4845 memcached_server_st *server_pool;
4846 memcached_st *memc;
4847
4848 (void)trash;
4849
4850 memc= memcached_create(NULL);
4851 assert(memc);
4852
4853 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4854 assert(rc == MEMCACHED_SUCCESS);
4855
4856 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4857 assert(value == 1);
4858
4859 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
4860 MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED) == MEMCACHED_SUCCESS);
4861
4862 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
4863 MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED);
4864
4865 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");
4866 memcached_server_push(memc, server_pool);
4867
4868 /* verify that the server list was parsed okay. */
4869 assert(memc->number_of_hosts == 8);
4870 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
4871 assert(server_pool[0].port == 11211);
4872 assert(server_pool[0].weight == 600);
4873 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
4874 assert(server_pool[2].port == 11211);
4875 assert(server_pool[2].weight == 200);
4876 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
4877 assert(server_pool[7].port == 11211);
4878 assert(server_pool[7].weight == 100);
4879
4880 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4881 * us test the boundary wraparound.
4882 */
4883 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4884
4885 /* verify the standard ketama set. */
4886 for (x= 0; x < 99; x++)
4887 {
4888 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4889 char *hostname = memc->hosts[server_idx].hostname;
4890 assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
4891 }
4892
4893 memcached_server_list_free(server_pool);
4894 memcached_free(memc);
4895
4896 return TEST_SUCCESS;
4897 }
4898
4899 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4900 {
4901 memcached_return rc;
4902 uint64_t value;
4903 int x;
4904 memcached_server_st *server_pool;
4905 memcached_st *memc;
4906
4907 (void)trash;
4908
4909 memc= memcached_create(NULL);
4910 assert(memc);
4911
4912 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4913 assert(rc == MEMCACHED_SUCCESS);
4914
4915 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4916 assert(value == 1);
4917
4918 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
4919 MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
4920
4921 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
4922 MEMCACHED_KETAMA_COMPAT_SPY);
4923
4924 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");
4925 memcached_server_push(memc, server_pool);
4926
4927 /* verify that the server list was parsed okay. */
4928 assert(memc->number_of_hosts == 8);
4929 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
4930 assert(server_pool[0].port == 11211);
4931 assert(server_pool[0].weight == 600);
4932 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
4933 assert(server_pool[2].port == 11211);
4934 assert(server_pool[2].weight == 200);
4935 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
4936 assert(server_pool[7].port == 11211);
4937 assert(server_pool[7].weight == 100);
4938
4939 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4940 * us test the boundary wraparound.
4941 */
4942 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4943
4944 /* verify the standard ketama set. */
4945 for (x= 0; x < 99; x++)
4946 {
4947 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
4948 char *hostname = memc->hosts[server_idx].hostname;
4949 assert(strcmp(hostname, ketama_test_cases_spy[x].server) == 0);
4950 }
4951
4952 memcached_server_list_free(server_pool);
4953 memcached_free(memc);
4954
4955 return TEST_SUCCESS;
4956 }
4957
4958 static test_return_t regression_bug_434484(memcached_st *memc)
4959 {
4960 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4961 return TEST_SKIPPED;
4962
4963 memcached_return ret;
4964 const char *key= "regression_bug_434484";
4965 size_t keylen= strlen(key);
4966
4967 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
4968 assert(ret == MEMCACHED_NOTSTORED);
4969
4970 size_t size= 2048 * 1024;
4971 void *data= calloc(1, size);
4972 assert(data != NULL);
4973 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
4974 assert(ret == MEMCACHED_E2BIG);
4975 free(data);
4976
4977 return TEST_SUCCESS;
4978 }
4979
4980 static test_return_t regression_bug_434843(memcached_st *memc)
4981 {
4982 if (pre_binary(memc) != MEMCACHED_SUCCESS)
4983 return TEST_SKIPPED;
4984
4985 memcached_return rc;
4986 unsigned int counter= 0;
4987 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
4988
4989 /*
4990 * I only want to hit only _one_ server so I know the number of requests I'm
4991 * sending in the pipleine to the server. Let's try to do a multiget of
4992 * 1024 (that should satisfy most users don't you think?). Future versions
4993 * will include a mget_execute function call if you need a higher number.
4994 */
4995 uint32_t number_of_hosts= memc->number_of_hosts;
4996 memc->number_of_hosts= 1;
4997 const size_t max_keys= 1024;
4998 char **keys= calloc(max_keys, sizeof(char*));
4999 size_t *key_length=calloc(max_keys, sizeof(size_t));
5000
5001 for (int x= 0; x < (int)max_keys; ++x)
5002 {
5003 char k[251];
5004 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5005 keys[x]= strdup(k);
5006 assert(keys[x] != NULL);
5007 }
5008
5009 /*
5010 * Run two times.. the first time we should have 100% cache miss,
5011 * and the second time we should have 100% cache hits
5012 */
5013 for (int y= 0; y < 2; ++y)
5014 {
5015 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5016 assert(rc == MEMCACHED_SUCCESS);
5017 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5018 if (y == 0)
5019 {
5020 /* The first iteration should give me a 100% cache miss. verify that*/
5021 assert(counter == 0);
5022 char blob[1024]= { 0 };
5023 for (int x= 0; x < (int)max_keys; ++x)
5024 {
5025 rc= memcached_add(memc, keys[x], key_length[x],
5026 blob, sizeof(blob), 0, 0);
5027 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5028 }
5029 }
5030 else
5031 {
5032 /* Verify that we received all of the key/value pairs */
5033 assert(counter == (unsigned int)max_keys);
5034 }
5035 }
5036
5037 /* Release allocated resources */
5038 for (size_t x= 0; x < max_keys; ++x)
5039 free(keys[x]);
5040 free(keys);
5041 free(key_length);
5042
5043 memc->number_of_hosts= number_of_hosts;
5044 return TEST_SUCCESS;
5045 }
5046
5047 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5048 {
5049 memcached_return rc;
5050 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5051 assert(rc == MEMCACHED_SUCCESS);
5052
5053 return regression_bug_434843(memc);
5054 }
5055
5056 static test_return_t regression_bug_421108(memcached_st *memc)
5057 {
5058 memcached_return rc;
5059 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5060 assert(rc == MEMCACHED_SUCCESS);
5061
5062 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5063 assert(rc == MEMCACHED_SUCCESS);
5064 assert(bytes != NULL);
5065 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5066 "bytes_read", &rc);
5067 assert(rc == MEMCACHED_SUCCESS);
5068 assert(bytes_read != NULL);
5069
5070 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5071 "bytes_written", &rc);
5072 assert(rc == MEMCACHED_SUCCESS);
5073 assert(bytes_written != NULL);
5074
5075 assert(strcmp(bytes, bytes_read) != 0);
5076 assert(strcmp(bytes, bytes_written) != 0);
5077
5078 /* Release allocated resources */
5079 free(bytes);
5080 free(bytes_read);
5081 free(bytes_written);
5082 memcached_stat_free(NULL, memc_stat);
5083 return TEST_SUCCESS;
5084 }
5085
5086 /*
5087 * The test case isn't obvious so I should probably document why
5088 * it works the way it does. Bug 442914 was caused by a bug
5089 * in the logic in memcached_purge (it did not handle the case
5090 * where the number of bytes sent was equal to the watermark).
5091 * In this test case, create messages so that we hit that case
5092 * and then disable noreply mode and issue a new command to
5093 * verify that it isn't stuck. If we change the format for the
5094 * delete command or the watermarks, we need to update this
5095 * test....
5096 */
5097 static test_return_t regression_bug_442914(memcached_st *memc)
5098 {
5099 memcached_return rc;
5100 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5101 assert(rc == MEMCACHED_SUCCESS);
5102 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5103
5104 uint32_t number_of_hosts= memc->number_of_hosts;
5105 memc->number_of_hosts= 1;
5106
5107 char k[250];
5108 size_t len;
5109
5110 for (int x= 0; x < 250; ++x)
5111 {
5112 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5113 rc= memcached_delete(memc, k, len, 0);
5114 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5115 }
5116
5117 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
5118 rc= memcached_delete(memc, k, len, 0);
5119 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5120
5121 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5122 assert(rc == MEMCACHED_SUCCESS);
5123 rc= memcached_delete(memc, k, len, 0);
5124 assert(rc == MEMCACHED_NOTFOUND);
5125
5126 memc->number_of_hosts= number_of_hosts;
5127
5128 return TEST_SUCCESS;
5129 }
5130
5131 static test_return_t regression_bug_447342(memcached_st *memc)
5132 {
5133 if (memc->number_of_hosts < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5134 return TEST_SKIPPED;
5135
5136 memcached_return rc;
5137
5138 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5139 assert(rc == MEMCACHED_SUCCESS);
5140
5141 const size_t max_keys= 100;
5142 char **keys= calloc(max_keys, sizeof(char*));
5143 size_t *key_length=calloc(max_keys, sizeof(size_t));
5144
5145 for (int x= 0; x < (int)max_keys; ++x)
5146 {
5147 char k[251];
5148 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5149 keys[x]= strdup(k);
5150 assert(keys[x] != NULL);
5151 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5152 assert(rc == MEMCACHED_SUCCESS);
5153 }
5154
5155 /*
5156 ** We are using the quiet commands to store the replicas, so we need
5157 ** to ensure that all of them are processed before we can continue.
5158 ** In the test we go directly from storing the object to trying to
5159 ** receive the object from all of the different servers, so we
5160 ** could end up in a race condition (the memcached server hasn't yet
5161 ** processed the quiet command from the replication set when it process
5162 ** the request from the other client (created by the clone)). As a
5163 ** workaround for that we call memcached_quit to send the quit command
5164 ** to the server and wait for the response ;-) If you use the test code
5165 ** as an example for your own code, please note that you shouldn't need
5166 ** to do this ;-)
5167 */
5168 memcached_quit(memc);
5169
5170 /* Verify that all messages are stored, and we didn't stuff too much
5171 * into the servers
5172 */
5173 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5174 assert(rc == MEMCACHED_SUCCESS);
5175
5176 unsigned int counter= 0;
5177 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
5178 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5179 /* Verify that we received all of the key/value pairs */
5180 assert(counter == (unsigned int)max_keys);
5181
5182 memcached_quit(memc);
5183 /*
5184 * Don't do the following in your code. I am abusing the internal details
5185 * within the library, and this is not a supported interface.
5186 * This is to verify correct behavior in the library. Fake that two servers
5187 * are dead..
5188 */
5189 unsigned int port0= memc->hosts[0].port;
5190 unsigned int port2= memc->hosts[2].port;
5191 memc->hosts[0].port= 0;
5192 memc->hosts[2].port= 0;
5193
5194 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5195 assert(rc == MEMCACHED_SUCCESS);
5196
5197 counter= 0;
5198 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5199 assert(counter == (unsigned int)max_keys);
5200
5201 /* restore the memc handle */
5202 memc->hosts[0].port= port0;
5203 memc->hosts[2].port= port2;
5204
5205 memcached_quit(memc);
5206
5207 /* Remove half of the objects */
5208 for (int x= 0; x < (int)max_keys; ++x)
5209 if (x & 1)
5210 {
5211 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5212 assert(rc == MEMCACHED_SUCCESS);
5213 }
5214
5215 memcached_quit(memc);
5216 memc->hosts[0].port= 0;
5217 memc->hosts[2].port= 0;
5218
5219 /* now retry the command, this time we should have cache misses */
5220 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5221 assert(rc == MEMCACHED_SUCCESS);
5222
5223 counter= 0;
5224 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5225 assert(counter == (unsigned int)(max_keys >> 1));
5226
5227 /* Release allocated resources */
5228 for (size_t x= 0; x < max_keys; ++x)
5229 free(keys[x]);
5230 free(keys);
5231 free(key_length);
5232
5233 /* restore the memc handle */
5234 memc->hosts[0].port= port0;
5235 memc->hosts[2].port= port2;
5236 return TEST_SUCCESS;
5237 }
5238
5239 static test_return_t regression_bug_463297(memcached_st *memc)
5240 {
5241 memcached_st *memc_clone= memcached_clone(NULL, memc);
5242 assert(memc_clone != NULL);
5243 assert(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5244
5245 if (memc_clone->hosts[0].major_version > 1 ||
5246 (memc_clone->hosts[0].major_version == 1 &&
5247 memc_clone->hosts[0].minor_version > 2))
5248 {
5249 /* Binary protocol doesn't support deferred delete */
5250 memcached_st *bin_clone= memcached_clone(NULL, memc);
5251 assert(bin_clone != NULL);
5252 assert(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5253 assert(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5254 memcached_free(bin_clone);
5255
5256 memcached_quit(memc_clone);
5257
5258 /* If we know the server version, deferred delete should fail
5259 * with invalid arguments */
5260 assert(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5261
5262 /* If we don't know the server version, we should get a protocol error */
5263 memcached_return rc= memcached_delete(memc, "foo", 3, 1);
5264 /* but there is a bug in some of the memcached servers (1.4) that treats
5265 * the counter as noreply so it doesn't send the proper error message
5266 */
5267 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5268
5269 /* And buffered mode should be disabled and we should get protocol error */
5270 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5271 rc= memcached_delete(memc, "foo", 3, 1);
5272 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5273
5274 /* Same goes for noreply... */
5275 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5276 rc= memcached_delete(memc, "foo", 3, 1);
5277 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5278
5279 /* but a normal request should go through (and be buffered) */
5280 assert((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5281 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5282
5283 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5284 /* unbuffered noreply should be success */
5285 assert(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5286 /* unbuffered with reply should be not found... */
5287 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5288 assert(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5289 }
5290
5291 memcached_free(memc_clone);
5292 return TEST_SUCCESS;
5293 }
5294
5295
5296 /* Test memcached_server_get_last_disconnect
5297 * For a working server set, shall be NULL
5298 * For a set of non existing server, shall not be NULL
5299 */
5300 static test_return_t test_get_last_disconnect(memcached_st *memc)
5301 {
5302 memcached_return rc;
5303 memcached_server_st *disconnected_server;
5304
5305 /* With the working set of server */
5306 const char *key= "marmotte";
5307 const char *value= "milka";
5308
5309 rc= memcached_set(memc, key, strlen(key),
5310 value, strlen(value),
5311 (time_t)0, (uint32_t)0);
5312 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5313
5314 disconnected_server = memcached_server_get_last_disconnect(memc);
5315 assert(disconnected_server == NULL);
5316
5317 /* With a non existing server */
5318 memcached_st *mine;
5319 memcached_server_st *servers;
5320
5321 const char *server_list= "localhost:9";
5322
5323 servers= memcached_servers_parse(server_list);
5324 assert(servers);
5325 mine= memcached_create(NULL);
5326 rc= memcached_server_push(mine, servers);
5327 assert(rc == MEMCACHED_SUCCESS);
5328 memcached_server_list_free(servers);
5329 assert(mine);
5330
5331 rc= memcached_set(mine, key, strlen(key),
5332 value, strlen(value),
5333 (time_t)0, (uint32_t)0);
5334 assert(rc != MEMCACHED_SUCCESS);
5335
5336 disconnected_server = memcached_server_get_last_disconnect(mine);
5337 assert(disconnected_server != NULL);
5338 assert(disconnected_server->port == 9);
5339 assert(strncmp(disconnected_server->hostname,"localhost",9) == 0);
5340
5341 memcached_quit(mine);
5342 memcached_free(mine);
5343
5344 return TEST_SUCCESS;
5345 }
5346
5347 /*
5348 * This test ensures that the failure counter isn't incremented during
5349 * normal termination of the memcached instance.
5350 */
5351 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5352 {
5353 memcached_return rc;
5354
5355 /* Set value to force connection to the server */
5356 const char *key= "marmotte";
5357 const char *value= "milka";
5358
5359 /*
5360 * Please note that I'm abusing the internal structures in libmemcached
5361 * in a non-portable way and you shouldn't be doing this. I'm only
5362 * doing this in order to verify that the library works the way it should
5363 */
5364 uint32_t number_of_hosts= memc->number_of_hosts;
5365 memc->number_of_hosts= 1;
5366
5367 /* Ensure that we are connected to the server by setting a value */
5368 rc= memcached_set(memc, key, strlen(key),
5369 value, strlen(value),
5370 (time_t)0, (uint32_t)0);
5371 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5372
5373
5374 /* The test is to see that the memcached_quit doesn't increase the
5375 * the server failure conter, so let's ensure that it is zero
5376 * before sending quit
5377 */
5378 memc->hosts[0].server_failure_counter= 0;
5379
5380 memcached_quit(memc);
5381
5382 /* Verify that it memcached_quit didn't increment the failure counter
5383 * Please note that this isn't bullet proof, because an error could
5384 * occur...
5385 */
5386 assert(memc->hosts[0].server_failure_counter == 0);
5387
5388 /* restore the instance */
5389 memc->number_of_hosts= number_of_hosts;
5390
5391 return TEST_SUCCESS;
5392 }
5393
5394 test_st udp_setup_server_tests[] ={
5395 {"set_udp_behavior_test", 0, set_udp_behavior_test},
5396 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
5397 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
5398 {0, 0, 0}
5399 };
5400
5401 test_st upd_io_tests[] ={
5402 {"udp_set_test", 0, udp_set_test},
5403 {"udp_buffered_set_test", 0, udp_buffered_set_test},
5404 {"udp_set_too_big_test", 0, udp_set_too_big_test},
5405 {"udp_delete_test", 0, udp_delete_test},
5406 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
5407 {"udp_verbosity_test", 0, udp_verbosity_test},
5408 {"udp_quit_test", 0, udp_quit_test},
5409 {"udp_flush_test", 0, udp_flush_test},
5410 {"udp_incr_test", 0, udp_incr_test},
5411 {"udp_decr_test", 0, udp_decr_test},
5412 {"udp_stat_test", 0, udp_stat_test},
5413 {"udp_version_test", 0, udp_version_test},
5414 {"udp_get_test", 0, udp_get_test},
5415 {"udp_mixed_io_test", 0, udp_mixed_io_test},
5416 {0, 0, 0}
5417 };
5418
5419 /* Clean the server before beginning testing */
5420 test_st tests[] ={
5421 {"flush", 0, flush_test },
5422 {"init", 0, init_test },
5423 {"allocation", 0, allocation_test },
5424 {"server_list_null_test", 0, server_list_null_test},
5425 {"server_unsort", 0, server_unsort_test},
5426 {"server_sort", 0, server_sort_test},
5427 {"server_sort2", 0, server_sort2_test},
5428 {"clone_test", 0, clone_test },
5429 {"connection_test", 0, connection_test},
5430 {"callback_test", 0, callback_test},
5431 {"behavior_test", 0, behavior_test},
5432 {"userdata_test", 0, userdata_test},
5433 {"error", 0, error_test },
5434 {"set", 0, set_test },
5435 {"set2", 0, set_test2 },
5436 {"set3", 0, set_test3 },
5437 {"dump", 1, dump_test},
5438 {"add", 1, add_test },
5439 {"replace", 1, replace_test },
5440 {"delete", 1, delete_test },
5441 {"get", 1, get_test },
5442 {"get2", 0, get_test2 },
5443 {"get3", 0, get_test3 },
5444 {"get4", 0, get_test4 },
5445 {"partial mget", 0, get_test5 },
5446 {"stats_servername", 0, stats_servername_test },
5447 {"increment", 0, increment_test },
5448 {"increment_with_initial", 1, increment_with_initial_test },
5449 {"decrement", 0, decrement_test },
5450 {"decrement_with_initial", 1, decrement_with_initial_test },
5451 {"increment_by_key", 0, increment_by_key_test },
5452 {"increment_with_initial_by_key", 1, increment_with_initial_by_key_test },
5453 {"decrement_by_key", 0, decrement_by_key_test },
5454 {"decrement_with_initial_by_key", 1, decrement_with_initial_by_key_test },
5455 {"quit", 0, quit_test },
5456 {"mget", 1, mget_test },
5457 {"mget_result", 1, mget_result_test },
5458 {"mget_result_alloc", 1, mget_result_alloc_test },
5459 {"mget_result_function", 1, mget_result_function },
5460 {"mget_execute", 1, mget_execute },
5461 {"mget_end", 0, mget_end },
5462 {"get_stats", 0, get_stats },
5463 {"add_host_test", 0, add_host_test },
5464 {"add_host_test_1", 0, add_host_test1 },
5465 {"get_stats_keys", 0, get_stats_keys },
5466 {"behavior_test", 0, get_stats_keys },
5467 {"callback_test", 0, get_stats_keys },
5468 {"version_string_test", 0, version_string_test},
5469 {"bad_key", 1, bad_key_test },
5470 {"memcached_server_cursor", 1, memcached_server_cursor_test },
5471 {"read_through", 1, read_through },
5472 {"delete_through", 1, delete_through },
5473 {"noreply", 1, noreply_test},
5474 {"analyzer", 1, analyzer_test},
5475 #ifdef HAVE_LIBMEMCACHEDUTIL
5476 {"connectionpool", 1, connection_pool_test },
5477 #endif
5478 {"test_get_last_disconnect", 1, test_get_last_disconnect},
5479 {0, 0, 0}
5480 };
5481
5482 test_st async_tests[] ={
5483 {"add", 1, add_wrapper },
5484 {0, 0, 0}
5485 };
5486
5487 test_st string_tests[] ={
5488 {"string static with null", 0, string_static_null },
5489 {"string alloc with null", 0, string_alloc_null },
5490 {"string alloc with 1K", 0, string_alloc_with_size },
5491 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
5492 {"string append", 0, string_alloc_append },
5493 {"string append failure (too big)", 0, string_alloc_append_toobig },
5494 {0, 0, 0}
5495 };
5496
5497 test_st result_tests[] ={
5498 {"result static", 0, result_static},
5499 {"result alloc", 0, result_alloc},
5500 {0, 0, 0}
5501 };
5502
5503 test_st version_1_2_3[] ={
5504 {"append", 0, append_test },
5505 {"prepend", 0, prepend_test },
5506 {"cas", 0, cas_test },
5507 {"cas2", 0, cas2_test },
5508 {"append_binary", 0, append_binary_test },
5509 {0, 0, 0}
5510 };
5511
5512 test_st user_tests[] ={
5513 {"user_supplied_bug1", 0, user_supplied_bug1 },
5514 {"user_supplied_bug2", 0, user_supplied_bug2 },
5515 {"user_supplied_bug3", 0, user_supplied_bug3 },
5516 {"user_supplied_bug4", 0, user_supplied_bug4 },
5517 {"user_supplied_bug5", 1, user_supplied_bug5 },
5518 {"user_supplied_bug6", 1, user_supplied_bug6 },
5519 {"user_supplied_bug7", 1, user_supplied_bug7 },
5520 {"user_supplied_bug8", 1, user_supplied_bug8 },
5521 {"user_supplied_bug9", 1, user_supplied_bug9 },
5522 {"user_supplied_bug10", 1, user_supplied_bug10 },
5523 {"user_supplied_bug11", 1, user_supplied_bug11 },
5524 {"user_supplied_bug12", 1, user_supplied_bug12 },
5525 {"user_supplied_bug13", 1, user_supplied_bug13 },
5526 {"user_supplied_bug14", 1, user_supplied_bug14 },
5527 {"user_supplied_bug15", 1, user_supplied_bug15 },
5528 {"user_supplied_bug16", 1, user_supplied_bug16 },
5529 #ifndef __sun
5530 /*
5531 ** It seems to be something weird with the character sets..
5532 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5533 ** guess I need to find out how this is supposed to work.. Perhaps I need
5534 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5535 ** so just disable the code for now...).
5536 */
5537 {"user_supplied_bug17", 1, user_supplied_bug17 },
5538 #endif
5539 {"user_supplied_bug18", 1, user_supplied_bug18 },
5540 {"user_supplied_bug19", 1, user_supplied_bug19 },
5541 {"user_supplied_bug20", 1, user_supplied_bug20 },
5542 {"user_supplied_bug21", 1, user_supplied_bug21 },
5543 {"wrong_failure_counter_test", 1, wrong_failure_counter_test},
5544 {0, 0, 0}
5545 };
5546
5547 test_st replication_tests[]= {
5548 {"set", 1, replication_set_test },
5549 {"get", 0, replication_get_test },
5550 {"mget", 0, replication_mget_test },
5551 {"delete", 0, replication_delete_test },
5552 {"rand_mget", 0, replication_randomize_mget_test },
5553 {0, 0, 0}
5554 };
5555
5556 /*
5557 * The following test suite is used to verify that we don't introduce
5558 * regression bugs. If you want more information about the bug / test,
5559 * you should look in the bug report at
5560 * http://bugs.launchpad.net/libmemcached
5561 */
5562 test_st regression_tests[]= {
5563 {"lp:434484", 1, regression_bug_434484 },
5564 {"lp:434843", 1, regression_bug_434843 },
5565 {"lp:434843 buffered", 1, regression_bug_434843_buffered },
5566 {"lp:421108", 1, regression_bug_421108 },
5567 {"lp:442914", 1, regression_bug_442914 },
5568 {"lp:447342", 1, regression_bug_447342 },
5569 {"lp:463297", 1, regression_bug_463297 },
5570 {0, 0, 0}
5571 };
5572
5573 test_st ketama_compatibility[]= {
5574 {"libmemcached", 1, ketama_compatibility_libmemcached },
5575 {"spymemcached", 1, ketama_compatibility_spymemcached },
5576 {0, 0, 0}
5577 };
5578
5579 test_st generate_tests[] ={
5580 {"generate_pairs", 1, generate_pairs },
5581 {"generate_data", 1, generate_data },
5582 {"get_read", 0, get_read },
5583 {"delete_generate", 0, delete_generate },
5584 {"generate_buffer_data", 1, generate_buffer_data },
5585 {"delete_buffer", 0, delete_buffer_generate},
5586 {"generate_data", 1, generate_data },
5587 {"mget_read", 0, mget_read },
5588 {"mget_read_result", 0, mget_read_result },
5589 {"mget_read_function", 0, mget_read_function },
5590 {"cleanup", 1, cleanup_pairs },
5591 {"generate_large_pairs", 1, generate_large_pairs },
5592 {"generate_data", 1, generate_data },
5593 {"generate_buffer_data", 1, generate_buffer_data },
5594 {"cleanup", 1, cleanup_pairs },
5595 {0, 0, 0}
5596 };
5597
5598 test_st consistent_tests[] ={
5599 {"generate_pairs", 1, generate_pairs },
5600 {"generate_data", 1, generate_data },
5601 {"get_read", 0, get_read_count },
5602 {"cleanup", 1, cleanup_pairs },
5603 {0, 0, 0}
5604 };
5605
5606 test_st consistent_weighted_tests[] ={
5607 {"generate_pairs", 1, generate_pairs },
5608 {"generate_data", 1, generate_data_with_stats },
5609 {"get_read", 0, get_read_count },
5610 {"cleanup", 1, cleanup_pairs },
5611 {0, 0, 0}
5612 };
5613
5614 test_st hsieh_availability[] ={
5615 {"hsieh_avaibility_test",0,hsieh_avaibility_test},
5616 {0, 0, 0}
5617 };
5618
5619 test_st ketama_auto_eject_hosts[] ={
5620 {"auto_eject_hosts", 1, auto_eject_hosts },
5621 {"output_ketama_weighted_keys", 1, output_ketama_weighted_keys },
5622 {0, 0, 0}
5623 };
5624
5625 test_st hash_tests[] ={
5626 {"md5", 0, md5_run },
5627 {"crc", 0, crc_run },
5628 {"fnv1_64", 0, fnv1_64_run },
5629 {"fnv1a_64", 0, fnv1a_64_run },
5630 {"fnv1_32", 0, fnv1_32_run },
5631 {"fnv1a_32", 0, fnv1a_32_run },
5632 {"hsieh", 0, hsieh_run },
5633 {"murmur", 0, murmur_run },
5634 {"jenkis", 0, jenkins_run },
5635 {0, 0, 0}
5636 };
5637
5638 collection_st collection[] ={
5639 {"hsieh_availability",0,0,hsieh_availability},
5640 {"udp_setup", init_udp, 0, udp_setup_server_tests},
5641 {"udp_io", init_udp, 0, upd_io_tests},
5642 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
5643 {"block", 0, 0, tests},
5644 {"binary", pre_binary, 0, tests},
5645 {"nonblock", pre_nonblock, 0, tests},
5646 {"nodelay", pre_nodelay, 0, tests},
5647 {"settimer", pre_settimer, 0, tests},
5648 {"md5", pre_md5, 0, tests},
5649 {"crc", pre_crc, 0, tests},
5650 {"hsieh", pre_hsieh, 0, tests},
5651 {"jenkins", pre_jenkins, 0, tests},
5652 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
5653 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
5654 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
5655 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
5656 {"ketama", pre_behavior_ketama, 0, tests},
5657 {"ketama_auto_eject_hosts", pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5658 {"unix_socket", pre_unix_socket, 0, tests},
5659 {"unix_socket_nodelay", pre_nodelay, 0, tests},
5660 {"poll_timeout", poll_timeout, 0, tests},
5661 {"gets", enable_cas, 0, tests},
5662 {"consistent", enable_consistent, 0, tests},
5663 #ifdef MEMCACHED_ENABLE_DEPRECATED
5664 {"deprecated_memory_allocators", deprecated_set_memory_alloc, 0, tests},
5665 #endif
5666 {"memory_allocators", set_memory_alloc, 0, tests},
5667 {"prefix", set_prefix, 0, tests},
5668 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
5669 {"string", 0, 0, string_tests},
5670 {"result", 0, 0, result_tests},
5671 {"async", pre_nonblock, 0, async_tests},
5672 {"async_binary", pre_nonblock_binary, 0, async_tests},
5673 {"user", 0, 0, user_tests},
5674 {"generate", 0, 0, generate_tests},
5675 {"generate_hsieh", pre_hsieh, 0, generate_tests},
5676 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
5677 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
5678 {"generate_md5", pre_md5, 0, generate_tests},
5679 {"generate_murmur", pre_murmur, 0, generate_tests},
5680 {"generate_jenkins", pre_jenkins, 0, generate_tests},
5681 {"generate_nonblock", pre_nonblock, 0, generate_tests},
5682 {"consistent_not", 0, 0, consistent_tests},
5683 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
5684 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5685 {"ketama_compat", 0, 0, ketama_compatibility},
5686 {"test_hashes", 0, 0, hash_tests},
5687 {"replication", pre_replication, 0, replication_tests},
5688 {"replication_noblock", pre_replication_noblock, 0, replication_tests},
5689 {"regression", 0, 0, regression_tests},
5690 {0, 0, 0, 0}
5691 };
5692
5693 #define SERVERS_TO_CREATE 5
5694
5695 /* Prototypes for functions we will pass to test framework */
5696 void *world_create(void);
5697 void world_destroy(void *p);
5698
5699 void *world_create(void)
5700 {
5701 server_startup_st *construct;
5702
5703 construct= calloc(sizeof(server_startup_st), 1);
5704 construct->count= SERVERS_TO_CREATE;
5705 construct->udp= 0;
5706 server_startup(construct);
5707
5708 return construct;
5709 }
5710
5711
5712 void world_destroy(void *p)
5713 {
5714 server_startup_st *construct= (server_startup_st *)p;
5715 memcached_server_st *servers= (memcached_server_st *)construct->servers;
5716 memcached_server_list_free(servers);
5717
5718 server_shutdown(construct);
5719 free(construct);
5720 }
5721
5722 void get_world(world_st *world)
5723 {
5724 world->collections= collection;
5725 world->create= world_create;
5726 world->destroy= world_destroy;
5727 }