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