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