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