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