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