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