214 lines
5.2 KiB
Go
214 lines
5.2 KiB
Go
package selfstat
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/influxdata/telegraf/testutil"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var (
|
|
// only allow one test at a time
|
|
// this is because we are dealing with a global registry
|
|
testLock sync.Mutex
|
|
a int64
|
|
)
|
|
|
|
// testCleanup resets the global registry for test cleanup & unlocks the test lock
|
|
func testCleanup() {
|
|
registry = &Registry{
|
|
stats: make(map[uint64]map[string]Stat),
|
|
}
|
|
testLock.Unlock()
|
|
}
|
|
|
|
func BenchmarkStats(b *testing.B) {
|
|
testLock.Lock()
|
|
defer testCleanup()
|
|
b1 := Register("benchmark1", "test_field1", map[string]string{"test": "foo"})
|
|
for n := 0; n < b.N; n++ {
|
|
b1.Incr(1)
|
|
b1.Incr(3)
|
|
a = b1.Get()
|
|
}
|
|
}
|
|
|
|
func BenchmarkTimingStats(b *testing.B) {
|
|
testLock.Lock()
|
|
defer testCleanup()
|
|
b2 := RegisterTiming("benchmark2", "test_field1", map[string]string{"test": "foo"})
|
|
for n := 0; n < b.N; n++ {
|
|
b2.Incr(1)
|
|
b2.Incr(3)
|
|
a = b2.Get()
|
|
}
|
|
}
|
|
|
|
func TestRegisterAndIncrAndSet(t *testing.T) {
|
|
testLock.Lock()
|
|
defer testCleanup()
|
|
s1 := Register("test", "test_field1", map[string]string{"test": "foo"})
|
|
s2 := Register("test", "test_field2", map[string]string{"test": "foo"})
|
|
assert.Equal(t, int64(0), s1.Get())
|
|
|
|
s1.Incr(10)
|
|
s1.Incr(5)
|
|
assert.Equal(t, int64(15), s1.Get())
|
|
|
|
s1.Set(12)
|
|
assert.Equal(t, int64(12), s1.Get())
|
|
|
|
s1.Incr(-2)
|
|
assert.Equal(t, int64(10), s1.Get())
|
|
|
|
s2.Set(101)
|
|
assert.Equal(t, int64(101), s2.Get())
|
|
|
|
// make sure that the same field returns the same metric
|
|
// this one should be the same as s2.
|
|
foo := Register("test", "test_field2", map[string]string{"test": "foo"})
|
|
assert.Equal(t, int64(101), foo.Get())
|
|
|
|
// check that tags are consistent
|
|
assert.Equal(t, map[string]string{"test": "foo"}, foo.Tags())
|
|
assert.Equal(t, "internal_test", foo.Name())
|
|
}
|
|
|
|
func TestRegisterTimingAndIncrAndSet(t *testing.T) {
|
|
testLock.Lock()
|
|
defer testCleanup()
|
|
s1 := RegisterTiming("test", "test_field1_ns", map[string]string{"test": "foo"})
|
|
s2 := RegisterTiming("test", "test_field2_ns", map[string]string{"test": "foo"})
|
|
assert.Equal(t, int64(0), s1.Get())
|
|
|
|
s1.Incr(10)
|
|
s1.Incr(5)
|
|
assert.Equal(t, int64(7), s1.Get())
|
|
// previous value is used on subsequent calls to Get()
|
|
assert.Equal(t, int64(7), s1.Get())
|
|
|
|
s1.Set(12)
|
|
assert.Equal(t, int64(12), s1.Get())
|
|
|
|
s1.Incr(-2)
|
|
assert.Equal(t, int64(-2), s1.Get())
|
|
|
|
s2.Set(101)
|
|
assert.Equal(t, int64(101), s2.Get())
|
|
|
|
// make sure that the same field returns the same metric
|
|
// this one should be the same as s2.
|
|
foo := RegisterTiming("test", "test_field2_ns", map[string]string{"test": "foo"})
|
|
assert.Equal(t, int64(101), foo.Get())
|
|
|
|
// check that tags are consistent
|
|
assert.Equal(t, map[string]string{"test": "foo"}, foo.Tags())
|
|
assert.Equal(t, "internal_test", foo.Name())
|
|
}
|
|
|
|
func TestStatKeyConsistency(t *testing.T) {
|
|
lhs := key("internal_stats", map[string]string{
|
|
"foo": "bar",
|
|
"bar": "baz",
|
|
"whose": "first",
|
|
})
|
|
rhs := key("internal_stats", map[string]string{
|
|
"foo": "bar",
|
|
"bar": "baz",
|
|
"whose": "first",
|
|
})
|
|
require.Equal(t, lhs, rhs)
|
|
}
|
|
|
|
func TestRegisterMetricsAndVerify(t *testing.T) {
|
|
testLock.Lock()
|
|
defer testCleanup()
|
|
|
|
// register two metrics with the same key
|
|
s1 := RegisterTiming("test_timing", "test_field1_ns", map[string]string{"test": "foo"})
|
|
s2 := RegisterTiming("test_timing", "test_field2_ns", map[string]string{"test": "foo"})
|
|
s1.Incr(10)
|
|
s2.Incr(15)
|
|
assert.Len(t, Metrics(), 1)
|
|
|
|
// register two more metrics with different keys
|
|
s3 := RegisterTiming("test_timing", "test_field1_ns", map[string]string{"test": "bar"})
|
|
s4 := RegisterTiming("test_timing", "test_field2_ns", map[string]string{"test": "baz"})
|
|
s3.Incr(10)
|
|
s4.Incr(15)
|
|
assert.Len(t, Metrics(), 3)
|
|
|
|
// register some non-timing metrics
|
|
s5 := Register("test", "test_field1", map[string]string{"test": "bar"})
|
|
s6 := Register("test", "test_field2", map[string]string{"test": "baz"})
|
|
Register("test", "test_field3", map[string]string{"test": "baz"})
|
|
s5.Incr(10)
|
|
s5.Incr(18)
|
|
s6.Incr(15)
|
|
assert.Len(t, Metrics(), 5)
|
|
|
|
acc := testutil.Accumulator{}
|
|
acc.AddMetrics(Metrics())
|
|
|
|
// verify s1 & s2
|
|
acc.AssertContainsTaggedFields(t, "internal_test_timing",
|
|
map[string]interface{}{
|
|
"test_field1_ns": int64(10),
|
|
"test_field2_ns": int64(15),
|
|
},
|
|
map[string]string{
|
|
"test": "foo",
|
|
},
|
|
)
|
|
|
|
// verify s3
|
|
acc.AssertContainsTaggedFields(t, "internal_test_timing",
|
|
map[string]interface{}{
|
|
"test_field1_ns": int64(10),
|
|
},
|
|
map[string]string{
|
|
"test": "bar",
|
|
},
|
|
)
|
|
|
|
// verify s4
|
|
acc.AssertContainsTaggedFields(t, "internal_test_timing",
|
|
map[string]interface{}{
|
|
"test_field2_ns": int64(15),
|
|
},
|
|
map[string]string{
|
|
"test": "baz",
|
|
},
|
|
)
|
|
|
|
// verify s5
|
|
acc.AssertContainsTaggedFields(t, "internal_test",
|
|
map[string]interface{}{
|
|
"test_field1": int64(28),
|
|
},
|
|
map[string]string{
|
|
"test": "bar",
|
|
},
|
|
)
|
|
|
|
// verify s6 & s7
|
|
acc.AssertContainsTaggedFields(t, "internal_test",
|
|
map[string]interface{}{
|
|
"test_field2": int64(15),
|
|
"test_field3": int64(0),
|
|
},
|
|
map[string]string{
|
|
"test": "baz",
|
|
},
|
|
)
|
|
}
|
|
|
|
func TestRegisterCopy(t *testing.T) {
|
|
tags := map[string]string{"input": "mem", "alias": "mem1"}
|
|
stat := Register("gather", "metrics_gathered", tags)
|
|
tags["new"] = "value"
|
|
require.NotEqual(t, tags, stat.Tags())
|
|
}
|