Skip to content

Make Claude auto tests mirror Claude Code traffic - #4228

Closed
nixyme wants to merge 1 commit into
QuantumNous:mainfrom
nixyme:codex/claude-code-auto-test-hardening
Closed

Make Claude auto tests mirror Claude Code traffic#4228
nixyme wants to merge 1 commit into
QuantumNous:mainfrom
nixyme:codex/claude-code-auto-test-hardening

Conversation

@nixyme

@nixyme nixyme commented Apr 14, 2026

Copy link
Copy Markdown

Summary

  • make scheduled Claude health checks send Claude Code style headers
  • attach metadata.user_id to Claude auto-test requests and preserve metadata in Claude conversion
  • stop scheduled auto-tests from directly auto-disabling channels while keeping manual test disable behavior intact
  • add targeted regression coverage for the Claude Code test fixtures

Why

A large share of Claude channels were being auto-disabled even though manual Claude Code traffic could still succeed. The root cause was that auto-tests were not close enough to real Claude Code traffic, so Claude-only upstreams were returning false negatives. This change makes the synthetic traffic much closer to real Claude Code requests and removes the most dangerous part of the feedback loop: scheduled tests auto-banning channels.

Testing

  • go test ./controller -run 'TestApplyClaudeCodeTestFixtures'
  • go test ./relay/channel/claude -run 'TestRequestOpenAI2ClaudeMessage_PreservesMetadata'
  • go test ./controller ./service

Summary by CodeRabbit

  • Tests

    • Added test fixtures and coverage for Claude-specific channel testing
    • Added validation for metadata preservation in request transformation
  • Refactor

    • Enhanced channel test control flow with configurable auto-disable behavior
    • Improved metadata handling in Claude request processing

@coderabbitai

coderabbitai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The changes add Claude-specific request header and metadata fixtures applied during channel testing, introduce an allowAutoDisable parameter to control auto-ban behavior in scheduled channel tests, and modify Claude relay conversion to preserve metadata from OpenAI requests to Claude requests.

Changes

Cohort / File(s) Summary
Claude Test Fixtures
controller/channel-test.go, controller/channel_test_fixture_test.go
Added claudeCodeTestHeaders map and applyClaudeCodeTestFixtures function to conditionally set Claude-specific headers and metadata during channel testing. Extended testAllChannels with allowAutoDisable parameter to gate auto-disable logic. Updated callers (TestAllChannels and AutomaticallyTestChannels) with appropriate parameter values.
Claude Metadata Handling
relay/channel/claude/relay-claude.go, relay/channel/claude/relay_claude_test.go
Modified RequestOpenAI2ClaudeMessage to conditionally preserve metadata from OpenAI requests in Claude relay conversion. Added test case to verify metadata preservation behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • seefs001
  • Calcium-Ion

Poem

🐰 Whiskers twitch with delight divine,
Claude's metadata preserved in-line,
Headers dance, fixtures shine so bright,
Auto-disable gates held tight,
Testing channels, all feels right! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective: making Claude auto tests mirror Claude Code traffic by adding Claude Code style headers and metadata to automated health checks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controller/channel-test.go (1)

830-842: ⚠️ Potential issue | 🟠 Major

Clear the running flag on early setup failure.

testAllChannelsRunning is set before model.GetAllChannels, but the early return on getChannelErr never resets it. One transient query failure will make every later manual and scheduled run report “测试已在运行中” until the process restarts.

Proposed fix
 func testAllChannels(notify bool, allowAutoDisable bool) error {
 
 	testAllChannelsLock.Lock()
 	if testAllChannelsRunning {
 		testAllChannelsLock.Unlock()
 		return errors.New("测试已在运行中")
 	}
 	testAllChannelsRunning = true
 	testAllChannelsLock.Unlock()
 	channels, getChannelErr := model.GetAllChannels(0, 0, true, false)
 	if getChannelErr != nil {
+		testAllChannelsLock.Lock()
+		testAllChannelsRunning = false
+		testAllChannelsLock.Unlock()
 		return getChannelErr
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controller/channel-test.go` around lines 830 - 842, The function
testAllChannels sets testAllChannelsRunning before calling model.GetAllChannels
but returns early on error without clearing the flag; modify testAllChannels to
ensure testAllChannelsRunning is always cleared on exit (and testAllChannelsLock
unlocked) by introducing a deferred cleanup after acquiring the lock (e.g. defer
that sets testAllChannelsRunning = false and releases any held lock) so that any
early return from model.GetAllChannels or other setup failures resets the
running flag and avoids permanently blocking subsequent runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@controller/channel-test.go`:
- Around line 74-98: The current guard in applyClaudeCodeTestFixtures uses
info.RelayFormat to detect Claude but misses requests that start as OpenAI paths
and are later adapted to Claude; change the guard to detect the resolved
upstream being Claude instead (inspect the RelayInfo field that holds the
resolved upstream target — e.g., info.Upstream, info.UpstreamPath or
info.UpstreamURL — and test for the Claude upstream path/host used by your
adaptors) and only return early when that resolved upstream does not indicate
Claude; keep the rest of applyClaudeCodeTestFixtures (header injection, Metadata
set, and RuntimeHeadersOverride) intact.

---

Outside diff comments:
In `@controller/channel-test.go`:
- Around line 830-842: The function testAllChannels sets testAllChannelsRunning
before calling model.GetAllChannels but returns early on error without clearing
the flag; modify testAllChannels to ensure testAllChannelsRunning is always
cleared on exit (and testAllChannelsLock unlocked) by introducing a deferred
cleanup after acquiring the lock (e.g. defer that sets testAllChannelsRunning =
false and releases any held lock) so that any early return from
model.GetAllChannels or other setup failures resets the running flag and avoids
permanently blocking subsequent runs.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 999b6eac-4b01-42a3-b3eb-2e4db7642324

📥 Commits

Reviewing files that changed from the base of the PR and between 8c8661d and 6280175.

📒 Files selected for processing (4)
  • controller/channel-test.go
  • controller/channel_test_fixture_test.go
  • relay/channel/claude/relay-claude.go
  • relay/channel/claude/relay_claude_test.go

Comment on lines +74 to +98
func applyClaudeCodeTestFixtures(c *gin.Context, info *relaycommon.RelayInfo, request dto.Request) {
if c == nil || c.Request == nil || info == nil || info.RelayFormat != types.RelayFormatClaude {
return
}

for key, value := range claudeCodeTestHeaders {
if strings.TrimSpace(c.Request.Header.Get(key)) == "" {
c.Request.Header.Set(key, value)
}
}

if req, ok := request.(*dto.GeneralOpenAIRequest); ok && len(req.Metadata) == 0 {
req.Metadata = json.RawMessage(`{"user_id":"channel-test"}`)
}

runtimeHeaders := map[string]interface{}{}
for key, value := range relaycommon.GetEffectiveHeaderOverride(info) {
runtimeHeaders[key] = value
}
for key, value := range claudeCodeTestHeaders {
runtimeHeaders[key] = value
}
info.RuntimeHeadersOverride = runtimeHeaders
info.UseRuntimeHeadersOverride = true
}

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.

⚠️ Potential issue | 🟠 Major

Don't key the Claude fixture off inbound relay format alone.

testChannel still builds /v1/chat/completions by default, so Claude-backed channels often arrive here as RelayFormatOpenAI. Those requests are later converted to Claude upstreams in adaptors like relay/channel/aws/adaptor.go:124-128 and relay/channel/vertex/adaptor.go:327-336, so this guard skips the new headers/metadata for a chunk of the Claude traffic the PR is trying to harden. Gating on the resolved upstream Claude path would make this effective for the default test flow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controller/channel-test.go` around lines 74 - 98, The current guard in
applyClaudeCodeTestFixtures uses info.RelayFormat to detect Claude but misses
requests that start as OpenAI paths and are later adapted to Claude; change the
guard to detect the resolved upstream being Claude instead (inspect the
RelayInfo field that holds the resolved upstream target — e.g., info.Upstream,
info.UpstreamPath or info.UpstreamURL — and test for the Claude upstream
path/host used by your adaptors) and only return early when that resolved
upstream does not indicate Claude; keep the rest of applyClaudeCodeTestFixtures
(header injection, Metadata set, and RuntimeHeadersOverride) intact.

@seefs001

Copy link
Copy Markdown
Collaborator

newapi不会接受伪造请求特征操作的PR

@seefs001 seefs001 closed this Apr 14, 2026
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