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