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