a580f396d1820e06ea532fa7689b130d423448d3
[m6w6/libmemcached] / tests / function.c
1 /* libMemcached Functions Test
2 * Copyright (C) 2006-2009 Brian Aker
3 * All rights reserved.
4 *
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
7 */
8
9 /*
10 Sample test application.
11 */
12
13 #include "libmemcached/common.h"
14
15 #include <assert.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <signal.h>
23 #include <unistd.h>
24 #include <time.h>
25 #include "server.h"
26 #include "clients/generator.h"
27 #include "clients/execute.h"
28
29 #ifndef INT64_MAX
30 #define INT64_MAX LONG_MAX
31 #endif
32 #ifndef INT32_MAX
33 #define INT32_MAX INT_MAX
34 #endif
35
36
37 #include "test.h"
38
39 #ifdef HAVE_LIBMEMCACHEDUTIL
40 #include <pthread.h>
41 #include "libmemcached/memcached_util.h"
42 #endif
43
44 #include "hash_results.h"
45
46 #define GLOBAL_COUNT 10000
47 #define GLOBAL2_COUNT 100
48 #define SERVERS_TO_CREATE 5
49 static uint32_t global_count;
50
51 static pairs_st *global_pairs;
52 static const char *global_keys[GLOBAL_COUNT];
53 static size_t global_keys_length[GLOBAL_COUNT];
54
55 static test_return_t init_test(memcached_st *not_used __attribute__((unused)))
56 {
57 memcached_st memc;
58
59 (void)memcached_create(&memc);
60 memcached_free(&memc);
61
62 return TEST_SUCCESS;
63 }
64
65 static test_return_t server_list_null_test(memcached_st *ptr __attribute__((unused)))
66 {
67 memcached_server_st *server_list;
68 memcached_return_t rc;
69
70 server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, NULL);
71 test_truth(server_list == NULL);
72
73 server_list= memcached_server_list_append_with_weight(NULL, "localhost", 0, 0, NULL);
74 test_truth(server_list == NULL);
75
76 server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, &rc);
77 test_truth(server_list == NULL);
78
79 return TEST_SUCCESS;
80 }
81
82 #define TEST_PORT_COUNT 7
83 uint32_t test_ports[TEST_PORT_COUNT];
84
85 static memcached_return_t server_display_function(memcached_st *ptr __attribute__((unused)), memcached_server_st *server, void *context)
86 {
87 /* Do Nothing */
88 uint32_t bigger= *((uint32_t *)(context));
89 assert(bigger <= server->port);
90 *((uint32_t *)(context))= server->port;
91
92 return MEMCACHED_SUCCESS;
93 }
94
95 static test_return_t server_sort_test(memcached_st *ptr __attribute__((unused)))
96 {
97 uint32_t x;
98 uint32_t bigger= 0; /* Prime the value for the test_truth in server_display_function */
99 memcached_return_t rc;
100 memcached_server_fn callbacks[1];
101 memcached_st *local_memc;
102
103 local_memc= memcached_create(NULL);
104 test_truth(local_memc);
105 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
106
107 for (x= 0; x < TEST_PORT_COUNT; x++)
108 {
109 test_ports[x]= (uint32_t)random() % 64000;
110 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
111 test_truth(local_memc->number_of_hosts == x + 1);
112 test_truth(local_memc->hosts[0].count == x+1);
113 test_truth(rc == MEMCACHED_SUCCESS);
114 }
115
116 callbacks[0]= server_display_function;
117 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
118
119
120 memcached_free(local_memc);
121
122 return TEST_SUCCESS;
123 }
124
125 static test_return_t server_sort2_test(memcached_st *ptr __attribute__((unused)))
126 {
127 uint32_t bigger= 0; /* Prime the value for the test_truth in server_display_function */
128 memcached_return_t rc;
129 memcached_server_fn callbacks[1];
130 memcached_st *local_memc;
131
132 local_memc= memcached_create(NULL);
133 test_truth(local_memc);
134 rc= memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
135 test_truth(rc == MEMCACHED_SUCCESS);
136
137 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0);
138 test_truth(rc == MEMCACHED_SUCCESS);
139 test_truth(local_memc->hosts[0].port == 43043);
140
141 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0);
142 test_truth(rc == MEMCACHED_SUCCESS);
143 test_truth(local_memc->hosts[0].port == 43042);
144 test_truth(local_memc->hosts[1].port == 43043);
145
146 callbacks[0]= server_display_function;
147 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
148
149
150 memcached_free(local_memc);
151
152 return TEST_SUCCESS;
153 }
154
155 static memcached_return_t server_display_unsort_function(memcached_st *ptr __attribute__((unused)), memcached_server_st *server, void *context)
156 {
157 /* Do Nothing */
158 uint32_t x= *((uint32_t *)(context));
159
160 assert(test_ports[x] == server->port);
161 *((uint32_t *)(context))= ++x;
162
163 return MEMCACHED_SUCCESS;
164 }
165
166 static test_return_t server_unsort_test(memcached_st *ptr __attribute__((unused)))
167 {
168 uint32_t x;
169 uint32_t counter= 0; /* Prime the value for the test_truth in server_display_function */
170 uint32_t bigger= 0; /* Prime the value for the test_truth in server_display_function */
171 memcached_return_t rc;
172 memcached_server_fn callbacks[1];
173 memcached_st *local_memc;
174
175 local_memc= memcached_create(NULL);
176 test_truth(local_memc);
177
178 for (x= 0; x < TEST_PORT_COUNT; x++)
179 {
180 test_ports[x]= (uint32_t)(random() % 64000);
181 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
182 test_truth(local_memc->number_of_hosts == x+1);
183 test_truth(local_memc->hosts[0].count == x+1);
184 test_truth(rc == MEMCACHED_SUCCESS);
185 }
186
187 callbacks[0]= server_display_unsort_function;
188 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
189
190 /* Now we sort old data! */
191 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
192 callbacks[0]= server_display_function;
193 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
194
195
196 memcached_free(local_memc);
197
198 return TEST_SUCCESS;
199 }
200
201 static test_return_t allocation_test(memcached_st *not_used __attribute__((unused)))
202 {
203 memcached_st *memc;
204 memc= memcached_create(NULL);
205 test_truth(memc);
206 memcached_free(memc);
207
208 return TEST_SUCCESS;
209 }
210
211 static test_return_t clone_test(memcached_st *memc)
212 {
213 /* All null? */
214 {
215 memcached_st *memc_clone;
216 memc_clone= memcached_clone(NULL, NULL);
217 test_truth(memc_clone);
218 memcached_free(memc_clone);
219 }
220
221 /* Can we init from null? */
222 {
223 memcached_st *memc_clone;
224 memc_clone= memcached_clone(NULL, memc);
225 test_truth(memc_clone);
226
227 test_truth(memc_clone->call_free == memc->call_free);
228 test_truth(memc_clone->call_malloc == memc->call_malloc);
229 test_truth(memc_clone->call_realloc == memc->call_realloc);
230 test_truth(memc_clone->call_calloc == memc->call_calloc);
231 test_truth(memc_clone->connect_timeout == memc->connect_timeout);
232 test_truth(memc_clone->delete_trigger == memc->delete_trigger);
233 test_truth(memc_clone->distribution == memc->distribution);
234 { // Test all of the flags
235 test_truth(memc_clone->flags.no_block == memc->flags.no_block);
236 test_truth(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
237 test_truth(memc_clone->flags.reuse_memory == memc->flags.reuse_memory);
238 test_truth(memc_clone->flags.use_cache_lookups == memc->flags.use_cache_lookups);
239 test_truth(memc_clone->flags.support_cas == memc->flags.support_cas);
240 test_truth(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
241 test_truth(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
242 test_truth(memc_clone->flags.verify_key == memc->flags.verify_key);
243 test_truth(memc_clone->flags.ketama_weighted == memc->flags.ketama_weighted);
244 test_truth(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
245 test_truth(memc_clone->flags.hash_with_prefix_key == memc->flags.hash_with_prefix_key);
246 test_truth(memc_clone->flags.no_reply == memc->flags.no_reply);
247 test_truth(memc_clone->flags.use_udp == memc->flags.use_udp);
248 test_truth(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
249 test_truth(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
250 }
251 test_truth(memc_clone->get_key_failure == memc->get_key_failure);
252 test_truth(memc_clone->hash == memc->hash);
253 test_truth(memc_clone->distribution_hash == memc->distribution_hash);
254 test_truth(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
255 test_truth(memc_clone->io_msg_watermark == memc->io_msg_watermark);
256 test_truth(memc_clone->io_key_prefetch == memc->io_key_prefetch);
257 test_truth(memc_clone->on_cleanup == memc->on_cleanup);
258 test_truth(memc_clone->on_clone == memc->on_clone);
259 test_truth(memc_clone->poll_timeout == memc->poll_timeout);
260 test_truth(memc_clone->rcv_timeout == memc->rcv_timeout);
261 test_truth(memc_clone->recv_size == memc->recv_size);
262 test_truth(memc_clone->retry_timeout == memc->retry_timeout);
263 test_truth(memc_clone->send_size == memc->send_size);
264 test_truth(memc_clone->server_failure_limit == memc->server_failure_limit);
265 test_truth(memc_clone->snd_timeout == memc->snd_timeout);
266 test_truth(memc_clone->user_data == memc->user_data);
267
268 memcached_free(memc_clone);
269 }
270
271 /* Can we init from struct? */
272 {
273 memcached_st declared_clone;
274 memcached_st *memc_clone;
275 memset(&declared_clone, 0 , sizeof(memcached_st));
276 memc_clone= memcached_clone(&declared_clone, NULL);
277 test_truth(memc_clone);
278 memcached_free(memc_clone);
279 }
280
281 /* Can we init from struct? */
282 {
283 memcached_st declared_clone;
284 memcached_st *memc_clone;
285 memset(&declared_clone, 0 , sizeof(memcached_st));
286 memc_clone= memcached_clone(&declared_clone, memc);
287 test_truth(memc_clone);
288 memcached_free(memc_clone);
289 }
290
291 return TEST_SUCCESS;
292 }
293
294 static test_return_t userdata_test(memcached_st *memc)
295 {
296 void* foo= NULL;
297 test_truth(memcached_set_user_data(memc, foo) == NULL);
298 test_truth(memcached_get_user_data(memc) == foo);
299 test_truth(memcached_set_user_data(memc, NULL) == foo);
300
301 return TEST_SUCCESS;
302 }
303
304 static test_return_t connection_test(memcached_st *memc)
305 {
306 memcached_return_t rc;
307
308 rc= memcached_server_add_with_weight(memc, "localhost", 0, 0);
309 test_truth(rc == MEMCACHED_SUCCESS);
310
311 return TEST_SUCCESS;
312 }
313
314 static test_return_t error_test(memcached_st *memc)
315 {
316 memcached_return_t rc;
317 uint32_t values[] = { 851992627U, 2337886783U, 3196981036U, 4001849190U,
318 982370485U, 1263635348U, 4242906218U, 3829656100U,
319 1891735253U, 334139633U, 2257084983U, 3088286104U,
320 13199785U, 2542027183U, 1097051614U, 199566778U,
321 2748246961U, 2465192557U, 1664094137U, 2405439045U,
322 1842224848U, 692413798U, 3479807801U, 919913813U,
323 4269430871U, 610793021U, 527273862U, 1437122909U,
324 2300930706U, 2943759320U, 674306647U, 2400528935U,
325 54481931U, 4186304426U, 1741088401U, 2979625118U,
326 4159057246U, 3425930182U, 2593724503U};
327
328 // You have updated the memcache_error messages but not updated docs/tests.
329 test_truth(MEMCACHED_MAXIMUM_RETURN == 39);
330 for (rc= MEMCACHED_SUCCESS; rc < MEMCACHED_MAXIMUM_RETURN; rc++)
331 {
332 uint32_t hash_val;
333 const char *msg= memcached_strerror(memc, rc);
334 hash_val= memcached_generate_hash_value(msg, strlen(msg),
335 MEMCACHED_HASH_JENKINS);
336 test_truth(values[rc] == hash_val);
337 }
338
339 return TEST_SUCCESS;
340 }
341
342 static test_return_t set_test(memcached_st *memc)
343 {
344 memcached_return_t rc;
345 const char *key= "foo";
346 const char *value= "when we sanitize";
347
348 rc= memcached_set(memc, key, strlen(key),
349 value, strlen(value),
350 (time_t)0, (uint32_t)0);
351 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
352
353 return TEST_SUCCESS;
354 }
355
356 static test_return_t append_test(memcached_st *memc)
357 {
358 memcached_return_t rc;
359 const char *key= "fig";
360 const char *in_value= "we";
361 char *out_value= NULL;
362 size_t value_length;
363 uint32_t flags;
364
365 rc= memcached_flush(memc, 0);
366 test_truth(rc == MEMCACHED_SUCCESS);
367
368 rc= memcached_set(memc, key, strlen(key),
369 in_value, strlen(in_value),
370 (time_t)0, (uint32_t)0);
371 test_truth(rc == MEMCACHED_SUCCESS);
372
373 rc= memcached_append(memc, key, strlen(key),
374 " the", strlen(" the"),
375 (time_t)0, (uint32_t)0);
376 test_truth(rc == MEMCACHED_SUCCESS);
377
378 rc= memcached_append(memc, key, strlen(key),
379 " people", strlen(" people"),
380 (time_t)0, (uint32_t)0);
381 test_truth(rc == MEMCACHED_SUCCESS);
382
383 out_value= memcached_get(memc, key, strlen(key),
384 &value_length, &flags, &rc);
385 test_truth(!memcmp(out_value, "we the people", strlen("we the people")));
386 test_truth(strlen("we the people") == value_length);
387 test_truth(rc == MEMCACHED_SUCCESS);
388 free(out_value);
389
390 return TEST_SUCCESS;
391 }
392
393 static test_return_t append_binary_test(memcached_st *memc)
394 {
395 memcached_return_t rc;
396 const char *key= "numbers";
397 unsigned int *store_ptr;
398 unsigned int store_list[] = { 23, 56, 499, 98, 32847, 0 };
399 char *value;
400 size_t value_length;
401 uint32_t flags;
402 unsigned int x;
403
404 rc= memcached_flush(memc, 0);
405 test_truth(rc == MEMCACHED_SUCCESS);
406
407 rc= memcached_set(memc,
408 key, strlen(key),
409 NULL, 0,
410 (time_t)0, (uint32_t)0);
411 test_truth(rc == MEMCACHED_SUCCESS);
412
413 for (x= 0; store_list[x] ; x++)
414 {
415 rc= memcached_append(memc,
416 key, strlen(key),
417 (char *)&store_list[x], sizeof(unsigned int),
418 (time_t)0, (uint32_t)0);
419 test_truth(rc == MEMCACHED_SUCCESS);
420 }
421
422 value= memcached_get(memc, key, strlen(key),
423 &value_length, &flags, &rc);
424 test_truth((value_length == (sizeof(unsigned int) * x)));
425 test_truth(rc == MEMCACHED_SUCCESS);
426
427 store_ptr= (unsigned int *)value;
428 x= 0;
429 while ((size_t)store_ptr < (size_t)(value + value_length))
430 {
431 test_truth(*store_ptr == store_list[x++]);
432 store_ptr++;
433 }
434 free(value);
435
436 return TEST_SUCCESS;
437 }
438
439 static test_return_t cas2_test(memcached_st *memc)
440 {
441 memcached_return_t rc;
442 const char *keys[]= {"fudge", "son", "food"};
443 size_t key_length[]= {5, 3, 4};
444 const char *value= "we the people";
445 size_t value_length= strlen("we the people");
446 unsigned int x;
447 memcached_result_st results_obj;
448 memcached_result_st *results;
449 unsigned int set= 1;
450
451 rc= memcached_flush(memc, 0);
452 test_truth(rc == MEMCACHED_SUCCESS);
453
454 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
455
456 for (x= 0; x < 3; x++)
457 {
458 rc= memcached_set(memc, keys[x], key_length[x],
459 keys[x], key_length[x],
460 (time_t)50, (uint32_t)9);
461 test_truth(rc == MEMCACHED_SUCCESS);
462 }
463
464 rc= memcached_mget(memc, keys, key_length, 3);
465
466 results= memcached_result_create(memc, &results_obj);
467
468 results= memcached_fetch_result(memc, &results_obj, &rc);
469 test_truth(results);
470 test_truth(results->cas);
471 test_truth(rc == MEMCACHED_SUCCESS);
472 test_truth(memcached_result_cas(results));
473
474 test_truth(!memcmp(value, "we the people", strlen("we the people")));
475 test_truth(strlen("we the people") == value_length);
476 test_truth(rc == MEMCACHED_SUCCESS);
477
478 memcached_result_free(&results_obj);
479
480 return TEST_SUCCESS;
481 }
482
483 static test_return_t cas_test(memcached_st *memc)
484 {
485 memcached_return_t rc;
486 const char *key= "fun";
487 size_t key_length= strlen(key);
488 const char *value= "we the people";
489 const char* keys[2] = { key, NULL };
490 size_t keylengths[2] = { strlen(key), 0 };
491 size_t value_length= strlen(value);
492 const char *value2= "change the value";
493 size_t value2_length= strlen(value2);
494
495 memcached_result_st results_obj;
496 memcached_result_st *results;
497 unsigned int set= 1;
498
499 rc= memcached_flush(memc, 0);
500 test_truth(rc == MEMCACHED_SUCCESS);
501
502 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
503
504 rc= memcached_set(memc, key, strlen(key),
505 value, strlen(value),
506 (time_t)0, (uint32_t)0);
507 test_truth(rc == MEMCACHED_SUCCESS);
508
509 rc= memcached_mget(memc, keys, keylengths, 1);
510
511 results= memcached_result_create(memc, &results_obj);
512
513 results= memcached_fetch_result(memc, &results_obj, &rc);
514 test_truth(results);
515 test_truth(rc == MEMCACHED_SUCCESS);
516 test_truth(memcached_result_cas(results));
517 test_truth(!memcmp(value, memcached_result_value(results), value_length));
518 test_truth(strlen(memcached_result_value(results)) == value_length);
519 test_truth(rc == MEMCACHED_SUCCESS);
520 uint64_t cas = memcached_result_cas(results);
521
522 #if 0
523 results= memcached_fetch_result(memc, &results_obj, &rc);
524 test_truth(rc == MEMCACHED_END);
525 test_truth(results == NULL);
526 #endif
527
528 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
529 test_truth(rc == MEMCACHED_SUCCESS);
530
531 /*
532 * The item will have a new cas value, so try to set it again with the old
533 * value. This should fail!
534 */
535 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
536 test_truth(rc == MEMCACHED_DATA_EXISTS);
537
538 memcached_result_free(&results_obj);
539
540 return TEST_SUCCESS;
541 }
542
543 static test_return_t prepend_test(memcached_st *memc)
544 {
545 memcached_return_t rc;
546 const char *key= "fig";
547 const char *value= "people";
548 char *out_value= NULL;
549 size_t value_length;
550 uint32_t flags;
551
552 rc= memcached_flush(memc, 0);
553 test_truth(rc == MEMCACHED_SUCCESS);
554
555 rc= memcached_set(memc, key, strlen(key),
556 value, strlen(value),
557 (time_t)0, (uint32_t)0);
558 test_truth(rc == MEMCACHED_SUCCESS);
559
560 rc= memcached_prepend(memc, key, strlen(key),
561 "the ", strlen("the "),
562 (time_t)0, (uint32_t)0);
563 test_truth(rc == MEMCACHED_SUCCESS);
564
565 rc= memcached_prepend(memc, key, strlen(key),
566 "we ", strlen("we "),
567 (time_t)0, (uint32_t)0);
568 test_truth(rc == MEMCACHED_SUCCESS);
569
570 out_value= memcached_get(memc, key, strlen(key),
571 &value_length, &flags, &rc);
572 test_truth(!memcmp(out_value, "we the people", strlen("we the people")));
573 test_truth(strlen("we the people") == value_length);
574 test_truth(rc == MEMCACHED_SUCCESS);
575 free(out_value);
576
577 return TEST_SUCCESS;
578 }
579
580 /*
581 Set the value, then quit to make sure it is flushed.
582 Come back in and test that add fails.
583 */
584 static test_return_t add_test(memcached_st *memc)
585 {
586 memcached_return_t rc;
587 const char *key= "foo";
588 const char *value= "when we sanitize";
589 unsigned long long setting_value;
590
591 setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
592
593 rc= memcached_set(memc, key, strlen(key),
594 value, strlen(value),
595 (time_t)0, (uint32_t)0);
596 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
597 memcached_quit(memc);
598 rc= memcached_add(memc, key, strlen(key),
599 value, strlen(value),
600 (time_t)0, (uint32_t)0);
601
602 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
603 if (setting_value)
604 {
605 test_truth(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
606 }
607 else
608 {
609 test_truth(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_DATA_EXISTS);
610 }
611
612 return TEST_SUCCESS;
613 }
614
615 /*
616 ** There was a problem of leaking filedescriptors in the initial release
617 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
618 ** systems it seems that the kernel is slow on reclaiming the resources
619 ** because the connects starts to time out (the test doesn't do much
620 ** anyway, so just loop 10 iterations)
621 */
622 static test_return_t add_wrapper(memcached_st *memc)
623 {
624 unsigned int x;
625 unsigned int max= 10000;
626 #ifdef __sun
627 max= 10;
628 #endif
629 #ifdef __APPLE__
630 max= 10;
631 #endif
632
633 for (x= 0; x < max; x++)
634 add_test(memc);
635
636 return TEST_SUCCESS;
637 }
638
639 static test_return_t replace_test(memcached_st *memc)
640 {
641 memcached_return_t rc;
642 const char *key= "foo";
643 const char *value= "when we sanitize";
644 const char *original= "first we insert some data";
645
646 rc= memcached_set(memc, key, strlen(key),
647 original, strlen(original),
648 (time_t)0, (uint32_t)0);
649 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
650
651 rc= memcached_replace(memc, key, strlen(key),
652 value, strlen(value),
653 (time_t)0, (uint32_t)0);
654 test_truth(rc == MEMCACHED_SUCCESS);
655
656 return TEST_SUCCESS;
657 }
658
659 static test_return_t delete_test(memcached_st *memc)
660 {
661 memcached_return_t rc;
662 const char *key= "foo";
663 const char *value= "when we sanitize";
664
665 rc= memcached_set(memc, key, strlen(key),
666 value, strlen(value),
667 (time_t)0, (uint32_t)0);
668 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
669
670 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
671 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
672
673 return TEST_SUCCESS;
674 }
675
676 static test_return_t flush_test(memcached_st *memc)
677 {
678 memcached_return_t rc;
679
680 rc= memcached_flush(memc, 0);
681 test_truth(rc == MEMCACHED_SUCCESS);
682
683 return TEST_SUCCESS;
684 }
685
686 static memcached_return_t server_function(memcached_st *ptr __attribute__((unused)),
687 memcached_server_st *server __attribute__((unused)),
688 void *context __attribute__((unused)))
689 {
690 /* Do Nothing */
691
692 return MEMCACHED_SUCCESS;
693 }
694
695 static test_return_t memcached_server_cursor_test(memcached_st *memc)
696 {
697 char context[8];
698 strcpy(context, "foo bad");
699 memcached_server_fn callbacks[1];
700
701 callbacks[0]= server_function;
702 memcached_server_cursor(memc, callbacks, context, 1);
703 return TEST_SUCCESS;
704 }
705
706 static test_return_t bad_key_test(memcached_st *memc)
707 {
708 memcached_return_t rc;
709 const char *key= "foo bad";
710 char *string;
711 size_t string_length;
712 uint32_t flags;
713 memcached_st *memc_clone;
714 unsigned int set= 1;
715 size_t max_keylen= 0xffff;
716
717 // Just skip if we are in binary mode.
718 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
719 return TEST_SKIPPED;
720
721 memc_clone= memcached_clone(NULL, memc);
722 test_truth(memc_clone);
723
724 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
725 test_truth(rc == MEMCACHED_SUCCESS);
726
727 /* All keys are valid in the binary protocol (except for length) */
728 if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 0)
729 {
730 string= memcached_get(memc_clone, key, strlen(key),
731 &string_length, &flags, &rc);
732 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
733 test_truth(string_length == 0);
734 test_truth(!string);
735
736 set= 0;
737 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
738 test_truth(rc == MEMCACHED_SUCCESS);
739 string= memcached_get(memc_clone, key, strlen(key),
740 &string_length, &flags, &rc);
741 test_truth(rc == MEMCACHED_NOTFOUND);
742 test_truth(string_length == 0);
743 test_truth(!string);
744
745 /* Test multi key for bad keys */
746 const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
747 size_t key_lengths[] = { 7, 7, 7 };
748 set= 1;
749 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
750 test_truth(rc == MEMCACHED_SUCCESS);
751
752 rc= memcached_mget(memc_clone, keys, key_lengths, 3);
753 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
754
755 rc= memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1);
756 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
757
758 max_keylen= 250;
759
760 /* The following test should be moved to the end of this function when the
761 memcached server is updated to allow max size length of the keys in the
762 binary protocol
763 */
764 rc= memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
765 test_truth(rc == MEMCACHED_SUCCESS);
766
767 char *longkey= malloc(max_keylen + 1);
768 if (longkey != NULL)
769 {
770 memset(longkey, 'a', max_keylen + 1);
771 string= memcached_get(memc_clone, longkey, max_keylen,
772 &string_length, &flags, &rc);
773 test_truth(rc == MEMCACHED_NOTFOUND);
774 test_truth(string_length == 0);
775 test_truth(!string);
776
777 string= memcached_get(memc_clone, longkey, max_keylen + 1,
778 &string_length, &flags, &rc);
779 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
780 test_truth(string_length == 0);
781 test_truth(!string);
782
783 free(longkey);
784 }
785 }
786
787 /* Make sure zero length keys are marked as bad */
788 set= 1;
789 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
790 test_truth(rc == MEMCACHED_SUCCESS);
791 string= memcached_get(memc_clone, key, 0,
792 &string_length, &flags, &rc);
793 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
794 test_truth(string_length == 0);
795 test_truth(!string);
796
797 memcached_free(memc_clone);
798
799 return TEST_SUCCESS;
800 }
801
802 #define READ_THROUGH_VALUE "set for me"
803 static memcached_return_t read_through_trigger(memcached_st *memc __attribute__((unused)),
804 char *key __attribute__((unused)),
805 size_t key_length __attribute__((unused)),
806 memcached_result_st *result)
807 {
808
809 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
810 }
811
812 static test_return_t read_through(memcached_st *memc)
813 {
814 memcached_return_t rc;
815 const char *key= "foo";
816 char *string;
817 size_t string_length;
818 uint32_t flags;
819 memcached_trigger_key_fn cb= (memcached_trigger_key_fn)read_through_trigger;
820
821 string= memcached_get(memc, key, strlen(key),
822 &string_length, &flags, &rc);
823
824 test_truth(rc == MEMCACHED_NOTFOUND);
825 test_false(string_length);
826 test_false(string);
827
828 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE,
829 *(void **)&cb);
830 test_truth(rc == MEMCACHED_SUCCESS);
831
832 string= memcached_get(memc, key, strlen(key),
833 &string_length, &flags, &rc);
834
835 test_truth(rc == MEMCACHED_SUCCESS);
836 test_truth(string_length == strlen(READ_THROUGH_VALUE));
837 test_strcmp(READ_THROUGH_VALUE, string);
838 free(string);
839
840 string= memcached_get(memc, key, strlen(key),
841 &string_length, &flags, &rc);
842
843 test_truth(rc == MEMCACHED_SUCCESS);
844 test_truth(string_length == strlen(READ_THROUGH_VALUE));
845 test_truth(!strcmp(READ_THROUGH_VALUE, string));
846 free(string);
847
848 return TEST_SUCCESS;
849 }
850
851 static memcached_return_t delete_trigger(memcached_st *ptr __attribute__((unused)),
852 const char *key,
853 size_t key_length __attribute__((unused)))
854 {
855 assert(key);
856
857 return MEMCACHED_SUCCESS;
858 }
859
860 static test_return_t delete_through(memcached_st *memc)
861 {
862 memcached_trigger_delete_key_fn callback;
863 memcached_return_t rc;
864
865 callback= (memcached_trigger_delete_key_fn)delete_trigger;
866
867 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, *(void**)&callback);
868 test_truth(rc == MEMCACHED_SUCCESS);
869
870 return TEST_SUCCESS;
871 }
872
873 static test_return_t get_test(memcached_st *memc)
874 {
875 memcached_return_t rc;
876 const char *key= "foo";
877 char *string;
878 size_t string_length;
879 uint32_t flags;
880
881 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
882 test_truth(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
883
884 string= memcached_get(memc, key, strlen(key),
885 &string_length, &flags, &rc);
886
887 test_truth(rc == MEMCACHED_NOTFOUND);
888 test_false(string_length);
889 test_false(string);
890
891 return TEST_SUCCESS;
892 }
893
894 static test_return_t get_test2(memcached_st *memc)
895 {
896 memcached_return_t rc;
897 const char *key= "foo";
898 const char *value= "when we sanitize";
899 char *string;
900 size_t string_length;
901 uint32_t flags;
902
903 rc= memcached_set(memc, key, strlen(key),
904 value, strlen(value),
905 (time_t)0, (uint32_t)0);
906 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
907
908 string= memcached_get(memc, key, strlen(key),
909 &string_length, &flags, &rc);
910
911 test_truth(string);
912 test_truth(rc == MEMCACHED_SUCCESS);
913 test_truth(string_length == strlen(value));
914 test_truth(!memcmp(string, value, string_length));
915
916 free(string);
917
918 return TEST_SUCCESS;
919 }
920
921 static test_return_t set_test2(memcached_st *memc)
922 {
923 memcached_return_t rc;
924 const char *key= "foo";
925 const char *value= "train in the brain";
926 size_t value_length= strlen(value);
927 unsigned int x;
928
929 for (x= 0; x < 10; x++)
930 {
931 rc= memcached_set(memc, key, strlen(key),
932 value, value_length,
933 (time_t)0, (uint32_t)0);
934 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
935 }
936
937 return TEST_SUCCESS;
938 }
939
940 static test_return_t set_test3(memcached_st *memc)
941 {
942 memcached_return_t rc;
943 char *value;
944 size_t value_length= 8191;
945 unsigned int x;
946
947 value = (char*)malloc(value_length);
948 test_truth(value);
949
950 for (x= 0; x < value_length; x++)
951 value[x] = (char) (x % 127);
952
953 /* The dump test relies on there being at least 32 items in memcached */
954 for (x= 0; x < 32; x++)
955 {
956 char key[16];
957
958 sprintf(key, "foo%u", x);
959
960 rc= memcached_set(memc, key, strlen(key),
961 value, value_length,
962 (time_t)0, (uint32_t)0);
963 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
964 }
965
966 free(value);
967
968 return TEST_SUCCESS;
969 }
970
971 static test_return_t get_test3(memcached_st *memc)
972 {
973 memcached_return_t rc;
974 const char *key= "foo";
975 char *value;
976 size_t value_length= 8191;
977 char *string;
978 size_t string_length;
979 uint32_t flags;
980 uint32_t x;
981
982 value = (char*)malloc(value_length);
983 test_truth(value);
984
985 for (x= 0; x < value_length; x++)
986 value[x] = (char) (x % 127);
987
988 rc= memcached_set(memc, key, strlen(key),
989 value, value_length,
990 (time_t)0, (uint32_t)0);
991 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
992
993 string= memcached_get(memc, key, strlen(key),
994 &string_length, &flags, &rc);
995
996 test_truth(rc == MEMCACHED_SUCCESS);
997 test_truth(string);
998 test_truth(string_length == value_length);
999 test_truth(!memcmp(string, value, string_length));
1000
1001 free(string);
1002 free(value);
1003
1004 return TEST_SUCCESS;
1005 }
1006
1007 static test_return_t get_test4(memcached_st *memc)
1008 {
1009 memcached_return_t rc;
1010 const char *key= "foo";
1011 char *value;
1012 size_t value_length= 8191;
1013 char *string;
1014 size_t string_length;
1015 uint32_t flags;
1016 uint32_t x;
1017
1018 value = (char*)malloc(value_length);
1019 test_truth(value);
1020
1021 for (x= 0; x < value_length; x++)
1022 value[x] = (char) (x % 127);
1023
1024 rc= memcached_set(memc, key, strlen(key),
1025 value, value_length,
1026 (time_t)0, (uint32_t)0);
1027 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1028
1029 for (x= 0; x < 10; x++)
1030 {
1031 string= memcached_get(memc, key, strlen(key),
1032 &string_length, &flags, &rc);
1033
1034 test_truth(rc == MEMCACHED_SUCCESS);
1035 test_truth(string);
1036 test_truth(string_length == value_length);
1037 test_truth(!memcmp(string, value, string_length));
1038 free(string);
1039 }
1040
1041 free(value);
1042
1043 return TEST_SUCCESS;
1044 }
1045
1046 /*
1047 * This test verifies that memcached_read_one_response doesn't try to
1048 * dereference a NIL-pointer if you issue a multi-get and don't read out all
1049 * responses before you execute a storage command.
1050 */
1051 static test_return_t get_test5(memcached_st *memc)
1052 {
1053 /*
1054 ** Request the same key twice, to ensure that we hash to the same server
1055 ** (so that we have multiple response values queued up) ;-)
1056 */
1057 const char *keys[]= { "key", "key" };
1058 size_t lengths[]= { 3, 3 };
1059 uint32_t flags;
1060 size_t rlen;
1061
1062 memcached_return_t rc= memcached_set(memc, keys[0], lengths[0],
1063 keys[0], lengths[0], 0, 0);
1064 test_truth(rc == MEMCACHED_SUCCESS);
1065 rc= memcached_mget(memc, keys, lengths, 2);
1066
1067 memcached_result_st results_obj;
1068 memcached_result_st *results;
1069 results=memcached_result_create(memc, &results_obj);
1070 test_truth(results);
1071 results=memcached_fetch_result(memc, &results_obj, &rc);
1072 test_truth(results);
1073 memcached_result_free(&results_obj);
1074
1075 /* Don't read out the second result, but issue a set instead.. */
1076 rc= memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0);
1077 test_truth(rc == MEMCACHED_SUCCESS);
1078
1079 char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
1080 &rlen, &flags, &rc);
1081 test_truth(val == NULL);
1082 test_truth(rc == MEMCACHED_NOTFOUND);
1083 val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
1084 test_truth(val != NULL);
1085 test_truth(rc == MEMCACHED_SUCCESS);
1086 free(val);
1087
1088 return TEST_SUCCESS;
1089 }
1090
1091 static test_return_t mget_end(memcached_st *memc)
1092 {
1093 const char *keys[]= { "foo", "foo2" };
1094 size_t lengths[]= { 3, 4 };
1095 const char *values[]= { "fjord", "41" };
1096
1097 memcached_return_t rc;
1098
1099 // Set foo and foo2
1100 for (int i= 0; i < 2; i++)
1101 {
1102 rc= memcached_set(memc, keys[i], lengths[i], values[i], strlen(values[i]),
1103 (time_t)0, (uint32_t)0);
1104 test_truth(rc == MEMCACHED_SUCCESS);
1105 }
1106
1107 char *string;
1108 size_t string_length;
1109 uint32_t flags;
1110
1111 // retrieve both via mget
1112 rc= memcached_mget(memc, keys, lengths, 2);
1113 test_truth(rc == MEMCACHED_SUCCESS);
1114
1115 char key[MEMCACHED_MAX_KEY];
1116 size_t key_length;
1117
1118 // this should get both
1119 for (int i = 0; i < 2; i++)
1120 {
1121 string= memcached_fetch(memc, key, &key_length, &string_length,
1122 &flags, &rc);
1123 test_truth(rc == MEMCACHED_SUCCESS);
1124 int val = 0;
1125 if (key_length == 4)
1126 val= 1;
1127 test_truth(string_length == strlen(values[val]));
1128 test_truth(strncmp(values[val], string, string_length) == 0);
1129 free(string);
1130 }
1131
1132 // this should indicate end
1133 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1134 test_truth(rc == MEMCACHED_END);
1135
1136 // now get just one
1137 rc= memcached_mget(memc, keys, lengths, 1);
1138 test_truth(rc == MEMCACHED_SUCCESS);
1139
1140 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1141 test_truth(key_length == lengths[0]);
1142 test_truth(strncmp(keys[0], key, key_length) == 0);
1143 test_truth(string_length == strlen(values[0]));
1144 test_truth(strncmp(values[0], string, string_length) == 0);
1145 test_truth(rc == MEMCACHED_SUCCESS);
1146 free(string);
1147
1148 // this should indicate end
1149 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1150 test_truth(rc == MEMCACHED_END);
1151
1152 return TEST_SUCCESS;
1153 }
1154
1155 /* Do not copy the style of this code, I just access hosts to testthis function */
1156 static test_return_t stats_servername_test(memcached_st *memc)
1157 {
1158 memcached_return_t rc;
1159 memcached_stat_st memc_stat;
1160 rc= memcached_stat_servername(&memc_stat, NULL,
1161 memc->hosts[0].hostname,
1162 memc->hosts[0].port);
1163
1164 return TEST_SUCCESS;
1165 }
1166
1167 static test_return_t increment_test(memcached_st *memc)
1168 {
1169 uint64_t new_number;
1170 memcached_return_t rc;
1171 const char *key= "number";
1172 const char *value= "0";
1173
1174 rc= memcached_set(memc, key, strlen(key),
1175 value, strlen(value),
1176 (time_t)0, (uint32_t)0);
1177 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1178
1179 rc= memcached_increment(memc, key, strlen(key),
1180 1, &new_number);
1181 test_truth(rc == MEMCACHED_SUCCESS);
1182 test_truth(new_number == 1);
1183
1184 rc= memcached_increment(memc, key, strlen(key),
1185 1, &new_number);
1186 test_truth(rc == MEMCACHED_SUCCESS);
1187 test_truth(new_number == 2);
1188
1189 return TEST_SUCCESS;
1190 }
1191
1192 static test_return_t increment_with_initial_test(memcached_st *memc)
1193 {
1194 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1195 {
1196 uint64_t new_number;
1197 memcached_return_t rc;
1198 const char *key= "number";
1199 uint64_t initial= 0;
1200
1201 rc= memcached_increment_with_initial(memc, key, strlen(key),
1202 1, initial, 0, &new_number);
1203 test_truth(rc == MEMCACHED_SUCCESS);
1204 test_truth(new_number == initial);
1205
1206 rc= memcached_increment_with_initial(memc, key, strlen(key),
1207 1, initial, 0, &new_number);
1208 test_truth(rc == MEMCACHED_SUCCESS);
1209 test_truth(new_number == (initial + 1));
1210 }
1211 return TEST_SUCCESS;
1212 }
1213
1214 static test_return_t decrement_test(memcached_st *memc)
1215 {
1216 uint64_t new_number;
1217 memcached_return_t rc;
1218 const char *key= "number";
1219 const char *value= "3";
1220
1221 rc= memcached_set(memc, key, strlen(key),
1222 value, strlen(value),
1223 (time_t)0, (uint32_t)0);
1224 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1225
1226 rc= memcached_decrement(memc, key, strlen(key),
1227 1, &new_number);
1228 test_truth(rc == MEMCACHED_SUCCESS);
1229 test_truth(new_number == 2);
1230
1231 rc= memcached_decrement(memc, key, strlen(key),
1232 1, &new_number);
1233 test_truth(rc == MEMCACHED_SUCCESS);
1234 test_truth(new_number == 1);
1235
1236 return TEST_SUCCESS;
1237 }
1238
1239 static test_return_t decrement_with_initial_test(memcached_st *memc)
1240 {
1241 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1242 {
1243 uint64_t new_number;
1244 memcached_return_t rc;
1245 const char *key= "number";
1246 uint64_t initial= 3;
1247
1248 rc= memcached_decrement_with_initial(memc, key, strlen(key),
1249 1, initial, 0, &new_number);
1250 test_truth(rc == MEMCACHED_SUCCESS);
1251 test_truth(new_number == initial);
1252
1253 rc= memcached_decrement_with_initial(memc, key, strlen(key),
1254 1, initial, 0, &new_number);
1255 test_truth(rc == MEMCACHED_SUCCESS);
1256 test_truth(new_number == (initial - 1));
1257 }
1258 return TEST_SUCCESS;
1259 }
1260
1261 static test_return_t increment_by_key_test(memcached_st *memc)
1262 {
1263 uint64_t new_number;
1264 memcached_return_t rc;
1265 const char *master_key= "foo";
1266 const char *key= "number";
1267 const char *value= "0";
1268
1269 rc= memcached_set_by_key(memc, master_key, strlen(master_key),
1270 key, strlen(key),
1271 value, strlen(value),
1272 (time_t)0, (uint32_t)0);
1273 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1274
1275 rc= memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key),
1276 1, &new_number);
1277 test_truth(rc == MEMCACHED_SUCCESS);
1278 test_truth(new_number == 1);
1279
1280 rc= memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key),
1281 1, &new_number);
1282 test_truth(rc == MEMCACHED_SUCCESS);
1283 test_truth(new_number == 2);
1284
1285 return TEST_SUCCESS;
1286 }
1287
1288 static test_return_t increment_with_initial_by_key_test(memcached_st *memc)
1289 {
1290 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1291 {
1292 uint64_t new_number;
1293 memcached_return_t rc;
1294 const char *master_key= "foo";
1295 const char *key= "number";
1296 uint64_t initial= 0;
1297
1298 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1299 key, strlen(key),
1300 1, initial, 0, &new_number);
1301 test_truth(rc == MEMCACHED_SUCCESS);
1302 test_truth(new_number == initial);
1303
1304 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1305 key, strlen(key),
1306 1, initial, 0, &new_number);
1307 test_truth(rc == MEMCACHED_SUCCESS);
1308 test_truth(new_number == (initial + 1));
1309 }
1310 return TEST_SUCCESS;
1311 }
1312
1313 static test_return_t decrement_by_key_test(memcached_st *memc)
1314 {
1315 uint64_t new_number;
1316 memcached_return_t rc;
1317 const char *master_key= "foo";
1318 const char *key= "number";
1319 const char *value= "3";
1320
1321 rc= memcached_set_by_key(memc, master_key, strlen(master_key),
1322 key, strlen(key),
1323 value, strlen(value),
1324 (time_t)0, (uint32_t)0);
1325 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1326
1327 rc= memcached_decrement_by_key(memc, master_key, strlen(master_key),
1328 key, strlen(key),
1329 1, &new_number);
1330 test_truth(rc == MEMCACHED_SUCCESS);
1331 test_truth(new_number == 2);
1332
1333 rc= memcached_decrement_by_key(memc, master_key, strlen(master_key),
1334 key, strlen(key),
1335 1, &new_number);
1336 test_truth(rc == MEMCACHED_SUCCESS);
1337 test_truth(new_number == 1);
1338
1339 return TEST_SUCCESS;
1340 }
1341
1342 static test_return_t decrement_with_initial_by_key_test(memcached_st *memc)
1343 {
1344 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1345 {
1346 uint64_t new_number;
1347 memcached_return_t rc;
1348 const char *master_key= "foo";
1349 const char *key= "number";
1350 uint64_t initial= 3;
1351
1352 rc= memcached_decrement_with_initial_by_key(memc, master_key, strlen(master_key),
1353 key, strlen(key),
1354 1, initial, 0, &new_number);
1355 test_truth(rc == MEMCACHED_SUCCESS);
1356 test_truth(new_number == initial);
1357
1358 rc= memcached_decrement_with_initial_by_key(memc, master_key, strlen(master_key),
1359 key, strlen(key),
1360 1, initial, 0, &new_number);
1361 test_truth(rc == MEMCACHED_SUCCESS);
1362 test_truth(new_number == (initial - 1));
1363 }
1364 return TEST_SUCCESS;
1365 }
1366
1367 static test_return_t quit_test(memcached_st *memc)
1368 {
1369 memcached_return_t rc;
1370 const char *key= "fudge";
1371 const char *value= "sanford and sun";
1372
1373 rc= memcached_set(memc, key, strlen(key),
1374 value, strlen(value),
1375 (time_t)10, (uint32_t)3);
1376 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1377 memcached_quit(memc);
1378
1379 rc= memcached_set(memc, key, strlen(key),
1380 value, strlen(value),
1381 (time_t)50, (uint32_t)9);
1382 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1383
1384 return TEST_SUCCESS;
1385 }
1386
1387 static test_return_t mget_result_test(memcached_st *memc)
1388 {
1389 memcached_return_t rc;
1390 const char *keys[]= {"fudge", "son", "food"};
1391 size_t key_length[]= {5, 3, 4};
1392 unsigned int x;
1393
1394 memcached_result_st results_obj;
1395 memcached_result_st *results;
1396
1397 results= memcached_result_create(memc, &results_obj);
1398 test_truth(results);
1399 test_truth(&results_obj == results);
1400
1401 /* We need to empty the server before continueing test */
1402 rc= memcached_flush(memc, 0);
1403 test_truth(rc == MEMCACHED_SUCCESS);
1404
1405 rc= memcached_mget(memc, keys, key_length, 3);
1406 test_truth(rc == MEMCACHED_SUCCESS);
1407
1408 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1409 {
1410 test_truth(results);
1411 }
1412
1413 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1414 test_truth(!results);
1415 test_truth(rc == MEMCACHED_END);
1416
1417 for (x= 0; x < 3; x++)
1418 {
1419 rc= memcached_set(memc, keys[x], key_length[x],
1420 keys[x], key_length[x],
1421 (time_t)50, (uint32_t)9);
1422 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1423 }
1424
1425 rc= memcached_mget(memc, keys, key_length, 3);
1426 test_truth(rc == MEMCACHED_SUCCESS);
1427
1428 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1429 {
1430 test_truth(results);
1431 test_truth(&results_obj == results);
1432 test_truth(rc == MEMCACHED_SUCCESS);
1433 test_truth(memcached_result_key_length(results) == memcached_result_length(results));
1434 test_truth(!memcmp(memcached_result_key_value(results),
1435 memcached_result_value(results),
1436 memcached_result_length(results)));
1437 }
1438
1439 memcached_result_free(&results_obj);
1440
1441 return TEST_SUCCESS;
1442 }
1443
1444 static test_return_t mget_result_alloc_test(memcached_st *memc)
1445 {
1446 memcached_return_t rc;
1447 const char *keys[]= {"fudge", "son", "food"};
1448 size_t key_length[]= {5, 3, 4};
1449 unsigned int x;
1450
1451 memcached_result_st *results;
1452
1453 /* We need to empty the server before continueing test */
1454 rc= memcached_flush(memc, 0);
1455 test_truth(rc == MEMCACHED_SUCCESS);
1456
1457 rc= memcached_mget(memc, keys, key_length, 3);
1458 test_truth(rc == MEMCACHED_SUCCESS);
1459
1460 while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL)
1461 {
1462 test_truth(results);
1463 }
1464 test_truth(!results);
1465 test_truth(rc == MEMCACHED_END);
1466
1467 for (x= 0; x < 3; x++)
1468 {
1469 rc= memcached_set(memc, keys[x], key_length[x],
1470 keys[x], key_length[x],
1471 (time_t)50, (uint32_t)9);
1472 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1473 }
1474
1475 rc= memcached_mget(memc, keys, key_length, 3);
1476 test_truth(rc == MEMCACHED_SUCCESS);
1477
1478 x= 0;
1479 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1480 {
1481 test_truth(results);
1482 test_truth(rc == MEMCACHED_SUCCESS);
1483 test_truth(memcached_result_key_length(results) == memcached_result_length(results));
1484 test_truth(!memcmp(memcached_result_key_value(results),
1485 memcached_result_value(results),
1486 memcached_result_length(results)));
1487 memcached_result_free(results);
1488 x++;
1489 }
1490
1491 return TEST_SUCCESS;
1492 }
1493
1494 /* Count the results */
1495 static memcached_return_t callback_counter(memcached_st *ptr __attribute__((unused)),
1496 memcached_result_st *result __attribute__((unused)),
1497 void *context)
1498 {
1499 unsigned int *counter= (unsigned int *)context;
1500
1501 *counter= *counter + 1;
1502
1503 return MEMCACHED_SUCCESS;
1504 }
1505
1506 static test_return_t mget_result_function(memcached_st *memc)
1507 {
1508 memcached_return_t rc;
1509 const char *keys[]= {"fudge", "son", "food"};
1510 size_t key_length[]= {5, 3, 4};
1511 unsigned int x;
1512 unsigned int counter;
1513 memcached_execute_fn callbacks[1];
1514
1515 /* We need to empty the server before continueing test */
1516 rc= memcached_flush(memc, 0);
1517 for (x= 0; x < 3; x++)
1518 {
1519 rc= memcached_set(memc, keys[x], key_length[x],
1520 keys[x], key_length[x],
1521 (time_t)50, (uint32_t)9);
1522 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1523 }
1524
1525 rc= memcached_mget(memc, keys, key_length, 3);
1526 test_truth(rc == MEMCACHED_SUCCESS);
1527
1528 callbacks[0]= &callback_counter;
1529 counter= 0;
1530 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1531
1532 test_truth(counter == 3);
1533
1534 return TEST_SUCCESS;
1535 }
1536
1537 static test_return_t mget_test(memcached_st *memc)
1538 {
1539 memcached_return_t rc;
1540 const char *keys[]= {"fudge", "son", "food"};
1541 size_t key_length[]= {5, 3, 4};
1542 unsigned int x;
1543 uint32_t flags;
1544
1545 char return_key[MEMCACHED_MAX_KEY];
1546 size_t return_key_length;
1547 char *return_value;
1548 size_t return_value_length;
1549
1550 /* We need to empty the server before continueing test */
1551 rc= memcached_flush(memc, 0);
1552 test_truth(rc == MEMCACHED_SUCCESS);
1553
1554 rc= memcached_mget(memc, keys, key_length, 3);
1555 test_truth(rc == MEMCACHED_SUCCESS);
1556
1557 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1558 &return_value_length, &flags, &rc)) != NULL)
1559 {
1560 test_truth(return_value);
1561 }
1562 test_truth(!return_value);
1563 test_truth(return_value_length == 0);
1564 test_truth(rc == MEMCACHED_END);
1565
1566 for (x= 0; x < 3; x++)
1567 {
1568 rc= memcached_set(memc, keys[x], key_length[x],
1569 keys[x], key_length[x],
1570 (time_t)50, (uint32_t)9);
1571 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1572 }
1573
1574 rc= memcached_mget(memc, keys, key_length, 3);
1575 test_truth(rc == MEMCACHED_SUCCESS);
1576
1577 x= 0;
1578 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1579 &return_value_length, &flags, &rc)))
1580 {
1581 test_truth(return_value);
1582 test_truth(rc == MEMCACHED_SUCCESS);
1583 test_truth(return_key_length == return_value_length);
1584 test_truth(!memcmp(return_value, return_key, return_value_length));
1585 free(return_value);
1586 x++;
1587 }
1588
1589 return TEST_SUCCESS;
1590 }
1591
1592 static test_return_t mget_execute(memcached_st *memc)
1593 {
1594 bool binary= false;
1595 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1596 binary= true;
1597
1598 /*
1599 * I only want to hit _one_ server so I know the number of requests I'm
1600 * sending in the pipeline.
1601 */
1602 uint32_t number_of_hosts= memc->number_of_hosts;
1603 memc->number_of_hosts= 1;
1604
1605 int max_keys= binary ? 20480 : 1;
1606
1607
1608 char **keys= calloc((size_t)max_keys, sizeof(char*));
1609 size_t *key_length=calloc((size_t)max_keys, sizeof(size_t));
1610
1611 /* First add all of the items.. */
1612 char blob[1024] = {0};
1613 memcached_return_t rc;
1614 for (int x= 0; x < max_keys; ++x)
1615 {
1616 char k[251];
1617 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
1618 keys[x]= strdup(k);
1619 test_truth(keys[x] != NULL);
1620 rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
1621 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1622 }
1623
1624 /* Try to get all of them with a large multiget */
1625 unsigned int counter= 0;
1626 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
1627 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
1628 (size_t)max_keys, callbacks, &counter, 1);
1629
1630 if (binary)
1631 {
1632 test_truth(rc == MEMCACHED_SUCCESS);
1633
1634 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1635 test_truth(rc == MEMCACHED_END);
1636
1637 /* Verify that we got all of the items */
1638 test_truth(counter == (unsigned int)max_keys);
1639 }
1640 else
1641 {
1642 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
1643 test_truth(counter == 0);
1644 }
1645
1646 /* Release all allocated resources */
1647 for (int x= 0; x < max_keys; ++x)
1648 free(keys[x]);
1649 free(keys);
1650 free(key_length);
1651
1652 memc->number_of_hosts= number_of_hosts;
1653 return TEST_SUCCESS;
1654 }
1655
1656 static test_return_t get_stats_keys(memcached_st *memc)
1657 {
1658 char **stat_list;
1659 char **ptr;
1660 memcached_stat_st memc_stat;
1661 memcached_return_t rc;
1662
1663 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1664 test_truth(rc == MEMCACHED_SUCCESS);
1665 for (ptr= stat_list; *ptr; ptr++)
1666 test_truth(*ptr);
1667
1668 free(stat_list);
1669
1670 return TEST_SUCCESS;
1671 }
1672
1673 static test_return_t version_string_test(memcached_st *memc __attribute__((unused)))
1674 {
1675 const char *version_string;
1676
1677 version_string= memcached_lib_version();
1678
1679 test_truth(!strcmp(version_string, LIBMEMCACHED_VERSION_STRING));
1680
1681 return TEST_SUCCESS;
1682 }
1683
1684 static test_return_t get_stats(memcached_st *memc)
1685 {
1686 unsigned int x;
1687 char **stat_list;
1688 char **ptr;
1689 memcached_return_t rc;
1690 memcached_stat_st *memc_stat;
1691
1692 memc_stat= memcached_stat(memc, NULL, &rc);
1693 test_truth(rc == MEMCACHED_SUCCESS);
1694
1695 test_truth(rc == MEMCACHED_SUCCESS);
1696 test_truth(memc_stat);
1697
1698 for (x= 0; x < memcached_server_count(memc); x++)
1699 {
1700 stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1701 test_truth(rc == MEMCACHED_SUCCESS);
1702 for (ptr= stat_list; *ptr; ptr++);
1703
1704 free(stat_list);
1705 }
1706
1707 memcached_stat_free(NULL, memc_stat);
1708
1709 return TEST_SUCCESS;
1710 }
1711
1712 static test_return_t add_host_test(memcached_st *memc)
1713 {
1714 unsigned int x;
1715 memcached_server_st *servers;
1716 memcached_return_t rc;
1717 char servername[]= "0.example.com";
1718
1719 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1720 test_truth(servers);
1721 test_truth(1 == memcached_server_list_count(servers));
1722
1723 for (x= 2; x < 20; x++)
1724 {
1725 char buffer[SMALL_STRING_LEN];
1726
1727 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1728 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1729 &rc);
1730 test_truth(rc == MEMCACHED_SUCCESS);
1731 test_truth(x == memcached_server_list_count(servers));
1732 }
1733
1734 rc= memcached_server_push(memc, servers);
1735 test_truth(rc == MEMCACHED_SUCCESS);
1736 rc= memcached_server_push(memc, servers);
1737 test_truth(rc == MEMCACHED_SUCCESS);
1738
1739 memcached_server_list_free(servers);
1740
1741 return TEST_SUCCESS;
1742 }
1743
1744 static memcached_return_t clone_test_callback(memcached_st *parent __attribute__((unused)), memcached_st *memc_clone __attribute__((unused)))
1745 {
1746 return MEMCACHED_SUCCESS;
1747 }
1748
1749 static memcached_return_t cleanup_test_callback(memcached_st *ptr __attribute__((unused)))
1750 {
1751 return MEMCACHED_SUCCESS;
1752 }
1753
1754 static test_return_t callback_test(memcached_st *memc)
1755 {
1756 /* Test User Data */
1757 {
1758 int x= 5;
1759 int *test_ptr;
1760 memcached_return_t rc;
1761
1762 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
1763 test_truth(rc == MEMCACHED_SUCCESS);
1764 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1765 test_truth(*test_ptr == x);
1766 }
1767
1768 /* Test Clone Callback */
1769 {
1770 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1771 void *clone_cb_ptr= *(void **)&clone_cb;
1772 void *temp_function= NULL;
1773 memcached_return_t rc;
1774
1775 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1776 clone_cb_ptr);
1777 test_truth(rc == MEMCACHED_SUCCESS);
1778 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1779 test_truth(temp_function == clone_cb_ptr);
1780 }
1781
1782 /* Test Cleanup Callback */
1783 {
1784 memcached_cleanup_fn cleanup_cb=
1785 (memcached_cleanup_fn)cleanup_test_callback;
1786 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1787 void *temp_function= NULL;
1788 memcached_return_t rc;
1789
1790 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1791 cleanup_cb_ptr);
1792 test_truth(rc == MEMCACHED_SUCCESS);
1793 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1794 test_truth(temp_function == cleanup_cb_ptr);
1795 }
1796
1797 return TEST_SUCCESS;
1798 }
1799
1800 /* We don't test the behavior itself, we test the switches */
1801 static test_return_t behavior_test(memcached_st *memc)
1802 {
1803 uint64_t value;
1804 uint32_t set= 1;
1805
1806 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1807 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1808 test_truth(value == 1);
1809
1810 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1811 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1812 test_truth(value == 1);
1813
1814 set= MEMCACHED_HASH_MD5;
1815 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1816 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1817 test_truth(value == MEMCACHED_HASH_MD5);
1818
1819 set= 0;
1820
1821 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1822 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1823 test_truth(value == 0);
1824
1825 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1826 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1827 test_truth(value == 0);
1828
1829 set= MEMCACHED_HASH_DEFAULT;
1830 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1831 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1832 test_truth(value == MEMCACHED_HASH_DEFAULT);
1833
1834 set= MEMCACHED_HASH_CRC;
1835 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1836 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1837 test_truth(value == MEMCACHED_HASH_CRC);
1838
1839 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1840 test_truth(value > 0);
1841
1842 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1843 test_truth(value > 0);
1844
1845 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
1846 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value + 1);
1847 test_truth((value + 1) == memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
1848 return TEST_SUCCESS;
1849 }
1850
1851 static test_return_t fetch_all_results(memcached_st *memc)
1852 {
1853 memcached_return_t rc= MEMCACHED_SUCCESS;
1854 char return_key[MEMCACHED_MAX_KEY];
1855 size_t return_key_length;
1856 char *return_value;
1857 size_t return_value_length;
1858 uint32_t flags;
1859
1860 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1861 &return_value_length, &flags, &rc)))
1862 {
1863 test_truth(return_value);
1864 test_truth(rc == MEMCACHED_SUCCESS);
1865 free(return_value);
1866 }
1867
1868 return ((rc == MEMCACHED_END) || (rc == MEMCACHED_SUCCESS)) ? TEST_SUCCESS : TEST_FAILURE;
1869 }
1870
1871 /* Test case provided by Cal Haldenbrand */
1872 static test_return_t user_supplied_bug1(memcached_st *memc)
1873 {
1874 unsigned int setter= 1;
1875 unsigned int x;
1876
1877 unsigned long long total= 0;
1878 uint32_t size= 0;
1879 char key[10];
1880 char randomstuff[6 * 1024];
1881 memcached_return_t rc;
1882
1883 memset(randomstuff, 0, 6 * 1024);
1884
1885 /* We just keep looking at the same values over and over */
1886 srandom(10);
1887
1888 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1889 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1890
1891
1892 /* add key */
1893 for (x= 0 ; total < 20 * 1024576 ; x++ )
1894 {
1895 unsigned int j= 0;
1896
1897 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
1898 memset(randomstuff, 0, 6 * 1024);
1899 test_truth(size < 6 * 1024); /* Being safe here */
1900
1901 for (j= 0 ; j < size ;j++)
1902 randomstuff[j] = (signed char) ((rand() % 26) + 97);
1903
1904 total += size;
1905 sprintf(key, "%d", x);
1906 rc = memcached_set(memc, key, strlen(key),
1907 randomstuff, strlen(randomstuff), 10, 0);
1908 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1909 /* If we fail, lets try again */
1910 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
1911 rc = memcached_set(memc, key, strlen(key),
1912 randomstuff, strlen(randomstuff), 10, 0);
1913 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1914 }
1915
1916 return TEST_SUCCESS;
1917 }
1918
1919 /* Test case provided by Cal Haldenbrand */
1920 static test_return_t user_supplied_bug2(memcached_st *memc)
1921 {
1922 int errors;
1923 unsigned int setter;
1924 unsigned int x;
1925 unsigned long long total;
1926
1927 setter= 1;
1928 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1929 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1930 #ifdef NOT_YET
1931 setter = 20 * 1024576;
1932 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1933 setter = 20 * 1024576;
1934 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1935 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1936 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1937
1938 for (x= 0, errors= 0, total= 0 ; total < 20 * 1024576 ; x++)
1939 #endif
1940
1941 for (x= 0, errors= 0, total= 0 ; total < 24576 ; x++)
1942 {
1943 memcached_return_t rc= MEMCACHED_SUCCESS;
1944 char buffer[SMALL_STRING_LEN];
1945 uint32_t flags= 0;
1946 size_t val_len= 0;
1947 char *getval;
1948
1949 memset(buffer, 0, SMALL_STRING_LEN);
1950
1951 snprintf(buffer, SMALL_STRING_LEN, "%u", x);
1952 getval= memcached_get(memc, buffer, strlen(buffer),
1953 &val_len, &flags, &rc);
1954 if (rc != MEMCACHED_SUCCESS)
1955 {
1956 if (rc == MEMCACHED_NOTFOUND)
1957 errors++;
1958 else
1959 {
1960 test_truth(rc);
1961 }
1962
1963 continue;
1964 }
1965 total+= val_len;
1966 errors= 0;
1967 free(getval);
1968 }
1969
1970 return TEST_SUCCESS;
1971 }
1972
1973 /* Do a large mget() over all the keys we think exist */
1974 #define KEY_COUNT 3000 // * 1024576
1975 static test_return_t user_supplied_bug3(memcached_st *memc)
1976 {
1977 memcached_return_t rc;
1978 unsigned int setter;
1979 unsigned int x;
1980 char **keys;
1981 size_t key_lengths[KEY_COUNT];
1982
1983 setter= 1;
1984 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1985 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1986 #ifdef NOT_YET
1987 setter = 20 * 1024576;
1988 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1989 setter = 20 * 1024576;
1990 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1991 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1992 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1993 #endif
1994
1995 keys= calloc(KEY_COUNT, sizeof(char *));
1996 test_truth(keys);
1997 for (x= 0; x < KEY_COUNT; x++)
1998 {
1999 char buffer[30];
2000
2001 snprintf(buffer, 30, "%u", x);
2002 keys[x]= strdup(buffer);
2003 key_lengths[x]= strlen(keys[x]);
2004 }
2005
2006 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
2007 test_truth(rc == MEMCACHED_SUCCESS);
2008
2009 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
2010
2011 for (x= 0; x < KEY_COUNT; x++)
2012 free(keys[x]);
2013 free(keys);
2014
2015 return TEST_SUCCESS;
2016 }
2017
2018 /* Make sure we behave properly if server list has no values */
2019 static test_return_t user_supplied_bug4(memcached_st *memc)
2020 {
2021 memcached_return_t rc;
2022 const char *keys[]= {"fudge", "son", "food"};
2023 size_t key_length[]= {5, 3, 4};
2024 unsigned int x;
2025 uint32_t flags;
2026 char return_key[MEMCACHED_MAX_KEY];
2027 size_t return_key_length;
2028 char *return_value;
2029 size_t return_value_length;
2030
2031 /* Here we free everything before running a bunch of mget tests */
2032 {
2033 memcached_server_list_free(memc->hosts);
2034 memc->hosts= NULL;
2035 memc->number_of_hosts= 0;
2036 }
2037
2038
2039 /* We need to empty the server before continueing test */
2040 rc= memcached_flush(memc, 0);
2041 test_truth(rc == MEMCACHED_NO_SERVERS);
2042
2043 rc= memcached_mget(memc, keys, key_length, 3);
2044 test_truth(rc == MEMCACHED_NO_SERVERS);
2045
2046 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2047 &return_value_length, &flags, &rc)) != NULL)
2048 {
2049 test_truth(return_value);
2050 }
2051 test_truth(!return_value);
2052 test_truth(return_value_length == 0);
2053 test_truth(rc == MEMCACHED_NO_SERVERS);
2054
2055 for (x= 0; x < 3; x++)
2056 {
2057 rc= memcached_set(memc, keys[x], key_length[x],
2058 keys[x], key_length[x],
2059 (time_t)50, (uint32_t)9);
2060 test_truth(rc == MEMCACHED_NO_SERVERS);
2061 }
2062
2063 rc= memcached_mget(memc, keys, key_length, 3);
2064 test_truth(rc == MEMCACHED_NO_SERVERS);
2065
2066 x= 0;
2067 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2068 &return_value_length, &flags, &rc)))
2069 {
2070 test_truth(return_value);
2071 test_truth(rc == MEMCACHED_SUCCESS);
2072 test_truth(return_key_length == return_value_length);
2073 test_truth(!memcmp(return_value, return_key, return_value_length));
2074 free(return_value);
2075 x++;
2076 }
2077
2078 return TEST_SUCCESS;
2079 }
2080
2081 #define VALUE_SIZE_BUG5 1048064
2082 static test_return_t user_supplied_bug5(memcached_st *memc)
2083 {
2084 memcached_return_t rc;
2085 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2086 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2087 char return_key[MEMCACHED_MAX_KEY];
2088 size_t return_key_length;
2089 char *value;
2090 size_t value_length;
2091 uint32_t flags;
2092 unsigned int count;
2093 unsigned int x;
2094 char insert_data[VALUE_SIZE_BUG5];
2095
2096 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2097 insert_data[x]= (signed char)rand();
2098
2099 memcached_flush(memc, 0);
2100 value= memcached_get(memc, keys[0], key_length[0],
2101 &value_length, &flags, &rc);
2102 test_truth(value == NULL);
2103 rc= memcached_mget(memc, keys, key_length, 4);
2104
2105 count= 0;
2106 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2107 &value_length, &flags, &rc)))
2108 count++;
2109 test_truth(count == 0);
2110
2111 for (x= 0; x < 4; x++)
2112 {
2113 rc= memcached_set(memc, keys[x], key_length[x],
2114 insert_data, VALUE_SIZE_BUG5,
2115 (time_t)0, (uint32_t)0);
2116 test_truth(rc == MEMCACHED_SUCCESS);
2117 }
2118
2119 for (x= 0; x < 10; x++)
2120 {
2121 value= memcached_get(memc, keys[0], key_length[0],
2122 &value_length, &flags, &rc);
2123 test_truth(value);
2124 free(value);
2125
2126 rc= memcached_mget(memc, keys, key_length, 4);
2127 count= 0;
2128 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2129 &value_length, &flags, &rc)))
2130 {
2131 count++;
2132 free(value);
2133 }
2134 test_truth(count == 4);
2135 }
2136
2137 return TEST_SUCCESS;
2138 }
2139
2140 static test_return_t user_supplied_bug6(memcached_st *memc)
2141 {
2142 memcached_return_t rc;
2143 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2144 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2145 char return_key[MEMCACHED_MAX_KEY];
2146 size_t return_key_length;
2147 char *value;
2148 size_t value_length;
2149 uint32_t flags;
2150 unsigned int count;
2151 unsigned int x;
2152 char insert_data[VALUE_SIZE_BUG5];
2153
2154 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2155 insert_data[x]= (signed char)rand();
2156
2157 memcached_flush(memc, 0);
2158 value= memcached_get(memc, keys[0], key_length[0],
2159 &value_length, &flags, &rc);
2160 test_truth(value == NULL);
2161 test_truth(rc == MEMCACHED_NOTFOUND);
2162 rc= memcached_mget(memc, keys, key_length, 4);
2163 test_truth(rc == MEMCACHED_SUCCESS);
2164
2165 count= 0;
2166 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2167 &value_length, &flags, &rc)))
2168 count++;
2169 test_truth(count == 0);
2170 test_truth(rc == MEMCACHED_END);
2171
2172 for (x= 0; x < 4; x++)
2173 {
2174 rc= memcached_set(memc, keys[x], key_length[x],
2175 insert_data, VALUE_SIZE_BUG5,
2176 (time_t)0, (uint32_t)0);
2177 test_truth(rc == MEMCACHED_SUCCESS);
2178 }
2179
2180 for (x= 0; x < 2; x++)
2181 {
2182 value= memcached_get(memc, keys[0], key_length[0],
2183 &value_length, &flags, &rc);
2184 test_truth(value);
2185 free(value);
2186
2187 rc= memcached_mget(memc, keys, key_length, 4);
2188 test_truth(rc == MEMCACHED_SUCCESS);
2189 count= 3;
2190 /* We test for purge of partial complete fetches */
2191 for (count= 3; count; count--)
2192 {
2193 value= memcached_fetch(memc, return_key, &return_key_length,
2194 &value_length, &flags, &rc);
2195 test_truth(rc == MEMCACHED_SUCCESS);
2196 test_truth(!(memcmp(value, insert_data, value_length)));
2197 test_truth(value_length);
2198 free(value);
2199 }
2200 }
2201
2202 return TEST_SUCCESS;
2203 }
2204
2205 static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused)))
2206 {
2207 memcached_return_t rc;
2208 memcached_st *mine;
2209 memcached_st *memc_clone;
2210
2211 memcached_server_st *servers;
2212 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";
2213
2214 servers= memcached_servers_parse(server_list);
2215 test_truth(servers);
2216
2217 mine= memcached_create(NULL);
2218 rc= memcached_server_push(mine, servers);
2219 test_truth(rc == MEMCACHED_SUCCESS);
2220 memcached_server_list_free(servers);
2221
2222 test_truth(mine);
2223 memc_clone= memcached_clone(NULL, mine);
2224
2225 memcached_quit(mine);
2226 memcached_quit(memc_clone);
2227
2228
2229 memcached_free(mine);
2230 memcached_free(memc_clone);
2231
2232 return TEST_SUCCESS;
2233 }
2234
2235 /* Test flag store/retrieve */
2236 static test_return_t user_supplied_bug7(memcached_st *memc)
2237 {
2238 memcached_return_t rc;
2239 const char *keys= "036790384900";
2240 size_t key_length= strlen(keys);
2241 char return_key[MEMCACHED_MAX_KEY];
2242 size_t return_key_length;
2243 char *value;
2244 size_t value_length;
2245 uint32_t flags;
2246 unsigned int x;
2247 char insert_data[VALUE_SIZE_BUG5];
2248
2249 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2250 insert_data[x]= (signed char)rand();
2251
2252 memcached_flush(memc, 0);
2253
2254 flags= 245;
2255 rc= memcached_set(memc, keys, key_length,
2256 insert_data, VALUE_SIZE_BUG5,
2257 (time_t)0, flags);
2258 test_truth(rc == MEMCACHED_SUCCESS);
2259
2260 flags= 0;
2261 value= memcached_get(memc, keys, key_length,
2262 &value_length, &flags, &rc);
2263 test_truth(flags == 245);
2264 test_truth(value);
2265 free(value);
2266
2267 rc= memcached_mget(memc, &keys, &key_length, 1);
2268
2269 flags= 0;
2270 value= memcached_fetch(memc, return_key, &return_key_length,
2271 &value_length, &flags, &rc);
2272 test_truth(flags == 245);
2273 test_truth(value);
2274 free(value);
2275
2276
2277 return TEST_SUCCESS;
2278 }
2279
2280 static test_return_t user_supplied_bug9(memcached_st *memc)
2281 {
2282 memcached_return_t rc;
2283 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2284 size_t key_length[3];
2285 unsigned int x;
2286 uint32_t flags;
2287 unsigned count= 0;
2288
2289 char return_key[MEMCACHED_MAX_KEY];
2290 size_t return_key_length;
2291 char *return_value;
2292 size_t return_value_length;
2293
2294
2295 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2296 key_length[1]= strlen("fudge&*@#");
2297 key_length[2]= strlen("for^#@&$not");
2298
2299
2300 for (x= 0; x < 3; x++)
2301 {
2302 rc= memcached_set(memc, keys[x], key_length[x],
2303 keys[x], key_length[x],
2304 (time_t)50, (uint32_t)9);
2305 test_truth(rc == MEMCACHED_SUCCESS);
2306 }
2307
2308 rc= memcached_mget(memc, keys, key_length, 3);
2309 test_truth(rc == MEMCACHED_SUCCESS);
2310
2311 /* We need to empty the server before continueing test */
2312 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2313 &return_value_length, &flags, &rc)) != NULL)
2314 {
2315 test_truth(return_value);
2316 free(return_value);
2317 count++;
2318 }
2319 test_truth(count == 3);
2320
2321 return TEST_SUCCESS;
2322 }
2323
2324 /* We are testing with aggressive timeout to get failures */
2325 static test_return_t user_supplied_bug10(memcached_st *memc)
2326 {
2327 const char *key= "foo";
2328 char *value;
2329 size_t value_length= 512;
2330 unsigned int x;
2331 size_t key_len= 3;
2332 memcached_return_t rc;
2333 unsigned int set= 1;
2334 memcached_st *mclone= memcached_clone(NULL, memc);
2335 int32_t timeout;
2336
2337 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2338 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2339 timeout= 2;
2340 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2341 (uint64_t)timeout);
2342
2343 value = (char*)malloc(value_length * sizeof(char));
2344
2345 for (x= 0; x < value_length; x++)
2346 value[x]= (char) (x % 127);
2347
2348 for (x= 1; x <= 100000; ++x)
2349 {
2350 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2351
2352 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2353 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2354
2355 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2356 x--;
2357 }
2358
2359 free(value);
2360 memcached_free(mclone);
2361
2362 return TEST_SUCCESS;
2363 }
2364
2365 /*
2366 We are looking failures in the async protocol
2367 */
2368 static test_return_t user_supplied_bug11(memcached_st *memc)
2369 {
2370 const char *key= "foo";
2371 char *value;
2372 size_t value_length= 512;
2373 unsigned int x;
2374 size_t key_len= 3;
2375 memcached_return_t rc;
2376 unsigned int set= 1;
2377 int32_t timeout;
2378 memcached_st *mclone= memcached_clone(NULL, memc);
2379
2380 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2381 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2382 timeout= -1;
2383 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2384 (size_t)timeout);
2385
2386 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2387
2388 test_truth(timeout == -1);
2389
2390 value = (char*)malloc(value_length * sizeof(char));
2391
2392 for (x= 0; x < value_length; x++)
2393 value[x]= (char) (x % 127);
2394
2395 for (x= 1; x <= 100000; ++x)
2396 {
2397 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2398 }
2399
2400 free(value);
2401 memcached_free(mclone);
2402
2403 return TEST_SUCCESS;
2404 }
2405
2406 /*
2407 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2408 */
2409 static test_return_t user_supplied_bug12(memcached_st *memc)
2410 {
2411 memcached_return_t rc;
2412 uint32_t flags;
2413 size_t value_length;
2414 char *value;
2415 uint64_t number_value;
2416
2417 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2418 &value_length, &flags, &rc);
2419 test_truth(value == NULL);
2420 test_truth(rc == MEMCACHED_NOTFOUND);
2421
2422 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2423 1, &number_value);
2424
2425 test_truth(value == NULL);
2426 /* The binary protocol will set the key if it doesn't exist */
2427 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2428 {
2429 test_truth(rc == MEMCACHED_SUCCESS);
2430 }
2431 else
2432 {
2433 test_truth(rc == MEMCACHED_NOTFOUND);
2434 }
2435
2436 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2437
2438 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2439 &value_length, &flags, &rc);
2440 test_truth(value);
2441 test_truth(rc == MEMCACHED_SUCCESS);
2442 free(value);
2443
2444 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2445 1, &number_value);
2446 test_truth(number_value == 2);
2447 test_truth(rc == MEMCACHED_SUCCESS);
2448
2449 return TEST_SUCCESS;
2450 }
2451
2452 /*
2453 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2454 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2455 */
2456 static test_return_t user_supplied_bug13(memcached_st *memc)
2457 {
2458 char key[] = "key34567890";
2459 char *overflow;
2460 memcached_return_t rc;
2461 size_t overflowSize;
2462
2463 char commandFirst[]= "set key34567890 0 0 ";
2464 char commandLast[] = " \r\n"; /* first line of command sent to server */
2465 size_t commandLength;
2466 size_t testSize;
2467
2468 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2469
2470 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2471
2472 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2473 {
2474 overflow= malloc(testSize);
2475 test_truth(overflow != NULL);
2476
2477 memset(overflow, 'x', testSize);
2478 rc= memcached_set(memc, key, strlen(key),
2479 overflow, testSize, 0, 0);
2480 test_truth(rc == MEMCACHED_SUCCESS);
2481 free(overflow);
2482 }
2483
2484 return TEST_SUCCESS;
2485 }
2486
2487
2488 /*
2489 Test values of many different sizes
2490 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2491 set key34567890 0 0 8169 \r\n
2492 is sent followed by buffer of size 8169, followed by 8169
2493 */
2494 static test_return_t user_supplied_bug14(memcached_st *memc)
2495 {
2496 size_t setter= 1;
2497 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2498 memcached_return_t rc;
2499 const char *key= "foo";
2500 char *value;
2501 size_t value_length= 18000;
2502 char *string;
2503 size_t string_length;
2504 uint32_t flags;
2505 unsigned int x;
2506 size_t current_length;
2507
2508 value = (char*)malloc(value_length);
2509 test_truth(value);
2510
2511 for (x= 0; x < value_length; x++)
2512 value[x] = (char) (x % 127);
2513
2514 for (current_length= 0; current_length < value_length; current_length++)
2515 {
2516 rc= memcached_set(memc, key, strlen(key),
2517 value, current_length,
2518 (time_t)0, (uint32_t)0);
2519 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2520
2521 string= memcached_get(memc, key, strlen(key),
2522 &string_length, &flags, &rc);
2523
2524 test_truth(rc == MEMCACHED_SUCCESS);
2525 test_truth(string_length == current_length);
2526 test_truth(!memcmp(string, value, string_length));
2527
2528 free(string);
2529 }
2530
2531 free(value);
2532
2533 return TEST_SUCCESS;
2534 }
2535
2536 /*
2537 Look for zero length value problems
2538 */
2539 static test_return_t user_supplied_bug15(memcached_st *memc)
2540 {
2541 uint32_t x;
2542 memcached_return_t rc;
2543 const char *key= "mykey";
2544 char *value;
2545 size_t length;
2546 uint32_t flags;
2547
2548 for (x= 0; x < 2; x++)
2549 {
2550 rc= memcached_set(memc, key, strlen(key),
2551 NULL, 0,
2552 (time_t)0, (uint32_t)0);
2553
2554 test_truth(rc == MEMCACHED_SUCCESS);
2555
2556 value= memcached_get(memc, key, strlen(key),
2557 &length, &flags, &rc);
2558
2559 test_truth(rc == MEMCACHED_SUCCESS);
2560 test_truth(value == NULL);
2561 test_truth(length == 0);
2562 test_truth(flags == 0);
2563
2564 value= memcached_get(memc, key, strlen(key),
2565 &length, &flags, &rc);
2566
2567 test_truth(rc == MEMCACHED_SUCCESS);
2568 test_truth(value == NULL);
2569 test_truth(length == 0);
2570 test_truth(flags == 0);
2571 }
2572
2573 return TEST_SUCCESS;
2574 }
2575
2576 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2577 static test_return_t user_supplied_bug16(memcached_st *memc)
2578 {
2579 memcached_return_t rc;
2580 const char *key= "mykey";
2581 char *value;
2582 size_t length;
2583 uint32_t flags;
2584
2585 rc= memcached_set(memc, key, strlen(key),
2586 NULL, 0,
2587 (time_t)0, UINT32_MAX);
2588
2589 test_truth(rc == MEMCACHED_SUCCESS);
2590
2591 value= memcached_get(memc, key, strlen(key),
2592 &length, &flags, &rc);
2593
2594 test_truth(rc == MEMCACHED_SUCCESS);
2595 test_truth(value == NULL);
2596 test_truth(length == 0);
2597 test_truth(flags == UINT32_MAX);
2598
2599 return TEST_SUCCESS;
2600 }
2601
2602 #ifndef __sun
2603 /* Check the validity of chinese key*/
2604 static test_return_t user_supplied_bug17(memcached_st *memc)
2605 {
2606 memcached_return_t rc;
2607 const char *key= "豆瓣";
2608 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2609 char *value2;
2610 size_t length;
2611 uint32_t flags;
2612
2613 rc= memcached_set(memc, key, strlen(key),
2614 value, strlen(value),
2615 (time_t)0, 0);
2616
2617 test_truth(rc == MEMCACHED_SUCCESS);
2618
2619 value2= memcached_get(memc, key, strlen(key),
2620 &length, &flags, &rc);
2621
2622 test_truth(length==strlen(value));
2623 test_truth(rc == MEMCACHED_SUCCESS);
2624 test_truth(memcmp(value, value2, length)==0);
2625 free(value2);
2626
2627 return TEST_SUCCESS;
2628 }
2629 #endif
2630
2631 /*
2632 From Andrei on IRC
2633 */
2634
2635 static test_return_t user_supplied_bug19(memcached_st *memc)
2636 {
2637 memcached_st *m;
2638 memcached_server_st *s;
2639 memcached_return_t res;
2640
2641 (void)memc;
2642
2643 m= memcached_create(NULL);
2644 memcached_server_add_with_weight(m, "localhost", 11311, 100);
2645 memcached_server_add_with_weight(m, "localhost", 11312, 100);
2646
2647 s= memcached_server_by_key(m, "a", 1, &res);
2648 memcached_server_free(s);
2649
2650 memcached_free(m);
2651
2652 return TEST_SUCCESS;
2653 }
2654
2655 /* CAS test from Andei */
2656 static test_return_t user_supplied_bug20(memcached_st *memc)
2657 {
2658 memcached_return_t status;
2659 memcached_result_st *result, result_obj;
2660 const char *key = "abc";
2661 size_t key_len = strlen("abc");
2662 const char *value = "foobar";
2663 size_t value_len = strlen(value);
2664
2665 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2666
2667 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2668 test_truth(status == MEMCACHED_SUCCESS);
2669
2670 status = memcached_mget(memc, &key, &key_len, 1);
2671 test_truth(status == MEMCACHED_SUCCESS);
2672
2673 result= memcached_result_create(memc, &result_obj);
2674 test_truth(result);
2675
2676 memcached_result_create(memc, &result_obj);
2677 result= memcached_fetch_result(memc, &result_obj, &status);
2678
2679 test_truth(result);
2680 test_truth(status == MEMCACHED_SUCCESS);
2681
2682 memcached_result_free(result);
2683
2684 return TEST_SUCCESS;
2685 }
2686
2687 #include "ketama_test_cases.h"
2688 static test_return_t user_supplied_bug18(memcached_st *trash)
2689 {
2690 memcached_return_t rc;
2691 uint64_t value;
2692 int x;
2693 memcached_server_st *server_pool;
2694 memcached_st *memc;
2695
2696 (void)trash;
2697
2698 memc= memcached_create(NULL);
2699 test_truth(memc);
2700
2701 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2702 test_truth(rc == MEMCACHED_SUCCESS);
2703
2704 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2705 test_truth(value == 1);
2706
2707 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2708 test_truth(rc == MEMCACHED_SUCCESS);
2709
2710 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2711 test_truth(value == MEMCACHED_HASH_MD5);
2712
2713 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");
2714 memcached_server_push(memc, server_pool);
2715
2716 /* verify that the server list was parsed okay. */
2717 test_truth(memc->number_of_hosts == 8);
2718 test_truth(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2719 test_truth(server_pool[0].port == 11211);
2720 test_truth(server_pool[0].weight == 600);
2721 test_truth(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2722 test_truth(server_pool[2].port == 11211);
2723 test_truth(server_pool[2].weight == 200);
2724 test_truth(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2725 test_truth(server_pool[7].port == 11211);
2726 test_truth(server_pool[7].weight == 100);
2727
2728 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2729 * us test the boundary wraparound.
2730 */
2731 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2732
2733 /* verify the standard ketama set. */
2734 for (x= 0; x < 99; x++)
2735 {
2736 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2737 char *hostname = memc->hosts[server_idx].hostname;
2738 test_strcmp(hostname, ketama_test_cases[x].server);
2739 }
2740
2741 memcached_server_list_free(server_pool);
2742 memcached_free(memc);
2743
2744 return TEST_SUCCESS;
2745 }
2746
2747 /* Large mget() of missing keys with binary proto
2748 *
2749 * If many binary quiet commands (such as getq's in an mget) fill the output
2750 * buffer and the server chooses not to respond, memcached_flush hangs. See
2751 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2752 */
2753
2754 /* sighandler_t function that always asserts false */
2755 static void fail(int unused __attribute__((unused)))
2756 {
2757 assert(0);
2758 }
2759
2760
2761 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2762 {
2763 memcached_return_t rc;
2764 unsigned int x;
2765 char **keys;
2766 size_t* key_lengths;
2767 void (*oldalarm)(int);
2768 memcached_st *memc_clone;
2769
2770 memc_clone= memcached_clone(NULL, memc);
2771 test_truth(memc_clone);
2772
2773 /* only binproto uses getq for mget */
2774 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2775
2776 /* empty the cache to ensure misses (hence non-responses) */
2777 rc= memcached_flush(memc_clone, 0);
2778 test_truth(rc == MEMCACHED_SUCCESS);
2779
2780 key_lengths= calloc(key_count, sizeof(size_t));
2781 keys= calloc(key_count, sizeof(char *));
2782 test_truth(keys);
2783 for (x= 0; x < key_count; x++)
2784 {
2785 char buffer[30];
2786
2787 snprintf(buffer, 30, "%u", x);
2788 keys[x]= strdup(buffer);
2789 key_lengths[x]= strlen(keys[x]);
2790 }
2791
2792 oldalarm= signal(SIGALRM, fail);
2793 alarm(5);
2794
2795 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
2796 test_truth(rc == MEMCACHED_SUCCESS);
2797
2798 alarm(0);
2799 signal(SIGALRM, oldalarm);
2800
2801 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
2802
2803 for (x= 0; x < key_count; x++)
2804 free(keys[x]);
2805 free(keys);
2806 free(key_lengths);
2807
2808 memcached_free(memc_clone);
2809
2810 return TEST_SUCCESS;
2811 }
2812
2813 static test_return_t pre_binary(memcached_st *memc);
2814
2815 static test_return_t user_supplied_bug21(memcached_st *memc)
2816 {
2817 test_return_t test_rc;
2818 test_rc= pre_binary(memc);
2819
2820 if (test_rc != TEST_SUCCESS)
2821 return test_rc;
2822
2823 test_return_t rc;
2824
2825 /* should work as of r580 */
2826 rc= _user_supplied_bug21(memc, 10);
2827 test_truth(rc == TEST_SUCCESS);
2828
2829 /* should fail as of r580 */
2830 rc= _user_supplied_bug21(memc, 1000);
2831 test_truth(rc == TEST_SUCCESS);
2832
2833 return TEST_SUCCESS;
2834 }
2835
2836 static test_return_t auto_eject_hosts(memcached_st *trash)
2837 {
2838 (void) trash;
2839
2840 memcached_return_t rc;
2841 memcached_st *memc= memcached_create(NULL);
2842 test_truth(memc);
2843
2844 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2845 test_truth(rc == MEMCACHED_SUCCESS);
2846
2847 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2848 test_truth(value == 1);
2849
2850 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2851 test_truth(rc == MEMCACHED_SUCCESS);
2852
2853 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2854 test_truth(value == MEMCACHED_HASH_MD5);
2855
2856 /* server should be removed when in delay */
2857 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
2858 test_truth(rc == MEMCACHED_SUCCESS);
2859
2860 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
2861 test_truth(value == 1);
2862
2863 memcached_server_st *server_pool;
2864 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");
2865 memcached_server_push(memc, server_pool);
2866
2867 /* verify that the server list was parsed okay. */
2868 test_truth(memc->number_of_hosts == 8);
2869 test_truth(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2870 test_truth(server_pool[0].port == 11211);
2871 test_truth(server_pool[0].weight == 600);
2872 test_truth(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2873 test_truth(server_pool[2].port == 11211);
2874 test_truth(server_pool[2].weight == 200);
2875 test_truth(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2876 test_truth(server_pool[7].port == 11211);
2877 test_truth(server_pool[7].weight == 100);
2878
2879 memc->hosts[2].next_retry = time(NULL) + 15;
2880 memc->next_distribution_rebuild= time(NULL) - 1;
2881
2882 for (int x= 0; x < 99; x++)
2883 {
2884 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2885 test_truth(server_idx != 2);
2886 }
2887
2888 /* and re-added when it's back. */
2889 memc->hosts[2].next_retry = time(NULL) - 1;
2890 memc->next_distribution_rebuild= time(NULL) - 1;
2891 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
2892 memc->distribution);
2893 for (int x= 0; x < 99; x++)
2894 {
2895 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2896 char *hostname = memc->hosts[server_idx].hostname;
2897 test_truth(strcmp(hostname, ketama_test_cases[x].server) == 0);
2898 }
2899
2900 memcached_server_list_free(server_pool);
2901 memcached_free(memc);
2902
2903 return TEST_SUCCESS;
2904 }
2905
2906 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
2907 {
2908 (void) trash;
2909
2910 memcached_return_t rc;
2911 memcached_st *memc= memcached_create(NULL);
2912 test_truth(memc);
2913
2914
2915 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2916 test_truth(rc == MEMCACHED_SUCCESS);
2917
2918 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2919 test_truth(value == 1);
2920
2921 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2922 test_truth(rc == MEMCACHED_SUCCESS);
2923
2924 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2925 test_truth(value == MEMCACHED_HASH_MD5);
2926
2927
2928 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2929
2930 memcached_server_st *server_pool;
2931 server_pool = memcached_servers_parse("10.0.1.1:11211,10.0.1.2:11211,10.0.1.3:11211,10.0.1.4:11211,10.0.1.5:11211,10.0.1.6:11211,10.0.1.7:11211,10.0.1.8:11211,192.168.1.1:11211,192.168.100.1:11211");
2932 memcached_server_push(memc, server_pool);
2933
2934 // @todo this needs to be refactored to actually test something.
2935 #if 0
2936 FILE *fp;
2937 if ((fp = fopen("ketama_keys.txt", "w")))
2938 {
2939 // noop
2940 } else {
2941 printf("cannot write to file ketama_keys.txt");
2942 return TEST_FAILURE;
2943 }
2944
2945 for (int x= 0; x < 10000; x++)
2946 {
2947 char key[10];
2948 sprintf(key, "%d", x);
2949
2950 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2951 char *hostname = memc->hosts[server_idx].hostname;
2952 in_port_t port = memc->hosts[server_idx].port;
2953 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2954 }
2955 fclose(fp);
2956 #endif
2957 memcached_server_list_free(server_pool);
2958 memcached_free(memc);
2959
2960 return TEST_SUCCESS;
2961 }
2962
2963
2964 static test_return_t result_static(memcached_st *memc)
2965 {
2966 memcached_result_st result;
2967 memcached_result_st *result_ptr;
2968
2969 result_ptr= memcached_result_create(memc, &result);
2970 test_truth(result.options.is_allocated == false);
2971 test_truth(memcached_is_initialized(&result) == true);
2972 test_truth(result_ptr);
2973 test_truth(result_ptr == &result);
2974
2975 memcached_result_free(&result);
2976
2977 test_truth(result.options.is_allocated == false);
2978 test_truth(memcached_is_initialized(&result) == false);
2979
2980 return TEST_SUCCESS;
2981 }
2982
2983 static test_return_t result_alloc(memcached_st *memc)
2984 {
2985 memcached_result_st *result_ptr;
2986
2987 result_ptr= memcached_result_create(memc, NULL);
2988 test_truth(result_ptr);
2989 test_truth(result_ptr->options.is_allocated == true);
2990 test_truth(memcached_is_initialized(result_ptr) == true);
2991 memcached_result_free(result_ptr);
2992
2993 return TEST_SUCCESS;
2994 }
2995
2996 static test_return_t string_static_null(memcached_st *memc)
2997 {
2998 memcached_string_st string;
2999 memcached_string_st *string_ptr;
3000
3001 string_ptr= memcached_string_create(memc, &string, 0);
3002 test_truth(string.options.is_initialized == true);
3003 test_truth(string_ptr);
3004
3005 /* The following two better be the same! */
3006 test_truth(memcached_is_allocated(string_ptr) == false);
3007 test_truth(memcached_is_allocated(&string) == false);
3008 test_truth(&string == string_ptr);
3009
3010 test_truth(string.options.is_initialized == true);
3011 test_truth(memcached_is_initialized(&string) == true);
3012 memcached_string_free(&string);
3013 test_truth(memcached_is_initialized(&string) == false);
3014
3015 return TEST_SUCCESS;
3016 }
3017
3018 static test_return_t string_alloc_null(memcached_st *memc)
3019 {
3020 memcached_string_st *string;
3021
3022 string= memcached_string_create(memc, NULL, 0);
3023 test_truth(string);
3024 test_truth(memcached_is_allocated(string) == true);
3025 test_truth(memcached_is_initialized(string) == true);
3026 memcached_string_free(string);
3027
3028 return TEST_SUCCESS;
3029 }
3030
3031 static test_return_t string_alloc_with_size(memcached_st *memc)
3032 {
3033 memcached_string_st *string;
3034
3035 string= memcached_string_create(memc, NULL, 1024);
3036 test_truth(string);
3037 test_truth(memcached_is_allocated(string) == true);
3038 test_truth(memcached_is_initialized(string) == true);
3039 memcached_string_free(string);
3040
3041 return TEST_SUCCESS;
3042 }
3043
3044 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
3045 {
3046 memcached_string_st *string;
3047
3048 string= memcached_string_create(memc, NULL, SIZE_MAX);
3049 test_truth(string == NULL);
3050
3051 return TEST_SUCCESS;
3052 }
3053
3054 static test_return_t string_alloc_append(memcached_st *memc)
3055 {
3056 unsigned int x;
3057 char buffer[SMALL_STRING_LEN];
3058 memcached_string_st *string;
3059
3060 /* Ring the bell! */
3061 memset(buffer, 6, SMALL_STRING_LEN);
3062
3063 string= memcached_string_create(memc, NULL, 100);
3064 test_truth(string);
3065 test_truth(memcached_is_allocated(string) == true);
3066 test_truth(memcached_is_initialized(string) == true);
3067
3068 for (x= 0; x < 1024; x++)
3069 {
3070 memcached_return_t rc;
3071 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3072 test_truth(rc == MEMCACHED_SUCCESS);
3073 }
3074 test_truth(memcached_is_allocated(string) == true);
3075 memcached_string_free(string);
3076
3077 return TEST_SUCCESS;
3078 }
3079
3080 static test_return_t string_alloc_append_toobig(memcached_st *memc)
3081 {
3082 memcached_return_t rc;
3083 unsigned int x;
3084 char buffer[SMALL_STRING_LEN];
3085 memcached_string_st *string;
3086
3087 /* Ring the bell! */
3088 memset(buffer, 6, SMALL_STRING_LEN);
3089
3090 string= memcached_string_create(memc, NULL, 100);
3091 test_truth(string);
3092 test_truth(memcached_is_allocated(string) == true);
3093 test_truth(memcached_is_initialized(string) == true);
3094
3095 for (x= 0; x < 1024; x++)
3096 {
3097 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3098 test_truth(rc == MEMCACHED_SUCCESS);
3099 }
3100 rc= memcached_string_append(string, buffer, SIZE_MAX);
3101 test_truth(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
3102 test_truth(memcached_is_allocated(string) == true);
3103 memcached_string_free(string);
3104
3105 return TEST_SUCCESS;
3106 }
3107
3108 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
3109 {
3110 pairs_free(global_pairs);
3111
3112 return TEST_SUCCESS;
3113 }
3114
3115 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
3116 {
3117 unsigned long long x;
3118 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3119 global_count= GLOBAL_COUNT;
3120
3121 for (x= 0; x < global_count; x++)
3122 {
3123 global_keys[x]= global_pairs[x].key;
3124 global_keys_length[x]= global_pairs[x].key_length;
3125 }
3126
3127 return TEST_SUCCESS;
3128 }
3129
3130 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
3131 {
3132 unsigned long long x;
3133 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3134 global_count= GLOBAL2_COUNT;
3135
3136 for (x= 0; x < global_count; x++)
3137 {
3138 global_keys[x]= global_pairs[x].key;
3139 global_keys_length[x]= global_pairs[x].key_length;
3140 }
3141
3142 return TEST_SUCCESS;
3143 }
3144
3145 static test_return_t generate_data(memcached_st *memc)
3146 {
3147 execute_set(memc, global_pairs, global_count);
3148
3149 return TEST_SUCCESS;
3150 }
3151
3152 static test_return_t generate_data_with_stats(memcached_st *memc)
3153 {
3154 memcached_stat_st *stat_p;
3155 memcached_return_t rc;
3156 uint32_t host_index= 0;
3157 execute_set(memc, global_pairs, global_count);
3158
3159 //TODO: hosts used size stats
3160 stat_p= memcached_stat(memc, NULL, &rc);
3161 test_truth(stat_p);
3162
3163 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3164 {
3165 /* This test was changes so that "make test" would work properlly */
3166 #ifdef DEBUG
3167 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);
3168 #endif
3169 test_truth((unsigned long long)(stat_p + host_index)->bytes);
3170 }
3171
3172 memcached_stat_free(NULL, stat_p);
3173
3174 return TEST_SUCCESS;
3175 }
3176 static test_return_t generate_buffer_data(memcached_st *memc)
3177 {
3178 size_t latch= 0;
3179
3180 latch= 1;
3181 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3182 generate_data(memc);
3183
3184 return TEST_SUCCESS;
3185 }
3186
3187 static test_return_t get_read_count(memcached_st *memc)
3188 {
3189 unsigned int x;
3190 memcached_return_t rc;
3191 memcached_st *memc_clone;
3192
3193 memc_clone= memcached_clone(NULL, memc);
3194 test_truth(memc_clone);
3195
3196 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3197
3198 {
3199 char *return_value;
3200 size_t return_value_length;
3201 uint32_t flags;
3202 uint32_t count;
3203
3204 for (x= count= 0; x < global_count; x++)
3205 {
3206 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3207 &return_value_length, &flags, &rc);
3208 if (rc == MEMCACHED_SUCCESS)
3209 {
3210 count++;
3211 if (return_value)
3212 free(return_value);
3213 }
3214 }
3215 }
3216
3217 memcached_free(memc_clone);
3218
3219 return TEST_SUCCESS;
3220 }
3221
3222 static test_return_t get_read(memcached_st *memc)
3223 {
3224 unsigned int x;
3225 memcached_return_t rc;
3226
3227 {
3228 char *return_value;
3229 size_t return_value_length;
3230 uint32_t flags;
3231
3232 for (x= 0; x < global_count; x++)
3233 {
3234 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3235 &return_value_length, &flags, &rc);
3236 /*
3237 test_truth(return_value);
3238 test_truth(rc == MEMCACHED_SUCCESS);
3239 */
3240 if (rc == MEMCACHED_SUCCESS && return_value)
3241 free(return_value);
3242 }
3243 }
3244
3245 return TEST_SUCCESS;
3246 }
3247
3248 static test_return_t mget_read(memcached_st *memc)
3249 {
3250 memcached_return_t rc;
3251
3252 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3253 test_truth(rc == MEMCACHED_SUCCESS);
3254 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
3255
3256 return TEST_SUCCESS;
3257 }
3258
3259 static test_return_t mget_read_result(memcached_st *memc)
3260 {
3261 memcached_return_t rc;
3262
3263 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3264 test_truth(rc == MEMCACHED_SUCCESS);
3265 /* Turn this into a help function */
3266 {
3267 memcached_result_st results_obj;
3268 memcached_result_st *results;
3269
3270 results= memcached_result_create(memc, &results_obj);
3271
3272 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3273 {
3274 test_truth(results);
3275 test_truth(rc == MEMCACHED_SUCCESS);
3276 }
3277
3278 memcached_result_free(&results_obj);
3279 }
3280
3281 return TEST_SUCCESS;
3282 }
3283
3284 static test_return_t mget_read_function(memcached_st *memc)
3285 {
3286 memcached_return_t rc;
3287 unsigned int counter;
3288 memcached_execute_fn callbacks[1];
3289
3290 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3291 test_truth(rc == MEMCACHED_SUCCESS);
3292
3293 callbacks[0]= &callback_counter;
3294 counter= 0;
3295 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3296
3297 return TEST_SUCCESS;
3298 }
3299
3300 static test_return_t delete_generate(memcached_st *memc)
3301 {
3302 unsigned int x;
3303
3304 for (x= 0; x < global_count; x++)
3305 {
3306 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3307 }
3308
3309 return TEST_SUCCESS;
3310 }
3311
3312 static test_return_t delete_buffer_generate(memcached_st *memc)
3313 {
3314 size_t latch= 0;
3315 unsigned int x;
3316
3317 latch= 1;
3318 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3319
3320 for (x= 0; x < global_count; x++)
3321 {
3322 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3323 }
3324
3325 return TEST_SUCCESS;
3326 }
3327
3328 static test_return_t add_host_test1(memcached_st *memc)
3329 {
3330 unsigned int x;
3331 memcached_return_t rc;
3332 char servername[]= "0.example.com";
3333 memcached_server_st *servers;
3334
3335 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3336 test_truth(servers);
3337 test_truth(1 == memcached_server_list_count(servers));
3338
3339 for (x= 2; x < 20; x++)
3340 {
3341 char buffer[SMALL_STRING_LEN];
3342
3343 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
3344 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3345 &rc);
3346 test_truth(rc == MEMCACHED_SUCCESS);
3347 test_truth(x == memcached_server_list_count(servers));
3348 }
3349
3350 rc= memcached_server_push(memc, servers);
3351 test_truth(rc == MEMCACHED_SUCCESS);
3352 rc= memcached_server_push(memc, servers);
3353 test_truth(rc == MEMCACHED_SUCCESS);
3354
3355 memcached_server_list_free(servers);
3356
3357 return TEST_SUCCESS;
3358 }
3359
3360 static test_return_t pre_nonblock(memcached_st *memc)
3361 {
3362 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3363
3364 return TEST_SUCCESS;
3365 }
3366
3367 static test_return_t pre_nonblock_binary(memcached_st *memc)
3368 {
3369 memcached_return_t rc= MEMCACHED_FAILURE;
3370 memcached_st *memc_clone;
3371
3372 memc_clone= memcached_clone(NULL, memc);
3373 assert(memc_clone);
3374 // The memcached_version needs to be done on a clone, because the server
3375 // will not toggle protocol on an connection.
3376 memcached_version(memc_clone);
3377
3378 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3379 {
3380 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3381 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3382 test_truth(rc == MEMCACHED_SUCCESS);
3383 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3384 }
3385 else
3386 {
3387 return TEST_SKIPPED;
3388 }
3389
3390 memcached_free(memc_clone);
3391
3392 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3393 }
3394
3395 static test_return_t pre_murmur(memcached_st *memc)
3396 {
3397 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3398
3399 return TEST_SUCCESS;
3400 }
3401
3402 static test_return_t pre_jenkins(memcached_st *memc)
3403 {
3404 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3405
3406 return TEST_SUCCESS;
3407 }
3408
3409
3410 static test_return_t pre_md5(memcached_st *memc)
3411 {
3412 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3413
3414 return TEST_SUCCESS;
3415 }
3416
3417 static test_return_t pre_crc(memcached_st *memc)
3418 {
3419 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3420
3421 return TEST_SUCCESS;
3422 }
3423
3424 static test_return_t pre_hsieh(memcached_st *memc)
3425 {
3426 #ifdef HAVE_HSIEH_HASH
3427 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3428 return TEST_SUCCESS;
3429 #else
3430 (void) memc;
3431 return TEST_SKIPPED;
3432 #endif
3433 }
3434
3435 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3436 {
3437 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3438
3439 return TEST_SUCCESS;
3440 }
3441
3442 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3443 {
3444 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3445
3446 return TEST_SUCCESS;
3447 }
3448
3449 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3450 {
3451 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3452
3453 return TEST_SUCCESS;
3454 }
3455
3456 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3457 {
3458 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3459
3460 return TEST_SUCCESS;
3461 }
3462
3463 static test_return_t pre_behavior_ketama(memcached_st *memc)
3464 {
3465 memcached_return_t rc;
3466 uint64_t value;
3467
3468 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3469 test_truth(rc == MEMCACHED_SUCCESS);
3470
3471 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3472 test_truth(value == 1);
3473
3474 return TEST_SUCCESS;
3475 }
3476
3477 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3478 {
3479 memcached_return_t rc;
3480 uint64_t value;
3481
3482 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3483 test_truth(rc == MEMCACHED_SUCCESS);
3484
3485 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3486 test_truth(value == 1);
3487
3488 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3489 test_truth(rc == MEMCACHED_SUCCESS);
3490
3491 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3492 test_truth(value == MEMCACHED_HASH_MD5);
3493
3494 return TEST_SUCCESS;
3495 }
3496
3497 /**
3498 @note This should be testing to see if the server really supports the binary protocol.
3499 */
3500 static test_return_t pre_binary(memcached_st *memc)
3501 {
3502 memcached_return_t rc= MEMCACHED_FAILURE;
3503 memcached_st *memc_clone;
3504
3505 memc_clone= memcached_clone(NULL, memc);
3506 test_truth(memc_clone);
3507 // The memcached_version needs to be done on a clone, because the server
3508 // will not toggle protocol on an connection.
3509 memcached_version(memc_clone);
3510
3511 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3512 {
3513 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3514 test_truth(rc == MEMCACHED_SUCCESS);
3515 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3516 }
3517
3518 memcached_free(memc_clone);
3519
3520 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3521 }
3522
3523 static test_return_t pre_replication(memcached_st *memc)
3524 {
3525 test_return_t test_rc;
3526 test_rc= pre_binary(memc);
3527
3528 if (test_rc != TEST_SUCCESS)
3529 return test_rc;
3530
3531 /*
3532 * Make sure that we store the item on all servers
3533 * (master + replicas == number of servers)
3534 */
3535 memcached_return_t rc;
3536 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3537 memc->number_of_hosts - 1);
3538 test_truth(rc == MEMCACHED_SUCCESS);
3539 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memc->number_of_hosts - 1);
3540
3541 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3542 }
3543
3544 static test_return_t pre_replication_noblock(memcached_st *memc)
3545 {
3546 test_return_t rc= MEMCACHED_FAILURE;
3547 if (pre_replication(memc) == TEST_SUCCESS &&
3548 pre_nonblock(memc) == TEST_SUCCESS)
3549 rc= TEST_SUCCESS;
3550
3551 return rc;
3552 }
3553
3554 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3555 {
3556 #ifdef HARD_MALLOC_TESTS
3557 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3558 free(real_ptr);
3559 #else
3560 free(mem);
3561 #endif
3562 }
3563
3564 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3565 {
3566 #ifdef HARD_MALLOC_TESTS
3567 void *ret= malloc(size + 8);
3568 if (ret != NULL)
3569 {
3570 ret= (void*)((caddr_t)ret + 8);
3571 }
3572 #else
3573 void *ret= malloc(size);
3574 #endif
3575
3576 if (ret != NULL)
3577 {
3578 memset(ret, 0xff, size);
3579 }
3580
3581 return ret;
3582 }
3583
3584 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3585 {
3586 #ifdef HARD_MALLOC_TESTS
3587 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3588 void *nmem= realloc(real_ptr, size + 8);
3589
3590 void *ret= NULL;
3591 if (nmem != NULL)
3592 {
3593 ret= (void*)((caddr_t)nmem + 8);
3594 }
3595
3596 return ret;
3597 #else
3598 return realloc(mem, size);
3599 #endif
3600 }
3601
3602 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3603 {
3604 #ifdef HARD_MALLOC_TESTS
3605 void *mem= my_malloc(ptr, nelem * size);
3606 if (mem)
3607 {
3608 memset(mem, 0, nelem * size);
3609 }
3610
3611 return mem;
3612 #else
3613 return calloc(nelem, size);
3614 #endif
3615 }
3616
3617 static test_return_t set_prefix(memcached_st *memc)
3618 {
3619 memcached_return_t rc;
3620 const char *key= "mine";
3621 char *value;
3622
3623 /* Make sure be default none exists */
3624 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3625 test_truth(rc == MEMCACHED_FAILURE);
3626
3627 /* Test a clean set */
3628 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3629 test_truth(rc == MEMCACHED_SUCCESS);
3630
3631 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3632 test_truth(memcmp(value, key, 4) == 0);
3633 test_truth(rc == MEMCACHED_SUCCESS);
3634
3635 /* Test that we can turn it off */
3636 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3637 test_truth(rc == MEMCACHED_SUCCESS);
3638
3639 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3640 test_truth(rc == MEMCACHED_FAILURE);
3641
3642 /* Now setup for main test */
3643 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3644 test_truth(rc == MEMCACHED_SUCCESS);
3645
3646 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3647 test_truth(rc == MEMCACHED_SUCCESS);
3648 test_truth(memcmp(value, key, 4) == 0);
3649
3650 /* Set to Zero, and then Set to something too large */
3651 {
3652 char long_key[255];
3653 memset(long_key, 0, 255);
3654
3655 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3656 test_truth(rc == MEMCACHED_SUCCESS);
3657
3658 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3659 test_truth(rc == MEMCACHED_FAILURE);
3660 test_truth(value == NULL);
3661
3662 /* Test a long key for failure */
3663 /* TODO, extend test to determine based on setting, what result should be */
3664 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3665 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3666 //test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3667 test_truth(rc == MEMCACHED_SUCCESS);
3668
3669 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3670 strcpy(long_key, "This is more then the allotted number of characters");
3671 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3672 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3673
3674 /* Test for a bad prefix, but with a short key */
3675 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3676 test_truth(rc == MEMCACHED_SUCCESS);
3677
3678 strcpy(long_key, "dog cat");
3679 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3680 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3681 }
3682
3683 return TEST_SUCCESS;
3684 }
3685
3686 #ifdef MEMCACHED_ENABLE_DEPRECATED
3687 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3688 {
3689 void *test_ptr= NULL;
3690 void *cb_ptr= NULL;
3691 {
3692 memcached_malloc_fn malloc_cb=
3693 (memcached_malloc_fn)my_malloc;
3694 cb_ptr= *(void **)&malloc_cb;
3695 memcached_return_t rc;
3696
3697 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3698 test_truth(rc == MEMCACHED_SUCCESS);
3699 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3700 test_truth(rc == MEMCACHED_SUCCESS);
3701 test_truth(test_ptr == cb_ptr);
3702 }
3703
3704 {
3705 memcached_realloc_fn realloc_cb=
3706 (memcached_realloc_fn)my_realloc;
3707 cb_ptr= *(void **)&realloc_cb;
3708 memcached_return_t rc;
3709
3710 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3711 test_truth(rc == MEMCACHED_SUCCESS);
3712 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3713 test_truth(rc == MEMCACHED_SUCCESS);
3714 test_truth(test_ptr == cb_ptr);
3715 }
3716
3717 {
3718 memcached_free_fn free_cb=
3719 (memcached_free_fn)my_free;
3720 cb_ptr= *(void **)&free_cb;
3721 memcached_return_t rc;
3722
3723 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3724 test_truth(rc == MEMCACHED_SUCCESS);
3725 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3726 test_truth(rc == MEMCACHED_SUCCESS);
3727 test_truth(test_ptr == cb_ptr);
3728 }
3729
3730 return TEST_SUCCESS;
3731 }
3732 #endif
3733
3734 static test_return_t set_memory_alloc(memcached_st *memc)
3735 {
3736 memcached_return_t rc;
3737 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3738 my_realloc, my_calloc);
3739 test_truth(rc == MEMCACHED_FAILURE);
3740
3741 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3742 my_realloc, my_calloc);
3743
3744 memcached_malloc_fn mem_malloc;
3745 memcached_free_fn mem_free;
3746 memcached_realloc_fn mem_realloc;
3747 memcached_calloc_fn mem_calloc;
3748 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3749 &mem_realloc, &mem_calloc);
3750
3751 test_truth(mem_malloc == my_malloc);
3752 test_truth(mem_realloc == my_realloc);
3753 test_truth(mem_calloc == my_calloc);
3754 test_truth(mem_free == my_free);
3755
3756 return TEST_SUCCESS;
3757 }
3758
3759 static test_return_t enable_consistent_crc(memcached_st *memc)
3760 {
3761 test_return_t rc;
3762 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3763 memcached_hash_t hash;
3764 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3765 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3766 return rc;
3767
3768 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3769 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3770
3771 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3772
3773 if (hash != MEMCACHED_HASH_CRC)
3774 return TEST_SKIPPED;
3775
3776 return TEST_SUCCESS;
3777 }
3778
3779 static test_return_t enable_consistent_hsieh(memcached_st *memc)
3780 {
3781 test_return_t rc;
3782 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3783 memcached_hash_t hash;
3784 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3785 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3786 return rc;
3787
3788 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3789 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3790
3791 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3792
3793 if (hash != MEMCACHED_HASH_HSIEH)
3794 return TEST_SKIPPED;
3795
3796
3797 return TEST_SUCCESS;
3798 }
3799
3800 static test_return_t enable_cas(memcached_st *memc)
3801 {
3802 unsigned int set= 1;
3803
3804 memcached_version(memc);
3805
3806 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3807 || memc->hosts[0].minor_version > 2)
3808 {
3809 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3810
3811 return TEST_SUCCESS;
3812 }
3813
3814 return TEST_SKIPPED;
3815 }
3816
3817 static test_return_t check_for_1_2_3(memcached_st *memc)
3818 {
3819 memcached_version(memc);
3820
3821 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3822 || memc->hosts[0].minor_version > 2)
3823 return TEST_SUCCESS;
3824
3825 return TEST_SKIPPED;
3826 }
3827
3828 static test_return_t pre_unix_socket(memcached_st *memc)
3829 {
3830 memcached_return_t rc;
3831 struct stat buf;
3832
3833 memcached_server_list_free(memc->hosts);
3834 memc->hosts= NULL;
3835 memc->number_of_hosts= 0;
3836
3837 if (stat("/tmp/memcached.socket", &buf))
3838 return TEST_SKIPPED;
3839
3840 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3841
3842 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
3843 }
3844
3845 static test_return_t pre_nodelay(memcached_st *memc)
3846 {
3847 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3848 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3849
3850 return TEST_SUCCESS;
3851 }
3852
3853 static test_return_t pre_settimer(memcached_st *memc)
3854 {
3855 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3856 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3857
3858 return TEST_SUCCESS;
3859 }
3860
3861 static test_return_t poll_timeout(memcached_st *memc)
3862 {
3863 size_t timeout;
3864
3865 timeout= 100;
3866
3867 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3868
3869 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3870
3871 test_truth(timeout == 100);
3872
3873 return TEST_SUCCESS;
3874 }
3875
3876 static test_return_t noreply_test(memcached_st *memc)
3877 {
3878 memcached_return_t ret;
3879 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3880 test_truth(ret == MEMCACHED_SUCCESS);
3881 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3882 test_truth(ret == MEMCACHED_SUCCESS);
3883 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3884 test_truth(ret == MEMCACHED_SUCCESS);
3885 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3886 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3887 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3888
3889 for (int count=0; count < 5; ++count)
3890 {
3891 for (int x=0; x < 100; ++x)
3892 {
3893 char key[10];
3894 size_t len= (size_t)sprintf(key, "%d", x);
3895 switch (count)
3896 {
3897 case 0:
3898 ret= memcached_add(memc, key, len, key, len, 0, 0);
3899 break;
3900 case 1:
3901 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3902 break;
3903 case 2:
3904 ret= memcached_set(memc, key, len, key, len, 0, 0);
3905 break;
3906 case 3:
3907 ret= memcached_append(memc, key, len, key, len, 0, 0);
3908 break;
3909 case 4:
3910 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3911 break;
3912 default:
3913 test_truth(count);
3914 break;
3915 }
3916 test_truth(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3917 }
3918
3919 /*
3920 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3921 ** API and is _ONLY_ done this way to verify that the library works the
3922 ** way it is supposed to do!!!!
3923 */
3924 int no_msg=0;
3925 for (uint32_t x=0; x < memc->number_of_hosts; ++x)
3926 no_msg+=(int)(memc->hosts[x].cursor_active);
3927
3928 test_truth(no_msg == 0);
3929 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3930
3931 /*
3932 ** Now validate that all items was set properly!
3933 */
3934 for (int x=0; x < 100; ++x)
3935 {
3936 char key[10];
3937 size_t len= (size_t)sprintf(key, "%d", x);
3938 size_t length;
3939 uint32_t flags;
3940 char* value=memcached_get(memc, key, strlen(key),
3941 &length, &flags, &ret);
3942 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
3943 switch (count)
3944 {
3945 case 0: /* FALLTHROUGH */
3946 case 1: /* FALLTHROUGH */
3947 case 2:
3948 test_truth(strncmp(value, key, len) == 0);
3949 test_truth(len == length);
3950 break;
3951 case 3:
3952 test_truth(length == len * 2);
3953 break;
3954 case 4:
3955 test_truth(length == len * 3);
3956 break;
3957 default:
3958 test_truth(count);
3959 break;
3960 }
3961 free(value);
3962 }
3963 }
3964
3965 /* Try setting an illegal cas value (should not return an error to
3966 * the caller (because we don't expect a return message from the server)
3967 */
3968 const char* keys[]= {"0"};
3969 size_t lengths[]= {1};
3970 size_t length;
3971 uint32_t flags;
3972 memcached_result_st results_obj;
3973 memcached_result_st *results;
3974 ret= memcached_mget(memc, keys, lengths, 1);
3975 test_truth(ret == MEMCACHED_SUCCESS);
3976
3977 results= memcached_result_create(memc, &results_obj);
3978 test_truth(results);
3979 results= memcached_fetch_result(memc, &results_obj, &ret);
3980 test_truth(results);
3981 test_truth(ret == MEMCACHED_SUCCESS);
3982 uint64_t cas= memcached_result_cas(results);
3983 memcached_result_free(&results_obj);
3984
3985 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3986 test_truth(ret == MEMCACHED_SUCCESS);
3987
3988 /*
3989 * The item will have a new cas value, so try to set it again with the old
3990 * value. This should fail!
3991 */
3992 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3993 test_truth(ret == MEMCACHED_SUCCESS);
3994 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3995 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3996 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
3997 free(value);
3998
3999 return TEST_SUCCESS;
4000 }
4001
4002 static test_return_t analyzer_test(memcached_st *memc)
4003 {
4004 memcached_return_t rc;
4005 memcached_stat_st *memc_stat;
4006 memcached_analysis_st *report;
4007
4008 memc_stat= memcached_stat(memc, NULL, &rc);
4009 test_truth(rc == MEMCACHED_SUCCESS);
4010 test_truth(memc_stat);
4011
4012 report= memcached_analyze(memc, memc_stat, &rc);
4013 test_truth(rc == MEMCACHED_SUCCESS);
4014 test_truth(report);
4015
4016 free(report);
4017 memcached_stat_free(NULL, memc_stat);
4018
4019 return TEST_SUCCESS;
4020 }
4021
4022 /* Count the objects */
4023 static memcached_return_t callback_dump_counter(memcached_st *ptr __attribute__((unused)),
4024 const char *key __attribute__((unused)),
4025 size_t key_length __attribute__((unused)),
4026 void *context)
4027 {
4028 uint32_t *counter= (uint32_t *)context;
4029
4030 *counter= *counter + 1;
4031
4032 return MEMCACHED_SUCCESS;
4033 }
4034
4035 static test_return_t dump_test(memcached_st *memc)
4036 {
4037 memcached_return_t rc;
4038 uint32_t counter= 0;
4039 memcached_dump_fn callbacks[1];
4040 test_return_t main_rc;
4041
4042 callbacks[0]= &callback_dump_counter;
4043
4044 /* No support for Binary protocol yet */
4045 if (memc->flags.binary_protocol)
4046 return TEST_SUCCESS;
4047
4048 main_rc= set_test3(memc);
4049
4050 test_truth (main_rc == TEST_SUCCESS);
4051
4052 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4053 test_truth(rc == MEMCACHED_SUCCESS);
4054
4055 /* We may have more then 32 if our previous flush has not completed */
4056 test_truth(counter >= 32);
4057
4058 return TEST_SUCCESS;
4059 }
4060
4061 #ifdef HAVE_LIBMEMCACHEDUTIL
4062 static void* connection_release(void *arg)
4063 {
4064 struct {
4065 memcached_pool_st* pool;
4066 memcached_st* mmc;
4067 } *resource= arg;
4068
4069 usleep(250);
4070 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4071 return arg;
4072 }
4073
4074 static test_return_t connection_pool_test(memcached_st *memc)
4075 {
4076 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
4077 test_truth(pool != NULL);
4078 memcached_st* mmc[10];
4079 memcached_return_t rc;
4080
4081 for (int x= 0; x < 10; ++x) {
4082 mmc[x]= memcached_pool_pop(pool, false, &rc);
4083 test_truth(mmc[x] != NULL);
4084 test_truth(rc == MEMCACHED_SUCCESS);
4085 }
4086
4087 test_truth(memcached_pool_pop(pool, false, &rc) == NULL);
4088 test_truth(rc == MEMCACHED_SUCCESS);
4089
4090 pthread_t tid;
4091 struct {
4092 memcached_pool_st* pool;
4093 memcached_st* mmc;
4094 } item= { .pool = pool, .mmc = mmc[9] };
4095 pthread_create(&tid, NULL, connection_release, &item);
4096 mmc[9]= memcached_pool_pop(pool, true, &rc);
4097 test_truth(rc == MEMCACHED_SUCCESS);
4098 pthread_join(tid, NULL);
4099 test_truth(mmc[9] == item.mmc);
4100 const char *key= "key";
4101 size_t keylen= strlen(key);
4102
4103 // verify that I can do ops with all connections
4104 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4105 test_truth(rc == MEMCACHED_SUCCESS);
4106
4107 for (unsigned int x= 0; x < 10; ++x) {
4108 uint64_t number_value;
4109 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4110 test_truth(rc == MEMCACHED_SUCCESS);
4111 test_truth(number_value == (x+1));
4112 }
4113
4114 // Release them..
4115 for (int x= 0; x < 10; ++x)
4116 test_truth(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4117
4118
4119 /* verify that I can set behaviors on the pool when I don't have all
4120 * of the connections in the pool. It should however be enabled
4121 * when I push the item into the pool
4122 */
4123 mmc[0]= memcached_pool_pop(pool, false, &rc);
4124 test_truth(mmc[0] != NULL);
4125
4126 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4127 test_truth(rc == MEMCACHED_SUCCESS);
4128
4129 mmc[1]= memcached_pool_pop(pool, false, &rc);
4130 test_truth(mmc[1] != NULL);
4131
4132 test_truth(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4133 test_truth(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4134 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4135
4136 mmc[0]= memcached_pool_pop(pool, false, &rc);
4137 test_truth(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4138 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4139
4140
4141 test_truth(memcached_pool_destroy(pool) == memc);
4142 return TEST_SUCCESS;
4143 }
4144 #endif
4145
4146 static test_return_t replication_set_test(memcached_st *memc)
4147 {
4148 memcached_return_t rc;
4149 memcached_st *memc_clone= memcached_clone(NULL, memc);
4150 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4151
4152 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4153 test_truth(rc == MEMCACHED_SUCCESS);
4154
4155 /*
4156 ** We are using the quiet commands to store the replicas, so we need
4157 ** to ensure that all of them are processed before we can continue.
4158 ** In the test we go directly from storing the object to trying to
4159 ** receive the object from all of the different servers, so we
4160 ** could end up in a race condition (the memcached server hasn't yet
4161 ** processed the quiet command from the replication set when it process
4162 ** the request from the other client (created by the clone)). As a
4163 ** workaround for that we call memcached_quit to send the quit command
4164 ** to the server and wait for the response ;-) If you use the test code
4165 ** as an example for your own code, please note that you shouldn't need
4166 ** to do this ;-)
4167 */
4168 memcached_quit(memc);
4169
4170 /*
4171 ** "bubba" should now be stored on all of our servers. We don't have an
4172 ** easy to use API to address each individual server, so I'll just iterate
4173 ** through a bunch of "master keys" and I should most likely hit all of the
4174 ** servers...
4175 */
4176 for (int x= 'a'; x <= 'z'; ++x)
4177 {
4178 char key[2]= { [0]= (char)x };
4179 size_t len;
4180 uint32_t flags;
4181 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4182 &len, &flags, &rc);
4183 test_truth(rc == MEMCACHED_SUCCESS);
4184 test_truth(val != NULL);
4185 free(val);
4186 }
4187
4188 memcached_free(memc_clone);
4189
4190 return TEST_SUCCESS;
4191 }
4192
4193 static test_return_t replication_get_test(memcached_st *memc)
4194 {
4195 memcached_return_t rc;
4196
4197 /*
4198 * Don't do the following in your code. I am abusing the internal details
4199 * within the library, and this is not a supported interface.
4200 * This is to verify correct behavior in the library
4201 */
4202 for (uint32_t host= 0; host < memc->number_of_hosts; ++host)
4203 {
4204 memcached_st *memc_clone= memcached_clone(NULL, memc);
4205 memc_clone->hosts[host].port= 0;
4206
4207 for (int x= 'a'; x <= 'z'; ++x)
4208 {
4209 char key[2]= { [0]= (char)x };
4210 size_t len;
4211 uint32_t flags;
4212 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4213 &len, &flags, &rc);
4214 test_truth(rc == MEMCACHED_SUCCESS);
4215 test_truth(val != NULL);
4216 free(val);
4217 }
4218
4219 memcached_free(memc_clone);
4220 }
4221
4222 return TEST_SUCCESS;
4223 }
4224
4225 static test_return_t replication_mget_test(memcached_st *memc)
4226 {
4227 memcached_return_t rc;
4228 memcached_st *memc_clone= memcached_clone(NULL, memc);
4229 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4230
4231 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4232 size_t len[]= { 5, 4, 4, 4 };
4233
4234 for (int x=0; x< 4; ++x)
4235 {
4236 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4237 test_truth(rc == MEMCACHED_SUCCESS);
4238 }
4239
4240 /*
4241 ** We are using the quiet commands to store the replicas, so we need
4242 ** to ensure that all of them are processed before we can continue.
4243 ** In the test we go directly from storing the object to trying to
4244 ** receive the object from all of the different servers, so we
4245 ** could end up in a race condition (the memcached server hasn't yet
4246 ** processed the quiet command from the replication set when it process
4247 ** the request from the other client (created by the clone)). As a
4248 ** workaround for that we call memcached_quit to send the quit command
4249 ** to the server and wait for the response ;-) If you use the test code
4250 ** as an example for your own code, please note that you shouldn't need
4251 ** to do this ;-)
4252 */
4253 memcached_quit(memc);
4254
4255 /*
4256 * Don't do the following in your code. I am abusing the internal details
4257 * within the library, and this is not a supported interface.
4258 * This is to verify correct behavior in the library
4259 */
4260 memcached_result_st result_obj;
4261 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4262 {
4263 memcached_st *new_clone= memcached_clone(NULL, memc);
4264 new_clone->hosts[host].port= 0;
4265
4266 for (int x= 'a'; x <= 'z'; ++x)
4267 {
4268 const char key[2]= { [0]= (const char)x };
4269
4270 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4271 test_truth(rc == MEMCACHED_SUCCESS);
4272
4273 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4274 test_truth(results);
4275
4276 int hits= 0;
4277 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4278 {
4279 hits++;
4280 }
4281 test_truth(hits == 4);
4282 memcached_result_free(&result_obj);
4283 }
4284
4285 memcached_free(new_clone);
4286 }
4287
4288 memcached_free(memc_clone);
4289
4290 return TEST_SUCCESS;
4291 }
4292
4293 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4294 {
4295 memcached_result_st result_obj;
4296 memcached_return_t rc;
4297 memcached_st *memc_clone= memcached_clone(NULL, memc);
4298 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4299 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4300
4301 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4302 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4303
4304 for (int x=0; x< 7; ++x)
4305 {
4306 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4307 test_truth(rc == MEMCACHED_SUCCESS);
4308 }
4309
4310 memcached_quit(memc);
4311
4312 for (int x=0; x< 7; ++x) {
4313 const char key[2]= { [0]= (const char)x };
4314
4315 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4316 test_truth(rc == MEMCACHED_SUCCESS);
4317
4318 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4319 test_truth(results);
4320
4321 int hits= 0;
4322 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4323 {
4324 ++hits;
4325 }
4326 test_truth(hits == 7);
4327 memcached_result_free(&result_obj);
4328 }
4329 memcached_free(memc_clone);
4330 return TEST_SUCCESS;
4331 }
4332
4333 static test_return_t replication_delete_test(memcached_st *memc)
4334 {
4335 memcached_return_t rc;
4336 memcached_st *memc_clone= memcached_clone(NULL, memc);
4337 /* Delete the items from all of the servers except 1 */
4338 uint64_t repl= memcached_behavior_get(memc,
4339 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4340 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4341
4342 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4343 size_t len[]= { 5, 4, 4, 4 };
4344
4345 for (int x=0; x< 4; ++x)
4346 {
4347 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4348 test_truth(rc == MEMCACHED_SUCCESS);
4349 }
4350
4351 /*
4352 * Don't do the following in your code. I am abusing the internal details
4353 * within the library, and this is not a supported interface.
4354 * This is to verify correct behavior in the library
4355 */
4356 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4357 for (uint32_t x= 0; x < (repl + 1); ++x)
4358 {
4359 memc_clone->hosts[hash].port= 0;
4360 if (++hash == memc_clone->number_of_hosts)
4361 hash= 0;
4362 }
4363
4364 memcached_result_st result_obj;
4365 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4366 {
4367 for (int x= 'a'; x <= 'z'; ++x)
4368 {
4369 const char key[2]= { [0]= (const char)x };
4370
4371 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4372 test_truth(rc == MEMCACHED_SUCCESS);
4373
4374 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4375 test_truth(results);
4376
4377 int hits= 0;
4378 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4379 {
4380 ++hits;
4381 }
4382 test_truth(hits == 4);
4383 memcached_result_free(&result_obj);
4384 }
4385 }
4386 memcached_free(memc_clone);
4387
4388 return TEST_SUCCESS;
4389 }
4390
4391 static void increment_request_id(uint16_t *id)
4392 {
4393 (*id)++;
4394 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4395 *id= 0;
4396 }
4397
4398 static uint16_t *get_udp_request_ids(memcached_st *memc)
4399 {
4400 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
4401 assert(ids != NULL);
4402 unsigned int x;
4403
4404 for (x= 0; x < memc->number_of_hosts; x++)
4405 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
4406
4407 return ids;
4408 }
4409
4410 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4411 {
4412 unsigned int x;
4413 memcached_server_st *cur_server = memc->hosts;
4414 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4415
4416 for (x= 0; x < memc->number_of_hosts; x++)
4417 {
4418 test_truth(cur_server[x].cursor_active == 0);
4419 test_truth(cur_req_ids[x] == expected_req_ids[x]);
4420 }
4421 free(expected_req_ids);
4422 free(cur_req_ids);
4423
4424 return TEST_SUCCESS;
4425 }
4426
4427 /*
4428 ** There is a little bit of a hack here, instead of removing
4429 ** the servers, I just set num host to 0 and them add then new udp servers
4430 **/
4431 static test_return_t init_udp(memcached_st *memc)
4432 {
4433 memcached_version(memc);
4434 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4435 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
4436 || memc->hosts[0].micro_version < 6)
4437 return TEST_SKIPPED;
4438
4439 uint32_t num_hosts= memc->number_of_hosts;
4440 unsigned int x= 0;
4441 memcached_server_st servers[num_hosts];
4442 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
4443 for (x= 0; x < num_hosts; x++)
4444 memcached_server_free(&memc->hosts[x]);
4445
4446 memc->number_of_hosts= 0;
4447 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4448 for (x= 0; x < num_hosts; x++)
4449 {
4450 test_truth(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4451 test_truth(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4452 }
4453
4454 return TEST_SUCCESS;
4455 }
4456
4457 static test_return_t binary_init_udp(memcached_st *memc)
4458 {
4459 test_return_t test_rc;
4460 test_rc= pre_binary(memc);
4461
4462 if (test_rc != TEST_SUCCESS)
4463 return test_rc;
4464
4465 return init_udp(memc);
4466 }
4467
4468 /* Make sure that I cant add a tcp server to a udp client */
4469 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4470 {
4471 memcached_server_st server;
4472 memcached_server_clone(&server, &memc->hosts[0]);
4473 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4474 test_truth(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4475 return TEST_SUCCESS;
4476 }
4477
4478 /* Make sure that I cant add a udp server to a tcp client */
4479 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4480 {
4481 memcached_server_st server;
4482 memcached_server_clone(&server, &memc->hosts[0]);
4483 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4484
4485 memcached_st tcp_client;
4486 memcached_create(&tcp_client);
4487 test_truth(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4488
4489 return TEST_SUCCESS;
4490 }
4491
4492 static test_return_t set_udp_behavior_test(memcached_st *memc)
4493 {
4494
4495 memcached_quit(memc);
4496 memc->number_of_hosts= 0;
4497 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, memc->distribution);
4498 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4499 test_truth(memc->flags.use_udp);
4500 test_truth(memc->flags.no_reply);
4501
4502 test_truth(memc->number_of_hosts == 0);
4503
4504 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4505 test_truth(! (memc->flags.use_udp));
4506 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4507 test_truth(! (memc->flags.no_reply));
4508
4509 return TEST_SUCCESS;
4510 }
4511
4512 static test_return_t udp_set_test(memcached_st *memc)
4513 {
4514 unsigned int x= 0;
4515 unsigned int num_iters= 1025; //request id rolls over at 1024
4516 for (x= 0; x < num_iters;x++)
4517 {
4518 memcached_return_t rc;
4519 const char *key= "foo";
4520 const char *value= "when we sanitize";
4521 uint16_t *expected_ids= get_udp_request_ids(memc);
4522 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
4523 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4524 rc= memcached_set(memc, key, strlen(key),
4525 value, strlen(value),
4526 (time_t)0, (uint32_t)0);
4527 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4528 /** NB, the check below assumes that if new write_ptr is less than
4529 * the original write_ptr that we have flushed. For large payloads, this
4530 * maybe an invalid assumption, but for the small payload we have it is OK
4531 */
4532 if (rc == MEMCACHED_SUCCESS ||
4533 memc->hosts[server_key].write_buffer_offset < init_offset)
4534 increment_request_id(&expected_ids[server_key]);
4535
4536 if (rc == MEMCACHED_SUCCESS)
4537 {
4538 test_truth(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4539 }
4540 else
4541 {
4542 test_truth(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4543 test_truth(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4544 }
4545 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4546 }
4547 return TEST_SUCCESS;
4548 }
4549
4550 static test_return_t udp_buffered_set_test(memcached_st *memc)
4551 {
4552 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4553 return udp_set_test(memc);
4554 }
4555
4556 static test_return_t udp_set_too_big_test(memcached_st *memc)
4557 {
4558 memcached_return_t rc;
4559 const char *key= "bar";
4560 char value[MAX_UDP_DATAGRAM_LENGTH];
4561 uint16_t *expected_ids= get_udp_request_ids(memc);
4562 rc= memcached_set(memc, key, strlen(key),
4563 value, MAX_UDP_DATAGRAM_LENGTH,
4564 (time_t)0, (uint32_t)0);
4565 test_truth(rc == MEMCACHED_WRITE_FAILURE);
4566 return post_udp_op_check(memc,expected_ids);
4567 }
4568
4569 static test_return_t udp_delete_test(memcached_st *memc)
4570 {
4571 unsigned int x= 0;
4572 unsigned int num_iters= 1025; //request id rolls over at 1024
4573 for (x= 0; x < num_iters;x++)
4574 {
4575 memcached_return_t rc;
4576 const char *key= "foo";
4577 uint16_t *expected_ids=get_udp_request_ids(memc);
4578 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4579 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4580 rc= memcached_delete(memc, key, strlen(key), 0);
4581 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4582 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
4583 increment_request_id(&expected_ids[server_key]);
4584 if (rc == MEMCACHED_SUCCESS)
4585 {
4586 test_truth(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4587 }
4588 else
4589 {
4590 test_truth(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4591 test_truth(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4592 }
4593 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4594 }
4595 return TEST_SUCCESS;
4596 }
4597
4598 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4599 {
4600 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4601 return udp_delete_test(memc);
4602 }
4603
4604 static test_return_t udp_verbosity_test(memcached_st *memc)
4605 {
4606 memcached_return_t rc;
4607 uint16_t *expected_ids= get_udp_request_ids(memc);
4608 unsigned int x;
4609 for (x= 0; x < memc->number_of_hosts;x++)
4610 increment_request_id(&expected_ids[x]);
4611
4612 rc= memcached_verbosity(memc,3);
4613 test_truth(rc == MEMCACHED_SUCCESS);
4614 return post_udp_op_check(memc,expected_ids);
4615 }
4616
4617 static test_return_t udp_quit_test(memcached_st *memc)
4618 {
4619 uint16_t *expected_ids= get_udp_request_ids(memc);
4620 memcached_quit(memc);
4621 return post_udp_op_check(memc, expected_ids);
4622 }
4623
4624 static test_return_t udp_flush_test(memcached_st *memc)
4625 {
4626 memcached_return_t rc;
4627 uint16_t *expected_ids= get_udp_request_ids(memc);
4628 unsigned int x;
4629 for (x= 0; x < memc->number_of_hosts;x++)
4630 increment_request_id(&expected_ids[x]);
4631
4632 rc= memcached_flush(memc,0);
4633 test_truth(rc == MEMCACHED_SUCCESS);
4634 return post_udp_op_check(memc,expected_ids);
4635 }
4636
4637 static test_return_t udp_incr_test(memcached_st *memc)
4638 {
4639 memcached_return_t rc;
4640 const char *key= "incr";
4641 const char *value= "1";
4642 rc= memcached_set(memc, key, strlen(key),
4643 value, strlen(value),
4644 (time_t)0, (uint32_t)0);
4645
4646 test_truth(rc == MEMCACHED_SUCCESS);
4647 uint16_t *expected_ids= get_udp_request_ids(memc);
4648 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4649 increment_request_id(&expected_ids[server_key]);
4650 uint64_t newvalue;
4651 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4652 test_truth(rc == MEMCACHED_SUCCESS);
4653 return post_udp_op_check(memc, expected_ids);
4654 }
4655
4656 static test_return_t udp_decr_test(memcached_st *memc)
4657 {
4658 memcached_return_t rc;
4659 const char *key= "decr";
4660 const char *value= "1";
4661 rc= memcached_set(memc, key, strlen(key),
4662 value, strlen(value),
4663 (time_t)0, (uint32_t)0);
4664
4665 test_truth(rc == MEMCACHED_SUCCESS);
4666 uint16_t *expected_ids= get_udp_request_ids(memc);
4667 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4668 increment_request_id(&expected_ids[server_key]);
4669 uint64_t newvalue;
4670 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4671 test_truth(rc == MEMCACHED_SUCCESS);
4672 return post_udp_op_check(memc, expected_ids);
4673 }
4674
4675
4676 static test_return_t udp_stat_test(memcached_st *memc)
4677 {
4678 memcached_stat_st * rv= NULL;
4679 memcached_return_t rc;
4680 char args[]= "";
4681 uint16_t *expected_ids = get_udp_request_ids(memc);
4682 rv = memcached_stat(memc, args, &rc);
4683 free(rv);
4684 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4685 return post_udp_op_check(memc, expected_ids);
4686 }
4687
4688 static test_return_t udp_version_test(memcached_st *memc)
4689 {
4690 memcached_return_t rc;
4691 uint16_t *expected_ids = get_udp_request_ids(memc);
4692 rc = memcached_version(memc);
4693 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4694 return post_udp_op_check(memc, expected_ids);
4695 }
4696
4697 static test_return_t udp_get_test(memcached_st *memc)
4698 {
4699 memcached_return_t rc;
4700 const char *key= "foo";
4701 size_t vlen;
4702 uint16_t *expected_ids = get_udp_request_ids(memc);
4703 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4704 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4705 test_truth(val == NULL);
4706 return post_udp_op_check(memc, expected_ids);
4707 }
4708
4709 static test_return_t udp_mixed_io_test(memcached_st *memc)
4710 {
4711 test_st current_op;
4712 test_st mixed_io_ops [] ={
4713 {"udp_set_test", 0,
4714 (test_callback_fn)udp_set_test},
4715 {"udp_set_too_big_test", 0,
4716 (test_callback_fn)udp_set_too_big_test},
4717 {"udp_delete_test", 0,
4718 (test_callback_fn)udp_delete_test},
4719 {"udp_verbosity_test", 0,
4720 (test_callback_fn)udp_verbosity_test},
4721 {"udp_quit_test", 0,
4722 (test_callback_fn)udp_quit_test},
4723 {"udp_flush_test", 0,
4724 (test_callback_fn)udp_flush_test},
4725 {"udp_incr_test", 0,
4726 (test_callback_fn)udp_incr_test},
4727 {"udp_decr_test", 0,
4728 (test_callback_fn)udp_decr_test},
4729 {"udp_version_test", 0,
4730 (test_callback_fn)udp_version_test}
4731 };
4732 unsigned int x= 0;
4733 for (x= 0; x < 500; x++)
4734 {
4735 current_op= mixed_io_ops[random() % 9];
4736 test_truth(current_op.test_fn(memc) == TEST_SUCCESS);
4737 }
4738 return TEST_SUCCESS;
4739 }
4740
4741 #if 0
4742 static test_return_t hash_sanity_test (memcached_st *memc)
4743 {
4744 (void)memc;
4745
4746 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4747 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4748 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4749 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4750 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4751 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4752 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4753 #ifdef HAVE_HSIEH_HASH
4754 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4755 #endif
4756 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4757 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4758 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4759
4760 return TEST_SUCCESS;
4761 }
4762 #endif
4763
4764 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4765 {
4766 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4767 #ifdef HAVE_HSIEH_HASH
4768 expected_rc= MEMCACHED_SUCCESS;
4769 #endif
4770 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4771 (uint64_t)MEMCACHED_HASH_HSIEH);
4772 test_truth(rc == expected_rc);
4773 return TEST_SUCCESS;
4774 }
4775
4776 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4777 {
4778 uint32_t x;
4779 const char **ptr;
4780
4781 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4782 {
4783 uint32_t hash_val;
4784
4785 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4786 test_truth(md5_values[x] == hash_val);
4787 }
4788
4789 return TEST_SUCCESS;
4790 }
4791
4792 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4793 {
4794 uint32_t x;
4795 const char **ptr;
4796
4797 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4798 {
4799 uint32_t hash_val;
4800
4801 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4802 test_truth(crc_values[x] == hash_val);
4803 }
4804
4805 return TEST_SUCCESS;
4806 }
4807
4808 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4809 {
4810 uint32_t x;
4811 const char **ptr;
4812
4813 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4814 {
4815 uint32_t hash_val;
4816
4817 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4818 test_truth(fnv1_64_values[x] == hash_val);
4819 }
4820
4821 return TEST_SUCCESS;
4822 }
4823
4824 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4825 {
4826 uint32_t x;
4827 const char **ptr;
4828
4829 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4830 {
4831 uint32_t hash_val;
4832
4833 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4834 test_truth(fnv1a_64_values[x] == hash_val);
4835 }
4836
4837 return TEST_SUCCESS;
4838 }
4839
4840 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4841 {
4842 uint32_t x;
4843 const char **ptr;
4844
4845
4846 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4847 {
4848 uint32_t hash_val;
4849
4850 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4851 test_truth(fnv1_32_values[x] == hash_val);
4852 }
4853
4854 return TEST_SUCCESS;
4855 }
4856
4857 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4858 {
4859 uint32_t x;
4860 const char **ptr;
4861
4862 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4863 {
4864 uint32_t hash_val;
4865
4866 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4867 test_truth(fnv1a_32_values[x] == hash_val);
4868 }
4869
4870 return TEST_SUCCESS;
4871 }
4872
4873 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4874 {
4875 uint32_t x;
4876 const char **ptr;
4877
4878 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4879 {
4880 uint32_t hash_val;
4881
4882 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4883 test_truth(hsieh_values[x] == hash_val);
4884 }
4885
4886 return TEST_SUCCESS;
4887 }
4888
4889 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4890 {
4891 #ifdef __sparc
4892 return TEST_SKIPPED;
4893 #else
4894 uint32_t x;
4895 const char **ptr;
4896
4897 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4898 {
4899 uint32_t hash_val;
4900
4901 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4902 test_truth(murmur_values[x] == hash_val);
4903 }
4904
4905 return TEST_SUCCESS;
4906 #endif
4907 }
4908
4909 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4910 {
4911 uint32_t x;
4912 const char **ptr;
4913
4914
4915 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4916 {
4917 uint32_t hash_val;
4918
4919 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4920 test_truth(jenkins_values[x] == hash_val);
4921 }
4922
4923 return TEST_SUCCESS;
4924 }
4925
4926
4927 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4928 {
4929 memcached_return_t rc;
4930 uint64_t value;
4931 int x;
4932 memcached_server_st *server_pool;
4933 memcached_st *memc;
4934
4935 (void)trash;
4936
4937 memc= memcached_create(NULL);
4938 test_truth(memc);
4939
4940 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4941 test_truth(rc == MEMCACHED_SUCCESS);
4942
4943 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4944 test_truth(value == 1);
4945
4946 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
4947 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
4948
4949
4950 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");
4951 memcached_server_push(memc, server_pool);
4952
4953 /* verify that the server list was parsed okay. */
4954 assert(memc->number_of_hosts == 8);
4955 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
4956 assert(server_pool[0].port == 11211);
4957 assert(server_pool[0].weight == 600);
4958 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
4959 assert(server_pool[2].port == 11211);
4960 assert(server_pool[2].weight == 200);
4961 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
4962 assert(server_pool[7].port == 11211);
4963 assert(server_pool[7].weight == 100);
4964
4965 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4966 * us test the boundary wraparound.
4967 */
4968 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4969
4970 /* verify the standard ketama set. */
4971 for (x= 0; x < 99; x++)
4972 {
4973 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4974 char *hostname = memc->hosts[server_idx].hostname;
4975 assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
4976 }
4977
4978 memcached_server_list_free(server_pool);
4979 memcached_free(memc);
4980
4981 return TEST_SUCCESS;
4982 }
4983
4984 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4985 {
4986 memcached_return_t rc;
4987 uint64_t value;
4988 int x;
4989 memcached_server_st *server_pool;
4990 memcached_st *memc;
4991
4992 (void)trash;
4993
4994 memc= memcached_create(NULL);
4995 test_truth(memc);
4996
4997 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4998 test_truth(rc == MEMCACHED_SUCCESS);
4999
5000 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5001 test_truth(value == 1);
5002
5003 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
5004 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
5005
5006 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");
5007 memcached_server_push(memc, server_pool);
5008
5009 /* verify that the server list was parsed okay. */
5010 assert(memc->number_of_hosts == 8);
5011 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
5012 assert(server_pool[0].port == 11211);
5013 assert(server_pool[0].weight == 600);
5014 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
5015 assert(server_pool[2].port == 11211);
5016 assert(server_pool[2].weight == 200);
5017 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
5018 assert(server_pool[7].port == 11211);
5019 assert(server_pool[7].weight == 100);
5020
5021 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5022 * us test the boundary wraparound.
5023 */
5024 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5025
5026 /* verify the standard ketama set. */
5027 for (x= 0; x < 99; x++)
5028 {
5029 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5030 char *hostname = memc->hosts[server_idx].hostname;
5031 assert(strcmp(hostname, ketama_test_cases_spy[x].server) == 0);
5032 }
5033
5034 memcached_server_list_free(server_pool);
5035 memcached_free(memc);
5036
5037 return TEST_SUCCESS;
5038 }
5039
5040 static test_return_t regression_bug_434484(memcached_st *memc)
5041 {
5042 test_return_t test_rc;
5043 test_rc= pre_binary(memc);
5044
5045 if (test_rc != TEST_SUCCESS)
5046 return test_rc;
5047
5048 memcached_return_t ret;
5049 const char *key= "regression_bug_434484";
5050 size_t keylen= strlen(key);
5051
5052 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5053 assert(ret == MEMCACHED_NOTSTORED);
5054
5055 size_t size= 2048 * 1024;
5056 void *data= calloc(1, size);
5057 assert(data != NULL);
5058 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5059 assert(ret == MEMCACHED_E2BIG);
5060 free(data);
5061
5062 return TEST_SUCCESS;
5063 }
5064
5065 static test_return_t regression_bug_434843(memcached_st *memc)
5066 {
5067 test_return_t test_rc;
5068 test_rc= pre_binary(memc);
5069
5070 if (test_rc != TEST_SUCCESS)
5071 return test_rc;
5072
5073 memcached_return_t rc;
5074 unsigned int counter= 0;
5075 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5076
5077 /*
5078 * I only want to hit only _one_ server so I know the number of requests I'm
5079 * sending in the pipleine to the server. Let's try to do a multiget of
5080 * 1024 (that should satisfy most users don't you think?). Future versions
5081 * will include a mget_execute function call if you need a higher number.
5082 */
5083 uint32_t number_of_hosts= memc->number_of_hosts;
5084 memc->number_of_hosts= 1;
5085 const size_t max_keys= 1024;
5086 char **keys= calloc(max_keys, sizeof(char*));
5087 size_t *key_length=calloc(max_keys, sizeof(size_t));
5088
5089 for (int x= 0; x < (int)max_keys; ++x)
5090 {
5091 char k[251];
5092 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5093 keys[x]= strdup(k);
5094 assert(keys[x] != NULL);
5095 }
5096
5097 /*
5098 * Run two times.. the first time we should have 100% cache miss,
5099 * and the second time we should have 100% cache hits
5100 */
5101 for (int y= 0; y < 2; ++y)
5102 {
5103 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5104 assert(rc == MEMCACHED_SUCCESS);
5105 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5106 if (y == 0)
5107 {
5108 /* The first iteration should give me a 100% cache miss. verify that*/
5109 assert(counter == 0);
5110 char blob[1024]= { 0 };
5111 for (int x= 0; x < (int)max_keys; ++x)
5112 {
5113 rc= memcached_add(memc, keys[x], key_length[x],
5114 blob, sizeof(blob), 0, 0);
5115 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5116 }
5117 }
5118 else
5119 {
5120 /* Verify that we received all of the key/value pairs */
5121 assert(counter == (unsigned int)max_keys);
5122 }
5123 }
5124
5125 /* Release allocated resources */
5126 for (size_t x= 0; x < max_keys; ++x)
5127 free(keys[x]);
5128 free(keys);
5129 free(key_length);
5130
5131 memc->number_of_hosts= number_of_hosts;
5132 return TEST_SUCCESS;
5133 }
5134
5135 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5136 {
5137 memcached_return_t rc;
5138 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5139 assert(rc == MEMCACHED_SUCCESS);
5140
5141 return regression_bug_434843(memc);
5142 }
5143
5144 static test_return_t regression_bug_421108(memcached_st *memc)
5145 {
5146 memcached_return_t rc;
5147 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5148 assert(rc == MEMCACHED_SUCCESS);
5149
5150 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5151 assert(rc == MEMCACHED_SUCCESS);
5152 assert(bytes != NULL);
5153 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5154 "bytes_read", &rc);
5155 assert(rc == MEMCACHED_SUCCESS);
5156 assert(bytes_read != NULL);
5157
5158 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5159 "bytes_written", &rc);
5160 assert(rc == MEMCACHED_SUCCESS);
5161 assert(bytes_written != NULL);
5162
5163 assert(strcmp(bytes, bytes_read) != 0);
5164 assert(strcmp(bytes, bytes_written) != 0);
5165
5166 /* Release allocated resources */
5167 free(bytes);
5168 free(bytes_read);
5169 free(bytes_written);
5170 memcached_stat_free(NULL, memc_stat);
5171 return TEST_SUCCESS;
5172 }
5173
5174 /*
5175 * The test case isn't obvious so I should probably document why
5176 * it works the way it does. Bug 442914 was caused by a bug
5177 * in the logic in memcached_purge (it did not handle the case
5178 * where the number of bytes sent was equal to the watermark).
5179 * In this test case, create messages so that we hit that case
5180 * and then disable noreply mode and issue a new command to
5181 * verify that it isn't stuck. If we change the format for the
5182 * delete command or the watermarks, we need to update this
5183 * test....
5184 */
5185 static test_return_t regression_bug_442914(memcached_st *memc)
5186 {
5187 memcached_return_t rc;
5188 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5189 assert(rc == MEMCACHED_SUCCESS);
5190 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5191
5192 uint32_t number_of_hosts= memc->number_of_hosts;
5193 memc->number_of_hosts= 1;
5194
5195 char k[250];
5196 size_t len;
5197
5198 for (int x= 0; x < 250; ++x)
5199 {
5200 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5201 rc= memcached_delete(memc, k, len, 0);
5202 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5203 }
5204
5205 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
5206 rc= memcached_delete(memc, k, len, 0);
5207 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5208
5209 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5210 assert(rc == MEMCACHED_SUCCESS);
5211 rc= memcached_delete(memc, k, len, 0);
5212 assert(rc == MEMCACHED_NOTFOUND);
5213
5214 memc->number_of_hosts= number_of_hosts;
5215
5216 return TEST_SUCCESS;
5217 }
5218
5219 static test_return_t regression_bug_447342(memcached_st *memc)
5220 {
5221 if (memc->number_of_hosts < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5222 return TEST_SKIPPED;
5223
5224 memcached_return_t rc;
5225
5226 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5227 assert(rc == MEMCACHED_SUCCESS);
5228
5229 const size_t max_keys= 100;
5230 char **keys= calloc(max_keys, sizeof(char*));
5231 size_t *key_length=calloc(max_keys, sizeof(size_t));
5232
5233 for (int x= 0; x < (int)max_keys; ++x)
5234 {
5235 char k[251];
5236 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5237 keys[x]= strdup(k);
5238 assert(keys[x] != NULL);
5239 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5240 assert(rc == MEMCACHED_SUCCESS);
5241 }
5242
5243 /*
5244 ** We are using the quiet commands to store the replicas, so we need
5245 ** to ensure that all of them are processed before we can continue.
5246 ** In the test we go directly from storing the object to trying to
5247 ** receive the object from all of the different servers, so we
5248 ** could end up in a race condition (the memcached server hasn't yet
5249 ** processed the quiet command from the replication set when it process
5250 ** the request from the other client (created by the clone)). As a
5251 ** workaround for that we call memcached_quit to send the quit command
5252 ** to the server and wait for the response ;-) If you use the test code
5253 ** as an example for your own code, please note that you shouldn't need
5254 ** to do this ;-)
5255 */
5256 memcached_quit(memc);
5257
5258 /* Verify that all messages are stored, and we didn't stuff too much
5259 * into the servers
5260 */
5261 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5262 assert(rc == MEMCACHED_SUCCESS);
5263
5264 unsigned int counter= 0;
5265 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5266 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5267 /* Verify that we received all of the key/value pairs */
5268 assert(counter == (unsigned int)max_keys);
5269
5270 memcached_quit(memc);
5271 /*
5272 * Don't do the following in your code. I am abusing the internal details
5273 * within the library, and this is not a supported interface.
5274 * This is to verify correct behavior in the library. Fake that two servers
5275 * are dead..
5276 */
5277 in_port_t port0= memc->hosts[0].port;
5278 in_port_t port2= memc->hosts[2].port;
5279
5280 memc->hosts[0].port= 0;
5281 memc->hosts[2].port= 0;
5282
5283 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5284 assert(rc == MEMCACHED_SUCCESS);
5285
5286 counter= 0;
5287 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5288 assert(counter == (unsigned int)max_keys);
5289
5290 /* restore the memc handle */
5291 memc->hosts[0].port= port0;
5292 memc->hosts[2].port= port2;
5293
5294 memcached_quit(memc);
5295
5296 /* Remove half of the objects */
5297 for (int x= 0; x < (int)max_keys; ++x)
5298 {
5299 if (x & 1)
5300 {
5301 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5302 assert(rc == MEMCACHED_SUCCESS);
5303 }
5304 }
5305
5306 memcached_quit(memc);
5307 memc->hosts[0].port= 0;
5308 memc->hosts[2].port= 0;
5309
5310 /* now retry the command, this time we should have cache misses */
5311 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5312 assert(rc == MEMCACHED_SUCCESS);
5313
5314 counter= 0;
5315 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5316 assert(counter == (unsigned int)(max_keys >> 1));
5317
5318 /* Release allocated resources */
5319 for (size_t x= 0; x < max_keys; ++x)
5320 free(keys[x]);
5321 free(keys);
5322 free(key_length);
5323
5324 /* restore the memc handle */
5325 memc->hosts[0].port= port0;
5326 memc->hosts[2].port= port2;
5327
5328 return TEST_SUCCESS;
5329 }
5330
5331 static test_return_t regression_bug_463297(memcached_st *memc)
5332 {
5333 memcached_st *memc_clone= memcached_clone(NULL, memc);
5334 assert(memc_clone != NULL);
5335 assert(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5336
5337 if (memc_clone->hosts[0].major_version > 1 ||
5338 (memc_clone->hosts[0].major_version == 1 &&
5339 memc_clone->hosts[0].minor_version > 2))
5340 {
5341 /* Binary protocol doesn't support deferred delete */
5342 memcached_st *bin_clone= memcached_clone(NULL, memc);
5343 assert(bin_clone != NULL);
5344 assert(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5345 assert(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5346 memcached_free(bin_clone);
5347
5348 memcached_quit(memc_clone);
5349
5350 /* If we know the server version, deferred delete should fail
5351 * with invalid arguments */
5352 assert(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5353
5354 /* If we don't know the server version, we should get a protocol error */
5355 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5356 /* but there is a bug in some of the memcached servers (1.4) that treats
5357 * the counter as noreply so it doesn't send the proper error message
5358 */
5359 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5360
5361 /* And buffered mode should be disabled and we should get protocol error */
5362 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5363 rc= memcached_delete(memc, "foo", 3, 1);
5364 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5365
5366 /* Same goes for noreply... */
5367 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5368 rc= memcached_delete(memc, "foo", 3, 1);
5369 assert(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5370
5371 /* but a normal request should go through (and be buffered) */
5372 assert((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5373 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5374
5375 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5376 /* unbuffered noreply should be success */
5377 assert(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5378 /* unbuffered with reply should be not found... */
5379 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5380 assert(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5381 }
5382
5383 memcached_free(memc_clone);
5384 return TEST_SUCCESS;
5385 }
5386
5387
5388 /* Test memcached_server_get_last_disconnect
5389 * For a working server set, shall be NULL
5390 * For a set of non existing server, shall not be NULL
5391 */
5392 static test_return_t test_get_last_disconnect(memcached_st *memc)
5393 {
5394 memcached_return_t rc;
5395 memcached_server_st *disconnected_server;
5396
5397 /* With the working set of server */
5398 const char *key= "marmotte";
5399 const char *value= "milka";
5400
5401 rc= memcached_set(memc, key, strlen(key),
5402 value, strlen(value),
5403 (time_t)0, (uint32_t)0);
5404 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5405
5406 disconnected_server = memcached_server_get_last_disconnect(memc);
5407 assert(disconnected_server == NULL);
5408
5409 /* With a non existing server */
5410 memcached_st *mine;
5411 memcached_server_st *servers;
5412
5413 const char *server_list= "localhost:9";
5414
5415 servers= memcached_servers_parse(server_list);
5416 assert(servers);
5417 mine= memcached_create(NULL);
5418 rc= memcached_server_push(mine, servers);
5419 assert(rc == MEMCACHED_SUCCESS);
5420 memcached_server_list_free(servers);
5421 assert(mine);
5422
5423 rc= memcached_set(mine, key, strlen(key),
5424 value, strlen(value),
5425 (time_t)0, (uint32_t)0);
5426 assert(rc != MEMCACHED_SUCCESS);
5427
5428 disconnected_server = memcached_server_get_last_disconnect(mine);
5429 assert(disconnected_server != NULL);
5430 assert(disconnected_server->port == 9);
5431 assert(strncmp(disconnected_server->hostname,"localhost",9) == 0);
5432
5433 memcached_quit(mine);
5434 memcached_free(mine);
5435
5436 return TEST_SUCCESS;
5437 }
5438
5439 /*
5440 * This test ensures that the failure counter isn't incremented during
5441 * normal termination of the memcached instance.
5442 */
5443 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5444 {
5445 memcached_return_t rc;
5446
5447 /* Set value to force connection to the server */
5448 const char *key= "marmotte";
5449 const char *value= "milka";
5450
5451 /*
5452 * Please note that I'm abusing the internal structures in libmemcached
5453 * in a non-portable way and you shouldn't be doing this. I'm only
5454 * doing this in order to verify that the library works the way it should
5455 */
5456 uint32_t number_of_hosts= memc->number_of_hosts;
5457 memc->number_of_hosts= 1;
5458
5459 /* Ensure that we are connected to the server by setting a value */
5460 rc= memcached_set(memc, key, strlen(key),
5461 value, strlen(value),
5462 (time_t)0, (uint32_t)0);
5463 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5464
5465
5466 /* The test is to see that the memcached_quit doesn't increase the
5467 * the server failure conter, so let's ensure that it is zero
5468 * before sending quit
5469 */
5470 memc->hosts[0].server_failure_counter= 0;
5471
5472 memcached_quit(memc);
5473
5474 /* Verify that it memcached_quit didn't increment the failure counter
5475 * Please note that this isn't bullet proof, because an error could
5476 * occur...
5477 */
5478 assert(memc->hosts[0].server_failure_counter == 0);
5479
5480 /* restore the instance */
5481 memc->number_of_hosts= number_of_hosts;
5482
5483 return TEST_SUCCESS;
5484 }
5485
5486 test_st udp_setup_server_tests[] ={
5487 {"set_udp_behavior_test", 0, (test_callback_fn)set_udp_behavior_test},
5488 {"add_tcp_server_udp_client_test", 0, (test_callback_fn)add_tcp_server_udp_client_test},
5489 {"add_udp_server_tcp_client_test", 0, (test_callback_fn)add_udp_server_tcp_client_test},
5490 {0, 0, 0}
5491 };
5492
5493 test_st upd_io_tests[] ={
5494 {"udp_set_test", 0, (test_callback_fn)udp_set_test},
5495 {"udp_buffered_set_test", 0, (test_callback_fn)udp_buffered_set_test},
5496 {"udp_set_too_big_test", 0, (test_callback_fn)udp_set_too_big_test},
5497 {"udp_delete_test", 0, (test_callback_fn)udp_delete_test},
5498 {"udp_buffered_delete_test", 0, (test_callback_fn)udp_buffered_delete_test},
5499 {"udp_verbosity_test", 0, (test_callback_fn)udp_verbosity_test},
5500 {"udp_quit_test", 0, (test_callback_fn)udp_quit_test},
5501 {"udp_flush_test", 0, (test_callback_fn)udp_flush_test},
5502 {"udp_incr_test", 0, (test_callback_fn)udp_incr_test},
5503 {"udp_decr_test", 0, (test_callback_fn)udp_decr_test},
5504 {"udp_stat_test", 0, (test_callback_fn)udp_stat_test},
5505 {"udp_version_test", 0, (test_callback_fn)udp_version_test},
5506 {"udp_get_test", 0, (test_callback_fn)udp_get_test},
5507 {"udp_mixed_io_test", 0, (test_callback_fn)udp_mixed_io_test},
5508 {0, 0, 0}
5509 };
5510
5511 /* Clean the server before beginning testing */
5512 test_st tests[] ={
5513 {"flush", 0, (test_callback_fn)flush_test },
5514 {"init", 0, (test_callback_fn)init_test },
5515 {"allocation", 0, (test_callback_fn)allocation_test },
5516 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5517 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5518 {"server_sort", 0, (test_callback_fn)server_sort_test},
5519 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5520 {"clone_test", 0, (test_callback_fn)clone_test },
5521 {"connection_test", 0, (test_callback_fn)connection_test},
5522 {"callback_test", 0, (test_callback_fn)callback_test},
5523 {"behavior_test", 0, (test_callback_fn)behavior_test},
5524 {"userdata_test", 0, (test_callback_fn)userdata_test},
5525 {"error", 0, (test_callback_fn)error_test },
5526 {"set", 0, (test_callback_fn)set_test },
5527 {"set2", 0, (test_callback_fn)set_test2 },
5528 {"set3", 0, (test_callback_fn)set_test3 },
5529 {"dump", 1, (test_callback_fn)dump_test},
5530 {"add", 1, (test_callback_fn)add_test },
5531 {"replace", 1, (test_callback_fn)replace_test },
5532 {"delete", 1, (test_callback_fn)delete_test },
5533 {"get", 1, (test_callback_fn)get_test },
5534 {"get2", 0, (test_callback_fn)get_test2 },
5535 {"get3", 0, (test_callback_fn)get_test3 },
5536 {"get4", 0, (test_callback_fn)get_test4 },
5537 {"partial mget", 0, (test_callback_fn)get_test5 },
5538 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5539 {"increment", 0, (test_callback_fn)increment_test },
5540 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5541 {"decrement", 0, (test_callback_fn)decrement_test },
5542 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5543 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5544 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5545 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5546 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5547 {"quit", 0, (test_callback_fn)quit_test },
5548 {"mget", 1, (test_callback_fn)mget_test },
5549 {"mget_result", 1, (test_callback_fn)mget_result_test },
5550 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5551 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5552 {"mget_execute", 1, (test_callback_fn)mget_execute },
5553 {"mget_end", 0, (test_callback_fn)mget_end },
5554 {"get_stats", 0, (test_callback_fn)get_stats },
5555 {"add_host_test", 0, (test_callback_fn)add_host_test },
5556 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5557 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5558 {"behavior_test", 0, (test_callback_fn)get_stats_keys },
5559 {"callback_test", 0, (test_callback_fn)get_stats_keys },
5560 {"version_string_test", 0, (test_callback_fn)version_string_test},
5561 {"bad_key", 1, (test_callback_fn)bad_key_test },
5562 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
5563 {"read_through", 1, (test_callback_fn)read_through },
5564 {"delete_through", 1, (test_callback_fn)delete_through },
5565 {"noreply", 1, (test_callback_fn)noreply_test},
5566 {"analyzer", 1, (test_callback_fn)analyzer_test},
5567 #ifdef HAVE_LIBMEMCACHEDUTIL
5568 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
5569 #endif
5570 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
5571 {0, 0, 0}
5572 };
5573
5574 test_st async_tests[] ={
5575 {"add", 1, (test_callback_fn)add_wrapper },
5576 {0, 0, 0}
5577 };
5578
5579 test_st string_tests[] ={
5580 {"string static with null", 0, (test_callback_fn)string_static_null },
5581 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
5582 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
5583 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
5584 {"string append", 0, (test_callback_fn)string_alloc_append },
5585 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
5586 {0, 0, (test_callback_fn)0}
5587 };
5588
5589 test_st result_tests[] ={
5590 {"result static", 0, (test_callback_fn)result_static},
5591 {"result alloc", 0, (test_callback_fn)result_alloc},
5592 {0, 0, (test_callback_fn)0}
5593 };
5594
5595 test_st version_1_2_3[] ={
5596 {"append", 0, (test_callback_fn)append_test },
5597 {"prepend", 0, (test_callback_fn)prepend_test },
5598 {"cas", 0, (test_callback_fn)cas_test },
5599 {"cas2", 0, (test_callback_fn)cas2_test },
5600 {"append_binary", 0, (test_callback_fn)append_binary_test },
5601 {0, 0, (test_callback_fn)0}
5602 };
5603
5604 test_st user_tests[] ={
5605 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
5606 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
5607 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
5608 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
5609 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
5610 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
5611 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
5612 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
5613 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
5614 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
5615 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
5616 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
5617 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
5618 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
5619 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
5620 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
5621 #ifndef __sun
5622 /*
5623 ** It seems to be something weird with the character sets..
5624 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5625 ** guess I need to find out how this is supposed to work.. Perhaps I need
5626 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5627 ** so just disable the code for now...).
5628 */
5629 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
5630 #endif
5631 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
5632 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
5633 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
5634 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
5635 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
5636 {0, 0, (test_callback_fn)0}
5637 };
5638
5639 test_st replication_tests[]= {
5640 {"set", 1, (test_callback_fn)replication_set_test },
5641 {"get", 0, (test_callback_fn)replication_get_test },
5642 {"mget", 0, (test_callback_fn)replication_mget_test },
5643 {"delete", 0, (test_callback_fn)replication_delete_test },
5644 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
5645 {0, 0, (test_callback_fn)0}
5646 };
5647
5648 /*
5649 * The following test suite is used to verify that we don't introduce
5650 * regression bugs. If you want more information about the bug / test,
5651 * you should look in the bug report at
5652 * http://bugs.launchpad.net/libmemcached
5653 */
5654 test_st regression_tests[]= {
5655 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
5656 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
5657 {"lp:434843 buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
5658 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
5659 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
5660 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
5661 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
5662 {0, 0, (test_callback_fn)0}
5663 };
5664
5665 test_st ketama_compatibility[]= {
5666 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
5667 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
5668 {0, 0, (test_callback_fn)0}
5669 };
5670
5671 test_st generate_tests[] ={
5672 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5673 {"generate_data", 1, (test_callback_fn)generate_data },
5674 {"get_read", 0, (test_callback_fn)get_read },
5675 {"delete_generate", 0, (test_callback_fn)delete_generate },
5676 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5677 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
5678 {"generate_data", 1, (test_callback_fn)generate_data },
5679 {"mget_read", 0, (test_callback_fn)mget_read },
5680 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
5681 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
5682 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5683 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
5684 {"generate_data", 1, (test_callback_fn)generate_data },
5685 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5686 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5687 {0, 0, (test_callback_fn)0}
5688 };
5689
5690 test_st consistent_tests[] ={
5691 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5692 {"generate_data", 1, (test_callback_fn)generate_data },
5693 {"get_read", 0, (test_callback_fn)get_read_count },
5694 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5695 {0, 0, (test_callback_fn)0}
5696 };
5697
5698 test_st consistent_weighted_tests[] ={
5699 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5700 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
5701 {"get_read", 0, (test_callback_fn)get_read_count },
5702 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5703 {0, 0, (test_callback_fn)0}
5704 };
5705
5706 test_st hsieh_availability[] ={
5707 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
5708 {0, 0, (test_callback_fn)0}
5709 };
5710
5711 #if 0
5712 test_st hash_sanity[] ={
5713 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
5714 {0, 0, (test_callback_fn)0}
5715 };
5716 #endif
5717
5718 test_st ketama_auto_eject_hosts[] ={
5719 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
5720 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
5721 {0, 0, (test_callback_fn)0}
5722 };
5723
5724 test_st hash_tests[] ={
5725 {"md5", 0, (test_callback_fn)md5_run },
5726 {"crc", 0, (test_callback_fn)crc_run },
5727 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
5728 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
5729 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
5730 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
5731 {"hsieh", 0, (test_callback_fn)hsieh_run },
5732 {"murmur", 0, (test_callback_fn)murmur_run },
5733 {"jenkis", 0, (test_callback_fn)jenkins_run },
5734 {0, 0, (test_callback_fn)0}
5735 };
5736
5737 collection_st collection[] ={
5738 #if 0
5739 {"hash_sanity", 0, 0, hash_sanity},
5740 #endif
5741 {"hsieh_availability", 0, 0, hsieh_availability},
5742 {"udp_setup", (test_callback_fn)init_udp, 0, udp_setup_server_tests},
5743 {"udp_io", (test_callback_fn)init_udp, 0, upd_io_tests},
5744 {"udp_binary_io", (test_callback_fn)binary_init_udp, 0, upd_io_tests},
5745 {"block", 0, 0, tests},
5746 {"binary", (test_callback_fn)pre_binary, 0, tests},
5747 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
5748 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5749 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
5750 {"md5", (test_callback_fn)pre_md5, 0, tests},
5751 {"crc", (test_callback_fn)pre_crc, 0, tests},
5752 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
5753 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
5754 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
5755 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
5756 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
5757 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
5758 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
5759 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5760 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
5761 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5762 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
5763 {"gets", (test_callback_fn)enable_cas, 0, tests},
5764 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
5765 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
5766 #ifdef MEMCACHED_ENABLE_DEPRECATED
5767 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
5768 #endif
5769 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
5770 {"prefix", (test_callback_fn)set_prefix, 0, tests},
5771 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
5772 {"string", 0, 0, string_tests},
5773 {"result", 0, 0, result_tests},
5774 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
5775 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
5776 {"user", 0, 0, user_tests},
5777 {"generate", 0, 0, generate_tests},
5778 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
5779 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
5780 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
5781 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
5782 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
5783 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
5784 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
5785 {"consistent_not", 0, 0, consistent_tests},
5786 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
5787 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5788 {"ketama_compat", 0, 0, ketama_compatibility},
5789 {"test_hashes", 0, 0, hash_tests},
5790 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
5791 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
5792 {"regression", 0, 0, regression_tests},
5793 {0, 0, 0, 0}
5794 };
5795
5796 #define SERVERS_TO_CREATE 5
5797
5798 #include "libmemcached_world.h"
5799
5800 void get_world(world_st *world)
5801 {
5802 world->collections= collection;
5803 world->collection_startup= (test_callback_fn)world_collection_startup;
5804 world->flush= (test_callback_fn)world_flush;
5805 world->pre_run= (test_callback_fn)world_pre_run;
5806 world->create= (test_callback_create_fn)world_create;
5807 world->post_run= (test_callback_fn)world_post_run;
5808 world->on_error= (test_callback_error_fn)world_on_error;
5809 world->destroy= (test_callback_fn)world_destroy;
5810 world->runner= &defualt_libmemcached_runner;
5811 }