| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | // Copyright 2021 The Prometheus Authors
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package agent | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-04-14 16:27:06 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	"strconv" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/go-kit/log" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
					
						
							|  |  |  | 	dto "github.com/prometheus/client_model/go" | 
					
						
							| 
									
										
										
										
											2022-04-14 16:27:06 +08:00
										 |  |  | 	"github.com/prometheus/common/model" | 
					
						
							| 
									
										
										
										
											2021-10-22 16:19:38 +08:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/model/exemplar" | 
					
						
							| 
									
										
										
										
											2021-11-08 22:23:17 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/model/labels" | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/storage" | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/storage/remote" | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/tsdb" | 
					
						
							| 
									
										
										
										
											2023-08-24 21:21:17 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/tsdb/chunks" | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/tsdb/record" | 
					
						
							|  |  |  | 	"github.com/prometheus/prometheus/tsdb/tsdbutil" | 
					
						
							| 
									
										
										
										
											2022-10-10 23:08:46 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/tsdb/wlog" | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/util/testutil" | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | func TestDB_InvalidSeries(t *testing.T) { | 
					
						
							|  |  |  | 	s := createTestAgentDB(t, nil, DefaultOptions()) | 
					
						
							|  |  |  | 	defer s.Close() | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	app := s.Appender(context.Background()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Samples", func(t *testing.T) { | 
					
						
							|  |  |  | 		_, err := app.Append(0, labels.Labels{}, 0, 0) | 
					
						
							|  |  |  | 		require.ErrorIs(t, err, tsdb.ErrInvalidSample, "should reject empty labels") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		_, err = app.Append(0, labels.FromStrings("a", "1", "a", "2"), 0, 0) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.ErrorIs(t, err, tsdb.ErrInvalidSample, "should reject duplicate labels") | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	t.Run("Histograms", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		_, err := app.AppendHistogram(0, labels.Labels{}, 0, tsdbutil.GenerateTestHistograms(1)[0], nil) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		require.ErrorIs(t, err, tsdb.ErrInvalidSample, "should reject empty labels") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		_, err = app.AppendHistogram(0, labels.FromStrings("a", "1", "a", "2"), 0, tsdbutil.GenerateTestHistograms(1)[0], nil) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		require.ErrorIs(t, err, tsdb.ErrInvalidSample, "should reject duplicate labels") | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	t.Run("Exemplars", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		sRef, err := app.Append(0, labels.FromStrings("a", "1"), 0, 0) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, err, "should not reject valid series") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		_, err = app.AppendExemplar(0, labels.EmptyLabels(), exemplar.Exemplar{}) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.EqualError(t, err, "unknown series ref when trying to add exemplar: 0") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		e := exemplar.Exemplar{Labels: labels.FromStrings("a", "1", "a", "2")} | 
					
						
							|  |  |  | 		_, err = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.ErrorIs(t, err, tsdb.ErrInvalidExemplar, "should reject duplicate labels") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		e = exemplar.Exemplar{Labels: labels.FromStrings("a_somewhat_long_trace_id", "nYJSNtFrFTY37VR7mHzEE/LIDt7cdAQcuOzFajgmLDAdBSRHYPDzrxhMA4zz7el8naI/AoXFv9/e/G0vcETcIoNUi3OieeLfaIRQci2oa")} | 
					
						
							|  |  |  | 		_, err = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.ErrorIs(t, err, storage.ErrExemplarLabelLength, "should reject too long label length") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Inverse check
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		e = exemplar.Exemplar{Labels: labels.FromStrings("a", "1"), Value: 20, Ts: 10, HasTs: true} | 
					
						
							|  |  |  | 		_, err = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, err, "should not reject valid exemplars") | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func createTestAgentDB(t *testing.T, reg prometheus.Registerer, opts *Options) *DB { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	dbDir := t.TempDir() | 
					
						
							|  |  |  | 	rs := remote.NewStorage(log.NewNopLogger(), reg, startTime, dbDir, time.Second*30, nil) | 
					
						
							|  |  |  | 	t.Cleanup(func() { | 
					
						
							|  |  |  | 		require.NoError(t, rs.Close()) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	db, err := Open(log.NewNopLogger(), reg, rs, dbDir, opts) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	return db | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestUnsupportedFunctions(t *testing.T) { | 
					
						
							|  |  |  | 	s := createTestAgentDB(t, nil, DefaultOptions()) | 
					
						
							|  |  |  | 	defer s.Close() | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Querier", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-09-12 18:37:38 +08:00
										 |  |  | 		_, err := s.Querier(0, 0) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		require.Equal(t, err, ErrUnsupported) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("ChunkQuerier", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-09-12 18:37:38 +08:00
										 |  |  | 		_, err := s.ChunkQuerier(0, 0) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		require.Equal(t, err, ErrUnsupported) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("ExemplarQuerier", func(t *testing.T) { | 
					
						
							|  |  |  | 		_, err := s.ExemplarQuerier(context.TODO()) | 
					
						
							|  |  |  | 		require.Equal(t, err, ErrUnsupported) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestCommit(t *testing.T) { | 
					
						
							|  |  |  | 	const ( | 
					
						
							|  |  |  | 		numDatapoints = 1000 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		numHistograms = 100 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		numSeries     = 8 | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	s := createTestAgentDB(t, nil, DefaultOptions()) | 
					
						
							|  |  |  | 	app := s.Appender(context.TODO()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lbls := labelsForTest(t.Name(), numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							| 
									
										
										
										
											2023-08-24 21:21:17 +08:00
										 |  |  | 			sample := chunks.GenerateSamples(0, 1) | 
					
						
							| 
									
										
										
										
											2023-03-31 01:50:13 +08:00
										 |  |  | 			ref, err := app.Append(0, lset, sample[0].T(), sample[0].F()) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			e := exemplar.Exemplar{ | 
					
						
							|  |  |  | 				Labels: lset, | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 				Ts:     sample[0].T() + int64(i), | 
					
						
							| 
									
										
										
										
											2023-03-31 01:50:13 +08:00
										 |  |  | 				Value:  sample[0].F(), | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 				HasTs:  true, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			_, err = app.AppendExemplar(ref, lset, e) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	lbls = labelsForTest(t.Name()+"_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), histograms[i], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), nil, floatHistograms[i]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	require.NoError(t, app.Commit()) | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | 	require.NoError(t, s.Close()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-10 23:08:46 +08:00
										 |  |  | 	sr, err := wlog.NewSegmentsReader(s.wal.Dir()) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	require.NoError(t, err) | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, sr.Close()) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	// Read records from WAL and check for expected count of series, samples, and exemplars.
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2022-10-10 23:08:46 +08:00
										 |  |  | 		r   = wlog.NewReader(sr) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		dec record.Decoder | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		walSeriesCount, walSamplesCount, walExemplarsCount, walHistogramCount, walFloatHistogramCount int | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 	for r.Next() { | 
					
						
							|  |  |  | 		rec := r.Record() | 
					
						
							|  |  |  | 		switch dec.Type(rec) { | 
					
						
							|  |  |  | 		case record.Series: | 
					
						
							|  |  |  | 			var series []record.RefSeries | 
					
						
							|  |  |  | 			series, err = dec.Series(rec, series) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walSeriesCount += len(series) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		case record.Samples: | 
					
						
							|  |  |  | 			var samples []record.RefSample | 
					
						
							|  |  |  | 			samples, err = dec.Samples(rec, samples) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walSamplesCount += len(samples) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		case record.HistogramSamples: | 
					
						
							|  |  |  | 			var histograms []record.RefHistogramSample | 
					
						
							|  |  |  | 			histograms, err = dec.HistogramSamples(rec, histograms) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walHistogramCount += len(histograms) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case record.FloatHistogramSamples: | 
					
						
							|  |  |  | 			var floatHistograms []record.RefFloatHistogramSample | 
					
						
							|  |  |  | 			floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walFloatHistogramCount += len(floatHistograms) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		case record.Exemplars: | 
					
						
							|  |  |  | 			var exemplars []record.RefExemplar | 
					
						
							|  |  |  | 			exemplars, err = dec.Exemplars(rec, exemplars) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walExemplarsCount += len(exemplars) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-04 01:11:19 +08:00
										 |  |  | 	// Check that the WAL contained the same number of committed series/samples/exemplars.
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	require.Equal(t, numSeries*3, walSeriesCount, "unexpected number of series") | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	require.Equal(t, numSeries*numDatapoints, walSamplesCount, "unexpected number of samples") | 
					
						
							|  |  |  | 	require.Equal(t, numSeries*numDatapoints, walExemplarsCount, "unexpected number of exemplars") | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	require.Equal(t, numSeries*numHistograms, walHistogramCount, "unexpected number of histograms") | 
					
						
							|  |  |  | 	require.Equal(t, numSeries*numHistograms, walFloatHistogramCount, "unexpected number of float histograms") | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRollback(t *testing.T) { | 
					
						
							|  |  |  | 	const ( | 
					
						
							|  |  |  | 		numDatapoints = 1000 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		numHistograms = 100 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		numSeries     = 8 | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	s := createTestAgentDB(t, nil, DefaultOptions()) | 
					
						
							|  |  |  | 	app := s.Appender(context.TODO()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lbls := labelsForTest(t.Name(), numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							| 
									
										
										
										
											2023-08-24 21:21:17 +08:00
										 |  |  | 			sample := chunks.GenerateSamples(0, 1) | 
					
						
							| 
									
										
										
										
											2023-03-31 01:50:13 +08:00
										 |  |  | 			_, err := app.Append(0, lset, sample[0].T(), sample[0].F()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	lbls = labelsForTest(t.Name()+"_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), histograms[i], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), nil, floatHistograms[i]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	// Do a rollback, which should clear uncommitted data. A followup call to
 | 
					
						
							|  |  |  | 	// commit should persist nothing to the WAL.
 | 
					
						
							|  |  |  | 	require.NoError(t, app.Rollback()) | 
					
						
							|  |  |  | 	require.NoError(t, app.Commit()) | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | 	require.NoError(t, s.Close()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-10 23:08:46 +08:00
										 |  |  | 	sr, err := wlog.NewSegmentsReader(s.wal.Dir()) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	require.NoError(t, err) | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, sr.Close()) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	// Read records from WAL and check for expected count of series and samples.
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2022-10-10 23:08:46 +08:00
										 |  |  | 		r   = wlog.NewReader(sr) | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		dec record.Decoder | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		walSeriesCount, walSamplesCount, walHistogramCount, walFloatHistogramCount, walExemplarsCount int | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 	for r.Next() { | 
					
						
							|  |  |  | 		rec := r.Record() | 
					
						
							|  |  |  | 		switch dec.Type(rec) { | 
					
						
							|  |  |  | 		case record.Series: | 
					
						
							|  |  |  | 			var series []record.RefSeries | 
					
						
							|  |  |  | 			series, err = dec.Series(rec, series) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walSeriesCount += len(series) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		case record.Samples: | 
					
						
							|  |  |  | 			var samples []record.RefSample | 
					
						
							|  |  |  | 			samples, err = dec.Samples(rec, samples) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walSamplesCount += len(samples) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		case record.Exemplars: | 
					
						
							|  |  |  | 			var exemplars []record.RefExemplar | 
					
						
							|  |  |  | 			exemplars, err = dec.Exemplars(rec, exemplars) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walExemplarsCount += len(exemplars) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		case record.HistogramSamples: | 
					
						
							|  |  |  | 			var histograms []record.RefHistogramSample | 
					
						
							|  |  |  | 			histograms, err = dec.HistogramSamples(rec, histograms) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walHistogramCount += len(histograms) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case record.FloatHistogramSamples: | 
					
						
							|  |  |  | 			var floatHistograms []record.RefFloatHistogramSample | 
					
						
							|  |  |  | 			floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walFloatHistogramCount += len(floatHistograms) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-27 21:28:26 +08:00
										 |  |  | 	// Check that only series get stored after calling Rollback.
 | 
					
						
							|  |  |  | 	require.Equal(t, numSeries*3, walSeriesCount, "series should have been written to WAL") | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	require.Equal(t, 0, walSamplesCount, "samples should not have been written to WAL") | 
					
						
							|  |  |  | 	require.Equal(t, 0, walExemplarsCount, "exemplars should not have been written to WAL") | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	require.Equal(t, 0, walHistogramCount, "histograms should not have been written to WAL") | 
					
						
							|  |  |  | 	require.Equal(t, 0, walFloatHistogramCount, "float histograms should not have been written to WAL") | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestFullTruncateWAL(t *testing.T) { | 
					
						
							|  |  |  | 	const ( | 
					
						
							|  |  |  | 		numDatapoints = 1000 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		numHistograms = 100 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		numSeries     = 800 | 
					
						
							|  |  |  | 		lastTs        = 500 | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	reg := prometheus.NewRegistry() | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	opts := DefaultOptions() | 
					
						
							|  |  |  | 	opts.TruncateFrequency = time.Minute * 2 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	s := createTestAgentDB(t, reg, opts) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		require.NoError(t, s.Close()) | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	app := s.Appender(context.TODO()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	lbls := labelsForTest(t.Name(), numSeries) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 			_, err := app.Append(0, lset, int64(lastTs), 0) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	lbls = labelsForTest(t.Name()+"_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(lastTs), histograms[i], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(lastTs), nil, floatHistograms[i]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	// Truncate WAL with mint to GC all the samples.
 | 
					
						
							|  |  |  | 	s.truncate(lastTs + 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := gatherFamily(t, reg, "prometheus_agent_deleted_series") | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	require.Equal(t, float64(numSeries*3), m.Metric[0].Gauge.GetValue(), "agent wal truncate mismatch of deleted series count") | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestPartialTruncateWAL(t *testing.T) { | 
					
						
							|  |  |  | 	const ( | 
					
						
							|  |  |  | 		numDatapoints = 1000 | 
					
						
							|  |  |  | 		numSeries     = 800 | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opts := DefaultOptions() | 
					
						
							|  |  |  | 	opts.TruncateFrequency = time.Minute * 2 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	reg := prometheus.NewRegistry() | 
					
						
							|  |  |  | 	s := createTestAgentDB(t, reg, opts) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		require.NoError(t, s.Close()) | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	app := s.Appender(context.TODO()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Create first batch of 800 series with 1000 data-points with a fixed lastTs as 500.
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	var lastTs int64 = 500 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	lbls := labelsForTest(t.Name()+"batch-1", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 			_, err := app.Append(0, lset, lastTs, 0) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	lbls = labelsForTest(t.Name()+"_histogram_batch-1", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numDatapoints) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, lastTs, histograms[i], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram_batch-1", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numDatapoints) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, lastTs, nil, floatHistograms[i]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	// Create second batch of 800 series with 1000 data-points with a fixed lastTs as 600.
 | 
					
						
							|  |  |  | 	lastTs = 600 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"batch-2", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 			_, err := app.Append(0, lset, lastTs, 0) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	lbls = labelsForTest(t.Name()+"_histogram_batch-2", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numDatapoints) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, lastTs, histograms[i], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram_batch-2", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numDatapoints) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, lastTs, nil, floatHistograms[i]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	// Truncate WAL with mint to GC only the first batch of 800 series and retaining 2nd batch of 800 series.
 | 
					
						
							|  |  |  | 	s.truncate(lastTs - 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := gatherFamily(t, reg, "prometheus_agent_deleted_series") | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	require.Equal(t, float64(numSeries*3), m.Metric[0].Gauge.GetValue(), "agent wal truncate mismatch of deleted series count") | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestWALReplay(t *testing.T) { | 
					
						
							|  |  |  | 	const ( | 
					
						
							|  |  |  | 		numDatapoints = 1000 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 		numHistograms = 100 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		numSeries     = 8 | 
					
						
							|  |  |  | 		lastTs        = 500 | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	s := createTestAgentDB(t, nil, DefaultOptions()) | 
					
						
							|  |  |  | 	app := s.Appender(context.TODO()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lbls := labelsForTest(t.Name(), numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 			_, err := app.Append(0, lset, lastTs, 0) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	lbls = labelsForTest(t.Name()+"_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, lastTs, histograms[i], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numHistograms; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, lastTs, nil, floatHistograms[i]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	require.NoError(t, app.Commit()) | 
					
						
							| 
									
										
										
										
											2021-11-10 22:35:54 +08:00
										 |  |  | 	require.NoError(t, s.Close()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	// Hack: s.wal.Dir() is the /wal subdirectory of the original storage path.
 | 
					
						
							|  |  |  | 	// We need the original directory so we can recreate the storage for replay.
 | 
					
						
							|  |  |  | 	storageDir := filepath.Dir(s.wal.Dir()) | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	reg := prometheus.NewRegistry() | 
					
						
							|  |  |  | 	replayStorage, err := Open(s.logger, reg, nil, storageDir, s.opts) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unable to create storage for the agent: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | 	defer func() { | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 		require.NoError(t, replayStorage.Close()) | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Check if all the series are retrieved back from the WAL.
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	m := gatherFamily(t, reg, "prometheus_agent_active_series") | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	require.Equal(t, float64(numSeries*3), m.Metric[0].Gauge.GetValue(), "agent wal replay mismatch of active series count") | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Check if lastTs of the samples retrieved from the WAL is retained.
 | 
					
						
							| 
									
										
										
										
											2021-11-30 23:44:40 +08:00
										 |  |  | 	metrics := replayStorage.series.series | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 	for i := 0; i < len(metrics); i++ { | 
					
						
							|  |  |  | 		mp := metrics[i] | 
					
						
							|  |  |  | 		for _, v := range mp { | 
					
						
							|  |  |  | 			require.Equal(t, v.lastTs, int64(lastTs)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | func TestLockfile(t *testing.T) { | 
					
						
							|  |  |  | 	tsdbutil.TestDirLockerUsage(t, func(t *testing.T, data string, createLock bool) (*tsdbutil.DirLocker, testutil.Closer) { | 
					
						
							|  |  |  | 		logger := log.NewNopLogger() | 
					
						
							|  |  |  | 		reg := prometheus.NewRegistry() | 
					
						
							|  |  |  | 		rs := remote.NewStorage(logger, reg, startTime, data, time.Second*30, nil) | 
					
						
							|  |  |  | 		t.Cleanup(func() { | 
					
						
							|  |  |  | 			require.NoError(t, rs.Close()) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		opts := DefaultOptions() | 
					
						
							|  |  |  | 		opts.NoLockfile = !createLock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Create the DB. This should create lockfile and its metrics.
 | 
					
						
							|  |  |  | 		db, err := Open(logger, nil, rs, data, opts) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return db.locker, testutil.NewCallbackCloser(func() { | 
					
						
							|  |  |  | 			require.NoError(t, db.Close()) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 16:27:06 +08:00
										 |  |  | func Test_ExistingWAL_NextRef(t *testing.T) { | 
					
						
							|  |  |  | 	dbDir := t.TempDir() | 
					
						
							|  |  |  | 	rs := remote.NewStorage(log.NewNopLogger(), nil, startTime, dbDir, time.Second*30, nil) | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		require.NoError(t, rs.Close()) | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	db, err := Open(log.NewNopLogger(), nil, rs, dbDir, DefaultOptions()) | 
					
						
							|  |  |  | 	require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	seriesCount := 10 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Append <seriesCount> series
 | 
					
						
							|  |  |  | 	app := db.Appender(context.Background()) | 
					
						
							|  |  |  | 	for i := 0; i < seriesCount; i++ { | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		lset := labels.FromStrings(model.MetricNameLabel, fmt.Sprintf("series_%d", i)) | 
					
						
							| 
									
										
										
										
											2022-04-14 16:27:06 +08:00
										 |  |  | 		_, err := app.Append(0, lset, 0, 100) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	histogramCount := 10 | 
					
						
							| 
									
										
										
										
											2023-02-10 19:39:33 +08:00
										 |  |  | 	histograms := tsdbutil.GenerateTestHistograms(histogramCount) | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	// Append <histogramCount> series
 | 
					
						
							|  |  |  | 	for i := 0; i < histogramCount; i++ { | 
					
						
							|  |  |  | 		lset := labels.FromStrings(model.MetricNameLabel, fmt.Sprintf("histogram_%d", i)) | 
					
						
							|  |  |  | 		_, err := app.AppendHistogram(0, lset, 0, histograms[i], nil) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-04-14 16:27:06 +08:00
										 |  |  | 	require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Truncate the WAL to force creation of a new segment.
 | 
					
						
							|  |  |  | 	require.NoError(t, db.truncate(0)) | 
					
						
							|  |  |  | 	require.NoError(t, db.Close()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create a new storage and see what nextRef is initialized to.
 | 
					
						
							|  |  |  | 	db, err = Open(log.NewNopLogger(), nil, rs, dbDir, DefaultOptions()) | 
					
						
							|  |  |  | 	require.NoError(t, err) | 
					
						
							|  |  |  | 	defer require.NoError(t, db.Close()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 00:13:44 +08:00
										 |  |  | 	require.Equal(t, uint64(seriesCount+histogramCount), db.nextRef.Load(), "nextRef should be equal to the number of series written across the entire WAL") | 
					
						
							| 
									
										
										
										
											2022-04-14 16:27:06 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:11:43 +08:00
										 |  |  | func Test_validateOptions(t *testing.T) { | 
					
						
							|  |  |  | 	t.Run("Apply defaults to zero values", func(t *testing.T) { | 
					
						
							|  |  |  | 		opts := validateOptions(&Options{}) | 
					
						
							|  |  |  | 		require.Equal(t, DefaultOptions(), opts) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Defaults are already valid", func(t *testing.T) { | 
					
						
							|  |  |  | 		require.Equal(t, DefaultOptions(), validateOptions(nil)) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("MaxWALTime should not be lower than TruncateFrequency", func(t *testing.T) { | 
					
						
							|  |  |  | 		opts := validateOptions(&Options{ | 
					
						
							|  |  |  | 			MaxWALTime:        int64(time.Hour / time.Millisecond), | 
					
						
							|  |  |  | 			TruncateFrequency: 2 * time.Hour, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		require.Equal(t, int64(2*time.Hour/time.Millisecond), opts.MaxWALTime) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | func startTime() (int64, error) { | 
					
						
							|  |  |  | 	return time.Now().Unix() * 1000, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create series for tests.
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | func labelsForTest(lName string, seriesCount int) [][]labels.Label { | 
					
						
							|  |  |  | 	var series [][]labels.Label | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < seriesCount; i++ { | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 		lset := []labels.Label{ | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 			{Name: "a", Value: lName}, | 
					
						
							|  |  |  | 			{Name: "instance", Value: "localhost" + strconv.Itoa(i)}, | 
					
						
							| 
									
										
										
										
											2022-05-05 05:41:36 +08:00
										 |  |  | 			{Name: "job", Value: "prometheus"}, | 
					
						
							| 
									
										
										
										
											2021-10-29 23:25:05 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		series = append(series, lset) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return series | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func gatherFamily(t *testing.T, reg prometheus.Gatherer, familyName string) *dto.MetricFamily { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	families, err := reg.Gather() | 
					
						
							|  |  |  | 	require.NoError(t, err, "failed to gather metrics") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, f := range families { | 
					
						
							|  |  |  | 		if f.GetName() == familyName { | 
					
						
							|  |  |  | 			return f | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Fatalf("could not find family %s", familyName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestStorage_DuplicateExemplarsIgnored(t *testing.T) { | 
					
						
							|  |  |  | 	s := createTestAgentDB(t, nil, DefaultOptions()) | 
					
						
							|  |  |  | 	app := s.Appender(context.Background()) | 
					
						
							|  |  |  | 	defer s.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 	sRef, err := app.Append(0, labels.FromStrings("a", "1"), 0, 0) | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 	require.NoError(t, err, "should not reject valid series") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Write a few exemplars to our appender and call Commit().
 | 
					
						
							|  |  |  | 	// If the Labels, Value or Timestamp are different than the last exemplar,
 | 
					
						
							|  |  |  | 	// then a new one should be appended; Otherwise, it should be skipped.
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 	e := exemplar.Exemplar{Labels: labels.FromStrings("a", "1"), Value: 20, Ts: 10, HasTs: true} | 
					
						
							|  |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							|  |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 	e.Labels = labels.FromStrings("b", "2") | 
					
						
							|  |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							|  |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							|  |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	e.Value = 42 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							|  |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	e.Ts = 25 | 
					
						
							| 
									
										
										
										
											2022-02-21 04:42:11 +08:00
										 |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							|  |  |  | 	_, _ = app.AppendExemplar(sRef, labels.EmptyLabels(), e) | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Read back what was written to the WAL.
 | 
					
						
							|  |  |  | 	var walExemplarsCount int | 
					
						
							| 
									
										
										
										
											2022-10-10 23:08:46 +08:00
										 |  |  | 	sr, err := wlog.NewSegmentsReader(s.wal.Dir()) | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 	require.NoError(t, err) | 
					
						
							|  |  |  | 	defer sr.Close() | 
					
						
							| 
									
										
										
										
											2022-10-10 23:08:46 +08:00
										 |  |  | 	r := wlog.NewReader(sr) | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var dec record.Decoder | 
					
						
							|  |  |  | 	for r.Next() { | 
					
						
							|  |  |  | 		rec := r.Record() | 
					
						
							| 
									
										
										
										
											2023-04-09 15:08:40 +08:00
										 |  |  | 		if dec.Type(rec) == record.Exemplars { | 
					
						
							| 
									
										
										
										
											2022-04-18 23:41:04 +08:00
										 |  |  | 			var exemplars []record.RefExemplar | 
					
						
							|  |  |  | 			exemplars, err = dec.Exemplars(rec, exemplars) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			walExemplarsCount += len(exemplars) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// We had 9 calls to AppendExemplar but only 4 of those should have gotten through.
 | 
					
						
							|  |  |  | 	require.Equal(t, 4, walExemplarsCount) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-10-13 22:33:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestDBAllowOOOSamples(t *testing.T) { | 
					
						
							|  |  |  | 	const ( | 
					
						
							|  |  |  | 		numDatapoints = 5 | 
					
						
							|  |  |  | 		numHistograms = 5 | 
					
						
							|  |  |  | 		numSeries     = 4 | 
					
						
							|  |  |  | 		offset        = 100 | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reg := prometheus.NewRegistry() | 
					
						
							|  |  |  | 	s := createTestAgentDB(t, reg, DefaultOptions()) | 
					
						
							|  |  |  | 	app := s.Appender(context.TODO()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Let's add some samples in the [offset, offset+numDatapoints) range.
 | 
					
						
							|  |  |  | 	lbls := labelsForTest(t.Name(), numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := offset; i < numDatapoints+offset; i++ { | 
					
						
							|  |  |  | 			ref, err := app.Append(0, lset, int64(i), float64(i)) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			e := exemplar.Exemplar{ | 
					
						
							|  |  |  | 				Labels: lset, | 
					
						
							|  |  |  | 				Ts:     int64(i) * 2, | 
					
						
							|  |  |  | 				Value:  float64(i), | 
					
						
							|  |  |  | 				HasTs:  true, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			_, err = app.AppendExemplar(ref, lset, e) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numHistograms) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := offset; i < numDatapoints+offset; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), histograms[i-offset], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram", numSeries) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := offset; i < numDatapoints+offset; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), nil, floatHistograms[i-offset]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	m := gatherFamily(t, reg, "prometheus_agent_samples_appended_total") | 
					
						
							|  |  |  | 	require.Equal(t, float64(20), m.Metric[0].Counter.GetValue(), "agent wal mismatch of total appended samples") | 
					
						
							|  |  |  | 	require.Equal(t, float64(40), m.Metric[1].Counter.GetValue(), "agent wal mismatch of total appended histograms") | 
					
						
							|  |  |  | 	require.NoError(t, s.Close()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Hack: s.wal.Dir() is the /wal subdirectory of the original storage path.
 | 
					
						
							|  |  |  | 	// We need the original directory so we can recreate the storage for replay.
 | 
					
						
							|  |  |  | 	storageDir := filepath.Dir(s.wal.Dir()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Replay the storage so that the lastTs for each series is recorded.
 | 
					
						
							|  |  |  | 	reg2 := prometheus.NewRegistry() | 
					
						
							|  |  |  | 	db, err := Open(s.logger, reg2, nil, storageDir, s.opts) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unable to create storage for the agent: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	app = db.Appender(context.Background()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Now the lastTs will have been recorded successfully.
 | 
					
						
							|  |  |  | 	// Let's try appending twice as many OOO samples in the [0, numDatapoints) range.
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_histogram", numSeries*2) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							|  |  |  | 			ref, err := app.Append(0, lset, int64(i), float64(i)) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			e := exemplar.Exemplar{ | 
					
						
							|  |  |  | 				Labels: lset, | 
					
						
							|  |  |  | 				Ts:     int64(i) * 2, | 
					
						
							|  |  |  | 				Value:  float64(i), | 
					
						
							|  |  |  | 				HasTs:  true, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			_, err = app.AppendExemplar(ref, lset, e) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_histogram", numSeries*2) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		histograms := tsdbutil.GenerateTestHistograms(numHistograms) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), histograms[i], nil) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbls = labelsForTest(t.Name()+"_float_histogram", numSeries*2) | 
					
						
							|  |  |  | 	for _, l := range lbls { | 
					
						
							|  |  |  | 		lset := labels.New(l...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < numDatapoints; i++ { | 
					
						
							|  |  |  | 			_, err := app.AppendHistogram(0, lset, int64(i), nil, floatHistograms[i]) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.NoError(t, app.Commit()) | 
					
						
							|  |  |  | 	m = gatherFamily(t, reg2, "prometheus_agent_samples_appended_total") | 
					
						
							|  |  |  | 	require.Equal(t, float64(40), m.Metric[0].Counter.GetValue(), "agent wal mismatch of total appended samples") | 
					
						
							|  |  |  | 	require.Equal(t, float64(80), m.Metric[1].Counter.GetValue(), "agent wal mismatch of total appended histograms") | 
					
						
							|  |  |  | 	require.NoError(t, db.Close()) | 
					
						
							|  |  |  | } |