pd/pkg/movingaverage/moving_average_test.go

122 lines
3.4 KiB
Go

// Copyright 2018 TiKV Project Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package movingaverage
import (
"math"
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func addRandData(ma MovingAvg, n int, mx float64) {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for range n {
ma.Add(r.Float64() * mx)
}
}
// checkReset checks the Reset works properly.
// emptyValue is the moving average of empty data set.
func checkReset(re *require.Assertions, ma MovingAvg, emptyValue float64) {
addRandData(ma, 100, 1000)
ma.Reset()
re.Equal(emptyValue, ma.Get())
}
// checkAddGet checks Add works properly.
func checkAdd(re *require.Assertions, ma MovingAvg, data []float64, expected []float64) {
re.Len(data, len(expected))
for i, x := range data {
ma.Add(x)
re.Equal(x, ma.GetInstantaneous())
re.LessOrEqual(math.Abs(ma.Get()-expected[i]), 1e-7)
}
}
// checkSet checks Set = Reset + Add
func checkSet(re *require.Assertions, ma MovingAvg, data []float64, expected []float64) {
re.Len(data, len(expected))
// Reset + Add
addRandData(ma, 100, 1000)
ma.Reset()
checkAdd(re, ma, data, expected)
// Set
addRandData(ma, 100, 1000)
ma.Set(data[0])
re.Equal(expected[0], ma.Get())
checkAdd(re, ma, data[1:], expected[1:])
}
// checkInstantaneous checks GetInstantaneous
func checkInstantaneous(re *require.Assertions, ma MovingAvg) {
value := 100.000000
ma.Add(value)
re.Equal(value, ma.GetInstantaneous())
}
func TestMedianFilter(t *testing.T) {
re := require.New(t)
var empty float64 = 0
data := []float64{2, 4, 2, 800, 600, 6, 3}
expected := []float64{2, 3, 2, 3, 4, 6, 6}
mf := NewMedianFilter(5)
re.Equal(empty, mf.Get())
checkReset(re, mf, empty)
checkAdd(re, mf, data, expected)
checkSet(re, mf, data, expected)
}
type testCase struct {
ma MovingAvg
expected []float64
}
func TestMovingAvg(t *testing.T) {
re := require.New(t)
var empty float64 = 0
data := []float64{1, 1, 1, 1, 5, 1, 1, 1}
testCases := []testCase{{
ma: NewEMA(0.9),
expected: []float64{1.000000, 1.000000, 1.000000, 1.000000, 4.600000, 1.360000, 1.036000, 1.003600},
}, {
ma: NewWMA(5),
expected: []float64{1.00000000, 1.00000000, 1.00000000, 1.00000000, 2.33333333, 2.06666667, 1.80000000, 1.533333333},
}, {
ma: NewHMA(5),
expected: []float64{1.0000000, 1.0000000, 1.0000000, 1.0000000, 3.6666667, 3.4000000, 1.0000000, 0.3777778},
}, {
ma: NewMedianFilter(5),
expected: []float64{1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000},
}, {
ma: NewMaxFilter(5),
expected: []float64{1.000000, 1.000000, 1.000000, 1.000000, 5.000000, 5.000000, 5.000000, 5.000000},
},
}
for _, testCase := range testCases {
re.Equal(empty, testCase.ma.Get())
checkReset(re, testCase.ma, empty)
checkAdd(re, testCase.ma, data, testCase.expected)
checkSet(re, testCase.ma, data, testCase.expected)
checkInstantaneous(re, testCase.ma)
}
}