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.
38
#include <libtest/test.hpp>
40
#include <libmemcached/memcached.h>
41
#include <libmemcached/server_instance.h>
42
#include <libmemcached/continuum.hpp>
44
#include <tests/ketama.h>
45
#include <tests/ketama_test_cases.h>
47
test_return_t ketama_compatibility_libmemcached(memcached_st *)
49
memcached_st *memc= memcached_create(NULL);
52
test_compare(MEMCACHED_SUCCESS,
53
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
55
test_compare(uint64_t(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
57
test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
58
test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA, memcached_behavior_get_distribution(memc));
60
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");
61
memcached_server_push(memc, server_pool);
63
/* verify that the server list was parsed okay. */
64
test_compare(8U, memcached_server_count(memc));
65
test_strcmp(server_pool[0].hostname, "10.0.1.1");
66
test_compare(in_port_t(11211), server_pool[0].port);
67
test_compare(600U, server_pool[0].weight);
68
test_strcmp(server_pool[2].hostname, "10.0.1.3");
69
test_compare(in_port_t(11211), server_pool[2].port);
70
test_compare(200U, server_pool[2].weight);
71
test_strcmp(server_pool[7].hostname, "10.0.1.8");
72
test_compare(in_port_t(11211), server_pool[7].port);
73
test_compare(100U, server_pool[7].weight);
75
/* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
76
* us test the boundary wraparound.
78
test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
80
/* verify the standard ketama set. */
81
for (uint32_t x= 0; x < 99; x++)
83
uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
84
memcached_server_instance_st instance=
85
memcached_server_instance_by_position(memc, server_idx);
86
const char *hostname = memcached_server_name(instance);
88
test_strcmp(hostname, ketama_test_cases[x].server);
91
memcached_server_list_free(server_pool);
97
test_return_t user_supplied_bug18(memcached_st *trash)
99
memcached_return_t rc;
106
memc= memcached_create(NULL);
109
rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
110
test_compare(MEMCACHED_SUCCESS, rc);
112
value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
113
test_true(value == 1);
115
rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
116
test_compare(MEMCACHED_SUCCESS, rc);
118
value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
119
test_true(value == MEMCACHED_HASH_MD5);
121
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");
122
memcached_server_push(memc, server_pool);
124
/* verify that the server list was parsed okay. */
125
test_true(memcached_server_count(memc) == 8);
126
test_strcmp(server_pool[0].hostname, "10.0.1.1");
127
test_true(server_pool[0].port == 11211);
128
test_true(server_pool[0].weight == 600);
129
test_strcmp(server_pool[2].hostname, "10.0.1.3");
130
test_true(server_pool[2].port == 11211);
131
test_true(server_pool[2].weight == 200);
132
test_strcmp(server_pool[7].hostname, "10.0.1.8");
133
test_true(server_pool[7].port == 11211);
134
test_true(server_pool[7].weight == 100);
136
/* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
137
* us test the boundary wraparound.
139
test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
141
/* verify the standard ketama set. */
142
for (x= 0; x < 99; x++)
144
uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
146
memcached_server_instance_st instance=
147
memcached_server_instance_by_position(memc, server_idx);
149
const char *hostname = memcached_server_name(instance);
150
test_strcmp(hostname, ketama_test_cases[x].server);
153
memcached_server_list_free(server_pool);
154
memcached_free(memc);
159
test_return_t auto_eject_hosts(memcached_st *trash)
162
memcached_server_instance_st instance;
164
memcached_return_t rc;
165
memcached_st *memc= memcached_create(NULL);
168
rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
169
test_compare(MEMCACHED_SUCCESS, rc);
171
uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
172
test_true(value == 1);
174
rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
175
test_compare(MEMCACHED_SUCCESS, rc);
177
value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
178
test_true(value == MEMCACHED_HASH_MD5);
180
/* server should be removed when in delay */
181
rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
182
test_compare(MEMCACHED_SUCCESS, rc);
184
value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
185
test_true(value == 1);
187
memcached_server_st *server_pool;
188
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");
189
memcached_server_push(memc, server_pool);
191
/* verify that the server list was parsed okay. */
192
test_true(memcached_server_count(memc) == 8);
193
test_strcmp(server_pool[0].hostname, "10.0.1.1");
194
test_true(server_pool[0].port == 11211);
195
test_true(server_pool[0].weight == 600);
196
test_strcmp(server_pool[2].hostname, "10.0.1.3");
197
test_true(server_pool[2].port == 11211);
198
test_true(server_pool[2].weight == 200);
199
test_strcmp(server_pool[7].hostname, "10.0.1.8");
200
test_true(server_pool[7].port == 11211);
201
test_true(server_pool[7].weight == 100);
203
instance= memcached_server_instance_by_position(memc, 2);
204
((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
205
memc->ketama.next_distribution_rebuild= time(NULL) - 1;
208
This would not work if there were only two hosts.
210
for (ptrdiff_t x= 0; x < 99; x++)
212
memcached_autoeject(memc);
213
uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
214
test_true(server_idx != 2);
217
/* and re-added when it's back. */
218
((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
219
memc->ketama.next_distribution_rebuild= time(NULL) - 1;
220
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
222
for (ptrdiff_t x= 0; x < 99; x++)
224
uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
225
// We re-use instance from above.
227
memcached_server_instance_by_position(memc, server_idx);
228
const char *hostname = memcached_server_name(instance);
229
test_strcmp(hostname, ketama_test_cases[x].server);
232
memcached_server_list_free(server_pool);
233
memcached_free(memc);
238
test_return_t ketama_compatibility_spymemcached(memcached_st *)
240
memcached_st *memc= memcached_create(NULL);
243
test_compare(MEMCACHED_SUCCESS,
244
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
246
test_compare(UINT64_C(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
248
test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY));
249
test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY, memcached_behavior_get_distribution(memc));
251
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");
252
test_true(server_pool);
253
memcached_server_push(memc, server_pool);
255
/* verify that the server list was parsed okay. */
256
test_compare(8U, memcached_server_count(memc));
257
test_strcmp(server_pool[0].hostname, "10.0.1.1");
258
test_compare(in_port_t(11211), server_pool[0].port);
259
test_compare(600U, server_pool[0].weight);
260
test_strcmp(server_pool[2].hostname, "10.0.1.3");
261
test_compare(in_port_t(11211), server_pool[2].port);
262
test_compare(200U, server_pool[2].weight);
263
test_strcmp(server_pool[7].hostname, "10.0.1.8");
264
test_compare(in_port_t(11211), server_pool[7].port);
265
test_compare(100U, server_pool[7].weight);
267
/* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
268
* us test the boundary wraparound.
270
test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
272
/* verify the standard ketama set. */
273
for (uint32_t x= 0; x < 99; x++)
275
uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
277
memcached_server_instance_st instance=
278
memcached_server_instance_by_position(memc, server_idx);
280
const char *hostname= memcached_server_name(instance);
282
test_strcmp(hostname, ketama_test_cases_spy[x].server);
285
memcached_server_list_free(server_pool);
286
memcached_free(memc);