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