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