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