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