5
5
"database/sql"
6
6
"encoding/json"
7
7
"fmt"
8
+ "strings"
8
9
"testing"
9
10
"time"
10
11
@@ -26,33 +27,32 @@ import (
26
27
func TestProvisionerJobs (t * testing.T ) {
27
28
t .Parallel ()
28
29
29
- db ,ps := dbtestutil .NewDB (t )
30
- client ,_ ,coderdAPI := coderdtest .NewWithAPI (t ,& coderdtest.Options {
31
- IncludeProvisionerDaemon :false ,
32
- Database :db ,
33
- Pubsub :ps ,
34
- })
35
- owner := coderdtest .CreateFirstUser (t ,client )
36
- templateAdminClient ,templateAdmin := coderdtest .CreateAnotherUser (t ,client ,owner .OrganizationID ,rbac .ScopedRoleOrgTemplateAdmin (owner .OrganizationID ))
37
- memberClient ,member := coderdtest .CreateAnotherUser (t ,client ,owner .OrganizationID )
38
-
39
- // These CLI tests are related to provisioner job CRUD operations and as such
40
- // do not require the overhead of starting a provisioner. Other provisioner job
41
- // functionalities (acquisition etc.) are tested elsewhere.
42
- template := dbgen .Template (t ,db , database.Template {
43
- OrganizationID :owner .OrganizationID ,
44
- CreatedBy :owner .UserID ,
45
- AllowUserCancelWorkspaceJobs :true ,
46
- })
47
- version := dbgen .TemplateVersion (t ,db , database.TemplateVersion {
48
- OrganizationID :owner .OrganizationID ,
49
- CreatedBy :owner .UserID ,
50
- TemplateID : uuid.NullUUID {UUID :template .ID ,Valid :true },
51
- })
52
-
53
30
t .Run ("Cancel" ,func (t * testing.T ) {
54
31
t .Parallel ()
55
32
33
+ db ,ps := dbtestutil .NewDB (t )
34
+ client ,_ ,coderdAPI := coderdtest .NewWithAPI (t ,& coderdtest.Options {
35
+ IncludeProvisionerDaemon :false ,
36
+ Database :db ,
37
+ Pubsub :ps ,
38
+ })
39
+ owner := coderdtest .CreateFirstUser (t ,client )
40
+ templateAdminClient ,templateAdmin := coderdtest .CreateAnotherUser (t ,client ,owner .OrganizationID ,rbac .ScopedRoleOrgTemplateAdmin (owner .OrganizationID ))
41
+ memberClient ,member := coderdtest .CreateAnotherUser (t ,client ,owner .OrganizationID )
42
+
43
+ // These CLI tests are related to provisioner job CRUD operations and as such
44
+ // do not require the overhead of starting a provisioner. Other provisioner job
45
+ // functionalities (acquisition etc.) are tested elsewhere.
46
+ template := dbgen .Template (t ,db , database.Template {
47
+ OrganizationID :owner .OrganizationID ,
48
+ CreatedBy :owner .UserID ,
49
+ AllowUserCancelWorkspaceJobs :true ,
50
+ })
51
+ version := dbgen .TemplateVersion (t ,db , database.TemplateVersion {
52
+ OrganizationID :owner .OrganizationID ,
53
+ CreatedBy :owner .UserID ,
54
+ TemplateID : uuid.NullUUID {UUID :template .ID ,Valid :true },
55
+ })
56
56
// Test helper to create a provisioner job of a given type with a given input.
57
57
prepareJob := func (t * testing.T ,jobType database.ProvisionerJobType ,input json.RawMessage ) database.ProvisionerJob {
58
58
t .Helper ()
@@ -178,4 +178,148 @@ func TestProvisionerJobs(t *testing.T) {
178
178
})
179
179
}
180
180
})
181
+
182
+ t .Run ("List" ,func (t * testing.T ) {
183
+ t .Parallel ()
184
+
185
+ db ,ps := dbtestutil .NewDB (t )
186
+ client ,_ ,coderdAPI := coderdtest .NewWithAPI (t ,& coderdtest.Options {
187
+ IncludeProvisionerDaemon :false ,
188
+ Database :db ,
189
+ Pubsub :ps ,
190
+ })
191
+ owner := coderdtest .CreateFirstUser (t ,client )
192
+ _ ,member := coderdtest .CreateAnotherUser (t ,client ,owner .OrganizationID )
193
+
194
+ // These CLI tests are related to provisioner job CRUD operations and as such
195
+ // do not require the overhead of starting a provisioner. Other provisioner job
196
+ // functionalities (acquisition etc.) are tested elsewhere.
197
+ template := dbgen .Template (t ,db , database.Template {
198
+ OrganizationID :owner .OrganizationID ,
199
+ CreatedBy :owner .UserID ,
200
+ AllowUserCancelWorkspaceJobs :true ,
201
+ })
202
+ version := dbgen .TemplateVersion (t ,db , database.TemplateVersion {
203
+ OrganizationID :owner .OrganizationID ,
204
+ CreatedBy :owner .UserID ,
205
+ TemplateID : uuid.NullUUID {UUID :template .ID ,Valid :true },
206
+ })
207
+ // Create some test jobs
208
+ job1 := dbgen .ProvisionerJob (t ,db ,coderdAPI .Pubsub , database.ProvisionerJob {
209
+ OrganizationID :owner .OrganizationID ,
210
+ InitiatorID :owner .UserID ,
211
+ Type :database .ProvisionerJobTypeTemplateVersionImport ,
212
+ Input : []byte (`{"template_version_id":"` + version .ID .String ()+ `"}` ),
213
+ Tags : database.StringMap {provisionersdk .TagScope :provisionersdk .ScopeOrganization },
214
+ })
215
+
216
+ job2 := dbgen .ProvisionerJob (t ,db ,coderdAPI .Pubsub , database.ProvisionerJob {
217
+ OrganizationID :owner .OrganizationID ,
218
+ InitiatorID :member .ID ,
219
+ Type :database .ProvisionerJobTypeWorkspaceBuild ,
220
+ Input : []byte (`{"workspace_build_id":"` + uuid .New ().String ()+ `"}` ),
221
+ Tags : database.StringMap {provisionersdk .TagScope :provisionersdk .ScopeOrganization },
222
+ })
223
+ // Test basic list command
224
+ t .Run ("Basic" ,func (t * testing.T ) {
225
+ t .Parallel ()
226
+
227
+ inv ,root := clitest .New (t ,"provisioner" ,"jobs" ,"list" )
228
+ clitest .SetupConfig (t ,client ,root )
229
+ var buf bytes.Buffer
230
+ inv .Stdout = & buf
231
+ err := inv .Run ()
232
+ require .NoError (t ,err )
233
+
234
+ // Should contain both jobs
235
+ output := buf .String ()
236
+ assert .Contains (t ,output ,job1 .ID .String ())
237
+ assert .Contains (t ,output ,job2 .ID .String ())
238
+ })
239
+
240
+ // Test list with JSON output
241
+ t .Run ("JSON" ,func (t * testing.T ) {
242
+ t .Parallel ()
243
+
244
+ inv ,root := clitest .New (t ,"provisioner" ,"jobs" ,"list" ,"--output" ,"json" )
245
+ clitest .SetupConfig (t ,client ,root )
246
+ var buf bytes.Buffer
247
+ inv .Stdout = & buf
248
+ err := inv .Run ()
249
+ require .NoError (t ,err )
250
+
251
+ // Parse JSON output
252
+ var jobs []codersdk.ProvisionerJob
253
+ err = json .Unmarshal (buf .Bytes (),& jobs )
254
+ require .NoError (t ,err )
255
+
256
+ // Should contain both jobs
257
+ jobIDs := make ([]uuid.UUID ,len (jobs ))
258
+ for i ,job := range jobs {
259
+ jobIDs [i ]= job .ID
260
+ }
261
+ assert .Contains (t ,jobIDs ,job1 .ID )
262
+ assert .Contains (t ,jobIDs ,job2 .ID )
263
+ })
264
+
265
+ // Test list with limit
266
+ t .Run ("Limit" ,func (t * testing.T ) {
267
+ t .Parallel ()
268
+
269
+ inv ,root := clitest .New (t ,"provisioner" ,"jobs" ,"list" ,"--limit" ,"1" )
270
+ clitest .SetupConfig (t ,client ,root )
271
+ var buf bytes.Buffer
272
+ inv .Stdout = & buf
273
+ err := inv .Run ()
274
+ require .NoError (t ,err )
275
+
276
+ // Should contain at most 1 job
277
+ output := buf .String ()
278
+ jobCount := 0
279
+ if strings .Contains (output ,job1 .ID .String ()) {
280
+ jobCount ++
281
+ }
282
+ if strings .Contains (output ,job2 .ID .String ()) {
283
+ jobCount ++
284
+ }
285
+ assert .LessOrEqual (t ,jobCount ,1 )
286
+ })
287
+
288
+ // Test list with initiator filter
289
+ t .Run ("InitiatorFilter" ,func (t * testing.T ) {
290
+ t .Parallel ()
291
+
292
+ // Get owner user details to access username
293
+ ctx := testutil .Context (t ,testutil .WaitShort )
294
+ ownerUser ,err := client .User (ctx ,owner .UserID .String ())
295
+ require .NoError (t ,err )
296
+
297
+ // Test filtering by initiator (using username)
298
+ inv ,root := clitest .New (t ,"provisioner" ,"jobs" ,"list" ,"--initiator" ,ownerUser .Username )
299
+ clitest .SetupConfig (t ,client ,root )
300
+ var buf bytes.Buffer
301
+ inv .Stdout = & buf
302
+ err = inv .Run ()
303
+ require .NoError (t ,err )
304
+
305
+ // Should only contain job1 (initiated by owner)
306
+ output := buf .String ()
307
+ assert .Contains (t ,output ,job1 .ID .String ())
308
+ assert .NotContains (t ,output ,job2 .ID .String ())
309
+ })
310
+
311
+ // Test list with invalid user
312
+ t .Run ("InvalidUser" ,func (t * testing.T ) {
313
+ t .Parallel ()
314
+
315
+ // Test with non-existent user
316
+ inv ,root := clitest .New (t ,"provisioner" ,"jobs" ,"list" ,"--initiator" ,"nonexistent-user" )
317
+ clitest .SetupConfig (t ,client ,root )
318
+ var buf bytes.Buffer
319
+ inv .Stdout = & buf
320
+ err := inv .Run ()
321
+ require .Error (t ,err )
322
+ assert .Contains (t ,err .Error (),"initiator not found: nonexistent-user" )
323
+ })
324
+ })
181
325
}