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