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