Skip to content

Commit bbc00ec

Browse files
author
Kowser
committed
fix(e2e): tolerate conductor-oss's read-only secret store; harden mcp-testkit preflight
conductor-oss's standalone server serves secrets from the process env, so PUT/DELETE /api/secrets/* return 500 "env-backed secrets are read-only". This never surfaced while e2e ran against the writable agentspan server; switching to conductor-oss exposed it as 4 CI failures (suite2, suite4, suite26). Mirrors the assumption-skip already shipped in the Java/C# ports: CredentialsCLI.set() and test_suite26's _put_secret() skip (not fail) on a "read-only" response body; CredentialsCLI.delete() additionally tolerates "read-only" as best-effort cleanup, same as it already does for "not found". Also widens test_suite5's mcp-testkit --help preflight from a 5s timeout that only caught FileNotFoundError to 15s + catching TimeoutExpired too — a separate, likely-environmental flake surfaced in the same CI run.
1 parent b543815 commit bbc00ec

3 files changed

Lines changed: 29 additions & 9 deletions

File tree

e2e/conftest.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,23 @@ def _run(self, *args: str) -> subprocess.CompletedProcess:
110110

111111
def set(self, name: str, value: str) -> None:
112112
result = self._run("credentials", "set", name, value)
113-
assert result.returncode == 0, (
114-
f"credentials set {name} failed: {result.stderr}"
115-
)
113+
if result.returncode != 0:
114+
# conductor-oss standalone serves secrets from the server process
115+
# env — the store is read-only there, so the write-dependent
116+
# lifecycle steps cannot run (a server-flavor capability, not an
117+
# SDK regression; mirrors the Java/C# ports' assumption-skip).
118+
if "read-only" in result.stderr.lower():
119+
pytest.skip(
120+
"server secret store is read-only (env-backed) — "
121+
"skipping write-dependent step"
122+
)
123+
raise AssertionError(f"credentials set {name} failed: {result.stderr}")
116124

117125
def delete(self, name: str) -> None:
118126
result = self._run("credentials", "delete", name)
119-
# Ignore "not found" errors during cleanup
120-
if result.returncode != 0 and "not found" not in result.stderr.lower():
127+
# Ignore "not found" and "read-only" errors during cleanup — best-effort
128+
stderr = result.stderr.lower()
129+
if result.returncode != 0 and "not found" not in stderr and "read-only" not in stderr:
121130
raise AssertionError(
122131
f"credentials delete {name} failed: {result.stderr}"
123132
)

e2e/test_suite26_worker_credentials.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,17 @@ def _put_secret(name: str, value: str) -> None:
8989
headers={"Content-Type": "text/plain"},
9090
timeout=10,
9191
)
92-
r.raise_for_status()
92+
if not r.ok:
93+
# conductor-oss standalone serves secrets from the server process
94+
# env — the store is read-only there, so the write-dependent
95+
# lifecycle steps cannot run (a server-flavor capability, not an
96+
# SDK regression; mirrors the Java/C# ports' assumption-skip).
97+
if "read-only" in r.text.lower():
98+
pytest.skip(
99+
"server secret store is read-only (env-backed) — "
100+
"skipping write-dependent step"
101+
)
102+
r.raise_for_status()
93103

94104

95105
def _delete_secret(name: str) -> None:

e2e/test_suite5_http_tools.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,12 @@ def test_http_lifecycle(self, runtime, cli_credentials, model):
457457
["mcp-testkit", "--help"],
458458
capture_output=True,
459459
text=True,
460-
timeout=5,
460+
timeout=15,
461461
)
462-
except FileNotFoundError:
462+
except (FileNotFoundError, subprocess.TimeoutExpired):
463463
pytest.skip(
464-
"mcp-testkit not installed — required for Suite 5 HTTP tools test"
464+
"mcp-testkit not installed or unresponsive — required for "
465+
"Suite 5 HTTP tools test"
465466
)
466467

467468
server_proc = None

0 commit comments

Comments
 (0)