@@ -45,25 +45,26 @@ func TestMetricsCollector(t *testing.T) {
4545 ownerIDs []uuid.UUID
4646 metrics []metricCheck
4747 templateDeleted []bool
48+ eligible []bool
4849 }
4950
5051 tests := []testCase {
5152 {
52- name : "prebuild created " ,
53+ name : "prebuild provisioned but not completed " ,
5354 transitions : allTransitions ,
54- jobStatuses : allJobStatuses ,
55+ jobStatuses : allJobStatusesExcept ( database . ProvisionerJobStatusPending , database . ProvisionerJobStatusRunning , database . ProvisionerJobStatusCanceling ) ,
5556 initiatorIDs : []uuid.UUID {agplprebuilds .SystemUserID },
56- // TODO: reexamine and refactor the test cases and assertions:
57- // * a running prebuild that is not elibible to be claimed currently seems to be eligible.
58- // * a prebuild that was claimed should not be deemed running, not eligible.
59- ownerIDs : []uuid.UUID {agplprebuilds .SystemUserID , uuid .New ()},
57+ ownerIDs : []uuid.UUID {agplprebuilds .SystemUserID },
6058 metrics : []metricCheck {
6159 {"coderd_prebuilt_workspaces_created_total" , ptr .To (1.0 ), true },
60+ {"coderd_prebuilt_workspaces_claimed_total" , ptr .To (0.0 ), true },
61+ {"coderd_prebuilt_workspaces_failed_total" , ptr .To (0.0 ), true },
6262 {"coderd_prebuilt_workspaces_desired" , ptr .To (1.0 ), false },
6363 {"coderd_prebuilt_workspaces_running" , ptr .To (0.0 ), false },
6464 {"coderd_prebuilt_workspaces_eligible" , ptr .To (0.0 ), false },
6565 },
6666 templateDeleted : []bool {false },
67+ eligible : []bool {false },
6768 },
6869 {
6970 name : "prebuild running" ,
@@ -73,11 +74,14 @@ func TestMetricsCollector(t *testing.T) {
7374 ownerIDs : []uuid.UUID {agplprebuilds .SystemUserID },
7475 metrics : []metricCheck {
7576 {"coderd_prebuilt_workspaces_created_total" , ptr .To (1.0 ), true },
77+ {"coderd_prebuilt_workspaces_claimed_total" , ptr .To (0.0 ), true },
78+ {"coderd_prebuilt_workspaces_failed_total" , ptr .To (0.0 ), true },
7679 {"coderd_prebuilt_workspaces_desired" , ptr .To (1.0 ), false },
7780 {"coderd_prebuilt_workspaces_running" , ptr .To (1.0 ), false },
7881 {"coderd_prebuilt_workspaces_eligible" , ptr .To (0.0 ), false },
7982 },
8083 templateDeleted : []bool {false },
84+ eligible : []bool {false },
8185 },
8286 {
8387 name : "prebuild failed" ,
@@ -93,6 +97,41 @@ func TestMetricsCollector(t *testing.T) {
9397 {"coderd_prebuilt_workspaces_eligible" , ptr .To (0.0 ), false },
9498 },
9599 templateDeleted : []bool {false },
100+ eligible : []bool {false },
101+ },
102+ {
103+ name : "prebuild eligible" ,
104+ transitions : []database.WorkspaceTransition {database .WorkspaceTransitionStart },
105+ jobStatuses : []database.ProvisionerJobStatus {database .ProvisionerJobStatusSucceeded },
106+ initiatorIDs : []uuid.UUID {agplprebuilds .SystemUserID },
107+ ownerIDs : []uuid.UUID {agplprebuilds .SystemUserID },
108+ metrics : []metricCheck {
109+ {"coderd_prebuilt_workspaces_created_total" , ptr .To (1.0 ), true },
110+ {"coderd_prebuilt_workspaces_claimed_total" , ptr .To (0.0 ), true },
111+ {"coderd_prebuilt_workspaces_failed_total" , ptr .To (0.0 ), true },
112+ {"coderd_prebuilt_workspaces_desired" , ptr .To (1.0 ), false },
113+ {"coderd_prebuilt_workspaces_running" , ptr .To (1.0 ), false },
114+ {"coderd_prebuilt_workspaces_eligible" , ptr .To (1.0 ), false },
115+ },
116+ templateDeleted : []bool {false },
117+ eligible : []bool {true },
118+ },
119+ {
120+ name : "prebuild ineligible" ,
121+ transitions : allTransitions ,
122+ jobStatuses : allJobStatusesExcept (database .ProvisionerJobStatusSucceeded ),
123+ initiatorIDs : []uuid.UUID {agplprebuilds .SystemUserID },
124+ ownerIDs : []uuid.UUID {agplprebuilds .SystemUserID },
125+ metrics : []metricCheck {
126+ {"coderd_prebuilt_workspaces_created_total" , ptr .To (1.0 ), true },
127+ {"coderd_prebuilt_workspaces_claimed_total" , ptr .To (0.0 ), true },
128+ {"coderd_prebuilt_workspaces_failed_total" , ptr .To (0.0 ), true },
129+ {"coderd_prebuilt_workspaces_desired" , ptr .To (1.0 ), false },
130+ {"coderd_prebuilt_workspaces_running" , ptr .To (1.0 ), false },
131+ {"coderd_prebuilt_workspaces_eligible" , ptr .To (0.0 ), false },
132+ },
133+ templateDeleted : []bool {false },
134+ eligible : []bool {false },
96135 },
97136 {
98137 name : "prebuild claimed" ,
@@ -108,6 +147,7 @@ func TestMetricsCollector(t *testing.T) {
108147 {"coderd_prebuilt_workspaces_eligible" , ptr .To (0.0 ), false },
109148 },
110149 templateDeleted : []bool {false },
150+ eligible : []bool {false },
111151 },
112152 {
113153 name : "workspaces that were not created by the prebuilds user are not counted" ,
@@ -121,6 +161,7 @@ func TestMetricsCollector(t *testing.T) {
121161 {"coderd_prebuilt_workspaces_eligible" , ptr .To (0.0 ), false },
122162 },
123163 templateDeleted : []bool {false },
164+ eligible : []bool {false },
124165 },
125166 {
126167 name : "deleted templates never desire prebuilds" ,
@@ -132,6 +173,7 @@ func TestMetricsCollector(t *testing.T) {
132173 {"coderd_prebuilt_workspaces_desired" , ptr .To (0.0 ), false },
133174 },
134175 templateDeleted : []bool {true },
176+ eligible : []bool {false },
135177 },
136178 {
137179 name : "running prebuilds for deleted templates are still counted, so that they can be deleted" ,
@@ -144,6 +186,7 @@ func TestMetricsCollector(t *testing.T) {
144186 {"coderd_prebuilt_workspaces_eligible" , ptr .To (0.0 ), false },
145187 },
146188 templateDeleted : []bool {true },
189+ eligible : []bool {false },
147190 },
148191 }
149192 for _ , test := range tests {
@@ -158,95 +201,99 @@ func TestMetricsCollector(t *testing.T) {
158201 ownerID := ownerID // capture for parallel
159202 for _ , templateDeleted := range test .templateDeleted {
160203 templateDeleted := templateDeleted // capture for parallel
161- t .Run (fmt .Sprintf ("%v/transition:%s/jobStatus:%s" , test .name , transition , jobStatus ), func (t * testing.T ) {
162- t .Parallel ()
204+ for _ , eligible := range test .eligible {
205+ eligible := eligible // capture for parallel
206+ t .Run (fmt .Sprintf ("%v/transition:%s/jobStatus:%s" , test .name , transition , jobStatus ), func (t * testing.T ) {
207+ t .Parallel ()
163208
164- logger := slogtest .Make (t , & slogtest.Options {IgnoreErrors : true })
165- t .Cleanup (func () {
166- if t .Failed () {
167- t .Logf ("failed to run test: %s" , test .name )
168- t .Logf ("transition: %s" , transition )
169- t .Logf ("jobStatus: %s" , jobStatus )
170- t .Logf ("initiatorID: %s" , initiatorID )
171- t .Logf ("ownerID: %s" , ownerID )
172- t .Logf ("templateDeleted: %t" , templateDeleted )
173- }
174- })
175- clock := quartz .NewMock (t )
176- db , pubsub := dbtestutil .NewDB (t )
177- reconciler := prebuilds .NewStoreReconciler (db , pubsub , codersdk.PrebuildsConfig {}, logger , quartz .NewMock (t ), prometheus .NewRegistry ())
178- ctx := testutil .Context (t , testutil .WaitLong )
209+ logger := slogtest .Make (t , & slogtest.Options {IgnoreErrors : true })
210+ t .Cleanup (func () {
211+ if t .Failed () {
212+ t .Logf ("failed to run test: %s" , test .name )
213+ t .Logf ("transition: %s" , transition )
214+ t .Logf ("jobStatus: %s" , jobStatus )
215+ t .Logf ("initiatorID: %s" , initiatorID )
216+ t .Logf ("ownerID: %s" , ownerID )
217+ t .Logf ("templateDeleted: %t" , templateDeleted )
218+ }
219+ })
220+ clock := quartz .NewMock (t )
221+ db , pubsub := dbtestutil .NewDB (t )
222+ reconciler := prebuilds .NewStoreReconciler (db , pubsub , codersdk.PrebuildsConfig {}, logger , quartz .NewMock (t ), prometheus .NewRegistry ())
223+ ctx := testutil .Context (t , testutil .WaitLong )
179224
180- createdUsers := []uuid.UUID {agplprebuilds .SystemUserID }
181- for _ , user := range slices .Concat (test .ownerIDs , test .initiatorIDs ) {
182- if ! slices .Contains (createdUsers , user ) {
183- dbgen .User (t , db , database.User {
184- ID : user ,
185- })
186- createdUsers = append (createdUsers , user )
225+ createdUsers := []uuid.UUID {agplprebuilds .SystemUserID }
226+ for _ , user := range slices .Concat (test .ownerIDs , test .initiatorIDs ) {
227+ if ! slices .Contains (createdUsers , user ) {
228+ dbgen .User (t , db , database.User {
229+ ID : user ,
230+ })
231+ createdUsers = append (createdUsers , user )
232+ }
187233 }
188- }
189234
190- collector := prebuilds .NewMetricsCollector (db , logger , reconciler )
191- registry := prometheus .NewPedanticRegistry ()
192- registry .Register (collector )
235+ collector := prebuilds .NewMetricsCollector (db , logger , reconciler )
236+ registry := prometheus .NewPedanticRegistry ()
237+ registry .Register (collector )
193238
194- numTemplates := 2
195- for i := 0 ; i < numTemplates ; i ++ {
196- org , template := setupTestDBTemplate (t , db , ownerID , templateDeleted )
197- templateVersionID := setupTestDBTemplateVersion (ctx , t , clock , db , pubsub , org .ID , ownerID , template .ID )
198- preset := setupTestDBPreset (t , db , templateVersionID , 1 , uuid .New ().String ())
199- setupTestDBWorkspace (
200- t , clock , db , pubsub ,
201- transition , jobStatus , org .ID , preset , template .ID , templateVersionID , initiatorID , ownerID ,
202- )
203- }
204-
205- metricsFamilies , err := registry .Gather ()
206- require .NoError (t , err )
207-
208- templates , err := db .GetTemplates (ctx )
209- require .NoError (t , err )
210- require .Equal (t , numTemplates , len (templates ))
239+ numTemplates := 2
240+ for i := 0 ; i < numTemplates ; i ++ {
241+ org , template := setupTestDBTemplate (t , db , ownerID , templateDeleted )
242+ templateVersionID := setupTestDBTemplateVersion (ctx , t , clock , db , pubsub , org .ID , ownerID , template .ID )
243+ preset := setupTestDBPreset (t , db , templateVersionID , 1 , uuid .New ().String ())
244+ workspace := setupTestDBWorkspace (
245+ t , clock , db , pubsub ,
246+ transition , jobStatus , org .ID , preset , template .ID , templateVersionID , initiatorID , ownerID ,
247+ )
248+ setupTestDBWorkspaceAgent (t , db , workspace .ID , eligible )
249+ }
211250
212- for _ , template := range templates {
213- org , err := db .GetOrganizationByID (ctx , template .OrganizationID )
214- require .NoError (t , err )
215- templateVersions , err := db .GetTemplateVersionsByTemplateID (ctx , database.GetTemplateVersionsByTemplateIDParams {
216- TemplateID : template .ID ,
217- })
251+ metricsFamilies , err := registry .Gather ()
218252 require .NoError (t , err )
219- require .Equal (t , 1 , len (templateVersions ))
220253
221- presets , err := db .GetPresetsByTemplateVersionID (ctx , templateVersions [ 0 ]. ID )
254+ templates , err := db .GetTemplates (ctx )
222255 require .NoError (t , err )
223- require .Equal (t , 1 , len (presets ))
256+ require .Equal (t , numTemplates , len (templates ))
224257
225- for _ , preset := range presets {
226- preset := preset // capture for parallel
227- labels := map [string ]string {
228- "template_name" : template .Name ,
229- "preset_name" : preset .Name ,
230- "organization_name" : org .Name ,
231- }
258+ for _ , template := range templates {
259+ org , err := db .GetOrganizationByID (ctx , template .OrganizationID )
260+ require .NoError (t , err )
261+ templateVersions , err := db .GetTemplateVersionsByTemplateID (ctx , database.GetTemplateVersionsByTemplateIDParams {
262+ TemplateID : template .ID ,
263+ })
264+ require .NoError (t , err )
265+ require .Equal (t , 1 , len (templateVersions ))
266+
267+ presets , err := db .GetPresetsByTemplateVersionID (ctx , templateVersions [0 ].ID )
268+ require .NoError (t , err )
269+ require .Equal (t , 1 , len (presets ))
232270
233- for _ , check := range test .metrics {
234- metric := findMetric (metricsFamilies , check .name , labels )
235- if check .value == nil {
236- continue
271+ for _ , preset := range presets {
272+ preset := preset // capture for parallel
273+ labels := map [string ]string {
274+ "template_name" : template .Name ,
275+ "preset_name" : preset .Name ,
276+ "organization_name" : org .Name ,
237277 }
238278
239- require .NotNil (t , metric , "metric %s should exist" , check .name )
279+ for _ , check := range test .metrics {
280+ metric := findMetric (metricsFamilies , check .name , labels )
281+ if check .value == nil {
282+ continue
283+ }
240284
241- if check .isCounter {
242- require .Equal (t , * check .value , metric .GetCounter ().GetValue (), "counter %s value mismatch" , check .name )
243- } else {
244- require .Equal (t , * check .value , metric .GetGauge ().GetValue (), "gauge %s value mismatch" , check .name )
285+ require .NotNil (t , metric , "metric %s should exist" , check .name )
286+
287+ if check .isCounter {
288+ require .Equal (t , * check .value , metric .GetCounter ().GetValue (), "counter %s value mismatch" , check .name )
289+ } else {
290+ require .Equal (t , * check .value , metric .GetGauge ().GetValue (), "gauge %s value mismatch" , check .name )
291+ }
245292 }
246293 }
247294 }
248- }
249- })
295+ })
296+ }
250297 }
251298 }
252299 }
0 commit comments