Updated test framework.
[m6w6/libmemcached] / tests / mem_functions.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(memcached_server_count(local_memc) == x + 1);
112 test_truth(memcached_servers_count(local_memc->hosts) == 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(memcached_server_count(local_memc) == x+1);
183 test_truth(memcached_servers_count(local_memc->hosts) == 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
1849 return TEST_SUCCESS;
1850 }
1851
1852 static test_return_t fetch_all_results(memcached_st *memc)
1853 {
1854 memcached_return_t rc= MEMCACHED_SUCCESS;
1855 char return_key[MEMCACHED_MAX_KEY];
1856 size_t return_key_length;
1857 char *return_value;
1858 size_t return_value_length;
1859 uint32_t flags;
1860
1861 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1862 &return_value_length, &flags, &rc)))
1863 {
1864 test_truth(return_value);
1865 test_truth(rc == MEMCACHED_SUCCESS);
1866 free(return_value);
1867 }
1868
1869 return ((rc == MEMCACHED_END) || (rc == MEMCACHED_SUCCESS)) ? TEST_SUCCESS : TEST_FAILURE;
1870 }
1871
1872 /* Test case provided by Cal Haldenbrand */
1873 static test_return_t user_supplied_bug1(memcached_st *memc)
1874 {
1875 unsigned int setter= 1;
1876 unsigned int x;
1877
1878 unsigned long long total= 0;
1879 uint32_t size= 0;
1880 char key[10];
1881 char randomstuff[6 * 1024];
1882 memcached_return_t rc;
1883
1884 memset(randomstuff, 0, 6 * 1024);
1885
1886 /* We just keep looking at the same values over and over */
1887 srandom(10);
1888
1889 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1890 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1891
1892
1893 /* add key */
1894 for (x= 0 ; total < 20 * 1024576 ; x++ )
1895 {
1896 unsigned int j= 0;
1897
1898 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
1899 memset(randomstuff, 0, 6 * 1024);
1900 test_truth(size < 6 * 1024); /* Being safe here */
1901
1902 for (j= 0 ; j < size ;j++)
1903 randomstuff[j] = (signed char) ((rand() % 26) + 97);
1904
1905 total += size;
1906 sprintf(key, "%d", x);
1907 rc = memcached_set(memc, key, strlen(key),
1908 randomstuff, strlen(randomstuff), 10, 0);
1909 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1910 /* If we fail, lets try again */
1911 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
1912 rc = memcached_set(memc, key, strlen(key),
1913 randomstuff, strlen(randomstuff), 10, 0);
1914 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1915 }
1916
1917 return TEST_SUCCESS;
1918 }
1919
1920 /* Test case provided by Cal Haldenbrand */
1921 static test_return_t user_supplied_bug2(memcached_st *memc)
1922 {
1923 int errors;
1924 unsigned int setter;
1925 unsigned int x;
1926 unsigned long long total;
1927
1928 setter= 1;
1929 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1930 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1931 #ifdef NOT_YET
1932 setter = 20 * 1024576;
1933 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1934 setter = 20 * 1024576;
1935 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1936 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1937 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1938
1939 for (x= 0, errors= 0, total= 0 ; total < 20 * 1024576 ; x++)
1940 #endif
1941
1942 for (x= 0, errors= 0, total= 0 ; total < 24576 ; x++)
1943 {
1944 memcached_return_t rc= MEMCACHED_SUCCESS;
1945 char buffer[SMALL_STRING_LEN];
1946 uint32_t flags= 0;
1947 size_t val_len= 0;
1948 char *getval;
1949
1950 memset(buffer, 0, SMALL_STRING_LEN);
1951
1952 snprintf(buffer, SMALL_STRING_LEN, "%u", x);
1953 getval= memcached_get(memc, buffer, strlen(buffer),
1954 &val_len, &flags, &rc);
1955 if (rc != MEMCACHED_SUCCESS)
1956 {
1957 if (rc == MEMCACHED_NOTFOUND)
1958 errors++;
1959 else
1960 {
1961 test_truth(rc);
1962 }
1963
1964 continue;
1965 }
1966 total+= val_len;
1967 errors= 0;
1968 free(getval);
1969 }
1970
1971 return TEST_SUCCESS;
1972 }
1973
1974 /* Do a large mget() over all the keys we think exist */
1975 #define KEY_COUNT 3000 // * 1024576
1976 static test_return_t user_supplied_bug3(memcached_st *memc)
1977 {
1978 memcached_return_t rc;
1979 unsigned int setter;
1980 unsigned int x;
1981 char **keys;
1982 size_t key_lengths[KEY_COUNT];
1983
1984 setter= 1;
1985 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1986 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1987 #ifdef NOT_YET
1988 setter = 20 * 1024576;
1989 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1990 setter = 20 * 1024576;
1991 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1992 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1993 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1994 #endif
1995
1996 keys= calloc(KEY_COUNT, sizeof(char *));
1997 test_truth(keys);
1998 for (x= 0; x < KEY_COUNT; x++)
1999 {
2000 char buffer[30];
2001
2002 snprintf(buffer, 30, "%u", x);
2003 keys[x]= strdup(buffer);
2004 key_lengths[x]= strlen(keys[x]);
2005 }
2006
2007 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
2008 test_truth(rc == MEMCACHED_SUCCESS);
2009
2010 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
2011
2012 for (x= 0; x < KEY_COUNT; x++)
2013 free(keys[x]);
2014 free(keys);
2015
2016 return TEST_SUCCESS;
2017 }
2018
2019 /* Make sure we behave properly if server list has no values */
2020 static test_return_t user_supplied_bug4(memcached_st *memc)
2021 {
2022 memcached_return_t rc;
2023 const char *keys[]= {"fudge", "son", "food"};
2024 size_t key_length[]= {5, 3, 4};
2025 unsigned int x;
2026 uint32_t flags;
2027 char return_key[MEMCACHED_MAX_KEY];
2028 size_t return_key_length;
2029 char *return_value;
2030 size_t return_value_length;
2031
2032 /* Here we free everything before running a bunch of mget tests */
2033 memcached_servers_reset(memc);
2034
2035
2036 /* We need to empty the server before continueing test */
2037 rc= memcached_flush(memc, 0);
2038 test_truth(rc == MEMCACHED_NO_SERVERS);
2039
2040 rc= memcached_mget(memc, keys, key_length, 3);
2041 test_truth(rc == MEMCACHED_NO_SERVERS);
2042
2043 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2044 &return_value_length, &flags, &rc)) != NULL)
2045 {
2046 test_truth(return_value);
2047 }
2048 test_truth(!return_value);
2049 test_truth(return_value_length == 0);
2050 test_truth(rc == MEMCACHED_NO_SERVERS);
2051
2052 for (x= 0; x < 3; x++)
2053 {
2054 rc= memcached_set(memc, keys[x], key_length[x],
2055 keys[x], key_length[x],
2056 (time_t)50, (uint32_t)9);
2057 test_truth(rc == MEMCACHED_NO_SERVERS);
2058 }
2059
2060 rc= memcached_mget(memc, keys, key_length, 3);
2061 test_truth(rc == MEMCACHED_NO_SERVERS);
2062
2063 x= 0;
2064 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2065 &return_value_length, &flags, &rc)))
2066 {
2067 test_truth(return_value);
2068 test_truth(rc == MEMCACHED_SUCCESS);
2069 test_truth(return_key_length == return_value_length);
2070 test_truth(!memcmp(return_value, return_key, return_value_length));
2071 free(return_value);
2072 x++;
2073 }
2074
2075 return TEST_SUCCESS;
2076 }
2077
2078 #define VALUE_SIZE_BUG5 1048064
2079 static test_return_t user_supplied_bug5(memcached_st *memc)
2080 {
2081 memcached_return_t rc;
2082 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2083 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2084 char return_key[MEMCACHED_MAX_KEY];
2085 size_t return_key_length;
2086 char *value;
2087 size_t value_length;
2088 uint32_t flags;
2089 unsigned int count;
2090 unsigned int x;
2091 char insert_data[VALUE_SIZE_BUG5];
2092
2093 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2094 insert_data[x]= (signed char)rand();
2095
2096 memcached_flush(memc, 0);
2097 value= memcached_get(memc, keys[0], key_length[0],
2098 &value_length, &flags, &rc);
2099 test_truth(value == NULL);
2100 rc= memcached_mget(memc, keys, key_length, 4);
2101
2102 count= 0;
2103 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2104 &value_length, &flags, &rc)))
2105 count++;
2106 test_truth(count == 0);
2107
2108 for (x= 0; x < 4; x++)
2109 {
2110 rc= memcached_set(memc, keys[x], key_length[x],
2111 insert_data, VALUE_SIZE_BUG5,
2112 (time_t)0, (uint32_t)0);
2113 test_truth(rc == MEMCACHED_SUCCESS);
2114 }
2115
2116 for (x= 0; x < 10; x++)
2117 {
2118 value= memcached_get(memc, keys[0], key_length[0],
2119 &value_length, &flags, &rc);
2120 test_truth(value);
2121 free(value);
2122
2123 rc= memcached_mget(memc, keys, key_length, 4);
2124 count= 0;
2125 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2126 &value_length, &flags, &rc)))
2127 {
2128 count++;
2129 free(value);
2130 }
2131 test_truth(count == 4);
2132 }
2133
2134 return TEST_SUCCESS;
2135 }
2136
2137 static test_return_t user_supplied_bug6(memcached_st *memc)
2138 {
2139 memcached_return_t rc;
2140 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2141 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2142 char return_key[MEMCACHED_MAX_KEY];
2143 size_t return_key_length;
2144 char *value;
2145 size_t value_length;
2146 uint32_t flags;
2147 unsigned int count;
2148 unsigned int x;
2149 char insert_data[VALUE_SIZE_BUG5];
2150
2151 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2152 insert_data[x]= (signed char)rand();
2153
2154 memcached_flush(memc, 0);
2155 value= memcached_get(memc, keys[0], key_length[0],
2156 &value_length, &flags, &rc);
2157 test_truth(value == NULL);
2158 test_truth(rc == MEMCACHED_NOTFOUND);
2159 rc= memcached_mget(memc, keys, key_length, 4);
2160 test_truth(rc == MEMCACHED_SUCCESS);
2161
2162 count= 0;
2163 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2164 &value_length, &flags, &rc)))
2165 count++;
2166 test_truth(count == 0);
2167 test_truth(rc == MEMCACHED_END);
2168
2169 for (x= 0; x < 4; x++)
2170 {
2171 rc= memcached_set(memc, keys[x], key_length[x],
2172 insert_data, VALUE_SIZE_BUG5,
2173 (time_t)0, (uint32_t)0);
2174 test_truth(rc == MEMCACHED_SUCCESS);
2175 }
2176
2177 for (x= 0; x < 2; x++)
2178 {
2179 value= memcached_get(memc, keys[0], key_length[0],
2180 &value_length, &flags, &rc);
2181 test_truth(value);
2182 free(value);
2183
2184 rc= memcached_mget(memc, keys, key_length, 4);
2185 test_truth(rc == MEMCACHED_SUCCESS);
2186 count= 3;
2187 /* We test for purge of partial complete fetches */
2188 for (count= 3; count; count--)
2189 {
2190 value= memcached_fetch(memc, return_key, &return_key_length,
2191 &value_length, &flags, &rc);
2192 test_truth(rc == MEMCACHED_SUCCESS);
2193 test_truth(!(memcmp(value, insert_data, value_length)));
2194 test_truth(value_length);
2195 free(value);
2196 }
2197 }
2198
2199 return TEST_SUCCESS;
2200 }
2201
2202 static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused)))
2203 {
2204 memcached_return_t rc;
2205 memcached_st *mine;
2206 memcached_st *memc_clone;
2207
2208 memcached_server_st *servers;
2209 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";
2210
2211 servers= memcached_servers_parse(server_list);
2212 test_truth(servers);
2213
2214 mine= memcached_create(NULL);
2215 rc= memcached_server_push(mine, servers);
2216 test_truth(rc == MEMCACHED_SUCCESS);
2217 memcached_server_list_free(servers);
2218
2219 test_truth(mine);
2220 memc_clone= memcached_clone(NULL, mine);
2221
2222 memcached_quit(mine);
2223 memcached_quit(memc_clone);
2224
2225
2226 memcached_free(mine);
2227 memcached_free(memc_clone);
2228
2229 return TEST_SUCCESS;
2230 }
2231
2232 /* Test flag store/retrieve */
2233 static test_return_t user_supplied_bug7(memcached_st *memc)
2234 {
2235 memcached_return_t rc;
2236 const char *keys= "036790384900";
2237 size_t key_length= strlen(keys);
2238 char return_key[MEMCACHED_MAX_KEY];
2239 size_t return_key_length;
2240 char *value;
2241 size_t value_length;
2242 uint32_t flags;
2243 unsigned int x;
2244 char insert_data[VALUE_SIZE_BUG5];
2245
2246 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2247 insert_data[x]= (signed char)rand();
2248
2249 memcached_flush(memc, 0);
2250
2251 flags= 245;
2252 rc= memcached_set(memc, keys, key_length,
2253 insert_data, VALUE_SIZE_BUG5,
2254 (time_t)0, flags);
2255 test_truth(rc == MEMCACHED_SUCCESS);
2256
2257 flags= 0;
2258 value= memcached_get(memc, keys, key_length,
2259 &value_length, &flags, &rc);
2260 test_truth(flags == 245);
2261 test_truth(value);
2262 free(value);
2263
2264 rc= memcached_mget(memc, &keys, &key_length, 1);
2265
2266 flags= 0;
2267 value= memcached_fetch(memc, return_key, &return_key_length,
2268 &value_length, &flags, &rc);
2269 test_truth(flags == 245);
2270 test_truth(value);
2271 free(value);
2272
2273
2274 return TEST_SUCCESS;
2275 }
2276
2277 static test_return_t user_supplied_bug9(memcached_st *memc)
2278 {
2279 memcached_return_t rc;
2280 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2281 size_t key_length[3];
2282 unsigned int x;
2283 uint32_t flags;
2284 unsigned count= 0;
2285
2286 char return_key[MEMCACHED_MAX_KEY];
2287 size_t return_key_length;
2288 char *return_value;
2289 size_t return_value_length;
2290
2291
2292 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2293 key_length[1]= strlen("fudge&*@#");
2294 key_length[2]= strlen("for^#@&$not");
2295
2296
2297 for (x= 0; x < 3; x++)
2298 {
2299 rc= memcached_set(memc, keys[x], key_length[x],
2300 keys[x], key_length[x],
2301 (time_t)50, (uint32_t)9);
2302 test_truth(rc == MEMCACHED_SUCCESS);
2303 }
2304
2305 rc= memcached_mget(memc, keys, key_length, 3);
2306 test_truth(rc == MEMCACHED_SUCCESS);
2307
2308 /* We need to empty the server before continueing test */
2309 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2310 &return_value_length, &flags, &rc)) != NULL)
2311 {
2312 test_truth(return_value);
2313 free(return_value);
2314 count++;
2315 }
2316 test_truth(count == 3);
2317
2318 return TEST_SUCCESS;
2319 }
2320
2321 /* We are testing with aggressive timeout to get failures */
2322 static test_return_t user_supplied_bug10(memcached_st *memc)
2323 {
2324 const char *key= "foo";
2325 char *value;
2326 size_t value_length= 512;
2327 unsigned int x;
2328 size_t key_len= 3;
2329 memcached_return_t rc;
2330 unsigned int set= 1;
2331 memcached_st *mclone= memcached_clone(NULL, memc);
2332 int32_t timeout;
2333
2334 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2335 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2336 timeout= 2;
2337 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2338 (uint64_t)timeout);
2339
2340 value = (char*)malloc(value_length * sizeof(char));
2341
2342 for (x= 0; x < value_length; x++)
2343 value[x]= (char) (x % 127);
2344
2345 for (x= 1; x <= 100000; ++x)
2346 {
2347 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2348
2349 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2350 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2351
2352 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2353 x--;
2354 }
2355
2356 free(value);
2357 memcached_free(mclone);
2358
2359 return TEST_SUCCESS;
2360 }
2361
2362 /*
2363 We are looking failures in the async protocol
2364 */
2365 static test_return_t user_supplied_bug11(memcached_st *memc)
2366 {
2367 const char *key= "foo";
2368 char *value;
2369 size_t value_length= 512;
2370 unsigned int x;
2371 size_t key_len= 3;
2372 memcached_return_t rc;
2373 unsigned int set= 1;
2374 int32_t timeout;
2375 memcached_st *mclone= memcached_clone(NULL, memc);
2376
2377 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2378 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2379 timeout= -1;
2380 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2381 (size_t)timeout);
2382
2383 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2384
2385 test_truth(timeout == -1);
2386
2387 value = (char*)malloc(value_length * sizeof(char));
2388
2389 for (x= 0; x < value_length; x++)
2390 value[x]= (char) (x % 127);
2391
2392 for (x= 1; x <= 100000; ++x)
2393 {
2394 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2395 }
2396
2397 free(value);
2398 memcached_free(mclone);
2399
2400 return TEST_SUCCESS;
2401 }
2402
2403 /*
2404 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2405 */
2406 static test_return_t user_supplied_bug12(memcached_st *memc)
2407 {
2408 memcached_return_t rc;
2409 uint32_t flags;
2410 size_t value_length;
2411 char *value;
2412 uint64_t number_value;
2413
2414 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2415 &value_length, &flags, &rc);
2416 test_truth(value == NULL);
2417 test_truth(rc == MEMCACHED_NOTFOUND);
2418
2419 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2420 1, &number_value);
2421
2422 test_truth(value == NULL);
2423 /* The binary protocol will set the key if it doesn't exist */
2424 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2425 {
2426 test_truth(rc == MEMCACHED_SUCCESS);
2427 }
2428 else
2429 {
2430 test_truth(rc == MEMCACHED_NOTFOUND);
2431 }
2432
2433 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2434
2435 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2436 &value_length, &flags, &rc);
2437 test_truth(value);
2438 test_truth(rc == MEMCACHED_SUCCESS);
2439 free(value);
2440
2441 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2442 1, &number_value);
2443 test_truth(number_value == 2);
2444 test_truth(rc == MEMCACHED_SUCCESS);
2445
2446 return TEST_SUCCESS;
2447 }
2448
2449 /*
2450 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2451 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2452 */
2453 static test_return_t user_supplied_bug13(memcached_st *memc)
2454 {
2455 char key[] = "key34567890";
2456 char *overflow;
2457 memcached_return_t rc;
2458 size_t overflowSize;
2459
2460 char commandFirst[]= "set key34567890 0 0 ";
2461 char commandLast[] = " \r\n"; /* first line of command sent to server */
2462 size_t commandLength;
2463 size_t testSize;
2464
2465 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2466
2467 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2468
2469 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2470 {
2471 overflow= malloc(testSize);
2472 test_truth(overflow != NULL);
2473
2474 memset(overflow, 'x', testSize);
2475 rc= memcached_set(memc, key, strlen(key),
2476 overflow, testSize, 0, 0);
2477 test_truth(rc == MEMCACHED_SUCCESS);
2478 free(overflow);
2479 }
2480
2481 return TEST_SUCCESS;
2482 }
2483
2484
2485 /*
2486 Test values of many different sizes
2487 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2488 set key34567890 0 0 8169 \r\n
2489 is sent followed by buffer of size 8169, followed by 8169
2490 */
2491 static test_return_t user_supplied_bug14(memcached_st *memc)
2492 {
2493 size_t setter= 1;
2494 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2495 memcached_return_t rc;
2496 const char *key= "foo";
2497 char *value;
2498 size_t value_length= 18000;
2499 char *string;
2500 size_t string_length;
2501 uint32_t flags;
2502 unsigned int x;
2503 size_t current_length;
2504
2505 value = (char*)malloc(value_length);
2506 test_truth(value);
2507
2508 for (x= 0; x < value_length; x++)
2509 value[x] = (char) (x % 127);
2510
2511 for (current_length= 0; current_length < value_length; current_length++)
2512 {
2513 rc= memcached_set(memc, key, strlen(key),
2514 value, current_length,
2515 (time_t)0, (uint32_t)0);
2516 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2517
2518 string= memcached_get(memc, key, strlen(key),
2519 &string_length, &flags, &rc);
2520
2521 test_truth(rc == MEMCACHED_SUCCESS);
2522 test_truth(string_length == current_length);
2523 test_truth(!memcmp(string, value, string_length));
2524
2525 free(string);
2526 }
2527
2528 free(value);
2529
2530 return TEST_SUCCESS;
2531 }
2532
2533 /*
2534 Look for zero length value problems
2535 */
2536 static test_return_t user_supplied_bug15(memcached_st *memc)
2537 {
2538 uint32_t x;
2539 memcached_return_t rc;
2540 const char *key= "mykey";
2541 char *value;
2542 size_t length;
2543 uint32_t flags;
2544
2545 for (x= 0; x < 2; x++)
2546 {
2547 rc= memcached_set(memc, key, strlen(key),
2548 NULL, 0,
2549 (time_t)0, (uint32_t)0);
2550
2551 test_truth(rc == MEMCACHED_SUCCESS);
2552
2553 value= memcached_get(memc, key, strlen(key),
2554 &length, &flags, &rc);
2555
2556 test_truth(rc == MEMCACHED_SUCCESS);
2557 test_truth(value == NULL);
2558 test_truth(length == 0);
2559 test_truth(flags == 0);
2560
2561 value= memcached_get(memc, key, strlen(key),
2562 &length, &flags, &rc);
2563
2564 test_truth(rc == MEMCACHED_SUCCESS);
2565 test_truth(value == NULL);
2566 test_truth(length == 0);
2567 test_truth(flags == 0);
2568 }
2569
2570 return TEST_SUCCESS;
2571 }
2572
2573 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2574 static test_return_t user_supplied_bug16(memcached_st *memc)
2575 {
2576 memcached_return_t rc;
2577 const char *key= "mykey";
2578 char *value;
2579 size_t length;
2580 uint32_t flags;
2581
2582 rc= memcached_set(memc, key, strlen(key),
2583 NULL, 0,
2584 (time_t)0, UINT32_MAX);
2585
2586 test_truth(rc == MEMCACHED_SUCCESS);
2587
2588 value= memcached_get(memc, key, strlen(key),
2589 &length, &flags, &rc);
2590
2591 test_truth(rc == MEMCACHED_SUCCESS);
2592 test_truth(value == NULL);
2593 test_truth(length == 0);
2594 test_truth(flags == UINT32_MAX);
2595
2596 return TEST_SUCCESS;
2597 }
2598
2599 #ifndef __sun
2600 /* Check the validity of chinese key*/
2601 static test_return_t user_supplied_bug17(memcached_st *memc)
2602 {
2603 memcached_return_t rc;
2604 const char *key= "豆瓣";
2605 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2606 char *value2;
2607 size_t length;
2608 uint32_t flags;
2609
2610 rc= memcached_set(memc, key, strlen(key),
2611 value, strlen(value),
2612 (time_t)0, 0);
2613
2614 test_truth(rc == MEMCACHED_SUCCESS);
2615
2616 value2= memcached_get(memc, key, strlen(key),
2617 &length, &flags, &rc);
2618
2619 test_truth(length==strlen(value));
2620 test_truth(rc == MEMCACHED_SUCCESS);
2621 test_truth(memcmp(value, value2, length)==0);
2622 free(value2);
2623
2624 return TEST_SUCCESS;
2625 }
2626 #endif
2627
2628 /*
2629 From Andrei on IRC
2630 */
2631
2632 static test_return_t user_supplied_bug19(memcached_st *memc)
2633 {
2634 memcached_st *m;
2635 memcached_server_st *s;
2636 memcached_return_t res;
2637
2638 (void)memc;
2639
2640 m= memcached_create(NULL);
2641 memcached_server_add_with_weight(m, "localhost", 11311, 100);
2642 memcached_server_add_with_weight(m, "localhost", 11312, 100);
2643
2644 s= memcached_server_by_key(m, "a", 1, &res);
2645 memcached_server_free(s);
2646
2647 memcached_free(m);
2648
2649 return TEST_SUCCESS;
2650 }
2651
2652 /* CAS test from Andei */
2653 static test_return_t user_supplied_bug20(memcached_st *memc)
2654 {
2655 memcached_return_t status;
2656 memcached_result_st *result, result_obj;
2657 const char *key = "abc";
2658 size_t key_len = strlen("abc");
2659 const char *value = "foobar";
2660 size_t value_len = strlen(value);
2661
2662 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2663
2664 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2665 test_truth(status == MEMCACHED_SUCCESS);
2666
2667 status = memcached_mget(memc, &key, &key_len, 1);
2668 test_truth(status == MEMCACHED_SUCCESS);
2669
2670 result= memcached_result_create(memc, &result_obj);
2671 test_truth(result);
2672
2673 memcached_result_create(memc, &result_obj);
2674 result= memcached_fetch_result(memc, &result_obj, &status);
2675
2676 test_truth(result);
2677 test_truth(status == MEMCACHED_SUCCESS);
2678
2679 memcached_result_free(result);
2680
2681 return TEST_SUCCESS;
2682 }
2683
2684 #include "ketama_test_cases.h"
2685 static test_return_t user_supplied_bug18(memcached_st *trash)
2686 {
2687 memcached_return_t rc;
2688 uint64_t value;
2689 int x;
2690 memcached_server_st *server_pool;
2691 memcached_st *memc;
2692
2693 (void)trash;
2694
2695 memc= memcached_create(NULL);
2696 test_truth(memc);
2697
2698 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2699 test_truth(rc == MEMCACHED_SUCCESS);
2700
2701 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2702 test_truth(value == 1);
2703
2704 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2705 test_truth(rc == MEMCACHED_SUCCESS);
2706
2707 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2708 test_truth(value == MEMCACHED_HASH_MD5);
2709
2710 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");
2711 memcached_server_push(memc, server_pool);
2712
2713 /* verify that the server list was parsed okay. */
2714 test_truth(memcached_server_count(memc) == 8);
2715 test_truth(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2716 test_truth(server_pool[0].port == 11211);
2717 test_truth(server_pool[0].weight == 600);
2718 test_truth(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2719 test_truth(server_pool[2].port == 11211);
2720 test_truth(server_pool[2].weight == 200);
2721 test_truth(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2722 test_truth(server_pool[7].port == 11211);
2723 test_truth(server_pool[7].weight == 100);
2724
2725 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2726 * us test the boundary wraparound.
2727 */
2728 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2729
2730 /* verify the standard ketama set. */
2731 for (x= 0; x < 99; x++)
2732 {
2733 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2734 char *hostname = memc->hosts[server_idx].hostname;
2735 test_strcmp(hostname, ketama_test_cases[x].server);
2736 }
2737
2738 memcached_server_list_free(server_pool);
2739 memcached_free(memc);
2740
2741 return TEST_SUCCESS;
2742 }
2743
2744 /* Large mget() of missing keys with binary proto
2745 *
2746 * If many binary quiet commands (such as getq's in an mget) fill the output
2747 * buffer and the server chooses not to respond, memcached_flush hangs. See
2748 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2749 */
2750
2751 /* sighandler_t function that always asserts false */
2752 static void fail(int unused __attribute__((unused)))
2753 {
2754 assert(0);
2755 }
2756
2757
2758 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2759 {
2760 memcached_return_t rc;
2761 unsigned int x;
2762 char **keys;
2763 size_t* key_lengths;
2764 void (*oldalarm)(int);
2765 memcached_st *memc_clone;
2766
2767 memc_clone= memcached_clone(NULL, memc);
2768 test_truth(memc_clone);
2769
2770 /* only binproto uses getq for mget */
2771 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2772
2773 /* empty the cache to ensure misses (hence non-responses) */
2774 rc= memcached_flush(memc_clone, 0);
2775 test_truth(rc == MEMCACHED_SUCCESS);
2776
2777 key_lengths= calloc(key_count, sizeof(size_t));
2778 keys= calloc(key_count, sizeof(char *));
2779 test_truth(keys);
2780 for (x= 0; x < key_count; x++)
2781 {
2782 char buffer[30];
2783
2784 snprintf(buffer, 30, "%u", x);
2785 keys[x]= strdup(buffer);
2786 key_lengths[x]= strlen(keys[x]);
2787 }
2788
2789 oldalarm= signal(SIGALRM, fail);
2790 alarm(5);
2791
2792 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
2793 test_truth(rc == MEMCACHED_SUCCESS);
2794
2795 alarm(0);
2796 signal(SIGALRM, oldalarm);
2797
2798 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
2799
2800 for (x= 0; x < key_count; x++)
2801 free(keys[x]);
2802 free(keys);
2803 free(key_lengths);
2804
2805 memcached_free(memc_clone);
2806
2807 return TEST_SUCCESS;
2808 }
2809
2810 static test_return_t pre_binary(memcached_st *memc);
2811
2812 static test_return_t user_supplied_bug21(memcached_st *memc)
2813 {
2814 test_return_t test_rc;
2815 test_rc= pre_binary(memc);
2816
2817 if (test_rc != TEST_SUCCESS)
2818 return test_rc;
2819
2820 test_return_t rc;
2821
2822 /* should work as of r580 */
2823 rc= _user_supplied_bug21(memc, 10);
2824 test_truth(rc == TEST_SUCCESS);
2825
2826 /* should fail as of r580 */
2827 rc= _user_supplied_bug21(memc, 1000);
2828 test_truth(rc == TEST_SUCCESS);
2829
2830 return TEST_SUCCESS;
2831 }
2832
2833 static test_return_t auto_eject_hosts(memcached_st *trash)
2834 {
2835 (void) trash;
2836
2837 memcached_return_t rc;
2838 memcached_st *memc= memcached_create(NULL);
2839 test_truth(memc);
2840
2841 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2842 test_truth(rc == MEMCACHED_SUCCESS);
2843
2844 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2845 test_truth(value == 1);
2846
2847 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2848 test_truth(rc == MEMCACHED_SUCCESS);
2849
2850 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2851 test_truth(value == MEMCACHED_HASH_MD5);
2852
2853 /* server should be removed when in delay */
2854 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
2855 test_truth(rc == MEMCACHED_SUCCESS);
2856
2857 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
2858 test_truth(value == 1);
2859
2860 memcached_server_st *server_pool;
2861 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");
2862 memcached_server_push(memc, server_pool);
2863
2864 /* verify that the server list was parsed okay. */
2865 test_truth(memcached_server_count(memc) == 8);
2866 test_truth(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2867 test_truth(server_pool[0].port == 11211);
2868 test_truth(server_pool[0].weight == 600);
2869 test_truth(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2870 test_truth(server_pool[2].port == 11211);
2871 test_truth(server_pool[2].weight == 200);
2872 test_truth(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2873 test_truth(server_pool[7].port == 11211);
2874 test_truth(server_pool[7].weight == 100);
2875
2876 memc->hosts[2].next_retry = time(NULL) + 15;
2877 memc->next_distribution_rebuild= time(NULL) - 1;
2878
2879 for (int x= 0; x < 99; x++)
2880 {
2881 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2882 test_truth(server_idx != 2);
2883 }
2884
2885 /* and re-added when it's back. */
2886 memc->hosts[2].next_retry = time(NULL) - 1;
2887 memc->next_distribution_rebuild= time(NULL) - 1;
2888 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
2889 memc->distribution);
2890 for (int x= 0; x < 99; x++)
2891 {
2892 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2893 char *hostname = memc->hosts[server_idx].hostname;
2894 test_truth(strcmp(hostname, ketama_test_cases[x].server) == 0);
2895 }
2896
2897 memcached_server_list_free(server_pool);
2898 memcached_free(memc);
2899
2900 return TEST_SUCCESS;
2901 }
2902
2903 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
2904 {
2905 (void) trash;
2906
2907 memcached_return_t rc;
2908 memcached_st *memc= memcached_create(NULL);
2909 test_truth(memc);
2910
2911
2912 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2913 test_truth(rc == MEMCACHED_SUCCESS);
2914
2915 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2916 test_truth(value == 1);
2917
2918 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2919 test_truth(rc == MEMCACHED_SUCCESS);
2920
2921 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2922 test_truth(value == MEMCACHED_HASH_MD5);
2923
2924
2925 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2926
2927 memcached_server_st *server_pool;
2928 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");
2929 memcached_server_push(memc, server_pool);
2930
2931 // @todo this needs to be refactored to actually test something.
2932 #if 0
2933 FILE *fp;
2934 if ((fp = fopen("ketama_keys.txt", "w")))
2935 {
2936 // noop
2937 } else {
2938 printf("cannot write to file ketama_keys.txt");
2939 return TEST_FAILURE;
2940 }
2941
2942 for (int x= 0; x < 10000; x++)
2943 {
2944 char key[10];
2945 sprintf(key, "%d", x);
2946
2947 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2948 char *hostname = memc->hosts[server_idx].hostname;
2949 in_port_t port = memc->hosts[server_idx].port;
2950 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2951 }
2952 fclose(fp);
2953 #endif
2954 memcached_server_list_free(server_pool);
2955 memcached_free(memc);
2956
2957 return TEST_SUCCESS;
2958 }
2959
2960
2961 static test_return_t result_static(memcached_st *memc)
2962 {
2963 memcached_result_st result;
2964 memcached_result_st *result_ptr;
2965
2966 result_ptr= memcached_result_create(memc, &result);
2967 test_truth(result.options.is_allocated == false);
2968 test_truth(memcached_is_initialized(&result) == true);
2969 test_truth(result_ptr);
2970 test_truth(result_ptr == &result);
2971
2972 memcached_result_free(&result);
2973
2974 test_truth(result.options.is_allocated == false);
2975 test_truth(memcached_is_initialized(&result) == false);
2976
2977 return TEST_SUCCESS;
2978 }
2979
2980 static test_return_t result_alloc(memcached_st *memc)
2981 {
2982 memcached_result_st *result_ptr;
2983
2984 result_ptr= memcached_result_create(memc, NULL);
2985 test_truth(result_ptr);
2986 test_truth(result_ptr->options.is_allocated == true);
2987 test_truth(memcached_is_initialized(result_ptr) == true);
2988 memcached_result_free(result_ptr);
2989
2990 return TEST_SUCCESS;
2991 }
2992
2993 static test_return_t string_static_null(memcached_st *memc)
2994 {
2995 memcached_string_st string;
2996 memcached_string_st *string_ptr;
2997
2998 string_ptr= memcached_string_create(memc, &string, 0);
2999 test_truth(string.options.is_initialized == true);
3000 test_truth(string_ptr);
3001
3002 /* The following two better be the same! */
3003 test_truth(memcached_is_allocated(string_ptr) == false);
3004 test_truth(memcached_is_allocated(&string) == false);
3005 test_truth(&string == string_ptr);
3006
3007 test_truth(string.options.is_initialized == true);
3008 test_truth(memcached_is_initialized(&string) == true);
3009 memcached_string_free(&string);
3010 test_truth(memcached_is_initialized(&string) == false);
3011
3012 return TEST_SUCCESS;
3013 }
3014
3015 static test_return_t string_alloc_null(memcached_st *memc)
3016 {
3017 memcached_string_st *string;
3018
3019 string= memcached_string_create(memc, NULL, 0);
3020 test_truth(string);
3021 test_truth(memcached_is_allocated(string) == true);
3022 test_truth(memcached_is_initialized(string) == true);
3023 memcached_string_free(string);
3024
3025 return TEST_SUCCESS;
3026 }
3027
3028 static test_return_t string_alloc_with_size(memcached_st *memc)
3029 {
3030 memcached_string_st *string;
3031
3032 string= memcached_string_create(memc, NULL, 1024);
3033 test_truth(string);
3034 test_truth(memcached_is_allocated(string) == true);
3035 test_truth(memcached_is_initialized(string) == true);
3036 memcached_string_free(string);
3037
3038 return TEST_SUCCESS;
3039 }
3040
3041 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
3042 {
3043 memcached_string_st *string;
3044
3045 string= memcached_string_create(memc, NULL, SIZE_MAX);
3046 test_truth(string == NULL);
3047
3048 return TEST_SUCCESS;
3049 }
3050
3051 static test_return_t string_alloc_append(memcached_st *memc)
3052 {
3053 unsigned int x;
3054 char buffer[SMALL_STRING_LEN];
3055 memcached_string_st *string;
3056
3057 /* Ring the bell! */
3058 memset(buffer, 6, SMALL_STRING_LEN);
3059
3060 string= memcached_string_create(memc, NULL, 100);
3061 test_truth(string);
3062 test_truth(memcached_is_allocated(string) == true);
3063 test_truth(memcached_is_initialized(string) == true);
3064
3065 for (x= 0; x < 1024; x++)
3066 {
3067 memcached_return_t rc;
3068 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3069 test_truth(rc == MEMCACHED_SUCCESS);
3070 }
3071 test_truth(memcached_is_allocated(string) == true);
3072 memcached_string_free(string);
3073
3074 return TEST_SUCCESS;
3075 }
3076
3077 static test_return_t string_alloc_append_toobig(memcached_st *memc)
3078 {
3079 memcached_return_t rc;
3080 unsigned int x;
3081 char buffer[SMALL_STRING_LEN];
3082 memcached_string_st *string;
3083
3084 /* Ring the bell! */
3085 memset(buffer, 6, SMALL_STRING_LEN);
3086
3087 string= memcached_string_create(memc, NULL, 100);
3088 test_truth(string);
3089 test_truth(memcached_is_allocated(string) == true);
3090 test_truth(memcached_is_initialized(string) == true);
3091
3092 for (x= 0; x < 1024; x++)
3093 {
3094 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3095 test_truth(rc == MEMCACHED_SUCCESS);
3096 }
3097 rc= memcached_string_append(string, buffer, SIZE_MAX);
3098 test_truth(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
3099 test_truth(memcached_is_allocated(string) == true);
3100 memcached_string_free(string);
3101
3102 return TEST_SUCCESS;
3103 }
3104
3105 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
3106 {
3107 pairs_free(global_pairs);
3108
3109 return TEST_SUCCESS;
3110 }
3111
3112 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
3113 {
3114 unsigned long long x;
3115 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3116 global_count= GLOBAL_COUNT;
3117
3118 for (x= 0; x < global_count; x++)
3119 {
3120 global_keys[x]= global_pairs[x].key;
3121 global_keys_length[x]= global_pairs[x].key_length;
3122 }
3123
3124 return TEST_SUCCESS;
3125 }
3126
3127 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
3128 {
3129 unsigned long long x;
3130 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3131 global_count= GLOBAL2_COUNT;
3132
3133 for (x= 0; x < global_count; x++)
3134 {
3135 global_keys[x]= global_pairs[x].key;
3136 global_keys_length[x]= global_pairs[x].key_length;
3137 }
3138
3139 return TEST_SUCCESS;
3140 }
3141
3142 static test_return_t generate_data(memcached_st *memc)
3143 {
3144 execute_set(memc, global_pairs, global_count);
3145
3146 return TEST_SUCCESS;
3147 }
3148
3149 static test_return_t generate_data_with_stats(memcached_st *memc)
3150 {
3151 memcached_stat_st *stat_p;
3152 memcached_return_t rc;
3153 uint32_t host_index= 0;
3154 execute_set(memc, global_pairs, global_count);
3155
3156 //TODO: hosts used size stats
3157 stat_p= memcached_stat(memc, NULL, &rc);
3158 test_truth(stat_p);
3159
3160 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3161 {
3162 /* This test was changes so that "make test" would work properlly */
3163 #ifdef DEBUG
3164 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);
3165 #endif
3166 test_truth((unsigned long long)(stat_p + host_index)->bytes);
3167 }
3168
3169 memcached_stat_free(NULL, stat_p);
3170
3171 return TEST_SUCCESS;
3172 }
3173 static test_return_t generate_buffer_data(memcached_st *memc)
3174 {
3175 size_t latch= 0;
3176
3177 latch= 1;
3178 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3179 generate_data(memc);
3180
3181 return TEST_SUCCESS;
3182 }
3183
3184 static test_return_t get_read_count(memcached_st *memc)
3185 {
3186 unsigned int x;
3187 memcached_return_t rc;
3188 memcached_st *memc_clone;
3189
3190 memc_clone= memcached_clone(NULL, memc);
3191 test_truth(memc_clone);
3192
3193 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3194
3195 {
3196 char *return_value;
3197 size_t return_value_length;
3198 uint32_t flags;
3199 uint32_t count;
3200
3201 for (x= count= 0; x < global_count; x++)
3202 {
3203 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3204 &return_value_length, &flags, &rc);
3205 if (rc == MEMCACHED_SUCCESS)
3206 {
3207 count++;
3208 if (return_value)
3209 free(return_value);
3210 }
3211 }
3212 }
3213
3214 memcached_free(memc_clone);
3215
3216 return TEST_SUCCESS;
3217 }
3218
3219 static test_return_t get_read(memcached_st *memc)
3220 {
3221 unsigned int x;
3222 memcached_return_t rc;
3223
3224 {
3225 char *return_value;
3226 size_t return_value_length;
3227 uint32_t flags;
3228
3229 for (x= 0; x < global_count; x++)
3230 {
3231 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3232 &return_value_length, &flags, &rc);
3233 /*
3234 test_truth(return_value);
3235 test_truth(rc == MEMCACHED_SUCCESS);
3236 */
3237 if (rc == MEMCACHED_SUCCESS && return_value)
3238 free(return_value);
3239 }
3240 }
3241
3242 return TEST_SUCCESS;
3243 }
3244
3245 static test_return_t mget_read(memcached_st *memc)
3246 {
3247 memcached_return_t rc;
3248
3249 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3250 test_truth(rc == MEMCACHED_SUCCESS);
3251 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
3252
3253 return TEST_SUCCESS;
3254 }
3255
3256 static test_return_t mget_read_result(memcached_st *memc)
3257 {
3258 memcached_return_t rc;
3259
3260 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3261 test_truth(rc == MEMCACHED_SUCCESS);
3262 /* Turn this into a help function */
3263 {
3264 memcached_result_st results_obj;
3265 memcached_result_st *results;
3266
3267 results= memcached_result_create(memc, &results_obj);
3268
3269 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3270 {
3271 test_truth(results);
3272 test_truth(rc == MEMCACHED_SUCCESS);
3273 }
3274
3275 memcached_result_free(&results_obj);
3276 }
3277
3278 return TEST_SUCCESS;
3279 }
3280
3281 static test_return_t mget_read_function(memcached_st *memc)
3282 {
3283 memcached_return_t rc;
3284 unsigned int counter;
3285 memcached_execute_fn callbacks[1];
3286
3287 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3288 test_truth(rc == MEMCACHED_SUCCESS);
3289
3290 callbacks[0]= &callback_counter;
3291 counter= 0;
3292 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3293
3294 return TEST_SUCCESS;
3295 }
3296
3297 static test_return_t delete_generate(memcached_st *memc)
3298 {
3299 unsigned int x;
3300
3301 for (x= 0; x < global_count; x++)
3302 {
3303 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3304 }
3305
3306 return TEST_SUCCESS;
3307 }
3308
3309 static test_return_t delete_buffer_generate(memcached_st *memc)
3310 {
3311 size_t latch= 0;
3312 unsigned int x;
3313
3314 latch= 1;
3315 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3316
3317 for (x= 0; x < global_count; x++)
3318 {
3319 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3320 }
3321
3322 return TEST_SUCCESS;
3323 }
3324
3325 static test_return_t add_host_test1(memcached_st *memc)
3326 {
3327 unsigned int x;
3328 memcached_return_t rc;
3329 char servername[]= "0.example.com";
3330 memcached_server_st *servers;
3331
3332 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3333 test_truth(servers);
3334 test_truth(1 == memcached_server_list_count(servers));
3335
3336 for (x= 2; x < 20; x++)
3337 {
3338 char buffer[SMALL_STRING_LEN];
3339
3340 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
3341 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3342 &rc);
3343 test_truth(rc == MEMCACHED_SUCCESS);
3344 test_truth(x == memcached_server_list_count(servers));
3345 }
3346
3347 rc= memcached_server_push(memc, servers);
3348 test_truth(rc == MEMCACHED_SUCCESS);
3349 rc= memcached_server_push(memc, servers);
3350 test_truth(rc == MEMCACHED_SUCCESS);
3351
3352 memcached_server_list_free(servers);
3353
3354 return TEST_SUCCESS;
3355 }
3356
3357 static test_return_t pre_nonblock(memcached_st *memc)
3358 {
3359 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3360
3361 return TEST_SUCCESS;
3362 }
3363
3364 static test_return_t pre_nonblock_binary(memcached_st *memc)
3365 {
3366 memcached_return_t rc= MEMCACHED_FAILURE;
3367 memcached_st *memc_clone;
3368
3369 memc_clone= memcached_clone(NULL, memc);
3370 test_truth(memc_clone);
3371 // The memcached_version needs to be done on a clone, because the server
3372 // will not toggle protocol on an connection.
3373 memcached_version(memc_clone);
3374
3375 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3376 {
3377 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3378 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3379 test_truth(rc == MEMCACHED_SUCCESS);
3380 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3381 }
3382 else
3383 {
3384 return TEST_SKIPPED;
3385 }
3386
3387 memcached_free(memc_clone);
3388
3389 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3390 }
3391
3392 static test_return_t pre_murmur(memcached_st *memc)
3393 {
3394 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3395
3396 return TEST_SUCCESS;
3397 }
3398
3399 static test_return_t pre_jenkins(memcached_st *memc)
3400 {
3401 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3402
3403 return TEST_SUCCESS;
3404 }
3405
3406
3407 static test_return_t pre_md5(memcached_st *memc)
3408 {
3409 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3410
3411 return TEST_SUCCESS;
3412 }
3413
3414 static test_return_t pre_crc(memcached_st *memc)
3415 {
3416 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3417
3418 return TEST_SUCCESS;
3419 }
3420
3421 static test_return_t pre_hsieh(memcached_st *memc)
3422 {
3423 #ifdef HAVE_HSIEH_HASH
3424 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3425 return TEST_SUCCESS;
3426 #else
3427 (void) memc;
3428 return TEST_SKIPPED;
3429 #endif
3430 }
3431
3432 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3433 {
3434 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3435
3436 return TEST_SUCCESS;
3437 }
3438
3439 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3440 {
3441 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3442
3443 return TEST_SUCCESS;
3444 }
3445
3446 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3447 {
3448 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3449
3450 return TEST_SUCCESS;
3451 }
3452
3453 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3454 {
3455 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3456
3457 return TEST_SUCCESS;
3458 }
3459
3460 static test_return_t pre_behavior_ketama(memcached_st *memc)
3461 {
3462 memcached_return_t rc;
3463 uint64_t value;
3464
3465 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3466 test_truth(rc == MEMCACHED_SUCCESS);
3467
3468 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3469 test_truth(value == 1);
3470
3471 return TEST_SUCCESS;
3472 }
3473
3474 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3475 {
3476 memcached_return_t rc;
3477 uint64_t value;
3478
3479 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3480 test_truth(rc == MEMCACHED_SUCCESS);
3481
3482 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3483 test_truth(value == 1);
3484
3485 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3486 test_truth(rc == MEMCACHED_SUCCESS);
3487
3488 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3489 test_truth(value == MEMCACHED_HASH_MD5);
3490
3491 return TEST_SUCCESS;
3492 }
3493
3494 /**
3495 @note This should be testing to see if the server really supports the binary protocol.
3496 */
3497 static test_return_t pre_binary(memcached_st *memc)
3498 {
3499 memcached_return_t rc= MEMCACHED_FAILURE;
3500 memcached_st *memc_clone;
3501
3502 memc_clone= memcached_clone(NULL, memc);
3503 test_truth(memc_clone);
3504 // The memcached_version needs to be done on a clone, because the server
3505 // will not toggle protocol on an connection.
3506 memcached_version(memc_clone);
3507
3508 if (memc_clone->hosts[0].major_version >= 1 && memc_clone->hosts[0].minor_version > 2)
3509 {
3510 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3511 test_truth(rc == MEMCACHED_SUCCESS);
3512 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3513 }
3514
3515 memcached_free(memc_clone);
3516
3517 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3518 }
3519
3520
3521 static test_return_t pre_replication(memcached_st *memc)
3522 {
3523 test_return_t test_rc;
3524 test_rc= pre_binary(memc);
3525
3526 if (test_rc != TEST_SUCCESS)
3527 return test_rc;
3528
3529 /*
3530 * Make sure that we store the item on all servers
3531 * (master + replicas == number of servers)
3532 */
3533 memcached_return_t rc;
3534 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3535 memcached_server_count(memc) - 1);
3536 test_truth(rc == MEMCACHED_SUCCESS);
3537 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3538
3539 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3540 }
3541
3542
3543 static test_return_t pre_replication_noblock(memcached_st *memc)
3544 {
3545 test_return_t rc;
3546
3547 rc= pre_replication(memc);
3548 if (rc != TEST_SUCCESS)
3549 return rc;
3550
3551 rc= pre_nonblock(memc);
3552
3553 return rc;
3554 }
3555
3556
3557 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3558 {
3559 #ifdef HARD_MALLOC_TESTS
3560 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3561 free(real_ptr);
3562 #else
3563 free(mem);
3564 #endif
3565 }
3566
3567
3568 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3569 {
3570 #ifdef HARD_MALLOC_TESTS
3571 void *ret= malloc(size + 8);
3572 if (ret != NULL)
3573 {
3574 ret= (void*)((caddr_t)ret + 8);
3575 }
3576 #else
3577 void *ret= malloc(size);
3578 #endif
3579
3580 if (ret != NULL)
3581 {
3582 memset(ret, 0xff, size);
3583 }
3584
3585 return ret;
3586 }
3587
3588
3589 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3590 {
3591 #ifdef HARD_MALLOC_TESTS
3592 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3593 void *nmem= realloc(real_ptr, size + 8);
3594
3595 void *ret= NULL;
3596 if (nmem != NULL)
3597 {
3598 ret= (void*)((caddr_t)nmem + 8);
3599 }
3600
3601 return ret;
3602 #else
3603 return realloc(mem, size);
3604 #endif
3605 }
3606
3607
3608 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3609 {
3610 #ifdef HARD_MALLOC_TESTS
3611 void *mem= my_malloc(ptr, nelem * size);
3612 if (mem)
3613 {
3614 memset(mem, 0, nelem * size);
3615 }
3616
3617 return mem;
3618 #else
3619 return calloc(nelem, size);
3620 #endif
3621 }
3622
3623
3624 static test_return_t set_prefix(memcached_st *memc)
3625 {
3626 memcached_return_t rc;
3627 const char *key= "mine";
3628 char *value;
3629
3630 /* Make sure be default none exists */
3631 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3632 test_truth(rc == MEMCACHED_FAILURE);
3633
3634 /* Test a clean set */
3635 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3636 test_truth(rc == MEMCACHED_SUCCESS);
3637
3638 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3639 test_truth(memcmp(value, key, 4) == 0);
3640 test_truth(rc == MEMCACHED_SUCCESS);
3641
3642 /* Test that we can turn it off */
3643 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3644 test_truth(rc == MEMCACHED_SUCCESS);
3645
3646 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3647 test_truth(rc == MEMCACHED_FAILURE);
3648
3649 /* Now setup for main test */
3650 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3651 test_truth(rc == MEMCACHED_SUCCESS);
3652
3653 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3654 test_truth(rc == MEMCACHED_SUCCESS);
3655 test_truth(memcmp(value, key, 4) == 0);
3656
3657 /* Set to Zero, and then Set to something too large */
3658 {
3659 char long_key[255];
3660 memset(long_key, 0, 255);
3661
3662 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3663 test_truth(rc == MEMCACHED_SUCCESS);
3664
3665 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3666 test_truth(rc == MEMCACHED_FAILURE);
3667 test_truth(value == NULL);
3668
3669 /* Test a long key for failure */
3670 /* TODO, extend test to determine based on setting, what result should be */
3671 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3672 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3673 //test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3674 test_truth(rc == MEMCACHED_SUCCESS);
3675
3676 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3677 strcpy(long_key, "This is more then the allotted number of characters");
3678 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3679 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3680
3681 /* Test for a bad prefix, but with a short key */
3682 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3683 test_truth(rc == MEMCACHED_SUCCESS);
3684
3685 strcpy(long_key, "dog cat");
3686 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3687 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3688 }
3689
3690 return TEST_SUCCESS;
3691 }
3692
3693
3694 #ifdef MEMCACHED_ENABLE_DEPRECATED
3695 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3696 {
3697 void *test_ptr= NULL;
3698 void *cb_ptr= NULL;
3699 {
3700 memcached_malloc_fn malloc_cb=
3701 (memcached_malloc_fn)my_malloc;
3702 cb_ptr= *(void **)&malloc_cb;
3703 memcached_return_t rc;
3704
3705 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3706 test_truth(rc == MEMCACHED_SUCCESS);
3707 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3708 test_truth(rc == MEMCACHED_SUCCESS);
3709 test_truth(test_ptr == cb_ptr);
3710 }
3711
3712 {
3713 memcached_realloc_fn realloc_cb=
3714 (memcached_realloc_fn)my_realloc;
3715 cb_ptr= *(void **)&realloc_cb;
3716 memcached_return_t rc;
3717
3718 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3719 test_truth(rc == MEMCACHED_SUCCESS);
3720 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3721 test_truth(rc == MEMCACHED_SUCCESS);
3722 test_truth(test_ptr == cb_ptr);
3723 }
3724
3725 {
3726 memcached_free_fn free_cb=
3727 (memcached_free_fn)my_free;
3728 cb_ptr= *(void **)&free_cb;
3729 memcached_return_t rc;
3730
3731 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3732 test_truth(rc == MEMCACHED_SUCCESS);
3733 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3734 test_truth(rc == MEMCACHED_SUCCESS);
3735 test_truth(test_ptr == cb_ptr);
3736 }
3737
3738 return TEST_SUCCESS;
3739 }
3740 #endif
3741
3742
3743 static test_return_t set_memory_alloc(memcached_st *memc)
3744 {
3745 memcached_return_t rc;
3746 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3747 my_realloc, my_calloc);
3748 test_truth(rc == MEMCACHED_FAILURE);
3749
3750 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3751 my_realloc, my_calloc);
3752
3753 memcached_malloc_fn mem_malloc;
3754 memcached_free_fn mem_free;
3755 memcached_realloc_fn mem_realloc;
3756 memcached_calloc_fn mem_calloc;
3757 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3758 &mem_realloc, &mem_calloc);
3759
3760 test_truth(mem_malloc == my_malloc);
3761 test_truth(mem_realloc == my_realloc);
3762 test_truth(mem_calloc == my_calloc);
3763 test_truth(mem_free == my_free);
3764
3765 return TEST_SUCCESS;
3766 }
3767
3768 static test_return_t enable_consistent_crc(memcached_st *memc)
3769 {
3770 test_return_t rc;
3771 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3772 memcached_hash_t hash;
3773 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3774 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3775 return rc;
3776
3777 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3778 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3779
3780 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3781
3782 if (hash != MEMCACHED_HASH_CRC)
3783 return TEST_SKIPPED;
3784
3785 return TEST_SUCCESS;
3786 }
3787
3788 static test_return_t enable_consistent_hsieh(memcached_st *memc)
3789 {
3790 test_return_t rc;
3791 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3792 memcached_hash_t hash;
3793 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3794 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3795 return rc;
3796
3797 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3798 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3799
3800 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3801
3802 if (hash != MEMCACHED_HASH_HSIEH)
3803 return TEST_SKIPPED;
3804
3805
3806 return TEST_SUCCESS;
3807 }
3808
3809 static test_return_t enable_cas(memcached_st *memc)
3810 {
3811 unsigned int set= 1;
3812
3813 memcached_version(memc);
3814
3815 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3816 || memc->hosts[0].minor_version > 2)
3817 {
3818 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3819
3820 return TEST_SUCCESS;
3821 }
3822
3823 return TEST_SKIPPED;
3824 }
3825
3826 static test_return_t check_for_1_2_3(memcached_st *memc)
3827 {
3828 memcached_version(memc);
3829
3830 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3831 || memc->hosts[0].minor_version > 2)
3832 return TEST_SUCCESS;
3833
3834 return TEST_SKIPPED;
3835 }
3836
3837 static test_return_t pre_unix_socket(memcached_st *memc)
3838 {
3839 memcached_return_t rc;
3840 struct stat buf;
3841
3842 memcached_servers_reset(memc);
3843
3844 if (stat("/tmp/memcached.socket", &buf))
3845 return TEST_SKIPPED;
3846
3847 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3848
3849 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
3850 }
3851
3852 static test_return_t pre_nodelay(memcached_st *memc)
3853 {
3854 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3855 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3856
3857 return TEST_SUCCESS;
3858 }
3859
3860 static test_return_t pre_settimer(memcached_st *memc)
3861 {
3862 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3863 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3864
3865 return TEST_SUCCESS;
3866 }
3867
3868 static test_return_t poll_timeout(memcached_st *memc)
3869 {
3870 size_t timeout;
3871
3872 timeout= 100;
3873
3874 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3875
3876 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3877
3878 test_truth(timeout == 100);
3879
3880 return TEST_SUCCESS;
3881 }
3882
3883 static test_return_t noreply_test(memcached_st *memc)
3884 {
3885 memcached_return_t ret;
3886 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3887 test_truth(ret == MEMCACHED_SUCCESS);
3888 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3889 test_truth(ret == MEMCACHED_SUCCESS);
3890 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3891 test_truth(ret == MEMCACHED_SUCCESS);
3892 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3893 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3894 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3895
3896 for (int count=0; count < 5; ++count)
3897 {
3898 for (int x=0; x < 100; ++x)
3899 {
3900 char key[10];
3901 size_t len= (size_t)sprintf(key, "%d", x);
3902 switch (count)
3903 {
3904 case 0:
3905 ret= memcached_add(memc, key, len, key, len, 0, 0);
3906 break;
3907 case 1:
3908 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3909 break;
3910 case 2:
3911 ret= memcached_set(memc, key, len, key, len, 0, 0);
3912 break;
3913 case 3:
3914 ret= memcached_append(memc, key, len, key, len, 0, 0);
3915 break;
3916 case 4:
3917 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3918 break;
3919 default:
3920 test_truth(count);
3921 break;
3922 }
3923 test_truth(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3924 }
3925
3926 /*
3927 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3928 ** API and is _ONLY_ done this way to verify that the library works the
3929 ** way it is supposed to do!!!!
3930 */
3931 int no_msg=0;
3932 for (uint32_t x=0; x < memcached_server_count(memc); ++x)
3933 no_msg+=(int)(memc->hosts[x].cursor_active);
3934
3935 test_truth(no_msg == 0);
3936 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3937
3938 /*
3939 ** Now validate that all items was set properly!
3940 */
3941 for (int x=0; x < 100; ++x)
3942 {
3943 char key[10];
3944 size_t len= (size_t)sprintf(key, "%d", x);
3945 size_t length;
3946 uint32_t flags;
3947 char* value=memcached_get(memc, key, strlen(key),
3948 &length, &flags, &ret);
3949 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
3950 switch (count)
3951 {
3952 case 0: /* FALLTHROUGH */
3953 case 1: /* FALLTHROUGH */
3954 case 2:
3955 test_truth(strncmp(value, key, len) == 0);
3956 test_truth(len == length);
3957 break;
3958 case 3:
3959 test_truth(length == len * 2);
3960 break;
3961 case 4:
3962 test_truth(length == len * 3);
3963 break;
3964 default:
3965 test_truth(count);
3966 break;
3967 }
3968 free(value);
3969 }
3970 }
3971
3972 /* Try setting an illegal cas value (should not return an error to
3973 * the caller (because we don't expect a return message from the server)
3974 */
3975 const char* keys[]= {"0"};
3976 size_t lengths[]= {1};
3977 size_t length;
3978 uint32_t flags;
3979 memcached_result_st results_obj;
3980 memcached_result_st *results;
3981 ret= memcached_mget(memc, keys, lengths, 1);
3982 test_truth(ret == MEMCACHED_SUCCESS);
3983
3984 results= memcached_result_create(memc, &results_obj);
3985 test_truth(results);
3986 results= memcached_fetch_result(memc, &results_obj, &ret);
3987 test_truth(results);
3988 test_truth(ret == MEMCACHED_SUCCESS);
3989 uint64_t cas= memcached_result_cas(results);
3990 memcached_result_free(&results_obj);
3991
3992 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3993 test_truth(ret == MEMCACHED_SUCCESS);
3994
3995 /*
3996 * The item will have a new cas value, so try to set it again with the old
3997 * value. This should fail!
3998 */
3999 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4000 test_truth(ret == MEMCACHED_SUCCESS);
4001 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4002 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4003 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
4004 free(value);
4005
4006 return TEST_SUCCESS;
4007 }
4008
4009 static test_return_t analyzer_test(memcached_st *memc)
4010 {
4011 memcached_return_t rc;
4012 memcached_stat_st *memc_stat;
4013 memcached_analysis_st *report;
4014
4015 memc_stat= memcached_stat(memc, NULL, &rc);
4016 test_truth(rc == MEMCACHED_SUCCESS);
4017 test_truth(memc_stat);
4018
4019 report= memcached_analyze(memc, memc_stat, &rc);
4020 test_truth(rc == MEMCACHED_SUCCESS);
4021 test_truth(report);
4022
4023 free(report);
4024 memcached_stat_free(NULL, memc_stat);
4025
4026 return TEST_SUCCESS;
4027 }
4028
4029 /* Count the objects */
4030 static memcached_return_t callback_dump_counter(memcached_st *ptr __attribute__((unused)),
4031 const char *key __attribute__((unused)),
4032 size_t key_length __attribute__((unused)),
4033 void *context)
4034 {
4035 uint32_t *counter= (uint32_t *)context;
4036
4037 *counter= *counter + 1;
4038
4039 return MEMCACHED_SUCCESS;
4040 }
4041
4042 static test_return_t dump_test(memcached_st *memc)
4043 {
4044 memcached_return_t rc;
4045 uint32_t counter= 0;
4046 memcached_dump_fn callbacks[1];
4047 test_return_t main_rc;
4048
4049 callbacks[0]= &callback_dump_counter;
4050
4051 /* No support for Binary protocol yet */
4052 if (memc->flags.binary_protocol)
4053 return TEST_SUCCESS;
4054
4055 main_rc= set_test3(memc);
4056
4057 test_truth (main_rc == TEST_SUCCESS);
4058
4059 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4060 test_truth(rc == MEMCACHED_SUCCESS);
4061
4062 /* We may have more then 32 if our previous flush has not completed */
4063 test_truth(counter >= 32);
4064
4065 return TEST_SUCCESS;
4066 }
4067
4068 #ifdef HAVE_LIBMEMCACHEDUTIL
4069 static void* connection_release(void *arg)
4070 {
4071 struct {
4072 memcached_pool_st* pool;
4073 memcached_st* mmc;
4074 } *resource= arg;
4075
4076 usleep(250);
4077 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4078 return arg;
4079 }
4080
4081 static test_return_t connection_pool_test(memcached_st *memc)
4082 {
4083 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
4084 test_truth(pool != NULL);
4085 memcached_st* mmc[10];
4086 memcached_return_t rc;
4087
4088 for (int x= 0; x < 10; ++x) {
4089 mmc[x]= memcached_pool_pop(pool, false, &rc);
4090 test_truth(mmc[x] != NULL);
4091 test_truth(rc == MEMCACHED_SUCCESS);
4092 }
4093
4094 test_truth(memcached_pool_pop(pool, false, &rc) == NULL);
4095 test_truth(rc == MEMCACHED_SUCCESS);
4096
4097 pthread_t tid;
4098 struct {
4099 memcached_pool_st* pool;
4100 memcached_st* mmc;
4101 } item= { .pool = pool, .mmc = mmc[9] };
4102 pthread_create(&tid, NULL, connection_release, &item);
4103 mmc[9]= memcached_pool_pop(pool, true, &rc);
4104 test_truth(rc == MEMCACHED_SUCCESS);
4105 pthread_join(tid, NULL);
4106 test_truth(mmc[9] == item.mmc);
4107 const char *key= "key";
4108 size_t keylen= strlen(key);
4109
4110 // verify that I can do ops with all connections
4111 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4112 test_truth(rc == MEMCACHED_SUCCESS);
4113
4114 for (unsigned int x= 0; x < 10; ++x) {
4115 uint64_t number_value;
4116 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4117 test_truth(rc == MEMCACHED_SUCCESS);
4118 test_truth(number_value == (x+1));
4119 }
4120
4121 // Release them..
4122 for (int x= 0; x < 10; ++x)
4123 test_truth(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4124
4125
4126 /* verify that I can set behaviors on the pool when I don't have all
4127 * of the connections in the pool. It should however be enabled
4128 * when I push the item into the pool
4129 */
4130 mmc[0]= memcached_pool_pop(pool, false, &rc);
4131 test_truth(mmc[0] != NULL);
4132
4133 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4134 test_truth(rc == MEMCACHED_SUCCESS);
4135
4136 mmc[1]= memcached_pool_pop(pool, false, &rc);
4137 test_truth(mmc[1] != NULL);
4138
4139 test_truth(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4140 test_truth(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4141 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4142
4143 mmc[0]= memcached_pool_pop(pool, false, &rc);
4144 test_truth(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4145 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4146
4147
4148 test_truth(memcached_pool_destroy(pool) == memc);
4149 return TEST_SUCCESS;
4150 }
4151 #endif
4152
4153 static test_return_t replication_set_test(memcached_st *memc)
4154 {
4155 memcached_return_t rc;
4156 memcached_st *memc_clone= memcached_clone(NULL, memc);
4157 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4158
4159 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4160 test_truth(rc == MEMCACHED_SUCCESS);
4161
4162 /*
4163 ** We are using the quiet commands to store the replicas, so we need
4164 ** to ensure that all of them are processed before we can continue.
4165 ** In the test we go directly from storing the object to trying to
4166 ** receive the object from all of the different servers, so we
4167 ** could end up in a race condition (the memcached server hasn't yet
4168 ** processed the quiet command from the replication set when it process
4169 ** the request from the other client (created by the clone)). As a
4170 ** workaround for that we call memcached_quit to send the quit command
4171 ** to the server and wait for the response ;-) If you use the test code
4172 ** as an example for your own code, please note that you shouldn't need
4173 ** to do this ;-)
4174 */
4175 memcached_quit(memc);
4176
4177 /*
4178 ** "bubba" should now be stored on all of our servers. We don't have an
4179 ** easy to use API to address each individual server, so I'll just iterate
4180 ** through a bunch of "master keys" and I should most likely hit all of the
4181 ** servers...
4182 */
4183 for (int x= 'a'; x <= 'z'; ++x)
4184 {
4185 char key[2]= { [0]= (char)x };
4186 size_t len;
4187 uint32_t flags;
4188 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4189 &len, &flags, &rc);
4190 test_truth(rc == MEMCACHED_SUCCESS);
4191 test_truth(val != NULL);
4192 free(val);
4193 }
4194
4195 memcached_free(memc_clone);
4196
4197 return TEST_SUCCESS;
4198 }
4199
4200 static test_return_t replication_get_test(memcached_st *memc)
4201 {
4202 memcached_return_t rc;
4203
4204 /*
4205 * Don't do the following in your code. I am abusing the internal details
4206 * within the library, and this is not a supported interface.
4207 * This is to verify correct behavior in the library
4208 */
4209 for (uint32_t host= 0; host < memcached_server_count(memc); ++host)
4210 {
4211 memcached_st *memc_clone= memcached_clone(NULL, memc);
4212 memc_clone->hosts[host].port= 0;
4213
4214 for (int x= 'a'; x <= 'z'; ++x)
4215 {
4216 char key[2]= { [0]= (char)x };
4217 size_t len;
4218 uint32_t flags;
4219 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4220 &len, &flags, &rc);
4221 test_truth(rc == MEMCACHED_SUCCESS);
4222 test_truth(val != NULL);
4223 free(val);
4224 }
4225
4226 memcached_free(memc_clone);
4227 }
4228
4229 return TEST_SUCCESS;
4230 }
4231
4232 static test_return_t replication_mget_test(memcached_st *memc)
4233 {
4234 memcached_return_t rc;
4235 memcached_st *memc_clone= memcached_clone(NULL, memc);
4236 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4237
4238 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4239 size_t len[]= { 5, 4, 4, 4 };
4240
4241 for (int x=0; x< 4; ++x)
4242 {
4243 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4244 test_truth(rc == MEMCACHED_SUCCESS);
4245 }
4246
4247 /*
4248 ** We are using the quiet commands to store the replicas, so we need
4249 ** to ensure that all of them are processed before we can continue.
4250 ** In the test we go directly from storing the object to trying to
4251 ** receive the object from all of the different servers, so we
4252 ** could end up in a race condition (the memcached server hasn't yet
4253 ** processed the quiet command from the replication set when it process
4254 ** the request from the other client (created by the clone)). As a
4255 ** workaround for that we call memcached_quit to send the quit command
4256 ** to the server and wait for the response ;-) If you use the test code
4257 ** as an example for your own code, please note that you shouldn't need
4258 ** to do this ;-)
4259 */
4260 memcached_quit(memc);
4261
4262 /*
4263 * Don't do the following in your code. I am abusing the internal details
4264 * within the library, and this is not a supported interface.
4265 * This is to verify correct behavior in the library
4266 */
4267 memcached_result_st result_obj;
4268 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4269 {
4270 memcached_st *new_clone= memcached_clone(NULL, memc);
4271 new_clone->hosts[host].port= 0;
4272
4273 for (int x= 'a'; x <= 'z'; ++x)
4274 {
4275 const char key[2]= { [0]= (const char)x };
4276
4277 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4278 test_truth(rc == MEMCACHED_SUCCESS);
4279
4280 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4281 test_truth(results);
4282
4283 int hits= 0;
4284 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4285 {
4286 hits++;
4287 }
4288 test_truth(hits == 4);
4289 memcached_result_free(&result_obj);
4290 }
4291
4292 memcached_free(new_clone);
4293 }
4294
4295 memcached_free(memc_clone);
4296
4297 return TEST_SUCCESS;
4298 }
4299
4300 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4301 {
4302 memcached_result_st result_obj;
4303 memcached_return_t rc;
4304 memcached_st *memc_clone= memcached_clone(NULL, memc);
4305 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4306 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4307
4308 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4309 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4310
4311 for (int x=0; x< 7; ++x)
4312 {
4313 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4314 test_truth(rc == MEMCACHED_SUCCESS);
4315 }
4316
4317 memcached_quit(memc);
4318
4319 for (int x=0; x< 7; ++x) {
4320 const char key[2]= { [0]= (const char)x };
4321
4322 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4323 test_truth(rc == MEMCACHED_SUCCESS);
4324
4325 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4326 test_truth(results);
4327
4328 int hits= 0;
4329 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4330 {
4331 ++hits;
4332 }
4333 test_truth(hits == 7);
4334 memcached_result_free(&result_obj);
4335 }
4336 memcached_free(memc_clone);
4337 return TEST_SUCCESS;
4338 }
4339
4340 static test_return_t replication_delete_test(memcached_st *memc)
4341 {
4342 memcached_return_t rc;
4343 memcached_st *memc_clone= memcached_clone(NULL, memc);
4344 /* Delete the items from all of the servers except 1 */
4345 uint64_t repl= memcached_behavior_get(memc,
4346 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4347 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4348
4349 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4350 size_t len[]= { 5, 4, 4, 4 };
4351
4352 for (int x=0; x< 4; ++x)
4353 {
4354 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4355 test_truth(rc == MEMCACHED_SUCCESS);
4356 }
4357
4358 /*
4359 * Don't do the following in your code. I am abusing the internal details
4360 * within the library, and this is not a supported interface.
4361 * This is to verify correct behavior in the library
4362 */
4363 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4364 for (uint32_t x= 0; x < (repl + 1); ++x)
4365 {
4366 memc_clone->hosts[hash].port= 0;
4367 if (++hash == memc_clone->number_of_hosts)
4368 hash= 0;
4369 }
4370
4371 memcached_result_st result_obj;
4372 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4373 {
4374 for (int x= 'a'; x <= 'z'; ++x)
4375 {
4376 const char key[2]= { [0]= (const char)x };
4377
4378 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4379 test_truth(rc == MEMCACHED_SUCCESS);
4380
4381 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4382 test_truth(results);
4383
4384 int hits= 0;
4385 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4386 {
4387 ++hits;
4388 }
4389 test_truth(hits == 4);
4390 memcached_result_free(&result_obj);
4391 }
4392 }
4393 memcached_free(memc_clone);
4394
4395 return TEST_SUCCESS;
4396 }
4397
4398 static void increment_request_id(uint16_t *id)
4399 {
4400 (*id)++;
4401 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4402 *id= 0;
4403 }
4404
4405 static uint16_t *get_udp_request_ids(memcached_st *memc)
4406 {
4407 uint16_t *ids= malloc(sizeof(uint16_t) * memcached_server_count(memc));
4408 assert(ids != NULL);
4409 unsigned int x;
4410
4411 for (x= 0; x < memcached_server_count(memc); x++)
4412 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
4413
4414 return ids;
4415 }
4416
4417 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4418 {
4419 unsigned int x;
4420 memcached_server_st *cur_server = memc->hosts;
4421 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4422
4423 for (x= 0; x < memcached_server_count(memc); x++)
4424 {
4425 test_truth(cur_server[x].cursor_active == 0);
4426 test_truth(cur_req_ids[x] == expected_req_ids[x]);
4427 }
4428 free(expected_req_ids);
4429 free(cur_req_ids);
4430
4431 return TEST_SUCCESS;
4432 }
4433
4434 /*
4435 ** There is a little bit of a hack here, instead of removing
4436 ** the servers, I just set num host to 0 and them add then new udp servers
4437 **/
4438 static test_return_t init_udp(memcached_st *memc)
4439 {
4440 memcached_version(memc);
4441 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4442 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
4443 || memc->hosts[0].micro_version < 6)
4444 return TEST_SKIPPED;
4445
4446 uint32_t num_hosts= memcached_server_count(memc);
4447 unsigned int x= 0;
4448 memcached_server_st servers[num_hosts];
4449 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
4450 for (x= 0; x < num_hosts; x++)
4451 memcached_server_free(&memc->hosts[x]);
4452
4453 memc->number_of_hosts= 0;
4454 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4455 for (x= 0; x < num_hosts; x++)
4456 {
4457 test_truth(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4458 test_truth(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4459 }
4460
4461 return TEST_SUCCESS;
4462 }
4463
4464 static test_return_t binary_init_udp(memcached_st *memc)
4465 {
4466 test_return_t test_rc;
4467 test_rc= pre_binary(memc);
4468
4469 if (test_rc != TEST_SUCCESS)
4470 return test_rc;
4471
4472 return init_udp(memc);
4473 }
4474
4475 /* Make sure that I cant add a tcp server to a udp client */
4476 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4477 {
4478 memcached_server_st server;
4479 memcached_server_clone(&server, &memc->hosts[0]);
4480 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4481 test_truth(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4482 return TEST_SUCCESS;
4483 }
4484
4485 /* Make sure that I cant add a udp server to a tcp client */
4486 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4487 {
4488 memcached_server_st server;
4489 memcached_server_clone(&server, &memc->hosts[0]);
4490 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4491
4492 memcached_st tcp_client;
4493 memcached_create(&tcp_client);
4494 test_truth(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4495
4496 return TEST_SUCCESS;
4497 }
4498
4499 static test_return_t set_udp_behavior_test(memcached_st *memc)
4500 {
4501
4502 memcached_quit(memc);
4503 memc->number_of_hosts= 0;
4504 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, memc->distribution);
4505 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4506 test_truth(memc->flags.use_udp);
4507 test_truth(memc->flags.no_reply);
4508
4509 test_truth(memcached_server_count(memc) == 0);
4510
4511 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4512 test_truth(! (memc->flags.use_udp));
4513 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4514 test_truth(! (memc->flags.no_reply));
4515
4516 return TEST_SUCCESS;
4517 }
4518
4519 static test_return_t udp_set_test(memcached_st *memc)
4520 {
4521 unsigned int x= 0;
4522 unsigned int num_iters= 1025; //request id rolls over at 1024
4523 for (x= 0; x < num_iters;x++)
4524 {
4525 memcached_return_t rc;
4526 const char *key= "foo";
4527 const char *value= "when we sanitize";
4528 uint16_t *expected_ids= get_udp_request_ids(memc);
4529 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
4530 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4531 rc= memcached_set(memc, key, strlen(key),
4532 value, strlen(value),
4533 (time_t)0, (uint32_t)0);
4534 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4535 /** NB, the check below assumes that if new write_ptr is less than
4536 * the original write_ptr that we have flushed. For large payloads, this
4537 * maybe an invalid assumption, but for the small payload we have it is OK
4538 */
4539 if (rc == MEMCACHED_SUCCESS ||
4540 memc->hosts[server_key].write_buffer_offset < init_offset)
4541 increment_request_id(&expected_ids[server_key]);
4542
4543 if (rc == MEMCACHED_SUCCESS)
4544 {
4545 test_truth(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4546 }
4547 else
4548 {
4549 test_truth(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4550 test_truth(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4551 }
4552 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4553 }
4554 return TEST_SUCCESS;
4555 }
4556
4557 static test_return_t udp_buffered_set_test(memcached_st *memc)
4558 {
4559 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4560 return udp_set_test(memc);
4561 }
4562
4563 static test_return_t udp_set_too_big_test(memcached_st *memc)
4564 {
4565 memcached_return_t rc;
4566 const char *key= "bar";
4567 char value[MAX_UDP_DATAGRAM_LENGTH];
4568 uint16_t *expected_ids= get_udp_request_ids(memc);
4569 rc= memcached_set(memc, key, strlen(key),
4570 value, MAX_UDP_DATAGRAM_LENGTH,
4571 (time_t)0, (uint32_t)0);
4572 test_truth(rc == MEMCACHED_WRITE_FAILURE);
4573 return post_udp_op_check(memc,expected_ids);
4574 }
4575
4576 static test_return_t udp_delete_test(memcached_st *memc)
4577 {
4578 unsigned int x= 0;
4579 unsigned int num_iters= 1025; //request id rolls over at 1024
4580 for (x= 0; x < num_iters;x++)
4581 {
4582 memcached_return_t rc;
4583 const char *key= "foo";
4584 uint16_t *expected_ids=get_udp_request_ids(memc);
4585 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4586 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
4587 rc= memcached_delete(memc, key, strlen(key), 0);
4588 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4589 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
4590 increment_request_id(&expected_ids[server_key]);
4591 if (rc == MEMCACHED_SUCCESS)
4592 {
4593 test_truth(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4594 }
4595 else
4596 {
4597 test_truth(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4598 test_truth(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4599 }
4600 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4601 }
4602 return TEST_SUCCESS;
4603 }
4604
4605 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4606 {
4607 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4608 return udp_delete_test(memc);
4609 }
4610
4611 static test_return_t udp_verbosity_test(memcached_st *memc)
4612 {
4613 memcached_return_t rc;
4614 uint16_t *expected_ids= get_udp_request_ids(memc);
4615 unsigned int x;
4616 for (x= 0; x < memcached_server_count(memc); x++)
4617 increment_request_id(&expected_ids[x]);
4618
4619 rc= memcached_verbosity(memc,3);
4620 test_truth(rc == MEMCACHED_SUCCESS);
4621 return post_udp_op_check(memc,expected_ids);
4622 }
4623
4624 static test_return_t udp_quit_test(memcached_st *memc)
4625 {
4626 uint16_t *expected_ids= get_udp_request_ids(memc);
4627 memcached_quit(memc);
4628 return post_udp_op_check(memc, expected_ids);
4629 }
4630
4631 static test_return_t udp_flush_test(memcached_st *memc)
4632 {
4633 memcached_return_t rc;
4634 uint16_t *expected_ids= get_udp_request_ids(memc);
4635 unsigned int x;
4636 for (x= 0; x < memcached_server_count(memc);x++)
4637 increment_request_id(&expected_ids[x]);
4638
4639 rc= memcached_flush(memc,0);
4640 test_truth(rc == MEMCACHED_SUCCESS);
4641 return post_udp_op_check(memc,expected_ids);
4642 }
4643
4644 static test_return_t udp_incr_test(memcached_st *memc)
4645 {
4646 memcached_return_t rc;
4647 const char *key= "incr";
4648 const char *value= "1";
4649 rc= memcached_set(memc, key, strlen(key),
4650 value, strlen(value),
4651 (time_t)0, (uint32_t)0);
4652
4653 test_truth(rc == MEMCACHED_SUCCESS);
4654 uint16_t *expected_ids= get_udp_request_ids(memc);
4655 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4656 increment_request_id(&expected_ids[server_key]);
4657 uint64_t newvalue;
4658 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4659 test_truth(rc == MEMCACHED_SUCCESS);
4660 return post_udp_op_check(memc, expected_ids);
4661 }
4662
4663 static test_return_t udp_decr_test(memcached_st *memc)
4664 {
4665 memcached_return_t rc;
4666 const char *key= "decr";
4667 const char *value= "1";
4668 rc= memcached_set(memc, key, strlen(key),
4669 value, strlen(value),
4670 (time_t)0, (uint32_t)0);
4671
4672 test_truth(rc == MEMCACHED_SUCCESS);
4673 uint16_t *expected_ids= get_udp_request_ids(memc);
4674 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4675 increment_request_id(&expected_ids[server_key]);
4676 uint64_t newvalue;
4677 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4678 test_truth(rc == MEMCACHED_SUCCESS);
4679 return post_udp_op_check(memc, expected_ids);
4680 }
4681
4682
4683 static test_return_t udp_stat_test(memcached_st *memc)
4684 {
4685 memcached_stat_st * rv= NULL;
4686 memcached_return_t rc;
4687 char args[]= "";
4688 uint16_t *expected_ids = get_udp_request_ids(memc);
4689 rv = memcached_stat(memc, args, &rc);
4690 free(rv);
4691 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4692 return post_udp_op_check(memc, expected_ids);
4693 }
4694
4695 static test_return_t udp_version_test(memcached_st *memc)
4696 {
4697 memcached_return_t rc;
4698 uint16_t *expected_ids = get_udp_request_ids(memc);
4699 rc = memcached_version(memc);
4700 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4701 return post_udp_op_check(memc, expected_ids);
4702 }
4703
4704 static test_return_t udp_get_test(memcached_st *memc)
4705 {
4706 memcached_return_t rc;
4707 const char *key= "foo";
4708 size_t vlen;
4709 uint16_t *expected_ids = get_udp_request_ids(memc);
4710 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4711 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4712 test_truth(val == NULL);
4713 return post_udp_op_check(memc, expected_ids);
4714 }
4715
4716 static test_return_t udp_mixed_io_test(memcached_st *memc)
4717 {
4718 test_st current_op;
4719 test_st mixed_io_ops [] ={
4720 {"udp_set_test", 0,
4721 (test_callback_fn)udp_set_test},
4722 {"udp_set_too_big_test", 0,
4723 (test_callback_fn)udp_set_too_big_test},
4724 {"udp_delete_test", 0,
4725 (test_callback_fn)udp_delete_test},
4726 {"udp_verbosity_test", 0,
4727 (test_callback_fn)udp_verbosity_test},
4728 {"udp_quit_test", 0,
4729 (test_callback_fn)udp_quit_test},
4730 {"udp_flush_test", 0,
4731 (test_callback_fn)udp_flush_test},
4732 {"udp_incr_test", 0,
4733 (test_callback_fn)udp_incr_test},
4734 {"udp_decr_test", 0,
4735 (test_callback_fn)udp_decr_test},
4736 {"udp_version_test", 0,
4737 (test_callback_fn)udp_version_test}
4738 };
4739 unsigned int x= 0;
4740 for (x= 0; x < 500; x++)
4741 {
4742 current_op= mixed_io_ops[random() % 9];
4743 test_truth(current_op.test_fn(memc) == TEST_SUCCESS);
4744 }
4745 return TEST_SUCCESS;
4746 }
4747
4748 #if 0
4749 static test_return_t hash_sanity_test (memcached_st *memc)
4750 {
4751 (void)memc;
4752
4753 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4754 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4755 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4756 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4757 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4758 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4759 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4760 #ifdef HAVE_HSIEH_HASH
4761 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4762 #endif
4763 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4764 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4765 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4766
4767 return TEST_SUCCESS;
4768 }
4769 #endif
4770
4771 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4772 {
4773 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4774 #ifdef HAVE_HSIEH_HASH
4775 expected_rc= MEMCACHED_SUCCESS;
4776 #endif
4777 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4778 (uint64_t)MEMCACHED_HASH_HSIEH);
4779 test_truth(rc == expected_rc);
4780 return TEST_SUCCESS;
4781 }
4782
4783 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4784 {
4785 uint32_t x;
4786 const char **ptr;
4787
4788 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4789 {
4790 uint32_t hash_val;
4791
4792 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4793 test_truth(md5_values[x] == hash_val);
4794 }
4795
4796 return TEST_SUCCESS;
4797 }
4798
4799 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4800 {
4801 uint32_t x;
4802 const char **ptr;
4803
4804 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4805 {
4806 uint32_t hash_val;
4807
4808 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4809 test_truth(crc_values[x] == hash_val);
4810 }
4811
4812 return TEST_SUCCESS;
4813 }
4814
4815 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4816 {
4817 uint32_t x;
4818 const char **ptr;
4819
4820 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4821 {
4822 uint32_t hash_val;
4823
4824 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4825 test_truth(fnv1_64_values[x] == hash_val);
4826 }
4827
4828 return TEST_SUCCESS;
4829 }
4830
4831 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4832 {
4833 uint32_t x;
4834 const char **ptr;
4835
4836 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4837 {
4838 uint32_t hash_val;
4839
4840 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4841 test_truth(fnv1a_64_values[x] == hash_val);
4842 }
4843
4844 return TEST_SUCCESS;
4845 }
4846
4847 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4848 {
4849 uint32_t x;
4850 const char **ptr;
4851
4852
4853 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4854 {
4855 uint32_t hash_val;
4856
4857 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4858 test_truth(fnv1_32_values[x] == hash_val);
4859 }
4860
4861 return TEST_SUCCESS;
4862 }
4863
4864 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4865 {
4866 uint32_t x;
4867 const char **ptr;
4868
4869 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4870 {
4871 uint32_t hash_val;
4872
4873 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4874 test_truth(fnv1a_32_values[x] == hash_val);
4875 }
4876
4877 return TEST_SUCCESS;
4878 }
4879
4880 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4881 {
4882 uint32_t x;
4883 const char **ptr;
4884
4885 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4886 {
4887 uint32_t hash_val;
4888
4889 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4890 test_truth(hsieh_values[x] == hash_val);
4891 }
4892
4893 return TEST_SUCCESS;
4894 }
4895
4896 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4897 {
4898 #ifdef __sparc
4899 return TEST_SKIPPED;
4900 #else
4901 uint32_t x;
4902 const char **ptr;
4903
4904 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4905 {
4906 uint32_t hash_val;
4907
4908 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4909 test_truth(murmur_values[x] == hash_val);
4910 }
4911
4912 return TEST_SUCCESS;
4913 #endif
4914 }
4915
4916 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4917 {
4918 uint32_t x;
4919 const char **ptr;
4920
4921
4922 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4923 {
4924 uint32_t hash_val;
4925
4926 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4927 test_truth(jenkins_values[x] == hash_val);
4928 }
4929
4930 return TEST_SUCCESS;
4931 }
4932
4933
4934 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4935 {
4936 memcached_return_t rc;
4937 uint64_t value;
4938 int x;
4939 memcached_server_st *server_pool;
4940 memcached_st *memc;
4941
4942 (void)trash;
4943
4944 memc= memcached_create(NULL);
4945 test_truth(memc);
4946
4947 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4948 test_truth(rc == MEMCACHED_SUCCESS);
4949
4950 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4951 test_truth(value == 1);
4952
4953 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
4954 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
4955
4956
4957 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");
4958 memcached_server_push(memc, server_pool);
4959
4960 /* verify that the server list was parsed okay. */
4961 test_truth(memcached_server_count(memc) == 8);
4962 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4963 test_truth(server_pool[0].port == 11211);
4964 test_truth(server_pool[0].weight == 600);
4965 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4966 test_truth(server_pool[2].port == 11211);
4967 test_truth(server_pool[2].weight == 200);
4968 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4969 test_truth(server_pool[7].port == 11211);
4970 test_truth(server_pool[7].weight == 100);
4971
4972 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4973 * us test the boundary wraparound.
4974 */
4975 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4976
4977 /* verify the standard ketama set. */
4978 for (x= 0; x < 99; x++)
4979 {
4980 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4981 char *hostname = memc->hosts[server_idx].hostname;
4982
4983 test_strcmp(hostname, ketama_test_cases[x].server);
4984 }
4985
4986 memcached_server_list_free(server_pool);
4987 memcached_free(memc);
4988
4989 return TEST_SUCCESS;
4990 }
4991
4992 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4993 {
4994 memcached_return_t rc;
4995 uint64_t value;
4996 int x;
4997 memcached_server_st *server_pool;
4998 memcached_st *memc;
4999
5000 (void)trash;
5001
5002 memc= memcached_create(NULL);
5003 test_truth(memc);
5004
5005 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5006 test_truth(rc == MEMCACHED_SUCCESS);
5007
5008 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5009 test_truth(value == 1);
5010
5011 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
5012 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
5013
5014 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");
5015 memcached_server_push(memc, server_pool);
5016
5017 /* verify that the server list was parsed okay. */
5018 test_truth(memcached_server_count(memc) == 8);
5019 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5020 test_truth(server_pool[0].port == 11211);
5021 test_truth(server_pool[0].weight == 600);
5022 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5023 test_truth(server_pool[2].port == 11211);
5024 test_truth(server_pool[2].weight == 200);
5025 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5026 test_truth(server_pool[7].port == 11211);
5027 test_truth(server_pool[7].weight == 100);
5028
5029 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5030 * us test the boundary wraparound.
5031 */
5032 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5033
5034 /* verify the standard ketama set. */
5035 for (x= 0; x < 99; x++)
5036 {
5037 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5038 char *hostname = memc->hosts[server_idx].hostname;
5039 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5040 }
5041
5042 memcached_server_list_free(server_pool);
5043 memcached_free(memc);
5044
5045 return TEST_SUCCESS;
5046 }
5047
5048 static test_return_t regression_bug_434484(memcached_st *memc)
5049 {
5050 test_return_t test_rc;
5051 test_rc= pre_binary(memc);
5052
5053 if (test_rc != TEST_SUCCESS)
5054 return test_rc;
5055
5056 memcached_return_t ret;
5057 const char *key= "regression_bug_434484";
5058 size_t keylen= strlen(key);
5059
5060 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5061 test_truth(ret == MEMCACHED_NOTSTORED);
5062
5063 size_t size= 2048 * 1024;
5064 void *data= calloc(1, size);
5065 test_truth(data != NULL);
5066 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5067 test_truth(ret == MEMCACHED_E2BIG);
5068 free(data);
5069
5070 return TEST_SUCCESS;
5071 }
5072
5073 static test_return_t regression_bug_434843(memcached_st *memc)
5074 {
5075 test_return_t test_rc;
5076 test_rc= pre_binary(memc);
5077
5078 if (test_rc != TEST_SUCCESS)
5079 return test_rc;
5080
5081 memcached_return_t rc;
5082 unsigned int counter= 0;
5083 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5084
5085 /*
5086 * I only want to hit only _one_ server so I know the number of requests I'm
5087 * sending in the pipleine to the server. Let's try to do a multiget of
5088 * 1024 (that should satisfy most users don't you think?). Future versions
5089 * will include a mget_execute function call if you need a higher number.
5090 */
5091 uint32_t number_of_hosts= memcached_server_count(memc);
5092 memc->number_of_hosts= 1;
5093 const size_t max_keys= 1024;
5094 char **keys= calloc(max_keys, sizeof(char*));
5095 size_t *key_length=calloc(max_keys, sizeof(size_t));
5096
5097 for (int x= 0; x < (int)max_keys; ++x)
5098 {
5099 char k[251];
5100 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5101 keys[x]= strdup(k);
5102 test_truth(keys[x] != NULL);
5103 }
5104
5105 /*
5106 * Run two times.. the first time we should have 100% cache miss,
5107 * and the second time we should have 100% cache hits
5108 */
5109 for (int y= 0; y < 2; ++y)
5110 {
5111 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5112 test_truth(rc == MEMCACHED_SUCCESS);
5113 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5114 if (y == 0)
5115 {
5116 /* The first iteration should give me a 100% cache miss. verify that*/
5117 test_truth(counter == 0);
5118 char blob[1024]= { 0 };
5119 for (int x= 0; x < (int)max_keys; ++x)
5120 {
5121 rc= memcached_add(memc, keys[x], key_length[x],
5122 blob, sizeof(blob), 0, 0);
5123 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5124 }
5125 }
5126 else
5127 {
5128 /* Verify that we received all of the key/value pairs */
5129 test_truth(counter == (unsigned int)max_keys);
5130 }
5131 }
5132
5133 /* Release allocated resources */
5134 for (size_t x= 0; x < max_keys; ++x)
5135 free(keys[x]);
5136 free(keys);
5137 free(key_length);
5138
5139 memc->number_of_hosts= number_of_hosts;
5140
5141 return TEST_SUCCESS;
5142 }
5143
5144 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5145 {
5146 memcached_return_t rc;
5147 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5148 test_truth(rc == MEMCACHED_SUCCESS);
5149
5150 return regression_bug_434843(memc);
5151 }
5152
5153 static test_return_t regression_bug_421108(memcached_st *memc)
5154 {
5155 memcached_return_t rc;
5156 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5157 test_truth(rc == MEMCACHED_SUCCESS);
5158
5159 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5160 test_truth(rc == MEMCACHED_SUCCESS);
5161 test_truth(bytes != NULL);
5162 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5163 "bytes_read", &rc);
5164 test_truth(rc == MEMCACHED_SUCCESS);
5165 test_truth(bytes_read != NULL);
5166
5167 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5168 "bytes_written", &rc);
5169 test_truth(rc == MEMCACHED_SUCCESS);
5170 test_truth(bytes_written != NULL);
5171
5172 test_truth(strcmp(bytes, bytes_read) != 0);
5173 test_truth(strcmp(bytes, bytes_written) != 0);
5174
5175 /* Release allocated resources */
5176 free(bytes);
5177 free(bytes_read);
5178 free(bytes_written);
5179 memcached_stat_free(NULL, memc_stat);
5180
5181 return TEST_SUCCESS;
5182 }
5183
5184 /*
5185 * The test case isn't obvious so I should probably document why
5186 * it works the way it does. Bug 442914 was caused by a bug
5187 * in the logic in memcached_purge (it did not handle the case
5188 * where the number of bytes sent was equal to the watermark).
5189 * In this test case, create messages so that we hit that case
5190 * and then disable noreply mode and issue a new command to
5191 * verify that it isn't stuck. If we change the format for the
5192 * delete command or the watermarks, we need to update this
5193 * test....
5194 */
5195 static test_return_t regression_bug_442914(memcached_st *memc)
5196 {
5197 memcached_return_t rc;
5198 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5199 test_truth(rc == MEMCACHED_SUCCESS);
5200 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5201
5202 uint32_t number_of_hosts= memcached_server_count(memc);
5203 memc->number_of_hosts= 1;
5204
5205 char k[250];
5206 size_t len;
5207
5208 for (int x= 0; x < 250; ++x)
5209 {
5210 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5211 rc= memcached_delete(memc, k, len, 0);
5212 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5213 }
5214
5215 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
5216 rc= memcached_delete(memc, k, len, 0);
5217 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5218
5219 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5220 test_truth(rc == MEMCACHED_SUCCESS);
5221 rc= memcached_delete(memc, k, len, 0);
5222 test_truth(rc == MEMCACHED_NOTFOUND);
5223
5224 memc->number_of_hosts= number_of_hosts;
5225
5226 return TEST_SUCCESS;
5227 }
5228
5229 static test_return_t regression_bug_447342(memcached_st *memc)
5230 {
5231 if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5232 return TEST_SKIPPED;
5233
5234 memcached_return_t rc;
5235
5236 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5237 test_truth(rc == MEMCACHED_SUCCESS);
5238
5239 const size_t max_keys= 100;
5240 char **keys= calloc(max_keys, sizeof(char*));
5241 size_t *key_length=calloc(max_keys, sizeof(size_t));
5242
5243 for (int x= 0; x < (int)max_keys; ++x)
5244 {
5245 char k[251];
5246 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5247 keys[x]= strdup(k);
5248 test_truth(keys[x] != NULL);
5249 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5250 test_truth(rc == MEMCACHED_SUCCESS);
5251 }
5252
5253 /*
5254 ** We are using the quiet commands to store the replicas, so we need
5255 ** to ensure that all of them are processed before we can continue.
5256 ** In the test we go directly from storing the object to trying to
5257 ** receive the object from all of the different servers, so we
5258 ** could end up in a race condition (the memcached server hasn't yet
5259 ** processed the quiet command from the replication set when it process
5260 ** the request from the other client (created by the clone)). As a
5261 ** workaround for that we call memcached_quit to send the quit command
5262 ** to the server and wait for the response ;-) If you use the test code
5263 ** as an example for your own code, please note that you shouldn't need
5264 ** to do this ;-)
5265 */
5266 memcached_quit(memc);
5267
5268 /* Verify that all messages are stored, and we didn't stuff too much
5269 * into the servers
5270 */
5271 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5272 test_truth(rc == MEMCACHED_SUCCESS);
5273
5274 unsigned int counter= 0;
5275 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5276 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5277 /* Verify that we received all of the key/value pairs */
5278 test_truth(counter == (unsigned int)max_keys);
5279
5280 memcached_quit(memc);
5281 /*
5282 * Don't do the following in your code. I am abusing the internal details
5283 * within the library, and this is not a supported interface.
5284 * This is to verify correct behavior in the library. Fake that two servers
5285 * are dead..
5286 */
5287 in_port_t port0= memc->hosts[0].port;
5288 in_port_t port2= memc->hosts[2].port;
5289
5290 memc->hosts[0].port= 0;
5291 memc->hosts[2].port= 0;
5292
5293 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5294 test_truth(rc == MEMCACHED_SUCCESS);
5295
5296 counter= 0;
5297 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5298 test_truth(counter == (unsigned int)max_keys);
5299
5300 /* restore the memc handle */
5301 memc->hosts[0].port= port0;
5302 memc->hosts[2].port= port2;
5303
5304 memcached_quit(memc);
5305
5306 /* Remove half of the objects */
5307 for (int x= 0; x < (int)max_keys; ++x)
5308 {
5309 if (x & 1)
5310 {
5311 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5312 test_truth(rc == MEMCACHED_SUCCESS);
5313 }
5314 }
5315
5316 memcached_quit(memc);
5317 memc->hosts[0].port= 0;
5318 memc->hosts[2].port= 0;
5319
5320 /* now retry the command, this time we should have cache misses */
5321 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5322 test_truth(rc == MEMCACHED_SUCCESS);
5323
5324 counter= 0;
5325 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5326 test_truth(counter == (unsigned int)(max_keys >> 1));
5327
5328 /* Release allocated resources */
5329 for (size_t x= 0; x < max_keys; ++x)
5330 free(keys[x]);
5331 free(keys);
5332 free(key_length);
5333
5334 /* restore the memc handle */
5335 memc->hosts[0].port= port0;
5336 memc->hosts[2].port= port2;
5337
5338 return TEST_SUCCESS;
5339 }
5340
5341 static test_return_t regression_bug_463297(memcached_st *memc)
5342 {
5343 memcached_st *memc_clone= memcached_clone(NULL, memc);
5344 test_truth(memc_clone != NULL);
5345 test_truth(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5346
5347 if (memc_clone->hosts[0].major_version > 1 ||
5348 (memc_clone->hosts[0].major_version == 1 &&
5349 memc_clone->hosts[0].minor_version > 2))
5350 {
5351 /* Binary protocol doesn't support deferred delete */
5352 memcached_st *bin_clone= memcached_clone(NULL, memc);
5353 test_truth(bin_clone != NULL);
5354 test_truth(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5355 test_truth(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5356 memcached_free(bin_clone);
5357
5358 memcached_quit(memc_clone);
5359
5360 /* If we know the server version, deferred delete should fail
5361 * with invalid arguments */
5362 test_truth(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5363
5364 /* If we don't know the server version, we should get a protocol error */
5365 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5366
5367 /* but there is a bug in some of the memcached servers (1.4) that treats
5368 * the counter as noreply so it doesn't send the proper error message
5369 */
5370 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5371
5372 /* And buffered mode should be disabled and we should get protocol error */
5373 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5374 rc= memcached_delete(memc, "foo", 3, 1);
5375 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5376
5377 /* Same goes for noreply... */
5378 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5379 rc= memcached_delete(memc, "foo", 3, 1);
5380 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5381
5382 /* but a normal request should go through (and be buffered) */
5383 test_truth((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5384 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5385
5386 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5387 /* unbuffered noreply should be success */
5388 test_truth(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5389 /* unbuffered with reply should be not found... */
5390 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5391 test_truth(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5392 }
5393
5394 memcached_free(memc_clone);
5395 return TEST_SUCCESS;
5396 }
5397
5398
5399 /* Test memcached_server_get_last_disconnect
5400 * For a working server set, shall be NULL
5401 * For a set of non existing server, shall not be NULL
5402 */
5403 static test_return_t test_get_last_disconnect(memcached_st *memc)
5404 {
5405 memcached_return_t rc;
5406 memcached_server_st *disconnected_server;
5407
5408 /* With the working set of server */
5409 const char *key= "marmotte";
5410 const char *value= "milka";
5411
5412 rc= memcached_set(memc, key, strlen(key),
5413 value, strlen(value),
5414 (time_t)0, (uint32_t)0);
5415 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5416
5417 disconnected_server = memcached_server_get_last_disconnect(memc);
5418 test_truth(disconnected_server == NULL);
5419
5420 /* With a non existing server */
5421 memcached_st *mine;
5422 memcached_server_st *servers;
5423
5424 const char *server_list= "localhost:9";
5425
5426 servers= memcached_servers_parse(server_list);
5427 test_truth(servers);
5428 mine= memcached_create(NULL);
5429 rc= memcached_server_push(mine, servers);
5430 test_truth(rc == MEMCACHED_SUCCESS);
5431 memcached_server_list_free(servers);
5432 test_truth(mine);
5433
5434 rc= memcached_set(mine, key, strlen(key),
5435 value, strlen(value),
5436 (time_t)0, (uint32_t)0);
5437 test_truth(rc != MEMCACHED_SUCCESS);
5438
5439 disconnected_server = memcached_server_get_last_disconnect(mine);
5440 test_truth(disconnected_server != NULL);
5441 test_truth(disconnected_server->port == 9);
5442 test_truth(strncmp(disconnected_server->hostname,"localhost",9) == 0);
5443
5444 memcached_quit(mine);
5445 memcached_free(mine);
5446
5447 return TEST_SUCCESS;
5448 }
5449
5450 /*
5451 * This test ensures that the failure counter isn't incremented during
5452 * normal termination of the memcached instance.
5453 */
5454 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5455 {
5456 memcached_return_t rc;
5457
5458 /* Set value to force connection to the server */
5459 const char *key= "marmotte";
5460 const char *value= "milka";
5461
5462 /*
5463 * Please note that I'm abusing the internal structures in libmemcached
5464 * in a non-portable way and you shouldn't be doing this. I'm only
5465 * doing this in order to verify that the library works the way it should
5466 */
5467 uint32_t number_of_hosts= memcached_server_count(memc);
5468 memc->number_of_hosts= 1;
5469
5470 /* Ensure that we are connected to the server by setting a value */
5471 rc= memcached_set(memc, key, strlen(key),
5472 value, strlen(value),
5473 (time_t)0, (uint32_t)0);
5474 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5475
5476
5477 /* The test is to see that the memcached_quit doesn't increase the
5478 * the server failure conter, so let's ensure that it is zero
5479 * before sending quit
5480 */
5481 memc->hosts[0].server_failure_counter= 0;
5482
5483 memcached_quit(memc);
5484
5485 /* Verify that it memcached_quit didn't increment the failure counter
5486 * Please note that this isn't bullet proof, because an error could
5487 * occur...
5488 */
5489 test_truth(memc->hosts[0].server_failure_counter == 0);
5490
5491 /* restore the instance */
5492 memc->number_of_hosts= number_of_hosts;
5493
5494 return TEST_SUCCESS;
5495 }
5496
5497 test_st udp_setup_server_tests[] ={
5498 {"set_udp_behavior_test", 0, (test_callback_fn)set_udp_behavior_test},
5499 {"add_tcp_server_udp_client_test", 0, (test_callback_fn)add_tcp_server_udp_client_test},
5500 {"add_udp_server_tcp_client_test", 0, (test_callback_fn)add_udp_server_tcp_client_test},
5501 {0, 0, 0}
5502 };
5503
5504 test_st upd_io_tests[] ={
5505 {"udp_set_test", 0, (test_callback_fn)udp_set_test},
5506 {"udp_buffered_set_test", 0, (test_callback_fn)udp_buffered_set_test},
5507 {"udp_set_too_big_test", 0, (test_callback_fn)udp_set_too_big_test},
5508 {"udp_delete_test", 0, (test_callback_fn)udp_delete_test},
5509 {"udp_buffered_delete_test", 0, (test_callback_fn)udp_buffered_delete_test},
5510 {"udp_verbosity_test", 0, (test_callback_fn)udp_verbosity_test},
5511 {"udp_quit_test", 0, (test_callback_fn)udp_quit_test},
5512 {"udp_flush_test", 0, (test_callback_fn)udp_flush_test},
5513 {"udp_incr_test", 0, (test_callback_fn)udp_incr_test},
5514 {"udp_decr_test", 0, (test_callback_fn)udp_decr_test},
5515 {"udp_stat_test", 0, (test_callback_fn)udp_stat_test},
5516 {"udp_version_test", 0, (test_callback_fn)udp_version_test},
5517 {"udp_get_test", 0, (test_callback_fn)udp_get_test},
5518 {"udp_mixed_io_test", 0, (test_callback_fn)udp_mixed_io_test},
5519 {0, 0, 0}
5520 };
5521
5522 /* Clean the server before beginning testing */
5523 test_st tests[] ={
5524 {"flush", 0, (test_callback_fn)flush_test },
5525 {"init", 0, (test_callback_fn)init_test },
5526 {"allocation", 0, (test_callback_fn)allocation_test },
5527 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5528 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5529 {"server_sort", 0, (test_callback_fn)server_sort_test},
5530 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5531 {"clone_test", 0, (test_callback_fn)clone_test },
5532 {"connection_test", 0, (test_callback_fn)connection_test},
5533 {"callback_test", 0, (test_callback_fn)callback_test},
5534 {"userdata_test", 0, (test_callback_fn)userdata_test},
5535 {"error", 0, (test_callback_fn)error_test },
5536 {"set", 0, (test_callback_fn)set_test },
5537 {"set2", 0, (test_callback_fn)set_test2 },
5538 {"set3", 0, (test_callback_fn)set_test3 },
5539 {"dump", 1, (test_callback_fn)dump_test},
5540 {"add", 1, (test_callback_fn)add_test },
5541 {"replace", 1, (test_callback_fn)replace_test },
5542 {"delete", 1, (test_callback_fn)delete_test },
5543 {"get", 1, (test_callback_fn)get_test },
5544 {"get2", 0, (test_callback_fn)get_test2 },
5545 {"get3", 0, (test_callback_fn)get_test3 },
5546 {"get4", 0, (test_callback_fn)get_test4 },
5547 {"partial mget", 0, (test_callback_fn)get_test5 },
5548 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5549 {"increment", 0, (test_callback_fn)increment_test },
5550 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5551 {"decrement", 0, (test_callback_fn)decrement_test },
5552 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5553 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5554 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5555 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5556 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5557 {"quit", 0, (test_callback_fn)quit_test },
5558 {"mget", 1, (test_callback_fn)mget_test },
5559 {"mget_result", 1, (test_callback_fn)mget_result_test },
5560 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5561 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5562 {"mget_execute", 1, (test_callback_fn)mget_execute },
5563 {"mget_end", 0, (test_callback_fn)mget_end },
5564 {"get_stats", 0, (test_callback_fn)get_stats },
5565 {"add_host_test", 0, (test_callback_fn)add_host_test },
5566 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5567 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5568 {"version_string_test", 0, (test_callback_fn)version_string_test},
5569 {"bad_key", 1, (test_callback_fn)bad_key_test },
5570 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
5571 {"read_through", 1, (test_callback_fn)read_through },
5572 {"delete_through", 1, (test_callback_fn)delete_through },
5573 {"noreply", 1, (test_callback_fn)noreply_test},
5574 {"analyzer", 1, (test_callback_fn)analyzer_test},
5575 #ifdef HAVE_LIBMEMCACHEDUTIL
5576 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
5577 #endif
5578 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
5579 {0, 0, 0}
5580 };
5581
5582 test_st behavior_tests[] ={
5583 {"behavior_test", 0, (test_callback_fn)behavior_test},
5584 {0, 0, 0}
5585 };
5586
5587 test_st async_tests[] ={
5588 {"add", 1, (test_callback_fn)add_wrapper },
5589 {0, 0, 0}
5590 };
5591
5592 test_st string_tests[] ={
5593 {"string static with null", 0, (test_callback_fn)string_static_null },
5594 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
5595 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
5596 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
5597 {"string append", 0, (test_callback_fn)string_alloc_append },
5598 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
5599 {0, 0, (test_callback_fn)0}
5600 };
5601
5602 test_st result_tests[] ={
5603 {"result static", 0, (test_callback_fn)result_static},
5604 {"result alloc", 0, (test_callback_fn)result_alloc},
5605 {0, 0, (test_callback_fn)0}
5606 };
5607
5608 test_st version_1_2_3[] ={
5609 {"append", 0, (test_callback_fn)append_test },
5610 {"prepend", 0, (test_callback_fn)prepend_test },
5611 {"cas", 0, (test_callback_fn)cas_test },
5612 {"cas2", 0, (test_callback_fn)cas2_test },
5613 {"append_binary", 0, (test_callback_fn)append_binary_test },
5614 {0, 0, (test_callback_fn)0}
5615 };
5616
5617 test_st user_tests[] ={
5618 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
5619 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
5620 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
5621 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
5622 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
5623 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
5624 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
5625 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
5626 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
5627 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
5628 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
5629 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
5630 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
5631 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
5632 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
5633 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
5634 #ifndef __sun
5635 /*
5636 ** It seems to be something weird with the character sets..
5637 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5638 ** guess I need to find out how this is supposed to work.. Perhaps I need
5639 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5640 ** so just disable the code for now...).
5641 */
5642 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
5643 #endif
5644 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
5645 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
5646 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
5647 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
5648 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
5649 {0, 0, (test_callback_fn)0}
5650 };
5651
5652 test_st replication_tests[]= {
5653 {"set", 1, (test_callback_fn)replication_set_test },
5654 {"get", 0, (test_callback_fn)replication_get_test },
5655 {"mget", 0, (test_callback_fn)replication_mget_test },
5656 {"delete", 0, (test_callback_fn)replication_delete_test },
5657 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
5658 {0, 0, (test_callback_fn)0}
5659 };
5660
5661 /*
5662 * The following test suite is used to verify that we don't introduce
5663 * regression bugs. If you want more information about the bug / test,
5664 * you should look in the bug report at
5665 * http://bugs.launchpad.net/libmemcached
5666 */
5667 test_st regression_tests[]= {
5668 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
5669 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
5670 {"lp:434843 buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
5671 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
5672 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
5673 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
5674 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
5675 {0, 0, (test_callback_fn)0}
5676 };
5677
5678 test_st ketama_compatibility[]= {
5679 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
5680 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
5681 {0, 0, (test_callback_fn)0}
5682 };
5683
5684 test_st generate_tests[] ={
5685 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5686 {"generate_data", 1, (test_callback_fn)generate_data },
5687 {"get_read", 0, (test_callback_fn)get_read },
5688 {"delete_generate", 0, (test_callback_fn)delete_generate },
5689 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5690 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
5691 {"generate_data", 1, (test_callback_fn)generate_data },
5692 {"mget_read", 0, (test_callback_fn)mget_read },
5693 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
5694 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
5695 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5696 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
5697 {"generate_data", 1, (test_callback_fn)generate_data },
5698 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5699 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5700 {0, 0, (test_callback_fn)0}
5701 };
5702
5703 test_st consistent_tests[] ={
5704 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5705 {"generate_data", 1, (test_callback_fn)generate_data },
5706 {"get_read", 0, (test_callback_fn)get_read_count },
5707 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5708 {0, 0, (test_callback_fn)0}
5709 };
5710
5711 test_st consistent_weighted_tests[] ={
5712 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5713 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
5714 {"get_read", 0, (test_callback_fn)get_read_count },
5715 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5716 {0, 0, (test_callback_fn)0}
5717 };
5718
5719 test_st hsieh_availability[] ={
5720 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
5721 {0, 0, (test_callback_fn)0}
5722 };
5723
5724 #if 0
5725 test_st hash_sanity[] ={
5726 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
5727 {0, 0, (test_callback_fn)0}
5728 };
5729 #endif
5730
5731 test_st ketama_auto_eject_hosts[] ={
5732 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
5733 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
5734 {0, 0, (test_callback_fn)0}
5735 };
5736
5737 test_st hash_tests[] ={
5738 {"md5", 0, (test_callback_fn)md5_run },
5739 {"crc", 0, (test_callback_fn)crc_run },
5740 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
5741 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
5742 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
5743 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
5744 {"hsieh", 0, (test_callback_fn)hsieh_run },
5745 {"murmur", 0, (test_callback_fn)murmur_run },
5746 {"jenkis", 0, (test_callback_fn)jenkins_run },
5747 {0, 0, (test_callback_fn)0}
5748 };
5749
5750 collection_st collection[] ={
5751 #if 0
5752 {"hash_sanity", 0, 0, hash_sanity},
5753 #endif
5754 {"hsieh_availability", 0, 0, hsieh_availability},
5755 {"udp_setup", (test_callback_fn)init_udp, 0, udp_setup_server_tests},
5756 {"udp_io", (test_callback_fn)init_udp, 0, upd_io_tests},
5757 {"udp_binary_io", (test_callback_fn)binary_init_udp, 0, upd_io_tests},
5758 {"block", 0, 0, tests},
5759 {"binary", (test_callback_fn)pre_binary, 0, tests},
5760 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
5761 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5762 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
5763 {"md5", (test_callback_fn)pre_md5, 0, tests},
5764 {"crc", (test_callback_fn)pre_crc, 0, tests},
5765 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
5766 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
5767 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
5768 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
5769 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
5770 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
5771 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
5772 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5773 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
5774 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5775 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
5776 {"gets", (test_callback_fn)enable_cas, 0, tests},
5777 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
5778 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
5779 #ifdef MEMCACHED_ENABLE_DEPRECATED
5780 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
5781 #endif
5782 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
5783 {"prefix", (test_callback_fn)set_prefix, 0, tests},
5784 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
5785 {"string", 0, 0, string_tests},
5786 {"result", 0, 0, result_tests},
5787 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
5788 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
5789 {"user", 0, 0, user_tests},
5790 {"generate", 0, 0, generate_tests},
5791 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
5792 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
5793 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
5794 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
5795 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
5796 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
5797 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
5798 {"consistent_not", 0, 0, consistent_tests},
5799 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
5800 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5801 {"ketama_compat", 0, 0, ketama_compatibility},
5802 {"test_hashes", 0, 0, hash_tests},
5803 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
5804 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
5805 {"regression", 0, 0, regression_tests},
5806 {"behaviors", 0, 0, behavior_tests},
5807 {0, 0, 0, 0}
5808 };
5809
5810 #define SERVERS_TO_CREATE 5
5811
5812 #include "libmemcached_world.h"
5813
5814 void get_world(world_st *world)
5815 {
5816 world->collections= collection;
5817
5818 world->create= (test_callback_create_fn)world_create;
5819 world->destroy= (test_callback_fn)world_destroy;
5820
5821 world->test.startup= (test_callback_fn)world_test_startup;
5822 world->test.flush= (test_callback_fn)world_flush;
5823 world->test.pre_run= (test_callback_fn)world_pre_run;
5824 world->test.post_run= (test_callback_fn)world_post_run;
5825 world->test.on_error= (test_callback_error_fn)world_on_error;
5826
5827 world->collection.startup= (test_callback_fn)world_container_startup;
5828 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
5829
5830 world->runner= &defualt_libmemcached_runner;
5831 }