package raft import ( "encoding/binary" "io" "io/ioutil" "os" "testing" ) func TestLog_followerLoop(t *testing.T) { l := NewInitializedLog() defer CloseLog(l) } func (l *Log) WaitUncommitted(index uint64) error { return l.waitUncommitted(index) } func (l *Log) WaitCommitted(index uint64) error { return l.waitCommitted(index) } func (l *Log) WaitApplied(index uint64) error { return l.Wait(index) } // NewOpenedLog returns an opened Log. Panic on error. func NewOpenedLog() *Log { l := NewLog() l.FSM = &IndexFSM{} if err := l.Open(tempfile()); err != nil { panic(err.Error()) } return l } // NewInitializedLog returns an opened & initialized Log. Panic on error. func NewInitializedLog() *Log { l := NewOpenedLog() if err := l.Initialize(); err != nil { panic(err.Error()) } return l } // CloseLog closes a log and deletes its underlying path. func CloseLog(l *Log) { defer os.RemoveAll(l.Path()) l.Close() } // IndexFSM represents a state machine that only records the last applied index. type IndexFSM struct { index uint64 } // MustApply updates the index. func (fsm *IndexFSM) Apply(entry *LogEntry) error { fsm.index = entry.Index return nil } // Index returns the highest applied index. func (fsm *IndexFSM) Index() uint64 { return fsm.index } // WriteTo writes a snapshot of the FSM to w. func (fsm *IndexFSM) WriteTo(w io.Writer) (n int64, err error) { return 0, binary.Write(w, binary.BigEndian, fsm.index) } // ReadFrom reads an FSM snapshot from r. func (fsm *IndexFSM) ReadFrom(r io.Reader) (n int64, err error) { return 0, binary.Read(r, binary.BigEndian, &fsm.index) } // tempfile returns the path to a non-existent file in the temp directory. func tempfile() string { f, _ := ioutil.TempFile("", "raft-") path := f.Name() f.Close() os.Remove(path) return path }