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