promql: Move tests to testutil (#6103)

* promql: Move tests to testutil

Signed-off-by: Alex Dzyoba <alex@dzyoba.com>

* promql: Match error type via errors.As in tests

Signed-off-by: Alex Dzyoba <alex@dzyoba.com>

* promql: Remove unused `expectedList` func from lex_test.go

Signed-off-by: Alex Dzyoba <alex@dzyoba.com>
This commit is contained in:
Alex Dzyoba 2019-10-10 03:06:53 +03:00 committed by Chris Marchbanks
parent 81d284f806
commit e3882629ba
6 changed files with 88 additions and 198 deletions

View File

@ -15,12 +15,11 @@ package promql
import ( import (
"context" "context"
"reflect" "errors"
"testing" "testing"
"time" "time"
"github.com/go-kit/kit/log" "github.com/go-kit/kit/log"
"github.com/pkg/errors"
"github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/labels"
"github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/storage"
@ -104,14 +103,14 @@ func TestQueryTimeout(t *testing.T) {
}) })
res := query.Exec(ctx) res := query.Exec(ctx)
if res.Err == nil { testutil.NotOk(t, res.Err, "expected timeout error but got none")
t.Fatalf("expected timeout error but got none")
} var e ErrQueryTimeout
if _, ok := res.Err.(ErrQueryTimeout); res.Err != nil && !ok { testutil.Assert(t, errors.As(res.Err, &e), "expected timeout error but got: %s", res.Err)
t.Fatalf("expected timeout error but got: %s", res.Err)
}
} }
const errQueryCanceled = ErrQueryCanceled("test statement execution")
func TestQueryCancel(t *testing.T) { func TestQueryCancel(t *testing.T) {
opts := EngineOpts{ opts := EngineOpts{
Logger: nil, Logger: nil,
@ -146,12 +145,8 @@ func TestQueryCancel(t *testing.T) {
block <- struct{}{} block <- struct{}{}
<-processing <-processing
if res.Err == nil { testutil.NotOk(t, res.Err, "expected cancellation error for query1 but got none")
t.Fatalf("expected cancellation error for query1 but got none") testutil.Equals(t, res.Err, errQueryCanceled)
}
if ee := ErrQueryCanceled("test statement execution"); res.Err != ee {
t.Fatalf("expected error %q, got %q", ee, res.Err)
}
// Canceling a query before starting it must have no effect. // Canceling a query before starting it must have no effect.
query2 := engine.newTestQuery(func(ctx context.Context) error { query2 := engine.newTestQuery(func(ctx context.Context) error {
@ -160,9 +155,7 @@ func TestQueryCancel(t *testing.T) {
query2.Cancel() query2.Cancel()
res = query2.Exec(ctx) res = query2.Exec(ctx)
if res.Err != nil { testutil.Ok(t, res.Err)
t.Fatalf("unexpected error on executing query2: %s", res.Err)
}
} }
// errQuerier implements storage.Querier which always returns error. // errQuerier implements storage.Querier which always returns error.
@ -203,28 +196,18 @@ func TestQueryError(t *testing.T) {
defer cancelCtx() defer cancelCtx()
vectorQuery, err := engine.NewInstantQuery(queryable, "foo", time.Unix(1, 0)) vectorQuery, err := engine.NewInstantQuery(queryable, "foo", time.Unix(1, 0))
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error creating query: %q", err)
}
res := vectorQuery.Exec(ctx) res := vectorQuery.Exec(ctx)
if res.Err == nil { testutil.NotOk(t, res.Err, "expected error on failed select but got none")
t.Fatalf("expected error on failed select but got none") testutil.Equals(t, res.Err, errStorage)
}
if res.Err != errStorage {
t.Fatalf("expected error %q, got %q", errStorage, res.Err)
}
matrixQuery, err := engine.NewInstantQuery(queryable, "foo[1m]", time.Unix(1, 0)) matrixQuery, err := engine.NewInstantQuery(queryable, "foo[1m]", time.Unix(1, 0))
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error creating query: %q", err)
}
res = matrixQuery.Exec(ctx) res = matrixQuery.Exec(ctx)
if res.Err == nil { testutil.NotOk(t, res.Err, "expected error on failed select but got none")
t.Fatalf("expected error on failed select but got none") testutil.Equals(t, res.Err, errStorage)
}
if res.Err != errStorage {
t.Fatalf("expected error %q, got %q", errStorage, res.Err)
}
} }
// paramCheckerQuerier implements storage.Querier which checks the start and end times // paramCheckerQuerier implements storage.Querier which checks the start and end times
@ -427,12 +410,8 @@ func TestEngineShutdown(t *testing.T) {
block <- struct{}{} block <- struct{}{}
<-processing <-processing
if res.Err == nil { testutil.NotOk(t, res.Err, "expected error on shutdown during query but got none")
t.Fatalf("expected error on shutdown during query but got none") testutil.Equals(t, res.Err, errQueryCanceled)
}
if ee := ErrQueryCanceled("test statement execution"); res.Err != ee {
t.Fatalf("expected error %q, got %q", ee, res.Err)
}
query2 := engine.newTestQuery(func(context.Context) error { query2 := engine.newTestQuery(func(context.Context) error {
t.Fatalf("reached query execution unexpectedly") t.Fatalf("reached query execution unexpectedly")
@ -442,12 +421,10 @@ func TestEngineShutdown(t *testing.T) {
// The second query is started after the engine shut down. It must // The second query is started after the engine shut down. It must
// be canceled immediately. // be canceled immediately.
res2 := query2.Exec(ctx) res2 := query2.Exec(ctx)
if res2.Err == nil { testutil.NotOk(t, res2.Err, "expected error on querying with canceled context but got none")
t.Fatalf("expected error on querying with canceled context but got none")
} var e ErrQueryCanceled
if _, ok := res2.Err.(ErrQueryCanceled); !ok { testutil.Assert(t, errors.As(res2.Err, &e), "expected cancellation error but got: %s", res2.Err)
t.Fatalf("expected cancellation error, got %q", res2.Err)
}
} }
func TestEngineEvalStmtTimestamps(t *testing.T) { func TestEngineEvalStmtTimestamps(t *testing.T) {
@ -455,15 +432,11 @@ func TestEngineEvalStmtTimestamps(t *testing.T) {
load 10s load 10s
metric 1 2 metric 1 2
`) `)
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error creating test: %q", err)
}
defer test.Close() defer test.Close()
err = test.Run() err = test.Run()
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error initializing test: %q", err)
}
cases := []struct { cases := []struct {
Query string Query string
@ -540,20 +513,16 @@ load 10s
} else { } else {
qry, err = test.QueryEngine().NewRangeQuery(test.Queryable(), c.Query, c.Start, c.End, c.Interval) qry, err = test.QueryEngine().NewRangeQuery(test.Queryable(), c.Query, c.Start, c.End, c.Interval)
} }
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error creating query: %q", err)
}
res := qry.Exec(test.Context()) res := qry.Exec(test.Context())
if c.ShouldError { if c.ShouldError {
testutil.NotOk(t, res.Err, "expected error for the query %q", c.Query) testutil.NotOk(t, res.Err, "expected error for the query %q", c.Query)
continue continue
} }
if res.Err != nil {
t.Fatalf("unexpected error running query: %q", res.Err) testutil.Ok(t, res.Err)
} testutil.Equals(t, res.Value, c.Result)
if !reflect.DeepEqual(res.Value, c.Result) {
t.Fatalf("unexpected result for query %q: got %q wanted %q", c.Query, res.Value.String(), c.Result.String())
}
} }
} }
@ -563,16 +532,11 @@ func TestMaxQuerySamples(t *testing.T) {
load 10s load 10s
metric 1 2 metric 1 2
`) `)
testutil.Ok(t, err)
if err != nil {
t.Fatalf("unexpected error creating test: %q", err)
}
defer test.Close() defer test.Close()
err = test.Run() err = test.Run()
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error initializing test: %q", err)
}
cases := []struct { cases := []struct {
Query string Query string
@ -772,16 +736,11 @@ load 10s
} else { } else {
qry, err = engine.NewRangeQuery(test.Queryable(), c.Query, c.Start, c.End, c.Interval) qry, err = engine.NewRangeQuery(test.Queryable(), c.Query, c.Start, c.End, c.Interval)
} }
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error creating query: %q", err)
}
res := qry.Exec(test.Context()) res := qry.Exec(test.Context())
if res.Err != nil && res.Err != c.Result.Err { testutil.Equals(t, res.Err, c.Result.Err)
t.Fatalf("unexpected error running query: %q, expected to get result: %q", res.Err, c.Result.Value) testutil.Equals(t, res.Value, c.Result.Value)
}
if !reflect.DeepEqual(res.Value, c.Result.Value) {
t.Fatalf("unexpected result for query %q: got %q wanted %q", c.Query, res.Value.String(), c.Result.String())
}
} }
} }
@ -1048,16 +1007,12 @@ func TestSubquerySelector(t *testing.T) {
SetDefaultEvaluationInterval(1 * time.Minute) SetDefaultEvaluationInterval(1 * time.Minute)
for _, tst := range tests { for _, tst := range tests {
test, err := NewTest(t, tst.loadString) test, err := NewTest(t, tst.loadString)
testutil.Ok(t, err)
if err != nil {
t.Fatalf("unexpected error creating test: %q", err)
}
defer test.Close() defer test.Close()
err = test.Run() err = test.Run()
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error initializing test: %q", err)
}
engine := test.QueryEngine() engine := test.QueryEngine()
for _, c := range tst.cases { for _, c := range tst.cases {
@ -1065,16 +1020,11 @@ func TestSubquerySelector(t *testing.T) {
var qry Query var qry Query
qry, err = engine.NewInstantQuery(test.Queryable(), c.Query, c.Start) qry, err = engine.NewInstantQuery(test.Queryable(), c.Query, c.Start)
if err != nil { testutil.Ok(t, err)
t.Fatalf("unexpected error creating query: %q", err)
}
res := qry.Exec(test.Context()) res := qry.Exec(test.Context())
if res.Err != nil && res.Err != c.Result.Err { testutil.Equals(t, res.Err, c.Result.Err)
t.Fatalf("unexpected error running query: %q, expected to get result: %q", res.Err, c.Result.Value) testutil.Equals(t, res.Value, c.Result.Value)
}
if !reflect.DeepEqual(res.Value, c.Result.Value) {
t.Fatalf("unexpected result for query %q: got %q wanted %q", c.Query, res.Value.String(), c.Result.String())
}
} }
} }
} }

View File

@ -14,9 +14,9 @@
package promql package promql
import ( import (
"fmt"
"reflect"
"testing" "testing"
"github.com/prometheus/prometheus/util/testutil"
) )
type testCase struct { type testCase struct {
@ -688,24 +688,12 @@ func TestLexer(t *testing.T) {
t.Fatalf("unexpected lexing error at position %d: %s", lastItem.pos, lastItem) t.Fatalf("unexpected lexing error at position %d: %s", lastItem.pos, lastItem)
} }
if !reflect.DeepEqual(lastItem, item{ItemEOF, Pos(len(test.input)), ""}) { eofItem := item{ItemEOF, Pos(len(test.input)), ""}
t.Logf("%d: input %q", i, test.input) testutil.Equals(t, lastItem, eofItem, "%d: input %q", i, test.input)
t.Fatalf("lexing error: expected output to end with EOF item.\ngot:\n%s", expectedList(out))
}
out = out[:len(out)-1] out = out[:len(out)-1]
if !reflect.DeepEqual(out, test.expected) { testutil.Equals(t, out, test.expected, "%d: input %q", i, test.input)
t.Logf("%d: input %q", i, test.input)
t.Fatalf("lexing mismatch:\nexpected:\n%s\ngot:\n%s", expectedList(test.expected), expectedList(out))
}
} }
}) })
} }
} }
func expectedList(exp []item) string {
s := ""
for _, it := range exp {
s += fmt.Sprintf("\t%#v\n", it)
}
return s
}

View File

@ -15,7 +15,6 @@ package promql
import ( import (
"math" "math"
"reflect"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -1590,26 +1589,14 @@ func TestParseExpressions(t *testing.T) {
expr, err := ParseExpr(test.input) expr, err := ParseExpr(test.input)
// Unexpected errors are always caused by a bug. // Unexpected errors are always caused by a bug.
if err == errUnexpected { testutil.Assert(t, err != errUnexpected, "unexpected error occurred")
t.Fatalf("unexpected error occurred")
}
if !test.fail && err != nil { if !test.fail {
t.Errorf("error in input '%s'", test.input) testutil.Ok(t, err)
t.Fatalf("could not parse: %s", err) testutil.Equals(t, expr, test.expected, "error on input '%s'", test.input)
} } else {
testutil.NotOk(t, err)
if test.fail && err != nil { testutil.Assert(t, strings.Contains(err.Error(), test.errMsg), "unexpected error on input '%s'", test.input)
if !strings.Contains(err.Error(), test.errMsg) {
t.Errorf("unexpected error on input '%s'", test.input)
t.Fatalf("expected error to contain %q but got %q", test.errMsg, err)
}
continue
}
if !reflect.DeepEqual(expr, test.expected) {
t.Errorf("error on input '%s'", test.input)
t.Fatalf("no match\n\nexpected:\n%s\ngot: \n%s\n", Tree(test.expected), Tree(expr))
} }
} }
} }
@ -1617,21 +1604,11 @@ func TestParseExpressions(t *testing.T) {
// NaN has no equality. Thus, we need a separate test for it. // NaN has no equality. Thus, we need a separate test for it.
func TestNaNExpression(t *testing.T) { func TestNaNExpression(t *testing.T) {
expr, err := ParseExpr("NaN") expr, err := ParseExpr("NaN")
if err != nil { testutil.Ok(t, err)
t.Errorf("error on input 'NaN'")
t.Fatalf("could not parse: %s", err)
}
nl, ok := expr.(*NumberLiteral) nl, ok := expr.(*NumberLiteral)
if !ok { testutil.Assert(t, ok, "expected number literal but got %T", expr)
t.Errorf("error on input 'NaN'") testutil.Assert(t, math.IsNaN(float64(nl.Val)), "expected 'NaN' in number literal but got %v", nl.Val)
t.Fatalf("expected number literal but got %T", expr)
}
if !math.IsNaN(float64(nl.Val)) {
t.Errorf("error on input 'NaN'")
t.Fatalf("expected 'NaN' in number literal but got %v", nl.Val)
}
} }
func mustLabelMatcher(mt labels.MatchType, name, val string) *labels.Matcher { func mustLabelMatcher(mt labels.MatchType, name, val string) *labels.Matcher {
@ -1746,29 +1723,14 @@ func TestParseSeries(t *testing.T) {
metric, vals, err := parseSeriesDesc(test.input) metric, vals, err := parseSeriesDesc(test.input)
// Unexpected errors are always caused by a bug. // Unexpected errors are always caused by a bug.
if err == errUnexpected { testutil.Assert(t, err != errUnexpected, "unexpected error occurred")
t.Fatalf("unexpected error occurred")
}
if test.fail { if !test.fail {
if err != nil { testutil.Ok(t, err)
continue testutil.Equals(t, test.expectedMetric, metric, "error on input '%s'", test.input)
} testutil.Equals(t, test.expectedValues, vals, "error in input '%s'", test.input)
t.Errorf("error in input: \n\n%s\n", test.input)
t.Fatalf("failure expected, but passed")
} else { } else {
if err != nil { testutil.NotOk(t, err)
t.Errorf("error in input: \n\n%s\n", test.input)
t.Fatalf("could not parse: %s", err)
}
}
testutil.Equals(t, test.expectedMetric, metric)
testutil.Equals(t, test.expectedValues, vals)
if !reflect.DeepEqual(vals, test.expectedValues) || !reflect.DeepEqual(metric, test.expectedMetric) {
t.Errorf("error in input: \n\n%s\n", test.input)
t.Fatalf("no match\n\nexpected:\n%s %s\ngot: \n%s %s\n", test.expectedMetric, test.expectedValues, metric, vals)
} }
} }
} }
@ -1778,13 +1740,10 @@ func TestRecoverParserRuntime(t *testing.T) {
var err error var err error
defer func() { defer func() {
if err != errUnexpected { testutil.Equals(t, err, errUnexpected)
t.Fatalf("wrong error message: %q, expected %q", err, errUnexpected)
}
if _, ok := <-p.lex.items; ok { _, ok := <-p.lex.items
t.Fatalf("lex.items was not closed") testutil.Assert(t, !ok, "lex.items was not closed")
}
}() }()
defer p.recover(&err) defer p.recover(&err)
// Cause a runtime panic. // Cause a runtime panic.
@ -1800,9 +1759,7 @@ func TestRecoverParserError(t *testing.T) {
e := errors.New("custom error") e := errors.New("custom error")
defer func() { defer func() {
if err.Error() != e.Error() { testutil.Equals(t, err.Error(), e.Error())
t.Fatalf("wrong error message: %q, expected %q", err, e)
}
}() }()
defer p.recover(&err) defer p.recover(&err)

View File

@ -15,6 +15,8 @@ package promql
import ( import (
"testing" "testing"
"github.com/prometheus/prometheus/util/testutil"
) )
func TestExprString(t *testing.T) { func TestExprString(t *testing.T) {
@ -88,15 +90,13 @@ func TestExprString(t *testing.T) {
for _, test := range inputs { for _, test := range inputs {
expr, err := ParseExpr(test.in) expr, err := ParseExpr(test.in)
if err != nil { testutil.Ok(t, err)
t.Fatalf("parsing error for %q: %s", test.in, err)
}
exp := test.in exp := test.in
if test.out != "" { if test.out != "" {
exp = test.out exp = test.out
} }
if expr.String() != exp {
t.Fatalf("expected %q to be returned as:\n%s\ngot:\n%s\n", test.in, exp, expr.String()) testutil.Equals(t, expr.String(), exp)
}
} }
} }

View File

@ -16,22 +16,21 @@ package promql
import ( import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/prometheus/prometheus/util/testutil"
) )
func TestEvaluations(t *testing.T) { func TestEvaluations(t *testing.T) {
files, err := filepath.Glob("testdata/*.test") files, err := filepath.Glob("testdata/*.test")
if err != nil { testutil.Ok(t, err)
t.Fatal(err)
}
for _, fn := range files { for _, fn := range files {
test, err := newTestFromFile(t, fn) test, err := newTestFromFile(t, fn)
if err != nil { testutil.Ok(t, err)
t.Errorf("error creating test for %s: %s", fn, err)
}
err = test.Run() err = test.Run()
if err != nil { testutil.Ok(t, err)
t.Errorf("error running test %s: %s", fn, err)
}
test.Close() test.Close()
} }
} }

View File

@ -18,6 +18,8 @@ import (
"os" "os"
"regexp" "regexp"
"testing" "testing"
"github.com/prometheus/prometheus/util/testutil"
) )
func TestQueryLogging(t *testing.T) { func TestQueryLogging(t *testing.T) {
@ -106,24 +108,18 @@ func TestIndexReuse(t *testing.T) {
func TestMMapFile(t *testing.T) { func TestMMapFile(t *testing.T) {
file, err := ioutil.TempFile("", "mmapedFile") file, err := ioutil.TempFile("", "mmapedFile")
if err != nil { testutil.Ok(t, err)
t.Fatalf("Couldn't create temp test file. %s", err)
}
filename := file.Name() filename := file.Name()
defer os.Remove(filename) defer os.Remove(filename)
fileAsBytes, err := getMMapedFile(filename, 2, nil) fileAsBytes, err := getMMapedFile(filename, 2, nil)
if err != nil { testutil.Ok(t, err)
t.Fatalf("Couldn't create test mmaped file")
}
copy(fileAsBytes, "ab") copy(fileAsBytes, "ab")
f, err := os.Open(filename) f, err := os.Open(filename)
if err != nil { testutil.Ok(t, err)
t.Fatalf("Couldn't open test mmaped file")
}
bytes := make([]byte, 4) bytes := make([]byte, 4)
n, err := f.Read(bytes) n, err := f.Read(bytes)