SSE: Localize/Contain Errors within an Expression (#73163)
Changes SSE to not always fail all queries when one fails. Now only the query itself, and nodes that depend on it will error. --------- Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com>
This commit is contained in:
co-authored by
Gilles De Mey
parent
01755608db
commit
35e488b22b
@@ -307,7 +307,7 @@ func (e *State) union(aResults, bResults Results, biNode *parse.BinaryNode) []*U
|
||||
}
|
||||
|
||||
func (e *State) walkBinary(node *parse.BinaryNode) (Results, error) {
|
||||
res := Results{Values{}}
|
||||
res := Results{Values: Values{}}
|
||||
ar, err := e.walk(node.Args[0])
|
||||
if err != nil {
|
||||
return res, err
|
||||
|
||||
@@ -27,114 +27,102 @@ func TestNaN(t *testing.T) {
|
||||
{
|
||||
name: "unary !: Op Number(NaN) is NaN",
|
||||
expr: "! $A",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("", nil, NaN)}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("", nil, NaN))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{[]Value{makeNumber("", nil, NaN)}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "unary -: Op Number(NaN) is NaN",
|
||||
expr: "-$A",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("", nil, NaN)}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("", nil, NaN))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{[]Value{makeNumber("", nil, NaN)}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "binary: Scalar Op(Non-AND/OR) Number(NaN) is NaN",
|
||||
expr: "1 * $A",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("", nil, NaN)}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("", nil, NaN))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{[]Value{makeNumber("", nil, NaN)}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "binary: Scalar Op(AND/OR) Number(NaN) is 0/1",
|
||||
expr: "1 || $A",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("", nil, NaN)}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("", nil, NaN))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{[]Value{makeNumber("", nil, float64Pointer(1))}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(1))),
|
||||
},
|
||||
{
|
||||
name: "binary: Scalar Op(Non-AND/OR) Series(with NaN value) is NaN)",
|
||||
expr: "1 - $A",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(-1),
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
},
|
||||
),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(-1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "binary: Number Op(Non-AND/OR) Series(with NaN value) is Series with NaN",
|
||||
expr: "$A == $B",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
},
|
||||
},
|
||||
"B": Results{[]Value{makeNumber("", nil, float64Pointer(0))}},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(0),
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
},
|
||||
),
|
||||
"B": resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(0),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "binary: Number(NaN) Op Series(with NaN value) is Series with NaN",
|
||||
expr: "$A + $B",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
},
|
||||
},
|
||||
"B": Results{[]Value{makeNumber("", nil, NaN)}},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), NaN,
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
},
|
||||
),
|
||||
"B": resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), NaN,
|
||||
}, tp{
|
||||
time.Unix(10, 0), NaN,
|
||||
}),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -200,200 +188,144 @@ func TestNullValues(t *testing.T) {
|
||||
name: "series: unary with a null value in it has a null value in result",
|
||||
expr: "- $A",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(-1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "series: binary with a null value in it has a null value in result",
|
||||
expr: "$A - $A",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(0),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "series and scalar: binary with a null value in it has a nil value in result",
|
||||
expr: "$A - 1",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(0),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "number: unary ! null number: is null",
|
||||
expr: "! $A",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "number: binary null number and null number: is null",
|
||||
expr: "$A + $A",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "number: binary non-null number and null number: is null",
|
||||
expr: "$A * $B",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
"B": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "number and series: binary non-null number and series with a null: is null",
|
||||
expr: "$A * $B",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(1)),
|
||||
},
|
||||
},
|
||||
"B": Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(-1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "series: binary with a null value in it has a null value in result",
|
||||
expr: "$A - $A",
|
||||
vars: Vars{
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(0),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "series and scalar: binary with a null value in it has a nil value in result",
|
||||
expr: "$A - 1",
|
||||
vars: Vars{
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(0),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "number: unary ! null number: is null",
|
||||
expr: "! $A",
|
||||
vars: Vars{
|
||||
"A": resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
{
|
||||
name: "number: binary null number and null number: is null",
|
||||
expr: "$A + $A",
|
||||
vars: Vars{
|
||||
"A": resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
{
|
||||
name: "number: binary non-null number and null number: is null",
|
||||
expr: "$A * $B",
|
||||
vars: Vars{
|
||||
"A": resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
"B": resultValuesNoErr(makeNumber("", nil, float64Pointer(1))),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
{
|
||||
name: "number and series: binary non-null number and series with a null: is null",
|
||||
expr: "$A * $B",
|
||||
vars: Vars{
|
||||
"A": resultValuesNoErr(makeNumber("", nil, float64Pointer(1))),
|
||||
"B": resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "number and series: binary null number and series with non-null and null: is null and null",
|
||||
expr: "$A * $B",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
"B": Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
"A": resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
"B": resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), nil,
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
),
|
||||
},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), nil,
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -442,7 +374,7 @@ func TestNoData(t *testing.T) {
|
||||
"!$A",
|
||||
"-$A",
|
||||
}
|
||||
vars := Vars{"A": Results{[]Value{NewNoData()}}}
|
||||
vars := Vars{"A": resultValuesNoErr(NewNoData())}
|
||||
for _, expr := range unaryOps {
|
||||
t.Run(fmt.Sprintf("op: %s", expr), func(t *testing.T) {
|
||||
e, err := New(expr)
|
||||
@@ -459,8 +391,8 @@ func TestNoData(t *testing.T) {
|
||||
|
||||
makeVars := func(a, b Value) Vars {
|
||||
return Vars{
|
||||
"A": Results{[]Value{a}},
|
||||
"B": Results{[]Value{b}},
|
||||
"A": resultValuesNoErr(a),
|
||||
"B": resultValuesNoErr(b),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestScalarExpr(t *testing.T) {
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
Results: Results{[]Value{NewScalar("", float64Pointer(1.0))}},
|
||||
Results: resultValuesNoErr(NewScalar("", float64Pointer(1.0))),
|
||||
},
|
||||
{
|
||||
name: "unary: scalar",
|
||||
@@ -34,7 +34,7 @@ func TestScalarExpr(t *testing.T) {
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
Results: Results{[]Value{NewScalar("", float64Pointer(0.0))}},
|
||||
Results: resultValuesNoErr(NewScalar("", float64Pointer(0.0))),
|
||||
},
|
||||
{
|
||||
name: "binary: scalar Op scalar",
|
||||
@@ -43,7 +43,7 @@ func TestScalarExpr(t *testing.T) {
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
Results: Results{[]Value{NewScalar("", float64Pointer(2.0))}},
|
||||
Results: resultValuesNoErr(NewScalar("", float64Pointer(2.0))),
|
||||
},
|
||||
{
|
||||
name: "binary: scalar Op scalar - divide by zero",
|
||||
@@ -52,25 +52,25 @@ func TestScalarExpr(t *testing.T) {
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
Results: Results{[]Value{NewScalar("", float64Pointer(math.Inf(1)))}},
|
||||
Results: resultValuesNoErr(NewScalar("", float64Pointer(math.Inf(1)))),
|
||||
},
|
||||
{
|
||||
name: "binary: scalar Op number",
|
||||
expr: "1 + $A",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("temp", nil, float64Pointer(2.0))}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("temp", nil, float64Pointer(2.0)))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
Results: Results{[]Value{makeNumber("", nil, float64Pointer(3.0))}},
|
||||
Results: resultValuesNoErr(makeNumber("", nil, float64Pointer(3.0))),
|
||||
},
|
||||
{
|
||||
name: "binary: number Op Scalar",
|
||||
expr: "$A - 3",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("temp", nil, float64Pointer(2.0))}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("temp", nil, float64Pointer(2.0)))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
Results: Results{[]Value{makeNumber("", nil, float64Pointer(-1))}},
|
||||
Results: resultValuesNoErr(makeNumber("", nil, float64Pointer(-1))),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -101,20 +101,20 @@ func TestNumberExpr(t *testing.T) {
|
||||
{
|
||||
name: "binary: number Op Scalar",
|
||||
expr: "$A / $A",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("temp", nil, float64Pointer(2.0))}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("temp", nil, float64Pointer(2.0)))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
results: Results{[]Value{makeNumber("", nil, float64Pointer(1))}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(1))),
|
||||
},
|
||||
{
|
||||
name: "unary: number",
|
||||
expr: "- $A",
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("temp", nil, float64Pointer(2.0))}}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("temp", nil, float64Pointer(2.0)))},
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
results: Results{[]Value{makeNumber("", nil, float64Pointer(-2.0))}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(-2.0))),
|
||||
},
|
||||
{
|
||||
name: "binary: Scalar Op Number (Number will nil val) returns nil",
|
||||
@@ -122,8 +122,8 @@ func TestNumberExpr(t *testing.T) {
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
resultIs: assert.Equal,
|
||||
vars: Vars{"A": Results{[]Value{makeNumber("", nil, nil)}}},
|
||||
results: Results{[]Value{makeNumber("", nil, nil)}},
|
||||
vars: Vars{"A": resultValuesNoErr(makeNumber("", nil, nil))},
|
||||
results: resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -25,15 +25,13 @@ func TestSeriesExpr(t *testing.T) {
|
||||
vars: aSeries,
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "binary scalar Op series",
|
||||
@@ -41,15 +39,13 @@ func TestSeriesExpr(t *testing.T) {
|
||||
vars: aSeries,
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(100),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(99),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(100),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(99),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "binary series Op scalar",
|
||||
@@ -57,15 +53,13 @@ func TestSeriesExpr(t *testing.T) {
|
||||
vars: aSeries,
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(100),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(99),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(100),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(99),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "series Op series",
|
||||
@@ -73,15 +67,13 @@ func TestSeriesExpr(t *testing.T) {
|
||||
vars: aSeries,
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(4),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(2),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{ // Not sure about preservering names...
|
||||
time.Unix(5, 0), float64Pointer(4),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(2),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "series Op number",
|
||||
@@ -89,15 +81,13 @@ func TestSeriesExpr(t *testing.T) {
|
||||
vars: aSeriesbNumber,
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", data.Labels{"id": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(9),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", data.Labels{"id": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(9),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "number Op series",
|
||||
@@ -105,15 +95,13 @@ func TestSeriesExpr(t *testing.T) {
|
||||
vars: aSeriesbNumber,
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", data.Labels{"id": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(9),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", data.Labels{"id": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(9),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "series Op series with label union",
|
||||
@@ -121,20 +109,18 @@ func TestSeriesExpr(t *testing.T) {
|
||||
vars: twoSeriesSets,
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", data.Labels{"sensor": "a", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(6 * .5),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8 * .2),
|
||||
}),
|
||||
makeSeries("", data.Labels{"sensor": "b", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(10 * .5),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(16 * .2),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", data.Labels{"sensor": "a", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(6 * .5),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8 * .2),
|
||||
}),
|
||||
makeSeries("", data.Labels{"sensor": "b", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(10 * .5),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(16 * .2),
|
||||
}),
|
||||
),
|
||||
},
|
||||
// Length of resulting series is A when A + B. However, only points where the time matches
|
||||
// for A and B are added to the result
|
||||
@@ -142,35 +128,29 @@ func TestSeriesExpr(t *testing.T) {
|
||||
name: "series Op series with sparse time join",
|
||||
expr: "$A + $B",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", data.Labels{}, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(2),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"B": Results{
|
||||
[]Value{
|
||||
makeSeries("efficiency", data.Labels{}, tp{
|
||||
time.Unix(5, 0), float64Pointer(3),
|
||||
}, tp{
|
||||
time.Unix(9, 0), float64Pointer(4),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", data.Labels{}, tp{
|
||||
time.Unix(5, 0), float64Pointer(1),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(2),
|
||||
}),
|
||||
),
|
||||
"B": resultValuesNoErr(
|
||||
makeSeries("efficiency", data.Labels{}, tp{
|
||||
time.Unix(5, 0), float64Pointer(3),
|
||||
}, tp{
|
||||
time.Unix(9, 0), float64Pointer(4),
|
||||
}),
|
||||
),
|
||||
},
|
||||
|
||||
newErrIs: assert.NoError,
|
||||
execErrIs: assert.NoError,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{ // Not sure about preserving names...
|
||||
time.Unix(5, 0), float64Pointer(4),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{ // Not sure about preserving names...
|
||||
time.Unix(5, 0), float64Pointer(4),
|
||||
}),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -48,59 +48,56 @@ func boolPointer(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
func resultValuesNoErr(v ...Value) Results {
|
||||
return Results{
|
||||
Values: v,
|
||||
Error: nil,
|
||||
}
|
||||
}
|
||||
|
||||
var aSeries = Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
),
|
||||
}
|
||||
|
||||
var aSeriesbNumber = Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"B": Results{
|
||||
[]Value{
|
||||
makeNumber("volt", data.Labels{"id": "1"}, float64Pointer(7)),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
),
|
||||
"B": resultValuesNoErr(
|
||||
makeNumber("volt", data.Labels{"id": "1"}, float64Pointer(7)),
|
||||
),
|
||||
}
|
||||
|
||||
var twoSeriesSets = Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", data.Labels{"sensor": "a", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(6),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8),
|
||||
}),
|
||||
makeSeries("temp", data.Labels{"sensor": "b", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(10),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(16),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"B": Results{
|
||||
[]Value{
|
||||
makeSeries("efficiency", data.Labels{"turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(.5),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(.2),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", data.Labels{"sensor": "a", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(6),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(8),
|
||||
}),
|
||||
makeSeries("temp", data.Labels{"sensor": "b", "turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(10),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(16),
|
||||
}),
|
||||
),
|
||||
"B": resultValuesNoErr(
|
||||
makeSeries("efficiency", data.Labels{"turbine": "1"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(.5),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(.2),
|
||||
}),
|
||||
),
|
||||
}
|
||||
|
||||
// NaN is just to make the calls a little cleaner, the one
|
||||
|
||||
@@ -23,16 +23,12 @@ func TestAbsFunc(t *testing.T) {
|
||||
name: "abs on number",
|
||||
expr: "abs($A)",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(-7)),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(makeNumber("", nil, float64Pointer(-7))),
|
||||
},
|
||||
newErrIs: require.NoError,
|
||||
execErrIs: require.NoError,
|
||||
resultIs: require.Equal,
|
||||
results: Results{[]Value{makeNumber("", nil, float64Pointer(7))}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(7))),
|
||||
},
|
||||
{
|
||||
name: "abs on scalar",
|
||||
@@ -41,34 +37,30 @@ func TestAbsFunc(t *testing.T) {
|
||||
newErrIs: require.NoError,
|
||||
execErrIs: require.NoError,
|
||||
resultIs: require.Equal,
|
||||
results: Results{[]Value{NewScalar("", float64Pointer(1.0))}},
|
||||
results: resultValuesNoErr(NewScalar("", float64Pointer(1.0))),
|
||||
},
|
||||
{
|
||||
name: "abs on series",
|
||||
expr: "abs($A)",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(-2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(-1),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(-2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(-1),
|
||||
}),
|
||||
),
|
||||
},
|
||||
newErrIs: require.NoError,
|
||||
execErrIs: require.NoError,
|
||||
resultIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "abs on string - should error",
|
||||
@@ -101,51 +93,39 @@ func TestIsNumberFunc(t *testing.T) {
|
||||
name: "is_number on number type with real number value",
|
||||
expr: "is_number($A)",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(6)),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(makeNumber("", nil, float64Pointer(6))),
|
||||
},
|
||||
results: Results{[]Value{makeNumber("", nil, float64Pointer(1))}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(1))),
|
||||
},
|
||||
{
|
||||
name: "is_number on number type with null value",
|
||||
expr: "is_number($A)",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
results: Results{[]Value{makeNumber("", nil, float64Pointer(0))}},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
{
|
||||
name: "is_number on on series",
|
||||
expr: "is_number($A)",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("", nil,
|
||||
tp{time.Unix(5, 0), float64Pointer(5)},
|
||||
tp{time.Unix(10, 0), nil},
|
||||
tp{time.Unix(15, 0), float64Pointer(math.NaN())},
|
||||
tp{time.Unix(20, 0), float64Pointer(math.Inf(-1))},
|
||||
tp{time.Unix(25, 0), float64Pointer(math.Inf(0))}),
|
||||
},
|
||||
},
|
||||
},
|
||||
results: Results{
|
||||
[]Value{
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("", nil,
|
||||
tp{time.Unix(5, 0), float64Pointer(1)},
|
||||
tp{time.Unix(10, 0), float64Pointer(0)},
|
||||
tp{time.Unix(15, 0), float64Pointer(0)},
|
||||
tp{time.Unix(20, 0), float64Pointer(0)},
|
||||
tp{time.Unix(25, 0), float64Pointer(0)}),
|
||||
},
|
||||
tp{time.Unix(5, 0), float64Pointer(5)},
|
||||
tp{time.Unix(10, 0), nil},
|
||||
tp{time.Unix(15, 0), float64Pointer(math.NaN())},
|
||||
tp{time.Unix(20, 0), float64Pointer(math.Inf(-1))},
|
||||
tp{time.Unix(25, 0), float64Pointer(math.Inf(0))}),
|
||||
),
|
||||
},
|
||||
results: resultValuesNoErr(
|
||||
makeSeries("", nil,
|
||||
tp{time.Unix(5, 0), float64Pointer(1)},
|
||||
tp{time.Unix(10, 0), float64Pointer(0)},
|
||||
tp{time.Unix(15, 0), float64Pointer(0)},
|
||||
tp{time.Unix(20, 0), float64Pointer(0)},
|
||||
tp{time.Unix(25, 0), float64Pointer(0)}),
|
||||
),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
||||
+54
-182
@@ -12,23 +12,19 @@ import (
|
||||
)
|
||||
|
||||
var seriesWithNil = Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), nil,
|
||||
}),
|
||||
),
|
||||
}
|
||||
|
||||
var seriesEmpty = Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil),
|
||||
),
|
||||
}
|
||||
|
||||
func TestSeriesReduce(t *testing.T) {
|
||||
@@ -56,11 +52,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: aSeries,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(3)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(3))),
|
||||
},
|
||||
{
|
||||
name: "sum series with a nil value",
|
||||
@@ -69,11 +61,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesWithNil,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "sum empty series",
|
||||
@@ -82,11 +70,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesEmpty,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(0)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
{
|
||||
name: "mean series with a nil value",
|
||||
@@ -95,11 +79,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesWithNil,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "mean empty series",
|
||||
@@ -108,11 +88,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesEmpty,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "min series with a nil value",
|
||||
@@ -121,11 +97,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesWithNil,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "min empty series",
|
||||
@@ -134,11 +106,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesEmpty,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "max series with a nil value",
|
||||
@@ -147,11 +115,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesWithNil,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "max empty series",
|
||||
@@ -160,11 +124,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesEmpty,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "mean series",
|
||||
@@ -173,11 +133,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: aSeries,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(1.5)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(1.5))),
|
||||
},
|
||||
{
|
||||
name: "count empty series",
|
||||
@@ -186,34 +142,24 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesEmpty,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(0)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
{
|
||||
name: "mean series with labels",
|
||||
red: "mean",
|
||||
varToReduce: "A",
|
||||
vars: Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", data.Labels{"host": "a"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", data.Labels{"host": "a"}, tp{
|
||||
time.Unix(5, 0), float64Pointer(2),
|
||||
}, tp{
|
||||
time.Unix(10, 0), float64Pointer(1),
|
||||
}),
|
||||
),
|
||||
},
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", data.Labels{"host": "a"}, float64Pointer(1.5)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", data.Labels{"host": "a"}, float64Pointer(1.5))),
|
||||
},
|
||||
{
|
||||
name: "last empty series",
|
||||
@@ -222,11 +168,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesEmpty,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, NaN)),
|
||||
},
|
||||
{
|
||||
name: "last null series",
|
||||
@@ -235,11 +177,7 @@ func TestSeriesReduce(t *testing.T) {
|
||||
vars: seriesWithNil,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -267,15 +205,13 @@ func TestSeriesReduce(t *testing.T) {
|
||||
}
|
||||
|
||||
var seriesNonNumbers = Vars{
|
||||
"A": Results{
|
||||
[]Value{
|
||||
makeSeries("temp", nil,
|
||||
tp{time.Unix(5, 0), NaN},
|
||||
tp{time.Unix(10, 0), float64Pointer(math.Inf(-1))},
|
||||
tp{time.Unix(15, 0), float64Pointer(math.Inf(1))},
|
||||
tp{time.Unix(15, 0), nil}),
|
||||
},
|
||||
},
|
||||
"A": resultValuesNoErr(
|
||||
makeSeries("temp", nil,
|
||||
tp{time.Unix(5, 0), NaN},
|
||||
tp{time.Unix(10, 0), float64Pointer(math.Inf(-1))},
|
||||
tp{time.Unix(15, 0), float64Pointer(math.Inf(1))},
|
||||
tp{time.Unix(15, 0), nil}),
|
||||
),
|
||||
}
|
||||
|
||||
func TestSeriesReduceDropNN(t *testing.T) {
|
||||
@@ -291,88 +227,56 @@ func TestSeriesReduceDropNN(t *testing.T) {
|
||||
red: "sum",
|
||||
varToReduce: "A",
|
||||
vars: aSeries,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(3)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(3))),
|
||||
},
|
||||
{
|
||||
name: "dropNN: sum series with a nil value",
|
||||
red: "sum",
|
||||
varToReduce: "A",
|
||||
vars: seriesWithNil,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(2)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(2))),
|
||||
},
|
||||
{
|
||||
name: "dropNN: sum empty series",
|
||||
red: "sum",
|
||||
varToReduce: "A",
|
||||
vars: seriesEmpty,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(0)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
{
|
||||
name: "dropNN: mean series with a nil value and real value",
|
||||
red: "mean",
|
||||
varToReduce: "A",
|
||||
vars: seriesWithNil,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(2)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(2))),
|
||||
},
|
||||
{
|
||||
name: "DropNN: mean empty series",
|
||||
red: "mean",
|
||||
varToReduce: "A",
|
||||
vars: seriesEmpty,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
{
|
||||
name: "DropNN: mean series that becomes empty after filtering non-number",
|
||||
red: "mean",
|
||||
varToReduce: "A",
|
||||
vars: seriesNonNumbers,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, nil),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, nil)),
|
||||
},
|
||||
{
|
||||
name: "DropNN: count empty series",
|
||||
red: "count",
|
||||
varToReduce: "A",
|
||||
vars: seriesEmpty,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(0)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
{
|
||||
name: "DropNN: count series with nil and value should only count real numbers",
|
||||
red: "count",
|
||||
varToReduce: "A",
|
||||
vars: seriesWithNil,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(1)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(1))),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -410,88 +314,56 @@ func TestSeriesReduceReplaceNN(t *testing.T) {
|
||||
red: "sum",
|
||||
varToReduce: "A",
|
||||
vars: aSeries,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(3)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(3))),
|
||||
},
|
||||
{
|
||||
name: "replaceNN: sum series with a nil value",
|
||||
red: "sum",
|
||||
varToReduce: "A",
|
||||
vars: seriesWithNil,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(replaceWith+2)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(replaceWith+2))),
|
||||
},
|
||||
{
|
||||
name: "replaceNN: sum empty series",
|
||||
red: "sum",
|
||||
varToReduce: "A",
|
||||
vars: seriesEmpty,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(0)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
{
|
||||
name: "replaceNN: mean series with a nil value and real value",
|
||||
red: "mean",
|
||||
varToReduce: "A",
|
||||
vars: seriesWithNil,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer((2+replaceWith)/2e0)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer((2+replaceWith)/2e0))),
|
||||
},
|
||||
{
|
||||
name: "replaceNN: mean empty series",
|
||||
red: "mean",
|
||||
varToReduce: "A",
|
||||
vars: seriesEmpty,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(replaceWith)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(replaceWith))),
|
||||
},
|
||||
{
|
||||
name: "replaceNN: mean series that becomes empty after filtering non-number",
|
||||
red: "mean",
|
||||
varToReduce: "A",
|
||||
vars: seriesNonNumbers,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(replaceWith)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(replaceWith))),
|
||||
},
|
||||
{
|
||||
name: "replaceNN: count empty series",
|
||||
red: "count",
|
||||
varToReduce: "A",
|
||||
vars: seriesEmpty,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(0)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(0))),
|
||||
},
|
||||
{
|
||||
name: "replaceNN: count series with nil and value should only count real numbers",
|
||||
red: "count",
|
||||
varToReduce: "A",
|
||||
vars: seriesWithNil,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, float64Pointer(2)),
|
||||
},
|
||||
},
|
||||
results: resultValuesNoErr(makeNumber("", nil, float64Pointer(2))),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
// Results is a container for Value interfaces.
|
||||
type Results struct {
|
||||
Values Values
|
||||
Error error
|
||||
}
|
||||
|
||||
// Values is a slice of Value interfaces
|
||||
|
||||
Reference in New Issue
Block a user