Merge in patch for additional lib for SASL
[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, size_t *keys_returned)
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 *keys_returned= 0;
2067
2068 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2069 &return_value_length, &flags, &rc)))
2070 {
2071 test_true(return_value);
2072 test_true(rc == MEMCACHED_SUCCESS);
2073 free(return_value);
2074 *keys_returned= *keys_returned +1;
2075 }
2076
2077 test_true_got(rc == MEMCACHED_END || rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
2078
2079 return TEST_SUCCESS;
2080 }
2081
2082 /* Test case provided by Cal Haldenbrand */
2083 static test_return_t user_supplied_bug1(memcached_st *memc)
2084 {
2085 unsigned int setter= 1;
2086
2087 unsigned long long total= 0;
2088 uint32_t size= 0;
2089 char key[10];
2090 char randomstuff[6 * 1024];
2091 memcached_return_t rc;
2092
2093 memset(randomstuff, 0, 6 * 1024);
2094
2095 /* We just keep looking at the same values over and over */
2096 srandom(10);
2097
2098 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2099 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2100
2101
2102 /* add key */
2103 for (uint32_t x= 0 ; total < 20 * 1024576 ; x++ )
2104 {
2105 unsigned int j= 0;
2106
2107 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
2108 memset(randomstuff, 0, 6 * 1024);
2109 test_true(size < 6 * 1024); /* Being safe here */
2110
2111 for (j= 0 ; j < size ;j++)
2112 randomstuff[j] = (signed char) ((rand() % 26) + 97);
2113
2114 total += size;
2115 snprintf(key, sizeof(key), "%u", x);
2116 rc = memcached_set(memc, key, strlen(key),
2117 randomstuff, strlen(randomstuff), 10, 0);
2118 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2119 /* If we fail, lets try again */
2120 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
2121 rc = memcached_set(memc, key, strlen(key),
2122 randomstuff, strlen(randomstuff), 10, 0);
2123 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2124 }
2125
2126 return TEST_SUCCESS;
2127 }
2128
2129 /* Test case provided by Cal Haldenbrand */
2130 static test_return_t user_supplied_bug2(memcached_st *memc)
2131 {
2132 unsigned int setter;
2133 size_t total= 0;
2134
2135 setter= 1;
2136 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2137 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2138 #ifdef NOT_YET
2139 setter = 20 * 1024576;
2140 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2141 setter = 20 * 1024576;
2142 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2143 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2144 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2145
2146 for (x= 0, errors= 0; total < 20 * 1024576 ; x++)
2147 #endif
2148
2149 for (uint32_t x= 0, errors= 0; total < 24576 ; x++)
2150 {
2151 memcached_return_t rc= MEMCACHED_SUCCESS;
2152 char buffer[SMALL_STRING_LEN];
2153 uint32_t flags= 0;
2154 size_t val_len= 0;
2155 char *getval;
2156
2157 memset(buffer, 0, SMALL_STRING_LEN);
2158
2159 snprintf(buffer, sizeof(buffer), "%u", x);
2160 getval= memcached_get(memc, buffer, strlen(buffer),
2161 &val_len, &flags, &rc);
2162 if (rc != MEMCACHED_SUCCESS)
2163 {
2164 if (rc == MEMCACHED_NOTFOUND)
2165 errors++;
2166 else
2167 {
2168 test_true(rc);
2169 }
2170
2171 continue;
2172 }
2173 total+= val_len;
2174 errors= 0;
2175 free(getval);
2176 }
2177
2178 return TEST_SUCCESS;
2179 }
2180
2181 /* Do a large mget() over all the keys we think exist */
2182 #define KEY_COUNT 3000 // * 1024576
2183 static test_return_t user_supplied_bug3(memcached_st *memc)
2184 {
2185 memcached_return_t rc;
2186 unsigned int setter;
2187 unsigned int x;
2188 char **keys;
2189 size_t key_lengths[KEY_COUNT];
2190
2191 setter= 1;
2192 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2193 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2194 #ifdef NOT_YET
2195 setter = 20 * 1024576;
2196 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2197 setter = 20 * 1024576;
2198 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2199 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2200 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2201 #endif
2202
2203 keys= calloc(KEY_COUNT, sizeof(char *));
2204 test_true(keys);
2205 for (x= 0; x < KEY_COUNT; x++)
2206 {
2207 char buffer[30];
2208
2209 snprintf(buffer, 30, "%u", x);
2210 keys[x]= strdup(buffer);
2211 key_lengths[x]= strlen(keys[x]);
2212 }
2213
2214 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
2215 test_true(rc == MEMCACHED_SUCCESS);
2216
2217 size_t keys_returned;
2218 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
2219
2220 for (x= 0; x < KEY_COUNT; x++)
2221 free(keys[x]);
2222 free(keys);
2223
2224 return TEST_SUCCESS;
2225 }
2226
2227 /* Make sure we behave properly if server list has no values */
2228 static test_return_t user_supplied_bug4(memcached_st *memc)
2229 {
2230 memcached_return_t rc;
2231 const char *keys[]= {"fudge", "son", "food"};
2232 size_t key_length[]= {5, 3, 4};
2233 unsigned int x;
2234 uint32_t flags;
2235 char return_key[MEMCACHED_MAX_KEY];
2236 size_t return_key_length;
2237 char *return_value;
2238 size_t return_value_length;
2239
2240 /* Here we free everything before running a bunch of mget tests */
2241 memcached_servers_reset(memc);
2242
2243
2244 /* We need to empty the server before continueing test */
2245 rc= memcached_flush(memc, 0);
2246 test_true(rc == MEMCACHED_NO_SERVERS);
2247
2248 rc= memcached_mget(memc, keys, key_length, 3);
2249 test_true(rc == MEMCACHED_NO_SERVERS);
2250
2251 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2252 &return_value_length, &flags, &rc)) != NULL)
2253 {
2254 test_true(return_value);
2255 }
2256 test_true(!return_value);
2257 test_true(return_value_length == 0);
2258 test_true(rc == MEMCACHED_NO_SERVERS);
2259
2260 for (x= 0; x < 3; x++)
2261 {
2262 rc= memcached_set(memc, keys[x], key_length[x],
2263 keys[x], key_length[x],
2264 (time_t)50, (uint32_t)9);
2265 test_true(rc == MEMCACHED_NO_SERVERS);
2266 }
2267
2268 rc= memcached_mget(memc, keys, key_length, 3);
2269 test_true(rc == MEMCACHED_NO_SERVERS);
2270
2271 x= 0;
2272 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2273 &return_value_length, &flags, &rc)))
2274 {
2275 test_true(return_value);
2276 test_true(rc == MEMCACHED_SUCCESS);
2277 test_true(return_key_length == return_value_length);
2278 test_true(!memcmp(return_value, return_key, return_value_length));
2279 free(return_value);
2280 x++;
2281 }
2282
2283 return TEST_SUCCESS;
2284 }
2285
2286 #define VALUE_SIZE_BUG5 1048064
2287 static test_return_t user_supplied_bug5(memcached_st *memc)
2288 {
2289 memcached_return_t rc;
2290 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2291 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2292 char return_key[MEMCACHED_MAX_KEY];
2293 size_t return_key_length;
2294 char *value;
2295 size_t value_length;
2296 uint32_t flags;
2297 unsigned int count;
2298 unsigned int x;
2299 char insert_data[VALUE_SIZE_BUG5];
2300
2301 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2302 insert_data[x]= (signed char)rand();
2303
2304 memcached_flush(memc, 0);
2305 value= memcached_get(memc, keys[0], key_length[0],
2306 &value_length, &flags, &rc);
2307 test_true(value == NULL);
2308 rc= memcached_mget(memc, keys, key_length, 4);
2309
2310 count= 0;
2311 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2312 &value_length, &flags, &rc)))
2313 count++;
2314 test_true(count == 0);
2315
2316 for (x= 0; x < 4; x++)
2317 {
2318 rc= memcached_set(memc, keys[x], key_length[x],
2319 insert_data, VALUE_SIZE_BUG5,
2320 (time_t)0, (uint32_t)0);
2321 test_true(rc == MEMCACHED_SUCCESS);
2322 }
2323
2324 for (x= 0; x < 10; x++)
2325 {
2326 value= memcached_get(memc, keys[0], key_length[0],
2327 &value_length, &flags, &rc);
2328 test_true(value);
2329 free(value);
2330
2331 rc= memcached_mget(memc, keys, key_length, 4);
2332 count= 0;
2333 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2334 &value_length, &flags, &rc)))
2335 {
2336 count++;
2337 free(value);
2338 }
2339 test_true(count == 4);
2340 }
2341
2342 return TEST_SUCCESS;
2343 }
2344
2345 static test_return_t user_supplied_bug6(memcached_st *memc)
2346 {
2347 memcached_return_t rc;
2348 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2349 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2350 char return_key[MEMCACHED_MAX_KEY];
2351 size_t return_key_length;
2352 char *value;
2353 size_t value_length;
2354 uint32_t flags;
2355 unsigned int count;
2356 unsigned int x;
2357 char insert_data[VALUE_SIZE_BUG5];
2358
2359 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2360 insert_data[x]= (signed char)rand();
2361
2362 memcached_flush(memc, 0);
2363 value= memcached_get(memc, keys[0], key_length[0],
2364 &value_length, &flags, &rc);
2365 test_true(value == NULL);
2366 test_true(rc == MEMCACHED_NOTFOUND);
2367 rc= memcached_mget(memc, keys, key_length, 4);
2368 test_true(rc == MEMCACHED_SUCCESS);
2369
2370 count= 0;
2371 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2372 &value_length, &flags, &rc)))
2373 count++;
2374 test_true(count == 0);
2375 test_true(rc == MEMCACHED_END);
2376
2377 for (x= 0; x < 4; x++)
2378 {
2379 rc= memcached_set(memc, keys[x], key_length[x],
2380 insert_data, VALUE_SIZE_BUG5,
2381 (time_t)0, (uint32_t)0);
2382 test_true(rc == MEMCACHED_SUCCESS);
2383 }
2384
2385 for (x= 0; x < 2; x++)
2386 {
2387 value= memcached_get(memc, keys[0], key_length[0],
2388 &value_length, &flags, &rc);
2389 test_true(value);
2390 free(value);
2391
2392 rc= memcached_mget(memc, keys, key_length, 4);
2393 test_true(rc == MEMCACHED_SUCCESS);
2394 count= 3;
2395 /* We test for purge of partial complete fetches */
2396 for (count= 3; count; count--)
2397 {
2398 value= memcached_fetch(memc, return_key, &return_key_length,
2399 &value_length, &flags, &rc);
2400 test_true(rc == MEMCACHED_SUCCESS);
2401 test_true(!(memcmp(value, insert_data, value_length)));
2402 test_true(value_length);
2403 free(value);
2404 }
2405 }
2406
2407 return TEST_SUCCESS;
2408 }
2409
2410 static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused)))
2411 {
2412 memcached_return_t rc;
2413 memcached_st *mine;
2414 memcached_st *memc_clone;
2415
2416 memcached_server_st *servers;
2417 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";
2418
2419 servers= memcached_servers_parse(server_list);
2420 test_true(servers);
2421
2422 mine= memcached_create(NULL);
2423 rc= memcached_server_push(mine, servers);
2424 test_true(rc == MEMCACHED_SUCCESS);
2425 memcached_server_list_free(servers);
2426
2427 test_true(mine);
2428 memc_clone= memcached_clone(NULL, mine);
2429
2430 memcached_quit(mine);
2431 memcached_quit(memc_clone);
2432
2433
2434 memcached_free(mine);
2435 memcached_free(memc_clone);
2436
2437 return TEST_SUCCESS;
2438 }
2439
2440 /* Test flag store/retrieve */
2441 static test_return_t user_supplied_bug7(memcached_st *memc)
2442 {
2443 memcached_return_t rc;
2444 const char *keys= "036790384900";
2445 size_t key_length= strlen(keys);
2446 char return_key[MEMCACHED_MAX_KEY];
2447 size_t return_key_length;
2448 char *value;
2449 size_t value_length;
2450 uint32_t flags;
2451 unsigned int x;
2452 char insert_data[VALUE_SIZE_BUG5];
2453
2454 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2455 insert_data[x]= (signed char)rand();
2456
2457 memcached_flush(memc, 0);
2458
2459 flags= 245;
2460 rc= memcached_set(memc, keys, key_length,
2461 insert_data, VALUE_SIZE_BUG5,
2462 (time_t)0, flags);
2463 test_true(rc == MEMCACHED_SUCCESS);
2464
2465 flags= 0;
2466 value= memcached_get(memc, keys, key_length,
2467 &value_length, &flags, &rc);
2468 test_true(flags == 245);
2469 test_true(value);
2470 free(value);
2471
2472 rc= memcached_mget(memc, &keys, &key_length, 1);
2473
2474 flags= 0;
2475 value= memcached_fetch(memc, return_key, &return_key_length,
2476 &value_length, &flags, &rc);
2477 test_true(flags == 245);
2478 test_true(value);
2479 free(value);
2480
2481
2482 return TEST_SUCCESS;
2483 }
2484
2485 static test_return_t user_supplied_bug9(memcached_st *memc)
2486 {
2487 memcached_return_t rc;
2488 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2489 size_t key_length[3];
2490 unsigned int x;
2491 uint32_t flags;
2492 unsigned count= 0;
2493
2494 char return_key[MEMCACHED_MAX_KEY];
2495 size_t return_key_length;
2496 char *return_value;
2497 size_t return_value_length;
2498
2499
2500 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2501 key_length[1]= strlen("fudge&*@#");
2502 key_length[2]= strlen("for^#@&$not");
2503
2504
2505 for (x= 0; x < 3; x++)
2506 {
2507 rc= memcached_set(memc, keys[x], key_length[x],
2508 keys[x], key_length[x],
2509 (time_t)50, (uint32_t)9);
2510 test_true(rc == MEMCACHED_SUCCESS);
2511 }
2512
2513 rc= memcached_mget(memc, keys, key_length, 3);
2514 test_true(rc == MEMCACHED_SUCCESS);
2515
2516 /* We need to empty the server before continueing test */
2517 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2518 &return_value_length, &flags, &rc)) != NULL)
2519 {
2520 test_true(return_value);
2521 free(return_value);
2522 count++;
2523 }
2524 test_true(count == 3);
2525
2526 return TEST_SUCCESS;
2527 }
2528
2529 /* We are testing with aggressive timeout to get failures */
2530 static test_return_t user_supplied_bug10(memcached_st *memc)
2531 {
2532 const char *key= "foo";
2533 char *value;
2534 size_t value_length= 512;
2535 unsigned int x;
2536 size_t key_len= 3;
2537 memcached_return_t rc;
2538 unsigned int set= 1;
2539 memcached_st *mclone= memcached_clone(NULL, memc);
2540 int32_t timeout;
2541
2542 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2543 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2544 timeout= 2;
2545 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2546 (uint64_t)timeout);
2547
2548 value = (char*)malloc(value_length * sizeof(char));
2549
2550 for (x= 0; x < value_length; x++)
2551 value[x]= (char) (x % 127);
2552
2553 for (x= 1; x <= 100000; ++x)
2554 {
2555 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2556
2557 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2558 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2559
2560 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2561 x--;
2562 }
2563
2564 free(value);
2565 memcached_free(mclone);
2566
2567 return TEST_SUCCESS;
2568 }
2569
2570 /*
2571 We are looking failures in the async protocol
2572 */
2573 static test_return_t user_supplied_bug11(memcached_st *memc)
2574 {
2575 const char *key= "foo";
2576 char *value;
2577 size_t value_length= 512;
2578 unsigned int x;
2579 size_t key_len= 3;
2580 memcached_return_t rc;
2581 unsigned int set= 1;
2582 int32_t timeout;
2583 memcached_st *mclone= memcached_clone(NULL, memc);
2584
2585 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2586 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2587 timeout= -1;
2588 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2589 (size_t)timeout);
2590
2591 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2592
2593 test_true(timeout == -1);
2594
2595 value = (char*)malloc(value_length * sizeof(char));
2596
2597 for (x= 0; x < value_length; x++)
2598 value[x]= (char) (x % 127);
2599
2600 for (x= 1; x <= 100000; ++x)
2601 {
2602 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2603 }
2604
2605 free(value);
2606 memcached_free(mclone);
2607
2608 return TEST_SUCCESS;
2609 }
2610
2611 /*
2612 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2613 */
2614 static test_return_t user_supplied_bug12(memcached_st *memc)
2615 {
2616 memcached_return_t rc;
2617 uint32_t flags;
2618 size_t value_length;
2619 char *value;
2620 uint64_t number_value;
2621
2622 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2623 &value_length, &flags, &rc);
2624 test_true(value == NULL);
2625 test_true(rc == MEMCACHED_NOTFOUND);
2626
2627 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2628 1, &number_value);
2629
2630 test_true(value == NULL);
2631 /* The binary protocol will set the key if it doesn't exist */
2632 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2633 {
2634 test_true(rc == MEMCACHED_SUCCESS);
2635 }
2636 else
2637 {
2638 test_true(rc == MEMCACHED_NOTFOUND);
2639 }
2640
2641 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2642
2643 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2644 &value_length, &flags, &rc);
2645 test_true(value);
2646 test_true(rc == MEMCACHED_SUCCESS);
2647 free(value);
2648
2649 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2650 1, &number_value);
2651 test_true(number_value == 2);
2652 test_true(rc == MEMCACHED_SUCCESS);
2653
2654 return TEST_SUCCESS;
2655 }
2656
2657 /*
2658 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2659 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2660 */
2661 static test_return_t user_supplied_bug13(memcached_st *memc)
2662 {
2663 char key[] = "key34567890";
2664 char *overflow;
2665 memcached_return_t rc;
2666 size_t overflowSize;
2667
2668 char commandFirst[]= "set key34567890 0 0 ";
2669 char commandLast[] = " \r\n"; /* first line of command sent to server */
2670 size_t commandLength;
2671 size_t testSize;
2672
2673 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2674
2675 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2676
2677 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2678 {
2679 overflow= malloc(testSize);
2680 test_true(overflow != NULL);
2681
2682 memset(overflow, 'x', testSize);
2683 rc= memcached_set(memc, key, strlen(key),
2684 overflow, testSize, 0, 0);
2685 test_true(rc == MEMCACHED_SUCCESS);
2686 free(overflow);
2687 }
2688
2689 return TEST_SUCCESS;
2690 }
2691
2692
2693 /*
2694 Test values of many different sizes
2695 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2696 set key34567890 0 0 8169 \r\n
2697 is sent followed by buffer of size 8169, followed by 8169
2698 */
2699 static test_return_t user_supplied_bug14(memcached_st *memc)
2700 {
2701 size_t setter= 1;
2702 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2703 memcached_return_t rc;
2704 const char *key= "foo";
2705 char *value;
2706 size_t value_length= 18000;
2707 char *string;
2708 size_t string_length;
2709 uint32_t flags;
2710 unsigned int x;
2711 size_t current_length;
2712
2713 value = (char*)malloc(value_length);
2714 test_true(value);
2715
2716 for (x= 0; x < value_length; x++)
2717 value[x] = (char) (x % 127);
2718
2719 for (current_length= 0; current_length < value_length; current_length++)
2720 {
2721 rc= memcached_set(memc, key, strlen(key),
2722 value, current_length,
2723 (time_t)0, (uint32_t)0);
2724 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2725
2726 string= memcached_get(memc, key, strlen(key),
2727 &string_length, &flags, &rc);
2728
2729 test_true(rc == MEMCACHED_SUCCESS);
2730 test_true(string_length == current_length);
2731 test_true(!memcmp(string, value, string_length));
2732
2733 free(string);
2734 }
2735
2736 free(value);
2737
2738 return TEST_SUCCESS;
2739 }
2740
2741 /*
2742 Look for zero length value problems
2743 */
2744 static test_return_t user_supplied_bug15(memcached_st *memc)
2745 {
2746 uint32_t x;
2747 memcached_return_t rc;
2748 const char *key= "mykey";
2749 char *value;
2750 size_t length;
2751 uint32_t flags;
2752
2753 for (x= 0; x < 2; x++)
2754 {
2755 rc= memcached_set(memc, key, strlen(key),
2756 NULL, 0,
2757 (time_t)0, (uint32_t)0);
2758
2759 test_true(rc == MEMCACHED_SUCCESS);
2760
2761 value= memcached_get(memc, key, strlen(key),
2762 &length, &flags, &rc);
2763
2764 test_true(rc == MEMCACHED_SUCCESS);
2765 test_true(value == NULL);
2766 test_true(length == 0);
2767 test_true(flags == 0);
2768
2769 value= memcached_get(memc, key, strlen(key),
2770 &length, &flags, &rc);
2771
2772 test_true(rc == MEMCACHED_SUCCESS);
2773 test_true(value == NULL);
2774 test_true(length == 0);
2775 test_true(flags == 0);
2776 }
2777
2778 return TEST_SUCCESS;
2779 }
2780
2781 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2782 static test_return_t user_supplied_bug16(memcached_st *memc)
2783 {
2784 memcached_return_t rc;
2785 const char *key= "mykey";
2786 char *value;
2787 size_t length;
2788 uint32_t flags;
2789
2790 rc= memcached_set(memc, key, strlen(key),
2791 NULL, 0,
2792 (time_t)0, UINT32_MAX);
2793
2794 test_true(rc == MEMCACHED_SUCCESS);
2795
2796 value= memcached_get(memc, key, strlen(key),
2797 &length, &flags, &rc);
2798
2799 test_true(rc == MEMCACHED_SUCCESS);
2800 test_true(value == NULL);
2801 test_true(length == 0);
2802 test_true(flags == UINT32_MAX);
2803
2804 return TEST_SUCCESS;
2805 }
2806
2807 #if !defined(__sun) && !defined(__OpenBSD__)
2808 /* Check the validity of chinese key*/
2809 static test_return_t user_supplied_bug17(memcached_st *memc)
2810 {
2811 memcached_return_t rc;
2812 const char *key= "豆瓣";
2813 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2814 char *value2;
2815 size_t length;
2816 uint32_t flags;
2817
2818 rc= memcached_set(memc, key, strlen(key),
2819 value, strlen(value),
2820 (time_t)0, 0);
2821
2822 test_true(rc == MEMCACHED_SUCCESS);
2823
2824 value2= memcached_get(memc, key, strlen(key),
2825 &length, &flags, &rc);
2826
2827 test_true(length==strlen(value));
2828 test_true(rc == MEMCACHED_SUCCESS);
2829 test_true(memcmp(value, value2, length)==0);
2830 free(value2);
2831
2832 return TEST_SUCCESS;
2833 }
2834 #endif
2835
2836 /*
2837 From Andrei on IRC
2838 */
2839
2840 static test_return_t user_supplied_bug19(memcached_st *not_used)
2841 {
2842 memcached_st *memc;
2843 const memcached_server_st *server;
2844 memcached_return_t res;
2845
2846 (void)not_used;
2847
2848 memc= memcached_create(NULL);
2849 memcached_server_add_with_weight(memc, "localhost", 11311, 100);
2850 memcached_server_add_with_weight(memc, "localhost", 11312, 100);
2851
2852 server= memcached_server_by_key(memc, "a", 1, &res);
2853
2854 memcached_free(memc);
2855
2856 return TEST_SUCCESS;
2857 }
2858
2859 /* CAS test from Andei */
2860 static test_return_t user_supplied_bug20(memcached_st *memc)
2861 {
2862 memcached_return_t status;
2863 memcached_result_st *result, result_obj;
2864 const char *key = "abc";
2865 size_t key_len = strlen("abc");
2866 const char *value = "foobar";
2867 size_t value_len = strlen(value);
2868
2869 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2870
2871 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2872 test_true(status == MEMCACHED_SUCCESS);
2873
2874 status = memcached_mget(memc, &key, &key_len, 1);
2875 test_true(status == MEMCACHED_SUCCESS);
2876
2877 result= memcached_result_create(memc, &result_obj);
2878 test_true(result);
2879
2880 memcached_result_create(memc, &result_obj);
2881 result= memcached_fetch_result(memc, &result_obj, &status);
2882
2883 test_true(result);
2884 test_true(status == MEMCACHED_SUCCESS);
2885
2886 memcached_result_free(result);
2887
2888 return TEST_SUCCESS;
2889 }
2890
2891 #include "ketama_test_cases.h"
2892 static test_return_t user_supplied_bug18(memcached_st *trash)
2893 {
2894 memcached_return_t rc;
2895 uint64_t value;
2896 int x;
2897 memcached_server_st *server_pool;
2898 memcached_st *memc;
2899
2900 (void)trash;
2901
2902 memc= memcached_create(NULL);
2903 test_true(memc);
2904
2905 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2906 test_true(rc == MEMCACHED_SUCCESS);
2907
2908 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2909 test_true(value == 1);
2910
2911 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2912 test_true(rc == MEMCACHED_SUCCESS);
2913
2914 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2915 test_true(value == MEMCACHED_HASH_MD5);
2916
2917 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");
2918 memcached_server_push(memc, server_pool);
2919
2920 /* verify that the server list was parsed okay. */
2921 test_true(memcached_server_count(memc) == 8);
2922 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2923 test_true(server_pool[0].port == 11211);
2924 test_true(server_pool[0].weight == 600);
2925 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2926 test_true(server_pool[2].port == 11211);
2927 test_true(server_pool[2].weight == 200);
2928 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2929 test_true(server_pool[7].port == 11211);
2930 test_true(server_pool[7].weight == 100);
2931
2932 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2933 * us test the boundary wraparound.
2934 */
2935 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2936
2937 /* verify the standard ketama set. */
2938 for (x= 0; x < 99; x++)
2939 {
2940 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2941
2942 memcached_server_instance_st instance=
2943 memcached_server_instance_by_position(memc, server_idx);
2944
2945 const char *hostname = memcached_server_name(instance);
2946 test_strcmp(hostname, ketama_test_cases[x].server);
2947 }
2948
2949 memcached_server_list_free(server_pool);
2950 memcached_free(memc);
2951
2952 return TEST_SUCCESS;
2953 }
2954
2955 /* Large mget() of missing keys with binary proto
2956 *
2957 * If many binary quiet commands (such as getq's in an mget) fill the output
2958 * buffer and the server chooses not to respond, memcached_flush hangs. See
2959 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2960 */
2961
2962 /* sighandler_t function that always asserts false */
2963 static void fail(int unused __attribute__((unused)))
2964 {
2965 assert(0);
2966 }
2967
2968
2969 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2970 {
2971 #ifdef WIN32
2972 (void)memc;
2973 (void)key_count;
2974 return TEST_SKIPPED;
2975 #else
2976 memcached_return_t rc;
2977 unsigned int x;
2978 char **keys;
2979 size_t* key_lengths;
2980 void (*oldalarm)(int);
2981 memcached_st *memc_clone;
2982
2983 memc_clone= memcached_clone(NULL, memc);
2984 test_true(memc_clone);
2985
2986 /* only binproto uses getq for mget */
2987 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2988
2989 /* empty the cache to ensure misses (hence non-responses) */
2990 rc= memcached_flush(memc_clone, 0);
2991 test_true(rc == MEMCACHED_SUCCESS);
2992
2993 key_lengths= calloc(key_count, sizeof(size_t));
2994 keys= calloc(key_count, sizeof(char *));
2995 test_true(keys);
2996 for (x= 0; x < key_count; x++)
2997 {
2998 char buffer[30];
2999
3000 snprintf(buffer, 30, "%u", x);
3001 keys[x]= strdup(buffer);
3002 key_lengths[x]= strlen(keys[x]);
3003 }
3004
3005 oldalarm= signal(SIGALRM, fail);
3006 alarm(5);
3007
3008 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
3009 test_true(rc == MEMCACHED_SUCCESS);
3010
3011 alarm(0);
3012 signal(SIGALRM, oldalarm);
3013
3014 size_t keys_returned;
3015 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3016
3017 for (x= 0; x < key_count; x++)
3018 free(keys[x]);
3019 free(keys);
3020 free(key_lengths);
3021
3022 memcached_free(memc_clone);
3023
3024 return TEST_SUCCESS;
3025 #endif
3026 }
3027
3028 static test_return_t user_supplied_bug21(memcached_st *memc)
3029 {
3030 test_return_t test_rc;
3031 test_rc= pre_binary(memc);
3032
3033 if (test_rc != TEST_SUCCESS)
3034 return test_rc;
3035
3036 test_return_t rc;
3037
3038 /* should work as of r580 */
3039 rc= _user_supplied_bug21(memc, 10);
3040 test_true(rc == TEST_SUCCESS);
3041
3042 /* should fail as of r580 */
3043 rc= _user_supplied_bug21(memc, 1000);
3044 test_true(rc == TEST_SUCCESS);
3045
3046 return TEST_SUCCESS;
3047 }
3048
3049 static test_return_t auto_eject_hosts(memcached_st *trash)
3050 {
3051 (void) trash;
3052 memcached_server_instance_st instance;
3053
3054 memcached_return_t rc;
3055 memcached_st *memc= memcached_create(NULL);
3056 test_true(memc);
3057
3058 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3059 test_true(rc == MEMCACHED_SUCCESS);
3060
3061 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3062 test_true(value == 1);
3063
3064 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3065 test_true(rc == MEMCACHED_SUCCESS);
3066
3067 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3068 test_true(value == MEMCACHED_HASH_MD5);
3069
3070 /* server should be removed when in delay */
3071 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
3072 test_true(rc == MEMCACHED_SUCCESS);
3073
3074 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
3075 test_true(value == 1);
3076
3077 memcached_server_st *server_pool;
3078 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");
3079 memcached_server_push(memc, server_pool);
3080
3081 /* verify that the server list was parsed okay. */
3082 test_true(memcached_server_count(memc) == 8);
3083 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
3084 test_true(server_pool[0].port == 11211);
3085 test_true(server_pool[0].weight == 600);
3086 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
3087 test_true(server_pool[2].port == 11211);
3088 test_true(server_pool[2].weight == 200);
3089 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
3090 test_true(server_pool[7].port == 11211);
3091 test_true(server_pool[7].weight == 100);
3092
3093 instance= memcached_server_instance_by_position(memc, 2);
3094 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
3095 memc->next_distribution_rebuild= time(NULL) - 1;
3096
3097 /*
3098 This would not work if there were only two hosts.
3099 */
3100 for (size_t x= 0; x < 99; x++)
3101 {
3102 memcached_autoeject(memc);
3103 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3104 test_true(server_idx != 2);
3105 }
3106
3107 /* and re-added when it's back. */
3108 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
3109 memc->next_distribution_rebuild= time(NULL) - 1;
3110 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
3111 memc->distribution);
3112 for (size_t x= 0; x < 99; x++)
3113 {
3114 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3115 // We re-use instance from above.
3116 instance=
3117 memcached_server_instance_by_position(memc, server_idx);
3118 const char *hostname = memcached_server_name(instance);
3119 test_true(strcmp(hostname, ketama_test_cases[x].server) == 0);
3120 }
3121
3122 memcached_server_list_free(server_pool);
3123 memcached_free(memc);
3124
3125 return TEST_SUCCESS;
3126 }
3127
3128 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
3129 {
3130 (void) trash;
3131
3132 memcached_return_t rc;
3133 memcached_st *memc= memcached_create(NULL);
3134 test_true(memc);
3135
3136
3137 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3138 test_true(rc == MEMCACHED_SUCCESS);
3139
3140 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3141 test_true(value == 1);
3142
3143 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3144 test_true(rc == MEMCACHED_SUCCESS);
3145
3146 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3147 test_true(value == MEMCACHED_HASH_MD5);
3148
3149
3150 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
3151
3152 memcached_server_st *server_pool;
3153 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");
3154 memcached_server_push(memc, server_pool);
3155
3156 // @todo this needs to be refactored to actually test something.
3157 #if 0
3158 FILE *fp;
3159 if ((fp = fopen("ketama_keys.txt", "w")))
3160 {
3161 // noop
3162 } else {
3163 printf("cannot write to file ketama_keys.txt");
3164 return TEST_FAILURE;
3165 }
3166
3167 for (int x= 0; x < 10000; x++)
3168 {
3169 char key[10];
3170 snprintf(key, sizeof(key), "%d", x);
3171
3172 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3173 char *hostname = memc->hosts[server_idx].hostname;
3174 in_port_t port = memc->hosts[server_idx].port;
3175 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3176 memcached_server_instance_st instance=
3177 memcached_server_instance_by_position(memc, host_index);
3178 }
3179 fclose(fp);
3180 #endif
3181 memcached_server_list_free(server_pool);
3182 memcached_free(memc);
3183
3184 return TEST_SUCCESS;
3185 }
3186
3187
3188 static test_return_t result_static(memcached_st *memc)
3189 {
3190 memcached_result_st result;
3191 memcached_result_st *result_ptr;
3192
3193 result_ptr= memcached_result_create(memc, &result);
3194 test_true(result.options.is_allocated == false);
3195 test_true(memcached_is_initialized(&result) == true);
3196 test_true(result_ptr);
3197 test_true(result_ptr == &result);
3198
3199 memcached_result_free(&result);
3200
3201 test_true(result.options.is_allocated == false);
3202 test_true(memcached_is_initialized(&result) == false);
3203
3204 return TEST_SUCCESS;
3205 }
3206
3207 static test_return_t result_alloc(memcached_st *memc)
3208 {
3209 memcached_result_st *result_ptr;
3210
3211 result_ptr= memcached_result_create(memc, NULL);
3212 test_true(result_ptr);
3213 test_true(result_ptr->options.is_allocated == true);
3214 test_true(memcached_is_initialized(result_ptr) == true);
3215 memcached_result_free(result_ptr);
3216
3217 return TEST_SUCCESS;
3218 }
3219
3220 static test_return_t string_static_null(memcached_st *memc)
3221 {
3222 memcached_string_st string;
3223 memcached_string_st *string_ptr;
3224
3225 string_ptr= memcached_string_create(memc, &string, 0);
3226 test_true(string.options.is_initialized == true);
3227 test_true(string_ptr);
3228
3229 /* The following two better be the same! */
3230 test_true(memcached_is_allocated(string_ptr) == false);
3231 test_true(memcached_is_allocated(&string) == false);
3232 test_true(&string == string_ptr);
3233
3234 test_true(string.options.is_initialized == true);
3235 test_true(memcached_is_initialized(&string) == true);
3236 memcached_string_free(&string);
3237 test_true(memcached_is_initialized(&string) == false);
3238
3239 return TEST_SUCCESS;
3240 }
3241
3242 static test_return_t string_alloc_null(memcached_st *memc)
3243 {
3244 memcached_string_st *string;
3245
3246 string= memcached_string_create(memc, NULL, 0);
3247 test_true(string);
3248 test_true(memcached_is_allocated(string) == true);
3249 test_true(memcached_is_initialized(string) == true);
3250 memcached_string_free(string);
3251
3252 return TEST_SUCCESS;
3253 }
3254
3255 static test_return_t string_alloc_with_size(memcached_st *memc)
3256 {
3257 memcached_string_st *string;
3258
3259 string= memcached_string_create(memc, NULL, 1024);
3260 test_true(string);
3261 test_true(memcached_is_allocated(string) == true);
3262 test_true(memcached_is_initialized(string) == true);
3263 memcached_string_free(string);
3264
3265 return TEST_SUCCESS;
3266 }
3267
3268 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
3269 {
3270 memcached_string_st *string;
3271
3272 string= memcached_string_create(memc, NULL, SIZE_MAX);
3273 test_true(string == NULL);
3274
3275 return TEST_SUCCESS;
3276 }
3277
3278 static test_return_t string_alloc_append(memcached_st *memc)
3279 {
3280 unsigned int x;
3281 char buffer[SMALL_STRING_LEN];
3282 memcached_string_st *string;
3283
3284 /* Ring the bell! */
3285 memset(buffer, 6, SMALL_STRING_LEN);
3286
3287 string= memcached_string_create(memc, NULL, 100);
3288 test_true(string);
3289 test_true(memcached_is_allocated(string) == true);
3290 test_true(memcached_is_initialized(string) == true);
3291
3292 for (x= 0; x < 1024; x++)
3293 {
3294 memcached_return_t rc;
3295 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3296 test_true(rc == MEMCACHED_SUCCESS);
3297 }
3298 test_true(memcached_is_allocated(string) == true);
3299 memcached_string_free(string);
3300
3301 return TEST_SUCCESS;
3302 }
3303
3304 static test_return_t string_alloc_append_toobig(memcached_st *memc)
3305 {
3306 memcached_return_t rc;
3307 unsigned int x;
3308 char buffer[SMALL_STRING_LEN];
3309 memcached_string_st *string;
3310
3311 /* Ring the bell! */
3312 memset(buffer, 6, SMALL_STRING_LEN);
3313
3314 string= memcached_string_create(memc, NULL, 100);
3315 test_true(string);
3316 test_true(memcached_is_allocated(string) == true);
3317 test_true(memcached_is_initialized(string) == true);
3318
3319 for (x= 0; x < 1024; x++)
3320 {
3321 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3322 test_true(rc == MEMCACHED_SUCCESS);
3323 }
3324 rc= memcached_string_append(string, buffer, SIZE_MAX);
3325 test_true(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
3326 test_true(memcached_is_allocated(string) == true);
3327 memcached_string_free(string);
3328
3329 return TEST_SUCCESS;
3330 }
3331
3332 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
3333 {
3334 pairs_free(global_pairs);
3335
3336 return TEST_SUCCESS;
3337 }
3338
3339 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
3340 {
3341 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3342 global_count= GLOBAL_COUNT;
3343
3344 for (size_t x= 0; x < global_count; x++)
3345 {
3346 global_keys[x]= global_pairs[x].key;
3347 global_keys_length[x]= global_pairs[x].key_length;
3348 }
3349
3350 return TEST_SUCCESS;
3351 }
3352
3353 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
3354 {
3355 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3356 global_count= GLOBAL2_COUNT;
3357
3358 for (size_t x= 0; x < global_count; x++)
3359 {
3360 global_keys[x]= global_pairs[x].key;
3361 global_keys_length[x]= global_pairs[x].key_length;
3362 }
3363
3364 return TEST_SUCCESS;
3365 }
3366
3367 static test_return_t generate_data(memcached_st *memc)
3368 {
3369 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3370
3371 test_true(check_execute == global_count);
3372
3373 return TEST_SUCCESS;
3374 }
3375
3376 static test_return_t generate_data_with_stats(memcached_st *memc)
3377 {
3378 memcached_stat_st *stat_p;
3379 memcached_return_t rc;
3380 uint32_t host_index= 0;
3381 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3382
3383 test_true(check_execute == global_count);
3384
3385 //TODO: hosts used size stats
3386 stat_p= memcached_stat(memc, NULL, &rc);
3387 test_true(stat_p);
3388
3389 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3390 {
3391 /* This test was changes so that "make test" would work properlly */
3392 #ifdef DEBUG
3393 memcached_server_instance_st instance=
3394 memcached_server_instance_by_position(memc, host_index);
3395
3396 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3397 #endif
3398 test_true((unsigned long long)(stat_p + host_index)->bytes);
3399 }
3400
3401 memcached_stat_free(NULL, stat_p);
3402
3403 return TEST_SUCCESS;
3404 }
3405 static test_return_t generate_buffer_data(memcached_st *memc)
3406 {
3407 size_t latch= 0;
3408
3409 latch= 1;
3410 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3411 generate_data(memc);
3412
3413 return TEST_SUCCESS;
3414 }
3415
3416 static test_return_t get_read_count(memcached_st *memc)
3417 {
3418 memcached_return_t rc;
3419 memcached_st *memc_clone;
3420
3421 memc_clone= memcached_clone(NULL, memc);
3422 test_true(memc_clone);
3423
3424 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3425
3426 {
3427 char *return_value;
3428 size_t return_value_length;
3429 uint32_t flags;
3430 uint32_t count;
3431
3432 for (size_t x= count= 0; x < global_count; x++)
3433 {
3434 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3435 &return_value_length, &flags, &rc);
3436 if (rc == MEMCACHED_SUCCESS)
3437 {
3438 count++;
3439 if (return_value)
3440 free(return_value);
3441 }
3442 }
3443 }
3444
3445 memcached_free(memc_clone);
3446
3447 return TEST_SUCCESS;
3448 }
3449
3450 static test_return_t get_read(memcached_st *memc)
3451 {
3452 memcached_return_t rc;
3453
3454 {
3455 char *return_value;
3456 size_t return_value_length;
3457 uint32_t flags;
3458
3459 for (size_t x= 0; x < global_count; x++)
3460 {
3461 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3462 &return_value_length, &flags, &rc);
3463 /*
3464 test_true(return_value);
3465 test_true(rc == MEMCACHED_SUCCESS);
3466 */
3467 if (rc == MEMCACHED_SUCCESS && return_value)
3468 free(return_value);
3469 }
3470 }
3471
3472 return TEST_SUCCESS;
3473 }
3474
3475 static test_return_t mget_read(memcached_st *memc)
3476 {
3477 memcached_return_t rc;
3478
3479 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3480 return TEST_SKIPPED;
3481
3482 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3483
3484 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3485
3486 // Go fetch the keys and test to see if all of them were returned
3487 {
3488 size_t keys_returned;
3489 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3490 char buffer[30];
3491 snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)keys_returned);
3492 test_true_got(global_count == keys_returned, buffer);
3493 }
3494
3495
3496 return TEST_SUCCESS;
3497 }
3498
3499 static test_return_t mget_read_result(memcached_st *memc)
3500 {
3501 memcached_return_t rc;
3502
3503 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3504 return TEST_SKIPPED;
3505
3506 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3507
3508 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3509
3510 /* Turn this into a help function */
3511 {
3512 memcached_result_st results_obj;
3513 memcached_result_st *results;
3514
3515 results= memcached_result_create(memc, &results_obj);
3516
3517 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3518 {
3519 test_true(results);
3520 test_true(rc == MEMCACHED_SUCCESS);
3521 }
3522
3523 memcached_result_free(&results_obj);
3524 }
3525
3526 return TEST_SUCCESS;
3527 }
3528
3529 static test_return_t mget_read_function(memcached_st *memc)
3530 {
3531 memcached_return_t rc;
3532 size_t counter;
3533 memcached_execute_fn callbacks[1];
3534
3535 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3536 return TEST_SKIPPED;
3537
3538 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3539
3540 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3541
3542 callbacks[0]= &callback_counter;
3543 counter= 0;
3544 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3545
3546 return TEST_SUCCESS;
3547 }
3548
3549 static test_return_t delete_generate(memcached_st *memc)
3550 {
3551 for (size_t x= 0; x < global_count; x++)
3552 {
3553 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3554 }
3555
3556 return TEST_SUCCESS;
3557 }
3558
3559 static test_return_t delete_buffer_generate(memcached_st *memc)
3560 {
3561 uint64_t latch= 0;
3562
3563 latch= 1;
3564 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3565
3566 for (size_t x= 0; x < global_count; x++)
3567 {
3568 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3569 }
3570
3571 return TEST_SUCCESS;
3572 }
3573
3574 static test_return_t add_host_test1(memcached_st *memc)
3575 {
3576 memcached_return_t rc;
3577 char servername[]= "0.example.com";
3578 memcached_server_st *servers;
3579
3580 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3581 test_true(servers);
3582 test_true(1 == memcached_server_list_count(servers));
3583
3584 for (size_t x= 2; x < 20; x++)
3585 {
3586 char buffer[SMALL_STRING_LEN];
3587
3588 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
3589 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3590 &rc);
3591 test_true(rc == MEMCACHED_SUCCESS);
3592 test_true(x == memcached_server_list_count(servers));
3593 }
3594
3595 rc= memcached_server_push(memc, servers);
3596 test_true(rc == MEMCACHED_SUCCESS);
3597 rc= memcached_server_push(memc, servers);
3598 test_true(rc == MEMCACHED_SUCCESS);
3599
3600 memcached_server_list_free(servers);
3601
3602 return TEST_SUCCESS;
3603 }
3604
3605 static test_return_t pre_nonblock(memcached_st *memc)
3606 {
3607 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3608
3609 return TEST_SUCCESS;
3610 }
3611
3612 static test_return_t pre_cork(memcached_st *memc)
3613 {
3614 memcached_return_t rc;
3615 bool set= true;
3616
3617 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
3618
3619 #ifdef __APPLE__
3620 return TEST_SKIPPED;
3621 #endif
3622
3623 if (rc == MEMCACHED_SUCCESS)
3624 return TEST_SUCCESS;
3625
3626 return TEST_SKIPPED;
3627 }
3628
3629 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3630 {
3631 test_return_t rc;
3632
3633 rc= pre_cork(memc);
3634
3635 #ifdef __APPLE__
3636 return TEST_SKIPPED;
3637 #endif
3638
3639 if (rc != TEST_SUCCESS)
3640 return rc;
3641
3642 return pre_nonblock(memc);
3643 }
3644
3645 static test_return_t pre_nonblock_binary(memcached_st *memc)
3646 {
3647 memcached_return_t rc= MEMCACHED_FAILURE;
3648 memcached_st *memc_clone;
3649
3650 memc_clone= memcached_clone(NULL, memc);
3651 test_true(memc_clone);
3652 // The memcached_version needs to be done on a clone, because the server
3653 // will not toggle protocol on an connection.
3654 memcached_version(memc_clone);
3655
3656 if (libmemcached_util_version_check(memc_clone, 1, 4, 4))
3657 {
3658 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3659 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3660 test_true(rc == MEMCACHED_SUCCESS);
3661 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3662 }
3663 else
3664 {
3665 return TEST_SKIPPED;
3666 }
3667
3668 memcached_free(memc_clone);
3669
3670 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3671 }
3672
3673 static test_return_t pre_murmur(memcached_st *memc)
3674 {
3675 #ifdef HAVE_MURMUR_HASH
3676 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3677 return TEST_SUCCESS;
3678 #else
3679 (void) memc;
3680 return TEST_SKIPPED;
3681 #endif
3682 }
3683
3684 static test_return_t pre_jenkins(memcached_st *memc)
3685 {
3686 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3687
3688 return TEST_SUCCESS;
3689 }
3690
3691
3692 static test_return_t pre_md5(memcached_st *memc)
3693 {
3694 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3695
3696 return TEST_SUCCESS;
3697 }
3698
3699 static test_return_t pre_crc(memcached_st *memc)
3700 {
3701 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3702
3703 return TEST_SUCCESS;
3704 }
3705
3706 static test_return_t pre_hsieh(memcached_st *memc)
3707 {
3708 #ifdef HAVE_HSIEH_HASH
3709 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3710 return TEST_SUCCESS;
3711 #else
3712 (void) memc;
3713 return TEST_SKIPPED;
3714 #endif
3715 }
3716
3717 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3718 {
3719 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3720
3721 return TEST_SUCCESS;
3722 }
3723
3724 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3725 {
3726 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3727
3728 return TEST_SUCCESS;
3729 }
3730
3731 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3732 {
3733 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3734
3735 return TEST_SUCCESS;
3736 }
3737
3738 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3739 {
3740 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3741
3742 return TEST_SUCCESS;
3743 }
3744
3745 static test_return_t pre_behavior_ketama(memcached_st *memc)
3746 {
3747 memcached_return_t rc;
3748 uint64_t value;
3749
3750 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3751 test_true(rc == MEMCACHED_SUCCESS);
3752
3753 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3754 test_true(value == 1);
3755
3756 return TEST_SUCCESS;
3757 }
3758
3759 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3760 {
3761 memcached_return_t rc;
3762 uint64_t value;
3763
3764 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3765 test_true(rc == MEMCACHED_SUCCESS);
3766
3767 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3768 test_true(value == 1);
3769
3770 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3771 test_true(rc == MEMCACHED_SUCCESS);
3772
3773 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3774 test_true(value == MEMCACHED_HASH_MD5);
3775
3776 return TEST_SUCCESS;
3777 }
3778
3779 /**
3780 @note This should be testing to see if the server really supports the binary protocol.
3781 */
3782 static test_return_t pre_binary(memcached_st *memc)
3783 {
3784 memcached_return_t rc= MEMCACHED_FAILURE;
3785
3786 if (libmemcached_util_version_check(memc, 1, 4, 4))
3787 {
3788 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3789 test_true(rc == MEMCACHED_SUCCESS);
3790 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3791 }
3792
3793 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3794 }
3795
3796 static test_return_t pre_sasl(memcached_st *memc)
3797 {
3798 memcached_return_t rc= MEMCACHED_FAILURE;
3799
3800 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
3801 const char *server= getenv("LIBMEMCACHED_TEST_SASL_SERVER");
3802 const char *user= getenv("LIBMEMCACHED_TEST_SASL_USERNAME");
3803 const char *pass= getenv("LIBMEMCACHED_TEST_SASL_PASSWORD");
3804
3805 if (server != NULL && user != NULL && pass != NULL)
3806 {
3807 memcached_server_st *servers= memcached_servers_parse(server);
3808 test_true(servers != NULL);
3809 memcached_servers_reset(memc);
3810 test_true(memcached_server_push(memc, servers) == MEMCACHED_SUCCESS);
3811 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3812 rc= memcached_set_sasl_auth_data(memc, user, pass);
3813 test_true(rc == MEMCACHED_SUCCESS);
3814 }
3815 #else
3816 (void)memc;
3817 #endif
3818
3819 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3820 }
3821
3822 static test_return_t pre_replication(memcached_st *memc)
3823 {
3824 test_return_t test_rc;
3825 test_rc= pre_binary(memc);
3826
3827 if (test_rc != TEST_SUCCESS)
3828 return test_rc;
3829
3830 /*
3831 * Make sure that we store the item on all servers
3832 * (master + replicas == number of servers)
3833 */
3834 memcached_return_t rc;
3835 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3836 memcached_server_count(memc) - 1);
3837 test_true(rc == MEMCACHED_SUCCESS);
3838 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3839
3840 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3841 }
3842
3843
3844 static test_return_t pre_replication_noblock(memcached_st *memc)
3845 {
3846 test_return_t rc;
3847
3848 rc= pre_replication(memc);
3849 if (rc != TEST_SUCCESS)
3850 return rc;
3851
3852 rc= pre_nonblock(memc);
3853
3854 return rc;
3855 }
3856
3857
3858 static void my_free(const memcached_st *ptr __attribute__((unused)), void *mem, void *context)
3859 {
3860 (void) context;
3861 #ifdef HARD_MALLOC_TESTS
3862 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3863 free(real_ptr);
3864 #else
3865 free(mem);
3866 #endif
3867 }
3868
3869
3870 static void *my_malloc(const memcached_st *ptr __attribute__((unused)), const size_t size, void *context)
3871 {
3872 (void)context;
3873 #ifdef HARD_MALLOC_TESTS
3874 void *ret= malloc(size + 8);
3875 if (ret != NULL)
3876 {
3877 ret= (void*)((caddr_t)ret + 8);
3878 }
3879 #else
3880 void *ret= malloc(size);
3881 #endif
3882
3883 if (ret != NULL)
3884 {
3885 memset(ret, 0xff, size);
3886 }
3887
3888 return ret;
3889 }
3890
3891
3892 static void *my_realloc(const memcached_st *ptr __attribute__((unused)), void *mem, const size_t size, void *context)
3893 {
3894 (void)context;
3895 #ifdef HARD_MALLOC_TESTS
3896 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3897 void *nmem= realloc(real_ptr, size + 8);
3898
3899 void *ret= NULL;
3900 if (nmem != NULL)
3901 {
3902 ret= (void*)((caddr_t)nmem + 8);
3903 }
3904
3905 return ret;
3906 #else
3907 return realloc(mem, size);
3908 #endif
3909 }
3910
3911
3912 static void *my_calloc(const memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size, void *context)
3913 {
3914 (void)context;
3915 #ifdef HARD_MALLOC_TESTS
3916 void *mem= my_malloc(ptr, nelem * size);
3917 if (mem)
3918 {
3919 memset(mem, 0, nelem * size);
3920 }
3921
3922 return mem;
3923 #else
3924 return calloc(nelem, size);
3925 #endif
3926 }
3927
3928
3929 static test_return_t set_prefix(memcached_st *memc)
3930 {
3931 memcached_return_t rc;
3932 const char *key= "mine";
3933 char *value;
3934
3935 /* Make sure be default none exists */
3936 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3937 test_true(rc == MEMCACHED_FAILURE);
3938
3939 /* Test a clean set */
3940 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3941 test_true(rc == MEMCACHED_SUCCESS);
3942
3943 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3944 test_true(memcmp(value, key, 4) == 0);
3945 test_true(rc == MEMCACHED_SUCCESS);
3946
3947 /* Test that we can turn it off */
3948 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3949 test_true(rc == MEMCACHED_SUCCESS);
3950
3951 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3952 test_true(rc == MEMCACHED_FAILURE);
3953
3954 /* Now setup for main test */
3955 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3956 test_true(rc == MEMCACHED_SUCCESS);
3957
3958 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3959 test_true(rc == MEMCACHED_SUCCESS);
3960 test_true(memcmp(value, key, 4) == 0);
3961
3962 /* Set to Zero, and then Set to something too large */
3963 {
3964 char long_key[255];
3965 memset(long_key, 0, 255);
3966
3967 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3968 test_true(rc == MEMCACHED_SUCCESS);
3969
3970 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3971 test_true(rc == MEMCACHED_FAILURE);
3972 test_true(value == NULL);
3973
3974 /* Test a long key for failure */
3975 /* TODO, extend test to determine based on setting, what result should be */
3976 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3977 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3978 //test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3979 test_true(rc == MEMCACHED_SUCCESS);
3980
3981 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3982 strcpy(long_key, "This is more then the allotted number of characters");
3983 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3984 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3985
3986 /* Test for a bad prefix, but with a short key */
3987 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3988 test_true(rc == MEMCACHED_SUCCESS);
3989
3990 strcpy(long_key, "dog cat");
3991 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3992 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3993 }
3994
3995 return TEST_SUCCESS;
3996 }
3997
3998
3999 #ifdef MEMCACHED_ENABLE_DEPRECATED
4000 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
4001 {
4002 void *test_ptr= NULL;
4003 void *cb_ptr= NULL;
4004 {
4005 memcached_malloc_fn malloc_cb=
4006 (memcached_malloc_fn)my_malloc;
4007 cb_ptr= *(void **)&malloc_cb;
4008 memcached_return_t rc;
4009
4010 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
4011 test_true(rc == MEMCACHED_SUCCESS);
4012 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
4013 test_true(rc == MEMCACHED_SUCCESS);
4014 test_true(test_ptr == cb_ptr);
4015 }
4016
4017 {
4018 memcached_realloc_fn realloc_cb=
4019 (memcached_realloc_fn)my_realloc;
4020 cb_ptr= *(void **)&realloc_cb;
4021 memcached_return_t rc;
4022
4023 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
4024 test_true(rc == MEMCACHED_SUCCESS);
4025 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
4026 test_true(rc == MEMCACHED_SUCCESS);
4027 test_true(test_ptr == cb_ptr);
4028 }
4029
4030 {
4031 memcached_free_fn free_cb=
4032 (memcached_free_fn)my_free;
4033 cb_ptr= *(void **)&free_cb;
4034 memcached_return_t rc;
4035
4036 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
4037 test_true(rc == MEMCACHED_SUCCESS);
4038 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
4039 test_true(rc == MEMCACHED_SUCCESS);
4040 test_true(test_ptr == cb_ptr);
4041 }
4042
4043 return TEST_SUCCESS;
4044 }
4045 #endif
4046
4047
4048 static test_return_t set_memory_alloc(memcached_st *memc)
4049 {
4050 memcached_return_t rc;
4051 rc= memcached_set_memory_allocators(memc, NULL, my_free,
4052 my_realloc, my_calloc, NULL);
4053 test_true(rc == MEMCACHED_FAILURE);
4054
4055 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
4056 my_realloc, my_calloc, NULL);
4057
4058 memcached_malloc_fn mem_malloc;
4059 memcached_free_fn mem_free;
4060 memcached_realloc_fn mem_realloc;
4061 memcached_calloc_fn mem_calloc;
4062 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
4063 &mem_realloc, &mem_calloc);
4064
4065 test_true(mem_malloc == my_malloc);
4066 test_true(mem_realloc == my_realloc);
4067 test_true(mem_calloc == my_calloc);
4068 test_true(mem_free == my_free);
4069
4070 return TEST_SUCCESS;
4071 }
4072
4073 static test_return_t enable_consistent_crc(memcached_st *memc)
4074 {
4075 test_return_t rc;
4076 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4077 memcached_hash_t hash;
4078 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4079 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
4080 return rc;
4081
4082 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4083 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4084
4085 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4086
4087 if (hash != MEMCACHED_HASH_CRC)
4088 return TEST_SKIPPED;
4089
4090 return TEST_SUCCESS;
4091 }
4092
4093 static test_return_t enable_consistent_hsieh(memcached_st *memc)
4094 {
4095 test_return_t rc;
4096 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4097 memcached_hash_t hash;
4098 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4099 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
4100 return rc;
4101
4102 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4103 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4104
4105 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4106
4107 if (hash != MEMCACHED_HASH_HSIEH)
4108 return TEST_SKIPPED;
4109
4110
4111 return TEST_SUCCESS;
4112 }
4113
4114 static test_return_t enable_cas(memcached_st *memc)
4115 {
4116 unsigned int set= 1;
4117
4118 if (libmemcached_util_version_check(memc, 1, 2, 4))
4119 {
4120 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
4121
4122 return TEST_SUCCESS;
4123 }
4124
4125 return TEST_SKIPPED;
4126 }
4127
4128 static test_return_t check_for_1_2_3(memcached_st *memc)
4129 {
4130 memcached_version(memc);
4131
4132 memcached_server_instance_st instance=
4133 memcached_server_instance_by_position(memc, 0);
4134
4135 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
4136 || instance->minor_version > 2)
4137 {
4138 return TEST_SUCCESS;
4139 }
4140
4141 return TEST_SKIPPED;
4142 }
4143
4144 static test_return_t pre_unix_socket(memcached_st *memc)
4145 {
4146 memcached_return_t rc;
4147 struct stat buf;
4148
4149 memcached_servers_reset(memc);
4150
4151 if (stat("/tmp/memcached.socket", &buf))
4152 return TEST_SKIPPED;
4153
4154 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
4155
4156 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
4157 }
4158
4159 static test_return_t pre_nodelay(memcached_st *memc)
4160 {
4161 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4162 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4163
4164 return TEST_SUCCESS;
4165 }
4166
4167 static test_return_t pre_settimer(memcached_st *memc)
4168 {
4169 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4170 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4171
4172 return TEST_SUCCESS;
4173 }
4174
4175 static test_return_t poll_timeout(memcached_st *memc)
4176 {
4177 size_t timeout;
4178
4179 timeout= 100;
4180
4181 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4182
4183 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
4184
4185 test_true(timeout == 100);
4186
4187 return TEST_SUCCESS;
4188 }
4189
4190 static test_return_t noreply_test(memcached_st *memc)
4191 {
4192 memcached_return_t ret;
4193 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4194 test_true(ret == MEMCACHED_SUCCESS);
4195 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4196 test_true(ret == MEMCACHED_SUCCESS);
4197 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
4198 test_true(ret == MEMCACHED_SUCCESS);
4199 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
4200 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
4201 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
4202
4203 for (int count=0; count < 5; ++count)
4204 {
4205 for (size_t x= 0; x < 100; ++x)
4206 {
4207 char key[10];
4208 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4209 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4210
4211 size_t len= (size_t)check_length;
4212
4213 switch (count)
4214 {
4215 case 0:
4216 ret= memcached_add(memc, key, len, key, len, 0, 0);
4217 break;
4218 case 1:
4219 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4220 break;
4221 case 2:
4222 ret= memcached_set(memc, key, len, key, len, 0, 0);
4223 break;
4224 case 3:
4225 ret= memcached_append(memc, key, len, key, len, 0, 0);
4226 break;
4227 case 4:
4228 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4229 break;
4230 default:
4231 test_true(count);
4232 break;
4233 }
4234 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
4235 }
4236
4237 /*
4238 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4239 ** API and is _ONLY_ done this way to verify that the library works the
4240 ** way it is supposed to do!!!!
4241 */
4242 int no_msg=0;
4243 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4244 {
4245 memcached_server_instance_st instance=
4246 memcached_server_instance_by_position(memc, x);
4247 no_msg+=(int)(instance->cursor_active);
4248 }
4249
4250 test_true(no_msg == 0);
4251 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4252
4253 /*
4254 ** Now validate that all items was set properly!
4255 */
4256 for (size_t x= 0; x < 100; ++x)
4257 {
4258 char key[10];
4259
4260 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4261
4262 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4263
4264 size_t len= (size_t)check_length;
4265 size_t length;
4266 uint32_t flags;
4267 char* value=memcached_get(memc, key, strlen(key),
4268 &length, &flags, &ret);
4269 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4270 switch (count)
4271 {
4272 case 0: /* FALLTHROUGH */
4273 case 1: /* FALLTHROUGH */
4274 case 2:
4275 test_true(strncmp(value, key, len) == 0);
4276 test_true(len == length);
4277 break;
4278 case 3:
4279 test_true(length == len * 2);
4280 break;
4281 case 4:
4282 test_true(length == len * 3);
4283 break;
4284 default:
4285 test_true(count);
4286 break;
4287 }
4288 free(value);
4289 }
4290 }
4291
4292 /* Try setting an illegal cas value (should not return an error to
4293 * the caller (because we don't expect a return message from the server)
4294 */
4295 const char* keys[]= {"0"};
4296 size_t lengths[]= {1};
4297 size_t length;
4298 uint32_t flags;
4299 memcached_result_st results_obj;
4300 memcached_result_st *results;
4301 ret= memcached_mget(memc, keys, lengths, 1);
4302 test_true(ret == MEMCACHED_SUCCESS);
4303
4304 results= memcached_result_create(memc, &results_obj);
4305 test_true(results);
4306 results= memcached_fetch_result(memc, &results_obj, &ret);
4307 test_true(results);
4308 test_true(ret == MEMCACHED_SUCCESS);
4309 uint64_t cas= memcached_result_cas(results);
4310 memcached_result_free(&results_obj);
4311
4312 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4313 test_true(ret == MEMCACHED_SUCCESS);
4314
4315 /*
4316 * The item will have a new cas value, so try to set it again with the old
4317 * value. This should fail!
4318 */
4319 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4320 test_true(ret == MEMCACHED_SUCCESS);
4321 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4322 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4323 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4324 free(value);
4325
4326 return TEST_SUCCESS;
4327 }
4328
4329 static test_return_t analyzer_test(memcached_st *memc)
4330 {
4331 memcached_return_t rc;
4332 memcached_stat_st *memc_stat;
4333 memcached_analysis_st *report;
4334
4335 memc_stat= memcached_stat(memc, NULL, &rc);
4336 test_true(rc == MEMCACHED_SUCCESS);
4337 test_true(memc_stat);
4338
4339 report= memcached_analyze(memc, memc_stat, &rc);
4340 test_true(rc == MEMCACHED_SUCCESS);
4341 test_true(report);
4342
4343 free(report);
4344 memcached_stat_free(NULL, memc_stat);
4345
4346 return TEST_SUCCESS;
4347 }
4348
4349 /* Count the objects */
4350 static memcached_return_t callback_dump_counter(const memcached_st *ptr __attribute__((unused)),
4351 const char *key __attribute__((unused)),
4352 size_t key_length __attribute__((unused)),
4353 void *context)
4354 {
4355 size_t *counter= (size_t *)context;
4356
4357 *counter= *counter + 1;
4358
4359 return MEMCACHED_SUCCESS;
4360 }
4361
4362 static test_return_t dump_test(memcached_st *memc)
4363 {
4364 memcached_return_t rc;
4365 size_t counter= 0;
4366 memcached_dump_fn callbacks[1];
4367 test_return_t main_rc;
4368
4369 callbacks[0]= &callback_dump_counter;
4370
4371 /* No support for Binary protocol yet */
4372 if (memc->flags.binary_protocol)
4373 return TEST_SUCCESS;
4374
4375 main_rc= set_test3(memc);
4376
4377 test_true (main_rc == TEST_SUCCESS);
4378
4379 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4380 test_true(rc == MEMCACHED_SUCCESS);
4381
4382 /* We may have more then 32 if our previous flush has not completed */
4383 test_true(counter >= 32);
4384
4385 return TEST_SUCCESS;
4386 }
4387
4388 #ifdef HAVE_LIBMEMCACHEDUTIL
4389 static void* connection_release(void *arg)
4390 {
4391 struct {
4392 memcached_pool_st* pool;
4393 memcached_st* mmc;
4394 } *resource= arg;
4395
4396 usleep(250);
4397 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4398 return arg;
4399 }
4400
4401 #define POOL_SIZE 10
4402 static test_return_t connection_pool_test(memcached_st *memc)
4403 {
4404 memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE);
4405 test_true(pool != NULL);
4406 memcached_st *mmc[POOL_SIZE];
4407 memcached_return_t rc;
4408
4409 for (size_t x= 0; x < POOL_SIZE; ++x)
4410 {
4411 mmc[x]= memcached_pool_pop(pool, false, &rc);
4412 test_true(mmc[x] != NULL);
4413 test_true(rc == MEMCACHED_SUCCESS);
4414 }
4415
4416 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4417 test_true(rc == MEMCACHED_SUCCESS);
4418
4419 pthread_t tid;
4420 struct {
4421 memcached_pool_st* pool;
4422 memcached_st* mmc;
4423 } item= { .pool = pool, .mmc = mmc[9] };
4424 pthread_create(&tid, NULL, connection_release, &item);
4425 mmc[9]= memcached_pool_pop(pool, true, &rc);
4426 test_true(rc == MEMCACHED_SUCCESS);
4427 pthread_join(tid, NULL);
4428 test_true(mmc[9] == item.mmc);
4429 const char *key= "key";
4430 size_t keylen= strlen(key);
4431
4432 // verify that I can do ops with all connections
4433 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4434 test_true(rc == MEMCACHED_SUCCESS);
4435
4436 for (size_t x= 0; x < POOL_SIZE; ++x)
4437 {
4438 uint64_t number_value;
4439 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4440 test_true(rc == MEMCACHED_SUCCESS);
4441 test_true(number_value == (x+1));
4442 }
4443
4444 // Release them..
4445 for (size_t x= 0; x < POOL_SIZE; ++x)
4446 {
4447 test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4448 }
4449
4450
4451 /* verify that I can set behaviors on the pool when I don't have all
4452 * of the connections in the pool. It should however be enabled
4453 * when I push the item into the pool
4454 */
4455 mmc[0]= memcached_pool_pop(pool, false, &rc);
4456 test_true(mmc[0] != NULL);
4457
4458 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4459 test_true(rc == MEMCACHED_SUCCESS);
4460
4461 mmc[1]= memcached_pool_pop(pool, false, &rc);
4462 test_true(mmc[1] != NULL);
4463
4464 test_true(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4465 test_true(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4466 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4467
4468 mmc[0]= memcached_pool_pop(pool, false, &rc);
4469 test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4470 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4471
4472 test_true(memcached_pool_destroy(pool) == memc);
4473
4474 return TEST_SUCCESS;
4475 }
4476
4477 static test_return_t util_version_test(memcached_st *memc)
4478 {
4479 bool if_successful;
4480
4481 if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
4482 test_true(if_successful == true);
4483
4484 if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
4485
4486 // We expect failure
4487 if (if_successful)
4488 {
4489 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4490 fprintf(stderr, "\nDumping Server Information\n\n");
4491 memcached_server_fn callbacks[1];
4492
4493 callbacks[0]= dump_server_information;
4494 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
4495 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4496 }
4497 test_true(if_successful == false);
4498
4499 memcached_server_instance_st instance=
4500 memcached_server_instance_by_position(memc, 0);
4501
4502 memcached_version(memc);
4503
4504 // We only use one binary when we test, so this should be just fine.
4505 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
4506 test_true(if_successful == true);
4507
4508 if (instance->micro_version > 0)
4509 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
4510 else if (instance->minor_version > 0)
4511 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4512 else if (instance->major_version > 0)
4513 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
4514
4515 test_true(if_successful == true);
4516
4517 if (instance->micro_version > 0)
4518 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
4519 else if (instance->minor_version > 0)
4520 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4521 else if (instance->major_version > 0)
4522 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
4523
4524 test_true(if_successful == false);
4525
4526 return TEST_SUCCESS;
4527 }
4528
4529 static test_return_t ping_test(memcached_st *memc)
4530 {
4531 memcached_return_t rc;
4532 memcached_server_instance_st instance=
4533 memcached_server_instance_by_position(memc, 0);
4534
4535 // Test both the version that returns a code, and the one that does not.
4536 test_true(libmemcached_util_ping(memcached_server_name(instance),
4537 memcached_server_port(instance), NULL));
4538
4539 test_true(libmemcached_util_ping(memcached_server_name(instance),
4540 memcached_server_port(instance), &rc));
4541
4542 test_true(rc == MEMCACHED_SUCCESS);
4543
4544 return TEST_SUCCESS;
4545 }
4546 #endif
4547
4548 static test_return_t replication_set_test(memcached_st *memc)
4549 {
4550 memcached_return_t rc;
4551 memcached_st *memc_clone= memcached_clone(NULL, memc);
4552 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4553
4554 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4555 test_true(rc == MEMCACHED_SUCCESS);
4556
4557 /*
4558 ** We are using the quiet commands to store the replicas, so we need
4559 ** to ensure that all of them are processed before we can continue.
4560 ** In the test we go directly from storing the object to trying to
4561 ** receive the object from all of the different servers, so we
4562 ** could end up in a race condition (the memcached server hasn't yet
4563 ** processed the quiet command from the replication set when it process
4564 ** the request from the other client (created by the clone)). As a
4565 ** workaround for that we call memcached_quit to send the quit command
4566 ** to the server and wait for the response ;-) If you use the test code
4567 ** as an example for your own code, please note that you shouldn't need
4568 ** to do this ;-)
4569 */
4570 memcached_quit(memc);
4571
4572 /*
4573 ** "bubba" should now be stored on all of our servers. We don't have an
4574 ** easy to use API to address each individual server, so I'll just iterate
4575 ** through a bunch of "master keys" and I should most likely hit all of the
4576 ** servers...
4577 */
4578 for (int x= 'a'; x <= 'z'; ++x)
4579 {
4580 char key[2]= { [0]= (char)x };
4581 size_t len;
4582 uint32_t flags;
4583 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4584 &len, &flags, &rc);
4585 test_true(rc == MEMCACHED_SUCCESS);
4586 test_true(val != NULL);
4587 free(val);
4588 }
4589
4590 memcached_free(memc_clone);
4591
4592 return TEST_SUCCESS;
4593 }
4594
4595 static test_return_t replication_get_test(memcached_st *memc)
4596 {
4597 memcached_return_t rc;
4598
4599 /*
4600 * Don't do the following in your code. I am abusing the internal details
4601 * within the library, and this is not a supported interface.
4602 * This is to verify correct behavior in the library
4603 */
4604 for (uint32_t host= 0; host < memcached_server_count(memc); ++host)
4605 {
4606 memcached_st *memc_clone= memcached_clone(NULL, memc);
4607 memcached_server_instance_st instance=
4608 memcached_server_instance_by_position(memc_clone, host);
4609
4610 ((memcached_server_write_instance_st)instance)->port= 0;
4611
4612 for (int x= 'a'; x <= 'z'; ++x)
4613 {
4614 char key[2]= { [0]= (char)x };
4615 size_t len;
4616 uint32_t flags;
4617 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4618 &len, &flags, &rc);
4619 test_true(rc == MEMCACHED_SUCCESS);
4620 test_true(val != NULL);
4621 free(val);
4622 }
4623
4624 memcached_free(memc_clone);
4625 }
4626
4627 return TEST_SUCCESS;
4628 }
4629
4630 static test_return_t replication_mget_test(memcached_st *memc)
4631 {
4632 memcached_return_t rc;
4633 memcached_st *memc_clone= memcached_clone(NULL, memc);
4634 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4635
4636 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4637 size_t len[]= { 5, 4, 4, 4 };
4638
4639 for (size_t x= 0; x< 4; ++x)
4640 {
4641 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4642 test_true(rc == MEMCACHED_SUCCESS);
4643 }
4644
4645 /*
4646 ** We are using the quiet commands to store the replicas, so we need
4647 ** to ensure that all of them are processed before we can continue.
4648 ** In the test we go directly from storing the object to trying to
4649 ** receive the object from all of the different servers, so we
4650 ** could end up in a race condition (the memcached server hasn't yet
4651 ** processed the quiet command from the replication set when it process
4652 ** the request from the other client (created by the clone)). As a
4653 ** workaround for that we call memcached_quit to send the quit command
4654 ** to the server and wait for the response ;-) If you use the test code
4655 ** as an example for your own code, please note that you shouldn't need
4656 ** to do this ;-)
4657 */
4658 memcached_quit(memc);
4659
4660 /*
4661 * Don't do the following in your code. I am abusing the internal details
4662 * within the library, and this is not a supported interface.
4663 * This is to verify correct behavior in the library
4664 */
4665 memcached_result_st result_obj;
4666 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4667 {
4668 memcached_st *new_clone= memcached_clone(NULL, memc);
4669 memcached_server_instance_st instance=
4670 memcached_server_instance_by_position(new_clone, host);
4671 ((memcached_server_write_instance_st)instance)->port= 0;
4672
4673 for (int x= 'a'; x <= 'z'; ++x)
4674 {
4675 char key[2]= { [0]= (char)x, [1]= 0 };
4676
4677 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4678 test_true(rc == MEMCACHED_SUCCESS);
4679
4680 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4681 test_true(results);
4682
4683 int hits= 0;
4684 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4685 {
4686 hits++;
4687 }
4688 test_true(hits == 4);
4689 memcached_result_free(&result_obj);
4690 }
4691
4692 memcached_free(new_clone);
4693 }
4694
4695 memcached_free(memc_clone);
4696
4697 return TEST_SUCCESS;
4698 }
4699
4700 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4701 {
4702 memcached_result_st result_obj;
4703 memcached_return_t rc;
4704 memcached_st *memc_clone= memcached_clone(NULL, memc);
4705 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4706 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4707
4708 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4709 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4710
4711 for (size_t x= 0; x< 7; ++x)
4712 {
4713 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4714 test_true(rc == MEMCACHED_SUCCESS);
4715 }
4716
4717 memcached_quit(memc);
4718
4719 for (size_t x= 0; x< 7; ++x)
4720 {
4721 const char key[2]= { [0]= (const char)x };
4722
4723 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4724 test_true(rc == MEMCACHED_SUCCESS);
4725
4726 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4727 test_true(results);
4728
4729 int hits= 0;
4730 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4731 {
4732 ++hits;
4733 }
4734 test_true(hits == 7);
4735 memcached_result_free(&result_obj);
4736 }
4737 memcached_free(memc_clone);
4738 return TEST_SUCCESS;
4739 }
4740
4741 static test_return_t replication_delete_test(memcached_st *memc)
4742 {
4743 memcached_return_t rc;
4744 memcached_st *memc_clone= memcached_clone(NULL, memc);
4745 /* Delete the items from all of the servers except 1 */
4746 uint64_t repl= memcached_behavior_get(memc,
4747 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4748 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4749
4750 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4751 size_t len[]= { 5, 4, 4, 4 };
4752
4753 for (size_t x= 0; x< 4; ++x)
4754 {
4755 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4756 test_true(rc == MEMCACHED_SUCCESS);
4757 }
4758
4759 /*
4760 * Don't do the following in your code. I am abusing the internal details
4761 * within the library, and this is not a supported interface.
4762 * This is to verify correct behavior in the library
4763 */
4764 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4765 for (uint32_t x= 0; x < (repl + 1); ++x)
4766 {
4767 memcached_server_instance_st instance=
4768 memcached_server_instance_by_position(memc_clone, x);
4769
4770 ((memcached_server_write_instance_st)instance)->port= 0;
4771 if (++hash == memc_clone->number_of_hosts)
4772 hash= 0;
4773 }
4774
4775 memcached_result_st result_obj;
4776 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4777 {
4778 for (size_t x= 'a'; x <= 'z'; ++x)
4779 {
4780 const char key[2]= { [0]= (const char)x };
4781
4782 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4783 test_true(rc == MEMCACHED_SUCCESS);
4784
4785 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4786 test_true(results);
4787
4788 int hits= 0;
4789 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4790 {
4791 ++hits;
4792 }
4793 test_true(hits == 4);
4794 memcached_result_free(&result_obj);
4795 }
4796 }
4797 memcached_free(memc_clone);
4798
4799 return TEST_SUCCESS;
4800 }
4801
4802 #if 0
4803 static test_return_t hash_sanity_test (memcached_st *memc)
4804 {
4805 (void)memc;
4806
4807 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4808 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4809 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4810 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4811 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4812 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4813 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4814 #ifdef HAVE_HSIEH_HASH
4815 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4816 #endif
4817 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4818 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4819 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4820
4821 return TEST_SUCCESS;
4822 }
4823 #endif
4824
4825 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4826 {
4827 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4828 #ifdef HAVE_HSIEH_HASH
4829 expected_rc= MEMCACHED_SUCCESS;
4830 #endif
4831 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4832 (uint64_t)MEMCACHED_HASH_HSIEH);
4833 test_true(rc == expected_rc);
4834
4835 return TEST_SUCCESS;
4836 }
4837
4838 static test_return_t murmur_avaibility_test (memcached_st *memc)
4839 {
4840 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4841 #ifdef HAVE_MURMUR_HASH
4842 expected_rc= MEMCACHED_SUCCESS;
4843 #endif
4844 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4845 (uint64_t)MEMCACHED_HASH_MURMUR);
4846 test_true(rc == expected_rc);
4847
4848 return TEST_SUCCESS;
4849 }
4850
4851 static test_return_t one_at_a_time_run (memcached_st *memc __attribute__((unused)))
4852 {
4853 uint32_t x;
4854 const char **ptr;
4855
4856 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4857 {
4858 uint32_t hash_val;
4859
4860 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT);
4861 test_true(one_at_a_time_values[x] == hash_val);
4862 }
4863
4864 return TEST_SUCCESS;
4865 }
4866
4867 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4868 {
4869 uint32_t x;
4870 const char **ptr;
4871
4872 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4873 {
4874 uint32_t hash_val;
4875
4876 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4877 test_true(md5_values[x] == hash_val);
4878 }
4879
4880 return TEST_SUCCESS;
4881 }
4882
4883 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4884 {
4885 uint32_t x;
4886 const char **ptr;
4887
4888 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4889 {
4890 uint32_t hash_val;
4891
4892 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4893 test_true(crc_values[x] == hash_val);
4894 }
4895
4896 return TEST_SUCCESS;
4897 }
4898
4899 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4900 {
4901 uint32_t x;
4902 const char **ptr;
4903
4904 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4905 {
4906 uint32_t hash_val;
4907
4908 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4909 test_true(fnv1_64_values[x] == hash_val);
4910 }
4911
4912 return TEST_SUCCESS;
4913 }
4914
4915 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4916 {
4917 uint32_t x;
4918 const char **ptr;
4919
4920 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4921 {
4922 uint32_t hash_val;
4923
4924 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4925 test_true(fnv1a_64_values[x] == hash_val);
4926 }
4927
4928 return TEST_SUCCESS;
4929 }
4930
4931 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4932 {
4933 uint32_t x;
4934 const char **ptr;
4935
4936
4937 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4938 {
4939 uint32_t hash_val;
4940
4941 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4942 test_true(fnv1_32_values[x] == hash_val);
4943 }
4944
4945 return TEST_SUCCESS;
4946 }
4947
4948 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4949 {
4950 uint32_t x;
4951 const char **ptr;
4952
4953 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4954 {
4955 uint32_t hash_val;
4956
4957 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4958 test_true(fnv1a_32_values[x] == hash_val);
4959 }
4960
4961 return TEST_SUCCESS;
4962 }
4963
4964 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4965 {
4966 uint32_t x;
4967 const char **ptr;
4968
4969 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4970 {
4971 uint32_t hash_val;
4972
4973 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4974 test_true(hsieh_values[x] == hash_val);
4975 }
4976
4977 return TEST_SUCCESS;
4978 }
4979
4980 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4981 {
4982 #ifdef WORDS_BIGENDIAN
4983 (void)murmur_values;
4984 return TEST_SKIPPED;
4985 #else
4986 uint32_t x;
4987 const char **ptr;
4988
4989 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4990 {
4991 uint32_t hash_val;
4992
4993 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4994 test_true(murmur_values[x] == hash_val);
4995 }
4996
4997 return TEST_SUCCESS;
4998 #endif
4999 }
5000
5001 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
5002 {
5003 uint32_t x;
5004 const char **ptr;
5005
5006
5007 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5008 {
5009 uint32_t hash_val;
5010
5011 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
5012 test_true(jenkins_values[x] == hash_val);
5013 }
5014
5015 return TEST_SUCCESS;
5016 }
5017
5018 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *context)
5019 {
5020 (void)context;
5021 return libhashkit_md5(string, string_length);
5022 }
5023
5024 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *context)
5025 {
5026 (void)context;
5027 return libhashkit_crc32(string, string_length);
5028 }
5029
5030 static test_return_t memcached_get_hashkit_test (memcached_st *memc)
5031 {
5032 uint32_t x;
5033 const char **ptr;
5034 const hashkit_st *kit;
5035 hashkit_st new_kit;
5036 hashkit_return_t hash_rc;
5037
5038 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};
5039 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};
5040
5041 kit= memcached_get_hashkit(memc);
5042
5043 hashkit_clone(&new_kit, kit);
5044 hash_rc= hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL);
5045 test_true(hash_rc == HASHKIT_SUCCESS);
5046
5047 memcached_set_hashkit(memc, &new_kit);
5048
5049 /*
5050 Verify Setting the hash.
5051 */
5052 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5053 {
5054 uint32_t hash_val;
5055
5056 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
5057 test_true(md5_values[x] == hash_val);
5058 }
5059
5060
5061 /*
5062 Now check memcached_st.
5063 */
5064 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5065 {
5066 uint32_t hash_val;
5067
5068 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
5069 test_true(md5_hosts[x] == hash_val);
5070 }
5071
5072 hash_rc= hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL);
5073 test_true(hash_rc == HASHKIT_SUCCESS);
5074
5075 memcached_set_hashkit(memc, &new_kit);
5076
5077 /*
5078 Verify Setting the hash.
5079 */
5080 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5081 {
5082 uint32_t hash_val;
5083
5084 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
5085 test_true(crc_values[x] == hash_val);
5086 }
5087
5088 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5089 {
5090 uint32_t hash_val;
5091
5092 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
5093 test_true(crc_hosts[x] == hash_val);
5094 }
5095
5096 return TEST_SUCCESS;
5097 }
5098
5099 /*
5100 Test case adapted from John Gorman <johngorman2@gmail.com>
5101
5102 We are testing the error condition when we connect to a server via memcached_get()
5103 but find that the server is not available.
5104 */
5105 static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
5106 {
5107 (void)memc;
5108 memcached_st *tl_memc_h;
5109 memcached_server_st *servers;
5110
5111 const char *key= "MemcachedLives";
5112 size_t len;
5113 uint32_t flags;
5114 memcached_return rc;
5115 char *value;
5116
5117 // Create a handle.
5118 tl_memc_h= memcached_create(NULL);
5119 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
5120 memcached_server_push(tl_memc_h, servers);
5121 memcached_server_list_free(servers);
5122
5123 // See if memcached is reachable.
5124 value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
5125
5126 test_false(value);
5127 test_true(len == 0);
5128 test_false(rc == MEMCACHED_SUCCESS);
5129
5130 memcached_free(tl_memc_h);
5131
5132 return TEST_SUCCESS;
5133 }
5134
5135 /*
5136 We connect to a server which exists, but search for a key that does not exist.
5137 */
5138 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
5139 {
5140 const char *key= "MemcachedKeyNotEXIST";
5141 size_t len;
5142 uint32_t flags;
5143 memcached_return rc;
5144 char *value;
5145
5146 // See if memcached is reachable.
5147 value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
5148
5149 test_false(value);
5150 test_true(len == 0);
5151 test_true(rc == MEMCACHED_NOTFOUND);
5152
5153 return TEST_SUCCESS;
5154 }
5155
5156 /*
5157 Test case adapted from John Gorman <johngorman2@gmail.com>
5158
5159 We are testing the error condition when we connect to a server via memcached_get_by_key()
5160 but find that the server is not available.
5161 */
5162 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
5163 {
5164 (void)memc;
5165 memcached_st *tl_memc_h;
5166 memcached_server_st *servers;
5167
5168 const char *key= "MemcachedLives";
5169 size_t len;
5170 uint32_t flags;
5171 memcached_return rc;
5172 char *value;
5173
5174 // Create a handle.
5175 tl_memc_h= memcached_create(NULL);
5176 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
5177 memcached_server_push(tl_memc_h, servers);
5178 memcached_server_list_free(servers);
5179
5180 // See if memcached is reachable.
5181 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
5182
5183 test_false(value);
5184 test_true(len == 0);
5185 test_false(rc == MEMCACHED_SUCCESS);
5186
5187 memcached_free(tl_memc_h);
5188
5189 return TEST_SUCCESS;
5190 }
5191
5192 /*
5193 We connect to a server which exists, but search for a key that does not exist.
5194 */
5195 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
5196 {
5197 const char *key= "MemcachedKeyNotEXIST";
5198 size_t len;
5199 uint32_t flags;
5200 memcached_return rc;
5201 char *value;
5202
5203 // See if memcached is reachable.
5204 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
5205
5206 test_false(value);
5207 test_true(len == 0);
5208 test_true(rc == MEMCACHED_NOTFOUND);
5209
5210 return TEST_SUCCESS;
5211 }
5212
5213
5214 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
5215 {
5216 memcached_return_t rc;
5217 uint64_t value;
5218 int x;
5219 memcached_server_st *server_pool;
5220 memcached_st *memc;
5221
5222 (void)trash;
5223
5224 memc= memcached_create(NULL);
5225 test_true(memc);
5226
5227 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5228 test_true(rc == MEMCACHED_SUCCESS);
5229
5230 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5231 test_true(value == 1);
5232
5233 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
5234 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
5235
5236
5237 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");
5238 memcached_server_push(memc, server_pool);
5239
5240 /* verify that the server list was parsed okay. */
5241 test_true(memcached_server_count(memc) == 8);
5242 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5243 test_true(server_pool[0].port == 11211);
5244 test_true(server_pool[0].weight == 600);
5245 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5246 test_true(server_pool[2].port == 11211);
5247 test_true(server_pool[2].weight == 200);
5248 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5249 test_true(server_pool[7].port == 11211);
5250 test_true(server_pool[7].weight == 100);
5251
5252 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5253 * us test the boundary wraparound.
5254 */
5255 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5256
5257 /* verify the standard ketama set. */
5258 for (x= 0; x < 99; x++)
5259 {
5260 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
5261 memcached_server_instance_st instance=
5262 memcached_server_instance_by_position(memc, server_idx);
5263 const char *hostname = memcached_server_name(instance);
5264
5265 test_strcmp(hostname, ketama_test_cases[x].server);
5266 }
5267
5268 memcached_server_list_free(server_pool);
5269 memcached_free(memc);
5270
5271 return TEST_SUCCESS;
5272 }
5273
5274 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
5275 {
5276 memcached_return_t rc;
5277 uint64_t value;
5278 int x;
5279 memcached_server_st *server_pool;
5280 memcached_st *memc;
5281
5282 (void)trash;
5283
5284 memc= memcached_create(NULL);
5285 test_true(memc);
5286
5287 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5288 test_true(rc == MEMCACHED_SUCCESS);
5289
5290 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5291 test_true(value == 1);
5292
5293 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
5294 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
5295
5296 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");
5297 memcached_server_push(memc, server_pool);
5298
5299 /* verify that the server list was parsed okay. */
5300 test_true(memcached_server_count(memc) == 8);
5301 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5302 test_true(server_pool[0].port == 11211);
5303 test_true(server_pool[0].weight == 600);
5304 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5305 test_true(server_pool[2].port == 11211);
5306 test_true(server_pool[2].weight == 200);
5307 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5308 test_true(server_pool[7].port == 11211);
5309 test_true(server_pool[7].weight == 100);
5310
5311 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5312 * us test the boundary wraparound.
5313 */
5314 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5315
5316 /* verify the standard ketama set. */
5317 for (x= 0; x < 99; x++)
5318 {
5319 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5320
5321 memcached_server_instance_st instance=
5322 memcached_server_instance_by_position(memc, server_idx);
5323
5324 const char *hostname= memcached_server_name(instance);
5325
5326 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5327 }
5328
5329 memcached_server_list_free(server_pool);
5330 memcached_free(memc);
5331
5332 return TEST_SUCCESS;
5333 }
5334
5335 static test_return_t regression_bug_434484(memcached_st *memc)
5336 {
5337 test_return_t test_rc;
5338 test_rc= pre_binary(memc);
5339
5340 if (test_rc != TEST_SUCCESS)
5341 return test_rc;
5342
5343 memcached_return_t ret;
5344 const char *key= "regression_bug_434484";
5345 size_t keylen= strlen(key);
5346
5347 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5348 test_true(ret == MEMCACHED_NOTSTORED);
5349
5350 size_t size= 2048 * 1024;
5351 void *data= calloc(1, size);
5352 test_true(data != NULL);
5353 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5354 test_true(ret == MEMCACHED_E2BIG);
5355 free(data);
5356
5357 return TEST_SUCCESS;
5358 }
5359
5360 static test_return_t regression_bug_434843(memcached_st *memc)
5361 {
5362 test_return_t test_rc;
5363 test_rc= pre_binary(memc);
5364
5365 if (test_rc != TEST_SUCCESS)
5366 return test_rc;
5367
5368 memcached_return_t rc;
5369 size_t counter= 0;
5370 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5371
5372 /*
5373 * I only want to hit only _one_ server so I know the number of requests I'm
5374 * sending in the pipleine to the server. Let's try to do a multiget of
5375 * 1024 (that should satisfy most users don't you think?). Future versions
5376 * will include a mget_execute function call if you need a higher number.
5377 */
5378 uint32_t number_of_hosts= memcached_server_count(memc);
5379 memc->number_of_hosts= 1;
5380 const size_t max_keys= 1024;
5381 char **keys= calloc(max_keys, sizeof(char*));
5382 size_t *key_length=calloc(max_keys, sizeof(size_t));
5383
5384 for (size_t x= 0; x < max_keys; ++x)
5385 {
5386 char k[251];
5387
5388 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5389 keys[x]= strdup(k);
5390 test_true(keys[x] != NULL);
5391 }
5392
5393 /*
5394 * Run two times.. the first time we should have 100% cache miss,
5395 * and the second time we should have 100% cache hits
5396 */
5397 for (size_t y= 0; y < 2; y++)
5398 {
5399 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5400 test_true(rc == MEMCACHED_SUCCESS);
5401 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5402
5403 if (y == 0)
5404 {
5405 /* The first iteration should give me a 100% cache miss. verify that*/
5406 char blob[1024]= { 0 };
5407
5408 test_true(counter == 0);
5409
5410 for (size_t x= 0; x < max_keys; ++x)
5411 {
5412 rc= memcached_add(memc, keys[x], key_length[x],
5413 blob, sizeof(blob), 0, 0);
5414 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5415 }
5416 }
5417 else
5418 {
5419 /* Verify that we received all of the key/value pairs */
5420 test_true(counter == max_keys);
5421 }
5422 }
5423
5424 /* Release allocated resources */
5425 for (size_t x= 0; x < max_keys; ++x)
5426 {
5427 free(keys[x]);
5428 }
5429 free(keys);
5430 free(key_length);
5431
5432 memc->number_of_hosts= number_of_hosts;
5433
5434 return TEST_SUCCESS;
5435 }
5436
5437 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5438 {
5439 memcached_return_t rc;
5440 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5441 test_true(rc == MEMCACHED_SUCCESS);
5442
5443 return regression_bug_434843(memc);
5444 }
5445
5446 static test_return_t regression_bug_421108(memcached_st *memc)
5447 {
5448 memcached_return_t rc;
5449 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5450 test_true(rc == MEMCACHED_SUCCESS);
5451
5452 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5453 test_true(rc == MEMCACHED_SUCCESS);
5454 test_true(bytes != NULL);
5455 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5456 "bytes_read", &rc);
5457 test_true(rc == MEMCACHED_SUCCESS);
5458 test_true(bytes_read != NULL);
5459
5460 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5461 "bytes_written", &rc);
5462 test_true(rc == MEMCACHED_SUCCESS);
5463 test_true(bytes_written != NULL);
5464
5465 test_true(strcmp(bytes, bytes_read) != 0);
5466 test_true(strcmp(bytes, bytes_written) != 0);
5467
5468 /* Release allocated resources */
5469 free(bytes);
5470 free(bytes_read);
5471 free(bytes_written);
5472 memcached_stat_free(NULL, memc_stat);
5473
5474 return TEST_SUCCESS;
5475 }
5476
5477 /*
5478 * The test case isn't obvious so I should probably document why
5479 * it works the way it does. Bug 442914 was caused by a bug
5480 * in the logic in memcached_purge (it did not handle the case
5481 * where the number of bytes sent was equal to the watermark).
5482 * In this test case, create messages so that we hit that case
5483 * and then disable noreply mode and issue a new command to
5484 * verify that it isn't stuck. If we change the format for the
5485 * delete command or the watermarks, we need to update this
5486 * test....
5487 */
5488 static test_return_t regression_bug_442914(memcached_st *memc)
5489 {
5490 memcached_return_t rc;
5491 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5492 test_true(rc == MEMCACHED_SUCCESS);
5493 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5494
5495 uint32_t number_of_hosts= memcached_server_count(memc);
5496 memc->number_of_hosts= 1;
5497
5498 char k[250];
5499 size_t len;
5500
5501 for (uint32_t x= 0; x < 250; ++x)
5502 {
5503 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5504 rc= memcached_delete(memc, k, len, 0);
5505 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5506 }
5507
5508 (void)snprintf(k, sizeof(k), "%037u", 251U);
5509 len= strlen(k);
5510
5511 rc= memcached_delete(memc, k, len, 0);
5512 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5513
5514 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5515 test_true(rc == MEMCACHED_SUCCESS);
5516 rc= memcached_delete(memc, k, len, 0);
5517 test_true(rc == MEMCACHED_NOTFOUND);
5518
5519 memc->number_of_hosts= number_of_hosts;
5520
5521 return TEST_SUCCESS;
5522 }
5523
5524 static test_return_t regression_bug_447342(memcached_st *memc)
5525 {
5526 memcached_server_instance_st instance_one;
5527 memcached_server_instance_st instance_two;
5528
5529 if (memcached_server_count(memc) < 3 || pre_replication(memc) != TEST_SUCCESS)
5530 return TEST_SKIPPED;
5531
5532 memcached_return_t rc;
5533
5534 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5535 test_true(rc == MEMCACHED_SUCCESS);
5536
5537 const size_t max_keys= 100;
5538 char **keys= calloc(max_keys, sizeof(char*));
5539 size_t *key_length= calloc(max_keys, sizeof(size_t));
5540
5541 for (size_t x= 0; x < max_keys; ++x)
5542 {
5543 char k[251];
5544
5545 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5546 keys[x]= strdup(k);
5547 test_true(keys[x] != NULL);
5548 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5549 test_true(rc == MEMCACHED_SUCCESS);
5550 }
5551
5552 /*
5553 ** We are using the quiet commands to store the replicas, so we need
5554 ** to ensure that all of them are processed before we can continue.
5555 ** In the test we go directly from storing the object to trying to
5556 ** receive the object from all of the different servers, so we
5557 ** could end up in a race condition (the memcached server hasn't yet
5558 ** processed the quiet command from the replication set when it process
5559 ** the request from the other client (created by the clone)). As a
5560 ** workaround for that we call memcached_quit to send the quit command
5561 ** to the server and wait for the response ;-) If you use the test code
5562 ** as an example for your own code, please note that you shouldn't need
5563 ** to do this ;-)
5564 */
5565 memcached_quit(memc);
5566
5567 /* Verify that all messages are stored, and we didn't stuff too much
5568 * into the servers
5569 */
5570 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5571 test_true(rc == MEMCACHED_SUCCESS);
5572
5573 size_t counter= 0;
5574 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5575 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5576 /* Verify that we received all of the key/value pairs */
5577 test_true(counter == max_keys);
5578
5579 memcached_quit(memc);
5580 /*
5581 * Don't do the following in your code. I am abusing the internal details
5582 * within the library, and this is not a supported interface.
5583 * This is to verify correct behavior in the library. Fake that two servers
5584 * are dead..
5585 */
5586 instance_one= memcached_server_instance_by_position(memc, 0);
5587 instance_two= memcached_server_instance_by_position(memc, 2);
5588 in_port_t port0= instance_one->port;
5589 in_port_t port2= instance_two->port;
5590
5591 ((memcached_server_write_instance_st)instance_one)->port= 0;
5592 ((memcached_server_write_instance_st)instance_two)->port= 0;
5593
5594 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5595 test_true(rc == MEMCACHED_SUCCESS);
5596
5597 counter= 0;
5598 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5599 test_true(counter == (unsigned int)max_keys);
5600
5601 /* restore the memc handle */
5602 ((memcached_server_write_instance_st)instance_one)->port= port0;
5603 ((memcached_server_write_instance_st)instance_two)->port= port2;
5604
5605 memcached_quit(memc);
5606
5607 /* Remove half of the objects */
5608 for (size_t x= 0; x < max_keys; ++x)
5609 {
5610 if (x & 1)
5611 {
5612 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5613 test_true(rc == MEMCACHED_SUCCESS);
5614 }
5615 }
5616
5617 memcached_quit(memc);
5618 ((memcached_server_write_instance_st)instance_one)->port= 0;
5619 ((memcached_server_write_instance_st)instance_two)->port= 0;
5620
5621 /* now retry the command, this time we should have cache misses */
5622 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5623 test_true(rc == MEMCACHED_SUCCESS);
5624
5625 counter= 0;
5626 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5627 test_true(counter == (unsigned int)(max_keys >> 1));
5628
5629 /* Release allocated resources */
5630 for (size_t x= 0; x < max_keys; ++x)
5631 {
5632 free(keys[x]);
5633 }
5634 free(keys);
5635 free(key_length);
5636
5637 /* restore the memc handle */
5638 ((memcached_server_write_instance_st)instance_one)->port= port0;
5639 ((memcached_server_write_instance_st)instance_two)->port= port2;
5640
5641 return TEST_SUCCESS;
5642 }
5643
5644 static test_return_t regression_bug_463297(memcached_st *memc)
5645 {
5646 memcached_st *memc_clone= memcached_clone(NULL, memc);
5647 test_true(memc_clone != NULL);
5648 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5649
5650 memcached_server_instance_st instance=
5651 memcached_server_instance_by_position(memc_clone, 0);
5652
5653 if (instance->major_version > 1 ||
5654 (instance->major_version == 1 &&
5655 instance->minor_version > 2))
5656 {
5657 /* Binary protocol doesn't support deferred delete */
5658 memcached_st *bin_clone= memcached_clone(NULL, memc);
5659 test_true(bin_clone != NULL);
5660 test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5661 test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5662 memcached_free(bin_clone);
5663
5664 memcached_quit(memc_clone);
5665
5666 /* If we know the server version, deferred delete should fail
5667 * with invalid arguments */
5668 test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5669
5670 /* If we don't know the server version, we should get a protocol error */
5671 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5672
5673 /* but there is a bug in some of the memcached servers (1.4) that treats
5674 * the counter as noreply so it doesn't send the proper error message
5675 */
5676 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5677
5678 /* And buffered mode should be disabled and we should get protocol error */
5679 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5680 rc= memcached_delete(memc, "foo", 3, 1);
5681 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5682
5683 /* Same goes for noreply... */
5684 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5685 rc= memcached_delete(memc, "foo", 3, 1);
5686 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5687
5688 /* but a normal request should go through (and be buffered) */
5689 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5690 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5691
5692 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5693 /* unbuffered noreply should be success */
5694 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5695 /* unbuffered with reply should be not found... */
5696 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5697 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5698 }
5699
5700 memcached_free(memc_clone);
5701 return TEST_SUCCESS;
5702 }
5703
5704
5705 /* Test memcached_server_get_last_disconnect
5706 * For a working server set, shall be NULL
5707 * For a set of non existing server, shall not be NULL
5708 */
5709 static test_return_t test_get_last_disconnect(memcached_st *memc)
5710 {
5711 memcached_return_t rc;
5712 memcached_server_instance_st disconnected_server;
5713
5714 /* With the working set of server */
5715 const char *key= "marmotte";
5716 const char *value= "milka";
5717
5718 memcached_reset_last_disconnected_server(memc);
5719 rc= memcached_set(memc, key, strlen(key),
5720 value, strlen(value),
5721 (time_t)0, (uint32_t)0);
5722 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5723
5724 disconnected_server = memcached_server_get_last_disconnect(memc);
5725 test_true(disconnected_server == NULL);
5726
5727 /* With a non existing server */
5728 memcached_st *mine;
5729 memcached_server_st *servers;
5730
5731 const char *server_list= "localhost:9";
5732
5733 servers= memcached_servers_parse(server_list);
5734 test_true(servers);
5735 mine= memcached_create(NULL);
5736 rc= memcached_server_push(mine, servers);
5737 test_true(rc == MEMCACHED_SUCCESS);
5738 memcached_server_list_free(servers);
5739 test_true(mine);
5740
5741 rc= memcached_set(mine, key, strlen(key),
5742 value, strlen(value),
5743 (time_t)0, (uint32_t)0);
5744 test_true(rc != MEMCACHED_SUCCESS);
5745
5746 disconnected_server= memcached_server_get_last_disconnect(mine);
5747 if (disconnected_server == NULL)
5748 {
5749 fprintf(stderr, "RC %s\n", memcached_strerror(mine, rc));
5750 abort();
5751 }
5752 test_true(disconnected_server != NULL);
5753 test_true(memcached_server_port(disconnected_server)== 9);
5754 test_true(strncmp(memcached_server_name(disconnected_server),"localhost",9) == 0);
5755
5756 memcached_quit(mine);
5757 memcached_free(mine);
5758
5759 return TEST_SUCCESS;
5760 }
5761
5762 static test_return_t test_verbosity(memcached_st *memc)
5763 {
5764 memcached_verbosity(memc, 3);
5765
5766 return TEST_SUCCESS;
5767 }
5768
5769 static test_return_t test_server_failure(memcached_st *memc)
5770 {
5771 memcached_st *local_memc;
5772 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
5773
5774 local_memc= memcached_create(NULL);
5775
5776 memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
5777 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
5778
5779 uint32_t server_count= memcached_server_count(local_memc);
5780
5781 test_true(server_count == 1);
5782
5783 // Disable the server
5784 instance= memcached_server_instance_by_position(local_memc, 0);
5785 ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
5786
5787 memcached_return_t rc;
5788 rc= memcached_set(local_memc, "foo", strlen("foo"),
5789 NULL, 0,
5790 (time_t)0, (uint32_t)0);
5791 test_true(rc == MEMCACHED_SERVER_MARKED_DEAD);
5792
5793 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5794 rc= memcached_set(local_memc, "foo", strlen("foo"),
5795 NULL, 0,
5796 (time_t)0, (uint32_t)0);
5797 test_true(rc == MEMCACHED_SUCCESS);
5798
5799
5800 memcached_free(local_memc);
5801
5802 return TEST_SUCCESS;
5803 }
5804
5805 static test_return_t test_cull_servers(memcached_st *memc)
5806 {
5807 uint32_t count = memcached_server_count(memc);
5808
5809 // Do not do this in your code, it is not supported.
5810 memc->servers[1].state.is_dead= true;
5811 memc->state.is_time_for_rebuild= true;
5812
5813 uint32_t new_count= memcached_server_count(memc);
5814 test_true(count == new_count);
5815
5816 #if 0
5817 test_true(count == new_count + 1 );
5818 #endif
5819
5820 return TEST_SUCCESS;
5821 }
5822
5823
5824 static memcached_return_t stat_printer(memcached_server_instance_st server,
5825 const char *key, size_t key_length,
5826 const char *value, size_t value_length,
5827 void *context)
5828 {
5829 (void)server;
5830 (void)context;
5831 (void)key;
5832 (void)key_length;
5833 (void)value;
5834 (void)value_length;
5835
5836 return MEMCACHED_SUCCESS;
5837 }
5838
5839 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5840 {
5841 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5842 test_true(rc == MEMCACHED_SUCCESS);
5843
5844 rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL);
5845 test_true(rc == MEMCACHED_SUCCESS);
5846
5847 rc= memcached_stat_execute(memc, "items", stat_printer, NULL);
5848 test_true(rc == MEMCACHED_SUCCESS);
5849
5850 rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL);
5851 test_true(rc == MEMCACHED_SUCCESS);
5852
5853 return TEST_SUCCESS;
5854 }
5855
5856 /*
5857 * This test ensures that the failure counter isn't incremented during
5858 * normal termination of the memcached instance.
5859 */
5860 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5861 {
5862 memcached_return_t rc;
5863 memcached_server_instance_st instance;
5864
5865 /* Set value to force connection to the server */
5866 const char *key= "marmotte";
5867 const char *value= "milka";
5868
5869 /*
5870 * Please note that I'm abusing the internal structures in libmemcached
5871 * in a non-portable way and you shouldn't be doing this. I'm only
5872 * doing this in order to verify that the library works the way it should
5873 */
5874 uint32_t number_of_hosts= memcached_server_count(memc);
5875 memc->number_of_hosts= 1;
5876
5877 /* Ensure that we are connected to the server by setting a value */
5878 rc= memcached_set(memc, key, strlen(key),
5879 value, strlen(value),
5880 (time_t)0, (uint32_t)0);
5881 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5882
5883
5884 instance= memcached_server_instance_by_position(memc, 0);
5885 /* The test is to see that the memcached_quit doesn't increase the
5886 * the server failure conter, so let's ensure that it is zero
5887 * before sending quit
5888 */
5889 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5890
5891 memcached_quit(memc);
5892
5893 /* Verify that it memcached_quit didn't increment the failure counter
5894 * Please note that this isn't bullet proof, because an error could
5895 * occur...
5896 */
5897 test_true(instance->server_failure_counter == 0);
5898
5899 /* restore the instance */
5900 memc->number_of_hosts= number_of_hosts;
5901
5902 return TEST_SUCCESS;
5903 }
5904
5905 /*
5906 * This tests ensures expected disconnections (for some behavior changes
5907 * for instance) do not wrongly increase failure counter
5908 */
5909 static test_return_t wrong_failure_counter_two_test(memcached_st *memc)
5910 {
5911 memcached_return rc;
5912
5913 memcached_st *memc_clone;
5914 memc_clone= memcached_clone(NULL, memc);
5915 test_true(memc_clone);
5916
5917 /* Set value to force connection to the server */
5918 const char *key= "marmotte";
5919 const char *value= "milka";
5920 char *string = NULL;
5921 size_t string_length;
5922 uint32_t flags;
5923
5924 rc= memcached_set(memc_clone, key, strlen(key),
5925 value, strlen(value),
5926 (time_t)0, (uint32_t)0);
5927 test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
5928
5929
5930 /* put failure limit to 1 */
5931 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5932 assert(rc == MEMCACHED_SUCCESS);
5933 /* Put a retry timeout to effectively activate failure_limit effect */
5934 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1);
5935 assert(rc == MEMCACHED_SUCCESS);
5936 /* change behavior that triggers memcached_quit()*/
5937 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5938 assert(rc == MEMCACHED_SUCCESS);
5939
5940
5941 /* Check if we still are connected */
5942 string= memcached_get(memc_clone, key, strlen(key),
5943 &string_length, &flags, &rc);
5944
5945 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
5946 test_true(string);
5947 free(string);
5948
5949 return TEST_SUCCESS;
5950 }
5951
5952
5953
5954
5955 /*
5956 * Test that ensures mget_execute does not end into recursive calls that finally fails
5957 */
5958 static test_return_t regression_bug_490486(memcached_st *memc)
5959 {
5960 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5961 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5962 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5963 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5964 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5965
5966 #ifdef __APPLE__
5967 return TEST_SKIPPED; // My MAC can't handle this test
5968 #endif
5969
5970 /*
5971 * I only want to hit _one_ server so I know the number of requests I'm
5972 * sending in the pipeline.
5973 */
5974 uint32_t number_of_hosts= memc->number_of_hosts;
5975 memc->number_of_hosts= 1;
5976 size_t max_keys= 20480;
5977
5978
5979 char **keys= calloc(max_keys, sizeof(char*));
5980 size_t *key_length=calloc(max_keys, sizeof(size_t));
5981
5982 /* First add all of the items.. */
5983 bool slept= false;
5984 char blob[1024]= { 0 };
5985 memcached_return rc;
5986 for (size_t x= 0; x < max_keys; ++x)
5987 {
5988 char k[251];
5989 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5990 keys[x]= strdup(k);
5991 assert(keys[x] != NULL);
5992 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5993 #ifdef __APPLE__
5994 if (rc == MEMCACHED_SERVER_MARKED_DEAD)
5995 {
5996 break; // We are out of business
5997 }
5998 #endif
5999 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT); // MEMCACHED_TIMEOUT <-- only observed on OSX
6000
6001 if (rc == MEMCACHED_TIMEOUT && slept == false)
6002 {
6003 x++;
6004 sleep(1);// We will try to sleep
6005 slept= true;
6006 }
6007 else if (rc == MEMCACHED_TIMEOUT && slept == true)
6008 {
6009 // We failed to send everything.
6010 break;
6011 }
6012 }
6013
6014 if (rc != MEMCACHED_SERVER_MARKED_DEAD)
6015 {
6016
6017 /* Try to get all of them with a large multiget */
6018 size_t counter= 0;
6019 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
6020 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
6021 (size_t)max_keys, callbacks, &counter, 1);
6022
6023 assert(rc == MEMCACHED_SUCCESS);
6024 char* the_value= NULL;
6025 char the_key[MEMCACHED_MAX_KEY];
6026 size_t the_key_length;
6027 size_t the_value_length;
6028 uint32_t the_flags;
6029
6030 do {
6031 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
6032
6033 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
6034 {
6035 ++counter;
6036 free(the_value);
6037 }
6038
6039 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
6040
6041
6042 assert(rc == MEMCACHED_END);
6043
6044 /* Verify that we got all of the items */
6045 assert(counter == max_keys);
6046 }
6047
6048 /* Release all allocated resources */
6049 for (size_t x= 0; x < max_keys; ++x)
6050 {
6051 free(keys[x]);
6052 }
6053 free(keys);
6054 free(key_length);
6055
6056 memc->number_of_hosts= number_of_hosts;
6057
6058 return TEST_SUCCESS;
6059 }
6060
6061 static test_return_t regression_bug_583031(memcached_st *unused)
6062 {
6063 (void)unused;
6064
6065 memcached_st *memc= memcached_create(NULL);
6066 assert(memc);
6067 memcached_server_add(memc, "10.2.3.4", 11211);
6068
6069 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
6070 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
6071 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
6072 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
6073 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
6074 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
6075
6076 memcached_return_t rc;
6077 size_t length;
6078 uint32_t flags;
6079
6080 (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc);
6081
6082 test_true_got(rc == MEMCACHED_TIMEOUT, memcached_strerror(NULL, rc));
6083
6084 memcached_free(memc);
6085
6086 return TEST_SUCCESS;
6087 }
6088
6089 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
6090 {
6091 fprintf(stderr, "Iteration #%u: ", it);
6092
6093 if(error == MEMCACHED_ERRNO)
6094 {
6095 fprintf(stderr, "system error %d from %s: %s\n",
6096 errno, what, strerror(errno));
6097 }
6098 else
6099 {
6100 fprintf(stderr, "error %d from %s: %s\n", error, what,
6101 memcached_strerror(mc, error));
6102 }
6103 }
6104
6105 #define TEST_CONSTANT_CREATION 200
6106
6107 static test_return_t regression_bug_(memcached_st *memc)
6108 {
6109 const char *remote_server;
6110 (void)memc;
6111
6112 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
6113 {
6114 return TEST_SKIPPED;
6115 }
6116
6117 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
6118 {
6119 memcached_st* mc= memcached_create(NULL);
6120 memcached_return rc;
6121
6122 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
6123 if (rc != MEMCACHED_SUCCESS)
6124 {
6125 memcached_die(mc, rc, "memcached_behavior_set", x);
6126 }
6127
6128 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
6129 if (rc != MEMCACHED_SUCCESS)
6130 {
6131 memcached_die(mc, rc, "memcached_behavior_set", x);
6132 }
6133
6134 rc= memcached_server_add(mc, remote_server, 0);
6135 if (rc != MEMCACHED_SUCCESS)
6136 {
6137 memcached_die(mc, rc, "memcached_server_add", x);
6138 }
6139
6140 const char *set_key= "akey";
6141 const size_t set_key_len= strlen(set_key);
6142 const char *set_value= "a value";
6143 const size_t set_value_len= strlen(set_value);
6144
6145 if (rc == MEMCACHED_SUCCESS)
6146 {
6147 if (x > 0)
6148 {
6149 size_t get_value_len;
6150 char *get_value;
6151 uint32_t get_value_flags;
6152
6153 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
6154 &get_value_flags, &rc);
6155 if (rc != MEMCACHED_SUCCESS)
6156 {
6157 memcached_die(mc, rc, "memcached_get", x);
6158 }
6159 else
6160 {
6161
6162 if (x != 0 &&
6163 (get_value_len != set_value_len
6164 || 0!=strncmp(get_value, set_value, get_value_len)))
6165 {
6166 fprintf(stderr, "Values don't match?\n");
6167 rc= MEMCACHED_FAILURE;
6168 }
6169 free(get_value);
6170 }
6171 }
6172
6173 rc= memcached_set(mc,
6174 set_key, set_key_len,
6175 set_value, set_value_len,
6176 0, /* time */
6177 0 /* flags */
6178 );
6179 if (rc != MEMCACHED_SUCCESS)
6180 {
6181 memcached_die(mc, rc, "memcached_set", x);
6182 }
6183 }
6184
6185 memcached_quit(mc);
6186 memcached_free(mc);
6187
6188 if (rc != MEMCACHED_SUCCESS)
6189 {
6190 break;
6191 }
6192 }
6193
6194 return TEST_SUCCESS;
6195 }
6196
6197 /*
6198 * Test that the sasl authentication works. We cannot use the default
6199 * pool of servers, because that would require that all servers we want
6200 * to test supports SASL authentication, and that they use the default
6201 * creds.
6202 */
6203 static test_return_t sasl_auth_test(memcached_st *memc)
6204 {
6205 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
6206 memcached_return_t rc;
6207
6208 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
6209 test_true(rc == MEMCACHED_SUCCESS);
6210 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_SUCCESS);
6211 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_SUCCESS);
6212 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_FAILURE);
6213 test_true((rc= memcached_destroy_sasl_auth_data(NULL)) == MEMCACHED_FAILURE);
6214 memcached_quit(memc);
6215
6216 rc= memcached_set_sasl_auth_data(memc,
6217 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
6218 getenv("LIBMEMCACHED_TEST_SASL_SERVER"));
6219 test_true(rc == MEMCACHED_SUCCESS);
6220
6221 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
6222 test_true(rc == MEMCACHED_AUTH_FAILURE);
6223 test_true(memcached_destroy_sasl_auth_data(memc) == MEMCACHED_SUCCESS);
6224
6225 memcached_quit(memc);
6226 return TEST_SUCCESS;
6227 #else
6228 (void)memc;
6229 return TEST_FAILURE;
6230 #endif
6231 }
6232
6233 /* Clean the server before beginning testing */
6234 test_st tests[] ={
6235 {"util_version", 1, (test_callback_fn)util_version_test },
6236 {"flush", 0, (test_callback_fn)flush_test },
6237 {"init", 0, (test_callback_fn)init_test },
6238 {"allocation", 0, (test_callback_fn)allocation_test },
6239 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
6240 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
6241 {"server_sort", 0, (test_callback_fn)server_sort_test},
6242 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
6243 {"memcached_server_remove", 0, (test_callback_fn)memcached_server_remove_test},
6244 {"clone_test", 0, (test_callback_fn)clone_test },
6245 {"connection_test", 0, (test_callback_fn)connection_test},
6246 {"callback_test", 0, (test_callback_fn)callback_test},
6247 {"userdata_test", 0, (test_callback_fn)userdata_test},
6248 {"error", 0, (test_callback_fn)error_test },
6249 {"set", 0, (test_callback_fn)set_test },
6250 {"set2", 0, (test_callback_fn)set_test2 },
6251 {"set3", 0, (test_callback_fn)set_test3 },
6252 {"dump", 1, (test_callback_fn)dump_test},
6253 {"add", 1, (test_callback_fn)add_test },
6254 {"replace", 1, (test_callback_fn)replace_test },
6255 {"delete", 1, (test_callback_fn)delete_test },
6256 {"get", 1, (test_callback_fn)get_test },
6257 {"get2", 0, (test_callback_fn)get_test2 },
6258 {"get3", 0, (test_callback_fn)get_test3 },
6259 {"get4", 0, (test_callback_fn)get_test4 },
6260 {"partial mget", 0, (test_callback_fn)get_test5 },
6261 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
6262 {"increment", 0, (test_callback_fn)increment_test },
6263 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
6264 {"decrement", 0, (test_callback_fn)decrement_test },
6265 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
6266 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
6267 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
6268 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
6269 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
6270 {"quit", 0, (test_callback_fn)quit_test },
6271 {"mget", 1, (test_callback_fn)mget_test },
6272 {"mget_result", 1, (test_callback_fn)mget_result_test },
6273 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
6274 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
6275 {"mget_execute", 1, (test_callback_fn)mget_execute },
6276 {"mget_end", 0, (test_callback_fn)mget_end },
6277 {"get_stats", 0, (test_callback_fn)get_stats },
6278 {"add_host_test", 0, (test_callback_fn)add_host_test },
6279 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
6280 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
6281 {"version_string_test", 0, (test_callback_fn)version_string_test},
6282 {"bad_key", 1, (test_callback_fn)bad_key_test },
6283 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
6284 {"read_through", 1, (test_callback_fn)read_through },
6285 {"delete_through", 1, (test_callback_fn)delete_through },
6286 {"noreply", 1, (test_callback_fn)noreply_test},
6287 {"analyzer", 1, (test_callback_fn)analyzer_test},
6288 #ifdef HAVE_LIBMEMCACHEDUTIL
6289 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
6290 {"ping", 1, (test_callback_fn)ping_test },
6291 #endif
6292 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
6293 {"verbosity", 1, (test_callback_fn)test_verbosity},
6294 {"test_server_failure", 1, (test_callback_fn)test_server_failure},
6295 {"cull_servers", 1, (test_callback_fn)test_cull_servers},
6296 {"memcached_stat_execute", 1, (test_callback_fn)memcached_stat_execute_test},
6297 {0, 0, 0}
6298 };
6299
6300 test_st behavior_tests[] ={
6301 {"behavior_test", 0, (test_callback_fn)behavior_test},
6302 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_CORK_test},
6303 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
6304 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
6305 {0, 0, 0}
6306 };
6307
6308 test_st regression_binary_vs_block[] ={
6309 {"block add", 1, (test_callback_fn)block_add_regression},
6310 {"binary add", 1, (test_callback_fn)binary_add_regression},
6311 {0, 0, 0}
6312 };
6313
6314 test_st async_tests[] ={
6315 {"add", 1, (test_callback_fn)add_wrapper },
6316 {0, 0, 0}
6317 };
6318
6319 test_st string_tests[] ={
6320 {"string static with null", 0, (test_callback_fn)string_static_null },
6321 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
6322 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
6323 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
6324 {"string append", 0, (test_callback_fn)string_alloc_append },
6325 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
6326 {0, 0, (test_callback_fn)0}
6327 };
6328
6329 test_st result_tests[] ={
6330 {"result static", 0, (test_callback_fn)result_static},
6331 {"result alloc", 0, (test_callback_fn)result_alloc},
6332 {0, 0, (test_callback_fn)0}
6333 };
6334
6335 test_st version_1_2_3[] ={
6336 {"append", 0, (test_callback_fn)append_test },
6337 {"prepend", 0, (test_callback_fn)prepend_test },
6338 {"cas", 0, (test_callback_fn)cas_test },
6339 {"cas2", 0, (test_callback_fn)cas2_test },
6340 {"append_binary", 0, (test_callback_fn)append_binary_test },
6341 {0, 0, (test_callback_fn)0}
6342 };
6343
6344 test_st user_tests[] ={
6345 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
6346 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
6347 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
6348 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
6349 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
6350 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
6351 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
6352 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
6353 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
6354 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
6355 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
6356 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
6357 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
6358 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
6359 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
6360 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
6361 #if !defined(__sun) && !defined(__OpenBSD__)
6362 /*
6363 ** It seems to be something weird with the character sets..
6364 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
6365 ** guess I need to find out how this is supposed to work.. Perhaps I need
6366 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
6367 ** so just disable the code for now...).
6368 */
6369 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
6370 #endif
6371 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
6372 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
6373 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
6374 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
6375 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
6376 {"wrong_failure_counter_two_test", 1, (test_callback_fn)wrong_failure_counter_two_test},
6377 {0, 0, (test_callback_fn)0}
6378 };
6379
6380 test_st replication_tests[]= {
6381 {"set", 1, (test_callback_fn)replication_set_test },
6382 {"get", 0, (test_callback_fn)replication_get_test },
6383 {"mget", 0, (test_callback_fn)replication_mget_test },
6384 {"delete", 0, (test_callback_fn)replication_delete_test },
6385 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
6386 {0, 0, (test_callback_fn)0}
6387 };
6388
6389 /*
6390 * The following test suite is used to verify that we don't introduce
6391 * regression bugs. If you want more information about the bug / test,
6392 * you should look in the bug report at
6393 * http://bugs.launchpad.net/libmemcached
6394 */
6395 test_st regression_tests[]= {
6396 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
6397 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
6398 {"lp:434843-buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
6399 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
6400 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
6401 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
6402 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
6403 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
6404 {"lp:583031", 1, (test_callback_fn)regression_bug_583031 },
6405 {"lp:?", 1, (test_callback_fn)regression_bug_ },
6406 {0, 0, (test_callback_fn)0}
6407 };
6408
6409 test_st sasl_auth_tests[]= {
6410 {"sasl_auth", 1, (test_callback_fn)sasl_auth_test },
6411 {0, 0, (test_callback_fn)0}
6412 };
6413
6414 test_st ketama_compatibility[]= {
6415 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
6416 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
6417 {0, 0, (test_callback_fn)0}
6418 };
6419
6420 test_st generate_tests[] ={
6421 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6422 {"generate_data", 1, (test_callback_fn)generate_data },
6423 {"get_read", 0, (test_callback_fn)get_read },
6424 {"delete_generate", 0, (test_callback_fn)delete_generate },
6425 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6426 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
6427 {"generate_data", 1, (test_callback_fn)generate_data },
6428 {"mget_read", 0, (test_callback_fn)mget_read },
6429 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
6430 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
6431 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6432 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
6433 {"generate_data", 1, (test_callback_fn)generate_data },
6434 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6435 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6436 {0, 0, (test_callback_fn)0}
6437 };
6438
6439 test_st consistent_tests[] ={
6440 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6441 {"generate_data", 1, (test_callback_fn)generate_data },
6442 {"get_read", 0, (test_callback_fn)get_read_count },
6443 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6444 {0, 0, (test_callback_fn)0}
6445 };
6446
6447 test_st consistent_weighted_tests[] ={
6448 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6449 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
6450 {"get_read", 0, (test_callback_fn)get_read_count },
6451 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6452 {0, 0, (test_callback_fn)0}
6453 };
6454
6455 test_st hsieh_availability[] ={
6456 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
6457 {0, 0, (test_callback_fn)0}
6458 };
6459
6460 test_st murmur_availability[] ={
6461 {"murmur_avaibility_test", 0, (test_callback_fn)murmur_avaibility_test},
6462 {0, 0, (test_callback_fn)0}
6463 };
6464
6465 #if 0
6466 test_st hash_sanity[] ={
6467 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
6468 {0, 0, (test_callback_fn)0}
6469 };
6470 #endif
6471
6472 test_st ketama_auto_eject_hosts[] ={
6473 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
6474 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
6475 {0, 0, (test_callback_fn)0}
6476 };
6477
6478 test_st hash_tests[] ={
6479 {"one_at_a_time_run", 0, (test_callback_fn)one_at_a_time_run },
6480 {"md5", 0, (test_callback_fn)md5_run },
6481 {"crc", 0, (test_callback_fn)crc_run },
6482 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
6483 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
6484 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
6485 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
6486 {"hsieh", 0, (test_callback_fn)hsieh_run },
6487 {"murmur", 0, (test_callback_fn)murmur_run },
6488 {"jenkis", 0, (test_callback_fn)jenkins_run },
6489 {"memcached_get_hashkit", 0, (test_callback_fn)memcached_get_hashkit_test },
6490 {0, 0, (test_callback_fn)0}
6491 };
6492
6493 test_st error_conditions[] ={
6494 {"memcached_get_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
6495 {"memcached_get_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
6496 {"memcached_get_by_key_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
6497 {"memcached_get_by_key_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6498 {0, 0, (test_callback_fn)0}
6499 };
6500
6501 collection_st collection[] ={
6502 #if 0
6503 {"hash_sanity", 0, 0, hash_sanity},
6504 #endif
6505 {"hsieh_availability", 0, 0, hsieh_availability},
6506 {"murmur_availability", 0, 0, murmur_availability},
6507 {"block", 0, 0, tests},
6508 {"binary", (test_callback_fn)pre_binary, 0, tests},
6509 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
6510 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6511 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
6512 {"md5", (test_callback_fn)pre_md5, 0, tests},
6513 {"crc", (test_callback_fn)pre_crc, 0, tests},
6514 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
6515 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
6516 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
6517 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
6518 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
6519 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
6520 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
6521 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6522 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
6523 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6524 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
6525 {"gets", (test_callback_fn)enable_cas, 0, tests},
6526 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
6527 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
6528 #ifdef MEMCACHED_ENABLE_DEPRECATED
6529 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
6530 #endif
6531 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
6532 {"prefix", (test_callback_fn)set_prefix, 0, tests},
6533 {"sasl_auth", (test_callback_fn)pre_sasl, 0, sasl_auth_tests },
6534 {"sasl", (test_callback_fn)pre_sasl, 0, tests },
6535 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
6536 {"string", 0, 0, string_tests},
6537 {"result", 0, 0, result_tests},
6538 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
6539 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
6540 {"user", 0, 0, user_tests},
6541 {"generate", 0, 0, generate_tests},
6542 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
6543 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
6544 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
6545 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
6546 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
6547 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
6548 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
6549 // Too slow
6550 {"generate_corked", (test_callback_fn)pre_cork, 0, generate_tests},
6551 {"generate_corked_and_nonblock", (test_callback_fn)pre_cork_and_nonblock, 0, generate_tests},
6552 {"consistent_not", 0, 0, consistent_tests},
6553 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
6554 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6555 {"ketama_compat", 0, 0, ketama_compatibility},
6556 {"test_hashes", 0, 0, hash_tests},
6557 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
6558 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
6559 {"regression", 0, 0, regression_tests},
6560 {"behaviors", 0, 0, behavior_tests},
6561 {"regression_binary_vs_block", (test_callback_fn)key_setup, (test_callback_fn)key_teardown, regression_binary_vs_block},
6562 {"error_conditions", 0, 0, error_conditions},
6563 {0, 0, 0, 0}
6564 };
6565
6566 #define SERVERS_TO_CREATE 5
6567
6568 #include "libmemcached_world.h"
6569
6570 void get_world(world_st *world)
6571 {
6572 world->collections= collection;
6573
6574 world->create= (test_callback_create_fn)world_create;
6575 world->destroy= (test_callback_fn)world_destroy;
6576
6577 world->test.startup= (test_callback_fn)world_test_startup;
6578 world->test.flush= (test_callback_fn)world_flush;
6579 world->test.pre_run= (test_callback_fn)world_pre_run;
6580 world->test.post_run= (test_callback_fn)world_post_run;
6581 world->test.on_error= (test_callback_error_fn)world_on_error;
6582
6583 world->collection.startup= (test_callback_fn)world_container_startup;
6584 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
6585
6586 world->runner= &defualt_libmemcached_runner;
6587 }