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