t.Fatalf("vols[0].Mtime(%s): %s\n", TEST_HASH, err)
}
- // Mark the volume bad and call PutBlock.
- vols[0].(*MockVolume).Bad = true
+ // vols[0].Touch will fail on the next call, so the volume
+ // manager will store a copy on vols[1] instead.
+ vols[0].(*MockVolume).Touchable = false
if err := PutBlock(TEST_BLOCK, TEST_HASH); err != nil {
t.Fatalf("PutBlock: %v", err)
}
- vols[0].(*MockVolume).Bad = false
+ vols[0].(*MockVolume).Touchable = true
// Now the mtime on the block on vols[0] should be unchanged, and
// there should be a copy of the block on vols[1].
t.Fatalf("vols[0].Mtime(%s): %s\n", TEST_HASH, err)
}
if !new_mtime.Equal(old_mtime) {
- t.Errorf("bad block mtimes do not match:\nold_mtime = %v\nnew_mtime = %v\n",
+ t.Errorf("mtime was changed on vols[0]:\nold_mtime = %v\nnew_mtime = %v\n",
old_mtime, new_mtime)
}
result, err := vols[1].Get(TEST_HASH)
// If the Bad field is true, this volume should return an error
// on all writes and puts.
//
+// The Touchable field signifies whether the Touch method will
+// succeed. Defaults to true. Note that Bad and Touchable are
+// independent: a MockVolume may be set up so that Put fails but Touch
+// works or vice versa.
+//
+// TODO(twp): rename Bad to something more descriptive, e.g. Writable,
+// and make sure that the tests that rely on it are testing the right
+// thing. We may need to simulate Writable, Touchable and Corrupt
+// volumes in different ways.
+//
type MockVolume struct {
Store map[string][]byte
Timestamps map[string]time.Time
Bad bool
+ Touchable bool
}
func CreateMockVolume() *MockVolume {
return &MockVolume{
- make(map[string][]byte),
- make(map[string]time.Time),
- false,
+ Store: make(map[string][]byte),
+ Timestamps: make(map[string]time.Time),
+ Bad: false,
+ Touchable: true,
}
}
}
func (v *MockVolume) Touch(loc string) error {
- if v.Bad {
- return errors.New("Bad volume")
+ if v.Touchable {
+ v.Timestamps[loc] = time.Now()
+ return nil
}
- v.Timestamps[loc] = time.Now()
- return nil
+ return errors.New("Touch failed")
}
func (v *MockVolume) Mtime(loc string) (time.Time, error) {
}
// Sleep for 1s, then put the block again. The volume
// should report a more recent mtime.
+ //
// TODO(twp): this would be better handled with a mock Time object.
+ // Alternatively, set the mtime manually to some moment in the past
+ // (maybe a v.SetMtime method?)
+ //
time.Sleep(time.Second)
if err := v.Put(TEST_HASH, TEST_BLOCK); err != nil {
t.Error(err)