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