Ensure that Query is closed for rules evaluations (#18733)
Some checks are pending
buf.build / lint and publish (push) Waiting to run
CI / Go tests (push) Waiting to run
CI / More Go tests (push) Waiting to run
CI / Go tests for 32-bit x86 (push) Waiting to run
CI / Go tests for Prometheus upgrades and downgrades (push) Waiting to run
CI / Go tests with previous Go version (push) Waiting to run
CI / UI tests (push) Waiting to run
CI / Go tests on Windows (push) Waiting to run
CI / Mixins tests (push) Waiting to run
CI / Compliance testing (push) Waiting to run
CI / Build Prometheus for common architectures (push) Waiting to run
CI / Build Prometheus for all architectures (push) Waiting to run
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
CI / Check generated parser (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / fuzzing (push) Waiting to run
CI / codeql (push) Waiting to run
CI / Publish main branch artifacts (push) Blocked by required conditions
CI / Publish release artefacts (push) Blocked by required conditions
CI / Publish UI on npm Registry (push) Blocked by required conditions
govulncheck / Run govulncheck (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run

Signed-off-by: Andrew Hall <andrew.hall@grafana.com>
This commit is contained in:
Julien 2026-05-20 10:11:24 +02:00 committed by GitHub
commit ea787c89cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 0 deletions

View file

@ -53,6 +53,8 @@ func EngineQueryFunc(engine promql.QueryEngine, q storage.Queryable) QueryFunc {
if err != nil {
return nil, err
}
defer q.Close()
res := q.Exec(ctx)
if res.Err != nil {
return nil, res.Err

View file

@ -43,11 +43,13 @@ import (
"github.com/prometheus/prometheus/model/timestamp"
"github.com/prometheus/prometheus/model/value"
"github.com/prometheus/prometheus/promql"
"github.com/prometheus/prometheus/promql/parser"
"github.com/prometheus/prometheus/promql/promqltest"
"github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/tsdb"
"github.com/prometheus/prometheus/tsdb/chunkenc"
"github.com/prometheus/prometheus/tsdb/tsdbutil"
"github.com/prometheus/prometheus/util/stats"
"github.com/prometheus/prometheus/util/teststorage"
prom_testutil "github.com/prometheus/prometheus/util/testutil"
)
@ -2773,3 +2775,35 @@ func BenchmarkRuleDependencyController_AnalyseRules(b *testing.B) {
}
}
}
// TestEngineQueryFunc_ClosesQuery verifies EngineQueryFunc Close()s the
// promql.Query it creates after every evaluation.
func TestEngineQueryFunc_ClosesQuery(t *testing.T) {
eng := &closeCountingEngine{}
qf := EngineQueryFunc(eng, nil)
_, err := qf(context.Background(), "vector(0)", time.Unix(0, 0))
require.NoError(t, err)
require.Equal(t, 1, eng.q.closeCalls, "Close must be called exactly once")
}
type closeCountingEngine struct{ q closeCountingQuery }
func (e *closeCountingEngine) NewInstantQuery(context.Context, storage.Queryable, promql.QueryOpts, string, time.Time) (promql.Query, error) {
return &e.q, nil
}
func (e *closeCountingEngine) NewRangeQuery(context.Context, storage.Queryable, promql.QueryOpts, string, time.Time, time.Time, time.Duration) (promql.Query, error) {
return &e.q, nil
}
type closeCountingQuery struct{ closeCalls int }
func (*closeCountingQuery) Exec(context.Context) *promql.Result {
return &promql.Result{Value: promql.Vector{}}
}
func (q *closeCountingQuery) Close() { q.closeCalls++ }
func (*closeCountingQuery) Statement() parser.Statement { return nil }
func (*closeCountingQuery) Stats() *stats.Statistics { return nil }
func (*closeCountingQuery) Cancel() {}
func (*closeCountingQuery) String() string { return "" }