summaryrefslogtreecommitdiff
path: root/internal/statsengine/histogram_test.go
blob: 96ad95a7055e7c7e8d29ae39c139867701b3c580 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package statsengine

import (
	"reflect"
	"testing"
)

func TestHistogramBucketIndexBoundaries(t *testing.T) {
	tests := []struct {
		name string
		dur  uint64
		idx  int
	}{
		{name: "zero", dur: 0, idx: 0},
		{name: "just below 1us", dur: 999, idx: 0},
		{name: "at 1us", dur: 1_000, idx: 1},
		{name: "at 10us", dur: 10_000, idx: 2},
		{name: "at 100us", dur: 100_000, idx: 3},
		{name: "at 1ms", dur: 1_000_000, idx: 4},
		{name: "at 10ms", dur: 10_000_000, idx: 5},
		{name: "at 100ms", dur: 100_000_000, idx: 6},
		{name: "at 1s", dur: 1_000_000_000, idx: 7},
		{name: "above 1s", dur: 5_000_000_000, idx: 7},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			if got := histogramBucketIndex(tc.dur); got != tc.idx {
				t.Fatalf("wrong bucket index for %d: got %d want %d", tc.dur, got, tc.idx)
			}
		})
	}
}

func TestHistogramSnapshotCountsAndRanges(t *testing.T) {
	h := newHistogram()

	h.Increment(0)
	h.Increment(1_000)
	h.Increment(1_000)
	h.Increment(1_500_000_000)

	snap := h.Snapshot()
	if snap.Total != 4 {
		t.Fatalf("wrong total: got %d want 4", snap.Total)
	}

	buckets := snap.Buckets()
	if len(buckets) != histogramBucketCount {
		t.Fatalf("wrong bucket count: got %d want %d", len(buckets), histogramBucketCount)
	}

	if buckets[0].Count != 1 || buckets[1].Count != 2 || buckets[7].Count != 1 {
		t.Fatalf("unexpected bucket counts: %+v", buckets)
	}

	if buckets[0].LowerNs != 0 || buckets[0].UpperNs != 1_000 {
		t.Fatalf("unexpected first range: %+v", buckets[0])
	}
	if buckets[7].LowerNs != 1_000_000_000 || buckets[7].UpperNs != 0 {
		t.Fatalf("unexpected last range: %+v", buckets[7])
	}
}

func TestHistogramSnapshotIsDefensive(t *testing.T) {
	h := newHistogram()
	h.Increment(1)

	s1 := h.Snapshot()
	b1 := s1.Buckets()
	b1[0].Count = 99

	s2 := h.Snapshot()
	if got := s2.Buckets()[0].Count; got != 1 {
		t.Fatalf("snapshot leaked mutable buckets: got %d", got)
	}

	if reflect.DeepEqual(b1, s2.Buckets()) {
		t.Fatalf("expected defensive copies of buckets")
	}
}

func TestNilHistogramSnapshot(t *testing.T) {
	var h *histogram
	s := h.Snapshot()
	if s.Total != 0 {
		t.Fatalf("expected zero total, got %d", s.Total)
	}
	if got := s.Buckets(); got != nil {
		t.Fatalf("expected nil buckets, got %#v", got)
	}
}