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