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