Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitff9e54b

Browse files
test: add failure testcase scenario
1 parentff8d3de commitff9e54b

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

‎enterprise/coderd/prebuilds/claim_test.go

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package prebuilds_test
33
import (
44
"context"
55
"database/sql"
6+
"errors"
67
"strings"
78
"sync/atomic"
89
"testing"
@@ -27,6 +28,32 @@ import (
2728
"github.com/coder/coder/v2/testutil"
2829
)
2930

31+
typeerrorStorestruct {
32+
claimingErrerror
33+
34+
database.Store
35+
}
36+
37+
funcnewErrorStore(db database.Store,claimingErrerror)*errorStore {
38+
return&errorStore{
39+
Store:db,
40+
claimingErr:claimingErr,
41+
}
42+
}
43+
44+
func (es*errorStore)InTx(fnfunc(store database.Store)error,opts*database.TxOptions)error {
45+
// Pass failure store down into transaction store.
46+
returnes.Store.InTx(func(store database.Store)error {
47+
newES:=newErrorStore(store,es.claimingErr)
48+
49+
returnfn(newES)
50+
},opts)
51+
}
52+
53+
func (es*errorStore)ClaimPrebuiltWorkspace(ctx context.Context,arg database.ClaimPrebuiltWorkspaceParams) (database.ClaimPrebuiltWorkspaceRow,error) {
54+
return database.ClaimPrebuiltWorkspaceRow{},es.claimingErr
55+
}
56+
3057
typestoreSpystruct {
3158
database.Store
3259

@@ -66,6 +93,171 @@ func (m *storeSpy) ClaimPrebuiltWorkspace(ctx context.Context, arg database.Clai
6693
returnresult,err
6794
}
6895

96+
funcTestClaimPrebuild_CheckDifferentErrors(t*testing.T) {
97+
t.Parallel()
98+
99+
if!dbtestutil.WillUsePostgres() {
100+
t.Skip("This test requires postgres")
101+
}
102+
103+
const (
104+
desiredInstances=1
105+
presetCount=2
106+
107+
expectedPrebuildsCount=desiredInstances*presetCount
108+
)
109+
110+
cases:=map[string]struct {
111+
claimingErrerror
112+
checkFnfunc(
113+
t*testing.T,
114+
ctx context.Context,
115+
store database.Store,
116+
userClient*codersdk.Client,
117+
user codersdk.User,
118+
templateVersionID uuid.UUID,
119+
presetID uuid.UUID,
120+
)
121+
}{
122+
"ErrNoClaimablePrebuiltWorkspaces is returned": {
123+
claimingErr:agplprebuilds.ErrNoClaimablePrebuiltWorkspaces,
124+
checkFn:func(
125+
t*testing.T,
126+
ctx context.Context,
127+
store database.Store,
128+
userClient*codersdk.Client,
129+
user codersdk.User,
130+
templateVersionID uuid.UUID,
131+
presetID uuid.UUID,
132+
) {
133+
// When: a user creates a new workspace with a preset for which prebuilds are configured.
134+
workspaceName:=strings.ReplaceAll(testutil.GetRandomName(t),"_","-")
135+
userWorkspace,err:=userClient.CreateUserWorkspace(ctx,user.Username, codersdk.CreateWorkspaceRequest{
136+
TemplateVersionID:templateVersionID,
137+
Name:workspaceName,
138+
TemplateVersionPresetID:presetID,
139+
})
140+
141+
require.NoError(t,err)
142+
coderdtest.AwaitWorkspaceBuildJobCompleted(t,userClient,userWorkspace.LatestBuild.ID)
143+
144+
// Then: the number of running prebuilds hasn't changed because claiming prebuild is failed and we fallback to creating new workspace.
145+
currentPrebuilds,err:=store.GetRunningPrebuiltWorkspaces(ctx)
146+
require.NoError(t,err)
147+
require.Equal(t,expectedPrebuildsCount,len(currentPrebuilds))
148+
},
149+
},
150+
"unexpected error during claim is returned": {
151+
claimingErr:errors.New("unexpected error during claim"),
152+
checkFn:func(
153+
t*testing.T,
154+
ctx context.Context,
155+
store database.Store,
156+
userClient*codersdk.Client,
157+
user codersdk.User,
158+
templateVersionID uuid.UUID,
159+
presetID uuid.UUID,
160+
) {
161+
// When: a user creates a new workspace with a preset for which prebuilds are configured.
162+
workspaceName:=strings.ReplaceAll(testutil.GetRandomName(t),"_","-")
163+
_,err:=userClient.CreateUserWorkspace(ctx,user.Username, codersdk.CreateWorkspaceRequest{
164+
TemplateVersionID:templateVersionID,
165+
Name:workspaceName,
166+
TemplateVersionPresetID:presetID,
167+
})
168+
169+
// Then: unexpected error happened and was propagated all the way to the caller
170+
require.Error(t,err)
171+
require.ErrorContains(t,err,"unexpected error during claim")
172+
},
173+
},
174+
}
175+
176+
forname,tc:=rangecases {
177+
t.Run(name,func(t*testing.T) {
178+
t.Parallel()
179+
180+
// Setup.
181+
ctx:=testutil.Context(t,testutil.WaitMedium)
182+
db,pubsub:=dbtestutil.NewDB(t)
183+
failureStore:=newErrorStore(db,tc.claimingErr)
184+
185+
logger:=testutil.Logger(t)
186+
client,_,api,owner:=coderdenttest.NewWithAPI(t,&coderdenttest.Options{
187+
Options:&coderdtest.Options{
188+
IncludeProvisionerDaemon:true,
189+
Database:failureStore,
190+
Pubsub:pubsub,
191+
},
192+
193+
EntitlementsUpdateInterval:time.Second,
194+
})
195+
196+
reconciler:=prebuilds.NewStoreReconciler(failureStore,pubsub, codersdk.PrebuildsConfig{},logger,quartz.NewMock(t))
197+
varclaimer agplprebuilds.Claimer=&prebuilds.EnterpriseClaimer{}
198+
api.AGPL.PrebuildsClaimer.Store(&claimer)
199+
200+
version:=coderdtest.CreateTemplateVersion(t,client,owner.OrganizationID,templateWithAgentAndPresetsWithPrebuilds(desiredInstances))
201+
_=coderdtest.AwaitTemplateVersionJobCompleted(t,client,version.ID)
202+
coderdtest.CreateTemplate(t,client,owner.OrganizationID,version.ID)
203+
presets,err:=client.TemplateVersionPresets(ctx,version.ID)
204+
require.NoError(t,err)
205+
require.Len(t,presets,presetCount)
206+
207+
userClient,user:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID,rbac.RoleMember())
208+
209+
ctx=dbauthz.AsPrebuildsOrchestrator(ctx)
210+
211+
// Given: the reconciliation state is snapshot.
212+
state,err:=reconciler.SnapshotState(ctx,failureStore)
213+
require.NoError(t,err)
214+
require.Len(t,state.Presets,presetCount)
215+
216+
// When: a reconciliation is setup for each preset.
217+
for_,preset:=rangepresets {
218+
ps,err:=state.FilterByPreset(preset.ID)
219+
require.NoError(t,err)
220+
require.NotNil(t,ps)
221+
actions,err:=reconciler.CalculateActions(ctx,*ps)
222+
require.NoError(t,err)
223+
require.NotNil(t,actions)
224+
225+
require.NoError(t,reconciler.ReconcilePreset(ctx,*ps))
226+
}
227+
228+
// Given: a set of running, eligible prebuilds eventually starts up.
229+
runningPrebuilds:=make(map[uuid.UUID]database.GetRunningPrebuiltWorkspacesRow,desiredInstances*presetCount)
230+
require.Eventually(t,func()bool {
231+
rows,err:=failureStore.GetRunningPrebuiltWorkspaces(ctx)
232+
require.NoError(t,err)
233+
234+
for_,row:=rangerows {
235+
runningPrebuilds[row.CurrentPresetID.UUID]=row
236+
237+
agents,err:=db.GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx,row.ID)
238+
require.NoError(t,err)
239+
240+
// Workspaces are eligible once its agent is marked "ready".
241+
for_,agent:=rangeagents {
242+
require.NoError(t,db.UpdateWorkspaceAgentLifecycleStateByID(ctx, database.UpdateWorkspaceAgentLifecycleStateByIDParams{
243+
ID:agent.ID,
244+
LifecycleState:database.WorkspaceAgentLifecycleStateReady,
245+
StartedAt: sql.NullTime{Time:time.Now().Add(time.Hour),Valid:true},
246+
ReadyAt: sql.NullTime{Time:time.Now().Add(-1*time.Hour),Valid:true},
247+
}))
248+
}
249+
}
250+
251+
t.Logf("found %d running prebuilds so far, want %d",len(runningPrebuilds),expectedPrebuildsCount)
252+
253+
returnlen(runningPrebuilds)==expectedPrebuildsCount
254+
},testutil.WaitSuperLong,testutil.IntervalSlow)
255+
256+
tc.checkFn(t,ctx,failureStore,userClient,user,version.ID,presets[0].ID)
257+
})
258+
}
259+
}
260+
69261
funcTestClaimPrebuild(t*testing.T) {
70262
t.Parallel()
71263

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp