Merge branch 'jszlenk/create_new_subproject' refs #21937
[arvados.git] / services / keepstore / volume_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package keepstore
6
7 import (
8         "sync"
9         "time"
10 )
11
12 var (
13         TestBlock = []byte("The quick brown fox jumps over the lazy dog.")
14         TestHash  = "e4d909c290d0fb1ca068ffaddf22cbd0"
15
16         TestBlock2 = []byte("Pack my box with five dozen liquor jugs.")
17         TestHash2  = "f15ac516f788aec4f30932ffb6395c39"
18
19         TestBlock3 = []byte("Now is the time for all good men to come to the aid of their country.")
20         TestHash3  = "eed29bbffbc2dbe5e5ee0bb71888e61f"
21
22         EmptyHash  = "d41d8cd98f00b204e9800998ecf8427e"
23         EmptyBlock = []byte("")
24 )
25
26 // A TestableVolume allows test suites to manipulate the state of an
27 // underlying Volume, in order to test behavior in cases that are
28 // impractical to achieve with a sequence of normal Volume operations.
29 type TestableVolume interface {
30         volume
31
32         // Returns the strings that a driver uses to record read/write operations.
33         ReadWriteOperationLabelValues() (r, w string)
34
35         // Specify the value Mtime() should return, until the next
36         // call to Touch, TouchWithDate, or BlockWrite.
37         TouchWithDate(locator string, lastBlockWrite time.Time)
38
39         // Clean up, delete temporary files.
40         Teardown()
41 }
42
43 // brbuffer is like bytes.Buffer, but it implements io.WriterAt.
44 // Convenient for testing (volume)BlockRead implementations.
45 type brbuffer struct {
46         mtx sync.Mutex
47         buf []byte
48 }
49
50 func (b *brbuffer) WriteAt(p []byte, offset int64) (int, error) {
51         b.mtx.Lock()
52         defer b.mtx.Unlock()
53         if short := int(offset) + len(p) - len(b.buf); short > 0 {
54                 b.buf = append(b.buf, make([]byte, short)...)
55         }
56         return copy(b.buf[offset:], p), nil
57 }
58
59 func (b *brbuffer) Bytes() []byte {
60         b.mtx.Lock()
61         defer b.mtx.Unlock()
62         return b.buf
63 }
64
65 func (b *brbuffer) String() string {
66         b.mtx.Lock()
67         defer b.mtx.Unlock()
68         return string(b.buf)
69 }
70
71 func (b *brbuffer) Len() int {
72         b.mtx.Lock()
73         defer b.mtx.Unlock()
74         return len(b.buf)
75 }
76
77 func (b *brbuffer) Reset() {
78         b.mtx.Lock()
79         defer b.mtx.Unlock()
80         b.buf = nil
81 }
82
83 // a brdiscarder is like io.Discard, but it implements
84 // io.WriterAt. Convenient for testing (volume)BlockRead
85 // implementations when the output is not checked.
86 type brdiscarder struct{}
87
88 func (brdiscarder) WriteAt(p []byte, offset int64) (int, error) { return len(p), nil }
89
90 var brdiscard = brdiscarder{}