ed58daf6d4854005e4258711bf62d7a25b54c2e4
[awesomized/libmemcached] / tests / libmemcached-1.0 / mem_functions.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Libmemcached library
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2006-2009 Brian Aker All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38 #include <config.h>
39 #include <libtest/test.hpp>
40
41 #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 std::vector<size_t> key_lengths;
3080 key_lengths.resize(key_count);
3081 std::vector<char *> keys;
3082 keys.resize(key_lengths.size());
3083 for (unsigned int x= 0; x < key_lengths.size(); x++)
3084 {
3085 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
3086 int key_length= snprintf(key, sizeof(key), "%u", x);
3087 test_true(key_length > 0 and key_length < MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1);
3088 keys[x]= strdup(key);
3089 key_lengths[x]= key_length;
3090 }
3091
3092 oldalarm= signal(SIGALRM, fail);
3093 alarm(5);
3094
3095 test_compare_got(MEMCACHED_SUCCESS,
3096 memcached_mget(memc_clone, &keys[0], &key_lengths[0], key_count), memcached_last_error_message(memc_clone));
3097
3098 alarm(0);
3099 signal(SIGALRM, oldalarm);
3100
3101 memcached_return_t rc;
3102 uint32_t flags;
3103 char return_key[MEMCACHED_MAX_KEY];
3104 size_t return_key_length;
3105 char *return_value;
3106 size_t return_value_length;
3107 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
3108 &return_value_length, &flags, &rc)))
3109 {
3110 test_false(return_value); // There are no keys to fetch, so the value should never be returned
3111 }
3112 test_compare(MEMCACHED_NOTFOUND, rc);
3113 test_zero(return_value_length);
3114 test_zero(return_key_length);
3115 test_false(return_key[0]);
3116 test_false(return_value);
3117
3118 for (std::vector<char *>::iterator iter= keys.begin();
3119 iter != keys.end();
3120 iter++)
3121 {
3122 free(*iter);
3123 }
3124
3125 memcached_free(memc_clone);
3126
3127 return TEST_SUCCESS;
3128 #endif
3129 }
3130
3131 static test_return_t user_supplied_bug21(memcached_st *memc)
3132 {
3133 test_skip(TEST_SUCCESS, pre_binary(memc));
3134
3135 /* should work as of r580 */
3136 test_compare(TEST_SUCCESS,
3137 _user_supplied_bug21(memc, 10));
3138
3139 /* should fail as of r580 */
3140 test_compare(TEST_SUCCESS,
3141 _user_supplied_bug21(memc, 1000));
3142
3143 return TEST_SUCCESS;
3144 }
3145
3146 static test_return_t output_ketama_weighted_keys(memcached_st *)
3147 {
3148 memcached_st *memc= memcached_create(NULL);
3149 test_true(memc);
3150
3151
3152 test_compare(MEMCACHED_SUCCESS,
3153 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
3154
3155 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3156 test_compare(value, uint64_t(1));
3157
3158 test_compare(MEMCACHED_SUCCESS,
3159 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
3160
3161 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3162 test_true(value == MEMCACHED_HASH_MD5);
3163
3164
3165 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
3166
3167 memcached_server_st *server_pool;
3168 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");
3169 memcached_server_push(memc, server_pool);
3170
3171 // @todo this needs to be refactored to actually test something.
3172 #if 0
3173 FILE *fp;
3174 if ((fp = fopen("ketama_keys.txt", "w")))
3175 {
3176 // noop
3177 } else {
3178 printf("cannot write to file ketama_keys.txt");
3179 return TEST_FAILURE;
3180 }
3181
3182 for (int x= 0; x < 10000; x++)
3183 {
3184 char key[10];
3185 snprintf(key, sizeof(key), "%d", x);
3186
3187 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3188 char *hostname = memc->hosts[server_idx].hostname;
3189 in_port_t port = memc->hosts[server_idx].port;
3190 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3191 memcached_server_instance_st instance=
3192 memcached_server_instance_by_position(memc, host_index);
3193 }
3194 fclose(fp);
3195 #endif
3196 memcached_server_list_free(server_pool);
3197 memcached_free(memc);
3198
3199 return TEST_SUCCESS;
3200 }
3201
3202
3203 static test_return_t result_static(memcached_st *memc)
3204 {
3205 memcached_result_st result;
3206 memcached_result_st *result_ptr= memcached_result_create(memc, &result);
3207 test_false(result.options.is_allocated);
3208 test_true(memcached_is_initialized(&result));
3209 test_true(result_ptr);
3210 test_true(result_ptr == &result);
3211
3212 memcached_result_free(&result);
3213
3214 test_false(result.options.is_allocated);
3215 test_false(memcached_is_initialized(&result));
3216
3217 return TEST_SUCCESS;
3218 }
3219
3220 static test_return_t result_alloc(memcached_st *memc)
3221 {
3222 memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
3223 test_true(result_ptr);
3224 test_true(result_ptr->options.is_allocated);
3225 test_true(memcached_is_initialized(result_ptr));
3226 memcached_result_free(result_ptr);
3227
3228 return TEST_SUCCESS;
3229 }
3230
3231 static test_return_t cleanup_pairs(memcached_st *memc)
3232 {
3233 (void)memc;
3234 pairs_free(global_pairs);
3235
3236 return TEST_SUCCESS;
3237 }
3238
3239 static test_return_t generate_pairs(memcached_st *)
3240 {
3241 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3242 global_count= GLOBAL_COUNT;
3243
3244 for (size_t x= 0; x < global_count; x++)
3245 {
3246 global_keys[x]= global_pairs[x].key;
3247 global_keys_length[x]= global_pairs[x].key_length;
3248 }
3249
3250 return TEST_SUCCESS;
3251 }
3252
3253 static test_return_t generate_large_pairs(memcached_st *)
3254 {
3255 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3256 global_count= GLOBAL2_COUNT;
3257
3258 for (size_t x= 0; x < global_count; x++)
3259 {
3260 global_keys[x]= global_pairs[x].key;
3261 global_keys_length[x]= global_pairs[x].key_length;
3262 }
3263
3264 return TEST_SUCCESS;
3265 }
3266
3267 static test_return_t generate_data(memcached_st *memc)
3268 {
3269 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3270
3271 test_compare_warn_hint(global_count, check_execute, "Possible false, positive, memcached may have ejected key/value based on memory needs");
3272
3273 return TEST_SUCCESS;
3274 }
3275
3276 static test_return_t generate_data_with_stats(memcached_st *memc)
3277 {
3278 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3279
3280 test_compare(check_execute, global_count);
3281
3282 // @todo hosts used size stats
3283 memcached_return_t rc;
3284 memcached_stat_st *stat_p= memcached_stat(memc, NULL, &rc);
3285 test_true(stat_p);
3286
3287 for (uint32_t host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3288 {
3289 /* This test was changes so that "make test" would work properlly */
3290 if (DEBUG)
3291 {
3292 memcached_server_instance_st instance=
3293 memcached_server_instance_by_position(memc, host_index);
3294
3295 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3296 }
3297 test_true((unsigned long long)(stat_p + host_index)->bytes);
3298 }
3299
3300 memcached_stat_free(NULL, stat_p);
3301
3302 return TEST_SUCCESS;
3303 }
3304 static test_return_t generate_buffer_data(memcached_st *memc)
3305 {
3306 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true);
3307 generate_data(memc);
3308
3309 return TEST_SUCCESS;
3310 }
3311
3312 static test_return_t get_read_count(memcached_st *memc)
3313 {
3314 memcached_st *memc_clone= memcached_clone(NULL, memc);
3315 test_true(memc_clone);
3316
3317 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3318
3319 {
3320 char *return_value;
3321 size_t return_value_length;
3322 uint32_t flags;
3323 uint32_t count;
3324
3325 for (size_t x= count= 0; x < global_count; x++)
3326 {
3327 memcached_return_t rc;
3328 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3329 &return_value_length, &flags, &rc);
3330 if (rc == MEMCACHED_SUCCESS)
3331 {
3332 count++;
3333 if (return_value)
3334 {
3335 free(return_value);
3336 }
3337 }
3338 }
3339 }
3340
3341 memcached_free(memc_clone);
3342
3343 return TEST_SUCCESS;
3344 }
3345
3346 static test_return_t get_read(memcached_st *memc)
3347 {
3348 size_t keys_returned= 0;
3349 for (size_t x= 0; x < global_count; x++)
3350 {
3351 size_t return_value_length;
3352 uint32_t flags;
3353 memcached_return_t rc;
3354 char *return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3355 &return_value_length, &flags, &rc);
3356 /*
3357 test_true(return_value);
3358 test_compare(MEMCACHED_SUCCESS, rc);
3359 */
3360 if (rc == MEMCACHED_SUCCESS && return_value)
3361 {
3362 keys_returned++;
3363 free(return_value);
3364 }
3365 }
3366 test_compare_warn_hint(global_count, keys_returned, "Possible false, positive, memcached may have ejected key/value based on memory needs");
3367
3368 return TEST_SUCCESS;
3369 }
3370
3371 static test_return_t mget_read(memcached_st *memc)
3372 {
3373
3374 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3375
3376 test_compare(MEMCACHED_SUCCESS,
3377 memcached_mget(memc, global_keys, global_keys_length, global_count));
3378
3379 // Go fetch the keys and test to see if all of them were returned
3380 {
3381 unsigned int keys_returned;
3382 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned));
3383 test_true(keys_returned > 0);
3384 test_compare_warn_hint(global_count, keys_returned, "Possible false, positive, memcached may have ejected key/value based on memory needs");
3385 }
3386
3387 return TEST_SUCCESS;
3388 }
3389
3390 static test_return_t mget_read_result(memcached_st *memc)
3391 {
3392
3393 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3394
3395 test_compare(MEMCACHED_SUCCESS,
3396 memcached_mget(memc, global_keys, global_keys_length, global_count));
3397
3398 /* Turn this into a help function */
3399 {
3400 memcached_result_st results_obj;
3401 memcached_result_st *results= memcached_result_create(memc, &results_obj);
3402 test_true(results);
3403
3404 memcached_return_t rc;
3405 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3406 {
3407 if (rc == MEMCACHED_IN_PROGRESS)
3408 {
3409 continue;
3410 }
3411
3412 test_true(results);
3413 test_compare(MEMCACHED_SUCCESS, rc);
3414 }
3415 test_compare(MEMCACHED_END, rc);
3416
3417 memcached_result_free(&results_obj);
3418 }
3419
3420 return TEST_SUCCESS;
3421 }
3422
3423 static test_return_t mget_read_internal_result(memcached_st *memc)
3424 {
3425
3426 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3427
3428 test_compare(MEMCACHED_SUCCESS,
3429 memcached_mget(memc, global_keys, global_keys_length, global_count));
3430 {
3431 memcached_result_st *results= NULL;
3432 memcached_return_t rc;
3433 while ((results= memcached_fetch_result(memc, results, &rc)))
3434 {
3435 test_true(results);
3436 test_compare(MEMCACHED_SUCCESS, rc);
3437 }
3438 test_compare(MEMCACHED_END, rc);
3439
3440 memcached_result_free(results);
3441 }
3442
3443 return TEST_SUCCESS;
3444 }
3445
3446 static test_return_t mget_read_partial_result(memcached_st *memc)
3447 {
3448
3449 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3450
3451 test_compare(MEMCACHED_SUCCESS,
3452 memcached_mget(memc, global_keys, global_keys_length, global_count));
3453
3454 // We will scan for just one key
3455 {
3456 memcached_result_st results_obj;
3457 memcached_result_st *results= memcached_result_create(memc, &results_obj);
3458
3459 memcached_return_t rc;
3460 results= memcached_fetch_result(memc, results, &rc);
3461 test_true(results);
3462 test_compare(MEMCACHED_SUCCESS, rc);
3463
3464 memcached_result_free(&results_obj);
3465 }
3466
3467 // We already have a read happening, lets start up another one.
3468 test_compare(MEMCACHED_SUCCESS,
3469 memcached_mget(memc, global_keys, global_keys_length, global_count));
3470 {
3471 memcached_result_st results_obj;
3472 memcached_result_st *results= memcached_result_create(memc, &results_obj);
3473 test_true(results);
3474 test_false(memcached_is_allocated(results));
3475
3476 memcached_return_t rc;
3477 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3478 {
3479 test_true(results);
3480 test_compare(MEMCACHED_SUCCESS, rc);
3481 }
3482 test_compare(MEMCACHED_END, rc);
3483
3484 memcached_result_free(&results_obj);
3485 }
3486
3487 return TEST_SUCCESS;
3488 }
3489
3490 static test_return_t mget_read_function(memcached_st *memc)
3491 {
3492 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3493
3494 test_compare(MEMCACHED_SUCCESS,
3495 memcached_mget(memc, global_keys, global_keys_length, global_count));
3496
3497 memcached_execute_fn callbacks[]= { &callback_counter };
3498 size_t counter= 0;
3499 test_compare(MEMCACHED_SUCCESS,
3500 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
3501
3502 return TEST_SUCCESS;
3503 }
3504
3505 static test_return_t delete_generate(memcached_st *memc)
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 delete_buffer_generate(memcached_st *memc)
3521 {
3522 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true);
3523
3524 size_t total= 0;
3525 for (size_t x= 0; x < global_count; x++)
3526 {
3527 if (memcached_success(memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0)))
3528 {
3529 total++;
3530 }
3531 }
3532 test_compare_warn_hint(global_count, total, "Possible false, positive, memcached may have ejected key/value based on memory needs");
3533
3534 return TEST_SUCCESS;
3535 }
3536
3537 static test_return_t add_host_test1(memcached_st *memc)
3538 {
3539 memcached_return_t rc;
3540 char servername[]= "0.example.com";
3541
3542 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3543 test_true(servers);
3544 test_compare(1U, memcached_server_list_count(servers));
3545
3546 for (uint32_t x= 2; x < 20; x++)
3547 {
3548 char buffer[SMALL_STRING_LEN];
3549
3550 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
3551 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3552 &rc);
3553 test_compare(MEMCACHED_SUCCESS, rc);
3554 test_compare(x, memcached_server_list_count(servers));
3555 }
3556
3557 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
3558 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
3559
3560 memcached_server_list_free(servers);
3561
3562 return TEST_SUCCESS;
3563 }
3564
3565 static test_return_t pre_nonblock(memcached_st *memc)
3566 {
3567 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3568
3569 return TEST_SUCCESS;
3570 }
3571
3572 static test_return_t pre_cork(memcached_st *memc)
3573 {
3574 #ifdef __APPLE__
3575 return TEST_SKIPPED;
3576 #endif
3577 bool set= true;
3578 if (memcached_success(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set)))
3579 return TEST_SUCCESS;
3580
3581 return TEST_SKIPPED;
3582 }
3583
3584 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3585 {
3586 #ifdef __APPLE__
3587 return TEST_SKIPPED;
3588 #endif
3589 test_return_t test_rc;
3590 if ((test_rc= pre_cork(memc)) != TEST_SUCCESS)
3591 return test_rc;
3592
3593 return pre_nonblock(memc);
3594 }
3595
3596 static test_return_t pre_nonblock_binary(memcached_st *memc)
3597 {
3598 memcached_st *memc_clone= memcached_clone(NULL, memc);
3599 test_true(memc_clone);
3600
3601 // The memcached_version needs to be done on a clone, because the server
3602 // will not toggle protocol on an connection.
3603 memcached_version(memc_clone);
3604
3605 memcached_return_t rc= MEMCACHED_FAILURE;
3606 if (libmemcached_util_version_check(memc_clone, 1, 4, 4))
3607 {
3608 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3609 test_compare(MEMCACHED_SUCCESS,
3610 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
3611 test_compare(uint64_t(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
3612 }
3613 else
3614 {
3615 memcached_free(memc_clone);
3616 return TEST_SKIPPED;
3617 }
3618
3619 memcached_free(memc_clone);
3620
3621 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3622 }
3623
3624 static test_return_t pre_murmur(memcached_st *memc)
3625 {
3626 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
3627 return TEST_SUCCESS;
3628 }
3629
3630 static test_return_t pre_jenkins(memcached_st *memc)
3631 {
3632 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3633
3634 return TEST_SKIPPED;
3635 }
3636
3637
3638 static test_return_t pre_md5(memcached_st *memc)
3639 {
3640 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3641
3642 return TEST_SUCCESS;
3643 }
3644
3645 static test_return_t pre_crc(memcached_st *memc)
3646 {
3647 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3648
3649 return TEST_SUCCESS;
3650 }
3651
3652 static test_return_t pre_hsieh(memcached_st *memc)
3653 {
3654 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH));
3655 return TEST_SUCCESS;
3656 }
3657
3658 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3659 {
3660 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
3661
3662 return TEST_SUCCESS;
3663 }
3664
3665 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3666 {
3667 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64));
3668
3669 return TEST_SUCCESS;
3670 }
3671
3672 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3673 {
3674 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3675
3676 return TEST_SUCCESS;
3677 }
3678
3679 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3680 {
3681 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3682
3683 return TEST_SUCCESS;
3684 }
3685
3686 static test_return_t pre_behavior_ketama(memcached_st *memc)
3687 {
3688 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3689 test_compare(MEMCACHED_SUCCESS, rc);
3690
3691 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3692 test_compare(value, uint64_t(1));
3693
3694 return TEST_SUCCESS;
3695 }
3696
3697 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3698 {
3699 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3700 test_compare(MEMCACHED_SUCCESS, rc);
3701
3702 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3703 test_compare(value, uint64_t(1));
3704
3705 test_compare(MEMCACHED_SUCCESS,
3706 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
3707
3708 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3709 test_compare(MEMCACHED_HASH_MD5, memcached_hash_t(value));
3710
3711 return TEST_SUCCESS;
3712 }
3713
3714 static test_return_t pre_replication(memcached_st *memc)
3715 {
3716 test_skip(TEST_SUCCESS, pre_binary(memc));
3717
3718 /*
3719 * Make sure that we store the item on all servers
3720 * (master + replicas == number of servers)
3721 */
3722 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, memcached_server_count(memc) - 1));
3723 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS), uint64_t(memcached_server_count(memc) - 1));
3724
3725 return TEST_SUCCESS;
3726 }
3727
3728
3729 static test_return_t pre_replication_noblock(memcached_st *memc)
3730 {
3731 test_skip(TEST_SUCCESS, pre_replication(memc));
3732
3733 return pre_nonblock(memc);
3734 }
3735
3736
3737 static void my_free(const memcached_st *ptr, void *mem, void *context)
3738 {
3739 (void)context;
3740 (void)ptr;
3741 #ifdef HARD_MALLOC_TESTS
3742 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3743 free(real_ptr);
3744 #else
3745 free(mem);
3746 #endif
3747 }
3748
3749
3750 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
3751 {
3752 (void)context;
3753 (void)ptr;
3754 #ifdef HARD_MALLOC_TESTS
3755 void *ret= malloc(size + 8);
3756 if (ret != NULL)
3757 {
3758 ret= (void*)((caddr_t)ret + 8);
3759 }
3760 #else
3761 void *ret= malloc(size);
3762 #endif
3763
3764 if (ret != NULL)
3765 {
3766 memset(ret, 0xff, size);
3767 }
3768
3769 return ret;
3770 }
3771
3772
3773 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
3774 {
3775 #ifdef HARD_MALLOC_TESTS
3776 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3777 void *nmem= realloc(real_ptr, size + 8);
3778
3779 void *ret= NULL;
3780 if (nmem != NULL)
3781 {
3782 ret= (void*)((caddr_t)nmem + 8);
3783 }
3784
3785 return ret;
3786 #else
3787 (void)ptr;
3788 return realloc(mem, size);
3789 #endif
3790 }
3791
3792
3793 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
3794 {
3795 #ifdef HARD_MALLOC_TESTS
3796 void *mem= my_malloc(ptr, nelem * size);
3797 if (mem)
3798 {
3799 memset(mem, 0, nelem * size);
3800 }
3801
3802 return mem;
3803 #else
3804 (void)ptr;
3805 return calloc(nelem, size);
3806 #endif
3807 }
3808
3809 static test_return_t selection_of_namespace_tests(memcached_st *memc)
3810 {
3811 memcached_return_t rc;
3812 const char *key= "mine";
3813 char *value;
3814
3815 /* Make sure be default none exists */
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 /* Test a clean set */
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_memcmp(value, key, 4);
3827 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3828
3829 /* Test that we can turn it off */
3830 test_compare(MEMCACHED_SUCCESS,
3831 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
3832
3833 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3834 test_null(value);
3835 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3836
3837 /* Now setup for main test */
3838 test_compare(MEMCACHED_SUCCESS,
3839 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3840
3841 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3842 test_true(value);
3843 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3844 test_memcmp(value, key, 4);
3845
3846 /* Set to Zero, and then Set to something too large */
3847 {
3848 char long_key[255];
3849 memset(long_key, 0, 255);
3850
3851 test_compare(MEMCACHED_SUCCESS,
3852 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
3853
3854 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3855 test_null(value);
3856 test_compare(MEMCACHED_SUCCESS, rc);
3857
3858 /* Test a long key for failure */
3859 /* TODO, extend test to determine based on setting, what result should be */
3860 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
3861 test_compare(MEMCACHED_SUCCESS,
3862 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3863
3864 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3865 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
3866 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3867 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3868
3869 /* Test for a bad prefix, but with a short key */
3870 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
3871 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
3872
3873 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3874 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "dog cat"));
3875 }
3876
3877 return TEST_SUCCESS;
3878 }
3879
3880 static test_return_t set_namespace(memcached_st *memc)
3881 {
3882 memcached_return_t rc;
3883 const char *key= "mine";
3884 char *value;
3885
3886 // Make sure we default to a null namespace
3887 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3888 test_null(value);
3889 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3890
3891 /* Test a clean set */
3892 test_compare(MEMCACHED_SUCCESS,
3893 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3894
3895 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3896 test_true(value);
3897 test_memcmp(value, key, 4);
3898 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3899
3900 return TEST_SUCCESS;
3901 }
3902
3903 static test_return_t set_namespace_and_binary(memcached_st *memc)
3904 {
3905 test_return_if(pre_binary(memc));
3906 test_return_if(set_namespace(memc));
3907
3908 return TEST_SUCCESS;
3909 }
3910
3911 #ifdef MEMCACHED_ENABLE_DEPRECATED
3912 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3913 {
3914 void *test_ptr= NULL;
3915 void *cb_ptr= NULL;
3916 {
3917 memcached_malloc_fn malloc_cb=
3918 (memcached_malloc_fn)my_malloc;
3919 cb_ptr= *(void **)&malloc_cb;
3920 memcached_return_t rc;
3921
3922 test_compare(MEMCACHED_SUCCESS,
3923 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
3924 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3925 test_compare(MEMCACHED_SUCCESS, rc);
3926 test_true(test_ptr == cb_ptr);
3927 }
3928
3929 {
3930 memcached_realloc_fn realloc_cb=
3931 (memcached_realloc_fn)my_realloc;
3932 cb_ptr= *(void **)&realloc_cb;
3933 memcached_return_t rc;
3934
3935 test_compare(MEMCACHED_SUCCESS,
3936 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
3937 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3938 test_compare(MEMCACHED_SUCCESS, rc);
3939 test_true(test_ptr == cb_ptr);
3940 }
3941
3942 {
3943 memcached_free_fn free_cb=
3944 (memcached_free_fn)my_free;
3945 cb_ptr= *(void **)&free_cb;
3946 memcached_return_t rc;
3947
3948 test_compare(MEMCACHED_SUCCESS,
3949 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
3950 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3951 test_compare(MEMCACHED_SUCCESS, rc);
3952 test_true(test_ptr == cb_ptr);
3953 }
3954
3955 return TEST_SUCCESS;
3956 }
3957 #endif
3958
3959
3960 static test_return_t set_memory_alloc(memcached_st *memc)
3961 {
3962 test_compare(MEMCACHED_INVALID_ARGUMENTS,
3963 memcached_set_memory_allocators(memc, NULL, my_free,
3964 my_realloc, my_calloc, NULL));
3965
3966 test_compare(MEMCACHED_SUCCESS,
3967 memcached_set_memory_allocators(memc, my_malloc, my_free,
3968 my_realloc, my_calloc, NULL));
3969
3970 memcached_malloc_fn mem_malloc;
3971 memcached_free_fn mem_free;
3972 memcached_realloc_fn mem_realloc;
3973 memcached_calloc_fn mem_calloc;
3974 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3975 &mem_realloc, &mem_calloc);
3976
3977 test_true(mem_malloc == my_malloc);
3978 test_true(mem_realloc == my_realloc);
3979 test_true(mem_calloc == my_calloc);
3980 test_true(mem_free == my_free);
3981
3982 return TEST_SUCCESS;
3983 }
3984
3985 static test_return_t enable_consistent_crc(memcached_st *memc)
3986 {
3987 test_return_t rc;
3988 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3989 memcached_hash_t hash;
3990 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3991 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3992 return rc;
3993
3994 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3995 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3996
3997 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3998
3999 if (hash != MEMCACHED_HASH_CRC)
4000 return TEST_SKIPPED;
4001
4002 return TEST_SUCCESS;
4003 }
4004
4005 static test_return_t enable_consistent_hsieh(memcached_st *memc)
4006 {
4007 test_return_t rc;
4008 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4009 memcached_hash_t hash;
4010 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4011 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
4012 {
4013 return rc;
4014 }
4015
4016 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4017 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4018
4019 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4020
4021 if (hash != MEMCACHED_HASH_HSIEH)
4022 return TEST_SKIPPED;
4023
4024
4025 return TEST_SUCCESS;
4026 }
4027
4028 static test_return_t enable_cas(memcached_st *memc)
4029 {
4030 unsigned int set= 1;
4031
4032 if (libmemcached_util_version_check(memc, 1, 2, 4))
4033 {
4034 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
4035
4036 return TEST_SUCCESS;
4037 }
4038
4039 return TEST_SKIPPED;
4040 }
4041
4042 static test_return_t check_for_1_2_3(memcached_st *memc)
4043 {
4044 memcached_version(memc);
4045
4046 memcached_server_instance_st instance=
4047 memcached_server_instance_by_position(memc, 0);
4048
4049 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
4050 or instance->minor_version > 2)
4051 {
4052 return TEST_SUCCESS;
4053 }
4054
4055 return TEST_SKIPPED;
4056 }
4057
4058 static test_return_t pre_unix_socket(memcached_st *memc)
4059 {
4060 struct stat buf;
4061
4062 memcached_servers_reset(memc);
4063 const char *socket_file= default_socket();
4064
4065 test_skip(0, stat(socket_file, &buf));
4066
4067 test_compare(MEMCACHED_SUCCESS,
4068 memcached_server_add_unix_socket_with_weight(memc, socket_file, 0));
4069
4070 return TEST_SUCCESS;
4071 }
4072
4073 static test_return_t pre_nodelay(memcached_st *memc)
4074 {
4075 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4076 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4077
4078 return TEST_SUCCESS;
4079 }
4080
4081 static test_return_t pre_settimer(memcached_st *memc)
4082 {
4083 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4084 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4085
4086 return TEST_SUCCESS;
4087 }
4088
4089 static test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc)
4090 {
4091 const uint64_t timeout= 100; // Not using, just checking that it sets
4092
4093 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4094
4095 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
4096
4097 return TEST_SUCCESS;
4098 }
4099
4100 static test_return_t noreply_test(memcached_st *memc)
4101 {
4102 test_compare(MEMCACHED_SUCCESS,
4103 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
4104 test_compare(MEMCACHED_SUCCESS,
4105 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
4106 test_compare(MEMCACHED_SUCCESS,
4107 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
4108 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
4109 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
4110 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS));
4111
4112 memcached_return_t ret;
4113 for (int count= 0; count < 5; ++count)
4114 {
4115 for (size_t x= 0; x < 100; ++x)
4116 {
4117 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
4118 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4119 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4120
4121 size_t len= (size_t)check_length;
4122
4123 switch (count)
4124 {
4125 case 0:
4126 ret= memcached_add(memc, key, len, key, len, 0, 0);
4127 break;
4128 case 1:
4129 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4130 break;
4131 case 2:
4132 ret= memcached_set(memc, key, len, key, len, 0, 0);
4133 break;
4134 case 3:
4135 ret= memcached_append(memc, key, len, key, len, 0, 0);
4136 break;
4137 case 4:
4138 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4139 break;
4140 default:
4141 test_true(count);
4142 break;
4143 }
4144 test_true_got(ret == MEMCACHED_SUCCESS or ret == MEMCACHED_BUFFERED, memcached_strerror(NULL, ret));
4145 }
4146
4147 /*
4148 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4149 ** API and is _ONLY_ done this way to verify that the library works the
4150 ** way it is supposed to do!!!!
4151 */
4152 #if 0
4153 int no_msg=0;
4154 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4155 {
4156 memcached_server_instance_st instance=
4157 memcached_server_instance_by_position(memc, x);
4158 no_msg+=(int)(instance->cursor_active);
4159 }
4160
4161 test_true(no_msg == 0);
4162 #endif
4163 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
4164
4165 /*
4166 ** Now validate that all items was set properly!
4167 */
4168 for (size_t x= 0; x < 100; ++x)
4169 {
4170 char key[10];
4171
4172 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4173
4174 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4175
4176 size_t len= (size_t)check_length;
4177 size_t length;
4178 uint32_t flags;
4179 char* value=memcached_get(memc, key, strlen(key),
4180 &length, &flags, &ret);
4181 test_true_got(ret == MEMCACHED_SUCCESS && value != NULL, memcached_strerror(NULL, ret));
4182 switch (count)
4183 {
4184 case 0: /* FALLTHROUGH */
4185 case 1: /* FALLTHROUGH */
4186 case 2:
4187 test_true(strncmp(value, key, len) == 0);
4188 test_true(len == length);
4189 break;
4190 case 3:
4191 test_true(length == len * 2);
4192 break;
4193 case 4:
4194 test_true(length == len * 3);
4195 break;
4196 default:
4197 test_true(count);
4198 break;
4199 }
4200 free(value);
4201 }
4202 }
4203
4204 /* Try setting an illegal cas value (should not return an error to
4205 * the caller (because we don't expect a return message from the server)
4206 */
4207 const char* keys[]= {"0"};
4208 size_t lengths[]= {1};
4209 size_t length;
4210 uint32_t flags;
4211 memcached_result_st results_obj;
4212 memcached_result_st *results;
4213 test_compare(MEMCACHED_SUCCESS,
4214 memcached_mget(memc, keys, lengths, 1));
4215
4216 results= memcached_result_create(memc, &results_obj);
4217 test_true(results);
4218 results= memcached_fetch_result(memc, &results_obj, &ret);
4219 test_true(results);
4220 test_compare(MEMCACHED_SUCCESS, ret);
4221 uint64_t cas= memcached_result_cas(results);
4222 memcached_result_free(&results_obj);
4223
4224 test_compare(MEMCACHED_SUCCESS,
4225 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
4226
4227 /*
4228 * The item will have a new cas value, so try to set it again with the old
4229 * value. This should fail!
4230 */
4231 test_compare(MEMCACHED_SUCCESS,
4232 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
4233 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4234 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4235 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4236 free(value);
4237
4238 return TEST_SUCCESS;
4239 }
4240
4241 static test_return_t analyzer_test(memcached_st *memc)
4242 {
4243 memcached_analysis_st *report;
4244 memcached_return_t rc;
4245
4246 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
4247 test_compare(MEMCACHED_SUCCESS, rc);
4248 test_true(memc_stat);
4249
4250 report= memcached_analyze(memc, memc_stat, &rc);
4251 test_compare(MEMCACHED_SUCCESS, rc);
4252 test_true(report);
4253
4254 free(report);
4255 memcached_stat_free(NULL, memc_stat);
4256
4257 return TEST_SUCCESS;
4258 }
4259
4260 static test_return_t util_version_test(memcached_st *memc)
4261 {
4262 test_compare_hint(MEMCACHED_SUCCESS, memcached_version(memc), memcached_last_error_message(memc));
4263 test_true(libmemcached_util_version_check(memc, 0, 0, 0));
4264
4265 bool if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
4266
4267 // We expect failure
4268 if (if_successful)
4269 {
4270 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4271 fprintf(stderr, "\nDumping Server Information\n\n");
4272 memcached_server_fn callbacks[1];
4273
4274 callbacks[0]= dump_server_information;
4275 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
4276 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4277 }
4278 test_true(if_successful == false);
4279
4280 memcached_server_instance_st instance=
4281 memcached_server_instance_by_position(memc, 0);
4282
4283 memcached_version(memc);
4284
4285 // We only use one binary when we test, so this should be just fine.
4286 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
4287 test_true(if_successful == true);
4288
4289 if (instance->micro_version > 0)
4290 {
4291 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
4292 }
4293 else if (instance->minor_version > 0)
4294 {
4295 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4296 }
4297 else if (instance->major_version > 0)
4298 {
4299 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
4300 }
4301
4302 test_true(if_successful == true);
4303
4304 if (instance->micro_version > 0)
4305 {
4306 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
4307 }
4308 else if (instance->minor_version > 0)
4309 {
4310 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4311 }
4312 else if (instance->major_version > 0)
4313 {
4314 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
4315 }
4316
4317 test_true(if_successful == false);
4318
4319 return TEST_SUCCESS;
4320 }
4321
4322 static test_return_t getpid_connection_failure_test(memcached_st *memc)
4323 {
4324 memcached_return_t rc;
4325 memcached_server_instance_st instance=
4326 memcached_server_instance_by_position(memc, 0);
4327
4328 // Test both the version that returns a code, and the one that does not.
4329 test_true(libmemcached_util_getpid(memcached_server_name(instance),
4330 memcached_server_port(instance) -1, NULL) == -1);
4331
4332 test_true(libmemcached_util_getpid(memcached_server_name(instance),
4333 memcached_server_port(instance) -1, &rc) == -1);
4334 test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(memc, rc));
4335
4336 return TEST_SUCCESS;
4337 }
4338
4339
4340 static test_return_t getpid_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_getpid(memcached_server_name(instance),
4348 memcached_server_port(instance), NULL) > -1);
4349
4350 test_true(libmemcached_util_getpid(memcached_server_name(instance),
4351 memcached_server_port(instance), &rc) > -1);
4352 test_compare(MEMCACHED_SUCCESS, rc);
4353
4354 return TEST_SUCCESS;
4355 }
4356
4357 static test_return_t ping_test(memcached_st *memc)
4358 {
4359 memcached_return_t rc;
4360 memcached_server_instance_st instance=
4361 memcached_server_instance_by_position(memc, 0);
4362
4363 // Test both the version that returns a code, and the one that does not.
4364 test_true(libmemcached_util_ping(memcached_server_name(instance),
4365 memcached_server_port(instance), NULL));
4366
4367 test_true(libmemcached_util_ping(memcached_server_name(instance),
4368 memcached_server_port(instance), &rc));
4369
4370 test_compare(MEMCACHED_SUCCESS, rc);
4371
4372 return TEST_SUCCESS;
4373 }
4374
4375
4376 #if 0
4377 static test_return_t hash_sanity_test (memcached_st *memc)
4378 {
4379 (void)memc;
4380
4381 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4382 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4383 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4384 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4385 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4386 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4387 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4388 #ifdef HAVE_HSIEH_HASH
4389 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4390 #endif
4391 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4392 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4393 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4394
4395 return TEST_SUCCESS;
4396 }
4397 #endif
4398
4399 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4400 {
4401 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
4402
4403 test_compare(MEMCACHED_SUCCESS,
4404 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4405 (uint64_t)MEMCACHED_HASH_HSIEH));
4406
4407 return TEST_SUCCESS;
4408 }
4409
4410 static test_return_t murmur_avaibility_test (memcached_st *memc)
4411 {
4412 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
4413
4414 test_compare(MEMCACHED_SUCCESS,
4415 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
4416
4417 return TEST_SUCCESS;
4418 }
4419
4420 static test_return_t one_at_a_time_run (memcached_st *)
4421 {
4422 uint32_t x;
4423 const char **ptr;
4424
4425 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4426 {
4427 test_compare(one_at_a_time_values[x],
4428 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT));
4429 }
4430
4431 return TEST_SUCCESS;
4432 }
4433
4434 static test_return_t md5_run (memcached_st *)
4435 {
4436 uint32_t x;
4437 const char **ptr;
4438
4439 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4440 {
4441 test_compare(md5_values[x],
4442 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5));
4443 }
4444
4445 return TEST_SUCCESS;
4446 }
4447
4448 static test_return_t crc_run (memcached_st *)
4449 {
4450 uint32_t x;
4451 const char **ptr;
4452
4453 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4454 {
4455 test_compare(crc_values[x],
4456 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC));
4457 }
4458
4459 return TEST_SUCCESS;
4460 }
4461
4462 static test_return_t fnv1_64_run (memcached_st *)
4463 {
4464 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1_64));
4465
4466 uint32_t x;
4467 const char **ptr;
4468
4469 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4470 {
4471 test_compare(fnv1_64_values[x],
4472 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64));
4473 }
4474
4475 return TEST_SUCCESS;
4476 }
4477
4478 static test_return_t fnv1a_64_run (memcached_st *)
4479 {
4480 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1A_64));
4481
4482 uint32_t x;
4483 const char **ptr;
4484
4485 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4486 {
4487 test_compare(fnv1a_64_values[x],
4488 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64));
4489 }
4490
4491 return TEST_SUCCESS;
4492 }
4493
4494 static test_return_t fnv1_32_run (memcached_st *)
4495 {
4496 uint32_t x;
4497 const char **ptr;
4498
4499 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4500 {
4501 test_compare(fnv1_32_values[x],
4502 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32));
4503 }
4504
4505 return TEST_SUCCESS;
4506 }
4507
4508 static test_return_t fnv1a_32_run (memcached_st *)
4509 {
4510 uint32_t x;
4511 const char **ptr;
4512
4513 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4514 {
4515 test_compare(fnv1a_32_values[x],
4516 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32));
4517 }
4518
4519 return TEST_SUCCESS;
4520 }
4521
4522 static test_return_t hsieh_run (memcached_st *)
4523 {
4524 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
4525
4526 uint32_t x;
4527 const char **ptr;
4528
4529 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4530 {
4531 test_compare(hsieh_values[x],
4532 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH));
4533 }
4534
4535 return TEST_SUCCESS;
4536 }
4537
4538 static test_return_t murmur_run (memcached_st *)
4539 {
4540 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
4541
4542 #ifdef WORDS_BIGENDIAN
4543 (void)murmur_values;
4544 return TEST_SKIPPED;
4545 #else
4546 uint32_t x;
4547 const char **ptr;
4548
4549 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4550 {
4551 test_compare(murmur_values[x],
4552 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR));
4553 }
4554
4555 return TEST_SUCCESS;
4556 #endif
4557 }
4558
4559 static test_return_t jenkins_run (memcached_st *)
4560 {
4561 uint32_t x;
4562 const char **ptr;
4563
4564 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4565 {
4566 test_compare(jenkins_values[x],
4567 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS));
4568 }
4569
4570 return TEST_SUCCESS;
4571 }
4572
4573 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *)
4574 {
4575 return libhashkit_md5(string, string_length);
4576 }
4577
4578 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *)
4579 {
4580 return libhashkit_crc32(string, string_length);
4581 }
4582
4583 static test_return_t memcached_get_hashkit_test (memcached_st *)
4584 {
4585 uint32_t x;
4586 const char **ptr;
4587 hashkit_st new_kit;
4588
4589 memcached_st *memc= memcached(test_literal_param("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5 --DISTRIBUTION=modula"));
4590
4591 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};
4592 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};
4593
4594 const hashkit_st *kit= memcached_get_hashkit(memc);
4595
4596 hashkit_clone(&new_kit, kit);
4597 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL));
4598
4599 memcached_set_hashkit(memc, &new_kit);
4600
4601 /*
4602 Verify Setting the hash.
4603 */
4604 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4605 {
4606 uint32_t hash_val;
4607
4608 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4609 test_compare_got(md5_values[x], hash_val, *ptr);
4610 }
4611
4612
4613 /*
4614 Now check memcached_st.
4615 */
4616 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4617 {
4618 uint32_t hash_val;
4619
4620 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4621 test_compare_got(md5_hosts[x], hash_val, *ptr);
4622 }
4623
4624 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL));
4625
4626 memcached_set_hashkit(memc, &new_kit);
4627
4628 /*
4629 Verify Setting the hash.
4630 */
4631 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4632 {
4633 uint32_t hash_val;
4634
4635 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4636 test_true(crc_values[x] == hash_val);
4637 }
4638
4639 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4640 {
4641 uint32_t hash_val;
4642
4643 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4644 test_compare(crc_hosts[x], hash_val);
4645 }
4646
4647 memcached_free(memc);
4648
4649 return TEST_SUCCESS;
4650 }
4651
4652 /*
4653 Test case adapted from John Gorman <johngorman2@gmail.com>
4654
4655 We are testing the error condition when we connect to a server via memcached_get()
4656 but find that the server is not available.
4657 */
4658 static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
4659 {
4660 const char *key= "MemcachedLives";
4661 size_t len;
4662 uint32_t flags;
4663 memcached_return rc;
4664
4665 // Create a handle.
4666 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
4667
4668 // See if memcached is reachable.
4669 char *value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
4670
4671 test_false(value);
4672 test_zero(len);
4673 test_true(memcached_failed(rc));
4674
4675 memcached_free(tl_memc_h);
4676
4677 return TEST_SUCCESS;
4678 }
4679
4680 /*
4681 We connect to a server which exists, but search for a key that does not exist.
4682 */
4683 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
4684 {
4685 const char *key= "MemcachedKeyNotEXIST";
4686 size_t len;
4687 uint32_t flags;
4688 memcached_return rc;
4689
4690 // See if memcached is reachable.
4691 char *value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
4692
4693 test_false(value);
4694 test_zero(len);
4695 test_compare(MEMCACHED_NOTFOUND, rc);
4696
4697 return TEST_SUCCESS;
4698 }
4699
4700 /*
4701 Test case adapted from John Gorman <johngorman2@gmail.com>
4702
4703 We are testing the error condition when we connect to a server via memcached_get_by_key()
4704 but find that the server is not available.
4705 */
4706 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
4707 {
4708 (void)memc;
4709 memcached_st *tl_memc_h;
4710 memcached_server_st *servers;
4711
4712 const char *key= "MemcachedLives";
4713 size_t len;
4714 uint32_t flags;
4715 memcached_return rc;
4716 char *value;
4717
4718 // Create a handle.
4719 tl_memc_h= memcached_create(NULL);
4720 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4721 memcached_server_push(tl_memc_h, servers);
4722 memcached_server_list_free(servers);
4723
4724 // See if memcached is reachable.
4725 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4726
4727 test_false(value);
4728 test_zero(len);
4729 test_true(memcached_failed(rc));
4730
4731 memcached_free(tl_memc_h);
4732
4733 return TEST_SUCCESS;
4734 }
4735
4736 /*
4737 We connect to a server which exists, but search for a key that does not exist.
4738 */
4739 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
4740 {
4741 const char *key= "MemcachedKeyNotEXIST";
4742 size_t len;
4743 uint32_t flags;
4744 memcached_return rc;
4745 char *value;
4746
4747 // See if memcached is reachable.
4748 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4749
4750 test_false(value);
4751 test_zero(len);
4752 test_compare(MEMCACHED_NOTFOUND, rc);
4753
4754 return TEST_SUCCESS;
4755 }
4756
4757 static test_return_t regression_bug_434484(memcached_st *memc)
4758 {
4759 test_skip(TEST_SUCCESS, pre_binary(memc));
4760
4761 const char *key= "regression_bug_434484";
4762 size_t keylen= strlen(key);
4763
4764 memcached_return_t ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
4765 test_compare(MEMCACHED_NOTSTORED, ret);
4766
4767 size_t size= 2048 * 1024;
4768 char *data= (char*)calloc(1, size);
4769 test_true(data);
4770 test_compare(MEMCACHED_E2BIG,
4771 memcached_set(memc, key, keylen, data, size, 0, 0));
4772 free(data);
4773
4774 return TEST_SUCCESS;
4775 }
4776
4777 static test_return_t regression_bug_434843(memcached_st *original_memc)
4778 {
4779 test_skip(TEST_SUCCESS, pre_binary(original_memc));
4780
4781 memcached_return_t rc;
4782 size_t counter= 0;
4783 memcached_execute_fn callbacks[]= { &callback_counter };
4784
4785 /*
4786 * I only want to hit only _one_ server so I know the number of requests I'm
4787 * sending in the pipleine to the server. Let's try to do a multiget of
4788 * 1024 (that should satisfy most users don't you think?). Future versions
4789 * will include a mget_execute function call if you need a higher number.
4790 */
4791 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
4792
4793 const size_t max_keys= 1024;
4794 char **keys= (char**)calloc(max_keys, sizeof(char*));
4795 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
4796
4797 for (size_t x= 0; x < max_keys; ++x)
4798 {
4799 char k[251];
4800
4801 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
4802 keys[x]= strdup(k);
4803 test_true(keys[x]);
4804 }
4805
4806 /*
4807 * Run two times.. the first time we should have 100% cache miss,
4808 * and the second time we should have 100% cache hits
4809 */
4810 for (size_t y= 0; y < 2; y++)
4811 {
4812 test_compare(MEMCACHED_SUCCESS,
4813 memcached_mget(memc, (const char**)keys, key_length, max_keys));
4814
4815 // One the first run we should get a NOT_FOUND, but on the second some data
4816 // should be returned.
4817 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
4818 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4819
4820 if (y == 0)
4821 {
4822 /* The first iteration should give me a 100% cache miss. verify that*/
4823 char blob[1024]= { 0 };
4824
4825 test_false(counter);
4826
4827 for (size_t x= 0; x < max_keys; ++x)
4828 {
4829 rc= memcached_add(memc, keys[x], key_length[x],
4830 blob, sizeof(blob), 0, 0);
4831 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4832 }
4833 }
4834 else
4835 {
4836 /* Verify that we received all of the key/value pairs */
4837 test_compare(counter, max_keys);
4838 }
4839 }
4840
4841 /* Release allocated resources */
4842 for (size_t x= 0; x < max_keys; ++x)
4843 {
4844 free(keys[x]);
4845 }
4846 free(keys);
4847 free(key_length);
4848
4849 memcached_free(memc);
4850
4851 return TEST_SUCCESS;
4852 }
4853
4854 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
4855 {
4856 memcached_return_t rc;
4857 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4858 test_compare(MEMCACHED_SUCCESS, rc);
4859
4860 return regression_bug_434843(memc);
4861 }
4862
4863 static test_return_t regression_bug_421108(memcached_st *memc)
4864 {
4865 memcached_return_t rc;
4866 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
4867 test_compare(MEMCACHED_SUCCESS, rc);
4868
4869 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
4870 test_compare(MEMCACHED_SUCCESS, rc);
4871 test_true(bytes_str);
4872 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
4873 "bytes_read", &rc);
4874 test_compare(MEMCACHED_SUCCESS, rc);
4875 test_true(bytes_read_str);
4876
4877 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
4878 "bytes_written", &rc);
4879 test_compare(MEMCACHED_SUCCESS, rc);
4880 test_true(bytes_written_str);
4881
4882 unsigned long long bytes= strtoull(bytes_str, 0, 10);
4883 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
4884 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
4885
4886 test_true(bytes != bytes_read);
4887 test_true(bytes != bytes_written);
4888
4889 /* Release allocated resources */
4890 free(bytes_str);
4891 free(bytes_read_str);
4892 free(bytes_written_str);
4893 memcached_stat_free(NULL, memc_stat);
4894
4895 return TEST_SUCCESS;
4896 }
4897
4898 /*
4899 * The test case isn't obvious so I should probably document why
4900 * it works the way it does. Bug 442914 was caused by a bug
4901 * in the logic in memcached_purge (it did not handle the case
4902 * where the number of bytes sent was equal to the watermark).
4903 * In this test case, create messages so that we hit that case
4904 * and then disable noreply mode and issue a new command to
4905 * verify that it isn't stuck. If we change the format for the
4906 * delete command or the watermarks, we need to update this
4907 * test....
4908 */
4909 static test_return_t regression_bug_442914(memcached_st *memc)
4910 {
4911 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
4912 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
4913
4914 uint32_t number_of_hosts= memcached_server_count(memc);
4915 memc->number_of_hosts= 1;
4916
4917 char k[250];
4918 size_t len;
4919
4920 for (uint32_t x= 0; x < 250; ++x)
4921 {
4922 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
4923 memcached_return_t rc= memcached_delete(memc, k, len, 0);
4924 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4925 }
4926
4927 len= snprintf(k, sizeof(k), "%037u", 251U);
4928
4929 memcached_return_t rc= memcached_delete(memc, k, len, 0);
4930 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4931
4932 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
4933 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, k, len, 0));
4934
4935 memc->number_of_hosts= number_of_hosts;
4936
4937 return TEST_SUCCESS;
4938 }
4939
4940 static test_return_t regression_bug_447342(memcached_st *memc)
4941 {
4942 memcached_server_instance_st instance_one;
4943 memcached_server_instance_st instance_two;
4944
4945 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
4946 return TEST_SKIPPED;
4947
4948 test_compare(MEMCACHED_SUCCESS,
4949 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
4950
4951 const unsigned int max_keys= 100;
4952 char **keys= (char**)calloc(max_keys, sizeof(char*));
4953 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
4954
4955 for (unsigned int x= 0; x < max_keys; ++x)
4956 {
4957 char k[251];
4958
4959 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
4960 keys[x]= strdup(k);
4961 test_true(keys[x]);
4962 test_compare(MEMCACHED_SUCCESS,
4963 memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0));
4964 }
4965
4966 /*
4967 ** We are using the quiet commands to store the replicas, so we need
4968 ** to ensure that all of them are processed before we can continue.
4969 ** In the test we go directly from storing the object to trying to
4970 ** receive the object from all of the different servers, so we
4971 ** could end up in a race condition (the memcached server hasn't yet
4972 ** processed the quiet command from the replication set when it process
4973 ** the request from the other client (created by the clone)). As a
4974 ** workaround for that we call memcached_quit to send the quit command
4975 ** to the server and wait for the response ;-) If you use the test code
4976 ** as an example for your own code, please note that you shouldn't need
4977 ** to do this ;-)
4978 */
4979 memcached_quit(memc);
4980
4981 /* Verify that all messages are stored, and we didn't stuff too much
4982 * into the servers
4983 */
4984 test_compare(MEMCACHED_SUCCESS,
4985 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
4986
4987 unsigned int counter= 0;
4988 memcached_execute_fn callbacks[]= { &callback_counter };
4989 test_compare(MEMCACHED_SUCCESS,
4990 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4991
4992 /* Verify that we received all of the key/value pairs */
4993 test_compare(counter, max_keys);
4994
4995 memcached_quit(memc);
4996 /*
4997 * Don't do the following in your code. I am abusing the internal details
4998 * within the library, and this is not a supported interface.
4999 * This is to verify correct behavior in the library. Fake that two servers
5000 * are dead..
5001 */
5002 instance_one= memcached_server_instance_by_position(memc, 0);
5003 instance_two= memcached_server_instance_by_position(memc, 2);
5004 in_port_t port0= instance_one->port;
5005 in_port_t port2= instance_two->port;
5006
5007 ((memcached_server_write_instance_st)instance_one)->port= 0;
5008 ((memcached_server_write_instance_st)instance_two)->port= 0;
5009
5010 test_compare(MEMCACHED_SUCCESS,
5011 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5012
5013 counter= 0;
5014 test_compare(MEMCACHED_SUCCESS,
5015 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5016 test_compare(counter, (unsigned int)max_keys);
5017
5018 /* restore the memc handle */
5019 ((memcached_server_write_instance_st)instance_one)->port= port0;
5020 ((memcached_server_write_instance_st)instance_two)->port= port2;
5021
5022 memcached_quit(memc);
5023
5024 /* Remove half of the objects */
5025 for (size_t x= 0; x < max_keys; ++x)
5026 {
5027 if (x & 1)
5028 {
5029 test_compare(MEMCACHED_SUCCESS,
5030 memcached_delete(memc, keys[x], key_length[x], 0));
5031 }
5032 }
5033
5034 memcached_quit(memc);
5035 ((memcached_server_write_instance_st)instance_one)->port= 0;
5036 ((memcached_server_write_instance_st)instance_two)->port= 0;
5037
5038 /* now retry the command, this time we should have cache misses */
5039 test_compare(MEMCACHED_SUCCESS,
5040 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5041
5042 counter= 0;
5043 test_compare(MEMCACHED_SUCCESS,
5044 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5045 test_compare(counter, (unsigned int)(max_keys >> 1));
5046
5047 /* Release allocated resources */
5048 for (size_t x= 0; x < max_keys; ++x)
5049 {
5050 free(keys[x]);
5051 }
5052 free(keys);
5053 free(key_length);
5054
5055 /* restore the memc handle */
5056 ((memcached_server_write_instance_st)instance_one)->port= port0;
5057 ((memcached_server_write_instance_st)instance_two)->port= port2;
5058
5059 return TEST_SUCCESS;
5060 }
5061
5062 static test_return_t regression_bug_463297(memcached_st *memc)
5063 {
5064 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc, "foo", 3, 1));
5065
5066 // Since we blocked timed delete, this test is no longer valid.
5067 #if 0
5068 memcached_st *memc_clone= memcached_clone(NULL, memc);
5069 test_true(memc_clone);
5070 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5071
5072 memcached_server_instance_st instance=
5073 memcached_server_instance_by_position(memc_clone, 0);
5074
5075 if (instance->major_version > 1 ||
5076 (instance->major_version == 1 &&
5077 instance->minor_version > 2))
5078 {
5079 /* Binary protocol doesn't support deferred delete */
5080 memcached_st *bin_clone= memcached_clone(NULL, memc);
5081 test_true(bin_clone);
5082 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
5083 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
5084 memcached_free(bin_clone);
5085
5086 memcached_quit(memc_clone);
5087
5088 /* If we know the server version, deferred delete should fail
5089 * with invalid arguments */
5090 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
5091
5092 /* If we don't know the server version, we should get a protocol error */
5093 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5094
5095 /* but there is a bug in some of the memcached servers (1.4) that treats
5096 * the counter as noreply so it doesn't send the proper error message
5097 */
5098 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5099
5100 /* And buffered mode should be disabled and we should get protocol error */
5101 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5102 rc= memcached_delete(memc, "foo", 3, 1);
5103 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5104
5105 /* Same goes for noreply... */
5106 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
5107 rc= memcached_delete(memc, "foo", 3, 1);
5108 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5109
5110 /* but a normal request should go through (and be buffered) */
5111 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
5112 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
5113
5114 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
5115 /* unbuffered noreply should be success */
5116 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
5117 /* unbuffered with reply should be not found... */
5118 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
5119 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
5120 }
5121
5122 memcached_free(memc_clone);
5123 #endif
5124
5125 return TEST_SUCCESS;
5126 }
5127
5128
5129 /* Test memcached_server_get_last_disconnect
5130 * For a working server set, shall be NULL
5131 * For a set of non existing server, shall not be NULL
5132 */
5133 static test_return_t test_get_last_disconnect(memcached_st *memc)
5134 {
5135 memcached_return_t rc;
5136 memcached_server_instance_st disconnected_server;
5137
5138 /* With the working set of server */
5139 const char *key= "marmotte";
5140 const char *value= "milka";
5141
5142 memcached_reset_last_disconnected_server(memc);
5143 test_false(memc->last_disconnected_server);
5144 rc= memcached_set(memc, key, strlen(key),
5145 value, strlen(value),
5146 (time_t)0, (uint32_t)0);
5147 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5148
5149 disconnected_server = memcached_server_get_last_disconnect(memc);
5150 test_false(disconnected_server);
5151
5152 /* With a non existing server */
5153 memcached_st *mine;
5154 memcached_server_st *servers;
5155
5156 const char *server_list= "localhost:9";
5157
5158 servers= memcached_servers_parse(server_list);
5159 test_true(servers);
5160 mine= memcached_create(NULL);
5161 rc= memcached_server_push(mine, servers);
5162 test_compare(MEMCACHED_SUCCESS, rc);
5163 memcached_server_list_free(servers);
5164 test_true(mine);
5165
5166 rc= memcached_set(mine, key, strlen(key),
5167 value, strlen(value),
5168 (time_t)0, (uint32_t)0);
5169 test_true(memcached_failed(rc));
5170
5171 disconnected_server= memcached_server_get_last_disconnect(mine);
5172 test_true_got(disconnected_server, memcached_strerror(mine, rc));
5173 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
5174 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
5175
5176 memcached_quit(mine);
5177 memcached_free(mine);
5178
5179 return TEST_SUCCESS;
5180 }
5181
5182 static test_return_t test_multiple_get_last_disconnect(memcached_st *)
5183 {
5184 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
5185 char buffer[BUFSIZ];
5186
5187 test_compare(MEMCACHED_SUCCESS,
5188 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
5189
5190 memcached_st *memc= memcached(server_string, strlen(server_string));
5191 test_true(memc);
5192
5193 // We will just use the error strings as our keys
5194 uint32_t counter= 100;
5195 while (--counter)
5196 {
5197 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
5198 {
5199 const char *msg= memcached_strerror(memc, memcached_return_t(x));
5200 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
5201 test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
5202
5203 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
5204 test_true(disconnected_server);
5205 test_strcmp("localhost", memcached_server_name(disconnected_server));
5206 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
5207
5208 if (random() % 2)
5209 {
5210 memcached_reset_last_disconnected_server(memc);
5211 }
5212 }
5213 }
5214
5215 memcached_free(memc);
5216
5217 return TEST_SUCCESS;
5218 }
5219
5220 static test_return_t test_verbosity(memcached_st *memc)
5221 {
5222 memcached_verbosity(memc, 3);
5223
5224 return TEST_SUCCESS;
5225 }
5226
5227
5228 static memcached_return_t stat_printer(memcached_server_instance_st server,
5229 const char *key, size_t key_length,
5230 const char *value, size_t value_length,
5231 void *context)
5232 {
5233 (void)server;
5234 (void)context;
5235 (void)key;
5236 (void)key_length;
5237 (void)value;
5238 (void)value_length;
5239
5240 return MEMCACHED_SUCCESS;
5241 }
5242
5243 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5244 {
5245 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5246 test_compare(MEMCACHED_SUCCESS, rc);
5247
5248 test_compare(MEMCACHED_SUCCESS,
5249 memcached_stat_execute(memc, "slabs", stat_printer, NULL));
5250
5251 test_compare(MEMCACHED_SUCCESS,
5252 memcached_stat_execute(memc, "items", stat_printer, NULL));
5253
5254 test_compare(MEMCACHED_SUCCESS,
5255 memcached_stat_execute(memc, "sizes", stat_printer, NULL));
5256
5257 return TEST_SUCCESS;
5258 }
5259
5260 /*
5261 * This test ensures that the failure counter isn't incremented during
5262 * normal termination of the memcached instance.
5263 */
5264 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5265 {
5266 memcached_return_t rc;
5267 memcached_server_instance_st instance;
5268
5269 /* Set value to force connection to the server */
5270 const char *key= "marmotte";
5271 const char *value= "milka";
5272
5273 /*
5274 * Please note that I'm abusing the internal structures in libmemcached
5275 * in a non-portable way and you shouldn't be doing this. I'm only
5276 * doing this in order to verify that the library works the way it should
5277 */
5278 uint32_t number_of_hosts= memcached_server_count(memc);
5279 memc->number_of_hosts= 1;
5280
5281 /* Ensure that we are connected to the server by setting a value */
5282 rc= memcached_set(memc, key, strlen(key),
5283 value, strlen(value),
5284 (time_t)0, (uint32_t)0);
5285 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
5286
5287
5288 instance= memcached_server_instance_by_position(memc, 0);
5289 /* The test is to see that the memcached_quit doesn't increase the
5290 * the server failure conter, so let's ensure that it is zero
5291 * before sending quit
5292 */
5293 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5294
5295 memcached_quit(memc);
5296
5297 /* Verify that it memcached_quit didn't increment the failure counter
5298 * Please note that this isn't bullet proof, because an error could
5299 * occur...
5300 */
5301 test_zero(instance->server_failure_counter);
5302
5303 /* restore the instance */
5304 memc->number_of_hosts= number_of_hosts;
5305
5306 return TEST_SUCCESS;
5307 }
5308
5309 /*
5310 * This tests ensures expected disconnections (for some behavior changes
5311 * for instance) do not wrongly increase failure counter
5312 */
5313 static test_return_t wrong_failure_counter_two_test(memcached_st *memc)
5314 {
5315 /* Set value to force connection to the server */
5316 const char *key= "marmotte";
5317 const char *value= "milka";
5318
5319 test_compare_hint(MEMCACHED_SUCCESS,
5320 memcached_set(memc, key, strlen(key),
5321 value, strlen(value),
5322 (time_t)0, (uint32_t)0),
5323 memcached_last_error_message(memc));
5324
5325
5326 /* put failure limit to 1 */
5327 test_compare(MEMCACHED_SUCCESS,
5328 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, true));
5329
5330 /* Put a retry timeout to effectively activate failure_limit effect */
5331 test_compare(MEMCACHED_SUCCESS,
5332 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, true));
5333
5334 /* change behavior that triggers memcached_quit()*/
5335 test_compare(MEMCACHED_SUCCESS,
5336 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true));
5337
5338
5339 /* Check if we still are connected */
5340 uint32_t flags;
5341 size_t string_length;
5342 memcached_return rc;
5343 char *string= memcached_get(memc, key, strlen(key),
5344 &string_length, &flags, &rc);
5345
5346 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
5347 test_true(string);
5348 free(string);
5349
5350 return TEST_SUCCESS;
5351 }
5352
5353
5354 /*
5355 * Test that ensures mget_execute does not end into recursive calls that finally fails
5356 */
5357 static test_return_t regression_bug_490486(memcached_st *original_memc)
5358 {
5359
5360 #ifdef __APPLE__
5361 return TEST_SKIPPED; // My MAC can't handle this test
5362 #endif
5363
5364 test_skip(TEST_SUCCESS, pre_binary(original_memc));
5365
5366 /*
5367 * I only want to hit _one_ server so I know the number of requests I'm
5368 * sending in the pipeline.
5369 */
5370 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL --POLL-TIMEOUT=1000 --REMOVE-FAILED-SERVERS=1 --RETRY-TIMEOUT=3600");
5371 test_true(memc);
5372
5373 size_t max_keys= 20480;
5374
5375 char **keys= (char **)calloc(max_keys, sizeof(char*));
5376 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5377
5378 /* First add all of the items.. */
5379 char blob[1024]= { 0 };
5380 for (size_t x= 0; x < max_keys; ++x)
5381 {
5382 char k[251];
5383 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5384 keys[x]= strdup(k);
5385 test_true(keys[x]);
5386 memcached_return rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5387 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
5388 }
5389
5390 {
5391
5392 /* Try to get all of them with a large multiget */
5393 size_t counter= 0;
5394 memcached_execute_function callbacks[]= { &callback_counter };
5395 memcached_return_t rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5396 (size_t)max_keys, callbacks, &counter, 1);
5397 test_compare(MEMCACHED_SUCCESS, rc);
5398
5399 char* the_value= NULL;
5400 char the_key[MEMCACHED_MAX_KEY];
5401 size_t the_key_length;
5402 size_t the_value_length;
5403 uint32_t the_flags;
5404
5405 do {
5406 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5407
5408 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5409 {
5410 ++counter;
5411 free(the_value);
5412 }
5413
5414 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5415
5416
5417 test_compare(MEMCACHED_END, rc);
5418
5419 /* Verify that we got all of the items */
5420 test_compare(counter, max_keys);
5421 }
5422
5423 /* Release all allocated resources */
5424 for (size_t x= 0; x < max_keys; ++x)
5425 {
5426 free(keys[x]);
5427 }
5428 free(keys);
5429 free(key_length);
5430
5431 memcached_free(memc);
5432
5433 return TEST_SUCCESS;
5434 }
5435
5436 static test_return_t regression_bug_583031(memcached_st *)
5437 {
5438 memcached_st *memc= memcached_create(NULL);
5439 test_true(memc);
5440 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
5441
5442 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
5443 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
5444 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
5445 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
5446 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5447 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
5448
5449 memcached_return_t rc;
5450 size_t length;
5451 uint32_t flags;
5452
5453 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
5454 test_false(value);
5455 test_zero(length);
5456
5457 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
5458
5459 memcached_free(memc);
5460
5461 return TEST_SUCCESS;
5462 }
5463
5464 static test_return_t regression_bug_581030(memcached_st *)
5465 {
5466 #ifndef DEBUG
5467 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
5468 test_false(local_stat);
5469
5470 memcached_stat_free(NULL, NULL);
5471 #endif
5472
5473 return TEST_SUCCESS;
5474 }
5475
5476 #define regression_bug_655423_COUNT 6000
5477 static test_return_t regression_bug_655423(memcached_st *memc)
5478 {
5479 memcached_st *clone= memcached_clone(NULL, memc);
5480 memc= NULL; // Just to make sure it is not used
5481 test_true(clone);
5482 char payload[100];
5483
5484 #ifdef __APPLE__
5485 return TEST_SKIPPED;
5486 #endif
5487
5488 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
5489 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
5490 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
5491 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
5492
5493 memset(payload, int('x'), sizeof(payload));
5494
5495 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5496 {
5497 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5498 snprintf(key, sizeof(key), "%u", x);
5499
5500 test_compare(MEMCACHED_SUCCESS, memcached_set(clone, key, strlen(key), payload, sizeof(payload), 0, 0));
5501 }
5502
5503 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5504 {
5505 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5506 snprintf(key, sizeof(key), "%u", x);
5507
5508 size_t value_length;
5509 memcached_return_t rc;
5510 char *value= memcached_get(clone, key, strlen(key), &value_length, NULL, &rc);
5511
5512 if (rc == MEMCACHED_NOTFOUND)
5513 {
5514 test_false(value);
5515 test_zero(value_length);
5516 continue;
5517 }
5518
5519 test_compare(MEMCACHED_SUCCESS, rc);
5520 test_true(value);
5521 test_compare(100LLU, value_length);
5522 free(value);
5523 }
5524
5525 char **keys= (char**)calloc(regression_bug_655423_COUNT, sizeof(char*));
5526 size_t *key_length= (size_t *)calloc(regression_bug_655423_COUNT, sizeof(size_t));
5527 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5528 {
5529 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5530 snprintf(key, sizeof(key), "%u", x);
5531
5532 keys[x]= strdup(key);
5533 test_true(keys[x]);
5534 key_length[x]= strlen(key);
5535 test_true(key_length[x]);
5536 }
5537
5538 test_compare(MEMCACHED_SUCCESS,
5539 memcached_mget(clone, (const char* const *)keys, key_length, regression_bug_655423_COUNT));
5540
5541 uint32_t count= 0;
5542 memcached_result_st *result= NULL;
5543 while ((result= memcached_fetch_result(clone, result, NULL)))
5544 {
5545 test_compare(size_t(100), memcached_result_length(result));
5546 count++;
5547 }
5548
5549 test_true(count > 100); // If we don't get back atleast this, something is up
5550
5551 /* Release all allocated resources */
5552 for (size_t x= 0; x < regression_bug_655423_COUNT; ++x)
5553 {
5554 free(keys[x]);
5555 }
5556 free(keys);
5557 free(key_length);
5558
5559
5560 memcached_free(clone);
5561
5562 return TEST_SUCCESS;
5563 }
5564
5565 /*
5566 * Test that ensures that buffered set to not trigger problems during io_flush
5567 */
5568 #define regression_bug_490520_COUNT 200480
5569 static test_return_t regression_bug_490520(memcached_st *memc)
5570 {
5571 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
5572 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
5573 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5574 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
5575 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5576
5577 memc->number_of_hosts= 1;
5578
5579 char **keys= (char **)calloc(regression_bug_490520_COUNT, sizeof(char*));
5580 size_t *key_length= (size_t *)calloc(regression_bug_490520_COUNT, sizeof(size_t));
5581
5582 /* First add all of the items.. */
5583 char blob[3333] = {0};
5584 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
5585 {
5586 char k[251];
5587 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5588 keys[x]= strdup(k);
5589 test_true(keys[x]);
5590
5591 memcached_return rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5592 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
5593 }
5594
5595 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
5596 {
5597 free(keys[x]);
5598 }
5599 free(keys);
5600 free(key_length);
5601
5602 return TEST_SUCCESS;
5603 }
5604
5605
5606 static test_return_t regression_bug_854604(memcached_st *)
5607 {
5608 char buffer[1024];
5609
5610 test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
5611
5612 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
5613
5614 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
5615 test_compare(buffer[0], 0);
5616
5617 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
5618 test_true(strlen(buffer));
5619
5620 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
5621 test_true(strlen(buffer));
5622
5623 return TEST_SUCCESS;
5624 }
5625
5626 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
5627 {
5628 fprintf(stderr, "Iteration #%u: ", it);
5629
5630 if (error == MEMCACHED_ERRNO)
5631 {
5632 fprintf(stderr, "system error %d from %s: %s\n",
5633 errno, what, strerror(errno));
5634 }
5635 else
5636 {
5637 fprintf(stderr, "error %d from %s: %s\n", error, what,
5638 memcached_strerror(mc, error));
5639 }
5640 }
5641
5642 #define TEST_CONSTANT_CREATION 200
5643
5644 static test_return_t regression_bug_(memcached_st *memc)
5645 {
5646 const char *remote_server;
5647 (void)memc;
5648
5649 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
5650 {
5651 return TEST_SKIPPED;
5652 }
5653
5654 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
5655 {
5656 memcached_st* mc= memcached_create(NULL);
5657 memcached_return rc;
5658
5659 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5660 if (rc != MEMCACHED_SUCCESS)
5661 {
5662 memcached_die(mc, rc, "memcached_behavior_set", x);
5663 }
5664
5665 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
5666 if (rc != MEMCACHED_SUCCESS)
5667 {
5668 memcached_die(mc, rc, "memcached_behavior_set", x);
5669 }
5670
5671 rc= memcached_server_add(mc, remote_server, 0);
5672 if (rc != MEMCACHED_SUCCESS)
5673 {
5674 memcached_die(mc, rc, "memcached_server_add", x);
5675 }
5676
5677 const char *set_key= "akey";
5678 const size_t set_key_len= strlen(set_key);
5679 const char *set_value= "a value";
5680 const size_t set_value_len= strlen(set_value);
5681
5682 if (rc == MEMCACHED_SUCCESS)
5683 {
5684 if (x > 0)
5685 {
5686 size_t get_value_len;
5687 char *get_value;
5688 uint32_t get_value_flags;
5689
5690 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
5691 &get_value_flags, &rc);
5692 if (rc != MEMCACHED_SUCCESS)
5693 {
5694 memcached_die(mc, rc, "memcached_get", x);
5695 }
5696 else
5697 {
5698
5699 if (x != 0 &&
5700 (get_value_len != set_value_len
5701 || 0!=strncmp(get_value, set_value, get_value_len)))
5702 {
5703 fprintf(stderr, "Values don't match?\n");
5704 rc= MEMCACHED_FAILURE;
5705 }
5706 free(get_value);
5707 }
5708 }
5709
5710 rc= memcached_set(mc,
5711 set_key, set_key_len,
5712 set_value, set_value_len,
5713 0, /* time */
5714 0 /* flags */
5715 );
5716 if (rc != MEMCACHED_SUCCESS)
5717 {
5718 memcached_die(mc, rc, "memcached_set", x);
5719 }
5720 }
5721
5722 memcached_quit(mc);
5723 memcached_free(mc);
5724
5725 if (rc != MEMCACHED_SUCCESS)
5726 {
5727 break;
5728 }
5729 }
5730
5731 return TEST_SUCCESS;
5732 }
5733
5734 /* Clean the server before beginning testing */
5735 test_st tests[] ={
5736 {"util_version", true, (test_callback_fn*)util_version_test },
5737 {"flush", false, (test_callback_fn*)flush_test },
5738 {"init", false, (test_callback_fn*)init_test },
5739 {"allocation", false, (test_callback_fn*)allocation_test },
5740 {"server_list_null_test", false, (test_callback_fn*)server_list_null_test},
5741 {"server_unsort", false, (test_callback_fn*)server_unsort_test},
5742 {"server_sort", false, (test_callback_fn*)server_sort_test},
5743 {"server_sort2", false, (test_callback_fn*)server_sort2_test},
5744 {"memcached_server_remove", false, (test_callback_fn*)memcached_server_remove_test},
5745 {"clone_test", false, (test_callback_fn*)clone_test },
5746 {"connection_test", false, (test_callback_fn*)connection_test},
5747 {"callback_test", false, (test_callback_fn*)callback_test},
5748 {"userdata_test", false, (test_callback_fn*)userdata_test},
5749 {"memcached_set()", false, (test_callback_fn*)set_test },
5750 {"memcached_set() 2", false, (test_callback_fn*)set_test2 },
5751 {"memcached_set() 3", false, (test_callback_fn*)set_test3 },
5752 {"add", true, (test_callback_fn*)add_test },
5753 {"memcached_fetch_result(MEMCACHED_NOTFOUND)", true, (test_callback_fn*)memcached_fetch_result_NOT_FOUND },
5754 {"replace", true, (test_callback_fn*)replace_test },
5755 {"delete", true, (test_callback_fn*)delete_test },
5756 {"get", true, (test_callback_fn*)get_test },
5757 {"get2", false, (test_callback_fn*)get_test2 },
5758 {"get3", false, (test_callback_fn*)get_test3 },
5759 {"get4", false, (test_callback_fn*)get_test4 },
5760 {"partial mget", false, (test_callback_fn*)get_test5 },
5761 {"stats_servername", false, (test_callback_fn*)stats_servername_test },
5762 {"increment", false, (test_callback_fn*)increment_test },
5763 {"increment_with_initial", true, (test_callback_fn*)increment_with_initial_test },
5764 {"decrement", false, (test_callback_fn*)decrement_test },
5765 {"decrement_with_initial", true, (test_callback_fn*)decrement_with_initial_test },
5766 {"increment_by_key", false, (test_callback_fn*)increment_by_key_test },
5767 {"increment_with_initial_by_key", true, (test_callback_fn*)increment_with_initial_by_key_test },
5768 {"decrement_by_key", false, (test_callback_fn*)decrement_by_key_test },
5769 {"decrement_with_initial_by_key", true, (test_callback_fn*)decrement_with_initial_by_key_test },
5770 {"binary_increment_with_prefix", true, (test_callback_fn*)binary_increment_with_prefix_test },
5771 {"quit", false, (test_callback_fn*)quit_test },
5772 {"mget", true, (test_callback_fn*)mget_test },
5773 {"mget_result", true, (test_callback_fn*)mget_result_test },
5774 {"mget_result_alloc", true, (test_callback_fn*)mget_result_alloc_test },
5775 {"mget_result_function", true, (test_callback_fn*)mget_result_function },
5776 {"mget_execute", true, (test_callback_fn*)mget_execute },
5777 {"mget_end", false, (test_callback_fn*)mget_end },
5778 {"get_stats", false, (test_callback_fn*)get_stats },
5779 {"add_host_test", false, (test_callback_fn*)add_host_test },
5780 {"add_host_test_1", false, (test_callback_fn*)add_host_test1 },
5781 {"get_stats_keys", false, (test_callback_fn*)get_stats_keys },
5782 {"version_string_test", true, (test_callback_fn*)version_string_test},
5783 {"memcached_mget() mixed memcached_get()", true, (test_callback_fn*)memcached_mget_mixed_memcached_get_TEST},
5784 {"bad_key", true, (test_callback_fn*)bad_key_test },
5785 {"memcached_server_cursor", true, (test_callback_fn*)memcached_server_cursor_test },
5786 {"read_through", true, (test_callback_fn*)read_through },
5787 {"delete_through", true, (test_callback_fn*)test_MEMCACHED_CALLBACK_DELETE_TRIGGER },
5788 {"noreply", true, (test_callback_fn*)noreply_test},
5789 {"analyzer", true, (test_callback_fn*)analyzer_test},
5790 {"memcached_pool_st", true, (test_callback_fn*)connection_pool_test },
5791 {"memcached_pool_st #2", true, (test_callback_fn*)connection_pool2_test },
5792 #if 0
5793 {"memcached_pool_st #3", true, (test_callback_fn*)connection_pool3_test },
5794 #endif
5795 {"memcached_pool_test", true, (test_callback_fn*)memcached_pool_test },
5796 {"test_get_last_disconnect", true, (test_callback_fn*)test_get_last_disconnect},
5797 {"verbosity", true, (test_callback_fn*)test_verbosity},
5798 {"memcached_stat_execute", true, (test_callback_fn*)memcached_stat_execute_test},
5799 {"memcached_exist(MEMCACHED_NOTFOUND)", true, (test_callback_fn*)memcached_exist_NOTFOUND },
5800 {"memcached_exist(MEMCACHED_SUCCESS)", true, (test_callback_fn*)memcached_exist_SUCCESS },
5801 {"memcached_exist_by_key(MEMCACHED_NOTFOUND)", true, (test_callback_fn*)memcached_exist_by_key_NOTFOUND },
5802 {"memcached_exist_by_key(MEMCACHED_SUCCESS)", true, (test_callback_fn*)memcached_exist_by_key_SUCCESS },
5803 {"memcached_touch", 0, (test_callback_fn*)test_memcached_touch},
5804 {"memcached_touch_with_prefix", 0, (test_callback_fn*)test_memcached_touch_by_key},
5805 #if 0
5806 {"memcached_dump() no data", true, (test_callback_fn*)memcached_dump_TEST },
5807 #endif
5808 {"memcached_dump() with data", true, (test_callback_fn*)memcached_dump_TEST2 },
5809 {0, 0, 0}
5810 };
5811
5812 test_st touch_tests[] ={
5813 {"memcached_touch", 0, (test_callback_fn*)test_memcached_touch},
5814 {"memcached_touch_with_prefix", 0, (test_callback_fn*)test_memcached_touch_by_key},
5815 {0, 0, 0}
5816 };
5817
5818 test_st memcached_stat_tests[] ={
5819 {"memcached_stat() INVALID ARG", 0, (test_callback_fn*)memcached_stat_TEST},
5820 {"memcached_stat()", 0, (test_callback_fn*)memcached_stat_TEST2},
5821 {0, 0, 0}
5822 };
5823
5824 test_st behavior_tests[] ={
5825 {"libmemcached_string_behavior()", false, (test_callback_fn*)libmemcached_string_behavior_test},
5826 {"libmemcached_string_distribution()", false, (test_callback_fn*)libmemcached_string_distribution_test},
5827 {"behavior_test", false, (test_callback_fn*)behavior_test},
5828 {"MEMCACHED_BEHAVIOR_CORK", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_CORK_test},
5829 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
5830 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
5831 {"MEMCACHED_BEHAVIOR_POLL_TIMEOUT", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test},
5832 {"MEMCACHED_CALLBACK_DELETE_TRIGGER_and_MEMCACHED_BEHAVIOR_NOREPLY", false, (test_callback_fn*)test_MEMCACHED_CALLBACK_DELETE_TRIGGER_and_MEMCACHED_BEHAVIOR_NOREPLY},
5833 {0, 0, 0}
5834 };
5835
5836 test_st libmemcachedutil_tests[] ={
5837 {"libmemcached_util_ping()", true, (test_callback_fn*)ping_test },
5838 {"libmemcached_util_getpid()", true, (test_callback_fn*)getpid_test },
5839 {"libmemcached_util_getpid(MEMCACHED_CONNECTION_FAILURE)", true, (test_callback_fn*)getpid_connection_failure_test },
5840 {0, 0, 0}
5841 };
5842
5843 test_st basic_tests[] ={
5844 {"init", true, (test_callback_fn*)basic_init_test},
5845 {"clone", true, (test_callback_fn*)basic_clone_test},
5846 {"reset", true, (test_callback_fn*)basic_reset_stack_test},
5847 {"reset heap", true, (test_callback_fn*)basic_reset_heap_test},
5848 {"reset stack clone", true, (test_callback_fn*)basic_reset_stack_clone_test},
5849 {"reset heap clone", true, (test_callback_fn*)basic_reset_heap_clone_test},
5850 {"memcached_return_t", false, (test_callback_fn*)memcached_return_t_TEST },
5851 {0, 0, 0}
5852 };
5853
5854 test_st regression_binary_vs_block[] ={
5855 {"block add", true, (test_callback_fn*)block_add_regression},
5856 {"binary add", true, (test_callback_fn*)binary_add_regression},
5857 {0, 0, 0}
5858 };
5859
5860 test_st async_tests[] ={
5861 {"add", true, (test_callback_fn*)add_wrapper },
5862 {0, 0, 0}
5863 };
5864
5865 test_st memcached_server_get_last_disconnect_tests[] ={
5866 {"memcached_server_get_last_disconnect()", false, (test_callback_fn*)test_multiple_get_last_disconnect},
5867 {0, 0, (test_callback_fn*)0}
5868 };
5869
5870
5871 test_st result_tests[] ={
5872 {"result static", false, (test_callback_fn*)result_static},
5873 {"result alloc", false, (test_callback_fn*)result_alloc},
5874 {0, 0, (test_callback_fn*)0}
5875 };
5876
5877 test_st version_1_2_3[] ={
5878 {"append", false, (test_callback_fn*)append_test },
5879 {"prepend", false, (test_callback_fn*)prepend_test },
5880 {"cas", false, (test_callback_fn*)cas_test },
5881 {"cas2", false, (test_callback_fn*)cas2_test },
5882 {"append_binary", false, (test_callback_fn*)append_binary_test },
5883 {0, 0, (test_callback_fn*)0}
5884 };
5885
5886 test_st haldenbrand_tests[] ={
5887 {"memcached_set", false, (test_callback_fn*)user_supplied_bug1 },
5888 {"memcached_get()", false, (test_callback_fn*)user_supplied_bug2 },
5889 {"memcached_mget()", false, (test_callback_fn*)user_supplied_bug3 },
5890 {0, 0, (test_callback_fn*)0}
5891 };
5892
5893 test_st user_tests[] ={
5894 {"user_supplied_bug4", true, (test_callback_fn*)user_supplied_bug4 },
5895 {"user_supplied_bug5", true, (test_callback_fn*)user_supplied_bug5 },
5896 {"user_supplied_bug6", true, (test_callback_fn*)user_supplied_bug6 },
5897 {"user_supplied_bug7", true, (test_callback_fn*)user_supplied_bug7 },
5898 {"user_supplied_bug8", true, (test_callback_fn*)user_supplied_bug8 },
5899 {"user_supplied_bug9", true, (test_callback_fn*)user_supplied_bug9 },
5900 {"user_supplied_bug10", true, (test_callback_fn*)user_supplied_bug10 },
5901 {"user_supplied_bug11", true, (test_callback_fn*)user_supplied_bug11 },
5902 {"user_supplied_bug12", true, (test_callback_fn*)user_supplied_bug12 },
5903 {"user_supplied_bug13", true, (test_callback_fn*)user_supplied_bug13 },
5904 {"user_supplied_bug14", true, (test_callback_fn*)user_supplied_bug14 },
5905 {"user_supplied_bug15", true, (test_callback_fn*)user_supplied_bug15 },
5906 {"user_supplied_bug16", true, (test_callback_fn*)user_supplied_bug16 },
5907 #if !defined(__sun) && !defined(__OpenBSD__)
5908 /*
5909 ** It seems to be something weird with the character sets..
5910 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5911 ** guess I need to find out how this is supposed to work.. Perhaps I need
5912 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5913 ** so just disable the code for now...).
5914 */
5915 {"user_supplied_bug17", true, (test_callback_fn*)user_supplied_bug17 },
5916 #endif
5917 {"user_supplied_bug18", true, (test_callback_fn*)user_supplied_bug18 },
5918 {"user_supplied_bug19", true, (test_callback_fn*)user_supplied_bug19 },
5919 {"user_supplied_bug20", true, (test_callback_fn*)user_supplied_bug20 },
5920 {"user_supplied_bug21", true, (test_callback_fn*)user_supplied_bug21 },
5921 {"wrong_failure_counter_test", true, (test_callback_fn*)wrong_failure_counter_test},
5922 {"wrong_failure_counter_two_test", true, (test_callback_fn*)wrong_failure_counter_two_test},
5923 {0, 0, (test_callback_fn*)0}
5924 };
5925
5926 test_st replication_tests[]= {
5927 {"set", true, (test_callback_fn*)replication_set_test },
5928 {"get", false, (test_callback_fn*)replication_get_test },
5929 {"mget", false, (test_callback_fn*)replication_mget_test },
5930 {"delete", true, (test_callback_fn*)replication_delete_test },
5931 {"rand_mget", false, (test_callback_fn*)replication_randomize_mget_test },
5932 {"miss", false, (test_callback_fn*)replication_miss_test },
5933 {"fail", false, (test_callback_fn*)replication_randomize_mget_fail_test },
5934 {0, 0, (test_callback_fn*)0}
5935 };
5936
5937 /*
5938 * The following test suite is used to verify that we don't introduce
5939 * regression bugs. If you want more information about the bug / test,
5940 * you should look in the bug report at
5941 * http://bugs.launchpad.net/libmemcached
5942 */
5943 test_st regression_tests[]= {
5944 {"lp:434484", true, (test_callback_fn*)regression_bug_434484 },
5945 {"lp:434843", true, (test_callback_fn*)regression_bug_434843 },
5946 {"lp:434843-buffered", true, (test_callback_fn*)regression_bug_434843_buffered },
5947 {"lp:421108", true, (test_callback_fn*)regression_bug_421108 },
5948 {"lp:442914", true, (test_callback_fn*)regression_bug_442914 },
5949 {"lp:447342", true, (test_callback_fn*)regression_bug_447342 },
5950 {"lp:463297", true, (test_callback_fn*)regression_bug_463297 },
5951 {"lp:490486", true, (test_callback_fn*)regression_bug_490486 },
5952 {"lp:583031", true, (test_callback_fn*)regression_bug_583031 },
5953 {"lp:?", true, (test_callback_fn*)regression_bug_ },
5954 {"lp:728286", true, (test_callback_fn*)regression_bug_728286 },
5955 {"lp:581030", true, (test_callback_fn*)regression_bug_581030 },
5956 {"lp:71231153 connect()", true, (test_callback_fn*)regression_bug_71231153_connect },
5957 {"lp:71231153 poll()", true, (test_callback_fn*)regression_bug_71231153_poll },
5958 {"lp:655423", true, (test_callback_fn*)regression_bug_655423 },
5959 {"lp:490520", true, (test_callback_fn*)regression_bug_490520 },
5960 {"lp:854604", true, (test_callback_fn*)regression_bug_854604 },
5961 {0, false, (test_callback_fn*)0}
5962 };
5963
5964 test_st ketama_compatibility[]= {
5965 {"libmemcached", true, (test_callback_fn*)ketama_compatibility_libmemcached },
5966 {"spymemcached", true, (test_callback_fn*)ketama_compatibility_spymemcached },
5967 {0, 0, (test_callback_fn*)0}
5968 };
5969
5970 test_st generate_tests[] ={
5971 {"generate_pairs", true, (test_callback_fn*)generate_pairs },
5972 {"generate_data", true, (test_callback_fn*)generate_data },
5973 {"get_read", false, (test_callback_fn*)get_read },
5974 {"delete_generate", false, (test_callback_fn*)delete_generate },
5975 {"generate_buffer_data", true, (test_callback_fn*)generate_buffer_data },
5976 {"delete_buffer", false, (test_callback_fn*)delete_buffer_generate},
5977 {"generate_data", true, (test_callback_fn*)generate_data },
5978 {"mget_read", false, (test_callback_fn*)mget_read },
5979 {"mget_read_result", false, (test_callback_fn*)mget_read_result },
5980 {"memcached_fetch_result() use internal result", false, (test_callback_fn*)mget_read_internal_result },
5981 {"memcached_fetch_result() partial read", false, (test_callback_fn*)mget_read_partial_result },
5982 {"mget_read_function", false, (test_callback_fn*)mget_read_function },
5983 {"cleanup", true, (test_callback_fn*)cleanup_pairs },
5984 {"generate_large_pairs", true, (test_callback_fn*)generate_large_pairs },
5985 {"generate_data", true, (test_callback_fn*)generate_data },
5986 {"generate_buffer_data", true, (test_callback_fn*)generate_buffer_data },
5987 {"cleanup", true, (test_callback_fn*)cleanup_pairs },
5988 {0, 0, (test_callback_fn*)0}
5989 };
5990
5991 test_st consistent_tests[] ={
5992 {"generate_pairs", true, (test_callback_fn*)generate_pairs },
5993 {"generate_data", true, (test_callback_fn*)generate_data },
5994 {"get_read", 0, (test_callback_fn*)get_read_count },
5995 {"cleanup", true, (test_callback_fn*)cleanup_pairs },
5996 {0, 0, (test_callback_fn*)0}
5997 };
5998
5999 test_st consistent_weighted_tests[] ={
6000 {"generate_pairs", true, (test_callback_fn*)generate_pairs },
6001 {"generate_data", true, (test_callback_fn*)generate_data_with_stats },
6002 {"get_read", false, (test_callback_fn*)get_read_count },
6003 {"cleanup", true, (test_callback_fn*)cleanup_pairs },
6004 {0, 0, (test_callback_fn*)0}
6005 };
6006
6007 test_st hsieh_availability[] ={
6008 {"hsieh_avaibility_test", false, (test_callback_fn*)hsieh_avaibility_test},
6009 {0, 0, (test_callback_fn*)0}
6010 };
6011
6012 test_st murmur_availability[] ={
6013 {"murmur_avaibility_test", false, (test_callback_fn*)murmur_avaibility_test},
6014 {0, 0, (test_callback_fn*)0}
6015 };
6016
6017 #if 0
6018 test_st hash_sanity[] ={
6019 {"hash sanity", 0, (test_callback_fn*)hash_sanity_test},
6020 {0, 0, (test_callback_fn*)0}
6021 };
6022 #endif
6023
6024 test_st ketama_auto_eject_hosts[] ={
6025 {"auto_eject_hosts", true, (test_callback_fn*)auto_eject_hosts },
6026 {"output_ketama_weighted_keys", true, (test_callback_fn*)output_ketama_weighted_keys },
6027 {0, 0, (test_callback_fn*)0}
6028 };
6029
6030 test_st hash_tests[] ={
6031 {"one_at_a_time_run", false, (test_callback_fn*)one_at_a_time_run },
6032 {"md5", false, (test_callback_fn*)md5_run },
6033 {"crc", false, (test_callback_fn*)crc_run },
6034 {"fnv1_64", false, (test_callback_fn*)fnv1_64_run },
6035 {"fnv1a_64", false, (test_callback_fn*)fnv1a_64_run },
6036 {"fnv1_32", false, (test_callback_fn*)fnv1_32_run },
6037 {"fnv1a_32", false, (test_callback_fn*)fnv1a_32_run },
6038 {"hsieh", false, (test_callback_fn*)hsieh_run },
6039 {"murmur", false, (test_callback_fn*)murmur_run },
6040 {"jenkis", false, (test_callback_fn*)jenkins_run },
6041 {"memcached_get_hashkit", false, (test_callback_fn*)memcached_get_hashkit_test },
6042 {0, 0, (test_callback_fn*)0}
6043 };
6044
6045 test_st error_conditions[] ={
6046 {"memcached_get(MEMCACHED_ERRNO)", false, (test_callback_fn*)memcached_get_MEMCACHED_ERRNO },
6047 {"memcached_get(MEMCACHED_NOTFOUND)", false, (test_callback_fn*)memcached_get_MEMCACHED_NOTFOUND },
6048 {"memcached_get_by_key(MEMCACHED_ERRNO)", false, (test_callback_fn*)memcached_get_by_key_MEMCACHED_ERRNO },
6049 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", false, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
6050 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", false, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
6051 {"memcached_increment(MEMCACHED_NO_SERVERS)", false, (test_callback_fn*)memcached_increment_MEMCACHED_NO_SERVERS },
6052 {0, 0, (test_callback_fn*)0}
6053 };
6054
6055 test_st parser_tests[] ={
6056 {"behavior", false, (test_callback_fn*)behavior_parser_test },
6057 {"boolean_options", false, (test_callback_fn*)parser_boolean_options_test },
6058 {"configure_file", false, (test_callback_fn*)memcached_create_with_options_with_filename },
6059 {"distribtions", false, (test_callback_fn*)parser_distribution_test },
6060 {"hash", false, (test_callback_fn*)parser_hash_test },
6061 {"libmemcached_check_configuration", false, (test_callback_fn*)libmemcached_check_configuration_test },
6062 {"libmemcached_check_configuration_with_filename", false, (test_callback_fn*)libmemcached_check_configuration_with_filename_test },
6063 {"number_options", false, (test_callback_fn*)parser_number_options_test },
6064 {"randomly generated options", false, (test_callback_fn*)random_statement_build_test },
6065 {"namespace", false, (test_callback_fn*)parser_key_prefix_test },
6066 {"server", false, (test_callback_fn*)server_test },
6067 {"bad server strings", false, (test_callback_fn*)servers_bad_test },
6068 {"server with weights", false, (test_callback_fn*)server_with_weight_test },
6069 {"parsing servername, port, and weight", false, (test_callback_fn*)test_hostname_port_weight },
6070 {"--socket=", false, (test_callback_fn*)test_parse_socket },
6071 {"--namespace=", false, (test_callback_fn*)test_namespace_keyword },
6072 {0, 0, (test_callback_fn*)0}
6073 };
6074
6075 test_st virtual_bucket_tests[] ={
6076 {"basic", false, (test_callback_fn*)virtual_back_map },
6077 {0, 0, (test_callback_fn*)0}
6078 };
6079
6080 test_st memcached_server_add_tests[] ={
6081 {"memcached_server_add(\"\")", false, (test_callback_fn*)memcached_server_add_empty_test },
6082 {"memcached_server_add(NULL)", false, (test_callback_fn*)memcached_server_add_null_test },
6083 {0, 0, (test_callback_fn*)0}
6084 };
6085
6086 test_st namespace_tests[] ={
6087 {"basic tests", true, (test_callback_fn*)selection_of_namespace_tests },
6088 {"increment", true, (test_callback_fn*)memcached_increment_namespace },
6089 {0, 0, (test_callback_fn*)0}
6090 };
6091
6092 collection_st collection[] ={
6093 #if 0
6094 {"hash_sanity", 0, 0, hash_sanity},
6095 #endif
6096 {"libmemcachedutil", 0, 0, libmemcachedutil_tests},
6097 {"basic", 0, 0, basic_tests},
6098 {"hsieh_availability", 0, 0, hsieh_availability},
6099 {"murmur_availability", 0, 0, murmur_availability},
6100 {"memcached_server_add", 0, 0, memcached_server_add_tests},
6101 {"block", 0, 0, tests},
6102 {"binary", (test_callback_fn*)pre_binary, 0, tests},
6103 {"nonblock", (test_callback_fn*)pre_nonblock, 0, tests},
6104 {"nodelay", (test_callback_fn*)pre_nodelay, 0, tests},
6105 {"settimer", (test_callback_fn*)pre_settimer, 0, tests},
6106 {"md5", (test_callback_fn*)pre_md5, 0, tests},
6107 {"crc", (test_callback_fn*)pre_crc, 0, tests},
6108 {"hsieh", (test_callback_fn*)pre_hsieh, 0, tests},
6109 {"jenkins", (test_callback_fn*)pre_jenkins, 0, tests},
6110 {"fnv1_64", (test_callback_fn*)pre_hash_fnv1_64, 0, tests},
6111 {"fnv1a_64", (test_callback_fn*)pre_hash_fnv1a_64, 0, tests},
6112 {"fnv1_32", (test_callback_fn*)pre_hash_fnv1_32, 0, tests},
6113 {"fnv1a_32", (test_callback_fn*)pre_hash_fnv1a_32, 0, tests},
6114 {"ketama", (test_callback_fn*)pre_behavior_ketama, 0, tests},
6115 {"ketama_auto_eject_hosts", (test_callback_fn*)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6116 {"unix_socket", (test_callback_fn*)pre_unix_socket, 0, tests},
6117 {"unix_socket_nodelay", (test_callback_fn*)pre_nodelay, 0, tests},
6118 {"gets", (test_callback_fn*)enable_cas, 0, tests},
6119 {"consistent_crc", (test_callback_fn*)enable_consistent_crc, 0, tests},
6120 {"consistent_hsieh", (test_callback_fn*)enable_consistent_hsieh, 0, tests},
6121 #ifdef MEMCACHED_ENABLE_DEPRECATED
6122 {"deprecated_memory_allocators", (test_callback_fn*)deprecated_set_memory_alloc, 0, tests},
6123 #endif
6124 {"memory_allocators", (test_callback_fn*)set_memory_alloc, 0, tests},
6125 {"namespace", (test_callback_fn*)set_namespace, 0, tests},
6126 {"namespace(BINARY)", (test_callback_fn*)set_namespace_and_binary, 0, tests},
6127 {"specific namespace", 0, 0, namespace_tests},
6128 {"specific namespace(BINARY)", (test_callback_fn*)pre_binary, 0, namespace_tests},
6129 {"version_1_2_3", (test_callback_fn*)check_for_1_2_3, 0, version_1_2_3},
6130 {"result", 0, 0, result_tests},
6131 {"async", (test_callback_fn*)pre_nonblock, 0, async_tests},
6132 {"async(BINARY)", (test_callback_fn*)pre_nonblock_binary, 0, async_tests},
6133 {"Cal Haldenbrand's tests", 0, 0, haldenbrand_tests},
6134 {"user written tests", 0, 0, user_tests},
6135 {"generate", 0, 0, generate_tests},
6136 {"generate_hsieh", (test_callback_fn*)pre_hsieh, 0, generate_tests},
6137 {"generate_ketama", (test_callback_fn*)pre_behavior_ketama, 0, generate_tests},
6138 {"generate_hsieh_consistent", (test_callback_fn*)enable_consistent_hsieh, 0, generate_tests},
6139 {"generate_md5", (test_callback_fn*)pre_md5, 0, generate_tests},
6140 {"generate_murmur", (test_callback_fn*)pre_murmur, 0, generate_tests},
6141 {"generate_jenkins", (test_callback_fn*)pre_jenkins, 0, generate_tests},
6142 {"generate_nonblock", (test_callback_fn*)pre_nonblock, 0, generate_tests},
6143 // Too slow
6144 {"generate_corked", (test_callback_fn*)pre_cork, 0, generate_tests},
6145 {"generate_corked_and_nonblock", (test_callback_fn*)pre_cork_and_nonblock, 0, generate_tests},
6146 {"consistent_not", 0, 0, consistent_tests},
6147 {"consistent_ketama", (test_callback_fn*)pre_behavior_ketama, 0, consistent_tests},
6148 {"consistent_ketama_weighted", (test_callback_fn*)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6149 {"ketama_compat", 0, 0, ketama_compatibility},
6150 {"test_hashes", 0, 0, hash_tests},
6151 {"replication", (test_callback_fn*)pre_replication, 0, replication_tests},
6152 {"replication_noblock", (test_callback_fn*)pre_replication_noblock, 0, replication_tests},
6153 {"regression", 0, 0, regression_tests},
6154 {"behaviors", 0, 0, behavior_tests},
6155 {"regression_binary_vs_block", (test_callback_fn*)key_setup, (test_callback_fn*)key_teardown, regression_binary_vs_block},
6156 {"error_conditions", 0, 0, error_conditions},
6157 {"parser", 0, 0, parser_tests},
6158 {"virtual buckets", 0, 0, virtual_bucket_tests},
6159 {"memcached_server_get_last_disconnect", 0, 0, memcached_server_get_last_disconnect_tests},
6160 {"touch", 0, 0, touch_tests},
6161 {"touch", (test_callback_fn*)pre_binary, 0, touch_tests},
6162 {"memcached_stat()", 0, 0, memcached_stat_tests},
6163 {0, 0, 0, 0}
6164 };
6165
6166 #define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
6167
6168 #include "tests/libmemcached_world.h"
6169
6170 void get_world(Framework *world)
6171 {
6172 world->collections= collection;
6173
6174 world->_create= (test_callback_create_fn*)world_create;
6175 world->_destroy= (test_callback_destroy_fn*)world_destroy;
6176
6177 world->item._startup= (test_callback_fn*)world_test_startup;
6178 world->item.set_pre((test_callback_fn*)world_pre_run);
6179 world->item.set_flush((test_callback_fn*)world_flush);
6180 world->item.set_post((test_callback_fn*)world_post_run);
6181 world->_on_error= (test_callback_error_fn*)world_on_error;
6182
6183 world->collection_startup= (test_callback_fn*)world_container_startup;
6184 world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
6185
6186 world->set_runner(&defualt_libmemcached_runner);
6187
6188 world->set_socket();
6189 }