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