IMPORTANT: due to a drive failure, as of 13-Mar-2021, the Mercurial repository had to be re-mirrored, which changed every commit SHA. The old SHAs and trees are backed up in the vault branches. Please migrate to the new branches as soon as you can.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
prosody/spec/util_hashring_spec.lua

85 lines
2.1 KiB

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);