etcdserver: add a test to ensure renaming db happens before persisting wal and snap files

release-3.2
fanmin shi 2017-05-05 10:16:39 -07:00
parent 8b7b7222dd
commit dfdaf082c5
2 changed files with 84 additions and 1 deletions

View File

@ -211,7 +211,7 @@ func TestConfgChangeBlocksApply(t *testing.T) {
}
// finish apply, unblock raft routine
<-ap.raftDone
<-ap.notifyc
select {
case <-continueC:

View File

@ -951,6 +951,89 @@ func TestSnapshot(t *testing.T) {
<-ch
}
// TestSnapshotOrdering ensures raft persists snapshot onto disk before
// snapshot db is applied.
func TestSnapshotOrdering(t *testing.T) {
n := newNopReadyNode()
st := store.New()
cl := membership.NewCluster("abc")
cl.SetStore(st)
testdir, err := ioutil.TempDir(os.TempDir(), "testsnapdir")
if err != nil {
t.Fatalf("couldn't open tempdir (%v)", err)
}
defer os.RemoveAll(testdir)
if err := os.MkdirAll(testdir+"/member/snap", 0755); err != nil {
t.Fatalf("couldn't make snap dir (%v)", err)
}
rs := raft.NewMemoryStorage()
p := mockstorage.NewStorageRecorderStream(testdir)
tr, snapDoneC := rafthttp.NewSnapTransporter(testdir)
r := newRaftNode(raftNodeConfig{
isIDRemoved: func(id uint64) bool { return cl.IsIDRemoved(types.ID(id)) },
Node: n,
transport: tr,
storage: p,
raftStorage: rs,
})
s := &EtcdServer{
Cfg: &ServerConfig{
DataDir: testdir,
},
r: *r,
store: st,
cluster: cl,
SyncTicker: &time.Ticker{},
}
s.applyV2 = &applierV2store{store: s.store, cluster: s.cluster}
be, tmpPath := backend.NewDefaultTmpBackend()
defer os.RemoveAll(tmpPath)
s.kv = mvcc.New(be, &lease.FakeLessor{}, &s.consistIndex)
s.be = be
s.start()
defer s.Stop()
actionc := p.Chan()
n.readyc <- raft.Ready{Messages: []raftpb.Message{{Type: raftpb.MsgSnap}}}
if ac := <-actionc; ac.Name != "Save" {
// MsgSnap triggers raftNode to call Save()
t.Fatalf("expect save() is called, but got %v", ac.Name)
}
// get the snapshot sent by the transport
snapMsg := <-snapDoneC
// Snapshot first triggers raftnode to persists the snapshot onto disk
// before renaming db snapshot file to db
snapMsg.Snapshot.Metadata.Index = 1
n.readyc <- raft.Ready{Snapshot: snapMsg.Snapshot}
var seenSaveSnap bool
timer := time.After(5 * time.Second)
for {
select {
case ac := <-actionc:
switch ac.Name {
// DBFilePath() is called immediately before snapshot renaming.
case "DBFilePath":
if !seenSaveSnap {
t.Fatalf("DBFilePath called before SaveSnap")
}
return
case "SaveSnap":
seenSaveSnap = true
default:
continue
}
case <-timer:
t.Fatalf("timeout waiting on actions")
}
}
}
// Applied > SnapCount should trigger a SaveSnap event
func TestTriggerSnap(t *testing.T) {
be, tmpPath := backend.NewDefaultTmpBackend()