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