|
@@ -1018,60 +1018,3 @@ func TestNodeCommitPaginationAfterRestart(t *testing.T) {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-// TestNodeBoundedLogGrowthWithPartition tests a scenario where a leader is
|
|
|
|
|
-// partitioned from a quorum of nodes. It verifies that the leader's log is
|
|
|
|
|
-// protected from unbounded growth even as new entries continue to be proposed.
|
|
|
|
|
-// This protection is provided by the MaxUncommittedEntriesSize configuration.
|
|
|
|
|
-func TestNodeBoundedLogGrowthWithPartition(t *testing.T) {
|
|
|
|
|
- const maxEntries = 16
|
|
|
|
|
- data := []byte("testdata")
|
|
|
|
|
- testEntry := raftpb.Entry{Data: data}
|
|
|
|
|
- maxEntrySize := uint64(maxEntries * PayloadSize(testEntry))
|
|
|
|
|
-
|
|
|
|
|
- s := NewMemoryStorage()
|
|
|
|
|
- cfg := newTestConfig(1, []uint64{1}, 10, 1, s)
|
|
|
|
|
- cfg.MaxUncommittedEntriesSize = maxEntrySize
|
|
|
|
|
- rn, err := NewRawNode(cfg)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- t.Fatal(err)
|
|
|
|
|
- }
|
|
|
|
|
- n := newNode()
|
|
|
|
|
- go n.run(rn)
|
|
|
|
|
- defer n.Stop()
|
|
|
|
|
- n.Campaign(context.TODO())
|
|
|
|
|
-
|
|
|
|
|
- rd := readyWithTimeout(&n)
|
|
|
|
|
- if len(rd.CommittedEntries) != 1 {
|
|
|
|
|
- t.Fatalf("expected 1 (empty) entry, got %d", len(rd.CommittedEntries))
|
|
|
|
|
- }
|
|
|
|
|
- s.Append(rd.Entries)
|
|
|
|
|
- n.Advance()
|
|
|
|
|
-
|
|
|
|
|
- // Simulate a network partition while we make our proposals by never
|
|
|
|
|
- // committing anything. These proposals should not cause the leader's
|
|
|
|
|
- // log to grow indefinitely.
|
|
|
|
|
- for i := 0; i < 1024; i++ {
|
|
|
|
|
- _ = n.Propose(context.TODO(), data)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Check the size of leader's uncommitted log tail. It should not exceed the
|
|
|
|
|
- // MaxUncommittedEntriesSize limit.
|
|
|
|
|
- checkUncommitted := func(exp uint64) {
|
|
|
|
|
- t.Helper()
|
|
|
|
|
- if a := rn.raft.uncommittedSize; exp != a {
|
|
|
|
|
- t.Fatalf("expected %d uncommitted entry bytes, found %d", exp, a)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- checkUncommitted(maxEntrySize)
|
|
|
|
|
-
|
|
|
|
|
- // Recover from the partition. The uncommitted tail of the Raft log should
|
|
|
|
|
- // disappear as entries are committed.
|
|
|
|
|
- rd = readyWithTimeout(&n)
|
|
|
|
|
- if len(rd.CommittedEntries) != maxEntries {
|
|
|
|
|
- t.Fatalf("expected %d entries, got %d", maxEntries, len(rd.CommittedEntries))
|
|
|
|
|
- }
|
|
|
|
|
- s.Append(rd.Entries)
|
|
|
|
|
- n.Advance()
|
|
|
|
|
- checkUncommitted(0)
|
|
|
|
|
-}
|
|
|