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

Skip to content

Commit d61b447

Browse files
committed
[ci skip] table test
1 parent a65369a commit d61b447

File tree

1 file changed

+99
-74
lines changed

1 file changed

+99
-74
lines changed

agent/containers_internal_test.go

+99-74
Original file line numberDiff line numberDiff line change
@@ -73,80 +73,105 @@ func TestContainersHandler(t *testing.T) {
7373
t.Run("list", func(t *testing.T) {
7474
t.Parallel()
7575

76-
// Given: a containersHandler backed by a mock
77-
var (
78-
ctx = testutil.Context(t, testutil.WaitShort)
79-
clk = quartz.NewMock(t)
80-
ctrl = gomock.NewController(t)
81-
mockLister = NewMockContainerLister(ctrl)
82-
now = time.Now().UTC()
83-
ch = containersHandler{
84-
cacheDuration: time.Second,
85-
cl: mockLister,
86-
clock: clk,
87-
}
88-
expected = []codersdk.WorkspaceAgentContainer{fakeContainer(t)}
89-
)
90-
91-
clk.Set(now).MustWait(ctx)
92-
93-
// When: getContainers is called for the first time
94-
ch.mtime = time.Time{}
95-
mockLister.EXPECT().List(gomock.Any()).Return(expected, nil)
96-
actual, err := ch.getContainers(ctx)
97-
98-
// Then: the underlying lister is called and the result is returned
99-
require.NoError(t, err, "expected no error on first call")
100-
require.Equal(t, expected, actual, "expected containers to be equal on first call")
101-
// Then: the result is cached
102-
require.Equal(t, now, ch.mtime, "expected container mtime to be set on first call")
103-
require.NotEmpty(t, ch.containers, "expected cached data to not be empty on first call")
104-
105-
// When: getContainers is called again
106-
actual, err = ch.getContainers(ctx)
107-
108-
// Then: the underlying lister is not called and the cached result is
109-
// returned
110-
require.NoError(t, err, "expected no error on second call")
111-
require.Equal(t, expected, actual, "expected containers to be equal on second call")
112-
// Then: the result is cached
113-
require.Equal(t, now, ch.mtime, "expected container mtime to not have changed on second call")
114-
require.Equal(t, expected, ch.containers, "expected cached data to not have changed on second call")
115-
116-
// When: getContainers is called after the cache duration has expired
117-
expected = append(expected, fakeContainer(t))
118-
later := now.Add(defaultGetContainersCacheDuration).Add(time.Second)
119-
clk.Set(later).MustWait(ctx)
120-
mockLister.EXPECT().List(gomock.Any()).Return(expected, nil)
121-
actual, err = ch.getContainers(ctx)
122-
123-
// Then: the underlying lister is called and the result is returned
124-
require.NoError(t, err, "expected no error on third call")
125-
require.Equal(t, expected, actual, "expected containers to be equal on third call")
126-
// Then: the result is cached
127-
require.Equal(t, later, ch.mtime, "expected container mtime to later on third call")
128-
require.Equal(t, expected, ch.containers, "expected cached data to not have changed on third call")
129-
130-
// When: getContainers is called again but the underlying lister returns an error
131-
actual, err = ch.getContainers(ctx)
132-
require.NoError(t, err)
133-
134-
// Then: the cached data is not updated
135-
require.Equal(t, expected, actual, "expected containers to be equal on fourth call")
136-
require.Equal(t, later, ch.mtime, "expected container mtime to not have changed on fourth call")
137-
require.Equal(t, expected, ch.containers, "expected cached data to not have changed on fourth call")
138-
139-
// When: time advances past mtime
140-
laterlater := later.Add(defaultGetContainersCacheDuration).Add(time.Second)
141-
clk.Set(laterlater).MustWait(ctx)
142-
mockLister.EXPECT().List(gomock.Any()).Return(nil, assert.AnError)
143-
actual, err = ch.getContainers(ctx)
144-
// Then: the underlying error is returned
145-
require.ErrorContains(t, err, assert.AnError.Error(), "expected error on fifth call")
146-
require.Nil(t, actual, "expected no data to be returned on fifth call")
147-
// Then: the underlying cached data remains the same
148-
require.Equal(t, later, ch.mtime, "expected container mtime to not have changed on fifth call")
149-
require.Equal(t, expected, ch.containers, "expected cached data to not have changed on fifth call")
76+
fakeCt := fakeContainer(t)
77+
fakeCt2 := fakeContainer(t)
78+
79+
// Each test case is called multiple times to ensure idempotency
80+
for _, tc := range []struct {
81+
name string
82+
// data to be stored in the handler
83+
cacheData []codersdk.WorkspaceAgentContainer
84+
// duration of cache
85+
cacheDur time.Duration
86+
// relative age of the cached data
87+
cacheAge time.Duration
88+
// function to set up expectations for the mock
89+
setupMock func(*MockContainerLister)
90+
// expected result
91+
expected []codersdk.WorkspaceAgentContainer
92+
// expected error
93+
expectedErr string
94+
}{
95+
{
96+
name: "no cache",
97+
setupMock: func(mcl *MockContainerLister) {
98+
mcl.EXPECT().List(gomock.Any()).Return([]codersdk.WorkspaceAgentContainer{fakeCt}, nil).AnyTimes()
99+
},
100+
expected: []codersdk.WorkspaceAgentContainer{fakeCt},
101+
},
102+
{
103+
name: "no data",
104+
cacheData: nil,
105+
cacheAge: 2 * time.Second,
106+
cacheDur: time.Second,
107+
setupMock: func(mcl *MockContainerLister) {
108+
mcl.EXPECT().List(gomock.Any()).Return([]codersdk.WorkspaceAgentContainer{fakeCt}, nil).AnyTimes()
109+
},
110+
expected: []codersdk.WorkspaceAgentContainer{fakeCt},
111+
},
112+
{
113+
name: "cached data",
114+
cacheAge: time.Second,
115+
cacheData: []codersdk.WorkspaceAgentContainer{fakeCt},
116+
cacheDur: 2 * time.Second,
117+
expected: []codersdk.WorkspaceAgentContainer{fakeCt},
118+
},
119+
{
120+
name: "lister error",
121+
setupMock: func(mcl *MockContainerLister) {
122+
mcl.EXPECT().List(gomock.Any()).Return(nil, assert.AnError).AnyTimes()
123+
},
124+
expectedErr: assert.AnError.Error(),
125+
},
126+
{
127+
name: "stale cache",
128+
cacheAge: 2 * time.Second,
129+
cacheData: []codersdk.WorkspaceAgentContainer{fakeCt},
130+
cacheDur: time.Second,
131+
setupMock: func(mcl *MockContainerLister) {
132+
mcl.EXPECT().List(gomock.Any()).Return([]codersdk.WorkspaceAgentContainer{fakeCt2}, nil).AnyTimes()
133+
},
134+
expected: []codersdk.WorkspaceAgentContainer{fakeCt2},
135+
},
136+
} {
137+
tc := tc
138+
t.Run(tc.name, func(t *testing.T) {
139+
t.Parallel()
140+
var (
141+
ctx = testutil.Context(t, testutil.WaitShort)
142+
clk = quartz.NewMock(t)
143+
ctrl = gomock.NewController(t)
144+
mockLister = NewMockContainerLister(ctrl)
145+
now = time.Now().UTC()
146+
ch = containersHandler{
147+
cacheDuration: tc.cacheDur,
148+
cl: mockLister,
149+
clock: clk,
150+
containers: tc.cacheData,
151+
}
152+
)
153+
if tc.cacheAge != 0 {
154+
ch.mtime = now.Add(-tc.cacheAge)
155+
}
156+
if tc.setupMock != nil {
157+
tc.setupMock(mockLister)
158+
}
159+
160+
clk.Set(now).MustWait(ctx)
161+
162+
// Repeat the test to ensure idempotency
163+
for i := 0; i < 2; i++ {
164+
actual, err := ch.getContainers(ctx)
165+
if tc.expectedErr != "" {
166+
require.Empty(t, actual, "expected no data (attempt %d)", i)
167+
require.ErrorContains(t, err, tc.expectedErr, "expected error (attempt %d)", i)
168+
} else {
169+
require.NoError(t, err, "expected no error (attempt %d)", i)
170+
require.Equal(t, tc.expected, actual, "expected containers to be equal (attempt %d)", i)
171+
}
172+
}
173+
})
174+
}
150175
})
151176
}
152177

0 commit comments

Comments
 (0)