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