1package metrics 2 3import ( 4 "testing" 5 "time" 6 7 "github.com/pascaldekloe/goe/verify" 8) 9 10func TestDisplayMetrics(t *testing.T) { 11 interval := 10 * time.Millisecond 12 inm := NewInmemSink(interval, 50*time.Millisecond) 13 14 // Add data points 15 inm.SetGauge([]string{"foo", "bar"}, 42) 16 inm.SetGaugeWithLabels([]string{"foo", "bar"}, 23, []Label{{"a", "b"}}) 17 inm.EmitKey([]string{"foo", "bar"}, 42) 18 inm.IncrCounter([]string{"foo", "bar"}, 20) 19 inm.IncrCounter([]string{"foo", "bar"}, 22) 20 inm.IncrCounterWithLabels([]string{"foo", "bar"}, 20, []Label{{"a", "b"}}) 21 inm.IncrCounterWithLabels([]string{"foo", "bar"}, 40, []Label{{"a", "b"}}) 22 inm.AddSample([]string{"foo", "bar"}, 20) 23 inm.AddSample([]string{"foo", "bar"}, 24) 24 inm.AddSampleWithLabels([]string{"foo", "bar"}, 23, []Label{{"a", "b"}}) 25 inm.AddSampleWithLabels([]string{"foo", "bar"}, 33, []Label{{"a", "b"}}) 26 27 data := inm.Data() 28 if len(data) != 1 { 29 t.Fatalf("bad: %v", data) 30 } 31 32 expected := MetricsSummary{ 33 Timestamp: data[0].Interval.Round(time.Second).UTC().String(), 34 Gauges: []GaugeValue{ 35 { 36 Name: "foo.bar", 37 Hash: "foo.bar", 38 Value: float32(42), 39 DisplayLabels: map[string]string{}, 40 }, 41 { 42 Name: "foo.bar", 43 Hash: "foo.bar;a=b", 44 Value: float32(23), 45 DisplayLabels: map[string]string{"a": "b"}, 46 }, 47 }, 48 Points: []PointValue{ 49 { 50 Name: "foo.bar", 51 Points: []float32{42}, 52 }, 53 }, 54 Counters: []SampledValue{ 55 { 56 Name: "foo.bar", 57 Hash: "foo.bar", 58 AggregateSample: &AggregateSample{ 59 Count: 2, 60 Min: 20, 61 Max: 22, 62 Sum: 42, 63 SumSq: 884, 64 Rate: 4200, 65 }, 66 Mean: 21, 67 Stddev: 1.4142135623730951, 68 }, 69 { 70 Name: "foo.bar", 71 Hash: "foo.bar;a=b", 72 AggregateSample: &AggregateSample{ 73 Count: 2, 74 Min: 20, 75 Max: 40, 76 Sum: 60, 77 SumSq: 2000, 78 Rate: 6000, 79 }, 80 Mean: 30, 81 Stddev: 14.142135623730951, 82 DisplayLabels: map[string]string{"a": "b"}, 83 }, 84 }, 85 Samples: []SampledValue{ 86 { 87 Name: "foo.bar", 88 Hash: "foo.bar", 89 AggregateSample: &AggregateSample{ 90 Count: 2, 91 Min: 20, 92 Max: 24, 93 Sum: 44, 94 SumSq: 976, 95 Rate: 4400, 96 }, 97 Mean: 22, 98 Stddev: 2.8284271247461903, 99 }, 100 { 101 Name: "foo.bar", 102 Hash: "foo.bar;a=b", 103 AggregateSample: &AggregateSample{ 104 Count: 2, 105 Min: 23, 106 Max: 33, 107 Sum: 56, 108 SumSq: 1618, 109 Rate: 5600, 110 }, 111 Mean: 28, 112 Stddev: 7.0710678118654755, 113 DisplayLabels: map[string]string{"a": "b"}, 114 }, 115 }, 116 } 117 118 raw, err := inm.DisplayMetrics(nil, nil) 119 if err != nil { 120 t.Fatalf("err: %v", err) 121 } 122 result := raw.(MetricsSummary) 123 124 // Ignore the LastUpdated field, we don't export that anyway 125 for i, got := range result.Counters { 126 expected.Counters[i].LastUpdated = got.LastUpdated 127 } 128 for i, got := range result.Samples { 129 expected.Samples[i].LastUpdated = got.LastUpdated 130 } 131 132 verify.Values(t, "all", result, expected) 133} 134 135func TestDisplayMetrics_RaceSetGauge(t *testing.T) { 136 interval := 200 * time.Millisecond 137 inm := NewInmemSink(interval, 10*interval) 138 result := make(chan float32) 139 140 go func() { 141 for { 142 time.Sleep(150 * time.Millisecond) 143 inm.SetGauge([]string{"foo", "bar"}, float32(42)) 144 } 145 }() 146 147 go func() { 148 start := time.Now() 149 var summary MetricsSummary 150 // test for twenty intervals 151 for time.Now().Sub(start) < 20*interval { 152 time.Sleep(100 * time.Millisecond) 153 raw, _ := inm.DisplayMetrics(nil, nil) 154 summary = raw.(MetricsSummary) 155 } 156 // save result 157 for _, g := range summary.Gauges { 158 if g.Name == "foo.bar" { 159 result <- g.Value 160 } 161 } 162 close(result) 163 }() 164 165 got := <-result 166 verify.Values(t, "all", got, float32(42)) 167} 168 169func TestDisplayMetrics_RaceAddSample(t *testing.T) { 170 interval := 200 * time.Millisecond 171 inm := NewInmemSink(interval, 10*interval) 172 result := make(chan float32) 173 174 go func() { 175 for { 176 time.Sleep(75 * time.Millisecond) 177 inm.AddSample([]string{"foo", "bar"}, float32(0.0)) 178 } 179 }() 180 181 go func() { 182 start := time.Now() 183 var summary MetricsSummary 184 // test for twenty intervals 185 for time.Now().Sub(start) < 20*interval { 186 time.Sleep(100 * time.Millisecond) 187 raw, _ := inm.DisplayMetrics(nil, nil) 188 summary = raw.(MetricsSummary) 189 } 190 // save result 191 for _, g := range summary.Gauges { 192 if g.Name == "foo.bar" { 193 result <- g.Value 194 } 195 } 196 close(result) 197 }() 198 199 got := <-result 200 verify.Values(t, "all", got, float32(0.0)) 201} 202 203func TestDisplayMetrics_RaceIncrCounter(t *testing.T) { 204 interval := 200 * time.Millisecond 205 inm := NewInmemSink(interval, 10*interval) 206 result := make(chan float32) 207 208 go func() { 209 for { 210 time.Sleep(75 * time.Millisecond) 211 inm.IncrCounter([]string{"foo", "bar"}, float32(0.0)) 212 } 213 }() 214 215 go func() { 216 start := time.Now() 217 var summary MetricsSummary 218 // test for twenty intervals 219 for time.Now().Sub(start) < 20*interval { 220 time.Sleep(30 * time.Millisecond) 221 raw, _ := inm.DisplayMetrics(nil, nil) 222 summary = raw.(MetricsSummary) 223 } 224 // save result for testing 225 for _, g := range summary.Gauges { 226 if g.Name == "foo.bar" { 227 result <- g.Value 228 } 229 } 230 close(result) 231 }() 232 233 got := <-result 234 verify.Values(t, "all", got, float32(0.0)) 235} 236 237func TestDisplayMetrics_RaceMetricsSetGauge(t *testing.T) { 238 interval := 200 * time.Millisecond 239 inm := NewInmemSink(interval, 10*interval) 240 met := &Metrics{Config: Config{FilterDefault: true}, sink: inm} 241 result := make(chan float32) 242 labels := []Label{ 243 {"name1", "value1"}, 244 {"name2", "value2"}, 245 } 246 247 go func() { 248 for { 249 time.Sleep(75 * time.Millisecond) 250 met.SetGaugeWithLabels([]string{"foo", "bar"}, float32(42), labels) 251 } 252 }() 253 254 go func() { 255 start := time.Now() 256 var summary MetricsSummary 257 // test for twenty intervals 258 for time.Now().Sub(start) < 40*interval { 259 time.Sleep(150 * time.Millisecond) 260 raw, _ := inm.DisplayMetrics(nil, nil) 261 summary = raw.(MetricsSummary) 262 } 263 // save result 264 for _, g := range summary.Gauges { 265 if g.Name == "foo.bar" { 266 result <- g.Value 267 } 268 } 269 close(result) 270 }() 271 272 got := <-result 273 verify.Values(t, "all", got, float32(42)) 274} 275 276