annotate spec/util_hashring_spec.lua @ 12659:c0eea4f6c739

usermanager: Add back temporary is_admin to warn about deprecated API usage Goal: Introduce role-auth with minimal disruption is_admin() is unsafe in a system with per-session permissions, so it has been deprecated. Roll-out approach: 1) First, log a warning when is_admin() is used. It should continue to function normally, backed by the new role API. Nothing is really using per-session authz yet, so there is minimal security concern. The 'strict_deprecate_is_admin' global setting can be set to 'true' to force a hard failure of is_admin() attempts (it will log an error and always return false). 2) In some time (at least 1 week), but possibly longer depending on the number of affected deployments: switch 'strict_deprecate_is_admin' to 'true' by default. It can still be disabled for systems that need it. 3) Further in the future, before the next release, the option will be removed and is_admin() will be permanently disabled.
author Matthew Wild <mwild1@gmail.com>
date Mon, 15 Aug 2022 15:25:07 +0100
parents de43ca319184
children 249b01adc54a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10007
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local hashring = require "util.hashring";
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 describe("util.hashring", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local sha256 = require "util.hashes".sha256;
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local ring = hashring.new(128, sha256);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 it("should fail to get a node that does not exist", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 assert.is_nil(ring:get_node("foo"))
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 it("should support adding nodes", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 ring:add_node("node1");
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 it("should return a single node for all keys if only one node exists", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 for i = 1, 100 do
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 assert.is_equal("node1", ring:get_node(tostring(i)))
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 end
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 it("should support adding a second node", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 ring:add_node("node2");
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 it("should fail to remove a non-existent node", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 assert.is_falsy(ring:remove_node("node3"));
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 it("should succeed to remove a node", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 assert.is_truthy(ring:remove_node("node1"));
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 it("should return the only node for all keys", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 for i = 1, 100 do
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 assert.is_equal("node2", ring:get_node(tostring(i)))
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 end
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 it("should support adding multiple nodes", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 ring:add_nodes({ "node1", "node3", "node4", "node5" });
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 it("should disrupt a minimal number of keys on node removal", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 local orig_ring = ring:clone();
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 local node_tallies = {};
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 local n = 1000;
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 for i = 1, n do
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 local key = tostring(i);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 local node = ring:get_node(key);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 node_tallies[node] = (node_tallies[node] or 0) + 1;
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 end
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 --[[
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 for node, key_count in pairs(node_tallies) do
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 print(node, key_count, ("%.2f%%"):format((key_count/n)*100));
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 end
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 ]]
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 ring:remove_node("node5");
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 local disrupted_keys = 0;
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 for i = 1, n do
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 local key = tostring(i);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 if orig_ring:get_node(key) ~= ring:get_node(key) then
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 disrupted_keys = disrupted_keys + 1;
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 end
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 end
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 assert.is_equal(node_tallies["node5"], disrupted_keys);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 it("should support removing multiple nodes", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 ring:remove_nodes({"node2", "node3", "node4", "node5"});
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 it("should return a single node for all keys if only one node remains", function ()
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 for i = 1, 100 do
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 assert.is_equal("node1", ring:get_node(tostring(i)))
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 end
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 end);
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84
de43ca319184 util.hashring: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 end);