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