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