diff --git a/CHANGELOG.md b/CHANGELOG.md index fb035a12c..6f029caf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.25.1 / 2021-03-14 + +* [BUGFIX] Fix a crash in `promtool` when a subquery with default resolution is used. #8569 +* [BUGFIX] Fix a bug that could return duplicate datapoints in queries. #8591 +* [BUGFIX] Fix crashes with arm64 when compiled with go1.16. #8593 + ## 2.25.0 / 2021-02-17 This release includes a new `--enable-feature=` flag that enables diff --git a/VERSION b/VERSION index 5c18f9195..d6af7e332 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.25.0 +2.25.1 diff --git a/cmd/promtool/testdata/rules.yml b/cmd/promtool/testdata/rules.yml index 7eff7f8f0..db33d343f 100644 --- a/cmd/promtool/testdata/rules.yml +++ b/cmd/promtool/testdata/rules.yml @@ -20,3 +20,7 @@ groups: # A recording rule that doesn't depend on input series. - record: fixed_data expr: 1 + + # Subquery with default resolution test. + - record: suquery_interval_test + expr: count_over_time(up[5m:]) diff --git a/cmd/promtool/unittest.go b/cmd/promtool/unittest.go index 64107f171..ea55ac04c 100644 --- a/cmd/promtool/unittest.go +++ b/cmd/promtool/unittest.go @@ -157,6 +157,7 @@ func (tg *testGroup) test(evalInterval time.Duration, groupOrderMap map[string]i return []error{err} } defer suite.Close() + suite.SubqueryInterval = evalInterval // Load the rule files. opts := &rules.ManagerOptions{ diff --git a/docs/configuration/unit_testing_rules.md b/docs/configuration/unit_testing_rules.md index 3043b2edf..644b35a17 100644 --- a/docs/configuration/unit_testing_rules.md +++ b/docs/configuration/unit_testing_rules.md @@ -22,8 +22,7 @@ You can use `promtool` to test your rules. rule_files: [ - ] -# optional, default = 1m -evaluation_interval: +[ evaluation_interval: | default = 1m ] # The order in which group names are listed below will be the order of evaluation of # rule groups (at a given evaluation time). The order is guaranteed only for the groups mentioned below. diff --git a/go.mod b/go.mod index 56807a7ba..d8cd3a0cb 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/go-openapi/strfmt v0.20.0 github.com/go-openapi/validate v0.20.2 // indirect github.com/gogo/protobuf v1.3.2 - github.com/golang/snappy v0.0.2 + github.com/golang/snappy v0.0.3 github.com/google/pprof v0.0.0-20210208152844-1612e9be7af6 github.com/gophercloud/gophercloud v0.15.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 diff --git a/go.sum b/go.sum index 5ba7e46a2..394900e1f 100644 --- a/go.sum +++ b/go.sum @@ -390,8 +390,8 @@ github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= diff --git a/promql/test.go b/promql/test.go index 77e133eed..9775e68f5 100644 --- a/promql/test.go +++ b/promql/test.go @@ -657,7 +657,8 @@ type LazyLoader struct { loadCmd *loadCmd - storage storage.Storage + storage storage.Storage + SubqueryInterval time.Duration queryEngine *Engine context context.Context @@ -710,11 +711,12 @@ func (ll *LazyLoader) clear() { ll.storage = teststorage.New(ll) opts := EngineOpts{ - Logger: nil, - Reg: nil, - MaxSamples: 10000, - Timeout: 100 * time.Second, - EnableAtModifier: true, + Logger: nil, + Reg: nil, + MaxSamples: 10000, + Timeout: 100 * time.Second, + NoStepSubqueryIntervalFn: func(int64) int64 { return durationMilliseconds(ll.SubqueryInterval) }, + EnableAtModifier: true, } ll.queryEngine = NewEngine(opts) diff --git a/storage/merge.go b/storage/merge.go index c57a24c76..fca052ca1 100644 --- a/storage/merge.go +++ b/storage/merge.go @@ -467,6 +467,7 @@ func (c *chainSampleIterator) Seek(t int64) bool { } if len(c.h) > 0 { c.curr = heap.Pop(&c.h).(chunkenc.Iterator) + c.lastt, _ = c.curr.At() return true } c.curr = nil diff --git a/storage/merge_test.go b/storage/merge_test.go index 415b7fb60..2ed68879a 100644 --- a/storage/merge_test.go +++ b/storage/merge_test.go @@ -647,6 +647,14 @@ func TestChainSampleIteratorSeek(t *testing.T) { seek: 2, expected: []tsdbutil.Sample{sample{2, 2}, sample{3, 3}, sample{4, 4}, sample{5, 5}}, }, + { + input: []chunkenc.Iterator{ + NewListSeriesIterator(samples{sample{0, 0}, sample{2, 2}, sample{3, 3}}), + NewListSeriesIterator(samples{sample{0, 0}, sample{1, 1}, sample{2, 2}}), + }, + seek: 0, + expected: []tsdbutil.Sample{sample{0, 0}, sample{1, 1}, sample{2, 2}, sample{3, 3}}, + }, } { merged := newChainSampleIterator(tc.input) actual := []tsdbutil.Sample{}