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