grafana/pkg/expr/mathexp/union_test.go
Kyle Brandt 4093fae99a
SSE: Refactor to simplify Series type (#35063)
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
2021-06-02 12:29:19 -04:00

245 lines
6.9 KiB
Go

package mathexp
import (
"testing"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/stretchr/testify/assert"
)
func Test_union(t *testing.T) {
var tests = []struct {
name string
aResults Results
bResults Results
unionsAre assert.ComparisonAssertionFunc
unions []*Union
}{
{
name: "equal tags single union",
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "1"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{
{
Labels: data.Labels{"id": "1"},
A: makeSeries("a", data.Labels{"id": "1"}),
B: makeSeries("b", data.Labels{"id": "1"}),
},
},
},
{
name: "equal tags keys with no matching values will result in a union when len(A) == 1 && len(B) == 1",
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "2"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{
{
A: makeSeries("a", data.Labels{"id": "1"}),
B: makeSeries("b", data.Labels{"id": "2"}),
},
},
},
{
name: "equal tags keys with no matching values will result in no unions when len(A) != 1 && len(B) != 1",
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1"}),
makeSeries("q", data.Labels{"id": "3"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "2"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{},
},
{
name: "empty results will result in no unions",
aResults: Results{},
bResults: Results{},
unionsAre: assert.EqualValues,
unions: []*Union{},
},
{
name: "incompatible tags of different length with will result in no unions when len(A) != 1 && len(B) != 1",
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"ID": "1"}),
makeSeries("q", data.Labels{"ID": "3"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "1", "fish": "red snapper"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{},
},
{
name: "A is subset of B results in single union with Labels of B",
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{
{
Labels: data.Labels{"id": "1", "fish": "herring"}, // Union gets the labels that is not the subset
A: makeSeries("a", data.Labels{"id": "1"}),
B: makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
},
},
},
{
name: "B is subset of A results in single union with Labels of A",
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1", "fish": "herring"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "1"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{
{
Labels: data.Labels{"id": "1", "fish": "herring"}, // Union gets the labels that is not the subset
A: makeSeries("a", data.Labels{"id": "1", "fish": "herring"}),
B: makeSeries("b", data.Labels{"id": "1"}),
},
},
},
{
name: "single valued A is subset of many valued B, results in many union with Labels of B",
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
makeSeries("b", data.Labels{"id": "1", "fish": "red snapper"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{
{
Labels: data.Labels{"id": "1", "fish": "herring"},
A: makeSeries("a", data.Labels{"id": "1"}),
B: makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
},
{
Labels: data.Labels{"id": "1", "fish": "red snapper"},
A: makeSeries("a", data.Labels{"id": "1"}),
B: makeSeries("b", data.Labels{"id": "1", "fish": "red snapper"}),
},
},
},
{
name: "A with different tags keys lengths to B makes 3 unions (with two unions have matching tags)",
// Is this the behavior we want? A result within the results will no longer
// be uniquely identifiable.
aResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1"}),
makeSeries("aa", data.Labels{"id": "1", "fish": "herring"}),
},
},
bResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
makeSeries("bb", data.Labels{"id": "1", "fish": "red snapper"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{
{
Labels: data.Labels{"id": "1", "fish": "herring"},
A: makeSeries("a", data.Labels{"id": "1"}),
B: makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
},
{
Labels: data.Labels{"id": "1", "fish": "red snapper"},
A: makeSeries("a", data.Labels{"id": "1"}),
B: makeSeries("bb", data.Labels{"id": "1", "fish": "red snapper"}),
},
{
Labels: data.Labels{"id": "1", "fish": "herring"},
A: makeSeries("aa", data.Labels{"id": "1", "fish": "herring"}),
B: makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
},
},
},
{
name: "B with different tags keys lengths to A makes 3 unions (with two unions have matching tags)",
// Is this the behavior we want? A result within the results will no longer
// be uniquely identifiable.
aResults: Results{
Values: Values{
makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
makeSeries("bb", data.Labels{"id": "1", "fish": "red snapper"}),
},
},
bResults: Results{
Values: Values{
makeSeries("a", data.Labels{"id": "1"}),
makeSeries("aa", data.Labels{"id": "1", "fish": "herring"}),
},
},
unionsAre: assert.EqualValues,
unions: []*Union{
{
Labels: data.Labels{"id": "1", "fish": "herring"},
A: makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
B: makeSeries("a", data.Labels{"id": "1"}),
},
{
Labels: data.Labels{"id": "1", "fish": "herring"},
A: makeSeries("b", data.Labels{"id": "1", "fish": "herring"}),
B: makeSeries("aa", data.Labels{"id": "1", "fish": "herring"}),
},
{
Labels: data.Labels{"id": "1", "fish": "red snapper"},
A: makeSeries("bb", data.Labels{"id": "1", "fish": "red snapper"}),
B: makeSeries("a", data.Labels{"id": "1"}),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
unions := union(tt.aResults, tt.bResults)
tt.unionsAre(t, tt.unions, unions)
})
}
}