1package metrics
2
3import (
4	"math/rand"
5	"sync"
6	"testing"
7	"time"
8)
9
10func BenchmarkEWMA(b *testing.B) {
11	a := NewEWMA1()
12	b.ResetTimer()
13	for i := 0; i < b.N; i++ {
14		a.Update(1)
15		a.Tick()
16	}
17}
18
19func BenchmarkEWMAParallel(b *testing.B) {
20	a := NewEWMA1()
21	b.ResetTimer()
22
23	b.RunParallel(func(pb *testing.PB) {
24		for pb.Next() {
25			a.Update(1)
26			a.Tick()
27		}
28	})
29}
30
31// exercise race detector
32func TestEWMAConcurrency(t *testing.T) {
33	rand.Seed(time.Now().Unix())
34	a := NewEWMA1()
35	wg := &sync.WaitGroup{}
36	reps := 100
37	for i := 0; i < reps; i++ {
38		wg.Add(1)
39		go func(ewma EWMA, wg *sync.WaitGroup) {
40			a.Update(rand.Int63())
41			wg.Done()
42		}(a, wg)
43	}
44	wg.Wait()
45}
46
47func TestEWMA1(t *testing.T) {
48	a := NewEWMA1()
49	a.Update(3)
50	a.Tick()
51	if rate := a.Rate(); 0.6 != rate {
52		t.Errorf("initial a.Rate(): 0.6 != %v\n", rate)
53	}
54	elapseMinute(a)
55	if rate := a.Rate(); 0.22072766470286553 != rate {
56		t.Errorf("1 minute a.Rate(): 0.22072766470286553 != %v\n", rate)
57	}
58	elapseMinute(a)
59	if rate := a.Rate(); 0.08120116994196772 != rate {
60		t.Errorf("2 minute a.Rate(): 0.08120116994196772 != %v\n", rate)
61	}
62	elapseMinute(a)
63	if rate := a.Rate(); 0.029872241020718428 != rate {
64		t.Errorf("3 minute a.Rate(): 0.029872241020718428 != %v\n", rate)
65	}
66	elapseMinute(a)
67	if rate := a.Rate(); 0.01098938333324054 != rate {
68		t.Errorf("4 minute a.Rate(): 0.01098938333324054 != %v\n", rate)
69	}
70	elapseMinute(a)
71	if rate := a.Rate(); 0.004042768199451294 != rate {
72		t.Errorf("5 minute a.Rate(): 0.004042768199451294 != %v\n", rate)
73	}
74	elapseMinute(a)
75	if rate := a.Rate(); 0.0014872513059998212 != rate {
76		t.Errorf("6 minute a.Rate(): 0.0014872513059998212 != %v\n", rate)
77	}
78	elapseMinute(a)
79	if rate := a.Rate(); 0.0005471291793327122 != rate {
80		t.Errorf("7 minute a.Rate(): 0.0005471291793327122 != %v\n", rate)
81	}
82	elapseMinute(a)
83	if rate := a.Rate(); 0.00020127757674150815 != rate {
84		t.Errorf("8 minute a.Rate(): 0.00020127757674150815 != %v\n", rate)
85	}
86	elapseMinute(a)
87	if rate := a.Rate(); 7.404588245200814e-05 != rate {
88		t.Errorf("9 minute a.Rate(): 7.404588245200814e-05 != %v\n", rate)
89	}
90	elapseMinute(a)
91	if rate := a.Rate(); 2.7239957857491083e-05 != rate {
92		t.Errorf("10 minute a.Rate(): 2.7239957857491083e-05 != %v\n", rate)
93	}
94	elapseMinute(a)
95	if rate := a.Rate(); 1.0021020474147462e-05 != rate {
96		t.Errorf("11 minute a.Rate(): 1.0021020474147462e-05 != %v\n", rate)
97	}
98	elapseMinute(a)
99	if rate := a.Rate(); 3.6865274119969525e-06 != rate {
100		t.Errorf("12 minute a.Rate(): 3.6865274119969525e-06 != %v\n", rate)
101	}
102	elapseMinute(a)
103	if rate := a.Rate(); 1.3561976441886433e-06 != rate {
104		t.Errorf("13 minute a.Rate(): 1.3561976441886433e-06 != %v\n", rate)
105	}
106	elapseMinute(a)
107	if rate := a.Rate(); 4.989172314621449e-07 != rate {
108		t.Errorf("14 minute a.Rate(): 4.989172314621449e-07 != %v\n", rate)
109	}
110	elapseMinute(a)
111	if rate := a.Rate(); 1.8354139230109722e-07 != rate {
112		t.Errorf("15 minute a.Rate(): 1.8354139230109722e-07 != %v\n", rate)
113	}
114}
115
116func TestEWMA5(t *testing.T) {
117	a := NewEWMA5()
118	a.Update(3)
119	a.Tick()
120	if rate := a.Rate(); 0.6 != rate {
121		t.Errorf("initial a.Rate(): 0.6 != %v\n", rate)
122	}
123	elapseMinute(a)
124	if rate := a.Rate(); 0.49123845184678905 != rate {
125		t.Errorf("1 minute a.Rate(): 0.49123845184678905 != %v\n", rate)
126	}
127	elapseMinute(a)
128	if rate := a.Rate(); 0.4021920276213837 != rate {
129		t.Errorf("2 minute a.Rate(): 0.4021920276213837 != %v\n", rate)
130	}
131	elapseMinute(a)
132	if rate := a.Rate(); 0.32928698165641596 != rate {
133		t.Errorf("3 minute a.Rate(): 0.32928698165641596 != %v\n", rate)
134	}
135	elapseMinute(a)
136	if rate := a.Rate(); 0.269597378470333 != rate {
137		t.Errorf("4 minute a.Rate(): 0.269597378470333 != %v\n", rate)
138	}
139	elapseMinute(a)
140	if rate := a.Rate(); 0.2207276647028654 != rate {
141		t.Errorf("5 minute a.Rate(): 0.2207276647028654 != %v\n", rate)
142	}
143	elapseMinute(a)
144	if rate := a.Rate(); 0.18071652714732128 != rate {
145		t.Errorf("6 minute a.Rate(): 0.18071652714732128 != %v\n", rate)
146	}
147	elapseMinute(a)
148	if rate := a.Rate(); 0.14795817836496392 != rate {
149		t.Errorf("7 minute a.Rate(): 0.14795817836496392 != %v\n", rate)
150	}
151	elapseMinute(a)
152	if rate := a.Rate(); 0.12113791079679326 != rate {
153		t.Errorf("8 minute a.Rate(): 0.12113791079679326 != %v\n", rate)
154	}
155	elapseMinute(a)
156	if rate := a.Rate(); 0.09917933293295193 != rate {
157		t.Errorf("9 minute a.Rate(): 0.09917933293295193 != %v\n", rate)
158	}
159	elapseMinute(a)
160	if rate := a.Rate(); 0.08120116994196763 != rate {
161		t.Errorf("10 minute a.Rate(): 0.08120116994196763 != %v\n", rate)
162	}
163	elapseMinute(a)
164	if rate := a.Rate(); 0.06648189501740036 != rate {
165		t.Errorf("11 minute a.Rate(): 0.06648189501740036 != %v\n", rate)
166	}
167	elapseMinute(a)
168	if rate := a.Rate(); 0.05443077197364752 != rate {
169		t.Errorf("12 minute a.Rate(): 0.05443077197364752 != %v\n", rate)
170	}
171	elapseMinute(a)
172	if rate := a.Rate(); 0.04456414692860035 != rate {
173		t.Errorf("13 minute a.Rate(): 0.04456414692860035 != %v\n", rate)
174	}
175	elapseMinute(a)
176	if rate := a.Rate(); 0.03648603757513079 != rate {
177		t.Errorf("14 minute a.Rate(): 0.03648603757513079 != %v\n", rate)
178	}
179	elapseMinute(a)
180	if rate := a.Rate(); 0.0298722410207183831020718428 != rate {
181		t.Errorf("15 minute a.Rate(): 0.0298722410207183831020718428 != %v\n", rate)
182	}
183}
184
185func TestEWMA15(t *testing.T) {
186	a := NewEWMA15()
187	a.Update(3)
188	a.Tick()
189	if rate := a.Rate(); 0.6 != rate {
190		t.Errorf("initial a.Rate(): 0.6 != %v\n", rate)
191	}
192	elapseMinute(a)
193	if rate := a.Rate(); 0.5613041910189706 != rate {
194		t.Errorf("1 minute a.Rate(): 0.5613041910189706 != %v\n", rate)
195	}
196	elapseMinute(a)
197	if rate := a.Rate(); 0.5251039914257684 != rate {
198		t.Errorf("2 minute a.Rate(): 0.5251039914257684 != %v\n", rate)
199	}
200	elapseMinute(a)
201	if rate := a.Rate(); 0.4912384518467888184678905 != rate {
202		t.Errorf("3 minute a.Rate(): 0.4912384518467888184678905 != %v\n", rate)
203	}
204	elapseMinute(a)
205	if rate := a.Rate(); 0.459557003018789 != rate {
206		t.Errorf("4 minute a.Rate(): 0.459557003018789 != %v\n", rate)
207	}
208	elapseMinute(a)
209	if rate := a.Rate(); 0.4299187863442732 != rate {
210		t.Errorf("5 minute a.Rate(): 0.4299187863442732 != %v\n", rate)
211	}
212	elapseMinute(a)
213	if rate := a.Rate(); 0.4021920276213831 != rate {
214		t.Errorf("6 minute a.Rate(): 0.4021920276213831 != %v\n", rate)
215	}
216	elapseMinute(a)
217	if rate := a.Rate(); 0.37625345116383313 != rate {
218		t.Errorf("7 minute a.Rate(): 0.37625345116383313 != %v\n", rate)
219	}
220	elapseMinute(a)
221	if rate := a.Rate(); 0.3519877317060185 != rate {
222		t.Errorf("8 minute a.Rate(): 0.3519877317060185 != %v\n", rate)
223	}
224	elapseMinute(a)
225	if rate := a.Rate(); 0.3292869816564153165641596 != rate {
226		t.Errorf("9 minute a.Rate(): 0.3292869816564153165641596 != %v\n", rate)
227	}
228	elapseMinute(a)
229	if rate := a.Rate(); 0.3080502714195546 != rate {
230		t.Errorf("10 minute a.Rate(): 0.3080502714195546 != %v\n", rate)
231	}
232	elapseMinute(a)
233	if rate := a.Rate(); 0.2881831806538789 != rate {
234		t.Errorf("11 minute a.Rate(): 0.2881831806538789 != %v\n", rate)
235	}
236	elapseMinute(a)
237	if rate := a.Rate(); 0.26959737847033216 != rate {
238		t.Errorf("12 minute a.Rate(): 0.26959737847033216 != %v\n", rate)
239	}
240	elapseMinute(a)
241	if rate := a.Rate(); 0.2522102307052083 != rate {
242		t.Errorf("13 minute a.Rate(): 0.2522102307052083 != %v\n", rate)
243	}
244	elapseMinute(a)
245	if rate := a.Rate(); 0.23594443252115815 != rate {
246		t.Errorf("14 minute a.Rate(): 0.23594443252115815 != %v\n", rate)
247	}
248	elapseMinute(a)
249	if rate := a.Rate(); 0.2207276647028646247028654470286553 != rate {
250		t.Errorf("15 minute a.Rate(): 0.2207276647028646247028654470286553 != %v\n", rate)
251	}
252}
253
254func elapseMinute(a EWMA) {
255	for i := 0; i < 12; i++ {
256		a.Tick()
257	}
258}
259