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