Skip to content

test(query-engine): add differential PromQL testing infra (#590, #594) - #630

Draft
milindsrivastava1997 wants to merge 10 commits into
mainfrom
worktree-594-590-promql-testing
Draft

test(query-engine): add differential PromQL testing infra (#590, #594)#630
milindsrivastava1997 wants to merge 10 commits into
mainfrom
worktree-594-590-promql-testing

Conversation

@milindsrivastava1997

Copy link
Copy Markdown
Contributor

Summary

Parallel test-infrastructure work for #590 and #594, run as 5 scoped agents against genuinely uncovered gaps (the existing suite already covers a lot of instant/range regression territory — this fills what was left).

#590 — Rust test suite for instant/range PromQL paths (asap-query-engine)

  • range_multistep_instant_equivalence_tests.rs — the generic oracle the issue called out as missing: a multi-step range query vs. N independent instant queries, one per step, across Tumbling/Sliding × single/dual-population. All pass (stable-key-set happy path).
  • range_query_validation_tests.rs + inline tests in simple_engine/mod.rs — boundary coverage for validate_range_query_params (start>=end, step==0, step-not-multiple-of-window, start==end), plus an instant/range skip-behavior parity check for orphan groups.
  • sliding_window_keyed_oracle_tests.rs + new simulate_sliding_window_keyed reference oracle — a property sweep (21 scenarios) over keyed sliding-window merges.

Bug found: the sliding-window sweep surfaced a real bug in execute_range_query_pipeline — for a step with current_time < window_size_ms, window_start = current_time.saturating_sub(window_size_ms) clamps to 0, aliasing onto the same store bucket as the legitimate step at current_time == window_size_ms. The too-early step gets a phantom duplicate of the later step's value instead of correctly having no sample. Pinned as a minimal, #[ignore]d regression test (not fixed here — out of scope for this PR, tracked separately).

#594 — Go differential e2e harness (promql-compliance/)

No live Prometheus/ASAPQuery run yet — this PR is code-only for the Go harness, per plan. CI wiring is deliberately deferred.

Test plan

  • cargo fmt, cargo check, cargo clippy, cargo test all pass (full pre-commit suite, run on the merged result)
  • go build ./... and go vet ./... pass for both promql-compliance/seeder and promql-compliance/harness
  • File a follow-up issue for the phantom-window sliding-range bug
  • Wire the Go harness into CI (separate PR, needs live Prometheus/ASAPQuery target decision)

🤖 Generated with Claude Code

milindsrivastava1997 and others added 10 commits August 26, 2026 00:22
Adds promql-compliance/seeder, a standalone Go module that builds a
prompb.WriteRequest for a fixed, hand-authored dataset (counters, a
gauge, and a label-churn series designed to exercise instant-vs-range
divergence), snappy-compresses it, and pushes the same bytes via
remote write to both a reference Prometheus and ASAPQuery's own
remote-write ingest endpoint. This is the data-seeding half of the
differential PromQL compliance harness proposed in #594; the
comparison-harness half is a separate workstream.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
…oracle (#590)

Adds the test #590 calls out as missing: for a stable key set, one
range(start,end,step) query's per-timestamp series must exactly equal N
separate instant(t) queries (one per step), not just checked at a single
timestamp. Covers {Tumbling, Sliding} x {single-population Sum,
dual-population Count} x >=4 steps. All four pass against current code.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
…ce-tester

Vendor prometheus/compliance/promql (commit 67b8327, Apache 2.0) into
promql-compliance/harness/ and patch Comparer.Compare to also run and diff an
instant query (PromAPI.Query) alongside the existing range query, since
upstream only ever exercised QueryRange. Range and instant outcomes are
tracked and reported independently (Result.RangeSuccess/InstantSuccess), so
"PASS: range, FAIL: instant" is a representable outcome instead of one
aggregate pass/fail -- this is the exact bug class cataloged in #589.

Adds config.yaml with placeholder reference/test target URLs and four seed
regression test cases ported from the query patterns described in #589,
#583, and #584 (top-k over range, per-step key snapshot churn, and two
sliding-window rate queries). Adds comparer_test.go with fake in-process
PromAPI doubles covering both diverging directions plus error/should-fail
handling, since no unit tests existed upstream.

Part of #594.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
…590)

validate_range_query_params had no dedicated tests. Adds direct unit tests
for its three error branches (start>=end, step==0, step not a multiple of
the tumbling window) plus the happy path, in an inline test module next to
the function (it's private and validate_range_query_params's error string
is discarded before reaching any public caller, so the exact-string
assertions can't be made from crate::tests).

Also adds end-to-end coverage via handle_range_query_promql confirming each
bad-param case is actually rejected in practice, including the start == end
boundary specifically, and a new test that runs the same keys-but-no-value
orphan-group scenario through both the instant and range entry points and
diffs their skip/error behavior explicitly, so a future regression that
splits their behavior fails here instead of only in one of the two existing
per-path tests.
Adds simulate_sliding_window_keyed, a pure-function sliding-window
oracle extended to keyed/grouped data (a sibling to the existing
simulate_sliding_window/simulate_sliding_window_with_alignment, kept
separate since those two are exercised by several existing
index-slicing call sites that don't have a notion of a key). Drives it
against a small deterministic sweep of window/slide configs and
per-key presence patterns (appearing, disappearing, oscillating, gap
mid-range) through a real SimpleEngine via
create_engine_multi_timestamp_with_window +
handle_range_query_promql.

The sweep surfaced a real bug: execute_range_query_pipeline computes
each Sliding-window step's window_start as
current_time.saturating_sub(lookback_ms), so every output step before
window_size_ms worth of history exists aliases onto the store's
start=0 window instead of correctly having no sample. Captured as a
minimal, #[ignore]'d regression
(sliding_window_range_query_start_before_window_size_ms_returns_wrong_value)
rather than patched, per #590's ground rules; the main property sweep
starts each scenario at its own window_size_ms to avoid that
known-buggy region while still exercising the key-expansion/merge
behavior it's meant to check.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
#590)

# Conflicts:
#	asap-query-engine/src/tests/mod.rs
@milindsrivastava1997
milindsrivastava1997 marked this pull request as draft August 26, 2026 12:28
@milindsrivastava1997 milindsrivastava1997 changed the title Add differential PromQL testing: multistep instant/range oracles + Go compliance harness (#590, #594) test(query-engine): add differential PromQL testing infra (#590, #594) Aug 26, 2026
@milindsrivastava1997

Copy link
Copy Markdown
Contributor Author

Handoff

Built via 5 parallel agents against genuine gaps in existing coverage (a lot of instant/range regression territory was already tested — this fills what wasn't).

Done, in this PR

Found along the way

TBD / not in this PR

  1. Fix Sliding-window range queries return a phantom duplicate for steps before the first full window #632. Not attempted — found by the tests this PR adds, scoped as its own fix.
  2. Live end-to-end run of the Go harness — needs a real Prometheus (--web.enable-remote-write-receiver) and ASAPQuery instance to point config.yaml at; currently placeholder URLs (localhost:9090/9091).
  3. CI wiring for the Go harness — last checkbox in Add differential e2e testing against real Prometheus using promql-compliance-tester #594, deliberately deferred (needs a decision on where/how it runs).
  4. Test suite ideas for instant/range PromQL query paths #590/Add differential e2e testing against real Prometheus using promql-compliance-tester #594 issue bodies still have their own checklists — worth revisiting once Sliding-window range queries return a phantom duplicate for steps before the first full window #632 is fixed and the harness has a live run, to decide what's left open vs. closeable.

Review pointers

  • The bug repro is the most interesting part to check first: asap-query-engine/src/tests/sliding_window_keyed_oracle_tests.rs:305.
  • Go modules each have their own go.mod under promql-compliance/seeder/ and promql-compliance/harness/ — no root Go module, nothing wired into the Rust build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant