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