1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
19 * * The names of its contributors may not be used to endorse or
20 * promote products derived from this software without specific prior
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include "mem_config.h"
38 #include "libtest/test.hpp"
40 #include "libmemcached-1.0/memcached.h"
42 #include "libmemcached/server_instance.h"
43 #include "libmemcached/continuum.hpp"
44 #include "libmemcached/instance.hpp"
46 #include "tests/ketama.h"
47 #include "tests/ketama_test_cases.h"
49 test_return_t
ketama_compatibility_libmemcached(memcached_st
*)
51 memcached_st
*memc
= memcached_create(NULL
);
54 test_compare(MEMCACHED_SUCCESS
,
55 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
, 1));
57 test_compare(uint64_t(1), memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
));
59 test_compare(MEMCACHED_SUCCESS
, memcached_behavior_set_distribution(memc
, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA
));
60 test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA
, memcached_behavior_get_distribution(memc
));
62 memcached_server_st
*server_pool
= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
63 memcached_server_push(memc
, server_pool
);
65 /* verify that the server list was parsed okay. */
66 test_compare(8U, memcached_server_count(memc
));
67 test_strcmp(server_pool
[0].hostname
, "10.0.1.1");
68 test_compare(in_port_t(11211), server_pool
[0].port
);
69 test_compare(600U, server_pool
[0].weight
);
70 test_strcmp(server_pool
[2].hostname
, "10.0.1.3");
71 test_compare(in_port_t(11211), server_pool
[2].port
);
72 test_compare(200U, server_pool
[2].weight
);
73 test_strcmp(server_pool
[7].hostname
, "10.0.1.8");
74 test_compare(in_port_t(11211), server_pool
[7].port
);
75 test_compare(100U, server_pool
[7].weight
);
77 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
78 * us test the boundary wraparound.
80 test_true(memcached_generate_hash(memc
, (char *)"VDEAAAAA", 8) == memc
->ketama
.continuum
[0].index
);
82 /* verify the standard ketama set. */
83 for (uint32_t x
= 0; x
< 99; x
++)
85 uint32_t server_idx
= memcached_generate_hash(memc
, ketama_test_cases
[x
].key
, strlen(ketama_test_cases
[x
].key
));
86 const memcached_instance_st
* instance
=
87 memcached_server_instance_by_position(memc
, server_idx
);
88 const char *hostname
= memcached_server_name(instance
);
90 test_strcmp(hostname
, ketama_test_cases
[x
].server
);
93 memcached_server_list_free(server_pool
);
99 test_return_t
user_supplied_bug18(memcached_st
*trash
)
101 memcached_return_t rc
;
108 memc
= memcached_create(NULL
);
111 rc
= memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
, 1);
112 test_compare(MEMCACHED_SUCCESS
, rc
);
114 value
= memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
);
115 test_true(value
== 1);
117 rc
= memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_KETAMA_HASH
, MEMCACHED_HASH_MD5
);
118 test_compare(MEMCACHED_SUCCESS
, rc
);
120 value
= memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_KETAMA_HASH
);
121 test_true(value
== MEMCACHED_HASH_MD5
);
123 memcached_server_st
*server_pool
= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
124 memcached_server_push(memc
, server_pool
);
126 /* verify that the server list was parsed okay. */
127 test_true(memcached_server_count(memc
) == 8);
128 test_strcmp(server_pool
[0].hostname
, "10.0.1.1");
129 test_true(server_pool
[0].port
== 11211);
130 test_true(server_pool
[0].weight
== 600);
131 test_strcmp(server_pool
[2].hostname
, "10.0.1.3");
132 test_true(server_pool
[2].port
== 11211);
133 test_true(server_pool
[2].weight
== 200);
134 test_strcmp(server_pool
[7].hostname
, "10.0.1.8");
135 test_true(server_pool
[7].port
== 11211);
136 test_true(server_pool
[7].weight
== 100);
138 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
139 * us test the boundary wraparound.
141 test_true(memcached_generate_hash(memc
, (char *)"VDEAAAAA", 8) == memc
->ketama
.continuum
[0].index
);
143 /* verify the standard ketama set. */
144 for (x
= 0; x
< 99; x
++)
146 uint32_t server_idx
= memcached_generate_hash(memc
, ketama_test_cases
[x
].key
, strlen(ketama_test_cases
[x
].key
));
148 const memcached_instance_st
* instance
=
149 memcached_server_instance_by_position(memc
, server_idx
);
151 const char *hostname
= memcached_server_name(instance
);
152 test_strcmp(hostname
, ketama_test_cases
[x
].server
);
155 memcached_server_list_free(server_pool
);
156 memcached_free(memc
);
161 test_return_t
auto_eject_hosts(memcached_st
*trash
)
165 memcached_return_t rc
;
166 memcached_st
*memc
= memcached_create(NULL
);
169 rc
= memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
, 1);
170 test_compare(MEMCACHED_SUCCESS
, rc
);
172 uint64_t value
= memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
);
173 test_true(value
== 1);
175 rc
= memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_KETAMA_HASH
, MEMCACHED_HASH_MD5
);
176 test_compare(MEMCACHED_SUCCESS
, rc
);
178 value
= memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_KETAMA_HASH
);
179 test_true(value
== MEMCACHED_HASH_MD5
);
181 /* server should be removed when in delay */
182 rc
= memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS
, 1);
183 test_compare(MEMCACHED_SUCCESS
, rc
);
185 value
= memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS
);
186 test_true(value
== 1);
188 memcached_server_st
*server_pool
;
189 server_pool
= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
190 memcached_server_push(memc
, server_pool
);
192 /* verify that the server list was parsed okay. */
193 test_true(memcached_server_count(memc
) == 8);
194 test_strcmp(server_pool
[0].hostname
, "10.0.1.1");
195 test_true(server_pool
[0].port
== 11211);
196 test_true(server_pool
[0].weight
== 600);
197 test_strcmp(server_pool
[2].hostname
, "10.0.1.3");
198 test_true(server_pool
[2].port
== 11211);
199 test_true(server_pool
[2].weight
== 200);
200 test_strcmp(server_pool
[7].hostname
, "10.0.1.8");
201 test_true(server_pool
[7].port
== 11211);
202 test_true(server_pool
[7].weight
== 100);
204 const memcached_instance_st
* instance
= memcached_server_instance_by_position(memc
, 2);
205 memcached_instance_next_retry(instance
, time(NULL
) +15);
206 memc
->ketama
.next_distribution_rebuild
= time(NULL
) - 1;
209 This would not work if there were only two hosts.
211 for (ptrdiff_t x
= 0; x
< 99; x
++)
213 memcached_autoeject(memc
);
214 uint32_t server_idx
= memcached_generate_hash(memc
, ketama_test_cases
[x
].key
, strlen(ketama_test_cases
[x
].key
));
215 test_true(server_idx
!= 2);
218 /* and re-added when it's back. */
219 time_t absolute_time
= time(NULL
) -1;
220 memcached_instance_next_retry(instance
, absolute_time
);
221 memc
->ketama
.next_distribution_rebuild
= absolute_time
;
222 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_DISTRIBUTION
,
224 for (ptrdiff_t x
= 0; x
< 99; x
++)
226 uint32_t server_idx
= memcached_generate_hash(memc
, ketama_test_cases
[x
].key
, strlen(ketama_test_cases
[x
].key
));
227 // We re-use instance from above.
229 memcached_server_instance_by_position(memc
, server_idx
);
230 const char *hostname
= memcached_server_name(instance
);
231 test_strcmp(hostname
, ketama_test_cases
[x
].server
);
234 memcached_server_list_free(server_pool
);
235 memcached_free(memc
);
240 test_return_t
ketama_compatibility_spymemcached(memcached_st
*)
242 memcached_st
*memc
= memcached_create(NULL
);
245 test_compare(MEMCACHED_SUCCESS
,
246 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
, 1));
248 test_compare(uint64_t(1), memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
));
250 test_compare(MEMCACHED_SUCCESS
, memcached_behavior_set_distribution(memc
, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY
));
251 test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY
, memcached_behavior_get_distribution(memc
));
253 memcached_server_st
*server_pool
= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
254 test_true(server_pool
);
255 memcached_server_push(memc
, server_pool
);
257 /* verify that the server list was parsed okay. */
258 test_compare(8U, memcached_server_count(memc
));
259 test_strcmp(server_pool
[0].hostname
, "10.0.1.1");
260 test_compare(in_port_t(11211), server_pool
[0].port
);
261 test_compare(600U, server_pool
[0].weight
);
262 test_strcmp(server_pool
[2].hostname
, "10.0.1.3");
263 test_compare(in_port_t(11211), server_pool
[2].port
);
264 test_compare(200U, server_pool
[2].weight
);
265 test_strcmp(server_pool
[7].hostname
, "10.0.1.8");
266 test_compare(in_port_t(11211), server_pool
[7].port
);
267 test_compare(100U, server_pool
[7].weight
);
269 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
270 * us test the boundary wraparound.
272 test_true(memcached_generate_hash(memc
, (char *)"VDEAAAAA", 8) == memc
->ketama
.continuum
[0].index
);
274 /* verify the standard ketama set. */
275 for (uint32_t x
= 0; x
< 99; x
++)
277 uint32_t server_idx
= memcached_generate_hash(memc
, ketama_test_cases_spy
[x
].key
, strlen(ketama_test_cases_spy
[x
].key
));
279 const memcached_instance_st
* instance
=
280 memcached_server_instance_by_position(memc
, server_idx
);
282 const char *hostname
= memcached_server_name(instance
);
284 test_strcmp(hostname
, ketama_test_cases_spy
[x
].server
);
287 memcached_server_list_free(server_pool
);
288 memcached_free(memc
);