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