Add a test for leadership expiration

de64
Vitaliy Filippov 2023-09-29 00:35:37 +03:00
parent 899c06faed
commit 1d8dfc861c
1 changed files with 38 additions and 5 deletions

View File

@ -1,9 +1,9 @@
const TinyRaft = require('./tinyraft.js');
function newNode(id, nodes, partitions)
function newNode(id, nodes, partitions, mod)
{
partitions = partitions || {};
let n = new TinyRaft({
let cfg = {
nodes: [ 1, 2, 3, 4, 5 ],
nodeId: id,
heartbeatTimeout: 100,
@ -16,7 +16,10 @@ function newNode(id, nodes, partitions)
setImmediate(function() { nodes[to].onReceive(n.nodeId, msg); });
}
},
});
};
if (mod)
mod(cfg);
let n = new TinyRaft(cfg);
n.on('change', (st) =>
{
console.log(
@ -27,13 +30,13 @@ function newNode(id, nodes, partitions)
nodes[id] = n;
}
function newNodes(count, partitions)
function newNodes(count, partitions, mod)
{
partitions = partitions || {};
const nodes = {};
for (let i = 1; i <= count; i++)
{
newNode(i, nodes, partitions);
newNode(i, nodes, partitions, mod);
}
for (let i = 1; i <= count; i++)
{
@ -148,10 +151,40 @@ async function testAddNode()
console.log('testAddNode: OK');
}
async function testLeadershipExpiration()
{
const partitions = {};
const nodes = newNodes(5, partitions, cfg => cfg.leadershipTimeout = 1500);
// Check that 5 nodes are in quorum after 2000ms
await new Promise(ok => setTimeout(ok, 2000));
checkQuorum(nodes, 5);
// Break network on the leader
let leader = nodes[1].leader;
console.log("stopping the leader's ("+leader+") network");
for (let i = 1; i <= 5; i++)
{
partitions[i+'-'+leader] = true;
partitions[leader+'-'+i] = true;
}
// Check that the leader loses leadership after 2 * leadershipTimeout
await new Promise(ok => setTimeout(ok, 3000));
if (nodes[leader].state != TinyRaft.CANDIDATE)
{
throw new Error("leadership expiration doesn't work");
}
// Clean up
for (const id in nodes)
{
nodes[id].stop();
}
console.log('testLeadershipExpiration: OK');
}
async function run()
{
await testStartThenRemoveNode();
await testAddNode();
await testLeadershipExpiration();
process.exit(0);
}