blob: 537b3cce0e1fff8c4aa84b63820135d91edde609 [file] [log] [blame]
package compare
import (
"sort"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.skia.org/infra/pinpoint/go/compare/thresholds"
)
func convertNormalizedToRawMagnitude(a, b []float64, normMagnitude float64) float64 {
all_values := append(a, b...)
sort.Float64s(all_values)
iqr := all_values[len(all_values)*3/4] - all_values[len(all_values)/4]
return normMagnitude * iqr
}
func TestCompareFunctional_GivenNoData_ReturnsError(t *testing.T) {
x := []float64{}
y := []float64{0, 0, 0, 0, 0}
const expected = Unknown
result, err := CompareFunctional(x, y, DefaultFunctionalErrRate)
assert.Error(t, err)
assert.Equal(t, ErrorVerdict, result.Verdict)
}
func TestCompareFunctional_GivenValidInputs_ReturnsCorrectResult(t *testing.T) {
test := func(name string, x, y []float64, expectedErrRate float64, expected Verdict) {
t.Run(name, func(t *testing.T) {
result, err := CompareFunctional(x, y, expectedErrRate)
assert.NoError(t, err)
assert.Equal(t, expected, result.Verdict)
if result.Verdict == Unknown {
assert.LessOrEqual(t, result.PValue, result.HighThreshold)
assert.Greater(t, result.PValue, result.LowThreshold)
} else if result.Verdict == Same {
assert.Greater(t, result.PValue, result.HighThreshold)
} else if result.Verdict == Different {
assert.LessOrEqual(t, result.PValue, result.LowThreshold)
} else {
t.Errorf("Obtained non-existent verdict %s", result.Verdict)
}
})
}
x := []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
y := []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
test("arrays are slightly different, return unknown", x, y, 0.5, Unknown)
x = []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
y = []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
test("arrays are the same, return same", x, y, 1.0, Same)
x = []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
y = []float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
test("arrays are significantly different, return different", x, y, 1.0, Different)
}
func TestComparePerformance_GivenNoData_ReturnsNil(t *testing.T) {
x := []float64{0, 0, 0, 0, 0}
y := []float64{}
const magnitude = 1.0
const expected = Unknown
result, err := ComparePerformance(x, y, magnitude, UnknownDir)
assert.NoError(t, err)
assert.Equal(t, NilVerdict, result.Verdict)
}
func TestComparePerformance_GivenValidInputs_ReturnsCorrectResult(t *testing.T) {
test := func(name string, x, y []float64, magnitude float64, expected Verdict) {
t.Run(name, func(t *testing.T) {
result, err := ComparePerformance(x, y, magnitude, UnknownDir)
assert.NoError(t, err)
assert.Equal(t, expected, result.Verdict)
switch result.Verdict {
case Unknown:
assert.LessOrEqual(t, result.PValue, result.HighThreshold)
assert.Greater(t, result.PValue, result.LowThreshold)
case Same:
assert.Greater(t, result.PValue, result.HighThreshold)
case Different:
assert.LessOrEqual(t, result.PValue, result.LowThreshold)
default:
assert.Fail(t, "Unsupported verdict found %s", result.Verdict)
}
})
}
x := []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
y := []float64{3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
mag := convertNormalizedToRawMagnitude(x, y, 0.5)
test("arrays are slightly different, return unknown", x, y, mag, Unknown)
x = []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
y = []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
test("arrays are the same, return same", x, y, 0.0, Same)
x = []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
y = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
test("arrays are significantly different, return different", x, y, 0.0, Different)
}
func TestCompare_GivenImprovement_ReturnsSameAndNoPValue(t *testing.T) {
test := func(name string, x, y []float64, dir ImprovementDir) {
t.Run(name, func(t *testing.T) {
result, err := compare(x, y, 0.0, 0.0, dir)
require.NoError(t, err)
assert.Equal(t, Same, result.Verdict)
assert.Zero(t, result.PValue)
switch dir {
case Up:
assert.Positive(t, result.MeanDiff)
case Down:
assert.Negative(t, result.MeanDiff)
}
})
}
var x = []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
var y = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
test("x < y, ImprovementDir = Up, return same", x, y, Up)
x = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
y = []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
test("x > y, ImprovementDir = Down, return same", x, y, Down)
}
func TestCompare_GivenRegression_ReturnsPValue(t *testing.T) {
test := func(name string, x, y []float64, dir ImprovementDir) {
t.Run(name, func(t *testing.T) {
result, err := compare(x, y, 0.0, 0.0, dir)
require.NoError(t, err)
assert.NotZero(t, result.PValue)
switch dir {
case Up:
assert.Negative(t, result.MeanDiff)
case Down:
assert.Positive(t, result.MeanDiff)
}
})
}
var x = []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
var y = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
test("x < y, ImprovementDir = Down", x, y, Down)
x = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
y = []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
test("x > y, ImprovementDir = Up", x, y, Up)
}
func TestComparePairwise_GivenImprovement_ReturnsSame(t *testing.T) {
test := func(name string, x, y []float64, dir ImprovementDir) {
t.Run(name, func(t *testing.T) {
result, err := ComparePairwise(x, y, dir)
require.NoError(t, err)
require.LessOrEqual(t, result.PairwiseWilcoxonSignedRankedTestResult.PValue, thresholds.LowThreshold)
assert.Equal(t, Same, result.Verdict)
switch dir {
case Up:
assert.Positive(t, result.PairwiseWilcoxonSignedRankedTestResult.UpperCi)
case Down:
assert.Negative(t, result.PairwiseWilcoxonSignedRankedTestResult.LowerCi)
}
})
}
var x = []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}
var y = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15}
test("x < y, ImprovementDir = Up", x, y, Up)
x = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15}
y = []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}
test("x > y, ImprovementDir = Down", x, y, Down)
}
func TestComparePairwise_GivenRegression_ReturnsDifferent(t *testing.T) {
test := func(name string, x, y []float64, dir ImprovementDir) {
t.Run(name, func(t *testing.T) {
result, err := ComparePairwise(x, y, dir)
require.NoError(t, err)
require.LessOrEqual(t, result.PairwiseWilcoxonSignedRankedTestResult.PValue, thresholds.LowThreshold)
assert.Equal(t, Different, result.Verdict)
assert.Positive(t, result.PairwiseWilcoxonSignedRankedTestResult.LowerCi*result.PairwiseWilcoxonSignedRankedTestResult.UpperCi)
switch dir {
case Up:
assert.Negative(t, result.PairwiseWilcoxonSignedRankedTestResult.UpperCi)
case Down:
assert.Positive(t, result.PairwiseWilcoxonSignedRankedTestResult.LowerCi)
}
})
}
var x = []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}
var y = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15}
test("x < y, ImprovementDir = Down", x, y, Down)
test("x < y, ImprovementDir = Unknown", x, y, UnknownDir)
x = []float64{7, 8, 9, 10, 11, 12, 13, 14, 15}
y = []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}
test("x > y, ImprovementDir = Up", x, y, Up)
}
func TestComparePairwise_GivenNoRegression_ReturnsSame(t *testing.T) {
test := func(name string, x, y []float64, dir ImprovementDir) {
t.Run(name, func(t *testing.T) {
result, err := ComparePairwise(x, y, dir)
require.NoError(t, err)
require.GreaterOrEqual(t, result.PairwiseWilcoxonSignedRankedTestResult.PValue, thresholds.LowThreshold)
assert.Equal(t, Same, result.Verdict)
assert.Negative(t, result.PairwiseWilcoxonSignedRankedTestResult.LowerCi*result.PairwiseWilcoxonSignedRankedTestResult.UpperCi)
})
}
var x = []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}
var y = []float64{1.1, 1.9, 3.1, 3.9, 4.1, 4.9, 6.1, 7.9, 9.1}
test("ImprovementDir = Down", x, y, Down)
test("ImprovementDir = Unknown", x, y, UnknownDir)
}