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