Software /
code /
prosody
Annotate
spec/util_hashring_spec.lua @ 13143:3ec48555b773
mod_storage_sql: Add UPSERT support
Currently limited to SQLite3 for lack of testing on other databases.
Adds a migration to replace the non-UNIQUE prosody_index, renaming it
prosody_unique_index since ALTER INDEX does not seem to be portable.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 10 Jun 2023 15:44:09 +0200 |
parent | 12795:87424cbedc55 |
rev | line source |
---|---|
10007 | 1 local hashring = require "util.hashring"; |
2 | |
3 describe("util.hashring", function () | |
12794
249b01adc54a
util.hashring: tests: don't randomize order - they are written in a sequential style
Matthew Wild <mwild1@gmail.com>
parents:
10007
diff
changeset
|
4 randomize(false); |
10007 | 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 | |
12795
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12794
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:
12794
diff
changeset
|
87 local r = hashring.new(128, sha256); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12794
diff
changeset
|
88 r:add_node("node1", { a = 1 }); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12794
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:
12794
diff
changeset
|
90 assert.is_equal("node1", node); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12794
diff
changeset
|
91 assert.same({ a = 1 }, value); |
87424cbedc55
util.hashring: Support associating arbitrary data with nodes
Matthew Wild <mwild1@gmail.com>
parents:
12794
diff
changeset
|
92 end); |
10007 | 93 end); |