blob: 761ec101b431f53473cec6df3b431346dcf4e596 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package watchable
import (
"testing"
"v.io/x/ref/services/syncbase/store"
"v.io/x/ref/services/syncbase/vclock"
)
// TestGetNextLogSeq tests that the getNextLogSeq helper works on range 0..10
// and continues to work after moving the log start.
func TestGetNextLogSeq(t *testing.T) {
ist, destroy := createStore()
defer destroy()
st, err := Wrap(ist, vclock.NewVClockForTests(nil), &Options{ManagedPrefixes: []string{}})
if err != nil {
t.Fatal(err)
}
// Check 0..10.
testGetNextLogSeqInterval(t, st, 0, 10)
// Update log start.
if _, err := st.watcher.updateLogStartSeq(st, 7); err != nil {
t.Fatalf("failed to update log start seq: %v", err)
}
// Delete some entries before the new start to simulate garbage collection.
for _, i := range []uint64{1, 3, 4, 5} {
if err := st.Delete([]byte(logEntryKey(i))); err != nil {
t.Fatalf("failed to delete log entry %d: %v", i, err)
}
}
// Check 11..20.
testGetNextLogSeqInterval(t, st, 11, 20)
}
// testGenNextLogSeqInterval tests that the getNextLogSeq helper works on range
// begin..end, assuming that begin is the next seq to be written.
func testGetNextLogSeqInterval(t *testing.T, st store.Store, begin, end uint64) {
for i := begin; i <= end; i++ {
seq, err := getNextLogSeq(st)
if err != nil {
t.Fatalf("failed to get log seq: %v", err)
}
if got, want := seq, i; got != want {
t.Fatalf("unexpected log seq: got %v, want %v", got, want)
}
st.Put([]byte(logEntryKey(i)), nil)
}
}
// TestPutLogStartSeq tests putting and getting the log start seq.
func TestPutLogStartSeq(t *testing.T) {
ist, destroy := createStore()
defer destroy()
st, err := Wrap(ist, vclock.NewVClockForTests(nil), &Options{ManagedPrefixes: []string{}})
if err != nil {
t.Fatal(err)
}
// Log start should default to 0.
if gotSeq, err := getLogStartSeq(st); err != nil {
t.Fatalf("getLogStartSeq() failed: %v", err)
} else if gotSeq != 0 {
t.Errorf("expected initial seq 0, got %d", gotSeq)
}
// Test log start persistence and encoding.
for _, seq := range []uint64{1, 42, 1337, 0x1f427, 0x1badb002, 0xdeadbeef} {
if err := putLogStartSeq(st, seq); err != nil {
t.Fatalf("putLogStartSeq(%d) failed: %v", seq, err)
}
// The log start should be the same when read from the wrapped store or from
// the watchable store.
if gotSeq, err := getLogStartSeq(st); err != nil {
t.Fatalf("getLogStartSeq(st) failed: %v", err)
} else if gotSeq != seq {
t.Errorf("expected seq %d, got %d", seq, gotSeq)
}
if gotSeq, err := getLogStartSeq(ist); err != nil {
t.Fatalf("getLogStartSeq(ist) failed: %v", err)
} else if gotSeq != seq {
t.Errorf("expected seq %d, got %d", seq, gotSeq)
}
}
}