From 16738b00e358ff7fe17c89ecc7186929313c2bbc Mon Sep 17 00:00:00 2001 From: sniper91 Date: Tue, 29 Nov 2022 19:04:13 +0800 Subject: [PATCH] Do no re-use result slice in chunkSetToSeriesSet This is required to preserve the interface property of SeriesSet that says "At returns full series. Returned series should be iterable even after Next is called." Signed-off-by: sniper91 --- storage/series.go | 2 +- storage/series_test.go | 60 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/storage/series.go b/storage/series.go index 377c060f7..81f7b7baf 100644 --- a/storage/series.go +++ b/storage/series.go @@ -205,7 +205,7 @@ func (c *chunkSetToSeriesSet) Next() bool { } c.iter = c.ChunkSeriesSet.At().Iterator(c.iter) - c.sameSeriesChunks = c.sameSeriesChunks[:0] + c.sameSeriesChunks = nil for c.iter.Next() { c.sameSeriesChunks = append( diff --git a/storage/series_test.go b/storage/series_test.go index b200a3fc4..8a2675e35 100644 --- a/storage/series_test.go +++ b/storage/series_test.go @@ -18,7 +18,9 @@ import ( "github.com/stretchr/testify/require" + "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/tsdb/chunkenc" + "github.com/prometheus/prometheus/tsdb/tsdbutil" ) func TestListSeriesIterator(t *testing.T) { @@ -65,3 +67,61 @@ func TestListSeriesIterator(t *testing.T) { // And we don't go back. (This exposes issue #10027.) require.Equal(t, chunkenc.ValNone, it.Seek(2)) } + +// TestSeriesSetToChunkSet test the property of SeriesSet that says +// returned series should be iterable even after Next is called. +func TestChunkSeriesSetToSeriesSet(t *testing.T) { + series := []struct { + lbs labels.Labels + samples []tsdbutil.Sample + }{ + { + lbs: labels.Labels{ + {Name: "__name__", Value: "up"}, + {Name: "instance", Value: "localhost:8080"}, + }, + samples: []tsdbutil.Sample{ + sample{t: 1, v: 1}, + sample{t: 2, v: 2}, + sample{t: 3, v: 3}, + sample{t: 4, v: 4}, + }, + }, { + lbs: labels.Labels{ + {Name: "__name__", Value: "up"}, + {Name: "instance", Value: "localhost:8081"}, + }, + samples: []tsdbutil.Sample{ + sample{t: 1, v: 2}, + sample{t: 2, v: 3}, + sample{t: 3, v: 4}, + sample{t: 4, v: 5}, + sample{t: 5, v: 6}, + sample{t: 6, v: 7}, + }, + }, + } + var chunkSeries []ChunkSeries + for _, s := range series { + chunkSeries = append(chunkSeries, NewListChunkSeriesFromSamples(s.lbs, s.samples)) + } + css := NewMockChunkSeriesSet(chunkSeries...) + + ss := NewSeriesSetFromChunkSeriesSet(css) + var ssSlice []Series + for ss.Next() { + ssSlice = append(ssSlice, ss.At()) + } + require.Len(t, ssSlice, 2) + var iter chunkenc.Iterator + for i, s := range ssSlice { + require.EqualValues(t, series[i].lbs, s.Labels()) + iter = s.Iterator(iter) + j := 0 + for iter.Next() == chunkenc.ValFloat { + ts, v := iter.At() + require.EqualValues(t, series[i].samples[j], sample{t: ts, v: v}) + j++ + } + } +}