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