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