Merge pull request #1672 from imorph/fix_summary_decay2
fix: use injected now() instead of time.Now() in summary methods
This commit is contained in:
commit
0c73c1c554
|
@ -243,6 +243,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
|
||||||
|
|
||||||
s := &summary{
|
s := &summary{
|
||||||
desc: desc,
|
desc: desc,
|
||||||
|
now: opts.now,
|
||||||
|
|
||||||
objectives: opts.Objectives,
|
objectives: opts.Objectives,
|
||||||
sortedObjectives: make([]float64, 0, len(opts.Objectives)),
|
sortedObjectives: make([]float64, 0, len(opts.Objectives)),
|
||||||
|
@ -280,6 +281,8 @@ type summary struct {
|
||||||
|
|
||||||
desc *Desc
|
desc *Desc
|
||||||
|
|
||||||
|
now func() time.Time
|
||||||
|
|
||||||
objectives map[float64]float64
|
objectives map[float64]float64
|
||||||
sortedObjectives []float64
|
sortedObjectives []float64
|
||||||
|
|
||||||
|
@ -307,7 +310,7 @@ func (s *summary) Observe(v float64) {
|
||||||
s.bufMtx.Lock()
|
s.bufMtx.Lock()
|
||||||
defer s.bufMtx.Unlock()
|
defer s.bufMtx.Unlock()
|
||||||
|
|
||||||
now := time.Now()
|
now := s.now()
|
||||||
if now.After(s.hotBufExpTime) {
|
if now.After(s.hotBufExpTime) {
|
||||||
s.asyncFlush(now)
|
s.asyncFlush(now)
|
||||||
}
|
}
|
||||||
|
@ -326,7 +329,7 @@ func (s *summary) Write(out *dto.Metric) error {
|
||||||
s.bufMtx.Lock()
|
s.bufMtx.Lock()
|
||||||
s.mtx.Lock()
|
s.mtx.Lock()
|
||||||
// Swap bufs even if hotBuf is empty to set new hotBufExpTime.
|
// Swap bufs even if hotBuf is empty to set new hotBufExpTime.
|
||||||
s.swapBufs(time.Now())
|
s.swapBufs(s.now())
|
||||||
s.bufMtx.Unlock()
|
s.bufMtx.Unlock()
|
||||||
|
|
||||||
s.flushColdBuf()
|
s.flushColdBuf()
|
||||||
|
|
|
@ -371,10 +371,7 @@ func TestSummaryVecConcurrency(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSummaryDecay(t *testing.T) {
|
func TestSummaryDecay(t *testing.T) {
|
||||||
if testing.Short() {
|
now := time.Now()
|
||||||
t.Skip("Skipping test in short mode.")
|
|
||||||
// More because it depends on timing than because it is particularly long...
|
|
||||||
}
|
|
||||||
|
|
||||||
sum := NewSummary(SummaryOpts{
|
sum := NewSummary(SummaryOpts{
|
||||||
Name: "test_summary",
|
Name: "test_summary",
|
||||||
|
@ -382,28 +379,28 @@ func TestSummaryDecay(t *testing.T) {
|
||||||
MaxAge: 100 * time.Millisecond,
|
MaxAge: 100 * time.Millisecond,
|
||||||
Objectives: map[float64]float64{0.1: 0.001},
|
Objectives: map[float64]float64{0.1: 0.001},
|
||||||
AgeBuckets: 10,
|
AgeBuckets: 10,
|
||||||
|
now: func() time.Time {
|
||||||
|
return now
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
m := &dto.Metric{}
|
m := &dto.Metric{}
|
||||||
i := 0
|
for i := 1; i <= 1000; i++ {
|
||||||
tick := time.NewTicker(time.Millisecond)
|
now = now.Add(time.Millisecond)
|
||||||
for range tick.C {
|
|
||||||
i++
|
|
||||||
sum.Observe(float64(i))
|
sum.Observe(float64(i))
|
||||||
if i%10 == 0 {
|
if i%10 == 0 {
|
||||||
sum.Write(m)
|
sum.Write(m)
|
||||||
if got, want := *m.Summary.Quantile[0].Value, math.Max(float64(i)/10, float64(i-90)); math.Abs(got-want) > 20 {
|
got := *m.Summary.Quantile[0].Value
|
||||||
|
want := math.Max(float64(i)/10, float64(i-90))
|
||||||
|
if math.Abs(got-want) > 20 {
|
||||||
t.Errorf("%d. got %f, want %f", i, got, want)
|
t.Errorf("%d. got %f, want %f", i, got, want)
|
||||||
}
|
}
|
||||||
m.Reset()
|
m.Reset()
|
||||||
}
|
}
|
||||||
if i >= 1000 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tick.Stop()
|
|
||||||
// Wait for MaxAge without observations and make sure quantiles are NaN.
|
// Simulate waiting for MaxAge without observations
|
||||||
time.Sleep(100 * time.Millisecond)
|
now = now.Add(100 * time.Millisecond)
|
||||||
sum.Write(m)
|
sum.Write(m)
|
||||||
if got := *m.Summary.Quantile[0].Value; !math.IsNaN(got) {
|
if got := *m.Summary.Quantile[0].Value; !math.IsNaN(got) {
|
||||||
t.Errorf("got %f, want NaN after expiration", got)
|
t.Errorf("got %f, want NaN after expiration", got)
|
||||||
|
|
Loading…
Reference in New Issue