You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #5756. Unblocked by #6006 (the cross-generation bridge + live dual-era e2e).
Background
#5981 removed two specs from the single-server dual-era k8s test (commit 5fa67123b) because
they cannot work without the vMCP cross-generation bridge, with a note asking whoever landed the
bridge to re-add them as vMCP e2e coverage:
mixed Legacy + Modern traffic over a shared Redis session store
session-store (Redis) outage → 503, then recovery
Both need a Legacy (session) client to open a session while a stateless backend is in play. On a
single-server MCPServer that is impossible: one go-sdk backend cannot be both stateless (to serve
Modern per-request clients) and session-issuing (for Legacy clients) at once, and the single-server
proxy does per-request version discrimination, not generation bridging.
#6006 lands the bridge and live four-cell coverage at two tiers, but neither configures Redis:
test/e2e/vmcp_dual_era_test.go is CLI-tier, a single thv vmcp serve process with no session
storage at all.
test/e2e/thv-operator/virtualmcp/virtualmcp_dual_era_backends_test.go is single-replica and sets
no SessionStorage.
So the bridge is proven, but the session-store dimension of it is not: nothing exercises a
Legacy client's session metadata living in Redis while a Modern backend is in the same group, and
nothing exercises what a Redis outage does to a mixed-era deployment.
Work
Add operator-tier coverage, most naturally by growing test/e2e/thv-operator/virtualmcp/virtualmcp_dual_era_backends_test.go (which already stands up a
mixed Legacy + Modern backend set):
VirtualMCPServer with sessionStorage: redis and multiple replicas, over the existing mixed-era
backend set. Drive Legacy client traffic (which mints a session) and Modern client traffic (which
mints none) concurrently, and assert neither interferes with the other.
Redis outage → the Legacy path returns 503; after recovery, sessions work again. The Modern path
should be unaffected throughout, since a stateless request needs no session store — that
asymmetry is the interesting assertion and is exactly what a single-server test could not express.
Notes for whoever picks this up
Health monitoring must be enabled explicitly or the era assertions cannot work at all. mcp_revision is observable only through live health state, and vMCP only starts the monitor when operational.failureHandling.healthCheckInterval > 0. With the section absent the /status
payload carries no backends and the assertions time out after the full budget. unhealthyThreshold is mandatory once the interval is set, or the vmcp pod fails at startup. Bridge era-mismatched client×backend cells in vMCP #6006's operator spec has a working config to copy.
Assert each backend's negotiated era rather than trusting the env. Since Unify e2e yardstick backend on 1.2.0 #6004 a single
yardstick image serves both eras and STATELESS decides which, so a forgotten env var silently
produces an all-Legacy backend set — and every spec still passes while testing one edge twice. Bridge era-mismatched client×backend cells in vMCP #6006 added mcp_revision to /status (and it is already on VirtualMCPServer.status.discoveredBackends[]) precisely so this is assertable; that gate caught
exactly this failure once already.
Redis-backed multi-replica dual-era already exists for the single-server case in test/e2e/thv-operator/acceptance_tests/dual_era_k8s_test.go — useful as a wiring reference for
the Redis/replica setup, even though its mixed-era specs are the ones that were removed.
Part of #5756. Unblocked by #6006 (the cross-generation bridge + live dual-era e2e).
Background
#5981 removed two specs from the single-server dual-era k8s test (commit
5fa67123b) becausethey cannot work without the vMCP cross-generation bridge, with a note asking whoever landed the
bridge to re-add them as vMCP e2e coverage:
Both need a Legacy (session) client to open a session while a stateless backend is in play. On a
single-server
MCPServerthat is impossible: one go-sdk backend cannot be both stateless (to serveModern per-request clients) and session-issuing (for Legacy clients) at once, and the single-server
proxy does per-request version discrimination, not generation bridging.
Why this is not covered by #6006
#6006 lands the bridge and live four-cell coverage at two tiers, but neither configures Redis:
test/e2e/vmcp_dual_era_test.gois CLI-tier, a singlethv vmcp serveprocess with no sessionstorage at all.
test/e2e/thv-operator/virtualmcp/virtualmcp_dual_era_backends_test.gois single-replica and setsno
SessionStorage.So the bridge is proven, but the session-store dimension of it is not: nothing exercises a
Legacy client's session metadata living in Redis while a Modern backend is in the same group, and
nothing exercises what a Redis outage does to a mixed-era deployment.
Work
Add operator-tier coverage, most naturally by growing
test/e2e/thv-operator/virtualmcp/virtualmcp_dual_era_backends_test.go(which already stands up amixed Legacy + Modern backend set):
VirtualMCPServerwithsessionStorage: redisand multiple replicas, over the existing mixed-erabackend set. Drive Legacy client traffic (which mints a session) and Modern client traffic (which
mints none) concurrently, and assert neither interferes with the other.
should be unaffected throughout, since a stateless request needs no session store — that
asymmetry is the interesting assertion and is exactly what a single-server test could not express.
Notes for whoever picks this up
mcp_revisionis observable only through live health state, and vMCP only starts the monitor whenoperational.failureHandling.healthCheckInterval > 0. With the section absent the/statuspayload carries no backends and the assertions time out after the full budget.
unhealthyThresholdis mandatory once the interval is set, or the vmcp pod fails at startup.Bridge era-mismatched client×backend cells in vMCP #6006's operator spec has a working config to copy.
yardstick image serves both eras and
STATELESSdecides which, so a forgotten env var silentlyproduces an all-Legacy backend set — and every spec still passes while testing one edge twice.
Bridge era-mismatched client×backend cells in vMCP #6006 added
mcp_revisionto/status(and it is already onVirtualMCPServer.status.discoveredBackends[]) precisely so this is assertable; that gate caughtexactly this failure once already.
test/e2e/thv-operator/acceptance_tests/dual_era_k8s_test.go— useful as a wiring reference forthe Redis/replica setup, even though its mixed-era specs are the ones that were removed.