Add regression tests for metrics mutations in AST.
It turned out in the end, that only drop_common_metrics() produced any erroneous output in the old system. The second expression in the test ("sum(testmetric) keeping_extra") already worked in the old code, but why not keep it in... The way to test ranged evaluations is a bit clumsy so far, so I want to build a nicer test framework in the end, where all the test cases can be specified as text files which specify desired inputs, outputs, query step widths, etc. Change-Id: I821859789e69b8232bededf670a1b76e9e8c8ca4
This commit is contained in:
parent
c9618d11e8
commit
00a2a93a05
|
@ -40,6 +40,7 @@ type SampleStream struct {
|
|||
Values metric.Values
|
||||
}
|
||||
|
||||
// Sample is a single sample belonging to a COWMetric.
|
||||
type Sample struct {
|
||||
Metric clientmodel.COWMetric
|
||||
Value clientmodel.SampleValue
|
||||
|
@ -413,7 +414,7 @@ func EvalVectorRange(node VectorNode, start clientmodel.Timestamp, end clientmod
|
|||
// TODO implement watchdog timer for long-running queries.
|
||||
evalTimer := queryStats.GetTimer(stats.InnerEvalTime).Start()
|
||||
sampleStreams := map[uint64]*SampleStream{}
|
||||
for t := start; t.Before(end); t = t.Add(interval) {
|
||||
for t := start; !t.After(end); t = t.Add(interval) {
|
||||
vector := node.Eval(t)
|
||||
for _, sample := range vector {
|
||||
samplePair := metric.SamplePair{
|
||||
|
|
|
@ -91,11 +91,12 @@ func (vector Vector) String() string {
|
|||
func (matrix Matrix) String() string {
|
||||
metricStrings := make([]string, 0, len(matrix))
|
||||
for _, sampleStream := range matrix {
|
||||
metricName, ok := sampleStream.Metric.Metric[clientmodel.MetricNameLabel]
|
||||
if !ok {
|
||||
panic("Tried to print matrix without metric name")
|
||||
metricName, hasName := sampleStream.Metric.Metric[clientmodel.MetricNameLabel]
|
||||
numLabels := len(sampleStream.Metric.Metric)
|
||||
if hasName {
|
||||
numLabels--
|
||||
}
|
||||
labelStrings := make([]string, 0, len(sampleStream.Metric.Metric)-1)
|
||||
labelStrings := make([]string, 0, numLabels)
|
||||
for label, value := range sampleStream.Metric.Metric {
|
||||
if label != clientmodel.MetricNameLabel {
|
||||
labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value))
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/prometheus/prometheus/rules/ast"
|
||||
"github.com/prometheus/prometheus/stats"
|
||||
"github.com/prometheus/prometheus/storage/local"
|
||||
"github.com/prometheus/prometheus/storage/metric"
|
||||
"github.com/prometheus/prometheus/utility/test"
|
||||
)
|
||||
|
||||
|
@ -60,7 +61,7 @@ func newTestStorage(t testing.TB) (storage local.Storage, closer test.Closer) {
|
|||
|
||||
func TestExpressions(t *testing.T) {
|
||||
// Labels in expected output need to be alphabetically sorted.
|
||||
var expressionTests = []struct {
|
||||
expressionTests := []struct {
|
||||
expr string
|
||||
output []string
|
||||
shouldFail bool
|
||||
|
@ -705,6 +706,188 @@ func TestExpressions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRangedEvaluationRegressions(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
in ast.Matrix
|
||||
out ast.Matrix
|
||||
expr string
|
||||
}{
|
||||
{
|
||||
// Testing COWMetric behavior in drop_common_labels.
|
||||
in: ast.Matrix{
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
clientmodel.MetricNameLabel: "testmetric",
|
||||
"testlabel": "1",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime,
|
||||
Value: 1,
|
||||
},
|
||||
{
|
||||
Timestamp: testStartTime.Add(time.Hour),
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
clientmodel.MetricNameLabel: "testmetric",
|
||||
"testlabel": "2",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime.Add(time.Hour),
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: ast.Matrix{
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
clientmodel.MetricNameLabel: "testmetric",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime,
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
clientmodel.MetricNameLabel: "testmetric",
|
||||
"testlabel": "1",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime.Add(time.Hour),
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
clientmodel.MetricNameLabel: "testmetric",
|
||||
"testlabel": "2",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime.Add(time.Hour),
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expr: "drop_common_labels(testmetric)",
|
||||
},
|
||||
{
|
||||
// Testing COWMetric behavior in vector aggregation.
|
||||
in: ast.Matrix{
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
clientmodel.MetricNameLabel: "testmetric",
|
||||
"testlabel": "1",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime,
|
||||
Value: 1,
|
||||
},
|
||||
{
|
||||
Timestamp: testStartTime.Add(time.Hour),
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
clientmodel.MetricNameLabel: "testmetric",
|
||||
"testlabel": "2",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime,
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: ast.Matrix{
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime,
|
||||
Value: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Metric: clientmodel.COWMetric{
|
||||
Metric: clientmodel.Metric{
|
||||
"testlabel": "1",
|
||||
},
|
||||
},
|
||||
Values: metric.Values{
|
||||
{
|
||||
Timestamp: testStartTime.Add(time.Hour),
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expr: "sum(testmetric) keeping_extra",
|
||||
},
|
||||
}
|
||||
|
||||
for i, s := range scenarios {
|
||||
storage, closer := local.NewTestStorage(t)
|
||||
storeMatrix(storage, s.in)
|
||||
|
||||
expr, err := LoadExprFromString(s.expr)
|
||||
if err != nil {
|
||||
t.Fatalf("%d. Error parsing expression: %v", i, err)
|
||||
}
|
||||
|
||||
got, err := ast.EvalVectorRange(
|
||||
expr.(ast.VectorNode),
|
||||
testStartTime,
|
||||
testStartTime.Add(time.Hour),
|
||||
time.Hour,
|
||||
storage,
|
||||
stats.NewTimerGroup(),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("%d. Error evaluating expression: %v", i, err)
|
||||
}
|
||||
|
||||
if got.String() != s.out.String() {
|
||||
t.Fatalf("%d. Expression: %s\n\ngot:\n=====\n%v\n====\n\nwant:\n=====\n%v\n=====\n", i, s.expr, got.String(), s.out.String())
|
||||
}
|
||||
|
||||
closer.Close()
|
||||
}
|
||||
}
|
||||
|
||||
var ruleTests = []struct {
|
||||
inputFile string
|
||||
shouldFail bool
|
||||
|
|
Loading…
Reference in New Issue