blob: 9a3f6b10c77bebe4ae134a3eeabb1309cfefc648 [file] [log] [blame]
package stats_test
import (
"reflect"
"testing"
"time"
libstats "veyron.io/veyron/veyron/lib/stats"
"veyron.io/veyron/veyron/lib/stats/counter"
"veyron.io/veyron/veyron/lib/stats/histogram"
istats "veyron.io/veyron/veyron/services/mgmt/stats"
)
func doGlob(root, pattern string, since time.Time, includeValues bool) ([]libstats.KeyValue, error) {
it := libstats.Glob(root, pattern, since, includeValues)
out := []libstats.KeyValue{}
for it.Advance() {
out = append(out, it.Value())
}
if err := it.Err(); err != nil {
return nil, err
}
return out, nil
}
func TestStats(t *testing.T) {
now := time.Unix(1, 0)
counter.Now = func() time.Time { return now }
a := libstats.NewInteger("ipc/test/aaa")
b := libstats.NewFloat("ipc/test/bbb")
c := libstats.NewString("ipc/test/ccc")
d := libstats.NewCounter("ipc/test/ddd")
a.Set(1)
b.Set(2)
c.Set("Hello")
d.Set(4)
got, err := libstats.Value("ipc/test/aaa")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if expected := int64(1); got != expected {
t.Errorf("unexpected result. Got %v, want %v", got, expected)
}
if _, err := libstats.Value(""); err != libstats.ErrNotFound {
t.Errorf("expected error, got err=%v", err)
}
if _, err := libstats.Value("does/not/exist"); err != libstats.ErrNotFound {
t.Errorf("expected error, got err=%v", err)
}
root := libstats.NewInteger("")
root.Set(42)
got, err = libstats.Value("")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if expected := int64(42); got != expected {
t.Errorf("unexpected result. Got %v, want %v", got, expected)
}
foo := libstats.NewInteger("foo")
foo.Set(55)
got, err = libstats.Value("foo")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if expected := int64(55); got != expected {
t.Errorf("unexpected result. Got %v, want %v", got, expected)
}
bar := libstats.NewInteger("foo/bar")
bar.Set(44)
got, err = libstats.Value("foo/bar")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if expected := int64(44); got != expected {
t.Errorf("unexpected result. Got %v, want %v", got, expected)
}
// Glob showing only nodes with a value.
result, err := doGlob("", "...", now, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected := []libstats.KeyValue{
libstats.KeyValue{Key: "", Value: int64(42)},
libstats.KeyValue{Key: "foo", Value: int64(55)},
libstats.KeyValue{Key: "foo/bar", Value: int64(44)},
libstats.KeyValue{Key: "ipc/test/aaa", Value: int64(1)},
libstats.KeyValue{Key: "ipc/test/bbb", Value: float64(2)},
libstats.KeyValue{Key: "ipc/test/ccc", Value: string("Hello")},
libstats.KeyValue{Key: "ipc/test/ddd", Value: int64(4)},
libstats.KeyValue{Key: "ipc/test/ddd/delta10m", Value: int64(4)},
libstats.KeyValue{Key: "ipc/test/ddd/delta1h", Value: int64(4)},
libstats.KeyValue{Key: "ipc/test/ddd/delta1m", Value: int64(4)},
libstats.KeyValue{Key: "ipc/test/ddd/rate10m", Value: float64(0)},
libstats.KeyValue{Key: "ipc/test/ddd/rate1h", Value: float64(0)},
libstats.KeyValue{Key: "ipc/test/ddd/rate1m", Value: float64(0)},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
result, err = doGlob("", "ipc/test/*", now, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{Key: "ipc/test/aaa", Value: int64(1)},
libstats.KeyValue{Key: "ipc/test/bbb", Value: float64(2)},
libstats.KeyValue{Key: "ipc/test/ccc", Value: string("Hello")},
libstats.KeyValue{Key: "ipc/test/ddd", Value: int64(4)},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
// Glob showing all nodes without values
result, err = doGlob("", "ipc/...", time.Time{}, false)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{Key: "ipc"},
libstats.KeyValue{Key: "ipc/test"},
libstats.KeyValue{Key: "ipc/test/aaa"},
libstats.KeyValue{Key: "ipc/test/bbb"},
libstats.KeyValue{Key: "ipc/test/ccc"},
libstats.KeyValue{Key: "ipc/test/ddd"},
libstats.KeyValue{Key: "ipc/test/ddd/delta10m"},
libstats.KeyValue{Key: "ipc/test/ddd/delta1h"},
libstats.KeyValue{Key: "ipc/test/ddd/delta1m"},
libstats.KeyValue{Key: "ipc/test/ddd/rate10m"},
libstats.KeyValue{Key: "ipc/test/ddd/rate1h"},
libstats.KeyValue{Key: "ipc/test/ddd/rate1m"},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
// Test the rate counter.
now = now.Add(10 * time.Second)
d.Incr(100)
result, err = doGlob("", "ipc/test/ddd/*", now, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{Key: "ipc/test/ddd/delta10m", Value: int64(104)},
libstats.KeyValue{Key: "ipc/test/ddd/delta1h", Value: int64(104)},
libstats.KeyValue{Key: "ipc/test/ddd/delta1m", Value: int64(104)},
libstats.KeyValue{Key: "ipc/test/ddd/rate10m", Value: float64(10.4)},
libstats.KeyValue{Key: "ipc/test/ddd/rate1h", Value: float64(0)},
libstats.KeyValue{Key: "ipc/test/ddd/rate1m", Value: float64(10.4)},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
// Test Glob on non-root object.
result, err = doGlob("ipc/test", "*", time.Time{}, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{Key: "aaa", Value: int64(1)},
libstats.KeyValue{Key: "bbb", Value: float64(2)},
libstats.KeyValue{Key: "ccc", Value: string("Hello")},
libstats.KeyValue{Key: "ddd", Value: int64(104)},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
result, err = doGlob("ipc/test/aaa", "", time.Time{}, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{Key: "", Value: int64(1)},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
// Test LastUpdate. The test only works on Counters.
result, err = doGlob("ipc/test", "ddd", now, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{Key: "ddd", Value: int64(104)},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
result, err = doGlob("ipc/test", "ddd", now.Add(time.Second), true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
// Test histogram
h := libstats.NewHistogram("ipc/test/hhh", histogram.Options{NumBuckets: 5, GrowthFactor: 0})
h.Add(1)
h.Add(2)
result, err = doGlob("", "ipc/test/hhh", now, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{
Key: "ipc/test/hhh",
Value: istats.HistogramValue{
Count: 2,
Sum: 3,
Buckets: []istats.HistogramBucket{
istats.HistogramBucket{LowBound: 0, Count: 0},
istats.HistogramBucket{LowBound: 1, Count: 1},
istats.HistogramBucket{LowBound: 2, Count: 1},
istats.HistogramBucket{LowBound: 3, Count: 0},
istats.HistogramBucket{LowBound: 4, Count: 0},
},
},
},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
now = now.Add(30 * time.Second)
h.Add(2)
now = now.Add(30 * time.Second)
h.Add(3)
result, err = doGlob("", "ipc/test/hhh/delta1m", now, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected = []libstats.KeyValue{
libstats.KeyValue{
Key: "ipc/test/hhh/delta1m",
Value: istats.HistogramValue{
Count: 2,
Sum: 5,
Buckets: []istats.HistogramBucket{
istats.HistogramBucket{LowBound: 0, Count: 0},
istats.HistogramBucket{LowBound: 1, Count: 0},
istats.HistogramBucket{LowBound: 2, Count: 1},
istats.HistogramBucket{LowBound: 3, Count: 1},
istats.HistogramBucket{LowBound: 4, Count: 0},
},
},
},
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", result, expected)
}
}
func TestMap(t *testing.T) {
m := libstats.NewMap("testing/foo")
m.Set([]libstats.KeyValue{{"a", 1}, {"b", 2}})
// Test the Value of the map.
{
got, err := libstats.Value("testing/foo")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if expected := interface{}(nil); got != expected {
t.Errorf("unexpected result. Got %v, want %v", got, expected)
}
}
// Test Glob on the map object.
{
got, err := doGlob("testing", "foo/...", time.Time{}, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected := []libstats.KeyValue{
libstats.KeyValue{Key: "foo", Value: nil},
libstats.KeyValue{Key: "foo/a", Value: int64(1)},
libstats.KeyValue{Key: "foo/b", Value: int64(2)},
}
if !reflect.DeepEqual(got, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", got, expected)
}
}
m.Delete([]string{"a"})
// Test Glob on the map object.
{
got, err := doGlob("testing", "foo/...", time.Time{}, true)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
expected := []libstats.KeyValue{
libstats.KeyValue{Key: "foo", Value: nil},
libstats.KeyValue{Key: "foo/b", Value: int64(2)},
}
if !reflect.DeepEqual(got, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", got, expected)
}
}
}
func TestDelete(t *testing.T) {
_ = libstats.NewInteger("a/b/c/d")
if _, err := libstats.GetStatsObject("a/b/c/d"); err != nil {
t.Errorf("unexpected error value: %v", err)
}
if err := libstats.Delete("a/b/c/d"); err != nil {
t.Errorf("unexpected error value: %v", err)
}
if _, err := libstats.GetStatsObject("a/b/c/d"); err != libstats.ErrNotFound {
t.Errorf("unexpected error value: Got %v, want %v", err, libstats.ErrNotFound)
}
if err := libstats.Delete("a/b"); err != nil {
t.Errorf("unexpected error value: %v", err)
}
if _, err := libstats.GetStatsObject("a/b"); err != libstats.ErrNotFound {
t.Errorf("unexpected error value: Got %v, want %v", err, libstats.ErrNotFound)
}
if _, err := libstats.GetStatsObject("a/b/c"); err != libstats.ErrNotFound {
t.Errorf("unexpected error value: Got %v, want %v", err, libstats.ErrNotFound)
}
}