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