|
|
|
|
@ -17,6 +17,7 @@ import ( |
|
|
|
|
"bytes" |
|
|
|
|
"compress/gzip" |
|
|
|
|
"context" |
|
|
|
|
"encoding/binary" |
|
|
|
|
"fmt" |
|
|
|
|
"io" |
|
|
|
|
"math" |
|
|
|
|
@ -29,6 +30,7 @@ import ( |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/go-kit/log" |
|
|
|
|
"github.com/gogo/protobuf/proto" |
|
|
|
|
"github.com/pkg/errors" |
|
|
|
|
"github.com/prometheus/client_golang/prometheus" |
|
|
|
|
dto "github.com/prometheus/client_model/go" |
|
|
|
|
@ -39,6 +41,7 @@ import ( |
|
|
|
|
"github.com/prometheus/prometheus/config" |
|
|
|
|
"github.com/prometheus/prometheus/discovery/targetgroup" |
|
|
|
|
"github.com/prometheus/prometheus/model/exemplar" |
|
|
|
|
"github.com/prometheus/prometheus/model/histogram" |
|
|
|
|
"github.com/prometheus/prometheus/model/labels" |
|
|
|
|
"github.com/prometheus/prometheus/model/relabel" |
|
|
|
|
"github.com/prometheus/prometheus/model/textparse" |
|
|
|
|
@ -737,12 +740,12 @@ func TestScrapeLoopStop(t *testing.T) { |
|
|
|
|
|
|
|
|
|
// We expected 1 actual sample for each scrape plus 5 for report samples.
|
|
|
|
|
// At least 2 scrapes were made, plus the final stale markers.
|
|
|
|
|
if len(appender.result) < 6*3 || len(appender.result)%6 != 0 { |
|
|
|
|
t.Fatalf("Expected at least 3 scrapes with 6 samples each, got %d samples", len(appender.result)) |
|
|
|
|
if len(appender.resultFloats) < 6*3 || len(appender.resultFloats)%6 != 0 { |
|
|
|
|
t.Fatalf("Expected at least 3 scrapes with 6 samples each, got %d samples", len(appender.resultFloats)) |
|
|
|
|
} |
|
|
|
|
// All samples in a scrape must have the same timestamp.
|
|
|
|
|
var ts int64 |
|
|
|
|
for i, s := range appender.result { |
|
|
|
|
for i, s := range appender.resultFloats { |
|
|
|
|
switch { |
|
|
|
|
case i%6 == 0: |
|
|
|
|
ts = s.t |
|
|
|
|
@ -751,9 +754,9 @@ func TestScrapeLoopStop(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// All samples from the last scrape must be stale markers.
|
|
|
|
|
for _, s := range appender.result[len(appender.result)-5:] { |
|
|
|
|
if !value.IsStaleNaN(s.v) { |
|
|
|
|
t.Fatalf("Appended last sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(s.v)) |
|
|
|
|
for _, s := range appender.resultFloats[len(appender.resultFloats)-5:] { |
|
|
|
|
if !value.IsStaleNaN(s.f) { |
|
|
|
|
t.Fatalf("Appended last sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(s.f)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -1189,10 +1192,10 @@ func TestScrapeLoopRunCreatesStaleMarkersOnFailedScrape(t *testing.T) { |
|
|
|
|
|
|
|
|
|
// 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for
|
|
|
|
|
// each scrape successful or not.
|
|
|
|
|
require.Equal(t, 27, len(appender.result), "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, 42.0, appender.result[0].v, "Appended first sample not as expected") |
|
|
|
|
require.True(t, value.IsStaleNaN(appender.result[6].v), |
|
|
|
|
"Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.result[6].v)) |
|
|
|
|
require.Equal(t, 27, len(appender.resultFloats), "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, 42.0, appender.resultFloats[0].f, "Appended first sample not as expected") |
|
|
|
|
require.True(t, value.IsStaleNaN(appender.resultFloats[6].f), |
|
|
|
|
"Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.resultFloats[6].f)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopRunCreatesStaleMarkersOnParseFailure(t *testing.T) { |
|
|
|
|
@ -1254,10 +1257,10 @@ func TestScrapeLoopRunCreatesStaleMarkersOnParseFailure(t *testing.T) { |
|
|
|
|
|
|
|
|
|
// 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for
|
|
|
|
|
// each scrape successful or not.
|
|
|
|
|
require.Equal(t, 17, len(appender.result), "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, 42.0, appender.result[0].v, "Appended first sample not as expected") |
|
|
|
|
require.True(t, value.IsStaleNaN(appender.result[6].v), |
|
|
|
|
"Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.result[6].v)) |
|
|
|
|
require.Equal(t, 17, len(appender.resultFloats), "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, 42.0, appender.resultFloats[0].f, "Appended first sample not as expected") |
|
|
|
|
require.True(t, value.IsStaleNaN(appender.resultFloats[6].f), |
|
|
|
|
"Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.resultFloats[6].f)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopCache(t *testing.T) { |
|
|
|
|
@ -1339,7 +1342,7 @@ func TestScrapeLoopCache(t *testing.T) { |
|
|
|
|
|
|
|
|
|
// 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for
|
|
|
|
|
// each scrape successful or not.
|
|
|
|
|
require.Equal(t, 26, len(appender.result), "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, 26, len(appender.resultFloats), "Appended samples not as expected:\n%s", appender) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopCacheMemoryExhaustionProtection(t *testing.T) { |
|
|
|
|
@ -1498,11 +1501,11 @@ func TestScrapeLoopAppend(t *testing.T) { |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
expected := []sample{ |
|
|
|
|
expected := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: test.expLset, |
|
|
|
|
t: timestamp.FromTime(now), |
|
|
|
|
v: test.expValue, |
|
|
|
|
f: test.expValue, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1510,11 +1513,11 @@ func TestScrapeLoopAppend(t *testing.T) { |
|
|
|
|
// DeepEqual will report NaNs as being different,
|
|
|
|
|
// so replace it with the expected one.
|
|
|
|
|
if test.expValue == float64(value.NormalNaN) { |
|
|
|
|
app.result[0].v = expected[0].v |
|
|
|
|
app.resultFloats[0].f = expected[0].f |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
t.Logf("Test:%s", test.title) |
|
|
|
|
require.Equal(t, expected, app.result) |
|
|
|
|
require.Equal(t, expected, app.resultFloats) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1584,13 +1587,13 @@ func TestScrapeLoopAppendForConflictingPrefixedLabels(t *testing.T) { |
|
|
|
|
|
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
require.Equal(t, []sample{ |
|
|
|
|
require.Equal(t, []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings(tc.expected...), |
|
|
|
|
t: timestamp.FromTime(time.Date(2000, 1, 1, 1, 0, 0, 0, time.UTC)), |
|
|
|
|
v: 0, |
|
|
|
|
f: 0, |
|
|
|
|
}, |
|
|
|
|
}, app.result) |
|
|
|
|
}, app.resultFloats) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -1638,15 +1641,15 @@ func TestScrapeLoopAppendCacheEntryButErrNotFound(t *testing.T) { |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
expected := []sample{ |
|
|
|
|
expected := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: lset, |
|
|
|
|
t: timestamp.FromTime(now), |
|
|
|
|
v: expValue, |
|
|
|
|
f: expValue, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
require.Equal(t, expected, app.result) |
|
|
|
|
require.Equal(t, expected, app.resultFloats) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopAppendSampleLimit(t *testing.T) { |
|
|
|
|
@ -1706,14 +1709,14 @@ func TestScrapeLoopAppendSampleLimit(t *testing.T) { |
|
|
|
|
require.Equal(t, 1.0, change, "Unexpected change of sample limit metric: %f", change) |
|
|
|
|
|
|
|
|
|
// And verify that we got the samples that fit under the limit.
|
|
|
|
|
want := []sample{ |
|
|
|
|
want := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), |
|
|
|
|
t: timestamp.FromTime(now), |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
require.Equal(t, want, resApp.rolledbackResult, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, want, resApp.rolledbackFloats, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
|
|
|
|
|
now = time.Now() |
|
|
|
|
slApp = sl.appender(context.Background()) |
|
|
|
|
@ -1866,19 +1869,19 @@ func TestScrapeLoop_ChangingMetricString(t *testing.T) { |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
// DeepEqual will report NaNs as being different, so replace with a different value.
|
|
|
|
|
want := []sample{ |
|
|
|
|
want := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), |
|
|
|
|
t: timestamp.FromTime(now), |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), |
|
|
|
|
t: timestamp.FromTime(now.Add(time.Minute)), |
|
|
|
|
v: 2, |
|
|
|
|
f: 2, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
require.Equal(t, want, capp.result, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopAppendStaleness(t *testing.T) { |
|
|
|
|
@ -1914,24 +1917,24 @@ func TestScrapeLoopAppendStaleness(t *testing.T) { |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
ingestedNaN := math.Float64bits(app.result[1].v) |
|
|
|
|
ingestedNaN := math.Float64bits(app.resultFloats[1].f) |
|
|
|
|
require.Equal(t, value.StaleNaN, ingestedNaN, "Appended stale sample wasn't as expected") |
|
|
|
|
|
|
|
|
|
// DeepEqual will report NaNs as being different, so replace with a different value.
|
|
|
|
|
app.result[1].v = 42 |
|
|
|
|
want := []sample{ |
|
|
|
|
app.resultFloats[1].f = 42 |
|
|
|
|
want := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), |
|
|
|
|
t: timestamp.FromTime(now), |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), |
|
|
|
|
t: timestamp.FromTime(now.Add(time.Second)), |
|
|
|
|
v: 42, |
|
|
|
|
f: 42, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
require.Equal(t, want, app.result, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, want, app.resultFloats, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopAppendNoStalenessIfTimestamp(t *testing.T) { |
|
|
|
|
@ -1966,40 +1969,44 @@ func TestScrapeLoopAppendNoStalenessIfTimestamp(t *testing.T) { |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
want := []sample{ |
|
|
|
|
want := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), |
|
|
|
|
t: 1000, |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
require.Equal(t, want, app.result, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, want, app.resultFloats, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopAppendExemplar(t *testing.T) { |
|
|
|
|
tests := []struct { |
|
|
|
|
title string |
|
|
|
|
scrapeText string |
|
|
|
|
contentType string |
|
|
|
|
discoveryLabels []string |
|
|
|
|
samples []sample |
|
|
|
|
floats []floatSample |
|
|
|
|
histograms []histogramSample |
|
|
|
|
exemplars []exemplar.Exemplar |
|
|
|
|
}{ |
|
|
|
|
{ |
|
|
|
|
title: "Metric without exemplars", |
|
|
|
|
scrapeText: "metric_total{n=\"1\"} 0\n# EOF", |
|
|
|
|
contentType: "application/openmetrics-text", |
|
|
|
|
discoveryLabels: []string{"n", "2"}, |
|
|
|
|
samples: []sample{{ |
|
|
|
|
floats: []floatSample{{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), |
|
|
|
|
v: 0, |
|
|
|
|
f: 0, |
|
|
|
|
}}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: "Metric with exemplars", |
|
|
|
|
scrapeText: "metric_total{n=\"1\"} 0 # {a=\"abc\"} 1.0\n# EOF", |
|
|
|
|
contentType: "application/openmetrics-text", |
|
|
|
|
discoveryLabels: []string{"n", "2"}, |
|
|
|
|
samples: []sample{{ |
|
|
|
|
floats: []floatSample{{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), |
|
|
|
|
v: 0, |
|
|
|
|
f: 0, |
|
|
|
|
}}, |
|
|
|
|
exemplars: []exemplar.Exemplar{ |
|
|
|
|
{Labels: labels.FromStrings("a", "abc"), Value: 1}, |
|
|
|
|
@ -2008,10 +2015,11 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { |
|
|
|
|
{ |
|
|
|
|
title: "Metric with exemplars and TS", |
|
|
|
|
scrapeText: "metric_total{n=\"1\"} 0 # {a=\"abc\"} 1.0 10000\n# EOF", |
|
|
|
|
contentType: "application/openmetrics-text", |
|
|
|
|
discoveryLabels: []string{"n", "2"}, |
|
|
|
|
samples: []sample{{ |
|
|
|
|
floats: []floatSample{{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), |
|
|
|
|
v: 0, |
|
|
|
|
f: 0, |
|
|
|
|
}}, |
|
|
|
|
exemplars: []exemplar.Exemplar{ |
|
|
|
|
{Labels: labels.FromStrings("a", "abc"), Value: 1, Ts: 10000000, HasTs: true}, |
|
|
|
|
@ -2022,18 +2030,117 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { |
|
|
|
|
scrapeText: `metric_total{n="1"} 1 # {t="1"} 1.0 10000 |
|
|
|
|
metric_total{n="2"} 2 # {t="2"} 2.0 20000 |
|
|
|
|
# EOF`, |
|
|
|
|
samples: []sample{{ |
|
|
|
|
contentType: "application/openmetrics-text", |
|
|
|
|
floats: []floatSample{{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_total", "n", "1"), |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, { |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_total", "n", "2"), |
|
|
|
|
v: 2, |
|
|
|
|
f: 2, |
|
|
|
|
}}, |
|
|
|
|
exemplars: []exemplar.Exemplar{ |
|
|
|
|
{Labels: labels.FromStrings("t", "1"), Value: 1, Ts: 10000000, HasTs: true}, |
|
|
|
|
{Labels: labels.FromStrings("t", "2"), Value: 2, Ts: 20000000, HasTs: true}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: "Native histogram with two exemplars", |
|
|
|
|
scrapeText: `name: "test_histogram" |
|
|
|
|
help: "Test histogram with many buckets removed to keep it manageable in size." |
|
|
|
|
type: HISTOGRAM |
|
|
|
|
metric: < |
|
|
|
|
histogram: < |
|
|
|
|
sample_count: 175 |
|
|
|
|
sample_sum: 0.0008280461746287094 |
|
|
|
|
bucket: < |
|
|
|
|
cumulative_count: 2 |
|
|
|
|
upper_bound: -0.0004899999999999998 |
|
|
|
|
> |
|
|
|
|
bucket: < |
|
|
|
|
cumulative_count: 4 |
|
|
|
|
upper_bound: -0.0003899999999999998 |
|
|
|
|
exemplar: < |
|
|
|
|
label: < |
|
|
|
|
name: "dummyID" |
|
|
|
|
value: "59727" |
|
|
|
|
> |
|
|
|
|
value: -0.00039 |
|
|
|
|
timestamp: < |
|
|
|
|
seconds: 1625851155 |
|
|
|
|
nanos: 146848499 |
|
|
|
|
> |
|
|
|
|
> |
|
|
|
|
> |
|
|
|
|
bucket: < |
|
|
|
|
cumulative_count: 16 |
|
|
|
|
upper_bound: -0.0002899999999999998 |
|
|
|
|
exemplar: < |
|
|
|
|
label: < |
|
|
|
|
name: "dummyID" |
|
|
|
|
value: "5617" |
|
|
|
|
> |
|
|
|
|
value: -0.00029 |
|
|
|
|
> |
|
|
|
|
> |
|
|
|
|
schema: 3 |
|
|
|
|
zero_threshold: 2.938735877055719e-39 |
|
|
|
|
zero_count: 2 |
|
|
|
|
negative_span: < |
|
|
|
|
offset: -162 |
|
|
|
|
length: 1 |
|
|
|
|
> |
|
|
|
|
negative_span: < |
|
|
|
|
offset: 23 |
|
|
|
|
length: 4 |
|
|
|
|
> |
|
|
|
|
negative_delta: 1 |
|
|
|
|
negative_delta: 3 |
|
|
|
|
negative_delta: -2 |
|
|
|
|
negative_delta: -1 |
|
|
|
|
negative_delta: 1 |
|
|
|
|
positive_span: < |
|
|
|
|
offset: -161 |
|
|
|
|
length: 1 |
|
|
|
|
> |
|
|
|
|
positive_span: < |
|
|
|
|
offset: 8 |
|
|
|
|
length: 3 |
|
|
|
|
> |
|
|
|
|
positive_delta: 1 |
|
|
|
|
positive_delta: 2 |
|
|
|
|
positive_delta: -1 |
|
|
|
|
positive_delta: -1 |
|
|
|
|
> |
|
|
|
|
timestamp_ms: 1234568 |
|
|
|
|
> |
|
|
|
|
|
|
|
|
|
`, |
|
|
|
|
contentType: "application/vnd.google.protobuf", |
|
|
|
|
histograms: []histogramSample{{ |
|
|
|
|
t: 1234568, |
|
|
|
|
h: &histogram.Histogram{ |
|
|
|
|
Count: 175, |
|
|
|
|
ZeroCount: 2, |
|
|
|
|
Sum: 0.0008280461746287094, |
|
|
|
|
ZeroThreshold: 2.938735877055719e-39, |
|
|
|
|
Schema: 3, |
|
|
|
|
PositiveSpans: []histogram.Span{ |
|
|
|
|
{Offset: -161, Length: 1}, |
|
|
|
|
{Offset: 8, Length: 3}, |
|
|
|
|
}, |
|
|
|
|
NegativeSpans: []histogram.Span{ |
|
|
|
|
{Offset: -162, Length: 1}, |
|
|
|
|
{Offset: 23, Length: 4}, |
|
|
|
|
}, |
|
|
|
|
PositiveBuckets: []int64{1, 2, -1, -1}, |
|
|
|
|
NegativeBuckets: []int64{1, 3, -2, -1, 1}, |
|
|
|
|
}, |
|
|
|
|
}}, |
|
|
|
|
exemplars: []exemplar.Exemplar{ |
|
|
|
|
{Labels: labels.FromStrings("dummyID", "59727"), Value: -0.00039, Ts: 1625851155146, HasTs: true}, |
|
|
|
|
{Labels: labels.FromStrings("dummyID", "5617"), Value: -0.00029, Ts: 1234568, HasTs: false}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for _, test := range tests { |
|
|
|
|
@ -2069,8 +2176,8 @@ metric_total{n="2"} 2 # {t="2"} 2.0 20000 |
|
|
|
|
|
|
|
|
|
now := time.Now() |
|
|
|
|
|
|
|
|
|
for i := range test.samples { |
|
|
|
|
test.samples[i].t = timestamp.FromTime(now) |
|
|
|
|
for i := range test.floats { |
|
|
|
|
test.floats[i].t = timestamp.FromTime(now) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// We need to set the timestamp for expected exemplars that does not have a timestamp.
|
|
|
|
|
@ -2080,10 +2187,29 @@ metric_total{n="2"} 2 # {t="2"} 2.0 20000 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_, _, _, err := sl.append(app, []byte(test.scrapeText), "application/openmetrics-text", now) |
|
|
|
|
buf := &bytes.Buffer{} |
|
|
|
|
if test.contentType == "application/vnd.google.protobuf" { |
|
|
|
|
// In case of protobuf, we have to create the binary representation.
|
|
|
|
|
pb := &dto.MetricFamily{} |
|
|
|
|
// From text to proto message.
|
|
|
|
|
require.NoError(t, proto.UnmarshalText(test.scrapeText, pb)) |
|
|
|
|
// From proto message to binary protobuf.
|
|
|
|
|
protoBuf, err := proto.Marshal(pb) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
// Write first length, then binary protobuf.
|
|
|
|
|
varintBuf := binary.AppendUvarint(nil, uint64(len(protoBuf))) |
|
|
|
|
buf.Write(varintBuf) |
|
|
|
|
buf.Write(protoBuf) |
|
|
|
|
} else { |
|
|
|
|
buf.WriteString(test.scrapeText) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_, _, _, err := sl.append(app, buf.Bytes(), test.contentType, now) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, app.Commit()) |
|
|
|
|
require.Equal(t, test.samples, app.result) |
|
|
|
|
require.Equal(t, test.floats, app.resultFloats) |
|
|
|
|
require.Equal(t, test.histograms, app.resultHistograms) |
|
|
|
|
require.Equal(t, test.exemplars, app.resultExemplars) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
@ -2093,12 +2219,12 @@ func TestScrapeLoopAppendExemplarSeries(t *testing.T) { |
|
|
|
|
scrapeText := []string{`metric_total{n="1"} 1 # {t="1"} 1.0 10000 |
|
|
|
|
# EOF`, `metric_total{n="1"} 2 # {t="2"} 2.0 20000 |
|
|
|
|
# EOF`} |
|
|
|
|
samples := []sample{{ |
|
|
|
|
samples := []floatSample{{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_total", "n", "1"), |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, { |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_total", "n", "1"), |
|
|
|
|
v: 2, |
|
|
|
|
f: 2, |
|
|
|
|
}} |
|
|
|
|
exemplars := []exemplar.Exemplar{ |
|
|
|
|
{Labels: labels.FromStrings("t", "1"), Value: 1, Ts: 10000000, HasTs: true}, |
|
|
|
|
@ -2154,7 +2280,7 @@ func TestScrapeLoopAppendExemplarSeries(t *testing.T) { |
|
|
|
|
require.NoError(t, app.Commit()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
require.Equal(t, samples, app.result) |
|
|
|
|
require.Equal(t, samples, app.resultFloats) |
|
|
|
|
require.Equal(t, exemplars, app.resultExemplars) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -2192,7 +2318,7 @@ func TestScrapeLoopRunReportsTargetDownOnScrapeError(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sl.run(nil) |
|
|
|
|
require.Equal(t, 0.0, appender.result[0].v, "bad 'up' value") |
|
|
|
|
require.Equal(t, 0.0, appender.resultFloats[0].f, "bad 'up' value") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopRunReportsTargetDownOnInvalidUTF8(t *testing.T) { |
|
|
|
|
@ -2230,7 +2356,7 @@ func TestScrapeLoopRunReportsTargetDownOnInvalidUTF8(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sl.run(nil) |
|
|
|
|
require.Equal(t, 0.0, appender.result[0].v, "bad 'up' value") |
|
|
|
|
require.Equal(t, 0.0, appender.resultFloats[0].f, "bad 'up' value") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type errorAppender struct { |
|
|
|
|
@ -2279,14 +2405,14 @@ func TestScrapeLoopAppendGracefullyIfAmendOrOutOfOrderOrOutOfBounds(t *testing.T |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
want := []sample{ |
|
|
|
|
want := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings(model.MetricNameLabel, "normal"), |
|
|
|
|
t: timestamp.FromTime(now), |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
require.Equal(t, want, app.result, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, want, app.resultFloats, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, 4, total) |
|
|
|
|
require.Equal(t, 4, added) |
|
|
|
|
require.Equal(t, 1, seriesAdded) |
|
|
|
|
@ -2598,14 +2724,14 @@ func TestScrapeLoop_RespectTimestamps(t *testing.T) { |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
want := []sample{ |
|
|
|
|
want := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), |
|
|
|
|
t: 0, |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
require.Equal(t, want, capp.result, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoop_DiscardTimestamps(t *testing.T) { |
|
|
|
|
@ -2640,14 +2766,14 @@ func TestScrapeLoop_DiscardTimestamps(t *testing.T) { |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
require.NoError(t, slApp.Commit()) |
|
|
|
|
|
|
|
|
|
want := []sample{ |
|
|
|
|
want := []floatSample{ |
|
|
|
|
{ |
|
|
|
|
metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), |
|
|
|
|
t: timestamp.FromTime(now), |
|
|
|
|
v: 1, |
|
|
|
|
f: 1, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
require.Equal(t, want, capp.result, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestScrapeLoopDiscardDuplicateLabels(t *testing.T) { |
|
|
|
|
|