Skip to content
This repository has been archived by the owner on Mar 4, 2024. It is now read-only.

Commit

Permalink
Add a test for logReinstate
Browse files Browse the repository at this point in the history
Signed-off-by: Cole Miller <[email protected]>
  • Loading branch information
cole-miller committed Nov 27, 2023
1 parent 97fcbf6 commit 10f4f6f
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions test/integration/test_replication.c
Original file line number Diff line number Diff line change
Expand Up @@ -1233,3 +1233,48 @@ TEST(replication, failPersistBarrierFollower, setUp, tearDown, 0, NULL)

return MUNIT_OK;
}

/* A leader originates a log entry, fails to persist it, and steps down.
* A follower that received the entry wins the ensuing election and sends
* the same entry back to the original leader, while the original leader
* still has an outgoing pending message that references its copy of the
* entry. This triggers the original leader to reinstate the entry in its
* log. */
TEST(replication, receiveSameWithPendingSend, setUp, tearDown, 0, NULL)
{
struct fixture *f = data;
struct raft_apply req;

/* Three voters. */
CLUSTER_GROW;
/* Server 0 is the leader. */
BOOTSTRAP_START_AND_ELECT;

/* Server 1 never gets the entry. */
raft_fixture_set_send_latency(&f->cluster, 0, 1, 10000);

/* Disk write fails, but not before the entry gets to server 2. */
CLUSTER_SET_DISK_LATENCY(0, 1000);
raft_fixture_append_fault(&f->cluster, 0, 0);
req.data = (void *)(intptr_t)RAFT_IOERR;
CLUSTER_APPLY_ADD_X(0, &req, 1, NULL);
/* Server 0 steps down. */
CLUSTER_STEP_UNTIL_STATE_IS(0, RAFT_FOLLOWER, 1500);
munit_assert_ullong(CLUSTER_RAFT(0)->current_term, ==, 2);
ASSERT_FOLLOWER(1);
ASSERT_FOLLOWER(2);
/* Only server 2 has the new entry. */
munit_assert_ullong(CLUSTER_RAFT(0)->last_stored, ==, 2);
munit_assert_ullong(CLUSTER_RAFT(1)->last_stored, ==, 2);
munit_assert_ullong(CLUSTER_RAFT(2)->last_stored, ==, 3);

/* Server 2 times out first and wins the election. */
raft_set_election_timeout(CLUSTER_RAFT(2), 500);
raft_fixture_start_elect(&f->cluster, 2);
CLUSTER_STEP_UNTIL_STATE_IS(2, RAFT_LEADER, 1000);
munit_assert_ullong(CLUSTER_RAFT(2)->current_term, ==, 3);

/* Server 0 gets the same entry back from server 2. */
CLUSTER_STEP_UNTIL_APPLIED(2, 3, 1000);
return MUNIT_OK;
}

0 comments on commit 10f4f6f

Please sign in to comment.