From 5f245144740322201fd0185ef9b6eb83299555d3 Mon Sep 17 00:00:00 2001 From: Georgy Moshkin <gmoshkin@picodata.io> Date: Wed, 4 Sep 2024 15:48:10 +0300 Subject: [PATCH] fix: fail to start with an explanation when current instance is expelled --- src/lib.rs | 5 +++++ test/conftest.py | 5 +++-- test/int/test_expelling.py | 10 +++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1fac71cb85..214e1aec21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1007,6 +1007,11 @@ fn postjoin( fiber::sleep(timeout); continue; }; + + if has_states!(instance, Expelled -> *) { + return Err(Error::Expelled); + } + let cluster_id = raft_storage .cluster_id() .expect("storage should never fail"); diff --git a/test/conftest.py b/test/conftest.py index c87dea6944..0b68a6b879 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -941,7 +941,7 @@ class Instance: ).start() def fail_to_start(self, timeout: int = 10): - assert self.process is None + assert self.process is None, "process is already running" self.start() assert self.process try: @@ -1237,7 +1237,8 @@ class Instance: self.check_process_alive() assert False except ProcessDead: - pass + # Make it so we can call Instance.start later + self.process = None def wait_online( self, timeout: int | float = 30, rps: int | float = 5, expected_incarnation=None diff --git a/test/int/test_expelling.py b/test/int/test_expelling.py index 7f02364c25..ab99b006c2 100644 --- a/test/int/test_expelling.py +++ b/test/int/test_expelling.py @@ -1,5 +1,5 @@ import pytest -from conftest import Cluster, Instance, Retriable +from conftest import Cluster, Instance, Retriable, log_crawler @pytest.fixture @@ -40,6 +40,10 @@ def test_expel_follower(cluster3: Cluster): # assert i3.process Retriable(timeout=10).call(i3.assert_process_dead) + lc = log_crawler(i3, "current instance is expelled from the cluster") + i3.fail_to_start() + assert lc.matched + def test_expel_leader(cluster3: Cluster): # Scenario: expel a Leader instance by command to itself @@ -61,6 +65,10 @@ def test_expel_leader(cluster3: Cluster): # assert i1.process Retriable(timeout=10).call(i1.assert_process_dead) + lc = log_crawler(i1, "current instance is expelled from the cluster") + i1.fail_to_start() + assert lc.matched + def test_expel_by_follower(cluster3: Cluster): # Scenario: expel an instance by command to a Follower -- GitLab