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