@@ -205,14 +205,20 @@ func TestCache_BuildTime(t *testing.T) {
205205t .Run (tt .name ,func (t * testing.T ) {
206206t .Parallel ()
207207
208+ ctx := testutil .Context (t ,testutil .WaitShort )
209+
208210var (
209- log = testutil .Logger (t )
210- clock = quartz .NewMock (t )
211- cache ,db = newMetricsCache (t ,log ,clock , metricscache.Intervals {
212- TemplateBuildTimes :testutil .IntervalFast ,
213- },false )
211+ log = testutil .Logger (t )
212+ clock = quartz .NewMock (t )
214213)
215214
215+ trapTickerFunc := clock .Trap ().TickerFunc ("metricscache" )
216+
217+ defer trapTickerFunc .Close ()
218+ cache ,db := newMetricsCache (t ,log ,clock , metricscache.Intervals {
219+ TemplateBuildTimes :testutil .IntervalFast ,
220+ },false )
221+
216222clock .Set (someDay )
217223
218224org := dbgen .Organization (t ,db , database.Organization {})
@@ -257,17 +263,20 @@ func TestCache_BuildTime(t *testing.T) {
257263})
258264}
259265
266+ // Wait for both ticker functions to be created (template build times and deployment stats)
267+ trapTickerFunc .MustWait (ctx ).MustRelease (ctx )
268+ trapTickerFunc .MustWait (ctx ).MustRelease (ctx )
269+
270+ _ ,wait := clock .AdvanceNext ()
271+ wait .MustWait (ctx )
272+
260273if tt .want .loads {
261274wantTransition := codersdk .WorkspaceTransition (tt .args .transition )
262- require .Eventuallyf (t ,func ()bool {
263- stats := cache .TemplateBuildTimeStats (template .ID )
264- ts := stats [wantTransition ]
265- return ts .P50 != nil && * ts .P50 == tt .want .buildTimeMs
266- },testutil .WaitLong ,testutil .IntervalMedium ,
267- "P50 never reached expected value for %v" ,wantTransition ,
268- )
269-
270275gotStats := cache .TemplateBuildTimeStats (template .ID )
276+ ts := gotStats [wantTransition ]
277+ require .NotNil (t ,ts .P50 ,"P50 should be set for %v" ,wantTransition )
278+ require .Equal (t ,tt .want .buildTimeMs ,* ts .P50 ,"P50 should match expected value for %v" ,wantTransition )
279+
271280for transition ,ts := range gotStats {
272281if transition == wantTransition {
273282// Checked above
@@ -276,14 +285,8 @@ func TestCache_BuildTime(t *testing.T) {
276285require .Empty (t ,ts ,"%v" ,transition )
277286}
278287}else {
279- var stats codersdk.TemplateBuildTimeStats
280- require .Never (t ,func ()bool {
281- stats = cache .TemplateBuildTimeStats (template .ID )
282- requireBuildTimeStatsEmpty (t ,stats )
283- return t .Failed ()
284- },testutil .WaitShort / 2 ,testutil .IntervalMedium ,
285- "BuildTimeStats populated" ,stats ,
286- )
288+ stats := cache .TemplateBuildTimeStats (template .ID )
289+ requireBuildTimeStatsEmpty (t ,stats )
287290}
288291})
289292}
@@ -292,14 +295,21 @@ func TestCache_BuildTime(t *testing.T) {
292295func TestCache_DeploymentStats (t * testing.T ) {
293296t .Parallel ()
294297
298+ ctx := testutil .Context (t ,testutil .WaitShort )
299+
295300var (
296- log = testutil .Logger (t )
297- clock = quartz .NewMock (t )
298- cache ,db = newMetricsCache (t ,log ,clock , metricscache.Intervals {
299- DeploymentStats :testutil .IntervalFast ,
300- },false )
301+ log = testutil .Logger (t )
302+ clock = quartz .NewMock (t )
301303)
302304
305+ tickerTrap := clock .Trap ().TickerFunc ("metricscache" )
306+ defer tickerTrap .Close ()
307+
308+ cache ,db := newMetricsCache (t ,log ,clock , metricscache.Intervals {
309+ TemplateBuildTimes :testutil .IntervalFast ,
310+ DeploymentStats :testutil .IntervalFast ,
311+ },false )
312+
303313err := db .InsertWorkspaceAgentStats (context .Background (), database.InsertWorkspaceAgentStatsParams {
304314ID : []uuid.UUID {uuid .New ()},
305315CreatedAt : []time.Time {clock .Now ()},
@@ -323,11 +333,14 @@ func TestCache_DeploymentStats(t *testing.T) {
323333})
324334require .NoError (t ,err )
325335
326- var stat codersdk.DeploymentStats
327- require .Eventually (t ,func ()bool {
328- var ok bool
329- stat ,ok = cache .DeploymentStats ()
330- return ok
331- },testutil .WaitLong ,testutil .IntervalMedium )
336+ // Wait for both ticker functions to be created (template build times and deployment stats)
337+ tickerTrap .MustWait (ctx ).MustRelease (ctx )
338+ tickerTrap .MustWait (ctx ).MustRelease (ctx )
339+
340+ _ ,wait := clock .AdvanceNext ()
341+ wait .MustWait (ctx )
342+
343+ stat ,ok := cache .DeploymentStats ()
344+ require .True (t ,ok ,"cache should be populated after refresh" )
332345require .Equal (t ,int64 (1 ),stat .SessionCount .VSCode )
333346}