123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /*
- Copyright 2019 The Vitess Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package stats
- import (
- "expvar"
- "testing"
- "time"
- )
- // For tests, we want to control exactly the time used by Rates.
- // The way Rates works is:
- // - at creation, do a snapshot.
- // - every interval, do a snapshot.
- // So in these tests, we make sure to always call snapshot() every interval.
- // We do other actions after epsilon, but then wait for intervalMinusEpsilon
- // and call snapshot().
- const (
- interval = 1 * time.Second
- epsilon = 50 * time.Millisecond
- intervalMinusEpsilon = interval - epsilon
- )
- func TestRates(t *testing.T) {
- now := time.Now()
- timeNow = func() time.Time {
- return now
- }
- clear()
- c := NewCountersWithSingleLabel("rcounter1", "rcounter help", "label")
- r := NewRates("rates1", c, 3, -1*time.Second)
- r.snapshot()
- now = now.Add(epsilon)
- c.Add("tag1", 0)
- c.Add("tag2", 0)
- now = now.Add(intervalMinusEpsilon)
- r.snapshot()
- now = now.Add(epsilon)
- checkRates(t, r, "after 1s", 0.0, `{"tag1":[0],"tag2":[0]}`)
- c.Add("tag1", 10)
- c.Add("tag2", 20)
- now = now.Add(intervalMinusEpsilon)
- r.snapshot()
- now = now.Add(epsilon)
- checkRates(t, r, "after 2s", 30.0, `{"tag1":[0,10],"tag2":[0,20]}`)
- now = now.Add(intervalMinusEpsilon)
- r.snapshot()
- now = now.Add(epsilon)
- checkRates(t, r, "after 3s", 0.0, `{"tag1":[0,10,0],"tag2":[0,20,0]}`)
- now = now.Add(intervalMinusEpsilon)
- r.snapshot()
- now = now.Add(epsilon)
- checkRates(t, r, "after 4s", 0.0, `{"tag1":[10,0,0],"tag2":[20,0,0]}`)
- }
- func checkRates(t *testing.T, r *Rates, desc string, wantRate float64, wantRateMap string) {
- if got := r.String(); got != wantRateMap {
- t.Errorf("%v: want %s, got %s", desc, wantRateMap, got)
- }
- if got := r.TotalRate(); got != wantRate {
- t.Errorf("%v: want rate %v, got rate %v", desc, wantRate, got)
- }
- }
- func TestRatesConsistency(t *testing.T) {
- now := time.Now()
- timeNow = func() time.Time {
- return now
- }
- // This tests the following invariant: in the time window
- // covered by rates, the sum of the rates reported must be
- // equal to the count reported by the counter.
- clear()
- c := NewCountersWithSingleLabel("rcounter4", "rcounter4 help", "label")
- r := NewRates("rates4", c, 100, -1*time.Second)
- r.snapshot()
- now = now.Add(epsilon)
- c.Add("a", 1000)
- now = now.Add(intervalMinusEpsilon)
- r.snapshot()
- now = now.Add(epsilon)
- c.Add("a", 1)
- now = now.Add(intervalMinusEpsilon)
- r.snapshot()
- now = now.Add(epsilon)
- result := r.Get()
- counts := c.Counts()
- t.Logf("r.Get(): %v", result)
- t.Logf("c.Counts(): %v", counts)
- rate, count := result["a"], counts["a"]
- var sum float64
- for _, v := range rate {
- sum += v
- }
- if sum != float64(counts["a"]) {
- t.Errorf("rate inconsistent with count: sum of %v != %v", rate, count)
- }
- }
- func TestRatesHook(t *testing.T) {
- clear()
- c := NewCountersWithSingleLabel("rcounter2", "rcounter2 help", "label")
- var gotname string
- var gotv *Rates
- clear()
- Register(func(name string, v expvar.Var) {
- gotname = name
- gotv = v.(*Rates)
- })
- v := NewRates("rates2", c, 2, 10*time.Second)
- if gotname != "rates2" {
- t.Errorf("want rates2, got %s", gotname)
- }
- if gotv != v {
- t.Errorf("want %#v, got %#v", v, gotv)
- }
- }
|