@@ -612,6 +612,85 @@ func TestGetWorkspaceAgentUsageStatsAndLabels(t *testing.T) {
612612})
613613}
614614
615+ func TestGetWorkspacesAndAgentsByOwnerID (t * testing.T ) {
616+ t .Parallel ()
617+ if testing .Short () {
618+ t .SkipNow ()
619+ }
620+
621+ ctx := testutil .Context (t ,testutil .WaitLong )
622+ sqlDB := testSQLDB (t )
623+ err := migrations .Up (sqlDB )
624+ require .NoError (t ,err )
625+ db := database .New (sqlDB )
626+
627+ org := dbgen .Organization (t ,db , database.Organization {})
628+ owner := dbgen .User (t ,db , database.User {
629+ RBACRoles : []string {rbac .RoleOwner ().String ()},
630+ })
631+ tpl := dbgen .Template (t ,db , database.Template {
632+ OrganizationID :org .ID ,
633+ CreatedBy :owner .ID ,
634+ })
635+
636+ pendingID := uuid .New ()
637+ createTemplateVersion (t ,db ,tpl ,tvArgs {
638+ Status :database .ProvisionerJobStatusPending ,
639+ CreateWorkspace :true ,
640+ WorkspaceID :pendingID ,
641+ CreateAgent :true ,
642+ })
643+ failedID := uuid .New ()
644+ createTemplateVersion (t ,db ,tpl ,tvArgs {
645+ Status :database .ProvisionerJobStatusFailed ,
646+ CreateWorkspace :true ,
647+ CreateAgent :true ,
648+ WorkspaceID :failedID ,
649+ })
650+ succeededID := uuid .New ()
651+ createTemplateVersion (t ,db ,tpl ,tvArgs {
652+ Status :database .ProvisionerJobStatusSucceeded ,
653+ WorkspaceTransition :database .WorkspaceTransitionStart ,
654+ CreateWorkspace :true ,
655+ WorkspaceID :succeededID ,
656+ CreateAgent :true ,
657+ ExtraAgents :1 ,
658+ ExtraBuilds :2 ,
659+ })
660+ deletedID := uuid .New ()
661+ createTemplateVersion (t ,db ,tpl ,tvArgs {
662+ Status :database .ProvisionerJobStatusSucceeded ,
663+ WorkspaceTransition :database .WorkspaceTransitionDelete ,
664+ CreateWorkspace :true ,
665+ WorkspaceID :deletedID ,
666+ CreateAgent :false ,
667+ })
668+
669+ ownerRows ,err := db .GetWorkspacesAndAgentsByOwnerID (ctx ,owner .ID )
670+ require .NoError (t ,err )
671+ require .Len (t ,ownerRows ,4 )
672+ for _ ,row := range ownerRows {
673+ switch row .ID {
674+ case pendingID :
675+ require .Len (t ,row .Agents ,1 )
676+ require .Equal (t ,database .ProvisionerJobStatusPending ,row .JobStatus )
677+ case failedID :
678+ require .Len (t ,row .Agents ,1 )
679+ require .Equal (t ,database .ProvisionerJobStatusFailed ,row .JobStatus )
680+ case succeededID :
681+ require .Len (t ,row .Agents ,2 )
682+ require .Equal (t ,database .ProvisionerJobStatusSucceeded ,row .JobStatus )
683+ require .Equal (t ,database .WorkspaceTransitionStart ,row .Transition )
684+ case deletedID :
685+ require .Len (t ,row .Agents ,0 )
686+ require .Equal (t ,database .ProvisionerJobStatusSucceeded ,row .JobStatus )
687+ require .Equal (t ,database .WorkspaceTransitionDelete ,row .Transition )
688+ default :
689+ t .Fatalf ("unexpected workspace ID: %s" ,row .ID )
690+ }
691+ }
692+ }
693+
615694func TestInsertWorkspaceAgentLogs (t * testing.T ) {
616695t .Parallel ()
617696if testing .Short () {
@@ -1537,7 +1616,11 @@ type tvArgs struct {
15371616Status database.ProvisionerJobStatus
15381617// CreateWorkspace is true if we should create a workspace for the template version
15391618CreateWorkspace bool
1619+ WorkspaceID uuid.UUID
1620+ CreateAgent bool
15401621WorkspaceTransition database.WorkspaceTransition
1622+ ExtraAgents int
1623+ ExtraBuilds int
15411624}
15421625
15431626// createTemplateVersion is a helper function to create a version with its dependencies.
@@ -1554,49 +1637,18 @@ func createTemplateVersion(t testing.TB, db database.Store, tpl database.Templat
15541637CreatedBy :tpl .CreatedBy ,
15551638})
15561639
1557- earlier := sql.NullTime {
1558- Time :dbtime .Now ().Add (time .Second * - 30 ),
1559- Valid :true ,
1560- }
1561- now := sql.NullTime {
1562- Time :dbtime .Now (),
1563- Valid :true ,
1564- }
1565- j := database.ProvisionerJob {
1640+ latestJob := database.ProvisionerJob {
15661641ID :version .JobID ,
1567- CreatedAt :earlier .Time ,
1568- UpdatedAt :earlier .Time ,
15691642Error : sql.NullString {},
15701643OrganizationID :tpl .OrganizationID ,
15711644InitiatorID :tpl .CreatedBy ,
15721645Type :database .ProvisionerJobTypeTemplateVersionImport ,
15731646}
1574-
1575- switch args .Status {
1576- case database .ProvisionerJobStatusRunning :
1577- j .StartedAt = earlier
1578- case database .ProvisionerJobStatusPending :
1579- case database .ProvisionerJobStatusFailed :
1580- j .StartedAt = earlier
1581- j .CompletedAt = now
1582- j .Error = sql.NullString {
1583- String :"failed" ,
1584- Valid :true ,
1585- }
1586- j .ErrorCode = sql.NullString {
1587- String :"failed" ,
1588- Valid :true ,
1589- }
1590- case database .ProvisionerJobStatusSucceeded :
1591- j .StartedAt = earlier
1592- j .CompletedAt = now
1593- default :
1594- t .Fatalf ("invalid status: %s" ,args .Status )
1595- }
1596-
1597- dbgen .ProvisionerJob (t ,db ,nil ,j )
1647+ setJobStatus (t ,args .Status ,& latestJob )
1648+ dbgen .ProvisionerJob (t ,db ,nil ,latestJob )
15981649if args .CreateWorkspace {
15991650wrk := dbgen .Workspace (t ,db , database.WorkspaceTable {
1651+ ID :args .WorkspaceID ,
16001652CreatedAt : time.Time {},
16011653UpdatedAt : time.Time {},
16021654OwnerID :tpl .CreatedBy ,
@@ -1607,24 +1659,93 @@ func createTemplateVersion(t testing.TB, db database.Store, tpl database.Templat
16071659if args .WorkspaceTransition != "" {
16081660trans = args .WorkspaceTransition
16091661}
1610- buildJob := dbgen . ProvisionerJob ( t , db , nil , database.ProvisionerJob {
1662+ latestJob = database.ProvisionerJob {
16111663Type :database .ProvisionerJobTypeWorkspaceBuild ,
1612- CompletedAt :now ,
16131664InitiatorID :tpl .CreatedBy ,
16141665OrganizationID :tpl .OrganizationID ,
1666+ }
1667+ setJobStatus (t ,args .Status ,& latestJob )
1668+ latestJob = dbgen .ProvisionerJob (t ,db ,nil ,latestJob )
1669+ latestResource := dbgen .WorkspaceResource (t ,db , database.WorkspaceResource {
1670+ JobID :latestJob .ID ,
16151671})
16161672dbgen .WorkspaceBuild (t ,db , database.WorkspaceBuild {
16171673WorkspaceID :wrk .ID ,
16181674TemplateVersionID :version .ID ,
16191675BuildNumber :1 ,
16201676Transition :trans ,
16211677InitiatorID :tpl .CreatedBy ,
1622- JobID :buildJob .ID ,
1678+ JobID :latestJob .ID ,
16231679})
1680+ for i := 0 ;i < args .ExtraBuilds ;i ++ {
1681+ latestJob = database.ProvisionerJob {
1682+ Type :database .ProvisionerJobTypeWorkspaceBuild ,
1683+ InitiatorID :tpl .CreatedBy ,
1684+ OrganizationID :tpl .OrganizationID ,
1685+ }
1686+ setJobStatus (t ,args .Status ,& latestJob )
1687+ latestJob = dbgen .ProvisionerJob (t ,db ,nil ,latestJob )
1688+ latestResource = dbgen .WorkspaceResource (t ,db , database.WorkspaceResource {
1689+ JobID :latestJob .ID ,
1690+ })
1691+ dbgen .WorkspaceBuild (t ,db , database.WorkspaceBuild {
1692+ WorkspaceID :wrk .ID ,
1693+ TemplateVersionID :version .ID ,
1694+ BuildNumber :int32 (i )+ 2 ,
1695+ Transition :trans ,
1696+ InitiatorID :tpl .CreatedBy ,
1697+ JobID :latestJob .ID ,
1698+ })
1699+ }
1700+
1701+ if args .CreateAgent {
1702+ dbgen .WorkspaceAgent (t ,db , database.WorkspaceAgent {
1703+ ResourceID :latestResource .ID ,
1704+ })
1705+ }
1706+ for i := 0 ;i < args .ExtraAgents ;i ++ {
1707+ dbgen .WorkspaceAgent (t ,db , database.WorkspaceAgent {
1708+ ResourceID :latestResource .ID ,
1709+ })
1710+ }
16241711}
16251712return version
16261713}
16271714
1715+ func setJobStatus (t testing.TB ,status database.ProvisionerJobStatus ,j * database.ProvisionerJob ) {
1716+ t .Helper ()
1717+
1718+ earlier := sql.NullTime {
1719+ Time :dbtime .Now ().Add (time .Second * - 30 ),
1720+ Valid :true ,
1721+ }
1722+ now := sql.NullTime {
1723+ Time :dbtime .Now (),
1724+ Valid :true ,
1725+ }
1726+ switch status {
1727+ case database .ProvisionerJobStatusRunning :
1728+ j .StartedAt = earlier
1729+ case database .ProvisionerJobStatusPending :
1730+ case database .ProvisionerJobStatusFailed :
1731+ j .StartedAt = earlier
1732+ j .CompletedAt = now
1733+ j .Error = sql.NullString {
1734+ String :"failed" ,
1735+ Valid :true ,
1736+ }
1737+ j .ErrorCode = sql.NullString {
1738+ String :"failed" ,
1739+ Valid :true ,
1740+ }
1741+ case database .ProvisionerJobStatusSucceeded :
1742+ j .StartedAt = earlier
1743+ j .CompletedAt = now
1744+ default :
1745+ t .Fatalf ("invalid status: %s" ,status )
1746+ }
1747+ }
1748+
16281749func TestArchiveVersions (t * testing.T ) {
16291750t .Parallel ()
16301751if testing .Short () {