diff --git a/test/int/conftest.py b/test/int/conftest.py index f4bea8e70950a9b367a5a2157487eab4b293f5f0..b2fa826ba8d9313745286853252a36058ec50f38 100644 --- a/test/int/conftest.py +++ b/test/int/conftest.py @@ -283,11 +283,20 @@ class Instance: assert status.is_ready() self.raft_id = status.id - @funcy.retry(tries=20, timeout=0.1) + @funcy.retry(tries=4, timeout=0.1, errors=AssertionError) def promote_or_fail(self): - self.assert_raft_status("Leader") + eprint(f"{self} is trying to become a leader") + + # 1. Force the node to campaign. self.call("picolib.raft_timeout_now") + # 2. Wait until the miracle occurs. + @funcy.retry(tries=4, timeout=0.1, errors=AssertionError) + def wait_promoted(): + assert self.__raft_status() == "Leader" + + wait_promoted() + @dataclass class Cluster: diff --git a/test/int/test_couple.py b/test/int/test_couple.py index 79e66f8b43e32cdbb1b21a3b834b7d871939be30..69685dc23a43cafd2353875320c18976ceb54df9 100644 --- a/test/int/test_couple.py +++ b/test/int/test_couple.py @@ -25,6 +25,19 @@ def test_follower_proposal(cluster2: Cluster): assert i2.eval("return check") == i2.listen +def test_switchover(cluster2: Cluster): + i1, i2 = cluster2.instances + + i1.promote_or_fail() + i1.assert_raft_status("Leader") + + i2.promote_or_fail() + i2.assert_raft_status("Leader") + + # Check idempotency + i2.promote_or_fail() + + def test_failover(cluster2: Cluster): i1, i2 = cluster2.instances i1.promote_or_fail()