Bug #446607: Syscall param write(buf) points to uninitialised byte(s)
[awesomized/libmemcached] / tests / function.c
1 /*
2 Sample test application.
3 */
4
5 #include "libmemcached/common.h"
6
7 #include <assert.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/time.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <signal.h>
15 #include <unistd.h>
16 #include <time.h>
17 #include "server.h"
18 #include "clients/generator.h"
19 #include "clients/execute.h"
20
21 #ifndef INT64_MAX
22 #define INT64_MAX LONG_MAX
23 #endif
24 #ifndef INT32_MAX
25 #define INT32_MAX INT_MAX
26 #endif
27
28
29 #include "test.h"
30
31 #ifdef HAVE_LIBMEMCACHEDUTIL
32 #include <pthread.h>
33 #include "libmemcached/memcached_util.h"
34 #endif
35
36 #define GLOBAL_COUNT 10000
37 #define GLOBAL2_COUNT 100
38 #define SERVERS_TO_CREATE 5
39 static uint32_t global_count;
40
41 static pairs_st *global_pairs;
42 static const char *global_keys[GLOBAL_COUNT];
43 static size_t global_keys_length[GLOBAL_COUNT];
44
45 static test_return init_test(memcached_st *not_used __attribute__((unused)))
46 {
47 memcached_st memc;
48
49 (void)memcached_create(&memc);
50 memcached_free(&memc);
51
52 return 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 void fail(int); /* sighandler_t function that always asserts false */
2548
2549 static test_return _user_supplied_bug21(memcached_st* memc, size_t key_count)
2550 {
2551 memcached_return rc;
2552 unsigned int x;
2553 char **keys;
2554 size_t* key_lengths;
2555 void (*oldalarm)(int);
2556 memcached_st *memc_clone;
2557
2558 memc_clone= memcached_clone(NULL, memc);
2559 assert(memc_clone);
2560
2561 /* only binproto uses getq for mget */
2562 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2563
2564 /* empty the cache to ensure misses (hence non-responses) */
2565 rc= memcached_flush(memc_clone, 0);
2566 assert(rc == MEMCACHED_SUCCESS);
2567
2568 key_lengths= calloc(key_count, sizeof(size_t));
2569 keys= calloc(key_count, sizeof(char *));
2570 assert(keys);
2571 for (x= 0; x < key_count; x++)
2572 {
2573 char buffer[30];
2574
2575 snprintf(buffer, 30, "%u", x);
2576 keys[x]= strdup(buffer);
2577 key_lengths[x]= strlen(keys[x]);
2578 }
2579
2580 oldalarm= signal(SIGALRM, fail);
2581 alarm(5);
2582
2583 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
2584 assert(rc == MEMCACHED_SUCCESS);
2585
2586 alarm(0);
2587 signal(SIGALRM, oldalarm);
2588
2589 assert(fetch_all_results(memc) == TEST_SUCCESS);
2590
2591 for (x= 0; x < key_count; x++)
2592 free(keys[x]);
2593 free(keys);
2594 free(key_lengths);
2595
2596 memcached_free(memc_clone);
2597
2598 return TEST_SUCCESS;
2599 }
2600
2601 static test_return user_supplied_bug21(memcached_st *memc)
2602 {
2603 test_return rc;
2604
2605 /* should work as of r580 */
2606 rc= _user_supplied_bug21(memc, 10);
2607 assert(rc == TEST_SUCCESS);
2608
2609 /* should fail as of r580 */
2610 rc= _user_supplied_bug21(memc, 1000);
2611 assert(rc == TEST_SUCCESS);
2612
2613 return TEST_SUCCESS;
2614 }
2615
2616 void fail(int unused __attribute__((unused)))
2617 {
2618 assert(0);
2619 }
2620
2621 static test_return auto_eject_hosts(memcached_st *trash)
2622 {
2623 (void) trash;
2624
2625 memcached_return rc;
2626 memcached_st *memc= memcached_create(NULL);
2627 assert(memc);
2628
2629 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2630 assert(rc == MEMCACHED_SUCCESS);
2631
2632 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2633 assert(value == 1);
2634
2635 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2636 assert(rc == MEMCACHED_SUCCESS);
2637
2638 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2639 assert(value == MEMCACHED_HASH_MD5);
2640
2641 /* server should be removed when in delay */
2642 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
2643 assert(rc == MEMCACHED_SUCCESS);
2644
2645 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
2646 assert(value == 1);
2647
2648 memcached_server_st *server_pool;
2649 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");
2650 memcached_server_push(memc, server_pool);
2651
2652 /* verify that the server list was parsed okay. */
2653 assert(memc->number_of_hosts == 8);
2654 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2655 assert(server_pool[0].port == 11211);
2656 assert(server_pool[0].weight == 600);
2657 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2658 assert(server_pool[2].port == 11211);
2659 assert(server_pool[2].weight == 200);
2660 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2661 assert(server_pool[7].port == 11211);
2662 assert(server_pool[7].weight == 100);
2663
2664 memc->hosts[2].next_retry = time(NULL) + 15;
2665 memc->next_distribution_rebuild= time(NULL) - 1;
2666
2667 for (int x= 0; x < 99; x++)
2668 {
2669 uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
2670 assert(server_idx != 2);
2671 }
2672
2673 /* and re-added when it's back. */
2674 memc->hosts[2].next_retry = time(NULL) - 1;
2675 memc->next_distribution_rebuild= time(NULL) - 1;
2676 run_distribution(memc);
2677 for (int x= 0; x < 99; x++)
2678 {
2679 uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
2680 char *hostname = memc->hosts[server_idx].hostname;
2681 assert(strcmp(hostname, test_cases[x].server) == 0);
2682 }
2683
2684 memcached_server_list_free(server_pool);
2685 memcached_free(memc);
2686
2687 return TEST_SUCCESS;
2688 }
2689
2690 static test_return result_static(memcached_st *memc)
2691 {
2692 memcached_result_st result;
2693 memcached_result_st *result_ptr;
2694
2695 result_ptr= memcached_result_create(memc, &result);
2696 assert(result.is_allocated == false);
2697 assert(result_ptr);
2698 memcached_result_free(&result);
2699
2700 return TEST_SUCCESS;
2701 }
2702
2703 static test_return result_alloc(memcached_st *memc)
2704 {
2705 memcached_result_st *result;
2706
2707 result= memcached_result_create(memc, NULL);
2708 assert(result);
2709 memcached_result_free(result);
2710
2711 return TEST_SUCCESS;
2712 }
2713
2714 static test_return string_static_null(memcached_st *memc)
2715 {
2716 memcached_string_st string;
2717 memcached_string_st *string_ptr;
2718
2719 string_ptr= memcached_string_create(memc, &string, 0);
2720 assert(string.is_allocated == false);
2721 assert(string_ptr);
2722 memcached_string_free(&string);
2723
2724 return TEST_SUCCESS;
2725 }
2726
2727 static test_return string_alloc_null(memcached_st *memc)
2728 {
2729 memcached_string_st *string;
2730
2731 string= memcached_string_create(memc, NULL, 0);
2732 assert(string);
2733 memcached_string_free(string);
2734
2735 return TEST_SUCCESS;
2736 }
2737
2738 static test_return string_alloc_with_size(memcached_st *memc)
2739 {
2740 memcached_string_st *string;
2741
2742 string= memcached_string_create(memc, NULL, 1024);
2743 assert(string);
2744 memcached_string_free(string);
2745
2746 return TEST_SUCCESS;
2747 }
2748
2749 static test_return string_alloc_with_size_toobig(memcached_st *memc)
2750 {
2751 memcached_string_st *string;
2752
2753 string= memcached_string_create(memc, NULL, SIZE_MAX);
2754 assert(string == NULL);
2755
2756 return TEST_SUCCESS;
2757 }
2758
2759 static test_return string_alloc_append(memcached_st *memc)
2760 {
2761 unsigned int x;
2762 char buffer[SMALL_STRING_LEN];
2763 memcached_string_st *string;
2764
2765 /* Ring the bell! */
2766 memset(buffer, 6, SMALL_STRING_LEN);
2767
2768 string= memcached_string_create(memc, NULL, 100);
2769 assert(string);
2770
2771 for (x= 0; x < 1024; x++)
2772 {
2773 memcached_return rc;
2774 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2775 assert(rc == MEMCACHED_SUCCESS);
2776 }
2777 memcached_string_free(string);
2778
2779 return TEST_SUCCESS;
2780 }
2781
2782 static test_return string_alloc_append_toobig(memcached_st *memc)
2783 {
2784 memcached_return rc;
2785 unsigned int x;
2786 char buffer[SMALL_STRING_LEN];
2787 memcached_string_st *string;
2788
2789 /* Ring the bell! */
2790 memset(buffer, 6, SMALL_STRING_LEN);
2791
2792 string= memcached_string_create(memc, NULL, 100);
2793 assert(string);
2794
2795 for (x= 0; x < 1024; x++)
2796 {
2797 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2798 assert(rc == MEMCACHED_SUCCESS);
2799 }
2800 rc= memcached_string_append(string, buffer, SIZE_MAX);
2801 assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
2802 memcached_string_free(string);
2803
2804 return TEST_SUCCESS;
2805 }
2806
2807 static test_return cleanup_pairs(memcached_st *memc __attribute__((unused)))
2808 {
2809 pairs_free(global_pairs);
2810
2811 return TEST_SUCCESS;
2812 }
2813
2814 static test_return generate_pairs(memcached_st *memc __attribute__((unused)))
2815 {
2816 unsigned long long x;
2817 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
2818 global_count= GLOBAL_COUNT;
2819
2820 for (x= 0; x < global_count; x++)
2821 {
2822 global_keys[x]= global_pairs[x].key;
2823 global_keys_length[x]= global_pairs[x].key_length;
2824 }
2825
2826 return TEST_SUCCESS;
2827 }
2828
2829 static test_return generate_large_pairs(memcached_st *memc __attribute__((unused)))
2830 {
2831 unsigned long long x;
2832 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
2833 global_count= GLOBAL2_COUNT;
2834
2835 for (x= 0; x < global_count; x++)
2836 {
2837 global_keys[x]= global_pairs[x].key;
2838 global_keys_length[x]= global_pairs[x].key_length;
2839 }
2840
2841 return TEST_SUCCESS;
2842 }
2843
2844 static test_return generate_data(memcached_st *memc)
2845 {
2846 execute_set(memc, global_pairs, global_count);
2847
2848 return TEST_SUCCESS;
2849 }
2850
2851 static test_return generate_data_with_stats(memcached_st *memc)
2852 {
2853 memcached_stat_st *stat_p;
2854 memcached_return rc;
2855 uint32_t host_index= 0;
2856 execute_set(memc, global_pairs, global_count);
2857
2858 //TODO: hosts used size stats
2859 stat_p= memcached_stat(memc, NULL, &rc);
2860 assert(stat_p);
2861
2862 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
2863 {
2864 /* This test was changes so that "make test" would work properlly */
2865 #ifdef DEBUG
2866 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);
2867 #endif
2868 assert((unsigned long long)(stat_p + host_index)->bytes);
2869 }
2870
2871 memcached_stat_free(NULL, stat_p);
2872
2873 return TEST_SUCCESS;
2874 }
2875 static test_return generate_buffer_data(memcached_st *memc)
2876 {
2877 size_t latch= 0;
2878
2879 latch= 1;
2880 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
2881 generate_data(memc);
2882
2883 return TEST_SUCCESS;
2884 }
2885
2886 static test_return get_read_count(memcached_st *memc)
2887 {
2888 unsigned int x;
2889 memcached_return rc;
2890 memcached_st *memc_clone;
2891
2892 memc_clone= memcached_clone(NULL, memc);
2893 assert(memc_clone);
2894
2895 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
2896
2897 {
2898 char *return_value;
2899 size_t return_value_length;
2900 uint32_t flags;
2901 uint32_t count;
2902
2903 for (x= count= 0; x < global_count; x++)
2904 {
2905 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
2906 &return_value_length, &flags, &rc);
2907 if (rc == MEMCACHED_SUCCESS)
2908 {
2909 count++;
2910 if (return_value)
2911 free(return_value);
2912 }
2913 }
2914 }
2915
2916 memcached_free(memc_clone);
2917
2918 return TEST_SUCCESS;
2919 }
2920
2921 static test_return get_read(memcached_st *memc)
2922 {
2923 unsigned int x;
2924 memcached_return rc;
2925
2926 {
2927 char *return_value;
2928 size_t return_value_length;
2929 uint32_t flags;
2930
2931 for (x= 0; x < global_count; x++)
2932 {
2933 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
2934 &return_value_length, &flags, &rc);
2935 /*
2936 assert(return_value);
2937 assert(rc == MEMCACHED_SUCCESS);
2938 */
2939 if (rc == MEMCACHED_SUCCESS && return_value)
2940 free(return_value);
2941 }
2942 }
2943
2944 return TEST_SUCCESS;
2945 }
2946
2947 static test_return mget_read(memcached_st *memc)
2948 {
2949 memcached_return rc;
2950
2951 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2952 assert(rc == MEMCACHED_SUCCESS);
2953 assert(fetch_all_results(memc) == TEST_SUCCESS);
2954
2955 return TEST_SUCCESS;
2956 }
2957
2958 static test_return mget_read_result(memcached_st *memc)
2959 {
2960 memcached_return rc;
2961
2962 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2963 assert(rc == MEMCACHED_SUCCESS);
2964 /* Turn this into a help function */
2965 {
2966 memcached_result_st results_obj;
2967 memcached_result_st *results;
2968
2969 results= memcached_result_create(memc, &results_obj);
2970
2971 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
2972 {
2973 assert(results);
2974 assert(rc == MEMCACHED_SUCCESS);
2975 }
2976
2977 memcached_result_free(&results_obj);
2978 }
2979
2980 return TEST_SUCCESS;
2981 }
2982
2983 static test_return mget_read_function(memcached_st *memc)
2984 {
2985 memcached_return rc;
2986 unsigned int counter;
2987 memcached_execute_function callbacks[1];
2988
2989 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2990 assert(rc == MEMCACHED_SUCCESS);
2991
2992 callbacks[0]= &callback_counter;
2993 counter= 0;
2994 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
2995
2996 return TEST_SUCCESS;
2997 }
2998
2999 static test_return delete_generate(memcached_st *memc)
3000 {
3001 unsigned int x;
3002
3003 for (x= 0; x < global_count; x++)
3004 {
3005 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3006 }
3007
3008 return TEST_SUCCESS;
3009 }
3010
3011 static test_return delete_buffer_generate(memcached_st *memc)
3012 {
3013 size_t latch= 0;
3014 unsigned int x;
3015
3016 latch= 1;
3017 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3018
3019 for (x= 0; x < global_count; x++)
3020 {
3021 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3022 }
3023
3024 return TEST_SUCCESS;
3025 }
3026
3027 static test_return add_host_test1(memcached_st *memc)
3028 {
3029 unsigned int x;
3030 memcached_return rc;
3031 char servername[]= "0.example.com";
3032 memcached_server_st *servers;
3033
3034 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3035 assert(servers);
3036 assert(1 == memcached_server_list_count(servers));
3037
3038 for (x= 2; x < 20; x++)
3039 {
3040 char buffer[SMALL_STRING_LEN];
3041
3042 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
3043 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3044 &rc);
3045 assert(rc == MEMCACHED_SUCCESS);
3046 assert(x == memcached_server_list_count(servers));
3047 }
3048
3049 rc= memcached_server_push(memc, servers);
3050 assert(rc == MEMCACHED_SUCCESS);
3051 rc= memcached_server_push(memc, servers);
3052 assert(rc == MEMCACHED_SUCCESS);
3053
3054 memcached_server_list_free(servers);
3055
3056 return TEST_SUCCESS;
3057 }
3058
3059 static memcached_return pre_nonblock(memcached_st *memc)
3060 {
3061 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3062
3063 return MEMCACHED_SUCCESS;
3064 }
3065
3066 static memcached_return pre_nonblock_binary(memcached_st *memc)
3067 {
3068 memcached_return rc= MEMCACHED_FAILURE;
3069 memcached_st *memc_clone;
3070
3071 memc_clone= memcached_clone(NULL, memc);
3072 assert(memc_clone);
3073 // The memcached_version needs to be done on a clone, because the server
3074 // will not toggle protocol on an connection.
3075 memcached_version(memc_clone);
3076
3077 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3078 {
3079 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3080 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3081 assert(rc == MEMCACHED_SUCCESS);
3082 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3083 }
3084
3085 memcached_free(memc_clone);
3086 return rc;
3087 }
3088
3089 static memcached_return pre_murmur(memcached_st *memc)
3090 {
3091 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3092
3093 return MEMCACHED_SUCCESS;
3094 }
3095
3096 static memcached_return pre_jenkins(memcached_st *memc)
3097 {
3098 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3099
3100 return MEMCACHED_SUCCESS;
3101 }
3102
3103
3104 static memcached_return pre_md5(memcached_st *memc)
3105 {
3106 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3107
3108 return MEMCACHED_SUCCESS;
3109 }
3110
3111 static memcached_return pre_crc(memcached_st *memc)
3112 {
3113 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3114
3115 return MEMCACHED_SUCCESS;
3116 }
3117
3118 static memcached_return pre_hsieh(memcached_st *memc)
3119 {
3120 #ifdef HAVE_HSIEH_HASH
3121 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3122 return MEMCACHED_SUCCESS;
3123 #else
3124 (void) memc;
3125 return MEMCACHED_FAILURE;
3126 #endif
3127 }
3128
3129 static memcached_return pre_hash_fnv1_64(memcached_st *memc)
3130 {
3131 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
3132
3133 return MEMCACHED_SUCCESS;
3134 }
3135
3136 static memcached_return pre_hash_fnv1a_64(memcached_st *memc)
3137 {
3138 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3139
3140 return MEMCACHED_SUCCESS;
3141 }
3142
3143 static memcached_return pre_hash_fnv1_32(memcached_st *memc)
3144 {
3145 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3146
3147 return MEMCACHED_SUCCESS;
3148 }
3149
3150 static memcached_return pre_hash_fnv1a_32(memcached_st *memc)
3151 {
3152 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3153
3154 return MEMCACHED_SUCCESS;
3155 }
3156
3157 static memcached_return pre_behavior_ketama(memcached_st *memc)
3158 {
3159 memcached_return rc;
3160 uint64_t value;
3161
3162 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3163 assert(rc == MEMCACHED_SUCCESS);
3164
3165 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3166 assert(value == 1);
3167
3168 return MEMCACHED_SUCCESS;
3169 }
3170
3171 static memcached_return pre_behavior_ketama_weighted(memcached_st *memc)
3172 {
3173 memcached_return rc;
3174 uint64_t value;
3175
3176 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3177 assert(rc == MEMCACHED_SUCCESS);
3178
3179 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3180 assert(value == 1);
3181
3182 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3183 assert(rc == MEMCACHED_SUCCESS);
3184
3185 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3186 assert(value == MEMCACHED_HASH_MD5);
3187 return MEMCACHED_SUCCESS;
3188 }
3189
3190 static memcached_return pre_binary(memcached_st *memc)
3191 {
3192 memcached_return rc= MEMCACHED_FAILURE;
3193 memcached_st *memc_clone;
3194
3195 memc_clone= memcached_clone(NULL, memc);
3196 assert(memc_clone);
3197 // The memcached_version needs to be done on a clone, because the server
3198 // will not toggle protocol on an connection.
3199 memcached_version(memc_clone);
3200
3201 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3202 {
3203 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3204 assert(rc == MEMCACHED_SUCCESS);
3205 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3206 }
3207
3208 memcached_free(memc_clone);
3209 return rc;
3210 }
3211
3212 static memcached_return pre_replication(memcached_st *memc)
3213 {
3214 memcached_return rc= MEMCACHED_FAILURE;
3215 if (pre_binary(memc) == MEMCACHED_SUCCESS)
3216 {
3217 /*
3218 * Make sure that we store the item on all servers
3219 * (master + replicas == number of servers)
3220 */
3221 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3222 memc->number_of_hosts - 1);
3223 assert(rc == MEMCACHED_SUCCESS);
3224 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memc->number_of_hosts - 1);
3225 }
3226
3227 return rc;
3228 }
3229
3230 static memcached_return pre_replication_noblock(memcached_st *memc)
3231 {
3232 memcached_return rc= MEMCACHED_FAILURE;
3233 if (pre_replication(memc) == MEMCACHED_SUCCESS &&
3234 pre_nonblock(memc) == MEMCACHED_SUCCESS)
3235 rc= MEMCACHED_SUCCESS;
3236
3237 return rc;
3238 }
3239
3240 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3241 {
3242 free(mem);
3243 }
3244
3245 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3246 {
3247 void *ret= malloc(size);
3248 if (ret != NULL)
3249 memset(ret, 0xff, size);
3250
3251 return ret;
3252 }
3253
3254 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3255 {
3256 return realloc(mem, size);
3257 }
3258
3259 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3260 {
3261 return calloc(nelem, size);
3262 }
3263
3264 static memcached_return set_prefix(memcached_st *memc)
3265 {
3266 memcached_return rc;
3267 const char *key= "mine";
3268 char *value;
3269
3270 /* Make sure be default none exists */
3271 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3272 assert(rc == MEMCACHED_FAILURE);
3273
3274 /* Test a clean set */
3275 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3276 assert(rc == MEMCACHED_SUCCESS);
3277
3278 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3279 assert(memcmp(value, key, 4) == 0);
3280 assert(rc == MEMCACHED_SUCCESS);
3281
3282 /* Test that we can turn it off */
3283 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3284 assert(rc == MEMCACHED_SUCCESS);
3285
3286 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3287 assert(rc == MEMCACHED_FAILURE);
3288
3289 /* Now setup for main test */
3290 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3291 assert(rc == MEMCACHED_SUCCESS);
3292
3293 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3294 assert(rc == MEMCACHED_SUCCESS);
3295 assert(memcmp(value, key, 4) == 0);
3296
3297 /* Set to Zero, and then Set to something too large */
3298 {
3299 char long_key[255];
3300 memset(long_key, 0, 255);
3301
3302 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3303 assert(rc == MEMCACHED_SUCCESS);
3304
3305 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3306 assert(rc == MEMCACHED_FAILURE);
3307 assert(value == NULL);
3308
3309 /* Test a long key for failure */
3310 /* TODO, extend test to determine based on setting, what result should be */
3311 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3312 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3313 //assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3314 assert(rc == MEMCACHED_SUCCESS);
3315
3316 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3317 strcpy(long_key, "This is more then the allotted number of characters");
3318 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3319 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3320
3321 /* Test for a bad prefix, but with a short key */
3322 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3323 assert(rc == MEMCACHED_SUCCESS);
3324
3325 strcpy(long_key, "dog cat");
3326 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3327 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
3328 }
3329
3330 return MEMCACHED_SUCCESS;
3331 }
3332
3333 #ifdef MEMCACHED_ENABLE_DEPRECATED
3334 static memcached_return deprecated_set_memory_alloc(memcached_st *memc)
3335 {
3336 void *test_ptr= NULL;
3337 void *cb_ptr= NULL;
3338 {
3339 memcached_malloc_function malloc_cb=
3340 (memcached_malloc_function)my_malloc;
3341 cb_ptr= *(void **)&malloc_cb;
3342 memcached_return rc;
3343
3344 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3345 assert(rc == MEMCACHED_SUCCESS);
3346 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3347 assert(rc == MEMCACHED_SUCCESS);
3348 assert(test_ptr == cb_ptr);
3349 }
3350
3351 {
3352 memcached_realloc_function realloc_cb=
3353 (memcached_realloc_function)my_realloc;
3354 cb_ptr= *(void **)&realloc_cb;
3355 memcached_return rc;
3356
3357 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3358 assert(rc == MEMCACHED_SUCCESS);
3359 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3360 assert(rc == MEMCACHED_SUCCESS);
3361 assert(test_ptr == cb_ptr);
3362 }
3363
3364 {
3365 memcached_free_function free_cb=
3366 (memcached_free_function)my_free;
3367 cb_ptr= *(void **)&free_cb;
3368 memcached_return rc;
3369
3370 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3371 assert(rc == MEMCACHED_SUCCESS);
3372 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3373 assert(rc == MEMCACHED_SUCCESS);
3374 assert(test_ptr == cb_ptr);
3375 }
3376 return MEMCACHED_SUCCESS;
3377 }
3378 #endif
3379
3380 static memcached_return set_memory_alloc(memcached_st *memc)
3381 {
3382 memcached_return rc;
3383 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3384 my_realloc, my_calloc);
3385 assert(rc == MEMCACHED_FAILURE);
3386
3387 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3388 my_realloc, my_calloc);
3389
3390 memcached_malloc_function mem_malloc;
3391 memcached_free_function mem_free;
3392 memcached_realloc_function mem_realloc;
3393 memcached_calloc_function mem_calloc;
3394 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3395 &mem_realloc, &mem_calloc);
3396
3397 assert(mem_malloc == my_malloc);
3398 assert(mem_realloc == my_realloc);
3399 assert(mem_calloc == my_calloc);
3400 assert(mem_free == my_free);
3401
3402 return MEMCACHED_SUCCESS;
3403 }
3404
3405 static memcached_return enable_consistent(memcached_st *memc)
3406 {
3407 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3408 memcached_hash hash;
3409 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3410 if (pre_hsieh(memc) != MEMCACHED_SUCCESS)
3411 return MEMCACHED_FAILURE;
3412
3413 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3414 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3415
3416 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3417 assert(hash == MEMCACHED_HASH_HSIEH);
3418
3419
3420 return MEMCACHED_SUCCESS;
3421 }
3422
3423 static memcached_return enable_cas(memcached_st *memc)
3424 {
3425 unsigned int set= 1;
3426
3427 memcached_version(memc);
3428
3429 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3430 || memc->hosts[0].minor_version > 2)
3431 {
3432 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3433
3434 return MEMCACHED_SUCCESS;
3435 }
3436
3437 return MEMCACHED_FAILURE;
3438 }
3439
3440 static memcached_return check_for_1_2_3(memcached_st *memc)
3441 {
3442 memcached_version(memc);
3443
3444 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3445 || memc->hosts[0].minor_version > 2)
3446 return MEMCACHED_SUCCESS;
3447
3448 return MEMCACHED_FAILURE;
3449 }
3450
3451 static memcached_return pre_unix_socket(memcached_st *memc)
3452 {
3453 memcached_return rc;
3454 struct stat buf;
3455
3456 memcached_server_list_free(memc->hosts);
3457 memc->hosts= NULL;
3458 memc->number_of_hosts= 0;
3459
3460 if (stat("/tmp/memcached.socket", &buf))
3461 return MEMCACHED_FAILURE;
3462
3463 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3464
3465 return rc;
3466 }
3467
3468 static memcached_return pre_nodelay(memcached_st *memc)
3469 {
3470 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3471 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3472
3473 return MEMCACHED_SUCCESS;
3474 }
3475
3476 static memcached_return pre_settimer(memcached_st *memc)
3477 {
3478 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3479 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3480
3481 return MEMCACHED_SUCCESS;
3482 }
3483
3484 static memcached_return poll_timeout(memcached_st *memc)
3485 {
3486 size_t timeout;
3487
3488 timeout= 100;
3489
3490 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3491
3492 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3493
3494 assert(timeout == 100);
3495
3496 return MEMCACHED_SUCCESS;
3497 }
3498
3499 static test_return noreply_test(memcached_st *memc)
3500 {
3501 memcached_return ret;
3502 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3503 assert(ret == MEMCACHED_SUCCESS);
3504 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3505 assert(ret == MEMCACHED_SUCCESS);
3506 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3507 assert(ret == MEMCACHED_SUCCESS);
3508 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3509 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3510 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3511
3512 for (int count=0; count < 5; ++count)
3513 {
3514 for (int x=0; x < 100; ++x)
3515 {
3516 char key[10];
3517 size_t len= (size_t)sprintf(key, "%d", x);
3518 switch (count)
3519 {
3520 case 0:
3521 ret=memcached_add(memc, key, len, key, len, 0, 0);
3522 break;
3523 case 1:
3524 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3525 break;
3526 case 2:
3527 ret=memcached_set(memc, key, len, key, len, 0, 0);
3528 break;
3529 case 3:
3530 ret=memcached_append(memc, key, len, key, len, 0, 0);
3531 break;
3532 case 4:
3533 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3534 break;
3535 default:
3536 assert(count);
3537 break;
3538 }
3539 assert(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3540 }
3541
3542 /*
3543 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3544 ** API and is _ONLY_ done this way to verify that the library works the
3545 ** way it is supposed to do!!!!
3546 */
3547 int no_msg=0;
3548 for (uint32_t x=0; x < memc->number_of_hosts; ++x)
3549 no_msg+=(int)(memc->hosts[x].cursor_active);
3550
3551 assert(no_msg == 0);
3552 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3553
3554 /*
3555 ** Now validate that all items was set properly!
3556 */
3557 for (int x=0; x < 100; ++x)
3558 {
3559 char key[10];
3560 size_t len= (size_t)sprintf(key, "%d", x);
3561 size_t length;
3562 uint32_t flags;
3563 char* value=memcached_get(memc, key, strlen(key),
3564 &length, &flags, &ret);
3565 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3566 switch (count)
3567 {
3568 case 0: /* FALLTHROUGH */
3569 case 1: /* FALLTHROUGH */
3570 case 2:
3571 assert(strncmp(value, key, len) == 0);
3572 assert(len == length);
3573 break;
3574 case 3:
3575 assert(length == len * 2);
3576 break;
3577 case 4:
3578 assert(length == len * 3);
3579 break;
3580 default:
3581 assert(count);
3582 break;
3583 }
3584 free(value);
3585 }
3586 }
3587
3588 /* Try setting an illegal cas value (should not return an error to
3589 * the caller (because we don't expect a return message from the server)
3590 */
3591 const char* keys[]= {"0"};
3592 size_t lengths[]= {1};
3593 size_t length;
3594 uint32_t flags;
3595 memcached_result_st results_obj;
3596 memcached_result_st *results;
3597 ret= memcached_mget(memc, keys, lengths, 1);
3598 assert(ret == MEMCACHED_SUCCESS);
3599
3600 results= memcached_result_create(memc, &results_obj);
3601 assert(results);
3602 results= memcached_fetch_result(memc, &results_obj, &ret);
3603 assert(results);
3604 assert(ret == MEMCACHED_SUCCESS);
3605 uint64_t cas= memcached_result_cas(results);
3606 memcached_result_free(&results_obj);
3607
3608 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3609 assert(ret == MEMCACHED_SUCCESS);
3610
3611 /*
3612 * The item will have a new cas value, so try to set it again with the old
3613 * value. This should fail!
3614 */
3615 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3616 assert(ret == MEMCACHED_SUCCESS);
3617 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3618 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3619 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3620 free(value);
3621
3622 return TEST_SUCCESS;
3623 }
3624
3625 static test_return analyzer_test(memcached_st *memc)
3626 {
3627 memcached_return rc;
3628 memcached_stat_st *memc_stat;
3629 memcached_analysis_st *report;
3630
3631 memc_stat= memcached_stat(memc, NULL, &rc);
3632 assert(rc == MEMCACHED_SUCCESS);
3633 assert(memc_stat);
3634
3635 report= memcached_analyze(memc, memc_stat, &rc);
3636 assert(rc == MEMCACHED_SUCCESS);
3637 assert(report);
3638
3639 free(report);
3640 memcached_stat_free(NULL, memc_stat);
3641
3642 return TEST_SUCCESS;
3643 }
3644
3645 /* Count the objects */
3646 static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),
3647 const char *key __attribute__((unused)),
3648 size_t key_length __attribute__((unused)),
3649 void *context)
3650 {
3651 uint32_t *counter= (uint32_t *)context;
3652
3653 *counter= *counter + 1;
3654
3655 return MEMCACHED_SUCCESS;
3656 }
3657
3658 static test_return dump_test(memcached_st *memc)
3659 {
3660 memcached_return rc;
3661 uint32_t counter= 0;
3662 memcached_dump_func callbacks[1];
3663 test_return main_rc;
3664
3665 callbacks[0]= &callback_dump_counter;
3666
3667 /* No support for Binary protocol yet */
3668 if (memc->flags & MEM_BINARY_PROTOCOL)
3669 return TEST_SUCCESS;
3670
3671 main_rc= set_test3(memc);
3672
3673 assert (main_rc == TEST_SUCCESS);
3674
3675 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
3676 assert(rc == MEMCACHED_SUCCESS);
3677
3678 /* We may have more then 32 if our previous flush has not completed */
3679 assert(counter >= 32);
3680
3681 return TEST_SUCCESS;
3682 }
3683
3684 #ifdef HAVE_LIBMEMCACHEDUTIL
3685 static void* connection_release(void *arg) {
3686 struct {
3687 memcached_pool_st* pool;
3688 memcached_st* mmc;
3689 } *resource= arg;
3690
3691 usleep(250);
3692 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
3693 return arg;
3694 }
3695
3696 static test_return connection_pool_test(memcached_st *memc)
3697 {
3698 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
3699 assert(pool != NULL);
3700 memcached_st* mmc[10];
3701 memcached_return rc;
3702
3703 for (int x= 0; x < 10; ++x) {
3704 mmc[x]= memcached_pool_pop(pool, false, &rc);
3705 assert(mmc[x] != NULL);
3706 assert(rc == MEMCACHED_SUCCESS);
3707 }
3708
3709 assert(memcached_pool_pop(pool, false, &rc) == NULL);
3710 assert(rc == MEMCACHED_SUCCESS);
3711
3712 pthread_t tid;
3713 struct {
3714 memcached_pool_st* pool;
3715 memcached_st* mmc;
3716 } item= { .pool = pool, .mmc = mmc[9] };
3717 pthread_create(&tid, NULL, connection_release, &item);
3718 mmc[9]= memcached_pool_pop(pool, true, &rc);
3719 assert(rc == MEMCACHED_SUCCESS);
3720 pthread_join(tid, NULL);
3721 assert(mmc[9] == item.mmc);
3722 const char *key= "key";
3723 size_t keylen= strlen(key);
3724
3725 // verify that I can do ops with all connections
3726 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
3727 assert(rc == MEMCACHED_SUCCESS);
3728
3729 for (unsigned int x= 0; x < 10; ++x) {
3730 uint64_t number_value;
3731 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
3732 assert(rc == MEMCACHED_SUCCESS);
3733 assert(number_value == (x+1));
3734 }
3735
3736 // Release them..
3737 for (int x= 0; x < 10; ++x)
3738 assert(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
3739
3740
3741 /* verify that I can set behaviors on the pool when I don't have all
3742 * of the connections in the pool. It should however be enabled
3743 * when I push the item into the pool
3744 */
3745 mmc[0]= memcached_pool_pop(pool, false, &rc);
3746 assert(mmc[0] != NULL);
3747
3748 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
3749 assert(rc == MEMCACHED_SUCCESS);
3750
3751 mmc[1]= memcached_pool_pop(pool, false, &rc);
3752 assert(mmc[1] != NULL);
3753
3754 assert(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3755 assert(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
3756 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3757
3758 mmc[0]= memcached_pool_pop(pool, false, &rc);
3759 assert(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
3760 assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
3761
3762
3763 assert(memcached_pool_destroy(pool) == memc);
3764 return TEST_SUCCESS;
3765 }
3766 #endif
3767
3768 static test_return replication_set_test(memcached_st *memc)
3769 {
3770 memcached_return rc;
3771 memcached_st *memc_clone= memcached_clone(NULL, memc);
3772 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3773
3774 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
3775 assert(rc == MEMCACHED_SUCCESS);
3776
3777 /*
3778 ** We are using the quiet commands to store the replicas, so we need
3779 ** to ensure that all of them are processed before we can continue.
3780 ** In the test we go directly from storing the object to trying to
3781 ** receive the object from all of the different servers, so we
3782 ** could end up in a race condition (the memcached server hasn't yet
3783 ** processed the quiet command from the replication set when it process
3784 ** the request from the other client (created by the clone)). As a
3785 ** workaround for that we call memcached_quit to send the quit command
3786 ** to the server and wait for the response ;-) If you use the test code
3787 ** as an example for your own code, please note that you shouldn't need
3788 ** to do this ;-)
3789 */
3790 memcached_quit(memc);
3791
3792 /*
3793 ** "bubba" should now be stored on all of our servers. We don't have an
3794 ** easy to use API to address each individual server, so I'll just iterate
3795 ** through a bunch of "master keys" and I should most likely hit all of the
3796 ** servers...
3797 */
3798 for (int x= 'a'; x <= 'z'; ++x)
3799 {
3800 char key[2]= { [0]= (char)x };
3801 size_t len;
3802 uint32_t flags;
3803 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
3804 &len, &flags, &rc);
3805 assert(rc == MEMCACHED_SUCCESS);
3806 assert(val != NULL);
3807 free(val);
3808 }
3809
3810 memcached_free(memc_clone);
3811
3812 return TEST_SUCCESS;
3813 }
3814
3815 static test_return replication_get_test(memcached_st *memc)
3816 {
3817 memcached_return rc;
3818
3819 /*
3820 * Don't do the following in your code. I am abusing the internal details
3821 * within the library, and this is not a supported interface.
3822 * This is to verify correct behavior in the library
3823 */
3824 for (uint32_t host= 0; host < memc->number_of_hosts; ++host)
3825 {
3826 memcached_st *memc_clone= memcached_clone(NULL, memc);
3827 memc_clone->hosts[host].port= 0;
3828
3829 for (int x= 'a'; x <= 'z'; ++x)
3830 {
3831 char key[2]= { [0]= (char)x };
3832 size_t len;
3833 uint32_t flags;
3834 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
3835 &len, &flags, &rc);
3836 assert(rc == MEMCACHED_SUCCESS);
3837 assert(val != NULL);
3838 free(val);
3839 }
3840
3841 memcached_free(memc_clone);
3842 }
3843
3844 return TEST_SUCCESS;
3845 }
3846
3847 static test_return replication_mget_test(memcached_st *memc)
3848 {
3849 memcached_return rc;
3850 memcached_st *memc_clone= memcached_clone(NULL, memc);
3851 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
3852
3853 const char *keys[]= { "bubba", "key1", "key2", "key3" };
3854 size_t len[]= { 5, 4, 4, 4 };
3855
3856 for (int x=0; x< 4; ++x)
3857 {
3858 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
3859 assert(rc == MEMCACHED_SUCCESS);
3860 }
3861
3862 /*
3863 ** We are using the quiet commands to store the replicas, so we need
3864 ** to ensure that all of them are processed before we can continue.
3865 ** In the test we go directly from storing the object to trying to
3866 ** receive the object from all of the different servers, so we
3867 ** could end up in a race condition (the memcached server hasn't yet
3868 ** processed the quiet command from the replication set when it process
3869 ** the request from the other client (created by the clone)). As a
3870 ** workaround for that we call memcached_quit to send the quit command
3871 ** to the server and wait for the response ;-) If you use the test code
3872 ** as an example for your own code, please note that you shouldn't need
3873 ** to do this ;-)
3874 */
3875 memcached_quit(memc);
3876
3877 /*
3878 * Don't do the following in your code. I am abusing the internal details
3879 * within the library, and this is not a supported interface.
3880 * This is to verify correct behavior in the library
3881 */
3882 memcached_result_st result_obj;
3883 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
3884 {
3885 memcached_st *new_clone= memcached_clone(NULL, memc);
3886 new_clone->hosts[host].port= 0;
3887
3888 for (int x= 'a'; x <= 'z'; ++x)
3889 {
3890 const char key[2]= { [0]= (const char)x };
3891
3892 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
3893 assert(rc == MEMCACHED_SUCCESS);
3894
3895 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
3896 assert(results);
3897
3898 int hits= 0;
3899 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
3900 {
3901 hits++;
3902 }
3903 assert(hits == 4);
3904 memcached_result_free(&result_obj);
3905 }
3906
3907 memcached_free(new_clone);
3908 }
3909
3910 memcached_free(memc_clone);
3911
3912 return TEST_SUCCESS;
3913 }
3914
3915 static test_return replication_delete_test(memcached_st *memc)
3916 {
3917 memcached_return rc;
3918 memcached_st *memc_clone= memcached_clone(NULL, memc);
3919 /* Delete the items from all of the servers except 1 */
3920 uint64_t repl= memcached_behavior_get(memc,
3921 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
3922 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
3923
3924 const char *keys[]= { "bubba", "key1", "key2", "key3" };
3925 size_t len[]= { 5, 4, 4, 4 };
3926
3927 for (int x=0; x< 4; ++x)
3928 {
3929 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
3930 assert(rc == MEMCACHED_SUCCESS);
3931 }
3932
3933 /*
3934 * Don't do the following in your code. I am abusing the internal details
3935 * within the library, and this is not a supported interface.
3936 * This is to verify correct behavior in the library
3937 */
3938 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
3939 for (uint32_t x= 0; x < (repl + 1); ++x)
3940 {
3941 memc_clone->hosts[hash].port= 0;
3942 if (++hash == memc_clone->number_of_hosts)
3943 hash= 0;
3944 }
3945
3946 memcached_result_st result_obj;
3947 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
3948 {
3949 for (int x= 'a'; x <= 'z'; ++x)
3950 {
3951 const char key[2]= { [0]= (const char)x };
3952
3953 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
3954 assert(rc == MEMCACHED_SUCCESS);
3955
3956 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
3957 assert(results);
3958
3959 int hits= 0;
3960 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
3961 {
3962 ++hits;
3963 }
3964 assert(hits == 4);
3965 memcached_result_free(&result_obj);
3966 }
3967 }
3968 memcached_free(memc_clone);
3969
3970 return TEST_SUCCESS;
3971 }
3972
3973 static void increment_request_id(uint16_t *id)
3974 {
3975 (*id)++;
3976 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
3977 *id= 0;
3978 }
3979
3980 static uint16_t *get_udp_request_ids(memcached_st *memc)
3981 {
3982 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
3983 assert(ids != NULL);
3984 unsigned int x;
3985
3986 for (x= 0; x < memc->number_of_hosts; x++)
3987 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
3988
3989 return ids;
3990 }
3991
3992 static test_return post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
3993 {
3994 unsigned int x;
3995 memcached_server_st *cur_server = memc->hosts;
3996 uint16_t *cur_req_ids = get_udp_request_ids(memc);
3997
3998 for (x= 0; x < memc->number_of_hosts; x++)
3999 {
4000 assert(cur_server[x].cursor_active == 0);
4001 assert(cur_req_ids[x] == expected_req_ids[x]);
4002 }
4003 free(expected_req_ids);
4004 free(cur_req_ids);
4005
4006 return TEST_SUCCESS;
4007 }
4008
4009 /*
4010 ** There is a little bit of a hack here, instead of removing
4011 ** the servers, I just set num host to 0 and them add then new udp servers
4012 **/
4013 static memcached_return init_udp(memcached_st *memc)
4014 {
4015 memcached_version(memc);
4016 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4017 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
4018 || memc->hosts[0].micro_version < 6)
4019 return MEMCACHED_FAILURE;
4020
4021 uint32_t num_hosts= memc->number_of_hosts;
4022 unsigned int x= 0;
4023 memcached_server_st servers[num_hosts];
4024 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
4025 for (x= 0; x < num_hosts; x++)
4026 memcached_server_free(&memc->hosts[x]);
4027
4028 memc->number_of_hosts= 0;
4029 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4030 for (x= 0; x < num_hosts; x++)
4031 {
4032 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4033 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4034 }
4035
4036 return MEMCACHED_SUCCESS;
4037 }
4038
4039 static memcached_return binary_init_udp(memcached_st *memc)
4040 {
4041 pre_binary(memc);
4042 return init_udp(memc);
4043 }
4044
4045 /* Make sure that I cant add a tcp server to a udp client */
4046 static test_return add_tcp_server_udp_client_test(memcached_st *memc)
4047 {
4048 memcached_server_st server;
4049 memcached_server_clone(&server, &memc->hosts[0]);
4050 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4051 assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4052 return TEST_SUCCESS;
4053 }
4054
4055 /* Make sure that I cant add a udp server to a tcp client */
4056 static test_return add_udp_server_tcp_client_test(memcached_st *memc)
4057 {
4058 memcached_server_st server;
4059 memcached_server_clone(&server, &memc->hosts[0]);
4060 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4061
4062 memcached_st tcp_client;
4063 memcached_create(&tcp_client);
4064 assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4065 return TEST_SUCCESS;
4066 }
4067
4068 static test_return set_udp_behavior_test(memcached_st *memc)
4069 {
4070
4071 memcached_quit(memc);
4072 memc->number_of_hosts= 0;
4073 run_distribution(memc);
4074 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4075 assert(memc->flags & MEM_USE_UDP);
4076 assert(memc->flags & MEM_NOREPLY);;
4077
4078 assert(memc->number_of_hosts == 0);
4079
4080 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4081 assert(!(memc->flags & MEM_USE_UDP));
4082 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4083 assert(!(memc->flags & MEM_NOREPLY));
4084 return TEST_SUCCESS;
4085 }
4086
4087 static test_return udp_set_test(memcached_st *memc)
4088 {
4089 unsigned int x= 0;
4090 unsigned int num_iters= 1025; //request id rolls over at 1024
4091 for (x= 0; x < num_iters;x++)
4092 {
4093 memcached_return rc;
4094 const char *key= "foo";
4095 const char *value= "when we sanitize";
4096 uint16_t *expected_ids= get_udp_request_ids(memc);
4097 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
4098 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4099 rc= memcached_set(memc, key, strlen(key),
4100 value, strlen(value),
4101 (time_t)0, (uint32_t)0);
4102 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4103 /** NB, the check below assumes that if new write_ptr is less than
4104 * the original write_ptr that we have flushed. For large payloads, this
4105 * maybe an invalid assumption, but for the small payload we have it is OK
4106 */
4107 if (rc == MEMCACHED_SUCCESS ||
4108 memc->hosts[server_key].write_buffer_offset < init_offset)
4109 increment_request_id(&expected_ids[server_key]);
4110
4111 if (rc == MEMCACHED_SUCCESS)
4112 {
4113 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4114 }
4115 else
4116 {
4117 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4118 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4119 }
4120 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4121 }
4122 return TEST_SUCCESS;
4123 }
4124
4125 static test_return udp_buffered_set_test(memcached_st *memc)
4126 {
4127 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4128 return udp_set_test(memc);
4129 }
4130
4131 static test_return udp_set_too_big_test(memcached_st *memc)
4132 {
4133 memcached_return rc;
4134 const char *key= "bar";
4135 char value[MAX_UDP_DATAGRAM_LENGTH];
4136 uint16_t *expected_ids= get_udp_request_ids(memc);
4137 rc= memcached_set(memc, key, strlen(key),
4138 value, MAX_UDP_DATAGRAM_LENGTH,
4139 (time_t)0, (uint32_t)0);
4140 assert(rc == MEMCACHED_WRITE_FAILURE);
4141 return post_udp_op_check(memc,expected_ids);
4142 }
4143
4144 static test_return udp_delete_test(memcached_st *memc)
4145 {
4146 unsigned int x= 0;
4147 unsigned int num_iters= 1025; //request id rolls over at 1024
4148 for (x= 0; x < num_iters;x++)
4149 {
4150 memcached_return rc;
4151 const char *key= "foo";
4152 uint16_t *expected_ids=get_udp_request_ids(memc);
4153 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4154 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4155 rc= memcached_delete(memc, key, strlen(key), 0);
4156 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4157 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
4158 increment_request_id(&expected_ids[server_key]);
4159 if (rc == MEMCACHED_SUCCESS)
4160 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4161 else
4162 {
4163 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4164 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4165 }
4166 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4167 }
4168 return TEST_SUCCESS;
4169 }
4170
4171 static test_return udp_buffered_delete_test(memcached_st *memc)
4172 {
4173 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4174 return udp_delete_test(memc);
4175 }
4176
4177 static test_return udp_verbosity_test(memcached_st *memc)
4178 {
4179 memcached_return rc;
4180 uint16_t *expected_ids= get_udp_request_ids(memc);
4181 unsigned int x;
4182 for (x= 0; x < memc->number_of_hosts;x++)
4183 increment_request_id(&expected_ids[x]);
4184
4185 rc= memcached_verbosity(memc,3);
4186 assert(rc == MEMCACHED_SUCCESS);
4187 return post_udp_op_check(memc,expected_ids);
4188 }
4189
4190 static test_return udp_quit_test(memcached_st *memc)
4191 {
4192 uint16_t *expected_ids= get_udp_request_ids(memc);
4193 memcached_quit(memc);
4194 return post_udp_op_check(memc, expected_ids);
4195 }
4196
4197 static test_return udp_flush_test(memcached_st *memc)
4198 {
4199 memcached_return rc;
4200 uint16_t *expected_ids= get_udp_request_ids(memc);
4201 unsigned int x;
4202 for (x= 0; x < memc->number_of_hosts;x++)
4203 increment_request_id(&expected_ids[x]);
4204
4205 rc= memcached_flush(memc,0);
4206 assert(rc == MEMCACHED_SUCCESS);
4207 return post_udp_op_check(memc,expected_ids);
4208 }
4209
4210 static test_return udp_incr_test(memcached_st *memc)
4211 {
4212 memcached_return rc;
4213 const char *key= "incr";
4214 const char *value= "1";
4215 rc= memcached_set(memc, key, strlen(key),
4216 value, strlen(value),
4217 (time_t)0, (uint32_t)0);
4218
4219 assert(rc == MEMCACHED_SUCCESS);
4220 uint16_t *expected_ids= get_udp_request_ids(memc);
4221 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4222 increment_request_id(&expected_ids[server_key]);
4223 uint64_t newvalue;
4224 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4225 assert(rc == MEMCACHED_SUCCESS);
4226 return post_udp_op_check(memc, expected_ids);
4227 }
4228
4229 static test_return udp_decr_test(memcached_st *memc)
4230 {
4231 memcached_return rc;
4232 const char *key= "decr";
4233 const char *value= "1";
4234 rc= memcached_set(memc, key, strlen(key),
4235 value, strlen(value),
4236 (time_t)0, (uint32_t)0);
4237
4238 assert(rc == MEMCACHED_SUCCESS);
4239 uint16_t *expected_ids= get_udp_request_ids(memc);
4240 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4241 increment_request_id(&expected_ids[server_key]);
4242 uint64_t newvalue;
4243 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4244 assert(rc == MEMCACHED_SUCCESS);
4245 return post_udp_op_check(memc, expected_ids);
4246 }
4247
4248
4249 static test_return udp_stat_test(memcached_st *memc)
4250 {
4251 memcached_stat_st * rv= NULL;
4252 memcached_return rc;
4253 char args[]= "";
4254 uint16_t *expected_ids = get_udp_request_ids(memc);
4255 rv = memcached_stat(memc, args, &rc);
4256 free(rv);
4257 assert(rc == MEMCACHED_NOT_SUPPORTED);
4258 return post_udp_op_check(memc, expected_ids);
4259 }
4260
4261 static test_return udp_version_test(memcached_st *memc)
4262 {
4263 memcached_return rc;
4264 uint16_t *expected_ids = get_udp_request_ids(memc);
4265 rc = memcached_version(memc);
4266 assert(rc == MEMCACHED_NOT_SUPPORTED);
4267 return post_udp_op_check(memc, expected_ids);
4268 }
4269
4270 static test_return udp_get_test(memcached_st *memc)
4271 {
4272 memcached_return rc;
4273 const char *key= "foo";
4274 size_t vlen;
4275 uint16_t *expected_ids = get_udp_request_ids(memc);
4276 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4277 assert(rc == MEMCACHED_NOT_SUPPORTED);
4278 assert(val == NULL);
4279 return post_udp_op_check(memc, expected_ids);
4280 }
4281
4282 static test_return udp_mixed_io_test(memcached_st *memc)
4283 {
4284 test_st current_op;
4285 test_st mixed_io_ops [] ={
4286 {"udp_set_test", 0, udp_set_test},
4287 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4288 {"udp_delete_test", 0, udp_delete_test},
4289 {"udp_verbosity_test", 0, udp_verbosity_test},
4290 {"udp_quit_test", 0, udp_quit_test},
4291 {"udp_flush_test", 0, udp_flush_test},
4292 {"udp_incr_test", 0, udp_incr_test},
4293 {"udp_decr_test", 0, udp_decr_test},
4294 {"udp_version_test", 0, udp_version_test}
4295 };
4296 unsigned int x= 0;
4297 for (x= 0; x < 500; x++)
4298 {
4299 current_op= mixed_io_ops[random() % 9];
4300 assert(current_op.function(memc) == TEST_SUCCESS);
4301 }
4302 return TEST_SUCCESS;
4303 }
4304
4305 static test_return hsieh_avaibility_test (memcached_st *memc)
4306 {
4307 memcached_return expected_rc= MEMCACHED_FAILURE;
4308 #ifdef HAVE_HSIEH_HASH
4309 expected_rc= MEMCACHED_SUCCESS;
4310 #endif
4311 memcached_return rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4312 (uint64_t)MEMCACHED_HASH_HSIEH);
4313 assert(rc == expected_rc);
4314 return TEST_SUCCESS;
4315 }
4316
4317 static const char *list[]=
4318 {
4319 "apple",
4320 "beat",
4321 "carrot",
4322 "daikon",
4323 "eggplant",
4324 "flower",
4325 "green",
4326 "hide",
4327 "ick",
4328 "jack",
4329 "kick",
4330 "lime",
4331 "mushrooms",
4332 "nectarine",
4333 "orange",
4334 "peach",
4335 "quant",
4336 "ripen",
4337 "strawberry",
4338 "tang",
4339 "up",
4340 "volumne",
4341 "when",
4342 "yellow",
4343 "zip",
4344 NULL
4345 };
4346
4347 static test_return md5_run (memcached_st *memc __attribute__((unused)))
4348 {
4349 uint32_t x;
4350 const char **ptr;
4351 uint32_t values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
4352 245758794U, 2550894432U, 121710495U, 3053817768U,
4353 1250994555U, 1862072655U, 2631955953U, 2951528551U,
4354 1451250070U, 2820856945U, 2060845566U, 3646985608U,
4355 2138080750U, 217675895U, 2230934345U, 1234361223U,
4356 3968582726U, 2455685270U, 1293568479U, 199067604U,
4357 2042482093U };
4358
4359
4360 for (ptr= list, x= 0; *ptr; ptr++, x++)
4361 {
4362 uint32_t hash_val;
4363
4364 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4365 assert(values[x] == hash_val);
4366 }
4367
4368 return TEST_SUCCESS;
4369 }
4370
4371 static test_return crc_run (memcached_st *memc __attribute__((unused)))
4372 {
4373 uint32_t x;
4374 const char **ptr;
4375 uint32_t values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
4376 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
4377 7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
4378 17300U, 28156U, 9192U, 20484U, 16925U };
4379
4380 for (ptr= list, x= 0; *ptr; ptr++, x++)
4381 {
4382 uint32_t hash_val;
4383
4384 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4385 assert(values[x] == hash_val);
4386 }
4387
4388 return TEST_SUCCESS;
4389 }
4390
4391 static test_return fnv1_64_run (memcached_st *memc __attribute__((unused)))
4392 {
4393 uint32_t x;
4394 const char **ptr;
4395 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4396 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4397 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4398 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4399 2815549194U, 2562818319U, 224996066U, 2680194749U,
4400 3035305390U, 246890365U, 2395624193U, 4145193337U,
4401 1801941682U };
4402
4403 for (ptr= list, x= 0; *ptr; ptr++, x++)
4404 {
4405 uint32_t hash_val;
4406
4407 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4408 assert(values[x] == hash_val);
4409 }
4410
4411 return TEST_SUCCESS;
4412 }
4413
4414 static test_return fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4415 {
4416 uint32_t x;
4417 const char **ptr;
4418 uint32_t values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
4419 3647689787U, 3241528582U, 1669328060U, 2604311949U,
4420 734810122U, 1516407546U, 560948863U, 1767346780U,
4421 561034892U, 4156330026U, 3716417003U, 3475297030U,
4422 1518272172U, 227211583U, 3938128828U, 126112909U,
4423 3043416448U, 3131561933U, 1328739897U, 2455664041U,
4424 2272238452U };
4425
4426 for (ptr= list, x= 0; *ptr; ptr++, x++)
4427 {
4428 uint32_t hash_val;
4429
4430 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4431 assert(values[x] == hash_val);
4432 }
4433
4434 return TEST_SUCCESS;
4435 }
4436
4437 static test_return fnv1_32_run (memcached_st *memc __attribute__((unused)))
4438 {
4439 uint32_t x;
4440 const char **ptr;
4441 uint32_t values[]= { 67176023U, 1190179409U, 2043204404U, 3221866419U,
4442 2567703427U, 3787535528U, 4147287986U, 3500475733U,
4443 344481048U, 3865235296U, 2181839183U, 119581266U,
4444 510234242U, 4248244304U, 1362796839U, 103389328U,
4445 1449620010U, 182962511U, 3554262370U, 3206747549U,
4446 1551306158U, 4127558461U, 1889140833U, 2774173721U,
4447 1180552018U };
4448
4449
4450 for (ptr= list, x= 0; *ptr; ptr++, x++)
4451 {
4452 uint32_t hash_val;
4453
4454 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4455 assert(values[x] == hash_val);
4456 }
4457
4458 return TEST_SUCCESS;
4459 }
4460
4461 static test_return fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4462 {
4463 uint32_t x;
4464 const char **ptr;
4465 uint32_t values[]= { 280767167U, 2421315013U, 3072375666U, 855001899U,
4466 459261019U, 3521085446U, 18738364U, 1625305005U,
4467 2162232970U, 777243802U, 3323728671U, 132336572U,
4468 3654473228U, 260679466U, 1169454059U, 2698319462U,
4469 1062177260U, 235516991U, 2218399068U, 405302637U,
4470 1128467232U, 3579622413U, 2138539289U, 96429129U,
4471 2877453236U };
4472
4473 for (ptr= list, x= 0; *ptr; ptr++, x++)
4474 {
4475 uint32_t hash_val;
4476
4477 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4478 assert(values[x] == hash_val);
4479 }
4480
4481 return TEST_SUCCESS;
4482 }
4483
4484 static test_return hsieh_run (memcached_st *memc __attribute__((unused)))
4485 {
4486 uint32_t x;
4487 const char **ptr;
4488 #ifdef HAVE_HSIEH_HASH
4489 uint32_t values[]= { 3738850110, 3636226060, 3821074029, 3489929160, 3485772682, 80540287,
4490 1805464076, 1895033657, 409795758, 979934958, 3634096985, 1284445480,
4491 2265380744, 707972988, 353823508, 1549198350, 1327930172, 9304163,
4492 4220749037, 2493964934, 2777873870, 2057831732, 1510213931, 2027828987,
4493 3395453351 };
4494 #else
4495 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 };
4496 #endif
4497
4498 for (ptr= list, x= 0; *ptr; ptr++, x++)
4499 {
4500 uint32_t hash_val;
4501
4502 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4503 assert(values[x] == hash_val);
4504 }
4505
4506 return TEST_SUCCESS;
4507 }
4508
4509 static test_return murmur_run (memcached_st *memc __attribute__((unused)))
4510 {
4511 uint32_t x;
4512 const char **ptr;
4513 uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
4514 1722477987U, 2991193800U, 4147007314U, 3633179701U,
4515 1805162104U, 3503289120U, 3395702895U, 3325073042U,
4516 2345265314U, 3340346032U, 2722964135U, 1173398992U,
4517 2815549194U, 2562818319U, 224996066U, 2680194749U,
4518 3035305390U, 246890365U, 2395624193U, 4145193337U,
4519 1801941682U };
4520
4521 for (ptr= list, x= 0; *ptr; ptr++, x++)
4522 {
4523 uint32_t hash_val;
4524
4525 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4526 assert(values[x] == hash_val);
4527 }
4528
4529 return TEST_SUCCESS;
4530 }
4531
4532 static test_return jenkins_run (memcached_st *memc __attribute__((unused)))
4533 {
4534 uint32_t x;
4535 const char **ptr;
4536 uint32_t values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U,
4537 3261968576U, 3515188778U, 4232909173U, 4288625128U,
4538 1812047395U, 3689182164U, 2502979932U, 1214050606U,
4539 2415988847U, 1494268927U, 1025545760U, 3920481083U,
4540 4153263658U, 3824871822U, 3072759809U, 798622255U,
4541 3065432577U, 1453328165U, 2691550971U, 3408888387U,
4542 2629893356U };
4543
4544
4545 for (ptr= list, x= 0; *ptr; ptr++, x++)
4546 {
4547 uint32_t hash_val;
4548
4549 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4550 assert(values[x] == hash_val);
4551 }
4552
4553 return TEST_SUCCESS;
4554 }
4555
4556 static test_return regression_bug_434484(memcached_st *memc)
4557 {
4558 if (pre_binary(memc) != TEST_SUCCESS)
4559 return TEST_SUCCESS;
4560
4561 memcached_return ret;
4562 const char *key= "regression_bug_434484";
4563 size_t keylen= strlen(key);
4564
4565 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
4566 assert(ret == MEMCACHED_NOTSTORED);
4567
4568 size_t size= 2048 * 1024;
4569 void *data= calloc(1, size);
4570 assert(data != NULL);
4571 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
4572 assert(ret == MEMCACHED_E2BIG);
4573 free(data);
4574
4575 return TEST_SUCCESS;
4576 }
4577
4578 static test_return regression_bug_434843(memcached_st *memc)
4579 {
4580 if (pre_binary(memc) != TEST_SUCCESS)
4581 return TEST_SUCCESS;
4582
4583 memcached_return rc;
4584 unsigned int counter= 0;
4585 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
4586
4587 /*
4588 * I only want to hit only _one_ server so I know the number of requests I'm
4589 * sending in the pipleine to the server. Let's try to do a multiget of
4590 * 10240 (that should satisfy most users don't you tink?)
4591 */
4592 uint32_t number_of_hosts= memc->number_of_hosts;
4593 memc->number_of_hosts= 1;
4594 const size_t max_keys= 10240;
4595 char **keys= calloc(max_keys, sizeof(char*));
4596 size_t *key_length=calloc(max_keys, sizeof(size_t));
4597
4598 for (int x= 0; x < (int)max_keys; ++x)
4599 {
4600 char k[251];
4601 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
4602 keys[x]= strdup(k);
4603 assert(keys[x] != NULL);
4604 }
4605
4606 /*
4607 * Run two times.. the first time we should have 100% cache miss,
4608 * and the second time we should have 100% cache hits
4609 */
4610 for (int y= 0; y < 2; ++y)
4611 {
4612 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
4613 assert(rc == MEMCACHED_SUCCESS);
4614 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
4615 if (y == 0)
4616 {
4617 /* The first iteration should give me a 100% cache miss. verify that*/
4618 assert(counter == 0);
4619 char blob[1024]= { 0 };
4620 for (int x= 0; x < (int)max_keys; ++x)
4621 {
4622 rc= memcached_add(memc, keys[x], key_length[x],
4623 blob, sizeof(blob), 0, 0);
4624 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4625 }
4626 }
4627 else
4628 {
4629 /* Verify that we received all of the key/value pairs */
4630 assert(counter == (unsigned int)max_keys);
4631 }
4632 }
4633
4634 /* Release allocated resources */
4635 for (size_t x= 0; x < max_keys; ++x)
4636 free(keys[x]);
4637 free(keys);
4638 free(key_length);
4639
4640 memc->number_of_hosts= number_of_hosts;
4641 return TEST_SUCCESS;
4642 }
4643
4644 static test_return regression_bug_434843_buffered(memcached_st *memc)
4645 {
4646 memcached_return rc;
4647 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4648 assert(rc == MEMCACHED_SUCCESS);
4649
4650 return regression_bug_434843(memc);
4651 }
4652
4653 static test_return regression_bug_421108(memcached_st *memc)
4654 {
4655 memcached_return rc;
4656 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
4657 assert(rc == MEMCACHED_SUCCESS);
4658
4659 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
4660 assert(rc == MEMCACHED_SUCCESS);
4661 assert(bytes != NULL);
4662 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
4663 "bytes_read", &rc);
4664 assert(rc == MEMCACHED_SUCCESS);
4665 assert(bytes_read != NULL);
4666
4667 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
4668 "bytes_written", &rc);
4669 assert(rc == MEMCACHED_SUCCESS);
4670 assert(bytes_written != NULL);
4671
4672 assert(strcmp(bytes, bytes_read) != 0);
4673 assert(strcmp(bytes, bytes_written) != 0);
4674
4675 /* Release allocated resources */
4676 free(bytes);
4677 free(bytes_read);
4678 free(bytes_written);
4679 memcached_stat_free(NULL, memc_stat);
4680 return TEST_SUCCESS;
4681 }
4682
4683 /*
4684 * The test case isn't obvious so I should probably document why
4685 * it works the way it does. Bug 442914 was caused by a bug
4686 * in the logic in memcached_purge (it did not handle the case
4687 * where the number of bytes sent was equal to the watermark).
4688 * In this test case, create messages so that we hit that case
4689 * and then disable noreply mode and issue a new command to
4690 * verify that it isn't stuck. If we change the format for the
4691 * delete command or the watermarks, we need to update this
4692 * test....
4693 */
4694 static test_return regression_bug_442914(memcached_st *memc)
4695 {
4696 memcached_return rc;
4697 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4698 assert(rc == MEMCACHED_SUCCESS);
4699 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
4700
4701 uint32_t number_of_hosts= memc->number_of_hosts;
4702 memc->number_of_hosts= 1;
4703
4704 char k[250];
4705 size_t len;
4706
4707 for (int x= 0; x < 250; ++x)
4708 {
4709 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
4710 rc= memcached_delete(memc, k, len, 0);
4711 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4712 }
4713
4714 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
4715 rc= memcached_delete(memc, k, len, 0);
4716 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4717
4718 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
4719 assert(rc == MEMCACHED_SUCCESS);
4720 rc= memcached_delete(memc, k, len, 0);
4721 assert(rc == MEMCACHED_NOTFOUND);
4722
4723 memc->number_of_hosts= number_of_hosts;
4724
4725 return TEST_SUCCESS;
4726 }
4727
4728 test_st udp_setup_server_tests[] ={
4729 {"set_udp_behavior_test", 0, set_udp_behavior_test},
4730 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
4731 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
4732 {0, 0, 0}
4733 };
4734
4735 test_st upd_io_tests[] ={
4736 {"udp_set_test", 0, udp_set_test},
4737 {"udp_buffered_set_test", 0, udp_buffered_set_test},
4738 {"udp_set_too_big_test", 0, udp_set_too_big_test},
4739 {"udp_delete_test", 0, udp_delete_test},
4740 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
4741 {"udp_verbosity_test", 0, udp_verbosity_test},
4742 {"udp_quit_test", 0, udp_quit_test},
4743 {"udp_flush_test", 0, udp_flush_test},
4744 {"udp_incr_test", 0, udp_incr_test},
4745 {"udp_decr_test", 0, udp_decr_test},
4746 {"udp_stat_test", 0, udp_stat_test},
4747 {"udp_version_test", 0, udp_version_test},
4748 {"udp_get_test", 0, udp_get_test},
4749 {"udp_mixed_io_test", 0, udp_mixed_io_test},
4750 {0, 0, 0}
4751 };
4752
4753 /* Clean the server before beginning testing */
4754 test_st tests[] ={
4755 {"flush", 0, flush_test },
4756 {"init", 0, init_test },
4757 {"allocation", 0, allocation_test },
4758 {"server_list_null_test", 0, server_list_null_test},
4759 {"server_unsort", 0, server_unsort_test},
4760 {"server_sort", 0, server_sort_test},
4761 {"server_sort2", 0, server_sort2_test},
4762 {"clone_test", 0, clone_test },
4763 {"connection_test", 0, connection_test},
4764 {"callback_test", 0, callback_test},
4765 {"behavior_test", 0, behavior_test},
4766 {"userdata_test", 0, userdata_test},
4767 {"error", 0, error_test },
4768 {"set", 0, set_test },
4769 {"set2", 0, set_test2 },
4770 {"set3", 0, set_test3 },
4771 {"dump", 1, dump_test},
4772 {"add", 1, add_test },
4773 {"replace", 1, replace_test },
4774 {"delete", 1, delete_test },
4775 {"get", 1, get_test },
4776 {"get2", 0, get_test2 },
4777 {"get3", 0, get_test3 },
4778 {"get4", 0, get_test4 },
4779 {"partial mget", 0, get_test5 },
4780 {"stats_servername", 0, stats_servername_test },
4781 {"increment", 0, increment_test },
4782 {"increment_with_initial", 1, increment_with_initial_test },
4783 {"decrement", 0, decrement_test },
4784 {"decrement_with_initial", 1, decrement_with_initial_test },
4785 {"quit", 0, quit_test },
4786 {"mget", 1, mget_test },
4787 {"mget_result", 1, mget_result_test },
4788 {"mget_result_alloc", 1, mget_result_alloc_test },
4789 {"mget_result_function", 1, mget_result_function },
4790 {"mget_end", 0, mget_end },
4791 {"get_stats", 0, get_stats },
4792 {"add_host_test", 0, add_host_test },
4793 {"add_host_test_1", 0, add_host_test1 },
4794 {"get_stats_keys", 0, get_stats_keys },
4795 {"behavior_test", 0, get_stats_keys },
4796 {"callback_test", 0, get_stats_keys },
4797 {"version_string_test", 0, version_string_test},
4798 {"bad_key", 1, bad_key_test },
4799 {"memcached_server_cursor", 1, memcached_server_cursor_test },
4800 {"read_through", 1, read_through },
4801 {"delete_through", 1, delete_through },
4802 {"noreply", 1, noreply_test},
4803 {"analyzer", 1, analyzer_test},
4804 #ifdef HAVE_LIBMEMCACHEDUTIL
4805 {"connectionpool", 1, connection_pool_test },
4806 #endif
4807 {0, 0, 0}
4808 };
4809
4810 test_st async_tests[] ={
4811 {"add", 1, add_wrapper },
4812 {0, 0, 0}
4813 };
4814
4815 test_st string_tests[] ={
4816 {"string static with null", 0, string_static_null },
4817 {"string alloc with null", 0, string_alloc_null },
4818 {"string alloc with 1K", 0, string_alloc_with_size },
4819 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
4820 {"string append", 0, string_alloc_append },
4821 {"string append failure (too big)", 0, string_alloc_append_toobig },
4822 {0, 0, 0}
4823 };
4824
4825 test_st result_tests[] ={
4826 {"result static", 0, result_static},
4827 {"result alloc", 0, result_alloc},
4828 {0, 0, 0}
4829 };
4830
4831 test_st version_1_2_3[] ={
4832 {"append", 0, append_test },
4833 {"prepend", 0, prepend_test },
4834 {"cas", 0, cas_test },
4835 {"cas2", 0, cas2_test },
4836 {"append_binary", 0, append_binary_test },
4837 {0, 0, 0}
4838 };
4839
4840 test_st user_tests[] ={
4841 {"user_supplied_bug1", 0, user_supplied_bug1 },
4842 {"user_supplied_bug2", 0, user_supplied_bug2 },
4843 {"user_supplied_bug3", 0, user_supplied_bug3 },
4844 {"user_supplied_bug4", 0, user_supplied_bug4 },
4845 {"user_supplied_bug5", 1, user_supplied_bug5 },
4846 {"user_supplied_bug6", 1, user_supplied_bug6 },
4847 {"user_supplied_bug7", 1, user_supplied_bug7 },
4848 {"user_supplied_bug8", 1, user_supplied_bug8 },
4849 {"user_supplied_bug9", 1, user_supplied_bug9 },
4850 {"user_supplied_bug10", 1, user_supplied_bug10 },
4851 {"user_supplied_bug11", 1, user_supplied_bug11 },
4852 {"user_supplied_bug12", 1, user_supplied_bug12 },
4853 {"user_supplied_bug13", 1, user_supplied_bug13 },
4854 {"user_supplied_bug14", 1, user_supplied_bug14 },
4855 {"user_supplied_bug15", 1, user_supplied_bug15 },
4856 {"user_supplied_bug16", 1, user_supplied_bug16 },
4857 #ifndef __sun
4858 /*
4859 ** It seems to be something weird with the character sets..
4860 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
4861 ** guess I need to find out how this is supposed to work.. Perhaps I need
4862 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
4863 ** so just disable the code for now...).
4864 */
4865 {"user_supplied_bug17", 1, user_supplied_bug17 },
4866 #endif
4867 {"user_supplied_bug18", 1, user_supplied_bug18 },
4868 {"user_supplied_bug19", 1, user_supplied_bug19 },
4869 {"user_supplied_bug20", 1, user_supplied_bug20 },
4870 {"user_supplied_bug21", 1, user_supplied_bug21 },
4871 {0, 0, 0}
4872 };
4873
4874 test_st replication_tests[]= {
4875 {"set", 1, replication_set_test },
4876 {"get", 0, replication_get_test },
4877 {"mget", 0, replication_mget_test },
4878 {"delete", 0, replication_delete_test },
4879 {0, 0, 0}
4880 };
4881
4882 /*
4883 * The following test suite is used to verify that we don't introduce
4884 * regression bugs. If you want more information about the bug / test,
4885 * you should look in the bug report at
4886 * http://bugs.launchpad.net/libmemcached
4887 */
4888 test_st regression_tests[]= {
4889 {"lp:434484", 1, regression_bug_434484 },
4890 {"lp:434843", 1, regression_bug_434843 },
4891 {"lp:434843 buffered", 1, regression_bug_434843_buffered },
4892 {"lp:421108", 1, regression_bug_421108 },
4893 {"lp:442914", 1, regression_bug_442914 },
4894 {0, 0, 0}
4895 };
4896
4897 test_st generate_tests[] ={
4898 {"generate_pairs", 1, generate_pairs },
4899 {"generate_data", 1, generate_data },
4900 {"get_read", 0, get_read },
4901 {"delete_generate", 0, delete_generate },
4902 {"generate_buffer_data", 1, generate_buffer_data },
4903 {"delete_buffer", 0, delete_buffer_generate},
4904 {"generate_data", 1, generate_data },
4905 {"mget_read", 0, mget_read },
4906 {"mget_read_result", 0, mget_read_result },
4907 {"mget_read_function", 0, mget_read_function },
4908 {"cleanup", 1, cleanup_pairs },
4909 {"generate_large_pairs", 1, generate_large_pairs },
4910 {"generate_data", 1, generate_data },
4911 {"generate_buffer_data", 1, generate_buffer_data },
4912 {"cleanup", 1, cleanup_pairs },
4913 {0, 0, 0}
4914 };
4915
4916 test_st consistent_tests[] ={
4917 {"generate_pairs", 1, generate_pairs },
4918 {"generate_data", 1, generate_data },
4919 {"get_read", 0, get_read_count },
4920 {"cleanup", 1, cleanup_pairs },
4921 {0, 0, 0}
4922 };
4923
4924 test_st consistent_weighted_tests[] ={
4925 {"generate_pairs", 1, generate_pairs },
4926 {"generate_data", 1, generate_data_with_stats },
4927 {"get_read", 0, get_read_count },
4928 {"cleanup", 1, cleanup_pairs },
4929 {0, 0, 0}
4930 };
4931
4932 test_st hsieh_availability[] ={
4933 {"hsieh_avaibility_test",0,hsieh_avaibility_test},
4934 {0, 0, 0}
4935 };
4936
4937 test_st ketama_auto_eject_hosts[] ={
4938 {"auto_eject_hosts", 1, auto_eject_hosts },
4939 {0, 0, 0}
4940 };
4941
4942 test_st hash_tests[] ={
4943 {"md5", 0, md5_run },
4944 {"crc", 0, crc_run },
4945 {"fnv1_64", 0, fnv1_64_run },
4946 {"fnv1a_64", 0, fnv1a_64_run },
4947 {"fnv1_32", 0, fnv1_32_run },
4948 {"fnv1a_32", 0, fnv1a_32_run },
4949 {"hsieh", 0, hsieh_run },
4950 {"murmur", 0, murmur_run },
4951 {"jenkis", 0, jenkins_run },
4952 {0, 0, 0}
4953 };
4954
4955 collection_st collection[] ={
4956 {"hsieh_availability",0,0,hsieh_availability},
4957 {"udp_setup", init_udp, 0, udp_setup_server_tests},
4958 {"udp_io", init_udp, 0, upd_io_tests},
4959 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
4960 {"block", 0, 0, tests},
4961 {"binary", pre_binary, 0, tests},
4962 {"nonblock", pre_nonblock, 0, tests},
4963 {"nodelay", pre_nodelay, 0, tests},
4964 {"settimer", pre_settimer, 0, tests},
4965 {"md5", pre_md5, 0, tests},
4966 {"crc", pre_crc, 0, tests},
4967 {"hsieh", pre_hsieh, 0, tests},
4968 {"jenkins", pre_jenkins, 0, tests},
4969 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
4970 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
4971 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
4972 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
4973 {"ketama", pre_behavior_ketama, 0, tests},
4974 {"ketama_auto_eject_hosts", pre_behavior_ketama, 0, ketama_auto_eject_hosts},
4975 {"unix_socket", pre_unix_socket, 0, tests},
4976 {"unix_socket_nodelay", pre_nodelay, 0, tests},
4977 {"poll_timeout", poll_timeout, 0, tests},
4978 {"gets", enable_cas, 0, tests},
4979 {"consistent", enable_consistent, 0, tests},
4980 #ifdef MEMCACHED_ENABLE_DEPRECATED
4981 {"deprecated_memory_allocators", deprecated_set_memory_alloc, 0, tests},
4982 #endif
4983 {"memory_allocators", set_memory_alloc, 0, tests},
4984 {"prefix", set_prefix, 0, tests},
4985 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
4986 {"string", 0, 0, string_tests},
4987 {"result", 0, 0, result_tests},
4988 {"async", pre_nonblock, 0, async_tests},
4989 {"async_binary", pre_nonblock_binary, 0, async_tests},
4990 {"user", 0, 0, user_tests},
4991 {"generate", 0, 0, generate_tests},
4992 {"generate_hsieh", pre_hsieh, 0, generate_tests},
4993 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
4994 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
4995 {"generate_md5", pre_md5, 0, generate_tests},
4996 {"generate_murmur", pre_murmur, 0, generate_tests},
4997 {"generate_jenkins", pre_jenkins, 0, generate_tests},
4998 {"generate_nonblock", pre_nonblock, 0, generate_tests},
4999 {"consistent_not", 0, 0, consistent_tests},
5000 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
5001 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5002 {"test_hashes", 0, 0, hash_tests},
5003 {"replication", pre_replication, 0, replication_tests},
5004 {"replication_noblock", pre_replication_noblock, 0, replication_tests},
5005 {"regression", 0, 0, regression_tests},
5006 {0, 0, 0, 0}
5007 };
5008
5009 #define SERVERS_TO_CREATE 5
5010
5011 /* Prototypes for functions we will pass to test framework */
5012 void *world_create(void);
5013 void world_destroy(void *p);
5014
5015 void *world_create(void)
5016 {
5017 server_startup_st *construct;
5018
5019 construct= calloc(sizeof(server_startup_st), 1);
5020 construct->count= SERVERS_TO_CREATE;
5021 construct->udp= 0;
5022 server_startup(construct);
5023
5024 return construct;
5025 }
5026
5027
5028 void world_destroy(void *p)
5029 {
5030 server_startup_st *construct= (server_startup_st *)p;
5031 memcached_server_st *servers= (memcached_server_st *)construct->servers;
5032 memcached_server_list_free(servers);
5033
5034 server_shutdown(construct);
5035 free(construct);
5036 }
5037
5038 void get_world(world_st *world)
5039 {
5040 world->collections= collection;
5041 world->create= world_create;
5042 world->destroy= world_destroy;
5043 }