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