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