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