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