Skip to content

Commit 7877776

Browse files
committed
fix: use injected now() instead of time.Now() in summary methods
Signed-off-by: Ivan Goncharov <[email protected]>
1 parent d3f2840 commit 7877776

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

prometheus/summary.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
243243

244244
s := &summary{
245245
desc: desc,
246+
now: opts.now,
246247

247248
objectives: opts.Objectives,
248249
sortedObjectives: make([]float64, 0, len(opts.Objectives)),
@@ -280,6 +281,8 @@ type summary struct {
280281

281282
desc *Desc
282283

284+
now func() time.Time
285+
283286
objectives map[float64]float64
284287
sortedObjectives []float64
285288

@@ -307,7 +310,7 @@ func (s *summary) Observe(v float64) {
307310
s.bufMtx.Lock()
308311
defer s.bufMtx.Unlock()
309312

310-
now := time.Now()
313+
now := s.now()
311314
if now.After(s.hotBufExpTime) {
312315
s.asyncFlush(now)
313316
}
@@ -326,7 +329,7 @@ func (s *summary) Write(out *dto.Metric) error {
326329
s.bufMtx.Lock()
327330
s.mtx.Lock()
328331
// Swap bufs even if hotBuf is empty to set new hotBufExpTime.
329-
s.swapBufs(time.Now())
332+
s.swapBufs(s.now())
330333
s.bufMtx.Unlock()
331334

332335
s.flushColdBuf()

prometheus/summary_test.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -373,37 +373,38 @@ func TestSummaryVecConcurrency(t *testing.T) {
373373
func TestSummaryDecay(t *testing.T) {
374374
if testing.Short() {
375375
t.Skip("Skipping test in short mode.")
376-
// More because it depends on timing than because it is particularly long...
377376
}
378377

378+
now := time.Now()
379+
379380
sum := NewSummary(SummaryOpts{
380381
Name: "test_summary",
381382
Help: "helpless",
382383
MaxAge: 100 * time.Millisecond,
383384
Objectives: map[float64]float64{0.1: 0.001},
384385
AgeBuckets: 10,
386+
now: func() time.Time {
387+
return now
388+
},
385389
})
386390

387391
m := &dto.Metric{}
388-
i := 0
389-
tick := time.NewTicker(time.Millisecond)
390-
for range tick.C {
391-
i++
392+
for i := 1; i <= 1000; i++ {
393+
now = now.Add(time.Millisecond)
392394
sum.Observe(float64(i))
393395
if i%10 == 0 {
394396
sum.Write(m)
395-
if got, want := *m.Summary.Quantile[0].Value, math.Max(float64(i)/10, float64(i-90)); math.Abs(got-want) > 20 {
397+
got := *m.Summary.Quantile[0].Value
398+
want := math.Max(float64(i)/10, float64(i-90))
399+
if math.Abs(got-want) > 20 {
396400
t.Errorf("%d. got %f, want %f", i, got, want)
397401
}
398402
m.Reset()
399403
}
400-
if i >= 1000 {
401-
break
402-
}
403404
}
404-
tick.Stop()
405-
// Wait for MaxAge without observations and make sure quantiles are NaN.
406-
time.Sleep(100 * time.Millisecond)
405+
406+
// Simulate waiting for MaxAge without observations
407+
now = now.Add(100 * time.Millisecond)
407408
sum.Write(m)
408409
if got := *m.Summary.Quantile[0].Value; !math.IsNaN(got) {
409410
t.Errorf("got %f, want NaN after expiration", got)

0 commit comments

Comments
 (0)