1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
local hashring = require "util.hashring";
describe("util.hashring", function ()
local sha256 = require "util.hashes".sha256;
local ring = hashring.new(128, sha256);
it("should fail to get a node that does not exist", function ()
assert.is_nil(ring:get_node("foo"))
end);
it("should support adding nodes", function ()
ring:add_node("node1");
end);
it("should return a single node for all keys if only one node exists", function ()
for i = 1, 100 do
assert.is_equal("node1", ring:get_node(tostring(i)))
end
end);
it("should support adding a second node", function ()
ring:add_node("node2");
end);
it("should fail to remove a non-existent node", function ()
assert.is_falsy(ring:remove_node("node3"));
end);
it("should succeed to remove a node", function ()
assert.is_truthy(ring:remove_node("node1"));
end);
it("should return the only node for all keys", function ()
for i = 1, 100 do
assert.is_equal("node2", ring:get_node(tostring(i)))
end
end);
it("should support adding multiple nodes", function ()
ring:add_nodes({ "node1", "node3", "node4", "node5" });
end);
it("should disrupt a minimal number of keys on node removal", function ()
local orig_ring = ring:clone();
local node_tallies = {};
local n = 1000;
for i = 1, n do
local key = tostring(i);
local node = ring:get_node(key);
node_tallies[node] = (node_tallies[node] or 0) + 1;
end
--[[
for node, key_count in pairs(node_tallies) do
print(node, key_count, ("%.2f%%"):format((key_count/n)*100));
end
]]
ring:remove_node("node5");
local disrupted_keys = 0;
for i = 1, n do
local key = tostring(i);
if orig_ring:get_node(key) ~= ring:get_node(key) then
disrupted_keys = disrupted_keys + 1;
end
end
assert.is_equal(node_tallies["node5"], disrupted_keys);
end);
it("should support removing multiple nodes", function ()
ring:remove_nodes({"node2", "node3", "node4", "node5"});
end);
it("should return a single node for all keys if only one node remains", function ()
for i = 1, 100 do
assert.is_equal("node1", ring:get_node(tostring(i)))
end
end);
end);
|