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