diff --git a/wal/wal.go b/wal/wal.go index 593d4e939..8dce3e4e7 100644 --- a/wal/wal.go +++ b/wal/wal.go @@ -51,7 +51,7 @@ func (w *WAL) writeInfo(id int64) error { return err } if o != 0 || w.bw.Buffered() != 0 { - return fmt.Errorf("cannot write info at %d, expect 0", o) + return fmt.Errorf("cannot write info at %d, expect 0", max(o, int64(w.bw.Buffered()))) } if err := w.writeInt64(infoType); err != nil { return err @@ -101,3 +101,10 @@ func (w *WAL) writeInt64(n int64) error { func (w *WAL) flush() error { return w.bw.Flush() } + +func max(a, b int64) int64 { + if a > b { + return a + } + return b +} diff --git a/wal/wal_test.go b/wal/wal_test.go index c79dfb420..e2b0ac688 100644 --- a/wal/wal_test.go +++ b/wal/wal_test.go @@ -3,7 +3,10 @@ package wal import ( "io/ioutil" "os" + "path" "testing" + + "github.com/coreos/etcd/raft" ) func TestNew(t *testing.T) { @@ -30,3 +33,73 @@ func TestNew(t *testing.T) { t.Fatal(err) } } + +func TestWriteEntry(t *testing.T) { + p := path.Join(os.TempDir(), "waltest") + w, err := New(p) + if err != nil { + t.Fatal(err) + } + e := &raft.Entry{1, 1, []byte{1}} + err = w.writeEntry(e) + if err != nil { + t.Fatal(err) + } + w.flush() + + err = os.Remove(p) + if err != nil { + t.Fatal(err) + } +} + +func TestWriteInfo(t *testing.T) { + p := path.Join(os.TempDir(), "waltest") + w, err := New(p) + if err != nil { + t.Fatal(err) + } + id := int64(0xBEEF) + err = w.writeInfo(id) + if err != nil { + t.Fatal(err) + } + + // make sure we can only write info at the head of the wal file + // still in buffer + err = w.writeInfo(id) + if err == nil || err.Error() != "cannot write info at 24, expect 0" { + t.Errorf("err = %v, want cannot write info at 8, expect 0", err) + } + + // flush to disk + w.flush() + err = w.writeInfo(id) + if err == nil || err.Error() != "cannot write info at 24, expect 0" { + t.Errorf("err = %v, want cannot write info at 8, expect 0", err) + } + + err = os.Remove(p) + if err != nil { + t.Fatal(err) + } +} + +func TestWriteState(t *testing.T) { + p := path.Join(os.TempDir(), "waltest") + w, err := New(p) + if err != nil { + t.Fatal(err) + } + st := &raft.State{1, 1, 1} + err = w.writeState(st) + if err != nil { + t.Fatal(err) + } + w.flush() + + err = os.Remove(p) + if err != nil { + t.Fatal(err) + } +}