mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
server: Written Snapshot's to WAL contains populated ConfState.
This will (among others) allow etcd-3.6 to not depend on store_v2 .snap files at all, as WAL + db file will be self-sufficient.
This commit is contained in:
@@ -27,3 +27,15 @@ func (rec *Record) Validate(crc uint32) error {
|
||||
rec.Reset()
|
||||
return ErrCRCMismatch
|
||||
}
|
||||
|
||||
// ValidateSnapshotForWrite ensures the Snapshot the newly written snapshot is valid.
|
||||
//
|
||||
// There might exist log-entries written by old etcd versions that does not conform
|
||||
// to the requirements.
|
||||
func ValidateSnapshotForWrite(e *Snapshot) error {
|
||||
// Since etcd>=3.5.0
|
||||
if e.ConfState == nil && e.Index > 0 {
|
||||
return errors.New("Saved (not-initial) snapshot is missing ConfState: " + e.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
36
server/wal/walpb/record_test.go
Normal file
36
server/wal/walpb/record_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package walpb
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/descriptor"
|
||||
"go.etcd.io/etcd/raft/v3/raftpb"
|
||||
)
|
||||
|
||||
func TestSnapshotMetadataCompatibility(t *testing.T) {
|
||||
_, snapshotMetadataMd := descriptor.ForMessage(&raftpb.SnapshotMetadata{})
|
||||
_, snapshotMd := descriptor.ForMessage(&Snapshot{})
|
||||
if len(snapshotMetadataMd.GetField()) != len(snapshotMd.GetField()) {
|
||||
t.Errorf("Different number of fields in raftpb.SnapshotMetadata vs. walpb.Snapshot. " +
|
||||
"They are supposed to be in sync.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSnapshot(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
snap *Snapshot
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "empty", snap: &Snapshot{}, wantErr: false},
|
||||
{name: "invalid", snap: &Snapshot{Index: 5, Term: 3}, wantErr: true},
|
||||
{name: "valid", snap: &Snapshot{Index: 5, Term: 3, ConfState: &raftpb.ConfState{Voters: []uint64{0x00cad1}}}, wantErr: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := ValidateSnapshotForWrite(tt.snap); (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateSnapshotForWrite() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user