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