Skip to content

fix(test): register the GetServerLogs fixture client only after PhaseReady - #1228

Merged
Dumbris merged 1 commit into
mainfrom
fix/logs-test-reconcile-race
Sep 9, 2026
Merged

fix(test): register the GetServerLogs fixture client only after PhaseReady#1228
Dumbris merged 1 commit into
mainfrom
fix/logs-test-reconcile-race

Conversation

@Dumbris

@Dumbris Dumbris commented Sep 8, 2026

Copy link
Copy Markdown
Member

Summary

TestGetServerLogs_MissingFileReturnsEmptyNotError (from #1216) flaked once on a loaded machine during the full go test -race ./internal/server/... run with server not found: never-logged, while passing 3/3 in isolation.

Cause. newLogsTestServer registered the upstream client via UpstreamManager().AddServerConfig at construction. Background initialization then runs LoadConfiguredServers, which snapshots the manager's clients, diffs them against cfg.Servers, and removes the difference in goroutines. A client added before that diff is on the removal list; under load the removal landed between construction and the call.

Why the #1218 pattern alone was not enough. Applying only ensureFixerClient-style re-registration at the call site fixed server not found but still failed 2/100 under -race: the removal's own Disconnecting from server line creates the per-server log file this test asserts is absent (Should be empty, but was [...]). The fixer tests never see that because they seed the log file themselves.

Fix. Wait for the runtime to reach PhaseReady before registering; the phase flips only after LoadConfiguredServers has taken its snapshot, so a client added afterwards is never on a removal list, and the supervisor's periodic reconcile only removes names from a config snapshot. The call-site re-registration is kept too, mirroring the fixer tests. Assertions unchanged.

Verification

  • 3s sleep between construction and the call: fails on the old fixture, passes with this change.
  • go test -race -count=5 -run 'TestGetServerLogs_' ./internal/server — ok
  • -count=50, twice, with 6 CPU hogs running — 200/200 pass (re-register-only variant: 2/100 fail)
  • golangci-lint run --config .github/.golangci.yml ./internal/server/... — 0 issues

Note for #1218: newFixerTestServer has the same construction-time registration and could in principle lose its client to the same one-shot removal before the call-site re-register; it only survives because it re-registers immediately before invoking the fixer and writes its own log file. The PhaseReady wait here would harden it too if it ever flakes.

…Ready

TestGetServerLogs_MissingFileReturnsEmptyNotError (#1216) flaked on a loaded
machine during the full `go test -race ./internal/server/...` run with
"server not found: never-logged", while passing every time in isolation.

CAUSE. newLogsTestServer registered the upstream client by calling
UpstreamManager().AddServerConfig at construction. Background initialization
then runs LoadConfiguredServers, which snapshots the manager's clients, diffs
them against cfg.Servers and removes the difference in goroutines. A client
added before that diff is on the removal list. On an idle machine the test
finished first; under load the removal landed in between.

The re-register-at-call-site pattern from diagnostics_fixers_test.go
(ensureFixerClient, #1218) is necessary but NOT sufficient here: it fixes
"server not found", but the removal's own "Disconnecting from server" line
creates the per-server log file this test asserts is absent, so the test
still failed 2/100 under -race with `Should be empty, but was [...]`. The
fixer tests never hit that because they seed the log file themselves.

FIX. Wait for the runtime to report PhaseReady before registering. The
phase flips only after LoadConfiguredServers has taken its snapshot, so a
client added afterwards is never on a removal list, and the supervisor's
periodic reconcile only removes names it found in a config snapshot. The
call-site re-registration (ensureLogsClient) is kept as well, mirroring the
fixer tests; re-registering an unchanged config keeps the existing client
and logs nothing. Assertions are unchanged.

REPRO. A 3s sleep between construction and the call fails on the old
fixture and passes with this change. Verified:
  go test -race -count=5 -run 'TestGetServerLogs_' ./internal/server  ok
  same with -count=50, twice, under 6 CPU hogs                       200/200
  golangci-lint (.github/.golangci.yml)                              0 issues
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 8, 2026

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 81e2450
Status: ✅  Deploy successful!
Preview URL: https://80b15b1f.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-logs-test-reconcile-race.mcpproxy-docs.pages.dev

View logs

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/logs-test-reconcile-race

Available Artifacts

  • archive-darwin-amd64 (29 MB)
  • archive-darwin-arm64 (26 MB)
  • archive-linux-amd64 (17 MB)
  • archive-linux-arm64 (16 MB)
  • archive-windows-amd64 (29 MB)
  • archive-windows-arm64 (26 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (23 MB)
  • installer-dmg-darwin-arm64 (21 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 34260706349 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

@Dumbris
Dumbris merged commit a742ef7 into main Sep 9, 2026
39 checks passed
@Dumbris
Dumbris deleted the fix/logs-test-reconcile-race branch September 9, 2026 03:23
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