Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / internal / cache / cache_test.go
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package cache
6
7 import (
8         "bytes"
9         "encoding/binary"
10         "fmt"
11         "io/ioutil"
12         "os"
13         "path/filepath"
14         "testing"
15         "time"
16 )
17
18 func init() {
19         verify = false // even if GODEBUG is set
20 }
21
22 func TestBasic(t *testing.T) {
23         dir, err := ioutil.TempDir("", "cachetest-")
24         if err != nil {
25                 t.Fatal(err)
26         }
27         defer os.RemoveAll(dir)
28         _, err = Open(filepath.Join(dir, "notexist"))
29         if err == nil {
30                 t.Fatal(`Open("tmp/notexist") succeeded, want failure`)
31         }
32
33         cdir := filepath.Join(dir, "c1")
34         if err := os.Mkdir(cdir, 0777); err != nil {
35                 t.Fatal(err)
36         }
37
38         c1, err := Open(cdir)
39         if err != nil {
40                 t.Fatalf("Open(c1) (create): %v", err)
41         }
42         if err := c1.putIndexEntry(dummyID(1), dummyID(12), 13, true); err != nil {
43                 t.Fatalf("addIndexEntry: %v", err)
44         }
45         if err := c1.putIndexEntry(dummyID(1), dummyID(2), 3, true); err != nil { // overwrite entry
46                 t.Fatalf("addIndexEntry: %v", err)
47         }
48         if entry, err := c1.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 {
49                 t.Fatalf("c1.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3)
50         }
51
52         c2, err := Open(cdir)
53         if err != nil {
54                 t.Fatalf("Open(c2) (reuse): %v", err)
55         }
56         if entry, err := c2.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 {
57                 t.Fatalf("c2.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3)
58         }
59         if err := c2.putIndexEntry(dummyID(2), dummyID(3), 4, true); err != nil {
60                 t.Fatalf("addIndexEntry: %v", err)
61         }
62         if entry, err := c1.Get(dummyID(2)); err != nil || entry.OutputID != dummyID(3) || entry.Size != 4 {
63                 t.Fatalf("c1.Get(2) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(3), 4)
64         }
65 }
66
67 func TestGrowth(t *testing.T) {
68         dir, err := ioutil.TempDir("", "cachetest-")
69         if err != nil {
70                 t.Fatal(err)
71         }
72         defer os.RemoveAll(dir)
73
74         c, err := Open(dir)
75         if err != nil {
76                 t.Fatalf("Open: %v", err)
77         }
78
79         n := 10000
80         if testing.Short() {
81                 n = 1000
82         }
83
84         for i := 0; i < n; i++ {
85                 if err := c.putIndexEntry(dummyID(i), dummyID(i*99), int64(i)*101, true); err != nil {
86                         t.Fatalf("addIndexEntry: %v", err)
87                 }
88                 id := ActionID(dummyID(i))
89                 entry, err := c.Get(id)
90                 if err != nil {
91                         t.Fatalf("Get(%x): %v", id, err)
92                 }
93                 if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 {
94                         t.Errorf("Get(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101)
95                 }
96         }
97         for i := 0; i < n; i++ {
98                 id := ActionID(dummyID(i))
99                 entry, err := c.Get(id)
100                 if err != nil {
101                         t.Fatalf("Get2(%x): %v", id, err)
102                 }
103                 if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 {
104                         t.Errorf("Get2(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101)
105                 }
106         }
107 }
108
109 func TestVerifyPanic(t *testing.T) {
110         os.Setenv("GODEBUG", "gocacheverify=1")
111         initEnv()
112         defer func() {
113                 os.Unsetenv("GODEBUG")
114                 verify = false
115         }()
116
117         if !verify {
118                 t.Fatal("initEnv did not set verify")
119         }
120
121         dir, err := ioutil.TempDir("", "cachetest-")
122         if err != nil {
123                 t.Fatal(err)
124         }
125         defer os.RemoveAll(dir)
126
127         c, err := Open(dir)
128         if err != nil {
129                 t.Fatalf("Open: %v", err)
130         }
131
132         id := ActionID(dummyID(1))
133         if err := c.PutBytes(id, []byte("abc")); err != nil {
134                 t.Fatal(err)
135         }
136
137         defer func() {
138                 if err := recover(); err != nil {
139                         t.Log(err)
140                         return
141                 }
142         }()
143         c.PutBytes(id, []byte("def"))
144         t.Fatal("mismatched Put did not panic in verify mode")
145 }
146
147 func dummyID(x int) [HashSize]byte {
148         var out [HashSize]byte
149         binary.LittleEndian.PutUint64(out[:], uint64(x))
150         return out
151 }
152
153 func TestCacheTrim(t *testing.T) {
154         dir, err := ioutil.TempDir("", "cachetest-")
155         if err != nil {
156                 t.Fatal(err)
157         }
158         defer os.RemoveAll(dir)
159
160         c, err := Open(dir)
161         if err != nil {
162                 t.Fatalf("Open: %v", err)
163         }
164         const start = 1000000000
165         now := int64(start)
166         c.now = func() time.Time { return time.Unix(now, 0) }
167
168         checkTime := func(name string, mtime int64) {
169                 t.Helper()
170                 file := filepath.Join(c.dir, name[:2], name)
171                 info, err := os.Stat(file)
172                 if err != nil {
173                         t.Fatal(err)
174                 }
175                 if info.ModTime().Unix() != mtime {
176                         t.Fatalf("%s mtime = %d, want %d", name, info.ModTime().Unix(), mtime)
177                 }
178         }
179
180         id := ActionID(dummyID(1))
181         c.PutBytes(id, []byte("abc"))
182         entry, _ := c.Get(id)
183         c.PutBytes(ActionID(dummyID(2)), []byte("def"))
184         mtime := now
185         checkTime(fmt.Sprintf("%x-a", id), mtime)
186         checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime)
187
188         // Get should not change recent mtimes.
189         now = start + 10
190         c.Get(id)
191         checkTime(fmt.Sprintf("%x-a", id), mtime)
192         checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime)
193
194         // Get should change distant mtimes.
195         now = start + 5000
196         mtime2 := now
197         if _, err := c.Get(id); err != nil {
198                 t.Fatal(err)
199         }
200         c.OutputFile(entry.OutputID)
201         checkTime(fmt.Sprintf("%x-a", id), mtime2)
202         checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime2)
203
204         // Trim should leave everything alone: it's all too new.
205         c.Trim()
206         if _, err := c.Get(id); err != nil {
207                 t.Fatal(err)
208         }
209         c.OutputFile(entry.OutputID)
210         data, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
211         if err != nil {
212                 t.Fatal(err)
213         }
214         checkTime(fmt.Sprintf("%x-a", dummyID(2)), start)
215
216         // Trim less than a day later should not do any work at all.
217         now = start + 80000
218         c.Trim()
219         if _, err := c.Get(id); err != nil {
220                 t.Fatal(err)
221         }
222         c.OutputFile(entry.OutputID)
223         data2, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
224         if err != nil {
225                 t.Fatal(err)
226         }
227         if !bytes.Equal(data, data2) {
228                 t.Fatalf("second trim did work: %q -> %q", data, data2)
229         }
230
231         // Fast forward and do another trim just before the 5 day cutoff.
232         // Note that because of usedQuantum the cutoff is actually 5 days + 1 hour.
233         // We used c.Get(id) just now, so 5 days later it should still be kept.
234         // On the other hand almost a full day has gone by since we wrote dummyID(2)
235         // and we haven't looked at it since, so 5 days later it should be gone.
236         now += 5 * 86400
237         checkTime(fmt.Sprintf("%x-a", dummyID(2)), start)
238         c.Trim()
239         if _, err := c.Get(id); err != nil {
240                 t.Fatal(err)
241         }
242         c.OutputFile(entry.OutputID)
243         mtime3 := now
244         if _, err := c.Get(dummyID(2)); err == nil { // haven't done a Get for this since original write above
245                 t.Fatalf("Trim did not remove dummyID(2)")
246         }
247
248         // The c.Get(id) refreshed id's mtime again.
249         // Check that another 5 days later it is still not gone,
250         // but check by using checkTime, which doesn't bring mtime forward.
251         now += 5 * 86400
252         c.Trim()
253         checkTime(fmt.Sprintf("%x-a", id), mtime3)
254         checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3)
255
256         // Half a day later Trim should still be a no-op, because there was a Trim recently.
257         // Even though the entry for id is now old enough to be trimmed,
258         // it gets a reprieve until the time comes for a new Trim scan.
259         now += 86400 / 2
260         c.Trim()
261         checkTime(fmt.Sprintf("%x-a", id), mtime3)
262         checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3)
263
264         // Another half a day later, Trim should actually run, and it should remove id.
265         now += 86400/2 + 1
266         c.Trim()
267         if _, err := c.Get(dummyID(1)); err == nil {
268                 t.Fatal("Trim did not remove dummyID(1)")
269         }
270 }