Remove how use instance (keep API intact)
[m6w6/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] == server->port))
303 {
304 fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)server->port);
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_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
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_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, 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_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, 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_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
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_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, 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_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
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_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
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 test_compare(*memc, MEMCACHED_SUCCESS);
1758 test_compare(rc, MEMCACHED_SUCCESS);
1759 }
1760
1761 return TEST_SUCCESS;
1762 }
1763
1764 test_return_t binary_add_regression(memcached_st *memc)
1765 {
1766 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
1767 return block_add_regression(memc);
1768 }
1769
1770 test_return_t get_stats_keys(memcached_st *memc)
1771 {
1772 char **stat_list;
1773 char **ptr;
1774 memcached_stat_st memc_stat;
1775 memcached_return_t rc;
1776
1777 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1778 test_compare(MEMCACHED_SUCCESS, rc);
1779 for (ptr= stat_list; *ptr; ptr++)
1780 test_true(*ptr);
1781
1782 free(stat_list);
1783
1784 return TEST_SUCCESS;
1785 }
1786
1787 test_return_t version_string_test(memcached_st *)
1788 {
1789 test_strcmp(LIBMEMCACHED_VERSION_STRING, memcached_lib_version());
1790
1791 return TEST_SUCCESS;
1792 }
1793
1794 test_return_t get_stats(memcached_st *memc)
1795 {
1796 memcached_return_t rc;
1797
1798 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
1799 test_compare(MEMCACHED_SUCCESS, rc);
1800 test_true(memc_stat);
1801
1802 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
1803 {
1804 char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1805 test_compare(MEMCACHED_SUCCESS, rc);
1806 for (char **ptr= stat_list; *ptr; ptr++) {};
1807
1808 free(stat_list);
1809 }
1810
1811 memcached_stat_free(NULL, memc_stat);
1812
1813 return TEST_SUCCESS;
1814 }
1815
1816 test_return_t add_host_test(memcached_st *memc)
1817 {
1818 char servername[]= "0.example.com";
1819
1820 memcached_return_t rc;
1821 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1822 test_compare(1U, memcached_server_list_count(servers));
1823
1824 for (unsigned int x= 2; x < 20; x++)
1825 {
1826 char buffer[SMALL_STRING_LEN];
1827
1828 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1829 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1830 &rc);
1831 test_compare(MEMCACHED_SUCCESS, rc);
1832 test_compare(x, memcached_server_list_count(servers));
1833 }
1834
1835 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1836 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1837
1838 memcached_server_list_free(servers);
1839
1840 return TEST_SUCCESS;
1841 }
1842
1843 test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc)
1844 {
1845 memcached_return_t rc;
1846
1847 const char *key= "not_found";
1848 size_t key_length= test_literal_param_size("not_found");
1849
1850 test_compare(MEMCACHED_SUCCESS,
1851 memcached_mget(memc, &key, &key_length, 1));
1852
1853 memcached_result_st *result= memcached_fetch_result(memc, NULL, &rc);
1854 test_null(result);
1855 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1856
1857 memcached_result_free(result);
1858
1859 return TEST_SUCCESS;
1860 }
1861
1862 static memcached_return_t clone_test_callback(memcached_st *, memcached_st *)
1863 {
1864 return MEMCACHED_SUCCESS;
1865 }
1866
1867 static memcached_return_t cleanup_test_callback(memcached_st *)
1868 {
1869 return MEMCACHED_SUCCESS;
1870 }
1871
1872 test_return_t callback_test(memcached_st *memc)
1873 {
1874 /* Test User Data */
1875 {
1876 int x= 5;
1877 int *test_ptr;
1878 memcached_return_t rc;
1879
1880 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x));
1881 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1882 test_true(*test_ptr == x);
1883 }
1884
1885 /* Test Clone Callback */
1886 {
1887 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1888 void *clone_cb_ptr= *(void **)&clone_cb;
1889 void *temp_function= NULL;
1890
1891 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, clone_cb_ptr));
1892 memcached_return_t rc;
1893 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1894 test_true(temp_function == clone_cb_ptr);
1895 test_compare(MEMCACHED_SUCCESS, rc);
1896 }
1897
1898 /* Test Cleanup Callback */
1899 {
1900 memcached_cleanup_fn cleanup_cb= (memcached_cleanup_fn)cleanup_test_callback;
1901 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1902 void *temp_function= NULL;
1903 memcached_return_t rc;
1904
1905 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, cleanup_cb_ptr));
1906 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1907 test_true(temp_function == cleanup_cb_ptr);
1908 }
1909
1910 return TEST_SUCCESS;
1911 }
1912
1913 /* We don't test the behavior itself, we test the switches */
1914 test_return_t behavior_test(memcached_st *memc)
1915 {
1916 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
1917 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1918
1919 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
1920 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1921
1922 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_MD5);
1923 test_compare(uint64_t(MEMCACHED_HASH_MD5), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1924
1925 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
1926 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1927
1928 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
1929 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1930
1931 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_DEFAULT);
1932 test_compare(uint64_t(MEMCACHED_HASH_DEFAULT), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1933
1934 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_CRC);
1935 test_compare(uint64_t(MEMCACHED_HASH_CRC), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1936
1937 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
1938
1939 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
1940
1941 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
1942 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value +1);
1943 test_compare((value +1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
1944
1945 return TEST_SUCCESS;
1946 }
1947
1948 test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
1949 {
1950 test_compare(MEMCACHED_DEPRECATED,
1951 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, true));
1952
1953 // Platform dependent
1954 #if 0
1955 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
1956 test_false(value);
1957 #endif
1958
1959 return TEST_SUCCESS;
1960 }
1961
1962
1963 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
1964 {
1965 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, true);
1966 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
1967
1968 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
1969
1970 if (memcached_success(rc))
1971 {
1972 test_true(value);
1973 }
1974 else
1975 {
1976 test_false(value);
1977 }
1978
1979 return TEST_SUCCESS;
1980 }
1981
1982
1983 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
1984 {
1985 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, true);
1986 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
1987
1988 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
1989
1990 if (memcached_success(rc))
1991 {
1992 test_true(value);
1993 }
1994 else
1995 {
1996 test_false(value);
1997 }
1998
1999 return TEST_SUCCESS;
2000 }
2001
2002 /* Make sure we behave properly if server list has no values */
2003 test_return_t user_supplied_bug4(memcached_st *memc)
2004 {
2005 const char *keys[]= {"fudge", "son", "food"};
2006 size_t key_length[]= {5, 3, 4};
2007
2008 /* Here we free everything before running a bunch of mget tests */
2009 memcached_servers_reset(memc);
2010
2011
2012 /* We need to empty the server before continueing test */
2013 test_compare(MEMCACHED_NO_SERVERS,
2014 memcached_flush(memc, 0));
2015
2016 test_compare(MEMCACHED_NO_SERVERS,
2017 memcached_mget(memc, keys, key_length, 3));
2018
2019 {
2020 unsigned int keys_returned;
2021 memcached_return_t rc;
2022 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, rc));
2023 test_compare(MEMCACHED_NOTFOUND, rc);
2024 test_zero(keys_returned);
2025 }
2026
2027 for (uint32_t x= 0; x < 3; x++)
2028 {
2029 test_compare(MEMCACHED_NO_SERVERS,
2030 memcached_set(memc, keys[x], key_length[x],
2031 keys[x], key_length[x],
2032 (time_t)50, (uint32_t)9));
2033 }
2034
2035 test_compare(MEMCACHED_NO_SERVERS,
2036 memcached_mget(memc, keys, key_length, 3));
2037
2038 {
2039 char *return_value;
2040 char return_key[MEMCACHED_MAX_KEY];
2041 memcached_return_t rc;
2042 size_t return_key_length;
2043 size_t return_value_length;
2044 uint32_t flags;
2045 uint32_t x= 0;
2046 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2047 &return_value_length, &flags, &rc)))
2048 {
2049 test_true(return_value);
2050 test_compare(MEMCACHED_SUCCESS, rc);
2051 test_true(return_key_length == return_value_length);
2052 test_memcmp(return_value, return_key, return_value_length);
2053 free(return_value);
2054 x++;
2055 }
2056 }
2057
2058 return TEST_SUCCESS;
2059 }
2060
2061 #define VALUE_SIZE_BUG5 1048064
2062 test_return_t user_supplied_bug5(memcached_st *memc)
2063 {
2064 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2065 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2066 char *value;
2067 size_t value_length;
2068 uint32_t flags;
2069 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2070
2071 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2072 {
2073 insert_data[x]= (signed char)rand();
2074 }
2075
2076 test_compare(MEMCACHED_SUCCESS,
2077 memcached_flush(memc, 0));
2078
2079 memcached_return_t rc;
2080 test_null(memcached_get(memc, keys[0], key_length[0], &value_length, &flags, &rc));
2081 test_compare(MEMCACHED_SUCCESS,
2082 memcached_mget(memc, keys, key_length, 4));
2083
2084 unsigned int count;
2085 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, rc));
2086 test_compare(MEMCACHED_NOTFOUND, rc);
2087 test_zero(count);
2088
2089 for (uint32_t x= 0; x < 4; x++)
2090 {
2091 test_compare(MEMCACHED_SUCCESS,
2092 memcached_set(memc, keys[x], key_length[x],
2093 insert_data, VALUE_SIZE_BUG5,
2094 (time_t)0, (uint32_t)0));
2095 }
2096
2097 for (uint32_t x= 0; x < 10; x++)
2098 {
2099 value= memcached_get(memc, keys[0], key_length[0],
2100 &value_length, &flags, &rc);
2101 test_compare(rc, MEMCACHED_SUCCESS);
2102 test_true(value);
2103 ::free(value);
2104
2105 test_compare(MEMCACHED_SUCCESS,
2106 memcached_mget(memc, keys, key_length, 4));
2107
2108 test_compare(TEST_SUCCESS, fetch_all_results(memc, count));
2109 test_compare(4U, count);
2110 }
2111 delete [] insert_data;
2112
2113 return TEST_SUCCESS;
2114 }
2115
2116 test_return_t user_supplied_bug6(memcached_st *memc)
2117 {
2118 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2119 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2120 char return_key[MEMCACHED_MAX_KEY];
2121 size_t return_key_length;
2122 char *value;
2123 size_t value_length;
2124 uint32_t flags;
2125 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2126
2127 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2128 {
2129 insert_data[x]= (signed char)rand();
2130 }
2131
2132 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
2133
2134 test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc, keys, test_array_length(keys)));
2135
2136 // We will now confirm that memcached_mget() returns success, but we will
2137 // then check to make sure that no actual keys are returned.
2138 test_compare(MEMCACHED_SUCCESS,
2139 memcached_mget(memc, keys, key_length, 4));
2140
2141 memcached_return_t rc;
2142 uint32_t count= 0;
2143 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2144 &value_length, &flags, &rc)))
2145 {
2146 count++;
2147 }
2148 test_zero(count);
2149 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
2150
2151 for (uint32_t x= 0; x < test_array_length(keys); x++)
2152 {
2153 test_compare(MEMCACHED_SUCCESS,
2154 memcached_set(memc, keys[x], key_length[x],
2155 insert_data, VALUE_SIZE_BUG5,
2156 (time_t)0, (uint32_t)0));
2157 }
2158 test_compare(TEST_SUCCESS, confirm_keys_exist(memc, keys, test_array_length(keys)));
2159
2160 for (uint32_t x= 0; x < 2; x++)
2161 {
2162 value= memcached_get(memc, keys[0], key_length[0],
2163 &value_length, &flags, &rc);
2164 test_true(value);
2165 free(value);
2166
2167 test_compare(MEMCACHED_SUCCESS,
2168 memcached_mget(memc, keys, key_length, 4));
2169 /* We test for purge of partial complete fetches */
2170 for (count= 3; count; count--)
2171 {
2172 value= memcached_fetch(memc, return_key, &return_key_length,
2173 &value_length, &flags, &rc);
2174 test_compare(MEMCACHED_SUCCESS, rc);
2175 test_memcmp(value, insert_data, value_length);
2176 test_true(value_length);
2177 free(value);
2178 }
2179 }
2180 delete [] insert_data;
2181
2182 return TEST_SUCCESS;
2183 }
2184
2185 test_return_t user_supplied_bug8(memcached_st *)
2186 {
2187 memcached_return_t rc;
2188 memcached_st *mine;
2189 memcached_st *memc_clone;
2190
2191 memcached_server_st *servers;
2192 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";
2193
2194 servers= memcached_servers_parse(server_list);
2195 test_true(servers);
2196
2197 mine= memcached_create(NULL);
2198 rc= memcached_server_push(mine, servers);
2199 test_compare(MEMCACHED_SUCCESS, rc);
2200 memcached_server_list_free(servers);
2201
2202 test_true(mine);
2203 memc_clone= memcached_clone(NULL, mine);
2204
2205 memcached_quit(mine);
2206 memcached_quit(memc_clone);
2207
2208
2209 memcached_free(mine);
2210 memcached_free(memc_clone);
2211
2212 return TEST_SUCCESS;
2213 }
2214
2215 /* Test flag store/retrieve */
2216 test_return_t user_supplied_bug7(memcached_st *memc)
2217 {
2218 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2219 test_true(insert_data);
2220
2221 for (size_t x= 0; x < VALUE_SIZE_BUG5; x++)
2222 {
2223 insert_data[x]= (signed char)rand();
2224 }
2225
2226 memcached_flush(memc, 0);
2227
2228 const char *keys= "036790384900";
2229 size_t key_length= strlen(keys);
2230 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys, key_length,
2231 insert_data, VALUE_SIZE_BUG5,
2232 time_t(0), 245U));
2233
2234 memcached_return_t rc;
2235 size_t value_length;
2236 uint32_t flags= 0;
2237 char *value= memcached_get(memc, keys, key_length,
2238 &value_length, &flags, &rc);
2239 test_compare(245U, flags);
2240 test_true(value);
2241 free(value);
2242
2243 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, &keys, &key_length, 1));
2244
2245 char return_key[MEMCACHED_MAX_KEY];
2246 size_t return_key_length;
2247 flags= 0;
2248 value= memcached_fetch(memc, return_key, &return_key_length,
2249 &value_length, &flags, &rc);
2250 test_compare(uint32_t(245), flags);
2251 test_true(value);
2252 free(value);
2253 delete [] insert_data;
2254
2255
2256 return TEST_SUCCESS;
2257 }
2258
2259 test_return_t user_supplied_bug9(memcached_st *memc)
2260 {
2261 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2262 size_t key_length[3];
2263 uint32_t flags;
2264 unsigned count= 0;
2265
2266 char return_key[MEMCACHED_MAX_KEY];
2267 size_t return_key_length;
2268 char *return_value;
2269 size_t return_value_length;
2270
2271
2272 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2273 key_length[1]= strlen("fudge&*@#");
2274 key_length[2]= strlen("for^#@&$not");
2275
2276
2277 for (unsigned int x= 0; x < 3; x++)
2278 {
2279 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
2280 keys[x], key_length[x],
2281 (time_t)50, (uint32_t)9);
2282 test_compare(MEMCACHED_SUCCESS, rc);
2283 }
2284
2285 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
2286 test_compare(MEMCACHED_SUCCESS, rc);
2287
2288 /* We need to empty the server before continueing test */
2289 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2290 &return_value_length, &flags, &rc)) != NULL)
2291 {
2292 test_true(return_value);
2293 free(return_value);
2294 count++;
2295 }
2296 test_compare(3U, count);
2297
2298 return TEST_SUCCESS;
2299 }
2300
2301 /* We are testing with aggressive timeout to get failures */
2302 test_return_t user_supplied_bug10(memcached_st *memc)
2303 {
2304 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
2305
2306 size_t value_length= 512;
2307 unsigned int set= 1;
2308 memcached_st *mclone= memcached_clone(NULL, memc);
2309
2310 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2311 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2312 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, uint64_t(0));
2313
2314 libtest::vchar_t value;
2315 value.reserve(value_length);
2316 for (uint32_t x= 0; x < value_length; x++)
2317 {
2318 value.push_back(char(x % 127));
2319 }
2320
2321 for (unsigned int x= 1; x <= 100000; ++x)
2322 {
2323 memcached_return_t rc= memcached_set(mclone,
2324 test_literal_param("foo"),
2325 &value[0], value.size(),
2326 0, 0);
2327
2328 test_true_got((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE
2329 or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED),
2330 memcached_strerror(NULL, rc));
2331
2332 if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
2333 {
2334 x--;
2335 }
2336 }
2337
2338 memcached_free(mclone);
2339
2340 return TEST_SUCCESS;
2341 }
2342
2343 /*
2344 We are looking failures in the async protocol
2345 */
2346 test_return_t user_supplied_bug11(memcached_st *memc)
2347 {
2348 memcached_st *mclone= memcached_clone(NULL, memc);
2349
2350 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, true);
2351 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2352 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, size_t(-1));
2353
2354 test_compare(-1, int32_t(memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT)));
2355
2356
2357 libtest::vchar_t value;
2358 value.reserve(512);
2359 for (unsigned int x= 0; x < 512; x++)
2360 {
2361 value.push_back(char(x % 127));
2362 }
2363
2364 for (unsigned int x= 1; x <= 100000; ++x)
2365 {
2366 memcached_return_t rc= memcached_set(mclone, test_literal_param("foo"), &value[0], value.size(), 0, 0);
2367 (void)rc;
2368 }
2369
2370 memcached_free(mclone);
2371
2372 return TEST_SUCCESS;
2373 }
2374
2375 /*
2376 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2377 */
2378 test_return_t user_supplied_bug12(memcached_st *memc)
2379 {
2380 memcached_return_t rc;
2381 uint32_t flags;
2382 size_t value_length;
2383 char *value;
2384 uint64_t number_value;
2385
2386 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2387 &value_length, &flags, &rc);
2388 test_null(value);
2389 test_compare(MEMCACHED_NOTFOUND, rc);
2390
2391 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2392 1, &number_value);
2393 test_null(value);
2394 /* The binary protocol will set the key if it doesn't exist */
2395 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2396 {
2397 test_compare(MEMCACHED_SUCCESS, rc);
2398 }
2399 else
2400 {
2401 test_compare(MEMCACHED_NOTFOUND, rc);
2402 }
2403
2404 test_compare(MEMCACHED_SUCCESS,
2405 memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0));
2406
2407 value= memcached_get(memc, "autoincrement", strlen("autoincrement"), &value_length, &flags, &rc);
2408 test_true(value);
2409 free(value);
2410
2411 test_compare(MEMCACHED_SUCCESS,
2412 memcached_increment(memc, "autoincrement", strlen("autoincrement"), 1, &number_value));
2413 test_compare(2UL, number_value);
2414
2415 return TEST_SUCCESS;
2416 }
2417
2418 /*
2419 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2420 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2421 */
2422 test_return_t user_supplied_bug13(memcached_st *memc)
2423 {
2424 char key[] = "key34567890";
2425
2426 char commandFirst[]= "set key34567890 0 0 ";
2427 char commandLast[] = " \r\n"; /* first line of command sent to server */
2428 size_t commandLength;
2429
2430 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2431
2432 size_t overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2433
2434 for (size_t testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2435 {
2436 char *overflow= new (std::nothrow) char[testSize];
2437 test_true(overflow);
2438
2439 memset(overflow, 'x', testSize);
2440 test_compare(MEMCACHED_SUCCESS,
2441 memcached_set(memc, key, strlen(key),
2442 overflow, testSize, 0, 0));
2443 delete [] overflow;
2444 }
2445
2446 return TEST_SUCCESS;
2447 }
2448
2449
2450 /*
2451 Test values of many different sizes
2452 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2453 set key34567890 0 0 8169 \r\n
2454 is sent followed by buffer of size 8169, followed by 8169
2455 */
2456 test_return_t user_supplied_bug14(memcached_st *memc)
2457 {
2458 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2459
2460 libtest::vchar_t value;
2461 value.reserve(18000);
2462 for (ptrdiff_t x= 0; x < 18000; x++)
2463 {
2464 value.push_back((char) (x % 127));
2465 }
2466
2467 for (size_t current_length= 1; current_length < value.size(); current_length++)
2468 {
2469 memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
2470 &value[0], current_length,
2471 (time_t)0, (uint32_t)0);
2472 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
2473
2474 size_t string_length;
2475 uint32_t flags;
2476 char *string= memcached_get(memc, test_literal_param("foo"),
2477 &string_length, &flags, &rc);
2478
2479 test_compare(MEMCACHED_SUCCESS, rc);
2480 test_compare(string_length, current_length);
2481 char buffer[1024];
2482 snprintf(buffer, sizeof(buffer), "%u", uint32_t(string_length));
2483 test_memcmp_hint(string, &value[0], string_length, buffer);
2484
2485 free(string);
2486 }
2487
2488 return TEST_SUCCESS;
2489 }
2490
2491 /*
2492 Look for zero length value problems
2493 */
2494 test_return_t user_supplied_bug15(memcached_st *memc)
2495 {
2496 for (uint32_t x= 0; x < 2; x++)
2497 {
2498 memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
2499 NULL, 0,
2500 (time_t)0, (uint32_t)0);
2501
2502 test_compare(MEMCACHED_SUCCESS, rc);
2503
2504 size_t length;
2505 uint32_t flags;
2506 char *value= memcached_get(memc, test_literal_param("mykey"),
2507 &length, &flags, &rc);
2508
2509 test_compare(MEMCACHED_SUCCESS, rc);
2510 test_false(value);
2511 test_zero(length);
2512 test_zero(flags);
2513
2514 value= memcached_get(memc, test_literal_param("mykey"),
2515 &length, &flags, &rc);
2516
2517 test_compare(MEMCACHED_SUCCESS, rc);
2518 test_null(value);
2519 test_zero(length);
2520 test_zero(flags);
2521 }
2522
2523 return TEST_SUCCESS;
2524 }
2525
2526 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2527 test_return_t user_supplied_bug16(memcached_st *memc)
2528 {
2529 test_compare_hint(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("mykey"),
2530 NULL, 0,
2531 (time_t)0, UINT32_MAX),
2532 memcached_last_error_message(memc));
2533
2534
2535 size_t length;
2536 uint32_t flags;
2537 memcached_return_t rc;
2538 char *value= memcached_get(memc, test_literal_param("mykey"),
2539 &length, &flags, &rc);
2540
2541 test_compare(MEMCACHED_SUCCESS, rc);
2542 test_null(value);
2543 test_zero(length);
2544 test_compare(flags, UINT32_MAX);
2545
2546 return TEST_SUCCESS;
2547 }
2548
2549 #if !defined(__sun) && !defined(__OpenBSD__)
2550 /* Check the validity of chinese key*/
2551 test_return_t user_supplied_bug17(memcached_st *memc)
2552 {
2553 const char *key= "豆瓣";
2554 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2555 memcached_return_t rc= memcached_set(memc, key, strlen(key),
2556 value, strlen(value),
2557 (time_t)0, 0);
2558
2559 test_compare(MEMCACHED_SUCCESS, rc);
2560
2561 size_t length;
2562 uint32_t flags;
2563 char *value2= memcached_get(memc, key, strlen(key),
2564 &length, &flags, &rc);
2565
2566 test_compare(length, strlen(value));
2567 test_compare(MEMCACHED_SUCCESS, rc);
2568 test_memcmp(value, value2, length);
2569 free(value2);
2570
2571 return TEST_SUCCESS;
2572 }
2573 #endif
2574
2575 /*
2576 From Andrei on IRC
2577 */
2578
2579 test_return_t user_supplied_bug19(memcached_st *)
2580 {
2581 memcached_return_t res;
2582
2583 memcached_st *memc= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
2584
2585 memcached_server_instance_st server= memcached_server_by_key(memc, "a", 1, &res);
2586 test_true(server);
2587
2588 memcached_free(memc);
2589
2590 return TEST_SUCCESS;
2591 }
2592
2593 /* CAS test from Andei */
2594 test_return_t user_supplied_bug20(memcached_st *memc)
2595 {
2596 const char *key= "abc";
2597 size_t key_len= strlen("abc");
2598
2599 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
2600
2601 test_compare(MEMCACHED_SUCCESS,
2602 memcached_set(memc,
2603 test_literal_param("abc"),
2604 test_literal_param("foobar"),
2605 (time_t)0, (uint32_t)0));
2606
2607 test_compare(MEMCACHED_SUCCESS,
2608 memcached_mget(memc, &key, &key_len, 1));
2609
2610 memcached_result_st result_obj;
2611 memcached_result_st *result= memcached_result_create(memc, &result_obj);
2612 test_true(result);
2613
2614 memcached_result_create(memc, &result_obj);
2615 memcached_return_t status;
2616 result= memcached_fetch_result(memc, &result_obj, &status);
2617
2618 test_true(result);
2619 test_compare(MEMCACHED_SUCCESS, status);
2620
2621 memcached_result_free(result);
2622
2623 return TEST_SUCCESS;
2624 }
2625
2626 /* Large mget() of missing keys with binary proto
2627 *
2628 * If many binary quiet commands (such as getq's in an mget) fill the output
2629 * buffer and the server chooses not to respond, memcached_flush hangs. See
2630 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2631 */
2632
2633 /* sighandler_t function that always asserts false */
2634 static void fail(int)
2635 {
2636 fatal_assert(0);
2637 }
2638
2639
2640 test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2641 {
2642 #ifdef WIN32
2643 (void)memc;
2644 (void)key_count;
2645 return TEST_SKIPPED;
2646 #else
2647 void (*oldalarm)(int);
2648
2649 memcached_st *memc_clone= memcached_clone(NULL, memc);
2650 test_true(memc_clone);
2651
2652 /* only binproto uses getq for mget */
2653 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
2654
2655 /* empty the cache to ensure misses (hence non-responses) */
2656 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
2657
2658 keys_st keys(key_count);
2659
2660 oldalarm= signal(SIGALRM, fail);
2661 alarm(5);
2662
2663 test_compare_got(MEMCACHED_SUCCESS,
2664 memcached_mget(memc_clone, keys.keys_ptr(), keys.lengths_ptr(), keys.size()),
2665 memcached_last_error_message(memc_clone));
2666
2667 alarm(0);
2668 signal(SIGALRM, oldalarm);
2669
2670 memcached_return_t rc;
2671 uint32_t flags;
2672 char return_key[MEMCACHED_MAX_KEY];
2673 size_t return_key_length;
2674 char *return_value;
2675 size_t return_value_length;
2676 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2677 &return_value_length, &flags, &rc)))
2678 {
2679 test_false(return_value); // There are no keys to fetch, so the value should never be returned
2680 }
2681 test_compare(MEMCACHED_NOTFOUND, rc);
2682 test_zero(return_value_length);
2683 test_zero(return_key_length);
2684 test_false(return_key[0]);
2685 test_false(return_value);
2686
2687 memcached_free(memc_clone);
2688
2689 return TEST_SUCCESS;
2690 #endif
2691 }
2692
2693 test_return_t user_supplied_bug21(memcached_st *memc)
2694 {
2695 test_skip(TEST_SUCCESS, pre_binary(memc));
2696
2697 /* should work as of r580 */
2698 test_compare(TEST_SUCCESS,
2699 _user_supplied_bug21(memc, 10));
2700
2701 /* should fail as of r580 */
2702 test_compare(TEST_SUCCESS,
2703 _user_supplied_bug21(memc, 1000));
2704
2705 return TEST_SUCCESS;
2706 }
2707
2708 test_return_t output_ketama_weighted_keys(memcached_st *)
2709 {
2710 memcached_st *memc= memcached_create(NULL);
2711 test_true(memc);
2712
2713
2714 test_compare(MEMCACHED_SUCCESS,
2715 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
2716
2717 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2718 test_compare(value, uint64_t(1));
2719
2720 test_compare(MEMCACHED_SUCCESS,
2721 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
2722
2723 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2724 test_true(value == MEMCACHED_HASH_MD5);
2725
2726
2727 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2728
2729 memcached_server_st *server_pool;
2730 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");
2731 memcached_server_push(memc, server_pool);
2732
2733 // @todo this needs to be refactored to actually test something.
2734 #if 0
2735 FILE *fp;
2736 if ((fp = fopen("ketama_keys.txt", "w")))
2737 {
2738 // noop
2739 } else {
2740 printf("cannot write to file ketama_keys.txt");
2741 return TEST_FAILURE;
2742 }
2743
2744 for (int x= 0; x < 10000; x++)
2745 {
2746 char key[10];
2747 snprintf(key, sizeof(key), "%d", x);
2748
2749 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2750 char *hostname = memc->hosts[server_idx].hostname;
2751 in_port_t port = memc->hosts[server_idx].port;
2752 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2753 memcached_server_instance_st instance=
2754 memcached_server_instance_by_position(memc, host_index);
2755 }
2756 fclose(fp);
2757 #endif
2758 memcached_server_list_free(server_pool);
2759 memcached_free(memc);
2760
2761 return TEST_SUCCESS;
2762 }
2763
2764
2765 test_return_t result_static(memcached_st *memc)
2766 {
2767 memcached_result_st result;
2768 memcached_result_st *result_ptr= memcached_result_create(memc, &result);
2769 test_false(result.options.is_allocated);
2770 test_true(memcached_is_initialized(&result));
2771 test_true(result_ptr);
2772 test_true(result_ptr == &result);
2773
2774 memcached_result_free(&result);
2775
2776 test_false(result.options.is_allocated);
2777 test_false(memcached_is_initialized(&result));
2778
2779 return TEST_SUCCESS;
2780 }
2781
2782 test_return_t result_alloc(memcached_st *memc)
2783 {
2784 memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
2785 test_true(result_ptr);
2786 test_true(result_ptr->options.is_allocated);
2787 test_true(memcached_is_initialized(result_ptr));
2788 memcached_result_free(result_ptr);
2789
2790 return TEST_SUCCESS;
2791 }
2792
2793
2794 test_return_t add_host_test1(memcached_st *memc)
2795 {
2796 memcached_return_t rc;
2797 char servername[]= "0.example.com";
2798
2799 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
2800 test_true(servers);
2801 test_compare(1U, memcached_server_list_count(servers));
2802
2803 for (uint32_t x= 2; x < 20; x++)
2804 {
2805 char buffer[SMALL_STRING_LEN];
2806
2807 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
2808 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
2809 &rc);
2810 test_compare(MEMCACHED_SUCCESS, rc);
2811 test_compare(x, memcached_server_list_count(servers));
2812 }
2813
2814 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2815 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2816
2817 memcached_server_list_free(servers);
2818
2819 return TEST_SUCCESS;
2820 }
2821
2822
2823 static void my_free(const memcached_st *ptr, void *mem, void *context)
2824 {
2825 (void)context;
2826 (void)ptr;
2827 #ifdef HARD_MALLOC_TESTS
2828 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
2829 free(real_ptr);
2830 #else
2831 free(mem);
2832 #endif
2833 }
2834
2835
2836 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
2837 {
2838 (void)context;
2839 (void)ptr;
2840 #ifdef HARD_MALLOC_TESTS
2841 void *ret= malloc(size + 8);
2842 if (ret != NULL)
2843 {
2844 ret= (void*)((caddr_t)ret + 8);
2845 }
2846 #else
2847 void *ret= malloc(size);
2848 #endif
2849
2850 if (ret != NULL)
2851 {
2852 memset(ret, 0xff, size);
2853 }
2854
2855 return ret;
2856 }
2857
2858
2859 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
2860 {
2861 #ifdef HARD_MALLOC_TESTS
2862 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
2863 void *nmem= realloc(real_ptr, size + 8);
2864
2865 void *ret= NULL;
2866 if (nmem != NULL)
2867 {
2868 ret= (void*)((caddr_t)nmem + 8);
2869 }
2870
2871 return ret;
2872 #else
2873 (void)ptr;
2874 return realloc(mem, size);
2875 #endif
2876 }
2877
2878
2879 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
2880 {
2881 #ifdef HARD_MALLOC_TESTS
2882 void *mem= my_malloc(ptr, nelem * size);
2883 if (mem)
2884 {
2885 memset(mem, 0, nelem * size);
2886 }
2887
2888 return mem;
2889 #else
2890 (void)ptr;
2891 return calloc(nelem, size);
2892 #endif
2893 }
2894
2895 test_return_t selection_of_namespace_tests(memcached_st *memc)
2896 {
2897 memcached_return_t rc;
2898 const char *key= "mine";
2899 char *value;
2900
2901 /* Make sure be default none exists */
2902 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2903 test_null(value);
2904 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2905
2906 /* Test a clean set */
2907 test_compare(MEMCACHED_SUCCESS,
2908 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2909
2910 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2911 test_true(value);
2912 test_memcmp(value, key, 4);
2913 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2914
2915 /* Test that we can turn it off */
2916 test_compare(MEMCACHED_SUCCESS,
2917 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
2918
2919 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2920 test_null(value);
2921 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2922
2923 /* Now setup for main test */
2924 test_compare(MEMCACHED_SUCCESS,
2925 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2926
2927 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2928 test_true(value);
2929 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2930 test_memcmp(value, key, 4);
2931
2932 /* Set to Zero, and then Set to something too large */
2933 {
2934 char long_key[255];
2935 memset(long_key, 0, 255);
2936
2937 test_compare(MEMCACHED_SUCCESS,
2938 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
2939
2940 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2941 test_null(value);
2942 test_compare(MEMCACHED_SUCCESS, rc);
2943
2944 /* Test a long key for failure */
2945 /* TODO, extend test to determine based on setting, what result should be */
2946 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
2947 test_compare(MEMCACHED_SUCCESS,
2948 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
2949
2950 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
2951 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
2952 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
2953 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
2954
2955 /* Test for a bad prefix, but with a short key */
2956 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
2957 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
2958
2959 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
2960 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "dog cat"));
2961 }
2962
2963 return TEST_SUCCESS;
2964 }
2965
2966 test_return_t set_namespace(memcached_st *memc)
2967 {
2968 memcached_return_t rc;
2969 const char *key= "mine";
2970 char *value;
2971
2972 // Make sure we default to a null namespace
2973 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2974 test_null(value);
2975 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2976
2977 /* Test a clean set */
2978 test_compare(MEMCACHED_SUCCESS,
2979 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2980
2981 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2982 test_true(value);
2983 test_memcmp(value, key, 4);
2984 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2985
2986 return TEST_SUCCESS;
2987 }
2988
2989 test_return_t set_namespace_and_binary(memcached_st *memc)
2990 {
2991 test_return_if(pre_binary(memc));
2992 test_return_if(set_namespace(memc));
2993
2994 return TEST_SUCCESS;
2995 }
2996
2997 #ifdef MEMCACHED_ENABLE_DEPRECATED
2998 test_return_t deprecated_set_memory_alloc(memcached_st *memc)
2999 {
3000 void *test_ptr= NULL;
3001 void *cb_ptr= NULL;
3002 {
3003 memcached_malloc_fn malloc_cb= (memcached_malloc_fn)my_malloc;
3004 cb_ptr= *(void **)&malloc_cb;
3005 memcached_return_t rc;
3006
3007 test_compare(MEMCACHED_SUCCESS,
3008 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
3009 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3010 test_compare(MEMCACHED_SUCCESS, rc);
3011 test_true(test_ptr == cb_ptr);
3012 }
3013
3014 {
3015 memcached_realloc_fn realloc_cb=
3016 (memcached_realloc_fn)my_realloc;
3017 cb_ptr= *(void **)&realloc_cb;
3018 memcached_return_t rc;
3019
3020 test_compare(MEMCACHED_SUCCESS,
3021 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
3022 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3023 test_compare(MEMCACHED_SUCCESS, rc);
3024 test_true(test_ptr == cb_ptr);
3025 }
3026
3027 {
3028 memcached_free_fn free_cb=
3029 (memcached_free_fn)my_free;
3030 cb_ptr= *(void **)&free_cb;
3031 memcached_return_t rc;
3032
3033 test_compare(MEMCACHED_SUCCESS,
3034 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
3035 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3036 test_compare(MEMCACHED_SUCCESS, rc);
3037 test_true(test_ptr == cb_ptr);
3038 }
3039
3040 return TEST_SUCCESS;
3041 }
3042 #endif
3043
3044
3045 test_return_t set_memory_alloc(memcached_st *memc)
3046 {
3047 test_compare(MEMCACHED_INVALID_ARGUMENTS,
3048 memcached_set_memory_allocators(memc, NULL, my_free,
3049 my_realloc, my_calloc, NULL));
3050
3051 test_compare(MEMCACHED_SUCCESS,
3052 memcached_set_memory_allocators(memc, my_malloc, my_free,
3053 my_realloc, my_calloc, NULL));
3054
3055 memcached_malloc_fn mem_malloc;
3056 memcached_free_fn mem_free;
3057 memcached_realloc_fn mem_realloc;
3058 memcached_calloc_fn mem_calloc;
3059 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3060 &mem_realloc, &mem_calloc);
3061
3062 test_true(mem_malloc == my_malloc);
3063 test_true(mem_realloc == my_realloc);
3064 test_true(mem_calloc == my_calloc);
3065 test_true(mem_free == my_free);
3066
3067 return TEST_SUCCESS;
3068 }
3069
3070 test_return_t enable_consistent_crc(memcached_st *memc)
3071 {
3072 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT));
3073 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3074
3075 test_return_t rc;
3076 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3077 {
3078 return rc;
3079 }
3080
3081 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3082
3083 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_CRC)
3084 {
3085 return TEST_SKIPPED;
3086 }
3087
3088 return TEST_SUCCESS;
3089 }
3090
3091 test_return_t enable_consistent_hsieh(memcached_st *memc)
3092 {
3093 test_return_t rc;
3094 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT);
3095 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3096 {
3097 return rc;
3098 }
3099
3100 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3101
3102 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_HSIEH)
3103 {
3104 return TEST_SKIPPED;
3105 }
3106
3107 return TEST_SUCCESS;
3108 }
3109
3110 test_return_t enable_cas(memcached_st *memc)
3111 {
3112 unsigned int set= 1;
3113
3114 if (libmemcached_util_version_check(memc, 1, 2, 4))
3115 {
3116 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3117
3118 return TEST_SUCCESS;
3119 }
3120
3121 return TEST_SKIPPED;
3122 }
3123
3124 test_return_t check_for_1_2_3(memcached_st *memc)
3125 {
3126 memcached_version(memc);
3127
3128 memcached_server_instance_st instance=
3129 memcached_server_instance_by_position(memc, 0);
3130
3131 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3132 or instance->minor_version > 2)
3133 {
3134 return TEST_SUCCESS;
3135 }
3136
3137 return TEST_SKIPPED;
3138 }
3139
3140 test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc)
3141 {
3142 const uint64_t timeout= 100; // Not using, just checking that it sets
3143
3144 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3145
3146 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
3147
3148 return TEST_SUCCESS;
3149 }
3150
3151 test_return_t noreply_test(memcached_st *memc)
3152 {
3153 test_compare(MEMCACHED_SUCCESS,
3154 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
3155 test_compare(MEMCACHED_SUCCESS,
3156 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3157 test_compare(MEMCACHED_SUCCESS,
3158 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
3159 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
3160 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
3161 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS));
3162
3163 memcached_return_t ret;
3164 for (int count= 0; count < 5; ++count)
3165 {
3166 for (size_t x= 0; x < 100; ++x)
3167 {
3168 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
3169 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3170 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3171
3172 size_t len= (size_t)check_length;
3173
3174 switch (count)
3175 {
3176 case 0:
3177 ret= memcached_add(memc, key, len, key, len, 0, 0);
3178 break;
3179 case 1:
3180 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3181 break;
3182 case 2:
3183 ret= memcached_set(memc, key, len, key, len, 0, 0);
3184 break;
3185 case 3:
3186 ret= memcached_append(memc, key, len, key, len, 0, 0);
3187 break;
3188 case 4:
3189 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3190 break;
3191 default:
3192 test_true(count);
3193 break;
3194 }
3195 test_true_got(ret == MEMCACHED_SUCCESS or ret == MEMCACHED_BUFFERED,
3196 memcached_strerror(NULL, ret));
3197 }
3198
3199 /*
3200 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3201 ** API and is _ONLY_ done this way to verify that the library works the
3202 ** way it is supposed to do!!!!
3203 */
3204 #if 0
3205 int no_msg=0;
3206 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
3207 {
3208 memcached_server_instance_st instance=
3209 memcached_server_instance_by_position(memc, x);
3210 no_msg+=(int)(instance->cursor_active);
3211 }
3212
3213 test_true(no_msg == 0);
3214 #endif
3215 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
3216
3217 /*
3218 ** Now validate that all items was set properly!
3219 */
3220 for (size_t x= 0; x < 100; ++x)
3221 {
3222 char key[10];
3223
3224 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3225
3226 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3227
3228 size_t len= (size_t)check_length;
3229 size_t length;
3230 uint32_t flags;
3231 char* value=memcached_get(memc, key, strlen(key),
3232 &length, &flags, &ret);
3233 // For the moment we will just go to the next key
3234 if (MEMCACHED_TIMEOUT == ret)
3235 {
3236 continue;
3237 }
3238 test_true(ret == MEMCACHED_SUCCESS and value != NULL);
3239 switch (count)
3240 {
3241 case 0: /* FALLTHROUGH */
3242 case 1: /* FALLTHROUGH */
3243 case 2:
3244 test_true(strncmp(value, key, len) == 0);
3245 test_true(len == length);
3246 break;
3247 case 3:
3248 test_true(length == len * 2);
3249 break;
3250 case 4:
3251 test_true(length == len * 3);
3252 break;
3253 default:
3254 test_true(count);
3255 break;
3256 }
3257 free(value);
3258 }
3259 }
3260
3261 /* Try setting an illegal cas value (should not return an error to
3262 * the caller (because we don't expect a return message from the server)
3263 */
3264 const char* keys[]= {"0"};
3265 size_t lengths[]= {1};
3266 size_t length;
3267 uint32_t flags;
3268 memcached_result_st results_obj;
3269 memcached_result_st *results;
3270 test_compare(MEMCACHED_SUCCESS,
3271 memcached_mget(memc, keys, lengths, 1));
3272
3273 results= memcached_result_create(memc, &results_obj);
3274 test_true(results);
3275 results= memcached_fetch_result(memc, &results_obj, &ret);
3276 test_true(results);
3277 test_compare(MEMCACHED_SUCCESS, ret);
3278 uint64_t cas= memcached_result_cas(results);
3279 memcached_result_free(&results_obj);
3280
3281 test_compare(MEMCACHED_SUCCESS,
3282 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3283
3284 /*
3285 * The item will have a new cas value, so try to set it again with the old
3286 * value. This should fail!
3287 */
3288 test_compare(MEMCACHED_SUCCESS,
3289 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3290 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3291 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3292 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
3293 free(value);
3294
3295 return TEST_SUCCESS;
3296 }
3297
3298 test_return_t analyzer_test(memcached_st *memc)
3299 {
3300 memcached_analysis_st *report;
3301 memcached_return_t rc;
3302
3303 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3304 test_compare(MEMCACHED_SUCCESS, rc);
3305 test_true(memc_stat);
3306
3307 report= memcached_analyze(memc, memc_stat, &rc);
3308 test_compare(MEMCACHED_SUCCESS, rc);
3309 test_true(report);
3310
3311 free(report);
3312 memcached_stat_free(NULL, memc_stat);
3313
3314 return TEST_SUCCESS;
3315 }
3316
3317 test_return_t util_version_test(memcached_st *memc)
3318 {
3319 test_compare_hint(MEMCACHED_SUCCESS, memcached_version(memc), memcached_last_error_message(memc));
3320 test_true(libmemcached_util_version_check(memc, 0, 0, 0));
3321
3322 bool if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
3323
3324 // We expect failure
3325 if (if_successful)
3326 {
3327 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3328 fprintf(stderr, "\nDumping Server Information\n\n");
3329 memcached_server_fn callbacks[1];
3330
3331 callbacks[0]= dump_server_information;
3332 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
3333 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3334 }
3335 test_true(if_successful == false);
3336
3337 memcached_server_instance_st instance=
3338 memcached_server_instance_by_position(memc, 0);
3339
3340 memcached_version(memc);
3341
3342 // We only use one binary when we test, so this should be just fine.
3343 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
3344 test_true(if_successful == true);
3345
3346 if (instance->micro_version > 0)
3347 {
3348 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
3349 }
3350 else if (instance->minor_version > 0)
3351 {
3352 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
3353 }
3354 else if (instance->major_version > 0)
3355 {
3356 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
3357 }
3358
3359 test_true(if_successful == true);
3360
3361 if (instance->micro_version > 0)
3362 {
3363 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
3364 }
3365 else if (instance->minor_version > 0)
3366 {
3367 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
3368 }
3369 else if (instance->major_version > 0)
3370 {
3371 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
3372 }
3373
3374 test_true(if_successful == false);
3375
3376 return TEST_SUCCESS;
3377 }
3378
3379 test_return_t getpid_connection_failure_test(memcached_st *memc)
3380 {
3381 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3382 memcached_return_t rc;
3383 memcached_server_instance_st instance=
3384 memcached_server_instance_by_position(memc, 0);
3385
3386 // Test both the version that returns a code, and the one that does not.
3387 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3388 memcached_server_port(instance) -1, NULL) == -1);
3389
3390 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3391 memcached_server_port(instance) -1, &rc) == -1);
3392 test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(memc, rc));
3393
3394 return TEST_SUCCESS;
3395 }
3396
3397
3398 test_return_t getpid_test(memcached_st *memc)
3399 {
3400 memcached_return_t rc;
3401 memcached_server_instance_st instance=
3402 memcached_server_instance_by_position(memc, 0);
3403
3404 // Test both the version that returns a code, and the one that does not.
3405 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3406 memcached_server_port(instance), NULL) > -1);
3407
3408 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3409 memcached_server_port(instance), &rc) > -1);
3410 test_compare(MEMCACHED_SUCCESS, rc);
3411
3412 return TEST_SUCCESS;
3413 }
3414
3415 static memcached_return_t ping_each_server(const memcached_st*,
3416 memcached_server_instance_st instance,
3417 void*)
3418 {
3419 // Test both the version that returns a code, and the one that does not.
3420 memcached_return_t rc;
3421 if (libmemcached_util_ping(memcached_server_name(instance),
3422 memcached_server_port(instance), &rc) == false)
3423 {
3424 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d %s", memcached_server_name(instance),
3425 memcached_server_port(instance), memcached_strerror(NULL, rc));
3426 }
3427
3428 if (libmemcached_util_ping(memcached_server_name(instance),
3429 memcached_server_port(instance), NULL) == false)
3430 {
3431 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d", memcached_server_name(instance), memcached_server_port(instance));
3432 }
3433
3434 return MEMCACHED_SUCCESS;
3435 }
3436
3437 test_return_t libmemcached_util_ping_TEST(memcached_st *memc)
3438 {
3439 memcached_server_fn callbacks[1]= { ping_each_server };
3440 memcached_server_cursor(memc, callbacks, NULL, 1);
3441
3442 return TEST_SUCCESS;
3443 }
3444
3445
3446 #if 0
3447 test_return_t hash_sanity_test (memcached_st *memc)
3448 {
3449 (void)memc;
3450
3451 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
3452 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
3453 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
3454 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
3455 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
3456 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
3457 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
3458 #ifdef HAVE_HSIEH_HASH
3459 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
3460 #endif
3461 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
3462 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
3463 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
3464
3465 return TEST_SUCCESS;
3466 }
3467 #endif
3468
3469 test_return_t hsieh_avaibility_test (memcached_st *memc)
3470 {
3471 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3472
3473 test_compare(MEMCACHED_SUCCESS,
3474 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
3475 (uint64_t)MEMCACHED_HASH_HSIEH));
3476
3477 return TEST_SUCCESS;
3478 }
3479
3480 test_return_t murmur_avaibility_test (memcached_st *memc)
3481 {
3482 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3483
3484 test_compare(MEMCACHED_SUCCESS,
3485 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
3486
3487 return TEST_SUCCESS;
3488 }
3489
3490 test_return_t one_at_a_time_run (memcached_st *)
3491 {
3492 uint32_t x;
3493 const char **ptr;
3494
3495 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3496 {
3497 test_compare(one_at_a_time_values[x],
3498 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT));
3499 }
3500
3501 return TEST_SUCCESS;
3502 }
3503
3504 test_return_t md5_run (memcached_st *)
3505 {
3506 uint32_t x;
3507 const char **ptr;
3508
3509 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3510 {
3511 test_compare(md5_values[x],
3512 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5));
3513 }
3514
3515 return TEST_SUCCESS;
3516 }
3517
3518 test_return_t crc_run (memcached_st *)
3519 {
3520 uint32_t x;
3521 const char **ptr;
3522
3523 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3524 {
3525 test_compare(crc_values[x],
3526 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC));
3527 }
3528
3529 return TEST_SUCCESS;
3530 }
3531
3532 test_return_t fnv1_64_run (memcached_st *)
3533 {
3534 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1_64));
3535
3536 uint32_t x;
3537 const char **ptr;
3538
3539 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3540 {
3541 test_compare(fnv1_64_values[x],
3542 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64));
3543 }
3544
3545 return TEST_SUCCESS;
3546 }
3547
3548 test_return_t fnv1a_64_run (memcached_st *)
3549 {
3550 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1A_64));
3551
3552 uint32_t x;
3553 const char **ptr;
3554
3555 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3556 {
3557 test_compare(fnv1a_64_values[x],
3558 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64));
3559 }
3560
3561 return TEST_SUCCESS;
3562 }
3563
3564 test_return_t fnv1_32_run (memcached_st *)
3565 {
3566 uint32_t x;
3567 const char **ptr;
3568
3569 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3570 {
3571 test_compare(fnv1_32_values[x],
3572 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32));
3573 }
3574
3575 return TEST_SUCCESS;
3576 }
3577
3578 test_return_t fnv1a_32_run (memcached_st *)
3579 {
3580 uint32_t x;
3581 const char **ptr;
3582
3583 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3584 {
3585 test_compare(fnv1a_32_values[x],
3586 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32));
3587 }
3588
3589 return TEST_SUCCESS;
3590 }
3591
3592 test_return_t hsieh_run (memcached_st *)
3593 {
3594 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3595
3596 uint32_t x;
3597 const char **ptr;
3598
3599 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3600 {
3601 test_compare(hsieh_values[x],
3602 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH));
3603 }
3604
3605 return TEST_SUCCESS;
3606 }
3607
3608 test_return_t murmur_run (memcached_st *)
3609 {
3610 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3611
3612 #ifdef WORDS_BIGENDIAN
3613 (void)murmur_values;
3614 return TEST_SKIPPED;
3615 #else
3616 uint32_t x;
3617 const char **ptr;
3618
3619 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3620 {
3621 test_compare(murmur_values[x],
3622 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR));
3623 }
3624
3625 return TEST_SUCCESS;
3626 #endif
3627 }
3628
3629 test_return_t jenkins_run (memcached_st *)
3630 {
3631 uint32_t x;
3632 const char **ptr;
3633
3634 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3635 {
3636 test_compare(jenkins_values[x],
3637 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS));
3638 }
3639
3640 return TEST_SUCCESS;
3641 }
3642
3643 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *)
3644 {
3645 return libhashkit_md5(string, string_length);
3646 }
3647
3648 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *)
3649 {
3650 return libhashkit_crc32(string, string_length);
3651 }
3652
3653 test_return_t memcached_get_hashkit_test (memcached_st *)
3654 {
3655 uint32_t x;
3656 const char **ptr;
3657 hashkit_st new_kit;
3658
3659 memcached_st *memc= memcached(test_literal_param("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5 --DISTRIBUTION=modula"));
3660
3661 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};
3662 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};
3663
3664 const hashkit_st *kit= memcached_get_hashkit(memc);
3665
3666 hashkit_clone(&new_kit, kit);
3667 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL));
3668
3669 memcached_set_hashkit(memc, &new_kit);
3670
3671 /*
3672 Verify Setting the hash.
3673 */
3674 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3675 {
3676 uint32_t hash_val;
3677
3678 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3679 test_compare_got(md5_values[x], hash_val, *ptr);
3680 }
3681
3682
3683 /*
3684 Now check memcached_st.
3685 */
3686 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3687 {
3688 uint32_t hash_val;
3689
3690 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3691 test_compare_got(md5_hosts[x], hash_val, *ptr);
3692 }
3693
3694 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL));
3695
3696 memcached_set_hashkit(memc, &new_kit);
3697
3698 /*
3699 Verify Setting the hash.
3700 */
3701 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3702 {
3703 uint32_t hash_val;
3704
3705 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3706 test_true(crc_values[x] == hash_val);
3707 }
3708
3709 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3710 {
3711 uint32_t hash_val;
3712
3713 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3714 test_compare(crc_hosts[x], hash_val);
3715 }
3716
3717 memcached_free(memc);
3718
3719 return TEST_SUCCESS;
3720 }
3721
3722 /*
3723 Test case adapted from John Gorman <johngorman2@gmail.com>
3724
3725 We are testing the error condition when we connect to a server via memcached_get()
3726 but find that the server is not available.
3727 */
3728 test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
3729 {
3730 size_t len;
3731 uint32_t flags;
3732 memcached_return rc;
3733
3734 // Create a handle.
3735 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
3736
3737 // See if memcached is reachable.
3738 char *value= memcached_get(tl_memc_h,
3739 test_literal_param(__func__),
3740 &len, &flags, &rc);
3741
3742 test_false(value);
3743 test_zero(len);
3744 test_true(memcached_failed(rc));
3745
3746 memcached_free(tl_memc_h);
3747
3748 return TEST_SUCCESS;
3749 }
3750
3751 /*
3752 We connect to a server which exists, but search for a key that does not exist.
3753 */
3754 test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
3755 {
3756 size_t len;
3757 uint32_t flags;
3758 memcached_return rc;
3759
3760 // See if memcached is reachable.
3761 char *value= memcached_get(memc,
3762 test_literal_param(__func__),
3763 &len, &flags, &rc);
3764
3765 test_false(value);
3766 test_zero(len);
3767 test_compare(MEMCACHED_NOTFOUND, rc);
3768
3769 return TEST_SUCCESS;
3770 }
3771
3772 /*
3773 Test case adapted from John Gorman <johngorman2@gmail.com>
3774
3775 We are testing the error condition when we connect to a server via memcached_get_by_key()
3776 but find that the server is not available.
3777 */
3778 test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *)
3779 {
3780 size_t len;
3781 uint32_t flags;
3782 memcached_return rc;
3783
3784 // Create a handle.
3785 memcached_st *tl_memc_h= memcached_create(NULL);
3786 memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
3787 memcached_server_push(tl_memc_h, servers);
3788 memcached_server_list_free(servers);
3789
3790 // See if memcached is reachable.
3791 char *value= memcached_get_by_key(tl_memc_h,
3792 test_literal_param(__func__), // Key
3793 test_literal_param(__func__), // Value
3794 &len, &flags, &rc);
3795
3796 test_false(value);
3797 test_zero(len);
3798 test_true(memcached_failed(rc));
3799
3800 memcached_free(tl_memc_h);
3801
3802 return TEST_SUCCESS;
3803 }
3804
3805 /*
3806 We connect to a server which exists, but search for a key that does not exist.
3807 */
3808 test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
3809 {
3810 size_t len;
3811 uint32_t flags;
3812 memcached_return rc;
3813
3814 // See if memcached is reachable.
3815 char *value= memcached_get_by_key(memc,
3816 test_literal_param(__func__), // Key
3817 test_literal_param(__func__), // Value
3818 &len, &flags, &rc);
3819
3820 test_false(value);
3821 test_zero(len);
3822 test_compare(MEMCACHED_NOTFOUND, rc);
3823
3824 return TEST_SUCCESS;
3825 }
3826
3827 test_return_t regression_bug_434484(memcached_st *memc)
3828 {
3829 test_skip(TEST_SUCCESS, pre_binary(memc));
3830
3831 test_compare(MEMCACHED_NOTSTORED,
3832 memcached_append(memc,
3833 test_literal_param(__func__), // Key
3834 test_literal_param(__func__), // Value
3835 0, 0));
3836
3837 libtest::vchar_t data;
3838 data.resize(2048 * 1024);
3839 test_compare(MEMCACHED_E2BIG,
3840 memcached_set(memc,
3841 test_literal_param(__func__), // Key
3842 &data[0], data.size(), 0, 0));
3843
3844 return TEST_SUCCESS;
3845 }
3846
3847 test_return_t regression_bug_434843(memcached_st *original_memc)
3848 {
3849 test_skip(TEST_SUCCESS, pre_binary(original_memc));
3850
3851 memcached_return_t rc;
3852 size_t counter= 0;
3853 memcached_execute_fn callbacks[]= { &callback_counter };
3854
3855 /*
3856 * I only want to hit only _one_ server so I know the number of requests I'm
3857 * sending in the pipleine to the server. Let's try to do a multiget of
3858 * 1024 (that should satisfy most users don't you think?). Future versions
3859 * will include a mget_execute function call if you need a higher number.
3860 */
3861 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
3862
3863 keys_st keys(1024);
3864
3865 /*
3866 * Run two times.. the first time we should have 100% cache miss,
3867 * and the second time we should have 100% cache hits
3868 */
3869 for (ptrdiff_t y= 0; y < 2; y++)
3870 {
3871 test_compare(MEMCACHED_SUCCESS,
3872 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
3873
3874 // One the first run we should get a NOT_FOUND, but on the second some data
3875 // should be returned.
3876 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
3877 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
3878
3879 if (y == 0)
3880 {
3881 /* The first iteration should give me a 100% cache miss. verify that*/
3882 char blob[1024]= { 0 };
3883
3884 test_false(counter);
3885
3886 for (size_t x= 0; x < keys.size(); ++x)
3887 {
3888 rc= memcached_add(memc,
3889 keys.key_at(x), keys.length_at(x),
3890 blob, sizeof(blob), 0, 0);
3891 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3892 }
3893 }
3894 else
3895 {
3896 /* Verify that we received all of the key/value pairs */
3897 test_compare(counter, keys.size());
3898 }
3899 }
3900
3901 memcached_free(memc);
3902
3903 return TEST_SUCCESS;
3904 }
3905
3906 test_return_t regression_bug_434843_buffered(memcached_st *memc)
3907 {
3908 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3909
3910 return regression_bug_434843(memc);
3911 }
3912
3913 test_return_t regression_bug_421108(memcached_st *memc)
3914 {
3915 memcached_return_t rc;
3916 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3917 test_compare(MEMCACHED_SUCCESS, rc);
3918
3919 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
3920 test_compare(MEMCACHED_SUCCESS, rc);
3921 test_true(bytes_str);
3922 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
3923 "bytes_read", &rc);
3924 test_compare(MEMCACHED_SUCCESS, rc);
3925 test_true(bytes_read_str);
3926
3927 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
3928 "bytes_written", &rc);
3929 test_compare(MEMCACHED_SUCCESS, rc);
3930 test_true(bytes_written_str);
3931
3932 unsigned long long bytes= strtoull(bytes_str, 0, 10);
3933 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
3934 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
3935
3936 test_true(bytes != bytes_read);
3937 test_true(bytes != bytes_written);
3938
3939 /* Release allocated resources */
3940 free(bytes_str);
3941 free(bytes_read_str);
3942 free(bytes_written_str);
3943 memcached_stat_free(NULL, memc_stat);
3944
3945 return TEST_SUCCESS;
3946 }
3947
3948 /*
3949 * The test case isn't obvious so I should probably document why
3950 * it works the way it does. Bug 442914 was caused by a bug
3951 * in the logic in memcached_purge (it did not handle the case
3952 * where the number of bytes sent was equal to the watermark).
3953 * In this test case, create messages so that we hit that case
3954 * and then disable noreply mode and issue a new command to
3955 * verify that it isn't stuck. If we change the format for the
3956 * delete command or the watermarks, we need to update this
3957 * test....
3958 */
3959 test_return_t regression_bug_442914(memcached_st *original_memc)
3960 {
3961 test_skip(original_memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3962
3963 memcached_st* memc= create_single_instance_memcached(original_memc, "--NOREPLY --TCP-NODELAY");
3964
3965 for (uint32_t x= 0; x < 250; ++x)
3966 {
3967 char key[250];
3968 size_t len= (size_t)snprintf(key, sizeof(key), "%0250u", x);
3969 memcached_return_t rc= memcached_delete(memc, key, len, 0);
3970 char error_buffer[2048]= { 0 };
3971 snprintf(error_buffer, sizeof(error_buffer), "%s key: %s", memcached_last_error_message(memc), key);
3972 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, error_buffer);
3973 }
3974
3975 // Delete, and then delete again to look for not found
3976 {
3977 char key[250];
3978 size_t len= snprintf(key, sizeof(key), "%037u", 251U);
3979 memcached_return_t rc= memcached_delete(memc, key, len, 0);
3980 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
3981
3982 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, false));
3983 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, key, len, 0));
3984 }
3985
3986 memcached_free(memc);
3987
3988 return TEST_SUCCESS;
3989 }
3990
3991 test_return_t regression_bug_447342(memcached_st *memc)
3992 {
3993 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
3994 {
3995 return TEST_SKIPPED;
3996 }
3997
3998 test_compare(MEMCACHED_SUCCESS,
3999 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
4000
4001 keys_st keys(100);
4002
4003 for (size_t x= 0; x < keys.size(); ++x)
4004 {
4005 test_compare(MEMCACHED_SUCCESS,
4006 memcached_set(memc,
4007 keys.key_at(x), keys.length_at(x), // Keys
4008 keys.key_at(x), keys.length_at(x), // Values
4009 0, 0));
4010 }
4011
4012 /*
4013 ** We are using the quiet commands to store the replicas, so we need
4014 ** to ensure that all of them are processed before we can continue.
4015 ** In the test we go directly from storing the object to trying to
4016 ** receive the object from all of the different servers, so we
4017 ** could end up in a race condition (the memcached server hasn't yet
4018 ** processed the quiet command from the replication set when it process
4019 ** the request from the other client (created by the clone)). As a
4020 ** workaround for that we call memcached_quit to send the quit command
4021 ** to the server and wait for the response ;-) If you use the test code
4022 ** as an example for your own code, please note that you shouldn't need
4023 ** to do this ;-)
4024 */
4025 memcached_quit(memc);
4026
4027 /* Verify that all messages are stored, and we didn't stuff too much
4028 * into the servers
4029 */
4030 test_compare(MEMCACHED_SUCCESS,
4031 memcached_mget(memc,
4032 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4033
4034 unsigned int counter= 0;
4035 memcached_execute_fn callbacks[]= { &callback_counter };
4036 test_compare(MEMCACHED_SUCCESS,
4037 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4038
4039 /* Verify that we received all of the key/value pairs */
4040 test_compare(counter, keys.size());
4041
4042 memcached_quit(memc);
4043 /*
4044 * Don't do the following in your code. I am abusing the internal details
4045 * within the library, and this is not a supported interface.
4046 * This is to verify correct behavior in the library. Fake that two servers
4047 * are dead..
4048 */
4049 memcached_server_instance_st instance_one= memcached_server_instance_by_position(memc, 0);
4050 memcached_server_instance_st instance_two= memcached_server_instance_by_position(memc, 2);
4051 in_port_t port0= instance_one->port;
4052 in_port_t port2= instance_two->port;
4053
4054 ((memcached_server_write_instance_st)instance_one)->port= 0;
4055 ((memcached_server_write_instance_st)instance_two)->port= 0;
4056
4057 test_compare(MEMCACHED_SUCCESS,
4058 memcached_mget(memc,
4059 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4060
4061 counter= 0;
4062 test_compare(MEMCACHED_SUCCESS,
4063 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4064 test_compare(counter, keys.size());
4065
4066 /* restore the memc handle */
4067 ((memcached_server_write_instance_st)instance_one)->port= port0;
4068 ((memcached_server_write_instance_st)instance_two)->port= port2;
4069
4070 memcached_quit(memc);
4071
4072 /* Remove half of the objects */
4073 for (size_t x= 0; x < keys.size(); ++x)
4074 {
4075 if (x & 1)
4076 {
4077 test_compare(MEMCACHED_SUCCESS,
4078 memcached_delete(memc, keys.key_at(x), keys.length_at(x), 0));
4079 }
4080 }
4081
4082 memcached_quit(memc);
4083 ((memcached_server_write_instance_st)instance_one)->port= 0;
4084 ((memcached_server_write_instance_st)instance_two)->port= 0;
4085
4086 /* now retry the command, this time we should have cache misses */
4087 test_compare(MEMCACHED_SUCCESS,
4088 memcached_mget(memc,
4089 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4090
4091 counter= 0;
4092 test_compare(MEMCACHED_SUCCESS,
4093 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4094 test_compare(counter, (unsigned int)(keys.size() >> 1));
4095
4096 /* restore the memc handle */
4097 ((memcached_server_write_instance_st)instance_one)->port= port0;
4098 ((memcached_server_write_instance_st)instance_two)->port= port2;
4099
4100 return TEST_SUCCESS;
4101 }
4102
4103 test_return_t regression_bug_463297(memcached_st *memc)
4104 {
4105 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc, "foo", 3, 1));
4106
4107 // Since we blocked timed delete, this test is no longer valid.
4108 #if 0
4109 memcached_st *memc_clone= memcached_clone(NULL, memc);
4110 test_true(memc_clone);
4111 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
4112
4113 memcached_server_instance_st instance=
4114 memcached_server_instance_by_position(memc_clone, 0);
4115
4116 if (instance->major_version > 1 ||
4117 (instance->major_version == 1 &&
4118 instance->minor_version > 2))
4119 {
4120 /* Binary protocol doesn't support deferred delete */
4121 memcached_st *bin_clone= memcached_clone(NULL, memc);
4122 test_true(bin_clone);
4123 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4124 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
4125 memcached_free(bin_clone);
4126
4127 memcached_quit(memc_clone);
4128
4129 /* If we know the server version, deferred delete should fail
4130 * with invalid arguments */
4131 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
4132
4133 /* If we don't know the server version, we should get a protocol error */
4134 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
4135
4136 /* but there is a bug in some of the memcached servers (1.4) that treats
4137 * the counter as noreply so it doesn't send the proper error message
4138 */
4139 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4140
4141 /* And buffered mode should be disabled and we should get protocol error */
4142 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
4143 rc= memcached_delete(memc, "foo", 3, 1);
4144 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4145
4146 /* Same goes for noreply... */
4147 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
4148 rc= memcached_delete(memc, "foo", 3, 1);
4149 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4150
4151 /* but a normal request should go through (and be buffered) */
4152 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
4153 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
4154
4155 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
4156 /* unbuffered noreply should be success */
4157 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
4158 /* unbuffered with reply should be not found... */
4159 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
4160 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
4161 }
4162
4163 memcached_free(memc_clone);
4164 #endif
4165
4166 return TEST_SUCCESS;
4167 }
4168
4169
4170 /* Test memcached_server_get_last_disconnect
4171 * For a working server set, shall be NULL
4172 * For a set of non existing server, shall not be NULL
4173 */
4174 test_return_t test_get_last_disconnect(memcached_st *memc)
4175 {
4176 memcached_return_t rc;
4177 memcached_server_instance_st disconnected_server;
4178
4179 /* With the working set of server */
4180 const char *key= "marmotte";
4181 const char *value= "milka";
4182
4183 memcached_reset_last_disconnected_server(memc);
4184 test_false(memc->last_disconnected_server);
4185 rc= memcached_set(memc, key, strlen(key),
4186 value, strlen(value),
4187 (time_t)0, (uint32_t)0);
4188 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4189
4190 disconnected_server = memcached_server_get_last_disconnect(memc);
4191 test_false(disconnected_server);
4192
4193 /* With a non existing server */
4194 memcached_st *mine;
4195 memcached_server_st *servers;
4196
4197 const char *server_list= "localhost:9";
4198
4199 servers= memcached_servers_parse(server_list);
4200 test_true(servers);
4201 mine= memcached_create(NULL);
4202 rc= memcached_server_push(mine, servers);
4203 test_compare(MEMCACHED_SUCCESS, rc);
4204 memcached_server_list_free(servers);
4205 test_true(mine);
4206
4207 rc= memcached_set(mine, key, strlen(key),
4208 value, strlen(value),
4209 (time_t)0, (uint32_t)0);
4210 test_true(memcached_failed(rc));
4211
4212 disconnected_server= memcached_server_get_last_disconnect(mine);
4213 test_true_got(disconnected_server, memcached_strerror(mine, rc));
4214 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
4215 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
4216
4217 memcached_quit(mine);
4218 memcached_free(mine);
4219
4220 return TEST_SUCCESS;
4221 }
4222
4223 test_return_t test_multiple_get_last_disconnect(memcached_st *)
4224 {
4225 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
4226 char buffer[BUFSIZ];
4227
4228 test_compare(MEMCACHED_SUCCESS,
4229 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
4230
4231 memcached_st *memc= memcached(server_string, strlen(server_string));
4232 test_true(memc);
4233
4234 // We will just use the error strings as our keys
4235 uint32_t counter= 100;
4236 while (--counter)
4237 {
4238 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
4239 {
4240 const char *msg= memcached_strerror(memc, memcached_return_t(x));
4241 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
4242 test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
4243
4244 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
4245 test_true(disconnected_server);
4246 test_strcmp("localhost", memcached_server_name(disconnected_server));
4247 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
4248
4249 if (random() % 2)
4250 {
4251 memcached_reset_last_disconnected_server(memc);
4252 }
4253 }
4254 }
4255
4256 memcached_free(memc);
4257
4258 return TEST_SUCCESS;
4259 }
4260
4261 test_return_t test_verbosity(memcached_st *memc)
4262 {
4263 memcached_verbosity(memc, 3);
4264
4265 return TEST_SUCCESS;
4266 }
4267
4268
4269 static memcached_return_t stat_printer(memcached_server_instance_st server,
4270 const char *key, size_t key_length,
4271 const char *value, size_t value_length,
4272 void *context)
4273 {
4274 (void)server;
4275 (void)context;
4276 (void)key;
4277 (void)key_length;
4278 (void)value;
4279 (void)value_length;
4280
4281 return MEMCACHED_SUCCESS;
4282 }
4283
4284 test_return_t memcached_stat_execute_test(memcached_st *memc)
4285 {
4286 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
4287 test_compare(MEMCACHED_SUCCESS, rc);
4288
4289 test_compare(MEMCACHED_SUCCESS,
4290 memcached_stat_execute(memc, "slabs", stat_printer, NULL));
4291
4292 test_compare(MEMCACHED_SUCCESS,
4293 memcached_stat_execute(memc, "items", stat_printer, NULL));
4294
4295 test_compare(MEMCACHED_SUCCESS,
4296 memcached_stat_execute(memc, "sizes", stat_printer, NULL));
4297
4298 return TEST_SUCCESS;
4299 }
4300
4301 /*
4302 * This test ensures that the failure counter isn't incremented during
4303 * normal termination of the memcached instance.
4304 */
4305 test_return_t wrong_failure_counter_test(memcached_st *original_memc)
4306 {
4307 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4308
4309 /* Ensure that we are connected to the server by setting a value */
4310 memcached_return_t rc= memcached_set(memc,
4311 test_literal_param(__func__), // Key
4312 test_literal_param(__func__), // Value
4313 time_t(0), uint32_t(0));
4314 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
4315
4316
4317 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4318
4319 /* The test is to see that the memcached_quit doesn't increase the
4320 * the server failure conter, so let's ensure that it is zero
4321 * before sending quit
4322 */
4323 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
4324
4325 memcached_quit(memc);
4326
4327 /* Verify that it memcached_quit didn't increment the failure counter
4328 * Please note that this isn't bullet proof, because an error could
4329 * occur...
4330 */
4331 test_zero(instance->server_failure_counter);
4332
4333 memcached_free(memc);
4334
4335 return TEST_SUCCESS;
4336 }
4337
4338 /*
4339 * This tests ensures expected disconnections (for some behavior changes
4340 * for instance) do not wrongly increase failure counter
4341 */
4342 test_return_t wrong_failure_counter_two_test(memcached_st *memc)
4343 {
4344 /* Set value to force connection to the server */
4345 const char *key= "marmotte";
4346 const char *value= "milka";
4347
4348 test_compare_hint(MEMCACHED_SUCCESS,
4349 memcached_set(memc, key, strlen(key),
4350 value, strlen(value),
4351 (time_t)0, (uint32_t)0),
4352 memcached_last_error_message(memc));
4353
4354
4355 /* put failure limit to 1 */
4356 test_compare(MEMCACHED_SUCCESS,
4357 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, true));
4358
4359 /* Put a retry timeout to effectively activate failure_limit effect */
4360 test_compare(MEMCACHED_SUCCESS,
4361 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, true));
4362
4363 /* change behavior that triggers memcached_quit()*/
4364 test_compare(MEMCACHED_SUCCESS,
4365 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true));
4366
4367
4368 /* Check if we still are connected */
4369 uint32_t flags;
4370 size_t string_length;
4371 memcached_return rc;
4372 char *string= memcached_get(memc, key, strlen(key),
4373 &string_length, &flags, &rc);
4374
4375 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
4376 test_true(string);
4377 free(string);
4378
4379 return TEST_SUCCESS;
4380 }
4381
4382 test_return_t regression_996813_TEST(memcached_st *)
4383 {
4384 memcached_st* memc= memcached_create(NULL);
4385
4386 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
4387 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1));
4388 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4389 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4390 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1));
4391 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 300));
4392 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
4393
4394 // We will never connect to these servers
4395 in_port_t base_port= 11211;
4396 for (size_t x= 0; x < 17; x++)
4397 {
4398 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", base_port +x));
4399 }
4400 test_compare(6U, memcached_generate_hash(memc, test_literal_param("SZ6hu0SHweFmpwpc0w2R")));
4401 test_compare(1U, memcached_generate_hash(memc, test_literal_param("SQCK9eiCf53YxHWnYA.o")));
4402 test_compare(9U, memcached_generate_hash(memc, test_literal_param("SUSDkGXuuZC9t9VhMwa.")));
4403 test_compare(0U, memcached_generate_hash(memc, test_literal_param("SnnqnJARfaCNT679iAF_")));
4404
4405 memcached_free(memc);
4406
4407 return TEST_SUCCESS;
4408 }
4409
4410
4411 /*
4412 * Test that ensures mget_execute does not end into recursive calls that finally fails
4413 */
4414 test_return_t regression_bug_490486(memcached_st *original_memc)
4415 {
4416
4417 #ifdef __APPLE__
4418 return TEST_SKIPPED; // My MAC can't handle this test
4419 #endif
4420
4421 test_skip(TEST_SUCCESS, pre_binary(original_memc));
4422
4423 /*
4424 * I only want to hit _one_ server so I know the number of requests I'm
4425 * sending in the pipeline.
4426 */
4427 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL --POLL-TIMEOUT=1000 --REMOVE-FAILED-SERVERS=1 --RETRY-TIMEOUT=3600");
4428 test_true(memc);
4429
4430 keys_st keys(20480);
4431
4432 /* First add all of the items.. */
4433 char blob[1024]= { 0 };
4434 for (size_t x= 0; x < keys.size(); ++x)
4435 {
4436 memcached_return rc= memcached_set(memc,
4437 keys.key_at(x), keys.length_at(x),
4438 blob, sizeof(blob), 0, 0);
4439 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
4440 }
4441
4442 {
4443
4444 /* Try to get all of them with a large multiget */
4445 size_t counter= 0;
4446 memcached_execute_function callbacks[]= { &callback_counter };
4447 memcached_return_t rc= memcached_mget_execute(memc,
4448 keys.keys_ptr(), keys.lengths_ptr(), keys.size(),
4449 callbacks, &counter, 1);
4450 test_compare(MEMCACHED_SUCCESS, rc);
4451
4452 char* the_value= NULL;
4453 char the_key[MEMCACHED_MAX_KEY];
4454 size_t the_key_length;
4455 size_t the_value_length;
4456 uint32_t the_flags;
4457
4458 do {
4459 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
4460
4461 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
4462 {
4463 ++counter;
4464 free(the_value);
4465 }
4466
4467 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
4468
4469
4470 test_compare(MEMCACHED_END, rc);
4471
4472 /* Verify that we got all of the items */
4473 test_compare(counter, keys.size());
4474 }
4475
4476 memcached_free(memc);
4477
4478 return TEST_SUCCESS;
4479 }
4480
4481 test_return_t regression_bug_583031(memcached_st *)
4482 {
4483 memcached_st *memc= memcached_create(NULL);
4484 test_true(memc);
4485 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
4486
4487 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
4488 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
4489 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4490 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4491 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4492 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
4493
4494 memcached_return_t rc;
4495 size_t length;
4496 uint32_t flags;
4497
4498 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
4499 test_false(value);
4500 test_zero(length);
4501
4502 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
4503
4504 memcached_free(memc);
4505
4506 return TEST_SUCCESS;
4507 }
4508
4509 test_return_t regression_bug_581030(memcached_st *)
4510 {
4511 #ifndef DEBUG
4512 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
4513 test_false(local_stat);
4514
4515 memcached_stat_free(NULL, NULL);
4516 #endif
4517
4518 return TEST_SUCCESS;
4519 }
4520
4521 #define regression_bug_655423_COUNT 6000
4522 test_return_t regression_bug_655423(memcached_st *memc)
4523 {
4524 memcached_st *clone= memcached_clone(NULL, memc);
4525 memc= NULL; // Just to make sure it is not used
4526 test_true(clone);
4527 char payload[100];
4528
4529 #ifdef __APPLE__
4530 return TEST_SKIPPED;
4531 #endif
4532
4533 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4534 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
4535 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4536 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
4537
4538 memset(payload, int('x'), sizeof(payload));
4539
4540 keys_st keys(regression_bug_655423_COUNT);
4541
4542 for (size_t x= 0; x < keys.size(); x++)
4543 {
4544 test_compare(MEMCACHED_SUCCESS, memcached_set(clone,
4545 keys.key_at(x),
4546 keys.length_at(x),
4547 payload, sizeof(payload), 0, 0));
4548 }
4549
4550 for (size_t x= 0; x < keys.size(); x++)
4551 {
4552 size_t value_length;
4553 memcached_return_t rc;
4554 char *value= memcached_get(clone,
4555 keys.key_at(x),
4556 keys.length_at(x),
4557 &value_length, NULL, &rc);
4558
4559 if (rc == MEMCACHED_NOTFOUND)
4560 {
4561 test_false(value);
4562 test_zero(value_length);
4563 continue;
4564 }
4565
4566 test_compare(MEMCACHED_SUCCESS, rc);
4567 test_true(value);
4568 test_compare(100LLU, value_length);
4569 free(value);
4570 }
4571
4572 test_compare(MEMCACHED_SUCCESS,
4573 memcached_mget(clone,
4574 keys.keys_ptr(), keys.lengths_ptr(),
4575 keys.size()));
4576
4577 uint32_t count= 0;
4578 memcached_result_st *result= NULL;
4579 while ((result= memcached_fetch_result(clone, result, NULL)))
4580 {
4581 test_compare(size_t(100), memcached_result_length(result));
4582 count++;
4583 }
4584
4585 test_true(count > 100); // If we don't get back atleast this, something is up
4586
4587 memcached_free(clone);
4588
4589 return TEST_SUCCESS;
4590 }
4591
4592 /*
4593 * Test that ensures that buffered set to not trigger problems during io_flush
4594 */
4595 #define regression_bug_490520_COUNT 200480
4596 test_return_t regression_bug_490520(memcached_st *original_memc)
4597 {
4598 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4599
4600 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
4601 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
4602 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4603 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
4604 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
4605
4606 /* First add all of the items.. */
4607 char blob[3333] = {0};
4608 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
4609 {
4610 char key[251];
4611 int key_length= snprintf(key, sizeof(key), "0200%u", x);
4612
4613 memcached_return rc= memcached_set(memc, key, key_length, blob, sizeof(blob), 0, 0);
4614 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
4615 }
4616
4617 memcached_free(memc);
4618
4619 return TEST_SUCCESS;
4620 }
4621
4622 test_return_t regression_1009493_TEST(memcached_st*)
4623 {
4624 memcached_st* memc= memcached_create(NULL);
4625 test_true(memc);
4626 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, true));
4627
4628 memcached_st* clone= memcached_clone(NULL, memc);
4629 test_true(clone);
4630
4631 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED),
4632 memcached_behavior_get(clone, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
4633
4634 memcached_free(memc);
4635 memcached_free(clone);
4636
4637 return TEST_SUCCESS;
4638 }
4639
4640 test_return_t regression_994772_TEST(memcached_st* memc)
4641 {
4642 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4643
4644 test_compare(MEMCACHED_SUCCESS,
4645 memcached_set(memc,
4646 test_literal_param(__func__), // Key
4647 test_literal_param(__func__), // Value
4648 time_t(0), uint32_t(0)));
4649
4650 const char *keys[] = { __func__ };
4651 size_t key_length[]= { strlen(__func__) };
4652 test_compare(MEMCACHED_SUCCESS,
4653 memcached_mget(memc, keys, key_length, 1));
4654
4655 memcached_return_t rc;
4656 memcached_result_st *results= memcached_fetch_result(memc, NULL, &rc);
4657 test_true(results);
4658 test_compare(MEMCACHED_SUCCESS, rc);
4659
4660 test_strcmp(__func__, memcached_result_value(results));
4661 uint64_t cas_value= memcached_result_cas(results);
4662 test_true(cas_value);
4663
4664 memcached_result_free(results);
4665
4666 // Bad cas value, sanity check
4667 test_true(cas_value != 9999);
4668 test_compare(MEMCACHED_END,
4669 memcached_cas(memc,
4670 test_literal_param(__func__), // Key
4671 test_literal_param(__FILE__), // Value
4672 time_t(0), uint32_t(0), 9999));
4673
4674 test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
4675 "different", strlen("different"), // Key
4676 test_literal_param(__FILE__), // Value
4677 time_t(0), uint32_t(0)));
4678
4679 return TEST_SUCCESS;
4680 }
4681
4682 test_return_t regression_bug_854604(memcached_st *)
4683 {
4684 char buffer[1024];
4685
4686 test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
4687
4688 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
4689
4690 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
4691 test_compare(buffer[0], 0);
4692
4693 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
4694 test_true(strlen(buffer));
4695
4696 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
4697 test_true(strlen(buffer));
4698
4699 return TEST_SUCCESS;
4700 }
4701
4702 static void die_message(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
4703 {
4704 fprintf(stderr, "Iteration #%u: ", it);
4705
4706 if (error == MEMCACHED_ERRNO)
4707 {
4708 fprintf(stderr, "system error %d from %s: %s\n",
4709 errno, what, strerror(errno));
4710 }
4711 else
4712 {
4713 fprintf(stderr, "error %d from %s: %s\n", error, what,
4714 memcached_strerror(mc, error));
4715 }
4716 }
4717
4718 #define TEST_CONSTANT_CREATION 200
4719
4720 test_return_t regression_bug_(memcached_st *memc)
4721 {
4722 const char *remote_server;
4723 (void)memc;
4724
4725 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
4726 {
4727 return TEST_SKIPPED;
4728 }
4729
4730 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
4731 {
4732 memcached_st* mc= memcached_create(NULL);
4733 memcached_return rc;
4734
4735 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
4736 if (rc != MEMCACHED_SUCCESS)
4737 {
4738 die_message(mc, rc, "memcached_behavior_set", x);
4739 }
4740
4741 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
4742 if (rc != MEMCACHED_SUCCESS)
4743 {
4744 die_message(mc, rc, "memcached_behavior_set", x);
4745 }
4746
4747 rc= memcached_server_add(mc, remote_server, 0);
4748 if (rc != MEMCACHED_SUCCESS)
4749 {
4750 die_message(mc, rc, "memcached_server_add", x);
4751 }
4752
4753 const char *set_key= "akey";
4754 const size_t set_key_len= strlen(set_key);
4755 const char *set_value= "a value";
4756 const size_t set_value_len= strlen(set_value);
4757
4758 if (rc == MEMCACHED_SUCCESS)
4759 {
4760 if (x > 0)
4761 {
4762 size_t get_value_len;
4763 char *get_value;
4764 uint32_t get_value_flags;
4765
4766 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
4767 &get_value_flags, &rc);
4768 if (rc != MEMCACHED_SUCCESS)
4769 {
4770 die_message(mc, rc, "memcached_get", x);
4771 }
4772 else
4773 {
4774
4775 if (x != 0 &&
4776 (get_value_len != set_value_len
4777 || 0!=strncmp(get_value, set_value, get_value_len)))
4778 {
4779 fprintf(stderr, "Values don't match?\n");
4780 rc= MEMCACHED_FAILURE;
4781 }
4782 free(get_value);
4783 }
4784 }
4785
4786 rc= memcached_set(mc,
4787 set_key, set_key_len,
4788 set_value, set_value_len,
4789 0, /* time */
4790 0 /* flags */
4791 );
4792 if (rc != MEMCACHED_SUCCESS)
4793 {
4794 die_message(mc, rc, "memcached_set", x);
4795 }
4796 }
4797
4798 memcached_quit(mc);
4799 memcached_free(mc);
4800
4801 if (rc != MEMCACHED_SUCCESS)
4802 {
4803 break;
4804 }
4805 }
4806
4807 return TEST_SUCCESS;
4808 }
4809
4810 test_return_t kill_HUP_TEST(memcached_st *original_memc)
4811 {
4812 memcached_st *memc= create_single_instance_memcached(original_memc, 0);
4813 test_true(memc);
4814
4815 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4816
4817 pid_t pid;
4818 test_true((pid= libmemcached_util_getpid(memcached_server_name(instance),
4819 memcached_server_port(instance), NULL)) > -1);
4820
4821
4822 test_compare(MEMCACHED_SUCCESS,
4823 memcached_set(memc,
4824 test_literal_param(__func__), // Keys
4825 test_literal_param(__func__), // Values
4826 0, 0));
4827 test_true_got(kill(pid, SIGHUP) == 0, strerror(errno));
4828
4829 test_compare(MEMCACHED_CONNECTION_FAILURE,
4830 memcached_set(memc,
4831 test_literal_param(__func__), // Keys
4832 test_literal_param(__func__), // Values
4833 0, 0));
4834
4835 memcached_free(memc);
4836
4837 return TEST_SUCCESS;
4838 }