Comparison

spec/util_hashring_spec.lua @ 10007:de43ca319184

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