Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bf6562a

Browse files
committed
Merge branch 'stevenmasley/file_cache_error' into lilac/dont-cache-errors
2 parents 8a6deb1 + 780233b commit bf6562a

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

coderd/files/cache_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ package files_test
22

33
import (
44
"context"
5+
"sync"
56
"sync/atomic"
67
"testing"
78
"time"
89

910
"github.com/google/uuid"
1011
"github.com/prometheus/client_golang/prometheus"
12+
"github.com/stretchr/testify/assert"
1113
"github.com/stretchr/testify/require"
1214
"go.uber.org/mock/gomock"
1315
"golang.org/x/sync/errgroup"
@@ -26,6 +28,63 @@ import (
2628
"github.com/coder/coder/v2/testutil"
2729
)
2830

31+
// TestCancelledFetch runs 2 Acquire calls. The first fails with a ctx.Canceled
32+
// error. The second call should ignore the first error and try to fetch the file
33+
// again, which should succeed.
34+
func TestCancelledFetch(t *testing.T) {
35+
t.Parallel()
36+
37+
fileID := uuid.New()
38+
rdy := make(chan struct{})
39+
dbM := dbmock.NewMockStore(gomock.NewController(t))
40+
41+
// First call should fail
42+
dbM.EXPECT().GetFileByID(gomock.Any(), gomock.Any()).DoAndReturn(func(mTx context.Context, fileID uuid.UUID) (database.File, error) {
43+
// Wait long enough for the second call to be queued up.
44+
return database.File{}, context.Canceled
45+
})
46+
47+
// Second call should succeed
48+
dbM.EXPECT().GetFileByID(gomock.Any(), gomock.Any()).DoAndReturn(func(mTx context.Context, fileID uuid.UUID) (database.File, error) {
49+
return database.File{
50+
ID: fileID,
51+
Data: make([]byte, 100),
52+
}, nil
53+
})
54+
55+
//nolint:gocritic // Unit testing
56+
ctx := dbauthz.AsFileReader(testutil.Context(t, testutil.WaitShort))
57+
cache := files.New(prometheus.NewRegistry(), &coderdtest.FakeAuthorizer{})
58+
59+
var wg sync.WaitGroup
60+
61+
// First call that will fail
62+
wg.Add(1)
63+
go func() {
64+
close(rdy)
65+
_, err := cache.Acquire(ctx, dbM, fileID)
66+
assert.ErrorIs(t, err, context.Canceled)
67+
wg.Done()
68+
}()
69+
70+
// Second call, that should succeed
71+
wg.Add(1)
72+
go func() {
73+
// Wait until the first goroutine has started
74+
<-rdy
75+
fs, err := cache.Acquire(ctx, dbM, fileID)
76+
assert.NoError(t, err)
77+
if fs != nil {
78+
fs.Close()
79+
}
80+
wg.Done()
81+
}()
82+
83+
// We need that second Acquire call to be queued up
84+
time.Sleep(testutil.IntervalFast)
85+
wg.Wait()
86+
}
87+
2988
// nolint:paralleltest,tparallel // Serially testing is easier
3089
func TestCacheRBAC(t *testing.T) {
3190
t.Parallel()

0 commit comments

Comments
 (0)