From a4e00cc2f8398c1a1afb33d7c7a138708f8cbdda Mon Sep 17 00:00:00 2001 From: Carrie Edwards Date: Fri, 20 Sep 2024 03:46:41 -0700 Subject: [PATCH] Add OOO test cases to PromQL tests --- promql/promqltest/test.go | 19 +++++++++++++++---- promql/promqltest/test_test.go | 10 ++++++++++ promql/promqltest/testdata/ooo.test | 11 +++++++++++ tsdb/db.go | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 promql/promqltest/testdata/ooo.test diff --git a/promql/promqltest/test.go b/promql/promqltest/test.go index e078bcb60b..148f11842d 100644 --- a/promql/promqltest/test.go +++ b/promql/promqltest/test.go @@ -46,7 +46,7 @@ import ( var ( patSpace = regexp.MustCompile("[\t ]+") - patLoad = regexp.MustCompile(`^load(?:_(with_nhcb))?\s+(.+?)$`) + patLoad = regexp.MustCompile(`^load(?:_(with_nhcb))?\s+(.+?)(?:\s+(\d+))?$`) patEvalInstant = regexp.MustCompile(`^eval(?:_(fail|warn|ordered|info))?\s+instant\s+(?:at\s+(.+?))?\s+(.+)$`) patEvalRange = regexp.MustCompile(`^eval(?:_(fail|warn|info))?\s+range\s+from\s+(.+)\s+to\s+(.+)\s+step\s+(.+?)\s+(.+)$`) ) @@ -204,11 +204,20 @@ func parseLoad(lines []string, i int) (int, *loadCmd, error) { withNHCB = parts[1] == "with_nhcb" step = parts[2] ) + startTime := testStartTime + if parts[3] != "" { + s, err := strconv.Atoi(parts[3]) + if err != nil { + return i, nil, raise(i, "invalid start time %q: %s", s, err) + } + startTime = time.Unix(int64(s), 0).UTC() + } + gap, err := model.ParseDuration(step) if err != nil { return i, nil, raise(i, "invalid step definition %q: %s", step, err) } - cmd := newLoadCmd(time.Duration(gap), withNHCB) + cmd := newLoadCmd(startTime, time.Duration(gap), withNHCB) for i+1 < len(lines) { i++ defLine := lines[i] @@ -422,6 +431,7 @@ func (*evalCmd) testCmd() {} // loadCmd is a command that loads sequences of sample values for specific // metrics into the storage. type loadCmd struct { + startTime time.Time gap time.Duration metrics map[uint64]labels.Labels defs map[uint64][]promql.Sample @@ -429,8 +439,9 @@ type loadCmd struct { withNHCB bool } -func newLoadCmd(gap time.Duration, withNHCB bool) *loadCmd { +func newLoadCmd(startTime time.Time, gap time.Duration, withNHCB bool) *loadCmd { return &loadCmd{ + startTime: startTime, gap: gap, metrics: map[uint64]labels.Labels{}, defs: map[uint64][]promql.Sample{}, @@ -448,7 +459,7 @@ func (cmd *loadCmd) set(m labels.Labels, vals ...parser.SequenceValue) { h := m.Hash() samples := make([]promql.Sample, 0, len(vals)) - ts := testStartTime + ts := cmd.startTime for _, v := range vals { if !v.Omitted { samples = append(samples, promql.Sample{ diff --git a/promql/promqltest/test_test.go b/promql/promqltest/test_test.go index 5da924e9a5..505e531cb2 100644 --- a/promql/promqltest/test_test.go +++ b/promql/promqltest/test_test.go @@ -14,6 +14,7 @@ package promqltest import ( + "io/fs" "math" "testing" "time" @@ -158,6 +159,15 @@ func TestLazyLoader_WithSamplesTill(t *testing.T) { } } +func TestRunTestOOO(t *testing.T) { + t.Run("testdata/ooo.test", func(t *testing.T) { + content, err := fs.ReadFile(testsFs, "testdata/ooo.test") + require.NoError(t, err) + engine := NewTestEngine(t, false, 0, DefaultMaxSamplesPerQuery) + RunTest(t, string(content), engine) + }) +} + func TestRunTest(t *testing.T) { testData := ` load 5m diff --git a/promql/promqltest/testdata/ooo.test b/promql/promqltest/testdata/ooo.test new file mode 100644 index 0000000000..ec72582eef --- /dev/null +++ b/promql/promqltest/testdata/ooo.test @@ -0,0 +1,11 @@ +# OOO samples + +load 30s 150 + http_requests{path="/foo"} 1 2 3 4 8 9 + +load 30s 0 + http_requests{path="/foo"} 1 2 3 0 1 + +eval range from 0 to 5m step 30s sum by (path) (http_requests) + {path="/foo"} 1 2 3 0 1 1 2 3 4 5 + diff --git a/tsdb/db.go b/tsdb/db.go index 997bad36cb..17ea8740b1 100644 --- a/tsdb/db.go +++ b/tsdb/db.go @@ -83,6 +83,7 @@ func DefaultOptions() *Options { IsolationDisabled: defaultIsolationDisabled, HeadChunksWriteQueueSize: chunks.DefaultWriteQueueSize, OutOfOrderCapMax: DefaultOutOfOrderCapMax, + OutOfOrderTimeWindow: 24 * time.Hour.Milliseconds(), EnableOverlappingCompaction: true, EnableSharding: false, EnableDelayedCompaction: false,