From 30fc82852aa5a96881eacdd307886c478b0e57d7 Mon Sep 17 00:00:00 2001 From: Thomas Jackson Date: Mon, 20 Jul 2020 11:08:46 -0700 Subject: [PATCH] Handle empty result sets in merge logic Fixes #329 --- pkg/promhttputil/merge.go | 7 ++++ pkg/promhttputil/merge_test.go | 58 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/pkg/promhttputil/merge.go b/pkg/promhttputil/merge.go index fb3b76eae..f1b11fa65 100644 --- a/pkg/promhttputil/merge.go +++ b/pkg/promhttputil/merge.go @@ -181,6 +181,13 @@ func MergeSampleStream(antiAffinityBuffer model.Time, a, b *model.SampleStream) return nil, fmt.Errorf("cannot merge mismatch fingerprints") } + // if either set of values are empty, return the one with data + if len(a.Values) == 0 { + return b, nil + } else if len(b.Values) == 0 { + return a, nil + } + // TODO: really there should be a library method for this in prometheus IMO // At this point we have 2 sorted lists of datapoints which we need to merge newValues := make([]model.SamplePair, 0, len(a.Values)) diff --git a/pkg/promhttputil/merge_test.go b/pkg/promhttputil/merge_test.go index c76a3a9b8..50ac9b56c 100644 --- a/pkg/promhttputil/merge_test.go +++ b/pkg/promhttputil/merge_test.go @@ -509,6 +509,64 @@ func TestMergeValues(t *testing.T) { }), antiAffinity: model.Time(2), }, + + { + name: "Matrix merge empty A", + a: model.Matrix([]*model.SampleStream{ + { + model.Metric(model.LabelSet{model.MetricNameLabel: model.LabelValue("hosta")}), + []model.SamplePair{}, + }, + }), + b: model.Matrix([]*model.SampleStream{ + { + model.Metric(model.LabelSet{model.MetricNameLabel: model.LabelValue("hosta")}), + []model.SamplePair{{ + model.Time(100), + model.SampleValue(10), + }}, + }, + }), + r: model.Matrix([]*model.SampleStream{ + { + model.Metric(model.LabelSet{model.MetricNameLabel: model.LabelValue("hosta")}), + []model.SamplePair{{ + model.Time(100), + model.SampleValue(10), + }}, + }, + }), + antiAffinity: model.Time(2), + }, + + { + name: "Matrix merge empty A", + a: model.Matrix([]*model.SampleStream{ + { + model.Metric(model.LabelSet{model.MetricNameLabel: model.LabelValue("hosta")}), + []model.SamplePair{{ + model.Time(100), + model.SampleValue(10), + }}, + }, + }), + b: model.Matrix([]*model.SampleStream{ + { + model.Metric(model.LabelSet{model.MetricNameLabel: model.LabelValue("hosta")}), + []model.SamplePair{}, + }, + }), + r: model.Matrix([]*model.SampleStream{ + { + model.Metric(model.LabelSet{model.MetricNameLabel: model.LabelValue("hosta")}), + []model.SamplePair{{ + model.Time(100), + model.SampleValue(10), + }}, + }, + }), + antiAffinity: model.Time(2), + }, } for _, test := range tests {