test(raft-log-replication): close Req 8.3 node-restart with sim restart primitive
raft_sim_restart_node models a process restart: the durable in-memory log[] (WAL) and persisted (term, voted_for) survive, while volatile consensus state is cleared by re-running raft_init (returns the node to FOLLOWER). Callbacks, ctx, idx, and partition flag are preserved. test_sim_9_5_node_restart_resumes_replication restarts a follower mid-replication (partial 2-of-3 log), asserts the log survived (load-bearing: log_count==2 would fail if wiped), role/term restored, then replication resumes and converges with Log Matching. Closes the 8.3 'node restart while replication proceeds' sub-clause (8/8 requirement sections now fully covered). ASAN green (220 tests).
This commit is contained in:
parent
0dbccf4b0a
commit
3d6dc9cc56
4 changed files with 116 additions and 1 deletions
|
|
@ -513,6 +513,18 @@ void raft_sim_partition(raft_sim_cluster_t *c, int node_idx, int isolated);
|
|||
*/
|
||||
int raft_sim_check_log_matching(const raft_sim_cluster_t *c);
|
||||
|
||||
/*
|
||||
* raft_sim_restart_node: model a process restart of node_idx (Req 8.3).
|
||||
*
|
||||
* Durable state survives a restart: the in-memory log[] (which models the WAL on
|
||||
* disk) and the persisted (term, voted_for) are retained. Volatile consensus
|
||||
* state (role, votes, election bookkeeping, leader progress) is cleared by
|
||||
* re-running raft_init with the restored (term, voted_for, log_count), returning
|
||||
* the node to FOLLOWER. The four callbacks, ctx, idx, and partition flag are
|
||||
* preserved. Returns raft_init's status (0 on success).
|
||||
*/
|
||||
int raft_sim_restart_node(raft_sim_cluster_t *c, int node_idx);
|
||||
|
||||
#endif /* XCE_TESTING */
|
||||
|
||||
#endif /* RAFT_H */
|
||||
|
|
|
|||
|
|
@ -413,4 +413,37 @@ int raft_sim_check_log_matching(const raft_sim_cluster_t *c)
|
|||
return 1; /* holds */
|
||||
}
|
||||
|
||||
int raft_sim_restart_node(raft_sim_cluster_t *c, int node_idx)
|
||||
{
|
||||
if (node_idx < 0 || node_idx >= c->n)
|
||||
return -1;
|
||||
|
||||
raft_sim_node_t *node = &c->nodes[node_idx];
|
||||
|
||||
/* Snapshot the DURABLE state that survives a process restart: the persisted
|
||||
* (term, voted_for) and the log length (the in-memory log[] models the WAL on
|
||||
* disk and is left untouched). Volatile consensus state is discarded by the
|
||||
* re-init below. */
|
||||
uint64_t restored_term = node->state.term;
|
||||
int restored_voted_for = node->state.voted_for;
|
||||
uint64_t restored_log_len = (uint64_t)node->log_count;
|
||||
|
||||
raft_config_t cfg;
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.n_peers = node->state.n_peers;
|
||||
cfg.self_idx = node->idx;
|
||||
cfg.my_priority = node->idx;
|
||||
cfg.election_timeout_ms = node->state.election_timeout_ms;
|
||||
cfg.initial_term = restored_term;
|
||||
cfg.initial_voted_for = restored_voted_for;
|
||||
cfg.initial_log_len = restored_log_len;
|
||||
cfg.cbs = &node->cbs;
|
||||
cfg.ctx = node; /* same ctx convention as raft_sim_init */
|
||||
|
||||
/* raft_init returns the node to FOLLOWER and clears votes/election/leader
|
||||
* progress while restoring (term, voted_for, log_len). The log[] array and
|
||||
* the partition flag are preserved. */
|
||||
return raft_init(&node->state, &cfg);
|
||||
}
|
||||
|
||||
#endif /* XCE_TESTING */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue