13 // MockVolumes are test doubles for Volumes, used to test handlers.
14 type MockVolume struct {
15 Store map[string][]byte
16 Timestamps map[string]time.Time
17 // Bad volumes return an error for every operation.
19 // Touchable volumes' Touch() method succeeds for a locator
20 // that has been Put().
22 // Readonly volumes return an error for Put, Delete, and
25 // Gate is a "starting gate", allowing test cases to pause
26 // volume operations long enough to inspect state. Every
27 // operation (except Status) starts by receiving from
28 // Gate. Sending one value unblocks one operation; closing the
29 // channel unblocks all operations. By default, Gate is a
30 // closed channel, so all operations proceed without
31 // blocking. See trash_worker_test.go for an example.
37 // CreateMockVolume returns a non-Bad, non-Readonly, Touchable mock
39 func CreateMockVolume() *MockVolume {
40 gate := make(chan struct{})
43 Store: make(map[string][]byte),
44 Timestamps: make(map[string]time.Time),
48 called: map[string]int{},
53 // CallCount returns how many times the named method has been called.
54 func (v *MockVolume) CallCount(method string) int {
56 defer v.mutex.Unlock()
57 if c, ok := v.called[method]; !ok {
64 func (v *MockVolume) gotCall(method string) {
66 defer v.mutex.Unlock()
67 if _, ok := v.called[method]; !ok {
74 func (v *MockVolume) Get(loc string) ([]byte, error) {
78 return nil, errors.New("Bad volume")
79 } else if block, ok := v.Store[loc]; ok {
80 buf := bufs.Get(len(block))
84 return nil, os.ErrNotExist
87 func (v *MockVolume) Put(loc string, block []byte) error {
91 return errors.New("Bad volume")
94 return MethodDisabledError
100 func (v *MockVolume) Touch(loc string) error {
104 return MethodDisabledError
107 v.Timestamps[loc] = time.Now()
110 return errors.New("Touch failed")
113 func (v *MockVolume) Mtime(loc string) (time.Time, error) {
119 err = errors.New("Bad volume")
120 } else if t, ok := v.Timestamps[loc]; ok {
128 func (v *MockVolume) IndexTo(prefix string, w io.Writer) error {
131 for loc, block := range v.Store {
132 if !IsValidLocator(loc) || !strings.HasPrefix(loc, prefix) {
135 _, err := fmt.Fprintf(w, "%s+%d %d\n",
136 loc, len(block), 123456789)
144 func (v *MockVolume) Delete(loc string) error {
148 return MethodDisabledError
150 if _, ok := v.Store[loc]; ok {
151 if time.Since(v.Timestamps[loc]) < blob_signature_ttl {
157 return os.ErrNotExist
160 func (v *MockVolume) Status() *VolumeStatus {
162 for _, block := range v.Store {
163 used = used + uint64(len(block))
165 return &VolumeStatus{"/bogo", 123, 1000000 - used, used}
168 func (v *MockVolume) String() string {
169 return "[MockVolume]"
172 func (v *MockVolume) Writable() bool {