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