| // Copyright 2015 The Vanadium 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 statslib_test |
| |
| import ( |
| "reflect" |
| "sort" |
| "testing" |
| "time" |
| |
| "v.io/v23" |
| "v.io/v23/context" |
| "v.io/v23/naming" |
| "v.io/v23/security" |
| "v.io/v23/services/stats" |
| "v.io/v23/services/watch" |
| "v.io/v23/vdl" |
| "v.io/v23/vom" |
| libstats "v.io/x/ref/lib/stats" |
| "v.io/x/ref/lib/stats/histogram" |
| _ "v.io/x/ref/runtime/factories/generic" |
| "v.io/x/ref/services/internal/statslib" |
| s_stats "v.io/x/ref/services/stats" |
| "v.io/x/ref/test" |
| "v.io/x/ref/test/testutil" |
| ) |
| |
| type statsDispatcher struct { |
| } |
| |
| func (d *statsDispatcher) Lookup(_ *context.T, suffix string) (interface{}, security.Authorizer, error) { |
| return statslib.NewStatsService(suffix, 100*time.Millisecond), nil, nil |
| } |
| |
| func TestStatsImpl(t *testing.T) { |
| ctx, shutdown := test.V23Init() |
| defer shutdown() |
| |
| ctx, server, err := v23.WithNewDispatchingServer(ctx, "", &statsDispatcher{}) |
| if err != nil { |
| t.Fatalf("NewServer failed: %v", err) |
| return |
| } |
| endpoint := server.Status().Endpoints[0].String() |
| |
| counter := libstats.NewCounter("testing/foo/bar") |
| counter.Incr(10) |
| |
| histogram := libstats.NewHistogram("testing/hist/foo", histogram.Options{ |
| NumBuckets: 5, |
| GrowthFactor: 1, |
| SmallestBucketSize: 1, |
| MinValue: 0, |
| }) |
| for i := 0; i < 10; i++ { |
| histogram.Add(int64(i)) |
| } |
| |
| name := naming.JoinAddressName(endpoint, "") |
| c := stats.StatsClient(name) |
| |
| // Test Glob() |
| { |
| results, _, err := testutil.GlobName(ctx, name, "testing/foo/...") |
| if err != nil { |
| t.Fatalf("testutil.GlobName failed: %v", err) |
| } |
| expected := []string{ |
| "testing/foo", |
| "testing/foo/bar", |
| "testing/foo/bar/delta10m", |
| "testing/foo/bar/delta1h", |
| "testing/foo/bar/delta1m", |
| "testing/foo/bar/rate10m", |
| "testing/foo/bar/rate1h", |
| "testing/foo/bar/rate1m", |
| "testing/foo/bar/timeseries10m", |
| "testing/foo/bar/timeseries1h", |
| "testing/foo/bar/timeseries1m", |
| } |
| sort.Strings(results) |
| sort.Strings(expected) |
| if !reflect.DeepEqual(results, expected) { |
| t.Errorf("unexpected result. Got %v, want %v", results, expected) |
| } |
| } |
| |
| // Test WatchGlob() |
| { |
| var noRM watch.ResumeMarker |
| ctx, cancel := context.WithCancel(ctx) |
| stream, err := c.WatchGlob(ctx, watch.GlobRequest{Pattern: "testing/foo/bar"}) |
| if err != nil { |
| t.Fatalf("c.WatchGlob failed: %v", err) |
| } |
| iterator := stream.RecvStream() |
| if !iterator.Advance() { |
| t.Fatalf("expected more stream values") |
| } |
| got := vdl.ValueOf(iterator.Value()) |
| expected := vdl.ValueOf(watch.Change{Name: "testing/foo/bar", Value: vom.RawBytesOf(int64(10)), ResumeMarker: noRM}) |
| if !vdl.EqualValue(got, expected) { |
| t.Errorf("unexpected result. Got %#v, want %#v", got, expected) |
| } |
| |
| counter.Incr(5) |
| |
| if !iterator.Advance() { |
| t.Fatalf("expected more stream values") |
| } |
| got = vdl.ValueOf(iterator.Value()) |
| expected = vdl.ValueOf(watch.Change{Name: "testing/foo/bar", Value: vom.RawBytesOf(int64(15)), ResumeMarker: noRM}) |
| if !vdl.EqualValue(got, expected) { |
| t.Errorf("unexpected result. Got %#v, want %#v", got, expected) |
| } |
| |
| counter.Incr(2) |
| |
| if !iterator.Advance() { |
| t.Fatalf("expected more stream values") |
| } |
| got = vdl.ValueOf(iterator.Value()) |
| expected = vdl.ValueOf(watch.Change{Name: "testing/foo/bar", Value: vom.RawBytesOf(int64(17)), ResumeMarker: noRM}) |
| if !vdl.EqualValue(got, expected) { |
| t.Errorf("unexpected result. Got %#v, want %#v", got, expected) |
| } |
| cancel() |
| |
| if iterator.Advance() { |
| t.Errorf("expected no more stream values, got: %v", iterator.Value()) |
| } |
| } |
| |
| // Test Value() |
| { |
| c := stats.StatsClient(naming.JoinAddressName(endpoint, "testing/foo/bar")) |
| value, err := c.Value(ctx) |
| if err != nil { |
| t.Errorf("unexpected error: %v", err) |
| } |
| vv := vdl.ValueOf(value) |
| if want := vdl.IntValue(vdl.Int64Type, 17); !vdl.EqualValue(vv, want) { |
| t.Errorf("unexpected result. Got %v, want %v", vv, want) |
| } |
| } |
| |
| // Test Value() with Histogram |
| { |
| c := stats.StatsClient(naming.JoinAddressName(endpoint, "testing/hist/foo")) |
| value, err := c.Value(ctx) |
| if err != nil { |
| t.Errorf("unexpected error: %v", err) |
| } |
| vv := vdl.ValueOf(value) |
| want := vdl.ValueOf(s_stats.HistogramValue{ |
| Count: 10, |
| Sum: 45, |
| Min: 0, |
| Max: 9, |
| Buckets: []s_stats.HistogramBucket{ |
| s_stats.HistogramBucket{LowBound: 0, Count: 1}, |
| s_stats.HistogramBucket{LowBound: 1, Count: 2}, |
| s_stats.HistogramBucket{LowBound: 3, Count: 4}, |
| s_stats.HistogramBucket{LowBound: 7, Count: 3}, |
| s_stats.HistogramBucket{LowBound: 15, Count: 0}, |
| }, |
| }) |
| if !vdl.EqualValue(vv, want) { |
| t.Errorf("unexpected result. Got %v, want %v", vv, want) |
| } |
| } |
| } |