Ledger
258 tests,
none unaccounted for
How the port stands against the reference implementation's own unit-test suite.
The target is etcd-io/raft pinned at
26647d5; the scope is that repository minus the database beside it
(mvcc, watch, lease, gRPC).
This page audits the unit-test side. The scripted side — 41 scenarios replayed block by block — is recorded in the porting notes, and all 41 match byte for byte.
Method
Mechanical, so it can be falsified
The reference tree's test functions were extracted from the pinned commit with two commands:
grep -rhoE '^func (Test[A-Za-z0-9_]+)\(t \*testing\.T\)' --include=*_test.go . \ | sed 's/func //;s/(t \*testing.T)//' | sort
That yields 258 Test* functions. Each is matched against this
repository by the convention the port follows: a MoonBit test carries the
reference name at the front of its own name, or names it in the comment above.
// TestRawNodeStep: RawNode.Step handles every network message. test "TestRawNodeStep every network payload routes through Step" { … }
A test's provenance is therefore visible in moon test output rather
than buried in a mapping file. Benchmark* functions are not in this
count; the three the port names are in
src/cmd/benchmark.
Result
Every test has a disposition
| Disposition | Count |
|---|---|
| Carried by a test of the same name | 199 |
N/A — out of scope, reason below | 9 |
| Covered by the scripted scenarios and by tests named after the behaviour | 50 |
Total reference Test* | 258 |
No reference test is unaccounted for, and the 50 are grouped below with the file that covers each group — so a wrong grouping is one grep away from being caught.
Out of scope
The nine that cannot be translated
Three reasons are admissible: a language-level concurrency shell, a benchmark, and a memory-layout assertion. Only the first and the third occur here.
| Reference test | Why not |
|---|---|
TestProtoMemorySizes |
It asserts the byte size of message fields under the reference language's struct layout. MoonBit's data model has no comparable layout to assert, and nothing in the protocol depends on one. |
TestNodeStop, TestNodeStepUnblock |
The goroutine-and-channel shell around the core: a Ready loop in a goroutine, a stop channel, a proposal queue. The port has no such shell — RawNode is the same state machine driven by the caller — so there is no lifecycle to stop or unblock. |
TestNodeCommitPaginationAfterRestart |
Same shell: it restarts a goroutine and counts the readies it hands out. Its substance — a committed batch paginated across readies, and the applied cursor surviving a restart — is carried by TestRawNodeCommitPaginationAfterRestart, which is translated. |
TestNetworkDrop, TestNetworkDelay |
The test network is a goroutine per node behind a channel; these two drive that shell's drop and delay knobs. The port's Cluster covers the same two faults — set_drop, set_delay — deterministically, and both are exercised throughout the property and scenario tests. |
TestBasicProgress, TestPause, TestRestart |
They assert on the progress of the goroutine-backed node, which the port does not have. The state they inspect — a Progress advancing, a paused follower, a node resumed from storage — is asserted directly in the tracker's progress tests, the replicate_pause script, and TestRawNodeRestart. |
Covered without a same-named test
The fifty, by area
These behaviours are exercised — through the scripts, and through tests named after what they check rather than after the function they came from.
Election timing
TestFollowerStartElection,
TestFollowerElectionTimeoutRandomized,
TestCandidateElectionTimeoutRandomized,
TestFollowersElectionTimeoutNonconflict,
TestCandidatesElectionTimeoutNonconflict,
TestPastElectionTimeout — covered by the randomised-timeout band
test, the pinned-timeout tick test, and the campaign and
prevote scripts.
One-round elections and their losers
TestCandidateConcede, TestSingleNodeCandidate,
TestSingleNodePreCandidate,
TestCandidateSelfVoteAfterLostElection, and the pre-vote variant,
TestCandidateDeliversPreCandidateSelfVoteAfterBecomingCandidate —
covered by the election, election-contention and pre-vote property tests,
the vote-record test, and the single_node script.
Stale and duplicated messages
TestOldMessages, TestAllServerStepdown — covered by the
stale-term and step-dispatch tests, and by the scripts' ignored-message blocks.
Replication and proposals
TestLogReplication, TestProposal,
TestProposalByProxy, TestLeaderMsgAppSelfAckAfterTermChange
— covered by the replication, forwarding and idempotent-append tests, and the
async_storage_writes scripts.
Heartbeats
TestBcastBeat, TestRecvMsgBeat — covered by the
replicate_pause and
heartbeat_resp_recovers_from_probing scripts.
Flow control
TestProgressFlowControl, TestProgressPaused,
TestProgressResumeByHeartbeatResp — covered by
replicate_pause (a full in-flight window),
probe_and_replicate, and the tracker's progress tests.
Learners
TestLearnerPromotion, TestLearnerLogReplication,
TestLearnerReceiveSnapshot — covered by the learners-next test and
the two auto-add scripts.
Snapshots
TestProvideSnap, TestIgnoreProvidingSnap,
TestRestoreFromSnapMsg, TestRestoreIgnoreSnapshot —
covered by the snapshot, snapshot-RPC and snapshot-scenario tests, and the
snapshot_succeed_via_app_resp scripts.
Membership
TestAddLearner, TestRemoveNode,
TestStepConfig, TestStepIgnoreConfig,
TestConfChangeCheckBeforeCampaign,
TestConfChangeV2CheckBeforeCampaign — covered by the configuration,
cluster and pending-change tests, and the nine confchange scripts.
Leadership transfer
TestLeaderTransferTimeout,
TestLeaderTransferRemoveNode,
TestLeaderTransferDemoteNode,
TestLeaderTransferToNonExistingNode,
TestTransferNonMember — covered by the transfer tests (a transfer to
a non-member is a no-op; an incomplete transfer aborts after an election
timeout) and the confchange_v2_replace_leader scripts.
Read index and leases
TestReadOnlyForNewLeader, TestReadOnlyOptionLease,
TestReadOnlyWithLearner, TestRaftFreesReadOnlyMem —
covered by the read-only and read-index-queue tests: lease-based reads, safe
reads with a learner, and lease reads without a quorum.
Check-quorum disruption
TestDisruptiveFollower,
TestDisruptiveFollowerPreVote — covered by the check-quorum test
(a leased follower drops a pre-vote) and the checkquorum script.
The scripted drivers themselves
TestDataDriven, TestConfChangeDataDriven,
TestInteraction — covered by the port's own interpreter and the two
scoreboards that replay all 41 scripts.
Why a ledger
Counts are mechanical; judgement is named
The counts above are two commands over the pinned tree and src/. The
fifty rows are the part that needs judgement, so they are grouped and each group
names what covers it. If a group is wrong, it is wrong in a way one grep exposes —
which is the point.