You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kratos/pkg/stat/metric/rolling_gauge_test.go

193 lines
3.8 KiB

6 years ago
package metric
import (
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestRollingGaugeAdd(t *testing.T) {
size := 3
bucketDuration := time.Second
opts := RollingGaugeOpts{
Size: size,
BucketDuration: bucketDuration,
}
r := NewRollingGauge(opts)
listBuckets := func() [][]float64 {
buckets := make([][]float64, 0)
r.Reduce(func(i Iterator) float64 {
for i.Next() {
bucket := i.Bucket()
buckets = append(buckets, bucket.Points)
}
return 0.0
})
return buckets
}
assert.Equal(t, [][]float64{{}, {}, {}}, listBuckets())
r.Add(1)
assert.Equal(t, [][]float64{{}, {}, {1}}, listBuckets())
time.Sleep(time.Second)
r.Add(2)
r.Add(3)
assert.Equal(t, [][]float64{{}, {1}, {2, 3}}, listBuckets())
time.Sleep(time.Second)
r.Add(4)
r.Add(5)
r.Add(6)
assert.Equal(t, [][]float64{{1}, {2, 3}, {4, 5, 6}}, listBuckets())
time.Sleep(time.Second)
r.Add(7)
assert.Equal(t, [][]float64{{2, 3}, {4, 5, 6}, {7}}, listBuckets())
}
func TestRollingGaugeReset(t *testing.T) {
size := 3
bucketDuration := time.Second
opts := RollingGaugeOpts{
Size: size,
BucketDuration: bucketDuration,
}
r := NewRollingGauge(opts)
listBuckets := func() [][]float64 {
buckets := make([][]float64, 0)
r.Reduce(func(i Iterator) float64 {
for i.Next() {
bucket := i.Bucket()
buckets = append(buckets, bucket.Points)
}
return 0.0
})
return buckets
}
r.Add(1)
time.Sleep(time.Second)
assert.Equal(t, [][]float64{{}, {1}}, listBuckets())
time.Sleep(time.Second)
assert.Equal(t, [][]float64{{1}}, listBuckets())
time.Sleep(time.Second)
assert.Equal(t, [][]float64{}, listBuckets())
// cross window
r.Add(1)
time.Sleep(time.Second * 5)
assert.Equal(t, [][]float64{}, listBuckets())
}
func TestRollingGaugeReduce(t *testing.T) {
size := 3
bucketDuration := time.Second
opts := RollingGaugeOpts{
Size: size,
BucketDuration: bucketDuration,
}
r := NewRollingGauge(opts)
for x := 0; x < size; x = x + 1 {
for i := 0; i <= x; i++ {
r.Add(int64(i))
}
if x < size-1 {
time.Sleep(bucketDuration)
}
}
var result = r.Reduce(func(i Iterator) float64 {
var result float64
for i.Next() {
bucket := i.Bucket()
for _, point := range bucket.Points {
result += point
}
}
return result
})
if result != 4.0 {
t.Fatalf("Validate sum of points. result: %f", result)
}
}
func TestRollingGaugeDataRace(t *testing.T) {
size := 3
bucketDuration := time.Second
opts := RollingGaugeOpts{
Size: size,
BucketDuration: bucketDuration,
}
r := NewRollingGauge(opts)
var stop = make(chan bool)
go func() {
for {
select {
case <-stop:
return
default:
r.Add(rand.Int63())
time.Sleep(time.Millisecond * 5)
}
}
}()
go func() {
for {
select {
case <-stop:
return
default:
_ = r.Reduce(func(i Iterator) float64 {
for i.Next() {
bucket := i.Bucket()
for range bucket.Points {
continue
}
}
return 0
})
}
}
}()
time.Sleep(time.Second * 3)
close(stop)
}
func BenchmarkRollingGaugeIncr(b *testing.B) {
size := 10
bucketDuration := time.Second
opts := RollingGaugeOpts{
Size: size,
BucketDuration: bucketDuration,
}
r := NewRollingGauge(opts)
b.ResetTimer()
for i := 0; i <= b.N; i++ {
r.Add(1.0)
}
}
func BenchmarkRollingGaugeReduce(b *testing.B) {
size := 10
bucketDuration := time.Second
opts := RollingGaugeOpts{
Size: size,
BucketDuration: bucketDuration,
}
r := NewRollingGauge(opts)
for i := 0; i <= 10; i++ {
r.Add(1.0)
time.Sleep(time.Millisecond * 500)
}
b.ResetTimer()
for i := 0; i <= b.N; i++ {
var _ = r.Reduce(func(i Iterator) float64 {
var result float64
for i.Next() {
bucket := i.Bucket()
if len(bucket.Points) != 0 {
result += bucket.Points[0]
}
}
return result
})
}
}