Skip to content

test fixes - #5569

Merged
akshaydeo merged 1 commit into
devfrom
07-27-test_fixes
Jul 27, 2026
Merged

akshaydeo merged 1 commit into
devfrom
07-27-test_fixes

Conversation

@akshaydeo

@akshaydeo akshaydeo commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fixes several correctness issues across the responses pipeline, Sidekiq runner contention, MCP server auth routing, and budget override handling. The core theme is ensuring that data decoded through the raw-preserved fast path is re-emitted verbatim rather than reconstructed from partial struct fields, and that identity/credential precedence rules are enforced rather than rejected as conflicts.

Changes

  • ResponsesMessage marshal/unmarshal (core/schemas/responses.go):

    • MarshalJSON now short-circuits to return rawPreserved bytes verbatim when they are present, preventing silent data loss (e.g. id, status, call_id, per-tool type discriminators) that caused OpenAI to reject re-submitted items.
    • UnmarshalJSON now surfaces the execution field into ResponsesToolMessage.Execution and the tools array into ToolSearchOutputTools as raw JSON when decoding through the fast path, so downstream consumers can read them without triggering a full re-decode.
  • Responses test (core/providers/openai/responses_test.go):

    • Added expectRoleDropped flag to the test table to correctly assert that a typeless reasoning item has its role stripped rather than preserved, matching the OpenAI API contract.
  • Sidekiq runner race test (framework/sidekiq/sidekiq_test.go):

    • Introduced testRunnerWithID to build runners with explicit IDs. TestRunnerRaceSingleWinner now uses distinct runner IDs (runner-A, runner-B) so that staleAfter is non-zero and the loser cannot immediately reclaim the winner's in-flight job, eliminating a spurious double-execution race.
  • MCP server auth (transports/bifrost-http/handlers/mcpserver_auth_test.go):

    • Changed the "stamped user id with a header VK is rejected as conflicting" test to assert that the stamped user's representative VK wins and the header VK is silently ignored, rather than returning an error. Conflict resolution is the responsibility of upstream SCIM inference middleware, not getMCPServerForRequest.
  • Mock config store (transports/bifrost-http/lib/config_test.go):

    • Implemented UpdateBudgetOverride on MockConfigStore to mirror the RDB store's behaviour: applies only override columns, leaves usage and base config untouched, and returns ErrNotFound for unknown IDs.
  • Config schema (transports/config.schema.json):

    • Added override_amount, override_mode, override_cycles_remaining, override_cycles_total, and override_anchor_reset fields to the budget schema so override state is expressible in config files.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

go test ./core/schemas/...
go test ./core/providers/openai/...
go test ./framework/sidekiq/...
go test ./transports/bifrost-http/...

Validate that:

  • A round-tripped ResponsesMessage with rawPreserved bytes re-emits the original JSON byte-for-byte.
  • TestRunnerRaceSingleWinner passes consistently without the job running twice.
  • getMCPServerForRequest returns the user's representative VK server when both a stamped user ID and a header VK are present.
  • UpdateBudgetOverride on the mock store returns ErrNotFound for unknown IDs and correctly updates only override fields for known ones.

Breaking changes

  • No

Security considerations

The MCP auth change ensures a header-supplied virtual key cannot redirect or escalate an already-authenticated user to a different key. The stamped identity always wins, which is the intended security boundary.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 10 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a6d327bc-2864-4433-af78-afe0b5488258

📥 Commits

Reviewing files that changed from the base of the PR and between e19a097 and ca3bde2.

📒 Files selected for processing (6)
  • core/providers/openai/responses_test.go
  • core/schemas/responses.go
  • framework/sidekiq/sidekiq_test.go
  • transports/bifrost-http/handlers/mcpserver_auth_test.go
  • transports/bifrost-http/lib/config_test.go
  • transports/config.schema.json
📝 Walkthrough

Walkthrough

The changes preserve additional OpenAI response fields, update GPT-oss role expectations, stabilize a Sidekiq race test, revise MCP authentication expectations, and add governance budget override schema and mock-store support.

Changes

Responses serialization

Layer / File(s) Summary
Response field preservation
core/schemas/responses.go
Preserves execution and raw tools data for tool-search items and re-emits preserved response bytes during marshaling.
GPT-oss role handling tests
core/providers/openai/responses_test.go
Tests role removal for typeless reasoning items and preserves roles where applicable.

Sidekiq race test

Layer / File(s) Summary
Runner identity setup
framework/sidekiq/sidekiq_test.go
Adds explicit runner IDs and uses distinct IDs in the single-winner race test.

MCP authentication test

Layer / File(s) Summary
Stamped-user precedence
transports/bifrost-http/handlers/mcpserver_auth_test.go
Verifies that the stamped user’s representative virtual key selects the MCP server over a header virtual key.

Budget override support

Layer / File(s) Summary
Override contract and mock behavior
transports/config.schema.json, transports/bifrost-http/lib/config_test.go
Adds governance budget override fields and mirrors override updates in the mock configuration store.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • maximhq/bifrost#5551 — Adds the missing MockConfigStore.UpdateBudgetOverride implementation referenced by the issue.

Possibly related PRs

  • maximhq/bifrost#4711 — Both changes update ResponsesMessage handling to preserve tool-search response fields and wire shape.

Suggested reviewers: pratham-mishra04, bearts

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning This PR does not implement Files API support; it focuses on unrelated test and correctness fixes instead. Add provider-side Files API support for the linked issue, or retarget the PR to the correct issue.
Out of Scope Changes check ⚠️ Warning Several changes are unrelated to Files API support, including Sidekiq, MCP auth, budget override, and response schema tests. Remove or split the unrelated fixes so this PR stays focused on Files API support.
Title check ❓ Inconclusive The title is too vague and generic to describe the main change in the PR. Use a concise, specific title that names the primary change, such as the main subsystem or bug fix.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The description is mostly complete and follows the template with summary, changes, testing, security, and checklist sections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 07-27-test_fixes

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

@akshaydeo
akshaydeo marked this pull request as ready for review July 27, 2026 04:03

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🤖 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.

Inline comments:
In `@core/providers/openai/responses_test.go`:
- Around line 559-560: Update the gpt-oss “preserves message when Content
already exists” fixture to set expectRoleDropped true for its typeless reasoning
item with a role. Adjust the role assertion logic in the response conversion
tests so it runs for both Content == nil and existing-content paths, not only
the summary-conversion branch, matching the stripping behavior in the responses
converter.

In `@transports/bifrost-http/lib/config_test.go`:
- Around line 784-788: The mock budget update flow around SetOverrideAt must not
retain the caller-supplied IsCalendarAligned when validation fails. Preserve the
original flag and restore it if SetOverrideAt returns an error, or perform
validation on a copy and commit the flag only after success, matching
RDBConfigStore.UpdateBudgetOverride behavior.

In `@transports/config.schema.json`:
- Around line 517-541: Update the override schema containing override_amount,
override_mode, override_cycles_remaining, override_cycles_total, and
override_anchor_reset to add allOf/if/then constraints matching
TableBudget.validateOverride: empty mode requires all override fields to be zero
or absent, cycles requires positive amount and cycle counts with a valid anchor,
and forever requires a positive amount with zero/absent cycle fields and no
anchor. Do not encode the cross-field constraint that override_cycles_total must
be at least override_cycles_remaining, leaving that validation to runtime.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3099d3cd-b404-4d6a-8844-fb40c1226438

📥 Commits

Reviewing files that changed from the base of the PR and between 7e0f2d4 and e19a097.

📒 Files selected for processing (6)
  • core/providers/openai/responses_test.go
  • core/schemas/responses.go
  • framework/sidekiq/sidekiq_test.go
  • transports/bifrost-http/handlers/mcpserver_auth_test.go
  • transports/bifrost-http/lib/config_test.go
  • transports/config.schema.json

Comment thread core/providers/openai/responses_test.go
Comment thread transports/bifrost-http/lib/config_test.go
Comment thread transports/config.schema.json

akshaydeo commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Jul 27, 5:08 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jul 27, 5:08 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit 55e8757 into dev Jul 27, 2026
14 of 15 checks passed
@akshaydeo
akshaydeo deleted the 07-27-test_fixes branch July 27, 2026 05:08
akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
## Summary

This PR fixes several correctness issues across the responses pipeline, Sidekiq runner contention, MCP server auth routing, and budget override handling. The core theme is ensuring that data decoded through the raw-preserved fast path is re-emitted verbatim rather than reconstructed from partial struct fields, and that identity/credential precedence rules are enforced rather than rejected as conflicts.

## Changes

- **`ResponsesMessage` marshal/unmarshal (`core/schemas/responses.go`):**
  - `MarshalJSON` now short-circuits to return `rawPreserved` bytes verbatim when they are present, preventing silent data loss (e.g. `id`, `status`, `call_id`, per-tool type discriminators) that caused OpenAI to reject re-submitted items.
  - `UnmarshalJSON` now surfaces the `execution` field into `ResponsesToolMessage.Execution` and the `tools` array into `ToolSearchOutputTools` as raw JSON when decoding through the fast path, so downstream consumers can read them without triggering a full re-decode.

- **Responses test (`core/providers/openai/responses_test.go`):**
  - Added `expectRoleDropped` flag to the test table to correctly assert that a typeless reasoning item has its `role` stripped rather than preserved, matching the OpenAI API contract.

- **Sidekiq runner race test (`framework/sidekiq/sidekiq_test.go`):**
  - Introduced `testRunnerWithID` to build runners with explicit IDs. `TestRunnerRaceSingleWinner` now uses distinct runner IDs (`runner-A`, `runner-B`) so that `staleAfter` is non-zero and the loser cannot immediately reclaim the winner's in-flight job, eliminating a spurious double-execution race.

- **MCP server auth (`transports/bifrost-http/handlers/mcpserver_auth_test.go`):**
  - Changed the "stamped user id with a header VK is rejected as conflicting" test to assert that the stamped user's representative VK wins and the header VK is silently ignored, rather than returning an error. Conflict resolution is the responsibility of upstream SCIM inference middleware, not `getMCPServerForRequest`.

- **Mock config store (`transports/bifrost-http/lib/config_test.go`):**
  - Implemented `UpdateBudgetOverride` on `MockConfigStore` to mirror the RDB store's behaviour: applies only override columns, leaves usage and base config untouched, and returns `ErrNotFound` for unknown IDs.

- **Config schema (`transports/config.schema.json`):**
  - Added `override_amount`, `override_mode`, `override_cycles_remaining`, `override_cycles_total`, and `override_anchor_reset` fields to the budget schema so override state is expressible in config files.

## Type of change

- [x] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go test ./core/schemas/...
go test ./core/providers/openai/...
go test ./framework/sidekiq/...
go test ./transports/bifrost-http/...
```

Validate that:
- A round-tripped `ResponsesMessage` with `rawPreserved` bytes re-emits the original JSON byte-for-byte.
- `TestRunnerRaceSingleWinner` passes consistently without the job running twice.
- `getMCPServerForRequest` returns the user's representative VK server when both a stamped user ID and a header VK are present.
- `UpdateBudgetOverride` on the mock store returns `ErrNotFound` for unknown IDs and correctly updates only override fields for known ones.

## Breaking changes

- [x] No

## Security considerations

The MCP auth change ensures a header-supplied virtual key cannot redirect or escalate an already-authenticated user to a different key. The stamped identity always wins, which is the intended security boundary.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
occcat pushed a commit to occcat/bifrost that referenced this pull request Sep 2, 2026
## Summary

This PR fixes several correctness issues across the responses pipeline, Sidekiq runner contention, MCP server auth routing, and budget override handling. The core theme is ensuring that data decoded through the raw-preserved fast path is re-emitted verbatim rather than reconstructed from partial struct fields, and that identity/credential precedence rules are enforced rather than rejected as conflicts.

## Changes

- **`ResponsesMessage` marshal/unmarshal (`core/schemas/responses.go`):**
  - `MarshalJSON` now short-circuits to return `rawPreserved` bytes verbatim when they are present, preventing silent data loss (e.g. `id`, `status`, `call_id`, per-tool type discriminators) that caused OpenAI to reject re-submitted items.
  - `UnmarshalJSON` now surfaces the `execution` field into `ResponsesToolMessage.Execution` and the `tools` array into `ToolSearchOutputTools` as raw JSON when decoding through the fast path, so downstream consumers can read them without triggering a full re-decode.

- **Responses test (`core/providers/openai/responses_test.go`):**
  - Added `expectRoleDropped` flag to the test table to correctly assert that a typeless reasoning item has its `role` stripped rather than preserved, matching the OpenAI API contract.

- **Sidekiq runner race test (`framework/sidekiq/sidekiq_test.go`):**
  - Introduced `testRunnerWithID` to build runners with explicit IDs. `TestRunnerRaceSingleWinner` now uses distinct runner IDs (`runner-A`, `runner-B`) so that `staleAfter` is non-zero and the loser cannot immediately reclaim the winner's in-flight job, eliminating a spurious double-execution race.

- **MCP server auth (`transports/bifrost-http/handlers/mcpserver_auth_test.go`):**
  - Changed the "stamped user id with a header VK is rejected as conflicting" test to assert that the stamped user's representative VK wins and the header VK is silently ignored, rather than returning an error. Conflict resolution is the responsibility of upstream SCIM inference middleware, not `getMCPServerForRequest`.

- **Mock config store (`transports/bifrost-http/lib/config_test.go`):**
  - Implemented `UpdateBudgetOverride` on `MockConfigStore` to mirror the RDB store's behaviour: applies only override columns, leaves usage and base config untouched, and returns `ErrNotFound` for unknown IDs.

- **Config schema (`transports/config.schema.json`):**
  - Added `override_amount`, `override_mode`, `override_cycles_remaining`, `override_cycles_total`, and `override_anchor_reset` fields to the budget schema so override state is expressible in config files.

## Type of change

- [x] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go test ./core/schemas/...
go test ./core/providers/openai/...
go test ./framework/sidekiq/...
go test ./transports/bifrost-http/...
```

Validate that:
- A round-tripped `ResponsesMessage` with `rawPreserved` bytes re-emits the original JSON byte-for-byte.
- `TestRunnerRaceSingleWinner` passes consistently without the job running twice.
- `getMCPServerForRequest` returns the user's representative VK server when both a stamped user ID and a header VK are present.
- `UpdateBudgetOverride` on the mock store returns `ErrNotFound` for unknown IDs and correctly updates only override fields for known ones.

## Breaking changes

- [x] No

## Security considerations

The MCP auth change ensures a header-supplied virtual key cannot redirect or escalate an already-authenticated user to a different key. The stamped identity always wins, which is the intended security boundary.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
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