OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / golang.org / x / net / internal / timeseries / timeseries_test.go
diff --git a/vendor/golang.org/x/net/internal/timeseries/timeseries_test.go b/vendor/golang.org/x/net/internal/timeseries/timeseries_test.go
new file mode 100644 (file)
index 0000000..66325a9
--- /dev/null
@@ -0,0 +1,170 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package timeseries
+
+import (
+       "math"
+       "testing"
+       "time"
+)
+
+func isNear(x *Float, y float64, tolerance float64) bool {
+       return math.Abs(x.Value()-y) < tolerance
+}
+
+func isApproximate(x *Float, y float64) bool {
+       return isNear(x, y, 1e-2)
+}
+
+func checkApproximate(t *testing.T, o Observable, y float64) {
+       x := o.(*Float)
+       if !isApproximate(x, y) {
+               t.Errorf("Wanted %g, got %g", y, x.Value())
+       }
+}
+
+func checkNear(t *testing.T, o Observable, y, tolerance float64) {
+       x := o.(*Float)
+       if !isNear(x, y, tolerance) {
+               t.Errorf("Wanted %g +- %g, got %g", y, tolerance, x.Value())
+       }
+}
+
+var baseTime = time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)
+
+func tu(s int64) time.Time {
+       return baseTime.Add(time.Duration(s) * time.Second)
+}
+
+func tu2(s int64, ns int64) time.Time {
+       return baseTime.Add(time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond)
+}
+
+func TestBasicTimeSeries(t *testing.T) {
+       ts := NewTimeSeries(NewFloat)
+       fo := new(Float)
+       *fo = Float(10)
+       ts.AddWithTime(fo, tu(1))
+       ts.AddWithTime(fo, tu(1))
+       ts.AddWithTime(fo, tu(1))
+       ts.AddWithTime(fo, tu(1))
+       checkApproximate(t, ts.Range(tu(0), tu(1)), 40)
+       checkApproximate(t, ts.Total(), 40)
+       ts.AddWithTime(fo, tu(3))
+       ts.AddWithTime(fo, tu(3))
+       ts.AddWithTime(fo, tu(3))
+       checkApproximate(t, ts.Range(tu(0), tu(2)), 40)
+       checkApproximate(t, ts.Range(tu(2), tu(4)), 30)
+       checkApproximate(t, ts.Total(), 70)
+       ts.AddWithTime(fo, tu(1))
+       ts.AddWithTime(fo, tu(1))
+       checkApproximate(t, ts.Range(tu(0), tu(2)), 60)
+       checkApproximate(t, ts.Range(tu(2), tu(4)), 30)
+       checkApproximate(t, ts.Total(), 90)
+       *fo = Float(100)
+       ts.AddWithTime(fo, tu(100))
+       checkApproximate(t, ts.Range(tu(99), tu(100)), 100)
+       checkApproximate(t, ts.Range(tu(0), tu(4)), 36)
+       checkApproximate(t, ts.Total(), 190)
+       *fo = Float(10)
+       ts.AddWithTime(fo, tu(1))
+       ts.AddWithTime(fo, tu(1))
+       checkApproximate(t, ts.Range(tu(0), tu(4)), 44)
+       checkApproximate(t, ts.Range(tu(37), tu2(100, 100e6)), 100)
+       checkApproximate(t, ts.Range(tu(50), tu2(100, 100e6)), 100)
+       checkApproximate(t, ts.Range(tu(99), tu2(100, 100e6)), 100)
+       checkApproximate(t, ts.Total(), 210)
+
+       for i, l := range ts.ComputeRange(tu(36), tu(100), 64) {
+               if i == 63 {
+                       checkApproximate(t, l, 100)
+               } else {
+                       checkApproximate(t, l, 0)
+               }
+       }
+
+       checkApproximate(t, ts.Range(tu(0), tu(100)), 210)
+       checkApproximate(t, ts.Range(tu(10), tu(100)), 100)
+
+       for i, l := range ts.ComputeRange(tu(0), tu(100), 100) {
+               if i < 10 {
+                       checkApproximate(t, l, 11)
+               } else if i >= 90 {
+                       checkApproximate(t, l, 10)
+               } else {
+                       checkApproximate(t, l, 0)
+               }
+       }
+}
+
+func TestFloat(t *testing.T) {
+       f := Float(1)
+       if g, w := f.String(), "1"; g != w {
+               t.Errorf("Float(1).String = %q; want %q", g, w)
+       }
+       f2 := Float(2)
+       var o Observable = &f2
+       f.Add(o)
+       if g, w := f.Value(), 3.0; g != w {
+               t.Errorf("Float post-add = %v; want %v", g, w)
+       }
+       f.Multiply(2)
+       if g, w := f.Value(), 6.0; g != w {
+               t.Errorf("Float post-multiply = %v; want %v", g, w)
+       }
+       f.Clear()
+       if g, w := f.Value(), 0.0; g != w {
+               t.Errorf("Float post-clear = %v; want %v", g, w)
+       }
+       f.CopyFrom(&f2)
+       if g, w := f.Value(), 2.0; g != w {
+               t.Errorf("Float post-CopyFrom = %v; want %v", g, w)
+       }
+}
+
+type mockClock struct {
+       time time.Time
+}
+
+func (m *mockClock) Time() time.Time { return m.time }
+func (m *mockClock) Set(t time.Time) { m.time = t }
+
+const buckets = 6
+
+var testResolutions = []time.Duration{
+       10 * time.Second,  // level holds one minute of observations
+       100 * time.Second, // level holds ten minutes of observations
+       10 * time.Minute,  // level holds one hour of observations
+}
+
+// TestTimeSeries uses a small number of buckets to force a higher
+// error rate on approximations from the timeseries.
+type TestTimeSeries struct {
+       timeSeries
+}
+
+func TestExpectedErrorRate(t *testing.T) {
+       ts := new(TestTimeSeries)
+       fake := new(mockClock)
+       fake.Set(time.Now())
+       ts.timeSeries.init(testResolutions, NewFloat, buckets, fake)
+       for i := 1; i <= 61*61; i++ {
+               fake.Set(fake.Time().Add(1 * time.Second))
+               ob := Float(1)
+               ts.AddWithTime(&ob, fake.Time())
+
+               // The results should be accurate within one missing bucket (1/6) of the observations recorded.
+               checkNear(t, ts.Latest(0, buckets), min(float64(i), 60), 10)
+               checkNear(t, ts.Latest(1, buckets), min(float64(i), 600), 100)
+               checkNear(t, ts.Latest(2, buckets), min(float64(i), 3600), 600)
+       }
+}
+
+func min(a, b float64) float64 {
+       if a < b {
+               return a
+       }
+       return b
+}