9
9
"time"
10
10
11
11
"github.com/google/uuid"
12
+ "github.com/sqlc-dev/pqtype"
12
13
"github.com/stretchr/testify/assert"
13
14
"github.com/stretchr/testify/require"
14
15
"go.uber.org/goleak"
@@ -18,6 +19,8 @@ import (
18
19
"cdr.dev/slog/sloggers/slogtest"
19
20
"github.com/coder/coder/v2/coderd/database"
20
21
"github.com/coder/coder/v2/coderd/database/dbmem"
22
+ "github.com/coder/coder/v2/coderd/database/dbtestutil"
23
+ "github.com/coder/coder/v2/coderd/database/dbtime"
21
24
"github.com/coder/coder/v2/coderd/database/provisionerjobs"
22
25
"github.com/coder/coder/v2/coderd/database/pubsub"
23
26
"github.com/coder/coder/v2/coderd/provisionerdserver"
@@ -315,6 +318,133 @@ func TestAcquirer_UnblockOnCancel(t *testing.T) {
315
318
require .Equal (t , jobID , job .ID )
316
319
}
317
320
321
+ func TestAcquirer_MatchTags (t * testing.T ) {
322
+ t .Parallel ()
323
+ if testing .Short () {
324
+ t .Skip ("skipping this test due to -short" )
325
+ }
326
+
327
+ someID := uuid .NewString ()
328
+ someOtherID := uuid .NewString ()
329
+
330
+ for _ , tt := range []struct {
331
+ name string
332
+ provisionerJobTags map [string ]string
333
+ acquireJobTags map [string ]string
334
+ expectAcquire bool
335
+ }{
336
+ {
337
+ name : "untagged provisioner and untagged job" ,
338
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" },
339
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" },
340
+ expectAcquire : true ,
341
+ },
342
+ {
343
+ name : "untagged provisioner and tagged job" ,
344
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" },
345
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" },
346
+ expectAcquire : false ,
347
+ },
348
+ {
349
+ name : "tagged provisioner and untagged job" ,
350
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" },
351
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" },
352
+ expectAcquire : false ,
353
+ },
354
+ {
355
+ name : "tagged provisioner and tagged job" ,
356
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" },
357
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" },
358
+ expectAcquire : true ,
359
+ },
360
+ {
361
+ name : "tagged provisioner and double-tagged job" ,
362
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" , "baz" : "zap" },
363
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" },
364
+ expectAcquire : false ,
365
+ },
366
+ {
367
+ name : "double-tagged provisioner and tagged job" ,
368
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" },
369
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" , "baz" : "zap" },
370
+ expectAcquire : true ,
371
+ },
372
+ {
373
+ name : "double-tagged provisioner and double-tagged job" ,
374
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" , "baz" : "zap" },
375
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" , "foo" : "bar" , "baz" : "zap" },
376
+ expectAcquire : true ,
377
+ },
378
+ {
379
+ name : "owner-scoped provisioner and untagged job" ,
380
+ provisionerJobTags : map [string ]string {"scope" : "organization" , "owner" : "" },
381
+ acquireJobTags : map [string ]string {"scope" : "owner" , "owner" : someID },
382
+ expectAcquire : false ,
383
+ },
384
+ {
385
+ name : "owner-scoped provisioner and owner-scoped job" ,
386
+ provisionerJobTags : map [string ]string {"scope" : "owner" , "owner" : someID },
387
+ acquireJobTags : map [string ]string {"scope" : "owner" , "owner" : someID },
388
+ expectAcquire : true ,
389
+ },
390
+ {
391
+ name : "owner-scoped provisioner and different owner-scoped job" ,
392
+ provisionerJobTags : map [string ]string {"scope" : "owner" , "owner" : someOtherID },
393
+ acquireJobTags : map [string ]string {"scope" : "owner" , "owner" : someID },
394
+ expectAcquire : false ,
395
+ },
396
+ {
397
+ name : "org-scoped provisioner and owner-scoped job" ,
398
+ provisionerJobTags : map [string ]string {"scope" : "owner" , "owner" : someID },
399
+ acquireJobTags : map [string ]string {"scope" : "organization" , "owner" : "" },
400
+ expectAcquire : false ,
401
+ },
402
+ } {
403
+ tt := tt
404
+ t .Run (tt .name , func (t * testing.T ) {
405
+ t .Parallel ()
406
+
407
+ ctx := testutil .Context (t , testutil .WaitShort / 2 )
408
+ // NOTE: explicitly not using fake store for this test.
409
+ db , ps := dbtestutil .NewDB (t )
410
+ log := slogtest .Make (t , nil ).Leveled (slog .LevelDebug )
411
+ org , err := db .InsertOrganization (ctx , database.InsertOrganizationParams {
412
+ ID : uuid .New (),
413
+ Name : "test org" ,
414
+ Description : "the organization of testing" ,
415
+ CreatedAt : dbtime .Now (),
416
+ UpdatedAt : dbtime .Now (),
417
+ })
418
+ require .NoError (t , err )
419
+ pj , err := db .InsertProvisionerJob (ctx , database.InsertProvisionerJobParams {
420
+ ID : uuid .New (),
421
+ CreatedAt : dbtime .Now (),
422
+ UpdatedAt : dbtime .Now (),
423
+ OrganizationID : org .ID ,
424
+ InitiatorID : uuid .New (),
425
+ Provisioner : database .ProvisionerTypeEcho ,
426
+ StorageMethod : database .ProvisionerStorageMethodFile ,
427
+ FileID : uuid .New (),
428
+ Type : database .ProvisionerJobTypeWorkspaceBuild ,
429
+ Input : []byte ("{}" ),
430
+ Tags : tt .provisionerJobTags ,
431
+ TraceMetadata : pqtype.NullRawMessage {},
432
+ })
433
+ require .NoError (t , err )
434
+ ptypes := []database.ProvisionerType {database .ProvisionerTypeEcho }
435
+ acq := provisionerdserver .NewAcquirer (ctx , log , db , ps )
436
+ aj , err := acq .AcquireJob (ctx , uuid .New (), ptypes , tt .acquireJobTags )
437
+ if tt .expectAcquire {
438
+ assert .NoError (t , err )
439
+ assert .Equal (t , pj .ID , aj .ID )
440
+ } else {
441
+ assert .Empty (t , aj , "should not have acquired job" )
442
+ assert .ErrorIs (t , err , context .DeadlineExceeded , "should have timed out" )
443
+ }
444
+ })
445
+ }
446
+ }
447
+
318
448
func postJob (t * testing.T , ps pubsub.Pubsub , pt database.ProvisionerType , tags provisionerdserver.Tags ) {
319
449
t .Helper ()
320
450
msg , err := json .Marshal (provisionerjobs.JobPosting {
0 commit comments