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