Skip to content

Commit

Permalink
Testing and fixing the file snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
armon committed Nov 15, 2013
1 parent e7f6d15 commit a301c03
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 6 deletions.
20 changes: 14 additions & 6 deletions file_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,13 @@ func NewFileSnapshotStore(base string, retain int) (*FileSnapshotStore, error) {
return nil, fmt.Errorf("must retain at least one snapshot")
}

// Ensure our path exists
path := filepath.Join(base, snapPath)
if err := os.Mkdir(path, 0755); err != nil && !os.IsExist(err) {
return nil, fmt.Errorf("snapshot path not accessible: %v", err)
}

// Setup the store
store := &FileSnapshotStore{
path: path,
retain: retain,
Expand All @@ -93,14 +99,15 @@ func (f *FileSnapshotStore) testPermissions() error {
return err
}
fh.Close()
os.Remove(path)
return nil
}

// Create is used to start a new snapshot
func (f *FileSnapshotStore) Create(index, term uint64, peers []byte) (SnapshotSink, error) {
// Create a new path
name := time.Now().Format(time.RFC3339) + tmpSuffix
path := filepath.Join(f.path, name)
name := time.Now().Format(time.RFC3339)
path := filepath.Join(f.path, name+tmpSuffix)
log.Printf("[INFO] Creating new snapshot at %s", path)

// Make the directory
Expand All @@ -115,7 +122,7 @@ func (f *FileSnapshotStore) Create(index, term uint64, peers []byte) (SnapshotSi
dir: path,
meta: fileSnapshotMeta{
SnapshotMeta: SnapshotMeta{
ID: path,
ID: name,
Index: index,
Term: term,
Peers: peers,
Expand Down Expand Up @@ -179,14 +186,15 @@ func (f *FileSnapshotStore) getSnapshots() ([]*fileSnapshotMeta, error) {

// Populate the metadata, reverse order (newest first)
var snapMeta []*fileSnapshotMeta
for i := len(snapshots) - 1; i >= 0; i++ {
for i := len(snapshots); i > 0; i-- {
// Ignore any files
if !snapshots[i].IsDir() {
snap := snapshots[i-1]
if !snap.IsDir() {
continue
}

// Ignore any temporary snapshots
dirName := snapshots[i].Name()
dirName := snap.Name()
if strings.HasSuffix(dirName, tmpSuffix) {
log.Printf("[WARN] Found temporary snapshot: %v", dirName)
continue
Expand Down
122 changes: 122 additions & 0 deletions file_snapshot_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package raft

import (
"bytes"
"io"
"io/ioutil"
"os"
"testing"
)

func TestFileSnapshotStoreImpl(t *testing.T) {
var impl interface{} = &FileSnapshotStore{}
if _, ok := impl.(SnapshotStore); !ok {
t.Fatalf("FileSnapshotStore not a SnapshotStore")
}
}

func TestFileSnapshotSinkImpl(t *testing.T) {
var impl interface{} = &FileSnapshotSink{}
if _, ok := impl.(SnapshotSink); !ok {
t.Fatalf("FileSnapshotSink not a SnapshotSink")
}
}

func TestFileSS_CreateSnapshot(t *testing.T) {
// Create a test dir
dir, err := ioutil.TempDir("", "raft")
if err != nil {
t.Fatalf("err: %v ", err)
}
defer os.RemoveAll(dir)

snap, err := NewFileSnapshotStore(dir, 3)
if err != nil {
t.Fatalf("err: %v", err)
}

// Check no snapshots
snaps, err := snap.List()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(snaps) != 0 {
t.Fatalf("did not expect any snapshots: %v", snaps)
}

// Create a new sink
peers := []byte("all my lovely friends")
sink, err := snap.Create(10, 3, peers)
if err != nil {
t.Fatalf("err: %v", err)
}

// The sink is not done, should not be in a list!
snaps, err = snap.List()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(snaps) != 0 {
t.Fatalf("did not expect any snapshots: %v", snaps)
}

// Write to the sink
_, err = sink.Write([]byte("first\n"))
if err != nil {
t.Fatalf("err: %v", err)
}
_, err = sink.Write([]byte("second\n"))
if err != nil {
t.Fatalf("err: %v", err)
}

// Done!
err = sink.Close()
if err != nil {
t.Fatalf("err: %v", err)
}

// Should have a snapshot!
snaps, err = snap.List()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(snaps) != 1 {
t.Fatalf("expect a snapshots: %v", snaps)
}

// Check the latest
latest := snaps[0]
if latest.Index != 10 {
t.Fatalf("bad snapshot: %v", *latest)
}
if latest.Term != 3 {
t.Fatalf("bad snapshot: %v", *latest)
}
if bytes.Compare(latest.Peers, peers) != 0 {
t.Fatalf("bad snapshot: %v", *latest)
}
if latest.Size != 13 {
t.Fatalf("bad snapshot: %v", *latest)
}

// Read the snapshot
r, err := snap.Open(latest.ID)
if err != nil {
t.Fatalf("err: %v", err)
}

// Read out everything
var buf bytes.Buffer
if _, err := io.Copy(&buf, r); err != nil {
t.Fatalf("err: %v", err)
}
if err := r.Close(); err != nil {
t.Fatalf("err: %v", err)
}

// Ensure a match
if bytes.Compare(buf.Bytes(), []byte("first\nsecond\n")) != 0 {
t.Fatalf("content mismatch")
}
}

0 comments on commit a301c03

Please sign in to comment.