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