From b1da201d76359569fc4b455a4464f43ab525dbe7 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Fri, 29 Sep 2023 00:49:24 +0300 Subject: [PATCH] Add initialTerm to testAdd and make it fail; add a failing testRestart --- tinyraft.spec.js | 54 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/tinyraft.spec.js b/tinyraft.spec.js index 9da77bf..c3a273b 100644 --- a/tinyraft.spec.js +++ b/tinyraft.spec.js @@ -132,7 +132,7 @@ async function testStartThenRemoveNode() async function testAddNode() { console.log('testAddNode'); - const nodes = newNodes(5); + const nodes = newNodes(5, {}, cfg => cfg.initialTerm = 1000); await new Promise(ok => setTimeout(ok, 2000)); checkQuorum(nodes, 5); // Add node @@ -180,11 +180,63 @@ async function testLeadershipExpiration() console.log('testLeadershipExpiration: OK'); } +async function testRestart() +{ + const nodes = newNodes(5, {}, cfg => cfg.initialTerm = 1000); + let leaderChanges = 0, prevLeader = null; + nodes[2].on('change', (st) => + { + const leader = st.state == TinyRaft.CANDIDATE ? null : st.leader; + if (leader != prevLeader) + { + prevLeader = leader; + leaderChanges++; + } + }); + // Check that 5 nodes are in quorum after 2000ms + await new Promise(ok => setTimeout(ok, 2000)); + checkQuorum(nodes, 5); + if (leaderChanges >= 3) + { + throw new Error("leaderChanges = "+leaderChanges+" (expected < 3)") + } + // Stop a follower + let restarted = 1 + (prevLeader % 5); + if (restarted == 2) + { + restarted = 1 + (prevLeader + 1) % 5; + } + console.log("stopping a follower (node "+restarted+")"); + nodes[restarted].stop(); + delete nodes[restarted]; + // Wait 2000ms + await new Promise(ok => setTimeout(ok, 2000)); + // Restart a follower + console.log("restarting a follower (node "+restarted+")"); + leaderChanges = 0; + newNode(restarted, nodes, {}, null); + nodes[restarted].start(); + // Check quorum and the fact that the leader didn't change after 2000ms + await new Promise(ok => setTimeout(ok, 2000)); + checkQuorum(nodes, 5); + if (leaderChanges > 0) + { + throw new Error("leader changed after restart of a follower"); + } + // Clean up + for (const id in nodes) + { + nodes[id].stop(); + } + console.log('testRestart: OK'); +} + async function run() { await testStartThenRemoveNode(); await testAddNode(); await testLeadershipExpiration(); + await testRestart(); process.exit(0); }