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