forked from alecthomas/localcache
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlocalcache_test.go
More file actions
135 lines (114 loc) · 3.11 KB
/
localcache_test.go
File metadata and controls
135 lines (114 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package localcache
import (
"fmt"
"io"
"io/fs"
"path/filepath"
"sort"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestCache(t *testing.T) {
cache := NewForTesting(t)
tx, _, err := cache.Mkdir("test")
require.NoError(t, err)
_, err = cache.Commit(tx)
require.NoError(t, err)
f, err := cache.Open("test")
require.NoError(t, err)
_ = f.Close()
tx, f, err = cache.Create("test")
require.NoError(t, err)
_, err = f.WriteString("hello")
_ = f.Close()
require.NoError(t, err)
_, err = cache.Commit(tx)
require.NoError(t, err)
f, err = cache.Open("test")
require.NoError(t, err)
data, err := io.ReadAll(f)
_ = f.Close()
require.NoError(t, err)
require.Equal(t, "hello", string(data))
tx, f, err = cache.Create("test-rollback")
require.NoError(t, err)
_ = f.Close()
err = cache.Rollback(tx)
require.NoError(t, err)
err = cache.Purge(time.Hour)
require.NoError(t, err)
err = cache.Remove("test")
require.NoError(t, err)
require.Equal(t, []string{"", "/8b", "/9f"}, list(cache))
}
func TestRollbackOnError(t *testing.T) {
cache := NewForTesting(t)
tx, _, err := cache.Mkdir("test")
require.NoError(t, err)
err = func() (err error) {
defer cache.RollbackOnError(tx, &err)
return fmt.Errorf("function failed")
}()
require.Error(t, err)
require.Equal(t, []string{"", "/9f"}, list(cache))
}
func list(cache *Cache) (out []string) {
_ = filepath.Walk(cache.root, func(path string, info fs.FileInfo, err error) error {
out = append(out, strings.TrimPrefix(path, cache.root))
return nil
})
sort.Strings(out)
return
}
func TestPurge(t *testing.T) {
globalClock := clock
testClock := &fakeClock{currentTime: time.Now()}
clock = testClock
defer func() { clock = globalClock }()
cache := NewForTesting(t)
texts := []string{"hello", "world", "in", "2021"}
for _, text := range texts {
// testClock advances 2 secs for every writeFile
err := cache.WriteFile(text, []byte(text))
require.NoError(t, err)
}
// clock has advanced 8 seconds
for _, text := range texts {
// all entries must exist
require.NotEmpty(t, cache.IfExists(text))
}
err := cache.Purge(3500 * time.Millisecond) // 3.5 seconds
require.NoError(t, err)
for _, text := range texts[:2] {
// first two entries should have been purged
require.Empty(t, cache.IfExists(text))
}
for _, text := range texts[2:] {
// last two entries should still exist
require.NotEmpty(t, cache.IfExists(text))
}
}
func TestPurgeKey(t *testing.T) {
globalClock := clock
testClock := &fakeClock{currentTime: time.Now()}
clock = testClock
defer func() { clock = globalClock }()
cache := NewForTesting(t)
err := cache.WriteFile("hello", []byte("hello"))
require.NoError(t, err)
err = cache.PurgeKey("hello", 5*time.Second)
require.NoError(t, err)
// entry should still exist
require.NotEmpty(t, cache.IfExists("hello"))
err = cache.PurgeKey("hello", 0*time.Second)
require.NoError(t, err)
// entry should be gone
require.Empty(t, cache.IfExists("hello"))
}
func TestPurgeKeyMissingEntry(t *testing.T) {
cache := NewForTesting(t)
err := cache.PurgeKey("missing-dir/missing-entry", 0)
require.NoError(t, err)
}