Skip to content

feat(bench): RFC 0031 — Loki container integration, RFC0031.1 green - #471

Merged
jensholdgaard merged 6 commits into
mainfrom
rfc0031-green-loki-container
Jul 11, 2026
Merged

feat(bench): RFC 0031 — Loki container integration, RFC0031.1 green#471
jensholdgaard merged 6 commits into
mainfrom
rfc0031-green-loki-container

Conversation

@jensholdgaard

@jensholdgaard jensholdgaard commented Jul 11, 2026

Copy link
Copy Markdown
Owner

What

The final slice of the RFC 0031 equivalence-harness: the Loki testcontainers integration that flips the RFC0031.1 stub green. Structured per review request:

  • Commit 1 (pushed, reviewable now): the shared OTLP fixture — the single source of truth. comparative_fixture(base_ns) → one OTLP LogsData (service.name = comparative-fixture), rendered two ways: fixture_jsonl (the Ourios corpus line, serde against the same with-serde type the loader parses — round-trips by construction) and the same LogsData protobuf-encoded for Loki's OTLP push. fixture_line_keys is the expected answer both systems must return. Local proof included: fixture_round_trips_through_the_ourios_side drives the fixture through the registry-bearing store + in-process query and asserts the extracted LineKeys equal fixture_line_keys.
  • Commit 2 (next): the container wiring — spin grafana/loki (testcontainers, Dex-style), push the fixture over OTLP (/otlp/v1/logs, protobuf), query_range the equivalent LogQL ({service_name="comparative-fixture"}), parse_loki_streamscompare_lines against the Ourios side → the RFC0031.1 stub becomes a real #[ignore]d test run by a new loki interop (testcontainers) CI job (modeled on collector-interop), plus a deliberate-mismatch arm (a narrower LogQL must yield Mismatch).
  • New dev-deps on ourios-bench: testcontainers-modules, reqwest, prost (protobuf encode), tokio test features.

Intentionally CI-only (like Dex)

The container test is #[ignore]d and executed by the CI job via --ignored --exact — there is no local Docker in the dev environment, matching the dex oidc / collector interop precedent. Everything around the container is already proven locally (comparator #467, Ourios extraction #468, registry-bearing store #469, Loki response parser #470, and commit 1's fixture round-trip); the container run validates only the last-mile Loki specifics.

The two known subtleties — validated through the container run

  1. Cross-system timestamp/body alignment: both systems ingest the same LogsData value, so (timestamp, body) is byte-identical by construction; the container run proves Loki's OTLP ingest → LogQL → response path preserves it (nanosecond timestamps and body bytes) end to end.
  2. RFC 0025 absent-vs-empty bodies: the fixture is string-bodied only; body_bytes deliberately errors on structured/absent bodies rather than collapsing them. Extending LineKey with a body-kind discriminator lands with the OTLP-native L2/L3/L4 gates, not here.

Scope

Focused on flipping RFC0031.1 green with one query pair. Nicer LogQL, more pairs, and the bytes-read metrics are follow-ups per the RFC's slice plan.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests

    • Added end-to-end compatibility testing between Ourios and Grafana Loki using shared log fixtures.
    • Added checks for equivalent query results and detection of intentionally narrower, non-equivalent queries.
    • Added validation that fixture logs can be ingested, queried, and compared consistently.
  • Chores

    • Integrated the Loki compatibility test into required CI checks.

The single source of truth for the RFC0031.1 equivalence check, in its
own commit so it reviews in isolation (container wiring follows).

- `FixtureRecord` + `comparative_fixture(base_ns)` — a deterministic
  3-record set (INFO/INFO/ERROR, distinct timestamps). `base_ns` is a
  parameter because Loki's default reject_old_samples refuses old lines,
  so the container test stamps near now while local tests use any base.
- `fixture_logs_data` — the records as one OTLP `LogsData` (one resource,
  `service.name = comparative-fixture`; one scope). Both systems' inputs
  derive from this one value: the Ourios corpus line and the Loki OTLP
  push, so `(timestamp, body)` is byte-identical by construction.
- `fixture_jsonl` — the `LogsData` as one OTLP/JSON Lines corpus line
  (serde against the same with-serde type `ingest_otlp_jsonl` parses, so
  it round-trips by construction).
- `fixture_line_keys` — the expected `LineKey`s a query matching every
  fixture record must return from either system.

Local proof (no container): `fixture_round_trips_through_the_ourios_side`
drives the fixture through the registry-bearing comparative store and the
in-process query, and asserts the extracted LineKeys equal
`fixture_line_keys` — the same expected keys the Loki container run is
compared against.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jensholdgaard, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b423ea0-0949-4cf7-9e1a-542180f449fa

📥 Commits

Reviewing files that changed from the base of the PR and between 38044ce and 58f1de9.

📒 Files selected for processing (3)
  • crates/ourios-bench/Cargo.toml
  • crates/ourios-bench/src/comparative.rs
  • crates/ourios-bench/tests/rfc0031_comparative.rs
📝 Walkthrough

Walkthrough

Changes

RFC0031.1 Loki equivalence

Layer / File(s) Summary
Comparative fixture harness
crates/ourios-bench/src/comparative.rs, crates/ourios-bench/src/lib.rs
Adds deterministic OTLP/JSONL fixtures, expected LineKey values, public re-exports, and an Ourios round-trip equivalence test.
Loki integration scenario
crates/ourios-bench/tests/rfc0031_comparative.rs
Replaces the RFC0031.1 stub with an ignored Testcontainers test that pushes fixtures to Loki, polls query results, and checks broad equality plus narrow-query inequality.
Container dependencies and CI wiring
crates/ourios-bench/Cargo.toml, .github/workflows/ci.yml
Adds integration-test dependencies and runs the exact ignored Loki test as a required CI job.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ComparativeFixture
  participant OuriosComparativeStore
  participant LokiContainer
  participant EquivalenceAssertions
  ComparativeFixture->>OuriosComparativeStore: provide JSONL fixture
  OuriosComparativeStore->>EquivalenceAssertions: return Ourios LineKeys
  ComparativeFixture->>LokiContainer: push OTLP LogsData
  LokiContainer->>EquivalenceAssertions: return broad and narrow query results
  EquivalenceAssertions->>EquivalenceAssertions: compare broad equality and narrow non-equality
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is detailed, but it does not use the required Summary/Related/Checklist template sections. Reformat it to include Summary, Related (issue/RFC links), and Checklist with the required checkbox items, especially tests/docs/RFC linkage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific and matches the main change: Loki container integration for RFC 0031.1.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rfc0031-green-loki-container

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The final slice of the equivalence harness: RFC0031.1 becomes a real
end-to-end test on a live Loki container (grafana/loki 3.5.3,
digest-pinned like Dex), run by the new required `loki-interop` CI job
via --ignored --exact — the dex-oidc / collector-interop pattern; there
is no local Docker, so validation is intentionally CI-only.

The test: the shared OTLP fixture (commit 1) is ingested by BOTH
systems — Ourios through the registry-bearing comparative store +
in-process query (the locally-proven path), Loki through its native
OTLP endpoint (the same LogsData value, prost-encoded to
/otlp/v1/logs) — then queried equivalently (logs DSL "severity >= 0"
vs LogQL {service_name="comparative-fixture"}), and the two LineKey
multisets must be identical via compare_lines. A deliberately narrower
LogQL (|= `logged in`, 2 of 3 lines) asserts the mismatch arm reports
Mismatch rather than silently passing.

Structure notes:
- Plain #[test]: ourios_query_lines owns its own runtime, so the Ourios
  half runs sync and only the container half runs inside block_on
  (nesting would panic).
- The fixture is stamped near now (Loki's reject_old_samples window).
- Readiness polls /ready and surfaces the container's stderr on timeout
  (a config rejection must not read as a bare timeout).
- New dev-deps: testcontainers-modules, reqwest (no TLS — plain http to
  the mapped port), prost 0.14 (the opentelemetry-proto 0.32
  generation), tokio rt-multi-thread + macros.
- CI: loki-interop job added and wired into ci-success's needs.

Default `cargo test` stays green (0 passed; 11 ignored — the live test
is #[ignore]d for Docker, ten red stubs remain for the later slices).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jensholdgaard
jensholdgaard marked this pull request as ready for review July 11, 2026 14:31
@jensholdgaard
jensholdgaard requested a review from Copilot July 11, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the RFC 0031.1 “result-set equivalence” slice end-to-end by adding a shared OTLP fixture and a Loki testcontainers-based interop test, then wiring that ignored test into CI via a dedicated required job.

Changes:

  • Adds a single-source-of-truth comparative fixture (LogsData + JSONL rendering + expected LineKeys) and a local Ourios-side round-trip proof test.
  • Converts RFC0031.1 from a red stub to a real ignored test that runs Loki in a container, pushes OTLP protobuf, queries LogQL, parses results, and compares via compare_lines.
  • Introduces a new loki-interop GitHub Actions job to run the ignored container test in CI.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/ourios-bench/tests/rfc0031_comparative.rs Implements the Loki container-based RFC0031.1 interop test and equivalence assertion.
crates/ourios-bench/src/lib.rs Re-exports new comparative fixture helpers/types for bench/test use.
crates/ourios-bench/src/comparative.rs Adds the shared OTLP fixture API and a local Ourios-side round-trip test.
crates/ourios-bench/Cargo.toml Adds dev-dependencies needed for Loki container interop (testcontainers/reqwest/prost/tokio features).
Cargo.lock Locks new dev-dependency additions.
.github/workflows/ci.yml Adds required loki-interop CI job to run the ignored RFC0031.1 test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/ourios-bench/tests/rfc0031_comparative.rs Outdated
Comment thread crates/ourios-bench/tests/rfc0031_comparative.rs Outdated
Comment thread crates/ourios-bench/src/comparative.rs Outdated
…nes)

CI clippy: the RFC0031.1 test fn hit too_many_lines (140/100). Extract
the container half as `loki_round_trip` (container + readiness + OTLP
push + both queries) and `loki_query_range` (one query_range call →
LineKeys). No behavior change — the loki-interop job already PASSED on
the previous head; this only restructures for the lint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Comment thread crates/ourios-bench/Cargo.toml Outdated
Comment thread crates/ourios-bench/tests/rfc0031_comparative.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/ourios-bench/tests/rfc0031_comparative.rs (1)

125-125: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a timeout to the reqwest::Client to prevent indefinite CI hangs.

Client::new() has no request timeout. If Loki accepts a connection but never responds (e.g., config rejection, deadlock), .send().await blocks forever — the deadline-based polling loops never reach their timeout checks because they run after the request returns. The OTLP push has no deadline at all. A hung request would block the job until GitHub's 6-hour default timeout.

♻️ Proposed fix
-        let http = reqwest::Client::new();
+        let http = reqwest::Client::builder()
+            .timeout(Duration::from_secs(30))
+            .build()
+            .expect("http client");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ourios-bench/tests/rfc0031_comparative.rs` at line 125, Update the
reqwest client initialization in the comparative benchmark test to configure a
finite request timeout instead of using Client::new(). Ensure the timeout
applies to both Loki polling requests and the OTLP push, using the existing
project convention or an appropriate bounded duration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/ourios-bench/tests/rfc0031_comparative.rs`:
- Line 125: Update the reqwest client initialization in the comparative
benchmark test to configure a finite request timeout instead of using
Client::new(). Ensure the timeout applies to both Loki polling requests and the
OTLP push, using the existing project convention or an appropriate bounded
duration.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 85e35305-24a1-4c51-aeb6-310f594ad21a

📥 Commits

Reviewing files that changed from the base of the PR and between 2e0c918 and 38044ce.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • crates/ourios-bench/Cargo.toml
  • crates/ourios-bench/src/comparative.rs
  • crates/ourios-bench/src/lib.rs
  • crates/ourios-bench/tests/rfc0031_comparative.rs

- tokio dev-dep: declare the `time` feature explicitly (sleep was
  compiling only via transitive feature unification).
- reqwest client: 10 s per-request timeout so a wedged container/network
  fails the request instead of hanging the CI job past its deadlines.
- Readiness panic surfaces BOTH container streams (Loki writes startup
  errors to stdout too, not just stderr).
- loki_query_range checks the HTTP status before parsing — a non-2xx
  body may not be streams JSON, and "parse failed" would mask the real
  error.
- fixture_logs_data rustdoc: proper FIXTURE_SERVICE intra-doc link.

No behavior change on the green path (the loki-interop job already
passed); these harden the failure modes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Comment thread crates/ourios-bench/tests/rfc0031_comparative.rs Outdated
Copilot review: the narrow line-filter used LogQL backtick (raw-string)
quoting — valid, and the passing loki-interop run proves Loki accepted
it — but the conventional form is double quotes; switch. More
substantively, the comment surfaced a latent weakness: the mismatch arm
asserted only inequality, so a silently-broken filter matching 0 lines
would still "pass". Pin the narrow result to exactly the two
"logged in" lines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Comment thread crates/ourios-bench/tests/rfc0031_comparative.rs Outdated
Copilot review: the 30 s backdate used bare subtraction, which would
panic on debug-build underflow if the clock were absurdly near the Unix
epoch. saturating_sub keeps it total.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Comment thread crates/ourios-bench/tests/rfc0031_comparative.rs
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.

2 participants