@@ -45,25 +45,26 @@ func TestMetricsCollector(t *testing.T) {
45
45
ownerIDs []uuid.UUID
46
46
metrics []metricCheck
47
47
templateDeleted []bool
48
+ eligible []bool
48
49
}
49
50
50
51
tests := []testCase {
51
52
{
52
- name :"prebuildcreated " ,
53
+ name :"prebuildprovisioned but not completed " ,
53
54
transitions :allTransitions ,
54
- jobStatuses :allJobStatuses ,
55
+ jobStatuses :allJobStatusesExcept ( database . ProvisionerJobStatusPending , database . ProvisionerJobStatusRunning , database . ProvisionerJobStatusCanceling ) ,
55
56
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 },
60
58
metrics : []metricCheck {
61
59
{"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 },
62
62
{"coderd_prebuilt_workspaces_desired" ,ptr .To (1.0 ),false },
63
63
{"coderd_prebuilt_workspaces_running" ,ptr .To (0.0 ),false },
64
64
{"coderd_prebuilt_workspaces_eligible" ,ptr .To (0.0 ),false },
65
65
},
66
66
templateDeleted : []bool {false },
67
+ eligible : []bool {false },
67
68
},
68
69
{
69
70
name :"prebuild running" ,
@@ -73,11 +74,14 @@ func TestMetricsCollector(t *testing.T) {
73
74
ownerIDs : []uuid.UUID {agplprebuilds .SystemUserID },
74
75
metrics : []metricCheck {
75
76
{"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 },
76
79
{"coderd_prebuilt_workspaces_desired" ,ptr .To (1.0 ),false },
77
80
{"coderd_prebuilt_workspaces_running" ,ptr .To (1.0 ),false },
78
81
{"coderd_prebuilt_workspaces_eligible" ,ptr .To (0.0 ),false },
79
82
},
80
83
templateDeleted : []bool {false },
84
+ eligible : []bool {false },
81
85
},
82
86
{
83
87
name :"prebuild failed" ,
@@ -93,6 +97,41 @@ func TestMetricsCollector(t *testing.T) {
93
97
{"coderd_prebuilt_workspaces_eligible" ,ptr .To (0.0 ),false },
94
98
},
95
99
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 },
96
135
},
97
136
{
98
137
name :"prebuild claimed" ,
@@ -108,6 +147,7 @@ func TestMetricsCollector(t *testing.T) {
108
147
{"coderd_prebuilt_workspaces_eligible" ,ptr .To (0.0 ),false },
109
148
},
110
149
templateDeleted : []bool {false },
150
+ eligible : []bool {false },
111
151
},
112
152
{
113
153
name :"workspaces that were not created by the prebuilds user are not counted" ,
@@ -121,6 +161,7 @@ func TestMetricsCollector(t *testing.T) {
121
161
{"coderd_prebuilt_workspaces_eligible" ,ptr .To (0.0 ),false },
122
162
},
123
163
templateDeleted : []bool {false },
164
+ eligible : []bool {false },
124
165
},
125
166
{
126
167
name :"deleted templates never desire prebuilds" ,
@@ -132,6 +173,7 @@ func TestMetricsCollector(t *testing.T) {
132
173
{"coderd_prebuilt_workspaces_desired" ,ptr .To (0.0 ),false },
133
174
},
134
175
templateDeleted : []bool {true },
176
+ eligible : []bool {false },
135
177
},
136
178
{
137
179
name :"running prebuilds for deleted templates are still counted, so that they can be deleted" ,
@@ -144,6 +186,7 @@ func TestMetricsCollector(t *testing.T) {
144
186
{"coderd_prebuilt_workspaces_eligible" ,ptr .To (0.0 ),false },
145
187
},
146
188
templateDeleted : []bool {true },
189
+ eligible : []bool {false },
147
190
},
148
191
}
149
192
for _ ,test := range tests {
@@ -158,95 +201,99 @@ func TestMetricsCollector(t *testing.T) {
158
201
ownerID := ownerID // capture for parallel
159
202
for _ ,templateDeleted := range test .templateDeleted {
160
203
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 ()
163
208
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 )
179
224
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
+ }
187
233
}
188
- }
189
234
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 )
193
238
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
+ }
211
250
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 ()
218
252
require .NoError (t ,err )
219
- require .Equal (t ,1 ,len (templateVersions ))
220
253
221
- presets ,err := db .GetPresetsByTemplateVersionID (ctx , templateVersions [ 0 ]. ID )
254
+ templates ,err := db .GetTemplates (ctx )
222
255
require .NoError (t ,err )
223
- require .Equal (t ,1 ,len (presets ))
256
+ require .Equal (t ,numTemplates ,len (templates ))
224
257
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 ))
232
270
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 ,
237
277
}
238
278
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
+ }
240
284
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
+ }
245
292
}
246
293
}
247
294
}
248
- }
249
- })
295
+ })
296
+ }
250
297
}
251
298
}
252
299
}