@@ -16,6 +16,7 @@ import (
16
16
"github.com/coder/coder/agent"
17
17
"github.com/coder/coder/coderd/coderdtest"
18
18
"github.com/coder/coder/coderd/httpapi"
19
+ "github.com/coder/coder/coderd/util/ptr"
19
20
"github.com/coder/coder/codersdk"
20
21
"github.com/coder/coder/codersdk/agentsdk"
21
22
"github.com/coder/coder/provisioner/echo"
@@ -156,6 +157,117 @@ func Test_Runner(t *testing.T) {
156
157
require .Len (t ,workspaces .Workspaces ,0 )
157
158
})
158
159
160
+ t .Run ("CleanupPendingBuild" ,func (t * testing.T ) {
161
+ t .Parallel ()
162
+
163
+ ctx ,cancel := context .WithTimeout (context .Background (),testutil .WaitLong )
164
+ defer cancel ()
165
+
166
+ client := coderdtest .New (t ,& coderdtest.Options {
167
+ IncludeProvisionerDaemon :true ,
168
+ })
169
+ user := coderdtest .CreateFirstUser (t ,client )
170
+
171
+ version := coderdtest .CreateTemplateVersion (t ,client ,user .OrganizationID ,& echo.Responses {
172
+ Parse :echo .ParseComplete ,
173
+ ProvisionPlan :echo .ProvisionComplete ,
174
+ ProvisionApply : []* proto.Provision_Response {
175
+ {
176
+ Type :& proto.Provision_Response_Log {Log :& proto.Log {}},
177
+ },
178
+ },
179
+ })
180
+
181
+ version = coderdtest .AwaitTemplateVersionJob (t ,client ,version .ID )
182
+ template := coderdtest .CreateTemplate (t ,client ,user .OrganizationID ,version .ID ,func (request * codersdk.CreateTemplateRequest ) {
183
+ request .AllowUserCancelWorkspaceJobs = ptr .Ref (true )
184
+ })
185
+
186
+ const (
187
+ username = "scaletest-user"
188
+ email = "scaletest@test.coder.com"
189
+ )
190
+ runner := createworkspaces .NewRunner (client , createworkspaces.Config {
191
+ User : createworkspaces.UserConfig {
192
+ OrganizationID :user .OrganizationID ,
193
+ Username :username ,
194
+ Email :email ,
195
+ },
196
+ Workspace : workspacebuild.Config {
197
+ OrganizationID :user .OrganizationID ,
198
+ Request : codersdk.CreateWorkspaceRequest {
199
+ TemplateID :template .ID ,
200
+ },
201
+ },
202
+ })
203
+
204
+ cancelCtx ,cancelFunc := context .WithCancel (ctx )
205
+ done := make (chan struct {})
206
+ logs := bytes .NewBuffer (nil )
207
+ go func () {
208
+ err := runner .Run (cancelCtx ,"1" ,logs )
209
+ logsStr := logs .String ()
210
+ t .Log ("Runner logs:\n \n " + logsStr )
211
+ require .ErrorIs (t ,err ,context .Canceled )
212
+ close (done )
213
+ }()
214
+
215
+ require .Eventually (t ,func ()bool {
216
+ workspaces ,err := client .Workspaces (ctx , codersdk.WorkspaceFilter {})
217
+ if err != nil {
218
+ return false
219
+ }
220
+
221
+ return len (workspaces .Workspaces )> 0
222
+ },testutil .WaitShort ,testutil .IntervalFast )
223
+
224
+ cancelFunc ()
225
+ <- done
226
+
227
+ // When we run the cleanup, it should be canceled
228
+ cancelCtx ,cancelFunc = context .WithCancel (ctx )
229
+ done = make (chan struct {})
230
+ go func () {
231
+ // This will return an error as the "delete" operation will never complete.
232
+ _ = runner .Cleanup (cancelCtx ,"1" )
233
+ close (done )
234
+ }()
235
+
236
+ // Ensure the job has been marked as deleted
237
+ require .Eventually (t ,func ()bool {
238
+ workspaces ,err := client .Workspaces (ctx , codersdk.WorkspaceFilter {})
239
+ if err != nil {
240
+ return false
241
+ }
242
+
243
+ if len (workspaces .Workspaces )== 0 {
244
+ return false
245
+ }
246
+
247
+ // There should be two builds
248
+ builds ,err := client .WorkspaceBuilds (ctx , codersdk.WorkspaceBuildsRequest {
249
+ WorkspaceID :workspaces .Workspaces [0 ].ID ,
250
+ })
251
+ if err != nil {
252
+ return false
253
+ }
254
+ for _ ,build := range builds {
255
+ // One of the builds should be for creating the workspace,
256
+ if build .Transition != codersdk .WorkspaceTransitionStart {
257
+ continue
258
+ }
259
+
260
+ // And it should be either canceled or cancelling
261
+ if build .Job .Status == codersdk .ProvisionerJobCanceled || build .Job .Status == codersdk .ProvisionerJobCanceling {
262
+ return true
263
+ }
264
+ }
265
+ return false
266
+ },testutil .WaitShort ,testutil .IntervalFast )
267
+ cancelFunc ()
268
+ <- done
269
+ })
270
+
159
271
t .Run ("NoCleanup" ,func (t * testing.T ) {
160
272
t .Parallel ()
161
273