author | Kim Alvefur <zash@zash.se> |
Sun, 24 Mar 2024 20:39:42 +0100 | |
changeset 13466 | 720aed1f5cf2 |
parent 12799 | 87424cbedc55 |
permissions | -rw-r--r-- |
10011 | 1 |
local hashring = require "util.hashring"; |
2 |
||
3 |
describe("util.hashring", function () |
|
12798
249b01adc54a
util.hashring: tests: don't randomize order - they are written in a sequential style
Matthew Wild <mwild1@gmail.com>
parents:
10011
diff
changeset
|
4 |
randomize(false); |
10011 | 5 |
|
6 |
local sha256 = require "util.hashes".sha256; |
|
7 |
||
8 |
local ring = hashring.new(128, sha256); |
|
9 |
||
10 |
it("should fail to get a node that does not exist", function () |
|
11 |
assert.is_nil(ring:get_node("foo")) |
|
12 |
end); |
|
13 |
||
14 |
it("should support adding nodes", function () |
|
15 |
ring:add_node("node1"); |
|
16 |
end); |
|
17 |
||
18 |
it("should return a single node for all keys if only one node exists", function () |
|
19 |
for i = 1, 100 do |
|
20 |
assert.is_equal("node1", ring:get_node(tostring(i))) |
|
21 |
end |
|
22 |
end); |
|
23 |
||
24 |
it("should support adding a second node", function () |
|
25 |
ring:add_node("node2"); |
|
26 |
end); |
|
27 |
||
28 |
it("should fail to remove a non-existent node", function () |
|
29 |
assert.is_falsy(ring:remove_node("node3")); |
|
30 |
end); |
|
31 |
||
32 |
it("should succeed to remove a node", function () |
|
33 |
assert.is_truthy(ring:remove_node("node1")); |
|
34 |
end); |
|
35 |
||
36 |
it("should return the only node for all keys", function () |
|
37 |
for i = 1, 100 do |
|
38 |
assert.is_equal("node2", ring:get_node(tostring(i))) |
|
39 |
end |
|
40 |
end); |
|
41 |
||
42 |
it("should support adding multiple nodes", function () |
|
43 |
ring:add_nodes({ "node1", "node3", "node4", "node5" }); |
|
44 |
end); |
|
45 |
||
46 |
it("should disrupt a minimal number of keys on node removal", function () |
|
47 |
local orig_ring = ring:clone(); |
|
48 |
local node_tallies = {}; |
|
49 |
||
50 |
local n = 1000; |
|
51 |
||
52 |
for i = 1, n do |
|
53 |
local key = tostring(i); |
|
54 |
local node = ring:get_node(key); |
|
55 |
node_tallies[node] = (node_tallies[node] or 0) + 1; |
|
56 |
end |
|
57 |
||
58 |
--[[ |
|
59 |
for node, key_count in pairs(node_tallies) do |
|
60 |
print(node, key_count, ("%.2f%%"):format((key_count/n)*100)); |
|
61 |
end |
|
62 |
]] |
|
63 |
||
64 |
ring:remove_node("node5"); |
|
65 |
||
66 |
local disrupted_keys = 0; |
|
67 |
for i = 1, n do |
|
68 |
local key = tostring(i); |
|
69 |
if orig_ring:get_node(key) ~= ring:get_node(key) then |
|
70 |
disrupted_keys = disrupted_keys + 1; |
|
71 |
end |
|
72 |
end |
|
73 |
assert.is_equal(node_tallies["node5"], disrupted_keys); |
|
74 |
end); |
|
75 |
||
76 |
it("should support removing multiple nodes", function () |
|
77 |
ring:remove_nodes({"node2", "node3", "node4", "node5"}); |
|
78 |
end); |
|
79 |
||
80 |
it("should return a single node for all keys if only one node remains", function () |
|
81 |
for i = 1, 100 do |
|
82 |
assert.is_equal("node1", ring:get_node(tostring(i))) |
|
83 |
end |
|
84 |
end); |
|
85 |
||
12799
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12798
diff
changeset
|
86 |
it("should support values associated with nodes", function () |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12798
diff
changeset
|
87 |
local r = hashring.new(128, sha256); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12798
diff
changeset
|
88 |
r:add_node("node1", { a = 1 }); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12798
diff
changeset
|
89 |
local node, value = r:get_node("foo"); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12798
diff
changeset
|
90 |
assert.is_equal("node1", node); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12798
diff
changeset
|
91 |
assert.same({ a = 1 }, value); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12798
diff
changeset
|
92 |
end); |
10011 | 93 |
end); |