From 67e479a4e2ddf4ce6a5fe4a46d01863279ef2727 Mon Sep 17 00:00:00 2001 From: Yaroslav Dynnikov <yaroslav.dynnikov@gmail.com> Date: Tue, 22 Feb 2022 12:02:24 +0300 Subject: [PATCH] test: make luatest more concise --- test/couple_test.lua | 22 ++-------------- test/helper/picodata.lua | 55 ++++++++++++++++++++++++++++++++++++++++ test/single_test.lua | 37 +++++---------------------- 3 files changed, 63 insertions(+), 51 deletions(-) diff --git a/test/couple_test.lua b/test/couple_test.lua index d65b282110..5ac01d63a9 100644 --- a/test/couple_test.lua +++ b/test/couple_test.lua @@ -39,28 +39,10 @@ end) g.test = function() -- Speed up node election - g.cluster.i1:interact({ - msg_type = "MsgTimeoutNow", - to = 1, - from = 0, - }) - - h.retrying({}, function() - t.assert_equals( - g.cluster.i2:connect():call('picolib.raft_status'), - { - id = 2, - leader_id = 1, - raft_state = "Follower", - } - ) - end) + g.cluster.i1:try_promote() t.assert_equals( - g.cluster.i2:connect():call( - 'picolib.raft_propose_eval', - {1, '_G.check = box.info.listen'} - ), + g.cluster.i2:raft_propose_eval(1, '_G.check = box.info.listen'), true ) t.assert_equals( diff --git a/test/helper/picodata.lua b/test/helper/picodata.lua index 90eabb1502..275c8605fa 100644 --- a/test/helper/picodata.lua +++ b/test/helper/picodata.lua @@ -18,6 +18,7 @@ local Picodata = { command = 'target/debug/picodata', process = nil, __type = 'Picodata', + id = -1, } function Picodata:inherit(object) @@ -82,6 +83,7 @@ function Picodata:start() luatest.helpers.retrying({}, function() self:connect() + self.id = self:raft_status().id end) end @@ -124,6 +126,42 @@ function Picodata:stop() self.process = nil end +--- Get the status of raft node. +-- @function +-- @return {id = number, leader_id = number, state = string} +-- State can be one of "Follower", "Candidate", "Leader", "PreCandidate". +function Picodata:raft_status() + checks('Picodata') + return self:connect():call('picolib.raft_status') +end + +--- Assert raft status matches expectations. +-- @function +-- @tparam string raft_state +-- @tparam[opt] number leader_id +function Picodata:assert_raft_status(raft_state, leader_id) + checks('Picodata', 'string', '?number') + return luatest.assert_covers( + self:raft_status(), + { + leader_id = leader_id, + raft_state = raft_state, + } + ) +end + +--- Propose Lua code evaluation on every node in cluster. +-- @tparam number timeout +-- @tparam string code +-- @treturn boolean whether proposal was committed on the current node. +function Picodata:raft_propose_eval(timeout, code) + checks('Picodata', 'number', 'string') + return self:connect():call( + 'picolib.raft_propose_eval', + {timeout, code} + ) +end + function Picodata:interact(opts) checks('Picodata', { -- See picolib/traft/row/message.rs @@ -156,4 +194,21 @@ function Picodata:interact(opts) }) end +--- Try forcing leader election when previous leader is dead. +-- Wait for the node becoming a leader. +-- Raise an exception if promotion fails. +function Picodata:try_promote() + checks('Picodata') + + self:interact({ + msg_type = "MsgTimeoutNow", + to = self.id, + from = 0, + }) + + return luatest.helpers.retrying({}, function() + self:assert_raft_status("Leader", self.id) + end) +end + return Picodata diff --git a/test/single_test.lua b/test/single_test.lua index 470372faf8..47be6a3c7e 100644 --- a/test/single_test.lua +++ b/test/single_test.lua @@ -22,51 +22,26 @@ g.after_all(function() end) g.test = function() - local conn = g.node:connect() + g.node:assert_raft_status("Follower") t.assert_equals( - conn:call('picolib.raft_status'), - { - id = 1, - leader_id = 0, - raft_state = "Follower", - } - ) - - t.assert_equals( - conn:call('picolib.raft_propose_eval', {1, 'return'}), + g.node:raft_propose_eval(1, 'return'), false -- No leader is elected yet ) - -- Speed up node election - g.node:interact({ - msg_type = "MsgTimeoutNow", - to = 1, - from = 0, - }) - - h.retrying({}, function() - t.assert_equals( - conn:call('picolib.raft_status'), - { - id = 1, - leader_id = 1, - raft_state = "Leader", - } - ) - end) + g.node:try_promote() t.assert_equals( - conn:call('picolib.raft_propose_eval', {0, 'return'}), + g.node:raft_propose_eval(0, 'return'), false -- Timeout ) t.assert_equals( - conn:call('picolib.raft_propose_eval', {1, '_G.success = true'}), + g.node:raft_propose_eval(1, '_G.success = true'), true ) t.assert_equals( - conn:eval('return success'), + g.node:connect():eval('return success'), true ) end -- GitLab