From 7b94717a3f43b5710baf968b47e3fcd0d161f1e0 Mon Sep 17 00:00:00 2001 From: Yaroslav Dynnikov <yaroslav.dynnikov@gmail.com> Date: Thu, 12 May 2022 10:35:30 +0300 Subject: [PATCH] fix: pytest wait_ready implementation Waiting for a valid `leader_id` on a node isn't enough. It may already have one, but still be a Learner. Instead, the fixture should wait until the node is promoted to voter. --- src/main.rs | 2 ++ src/traft/node.rs | 7 +++++++ test/int/conftest.py | 6 ++---- test/int/test_basics.py | 12 +++++------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7e1acbb0fd..614d22b8f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -589,6 +589,8 @@ fn postjoin(args: &args::Run) { } }; } + + node.mark_as_ready(); } fn main_tarantool(args: args::Tarantool) -> ! { diff --git a/src/traft/node.rs b/src/traft/node.rs index fa1d4efecb..548c77208f 100644 --- a/src/traft/node.rs +++ b/src/traft/node.rs @@ -53,6 +53,7 @@ pub struct Status { pub id: u64, pub leader_id: u64, pub raft_state: String, + pub is_ready: bool, } /// The heart of `traft` module - the Node. @@ -103,6 +104,7 @@ impl Node { id: cfg.id, leader_id: 0, raft_state: "Follower".into(), + is_ready: false, })); let main_loop_fn = { @@ -136,6 +138,11 @@ impl Node { self.status.borrow().clone() } + pub fn mark_as_ready(&self) { + self.status.borrow_mut().is_ready = true; + self.status_cond.broadcast(); + } + pub fn wait_status(&self) { self.status_cond.wait(); } diff --git a/test/int/conftest.py b/test/int/conftest.py index b2fa826ba8..236fddcd99 100644 --- a/test/int/conftest.py +++ b/test/int/conftest.py @@ -118,6 +118,7 @@ class RaftStatus: id: int raft_state: str leader_id: int + is_ready: bool def __eq__(self, other): match other: @@ -139,9 +140,6 @@ class RaftStatus: return False - def is_ready(self): - return self.leader_id > INVALID_ID - @dataclass class Instance: @@ -280,7 +278,7 @@ class Instance: @funcy.retry(tries=20, timeout=0.1) def wait_ready(self): status = self.__raft_status() - assert status.is_ready() + assert status.is_ready self.raft_id = status.id @funcy.retry(tries=4, timeout=0.1, errors=AssertionError) diff --git a/test/int/test_basics.py b/test/int/test_basics.py index 045501f364..3fdc16984f 100644 --- a/test/int/test_basics.py +++ b/test/int/test_basics.py @@ -36,6 +36,7 @@ def test_raft_status(): id=1, raft_state="SomeState", leader_id=1, + is_ready=False, ) assert (s == "SomeState") is True @@ -48,13 +49,10 @@ def test_raft_status(): assert (s == ("OtherState", 1)) is False assert (s == s) is True - assert (s == RaftStatus(s.id, s.raft_state, s.leader_id)) is True - assert (s == RaftStatus(-1, s.raft_state, s.leader_id)) is False - assert (s == RaftStatus(s.id, "OtherState", s.leader_id)) is False - assert (s == RaftStatus(s.id, s.raft_state, -1)) is False - - assert RaftStatus(1, "Follower", 0).is_ready() is False - assert RaftStatus(1, "Follower", 1).is_ready() is True + assert (s == RaftStatus(s.id, s.raft_state, s.leader_id, True)) is True + assert (s == RaftStatus(-1, s.raft_state, s.leader_id, True)) is False + assert (s == RaftStatus(s.id, "OtherState", s.leader_id, True)) is False + assert (s == RaftStatus(s.id, s.raft_state, -1, True)) is False def test_call_normalization(instance: Instance): -- GitLab