OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / internal / timeseries / timeseries_test.go
1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package timeseries
6
7 import (
8         "math"
9         "testing"
10         "time"
11 )
12
13 func isNear(x *Float, y float64, tolerance float64) bool {
14         return math.Abs(x.Value()-y) < tolerance
15 }
16
17 func isApproximate(x *Float, y float64) bool {
18         return isNear(x, y, 1e-2)
19 }
20
21 func checkApproximate(t *testing.T, o Observable, y float64) {
22         x := o.(*Float)
23         if !isApproximate(x, y) {
24                 t.Errorf("Wanted %g, got %g", y, x.Value())
25         }
26 }
27
28 func checkNear(t *testing.T, o Observable, y, tolerance float64) {
29         x := o.(*Float)
30         if !isNear(x, y, tolerance) {
31                 t.Errorf("Wanted %g +- %g, got %g", y, tolerance, x.Value())
32         }
33 }
34
35 var baseTime = time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)
36
37 func tu(s int64) time.Time {
38         return baseTime.Add(time.Duration(s) * time.Second)
39 }
40
41 func tu2(s int64, ns int64) time.Time {
42         return baseTime.Add(time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond)
43 }
44
45 func TestBasicTimeSeries(t *testing.T) {
46         ts := NewTimeSeries(NewFloat)
47         fo := new(Float)
48         *fo = Float(10)
49         ts.AddWithTime(fo, tu(1))
50         ts.AddWithTime(fo, tu(1))
51         ts.AddWithTime(fo, tu(1))
52         ts.AddWithTime(fo, tu(1))
53         checkApproximate(t, ts.Range(tu(0), tu(1)), 40)
54         checkApproximate(t, ts.Total(), 40)
55         ts.AddWithTime(fo, tu(3))
56         ts.AddWithTime(fo, tu(3))
57         ts.AddWithTime(fo, tu(3))
58         checkApproximate(t, ts.Range(tu(0), tu(2)), 40)
59         checkApproximate(t, ts.Range(tu(2), tu(4)), 30)
60         checkApproximate(t, ts.Total(), 70)
61         ts.AddWithTime(fo, tu(1))
62         ts.AddWithTime(fo, tu(1))
63         checkApproximate(t, ts.Range(tu(0), tu(2)), 60)
64         checkApproximate(t, ts.Range(tu(2), tu(4)), 30)
65         checkApproximate(t, ts.Total(), 90)
66         *fo = Float(100)
67         ts.AddWithTime(fo, tu(100))
68         checkApproximate(t, ts.Range(tu(99), tu(100)), 100)
69         checkApproximate(t, ts.Range(tu(0), tu(4)), 36)
70         checkApproximate(t, ts.Total(), 190)
71         *fo = Float(10)
72         ts.AddWithTime(fo, tu(1))
73         ts.AddWithTime(fo, tu(1))
74         checkApproximate(t, ts.Range(tu(0), tu(4)), 44)
75         checkApproximate(t, ts.Range(tu(37), tu2(100, 100e6)), 100)
76         checkApproximate(t, ts.Range(tu(50), tu2(100, 100e6)), 100)
77         checkApproximate(t, ts.Range(tu(99), tu2(100, 100e6)), 100)
78         checkApproximate(t, ts.Total(), 210)
79
80         for i, l := range ts.ComputeRange(tu(36), tu(100), 64) {
81                 if i == 63 {
82                         checkApproximate(t, l, 100)
83                 } else {
84                         checkApproximate(t, l, 0)
85                 }
86         }
87
88         checkApproximate(t, ts.Range(tu(0), tu(100)), 210)
89         checkApproximate(t, ts.Range(tu(10), tu(100)), 100)
90
91         for i, l := range ts.ComputeRange(tu(0), tu(100), 100) {
92                 if i < 10 {
93                         checkApproximate(t, l, 11)
94                 } else if i >= 90 {
95                         checkApproximate(t, l, 10)
96                 } else {
97                         checkApproximate(t, l, 0)
98                 }
99         }
100 }
101
102 func TestFloat(t *testing.T) {
103         f := Float(1)
104         if g, w := f.String(), "1"; g != w {
105                 t.Errorf("Float(1).String = %q; want %q", g, w)
106         }
107         f2 := Float(2)
108         var o Observable = &f2
109         f.Add(o)
110         if g, w := f.Value(), 3.0; g != w {
111                 t.Errorf("Float post-add = %v; want %v", g, w)
112         }
113         f.Multiply(2)
114         if g, w := f.Value(), 6.0; g != w {
115                 t.Errorf("Float post-multiply = %v; want %v", g, w)
116         }
117         f.Clear()
118         if g, w := f.Value(), 0.0; g != w {
119                 t.Errorf("Float post-clear = %v; want %v", g, w)
120         }
121         f.CopyFrom(&f2)
122         if g, w := f.Value(), 2.0; g != w {
123                 t.Errorf("Float post-CopyFrom = %v; want %v", g, w)
124         }
125 }
126
127 type mockClock struct {
128         time time.Time
129 }
130
131 func (m *mockClock) Time() time.Time { return m.time }
132 func (m *mockClock) Set(t time.Time) { m.time = t }
133
134 const buckets = 6
135
136 var testResolutions = []time.Duration{
137         10 * time.Second,  // level holds one minute of observations
138         100 * time.Second, // level holds ten minutes of observations
139         10 * time.Minute,  // level holds one hour of observations
140 }
141
142 // TestTimeSeries uses a small number of buckets to force a higher
143 // error rate on approximations from the timeseries.
144 type TestTimeSeries struct {
145         timeSeries
146 }
147
148 func TestExpectedErrorRate(t *testing.T) {
149         ts := new(TestTimeSeries)
150         fake := new(mockClock)
151         fake.Set(time.Now())
152         ts.timeSeries.init(testResolutions, NewFloat, buckets, fake)
153         for i := 1; i <= 61*61; i++ {
154                 fake.Set(fake.Time().Add(1 * time.Second))
155                 ob := Float(1)
156                 ts.AddWithTime(&ob, fake.Time())
157
158                 // The results should be accurate within one missing bucket (1/6) of the observations recorded.
159                 checkNear(t, ts.Latest(0, buckets), min(float64(i), 60), 10)
160                 checkNear(t, ts.Latest(1, buckets), min(float64(i), 600), 100)
161                 checkNear(t, ts.Latest(2, buckets), min(float64(i), 3600), 600)
162         }
163 }
164
165 func min(a, b float64) float64 {
166         if a < b {
167                 return a
168         }
169         return b
170 }