@@ -5021,3 +5021,145 @@ func requireUsersMatch(t testing.TB, expected []database.User, found []database.
5021
5021
t .Helper ()
5022
5022
require .ElementsMatch (t ,expected ,database .ConvertUserRows (found ),msg )
5023
5023
}
5024
+
5025
+ // TestGetRunningPrebuiltWorkspaces ensures the correct behavior of the
5026
+ // GetRunningPrebuiltWorkspaces query.
5027
+ func TestGetRunningPrebuiltWorkspaces (t * testing.T ) {
5028
+ t .Parallel ()
5029
+
5030
+ if ! dbtestutil .WillUsePostgres () {
5031
+ t .Skip ("Test requires PostgreSQL for complex queries" )
5032
+ }
5033
+
5034
+ ctx := testutil .Context (t ,testutil .WaitLong )
5035
+ db ,_ := dbtestutil .NewDB (t )
5036
+
5037
+ // Given: a prebuilt workspace with a successful start build and a stop build.
5038
+ org := dbgen .Organization (t ,db , database.Organization {})
5039
+ user := dbgen .User (t ,db , database.User {})
5040
+ template := dbgen .Template (t ,db , database.Template {
5041
+ CreatedBy :user .ID ,
5042
+ OrganizationID :org .ID ,
5043
+ })
5044
+ templateVersion := dbgen .TemplateVersion (t ,db , database.TemplateVersion {
5045
+ TemplateID : uuid.NullUUID {UUID :template .ID ,Valid :true },
5046
+ OrganizationID :org .ID ,
5047
+ CreatedBy :user .ID ,
5048
+ })
5049
+ preset := dbgen .Preset (t ,db , database.InsertPresetParams {
5050
+ TemplateVersionID :templateVersion .ID ,
5051
+ DesiredInstances : sql.NullInt32 {Int32 :1 ,Valid :true },
5052
+ })
5053
+
5054
+ // Create a prebuild workspace (owned by system user)
5055
+ prebuildSystemUser := uuid .MustParse ("c42fdf75-3097-471c-8c33-fb52454d81c0" )
5056
+ stoppedPrebuild := dbgen .Workspace (t ,db , database.WorkspaceTable {
5057
+ OwnerID :prebuildSystemUser ,
5058
+ TemplateID :template .ID ,
5059
+ Name :"test-prebuild" ,
5060
+ Deleted :false ,
5061
+ })
5062
+
5063
+ // Create a successful START build
5064
+ stoppedPrebuildJob1 := dbgen .ProvisionerJob (t ,db ,nil , database.ProvisionerJob {
5065
+ OrganizationID :org .ID ,
5066
+ InitiatorID :database .PrebuildsSystemUserID ,
5067
+ Provisioner :database .ProvisionerTypeEcho ,
5068
+ Type :database .ProvisionerJobTypeWorkspaceBuild ,
5069
+ StartedAt : sql.NullTime {Time :dbtime .Now ().Add (- time .Minute ),Valid :true },
5070
+ CompletedAt : sql.NullTime {Time :dbtime .Now (),Valid :true },
5071
+ Error : sql.NullString {},
5072
+ ErrorCode : sql.NullString {},
5073
+ })
5074
+ stoppedPrebuiltWorkspaceBuild1 := dbgen .WorkspaceBuild (t ,db , database.WorkspaceBuild {
5075
+ WorkspaceID :stoppedPrebuild .ID ,
5076
+ TemplateVersionID :templateVersion .ID ,
5077
+ TemplateVersionPresetID : uuid.NullUUID {UUID :preset .ID ,Valid :true },
5078
+ JobID :stoppedPrebuildJob1 .ID ,
5079
+ BuildNumber :1 ,
5080
+ Transition :database .WorkspaceTransitionStart ,
5081
+ InitiatorID :database .PrebuildsSystemUserID ,
5082
+ Reason :database .BuildReasonInitiator ,
5083
+ })
5084
+
5085
+ // Create a STOP build (making this prebuild "not running")
5086
+ stoppedPrebuildWorkspaceJob2 := dbgen .ProvisionerJob (t ,db ,nil , database.ProvisionerJob {
5087
+ OrganizationID :org .ID ,
5088
+ InitiatorID :database .PrebuildsSystemUserID ,
5089
+ Provisioner :database .ProvisionerTypeEcho ,
5090
+ Type :database .ProvisionerJobTypeWorkspaceBuild ,
5091
+ StartedAt : sql.NullTime {Time :dbtime .Now ().Add (- time .Minute ),Valid :true },
5092
+ CompletedAt : sql.NullTime {Time :dbtime .Now (),Valid :true },
5093
+ Error : sql.NullString {},
5094
+ ErrorCode : sql.NullString {},
5095
+ })
5096
+ stoppedPrebuiltWorkspaceBuild2 := dbgen .WorkspaceBuild (t ,db , database.WorkspaceBuild {
5097
+ WorkspaceID :stoppedPrebuild .ID ,
5098
+ TemplateVersionID :templateVersion .ID ,
5099
+ TemplateVersionPresetID : uuid.NullUUID {UUID :preset .ID ,Valid :true },
5100
+ JobID :stoppedPrebuildWorkspaceJob2 .ID ,
5101
+ BuildNumber :2 ,
5102
+ Transition :database .WorkspaceTransitionStop ,
5103
+ InitiatorID :database .PrebuildsSystemUserID ,
5104
+ Reason :database .BuildReasonInitiator ,
5105
+ })
5106
+
5107
+ // Create a second running prebuild workspace with a successful start build
5108
+ // and no stop build.
5109
+ runningPrebuild := dbgen .Workspace (t ,db , database.WorkspaceTable {
5110
+ OwnerID :prebuildSystemUser ,
5111
+ TemplateID :template .ID ,
5112
+ Name :"test-running-prebuild" ,
5113
+ Deleted :false ,
5114
+ })
5115
+ // Create a successful START build for the running prebuild workspace
5116
+ runningPrebuildJob1 := dbgen .ProvisionerJob (t ,db ,nil ,
5117
+ database.ProvisionerJob {
5118
+ OrganizationID :org .ID ,
5119
+ InitiatorID :user .ID ,
5120
+ Provisioner :database .ProvisionerTypeEcho ,
5121
+ Type :database .ProvisionerJobTypeWorkspaceBuild ,
5122
+ StartedAt : sql.NullTime {Time :dbtime .Now ().Add (- time .Minute ),Valid :true },
5123
+ CompletedAt : sql.NullTime {Time :dbtime .Now (),Valid :true },
5124
+ Error : sql.NullString {},
5125
+ ErrorCode : sql.NullString {},
5126
+ })
5127
+ runningPrebuiltWorkspaceBuild1 := dbgen .WorkspaceBuild (t ,db , database.WorkspaceBuild {
5128
+ WorkspaceID :runningPrebuild .ID ,
5129
+ TemplateVersionID :templateVersion .ID ,
5130
+ TemplateVersionPresetID : uuid.NullUUID {UUID :preset .ID ,Valid :true },
5131
+ JobID :runningPrebuildJob1 .ID ,
5132
+ BuildNumber :1 ,
5133
+ Transition :database .WorkspaceTransitionStart ,
5134
+ InitiatorID :database .PrebuildsSystemUserID ,
5135
+ Reason :database .BuildReasonInitiator ,
5136
+ })
5137
+
5138
+ // Create a third running regular workspace (not a prebuild) with a successful
5139
+ // start build.
5140
+ _ = dbgen .Workspace (t ,db , database.WorkspaceTable {
5141
+ OwnerID :user .ID ,
5142
+ TemplateID :template .ID ,
5143
+ Name :"test-running-regular-workspace" ,
5144
+ Deleted :false ,
5145
+ })
5146
+
5147
+ // Given: assert test invariants.
5148
+ require .Equal (t ,database .WorkspaceTransitionStart ,stoppedPrebuiltWorkspaceBuild1 .Transition )
5149
+ require .Equal (t ,int32 (1 ),stoppedPrebuiltWorkspaceBuild1 .BuildNumber )
5150
+ require .Equal (t ,database .ProvisionerJobStatusSucceeded ,stoppedPrebuildJob1 .JobStatus )
5151
+ require .Equal (t ,database .WorkspaceTransitionStop ,stoppedPrebuiltWorkspaceBuild2 .Transition )
5152
+ require .Equal (t ,int32 (2 ),stoppedPrebuiltWorkspaceBuild2 .BuildNumber )
5153
+ require .Equal (t ,database .ProvisionerJobStatusSucceeded ,stoppedPrebuildWorkspaceJob2 .JobStatus )
5154
+ require .Equal (t ,database .WorkspaceTransitionStart ,runningPrebuiltWorkspaceBuild1 .Transition )
5155
+ require .Equal (t ,int32 (1 ),runningPrebuiltWorkspaceBuild1 .BuildNumber )
5156
+ require .Equal (t ,database .ProvisionerJobStatusSucceeded ,runningPrebuildJob1 .JobStatus )
5157
+
5158
+ // When: we query for running prebuild workspaces
5159
+ runningPrebuilds ,err := db .GetRunningPrebuiltWorkspaces (ctx )
5160
+ require .NoError (t ,err )
5161
+
5162
+ // Then: the stopped prebuild workspace should not be returned.
5163
+ require .Len (t ,runningPrebuilds ,1 ,"expected only one running prebuilt workspace" )
5164
+ require .Equal (t ,runningPrebuild .ID ,runningPrebuilds [0 ].ID ,"expected the running prebuilt workspace to be returned" )
5165
+ }