mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
fix(ci): update tests to assert absence of requires_openai_auth (bug 3, #406)
- Restore build_provider_section() to headroom/providers/codex/install.py without requires_openai_auth (was removed entirely; pre-existing test test_provider_codex_install.py imports it and would fail to collect) - Flip test_codex_provider_section_preserves_openai_oauth to assert requires_openai_auth is ABSENT, not present (old behavior was wrong) - Fix test_provider_codex_runtime.py:337 same way — init config must NOT contain requires_openai_auth - Fix Ruff B023 lint error in test_providers.py:492 — capture loop variable config_path in lambda default arg (_p=config_path) - Fix e2e/init/run.py _verify_codex_local and _verify_codex_global to assert requires_openai_auth is absent, not present - Fix e2e/wrap/run.py verify_codex_wrap same way All unit tests pass locally (82 affected tests green). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
32f499cbba
commit
4071d57134
6 changed files with 67 additions and 17 deletions
|
|
@ -139,9 +139,13 @@ def _verify_codex_local(ctx: CaseContext) -> None:
|
|||
raise AssertionError("Codex config should point at the requested proxy port (9012)")
|
||||
if 'env_key = "OPENAI_API_KEY"' in config:
|
||||
raise AssertionError("Codex local init should preserve OAuth and never inject env_key")
|
||||
for expected in ("requires_openai_auth = true", "supports_websockets = true"):
|
||||
if expected not in config:
|
||||
raise AssertionError(f"Codex local init missing {expected!r}")
|
||||
# Bug 3 (#406): requires_openai_auth must be absent from headroom provider blocks.
|
||||
if "requires_openai_auth" in config:
|
||||
raise AssertionError(
|
||||
"Codex local init must NOT inject requires_openai_auth into the headroom provider block"
|
||||
)
|
||||
if "supports_websockets = true" not in config:
|
||||
raise AssertionError("Codex local init missing 'supports_websockets = true'")
|
||||
if config.count("[features]") != 1:
|
||||
raise AssertionError("Codex config should keep a single [features] table")
|
||||
if "codex_hooks = true" not in config:
|
||||
|
|
@ -177,9 +181,13 @@ def _verify_codex_global(ctx: CaseContext) -> None:
|
|||
raise AssertionError("Codex user config should point at port 8787 by default")
|
||||
if 'env_key = "OPENAI_API_KEY"' in config:
|
||||
raise AssertionError("Codex global init should preserve OAuth and never inject env_key")
|
||||
for expected in ("requires_openai_auth = true", "supports_websockets = true"):
|
||||
if expected not in config:
|
||||
raise AssertionError(f"Codex global init missing {expected!r}")
|
||||
# Bug 3 (#406): requires_openai_auth must be absent from headroom provider blocks.
|
||||
if "requires_openai_auth" in config:
|
||||
raise AssertionError(
|
||||
"Codex global init must NOT inject requires_openai_auth into the headroom provider block"
|
||||
)
|
||||
if "supports_websockets = true" not in config:
|
||||
raise AssertionError("Codex global init missing 'supports_websockets = true'")
|
||||
if "codex_hooks = true" not in config:
|
||||
raise AssertionError("Codex user config should enable codex_hooks")
|
||||
hooks = json.loads((ctx.home / ".codex" / "hooks.json").read_text(encoding="utf-8"))
|
||||
|
|
|
|||
|
|
@ -563,8 +563,12 @@ def verify_codex_wrap(
|
|||
'env_key = "OPENAI_API_KEY"' not in config,
|
||||
"Codex wrap should preserve OAuth and never inject env_key",
|
||||
)
|
||||
for expected in ("requires_openai_auth = true", "supports_websockets = true"):
|
||||
assert_true(expected in config, f"Codex wrap missing {expected!r}")
|
||||
# Bug 3 (#406): requires_openai_auth must be absent from headroom provider blocks.
|
||||
assert_true(
|
||||
"requires_openai_auth" not in config,
|
||||
"Codex wrap must NOT inject requires_openai_auth into the headroom provider block",
|
||||
)
|
||||
assert_true("supports_websockets = true" in config, "Codex wrap missing 'supports_websockets = true'")
|
||||
|
||||
entries = read_jsonl(log_dir / "codex.jsonl")
|
||||
assert_true(len(entries) > 0, "Codex shim should have been invoked")
|
||||
|
|
|
|||
|
|
@ -32,6 +32,31 @@ _ORPHAN_HEADROOM_TABLE = re.compile(
|
|||
)
|
||||
|
||||
|
||||
def build_provider_section(
|
||||
*,
|
||||
port: int,
|
||||
name: str,
|
||||
marker_start: str = _CODEX_MARKER_START,
|
||||
marker_end: str = _CODEX_MARKER_END,
|
||||
include_markers: bool = True,
|
||||
) -> str:
|
||||
"""Build a managed Codex provider block (without requires_openai_auth).
|
||||
|
||||
Bug 3 (#406): requires_openai_auth must NOT appear on custom provider
|
||||
blocks — it forces codex to demand OpenAI OAuth login for local-proxy
|
||||
traffic. The built-in openai provider carries this flag; headroom does not.
|
||||
"""
|
||||
body = (
|
||||
"[model_providers.headroom]\n"
|
||||
f'name = "{name}"\n'
|
||||
f'base_url = "{proxy_base_url(port)}"\n'
|
||||
"supports_websockets = true\n"
|
||||
)
|
||||
if not include_markers:
|
||||
return body
|
||||
return f"{marker_start}\n{body}{marker_end}\n"
|
||||
|
||||
|
||||
def build_install_env(*, port: int, backend: str) -> dict[str, str]:
|
||||
"""Build the persistent install environment for Codex."""
|
||||
del backend
|
||||
|
|
@ -49,11 +74,12 @@ def apply_provider_scope(manifest: DeploymentManifest) -> ManagedMutation | None
|
|||
f"{_CODEX_MARKER_START}\n"
|
||||
'model_provider = "headroom"\n'
|
||||
f'openai_base_url = "{proxy_base_url(manifest.port)}"\n\n'
|
||||
"[model_providers.headroom]\n"
|
||||
'name = "Headroom persistent proxy"\n'
|
||||
f'base_url = "{proxy_base_url(manifest.port)}"\n'
|
||||
"supports_websockets = true\n"
|
||||
f"{_CODEX_MARKER_END}\n"
|
||||
+ build_provider_section(
|
||||
port=manifest.port,
|
||||
name="Headroom persistent proxy",
|
||||
include_markers=False,
|
||||
)
|
||||
+ f"{_CODEX_MARKER_END}\n"
|
||||
)
|
||||
if path.exists():
|
||||
existing = path.read_text()
|
||||
|
|
|
|||
|
|
@ -489,7 +489,8 @@ def test_headroom_provider_block_never_sets_requires_openai_auth(
|
|||
for port in (8787, 9999):
|
||||
config_path = tmp_path / f"config_{port}.toml"
|
||||
monkeypatch.setattr(
|
||||
"headroom.providers.codex.install.codex_config_path", lambda: config_path
|
||||
"headroom.providers.codex.install.codex_config_path",
|
||||
lambda _p=config_path: _p,
|
||||
)
|
||||
manifest = _manifest(tmp_path)
|
||||
manifest.port = port
|
||||
|
|
|
|||
|
|
@ -3,12 +3,20 @@ from __future__ import annotations
|
|||
from headroom.providers.codex.install import build_provider_section
|
||||
|
||||
|
||||
def test_codex_provider_section_preserves_openai_oauth() -> None:
|
||||
def test_codex_provider_section_no_requires_openai_auth() -> None:
|
||||
"""Bug 3 (#406): build_provider_section must NOT include requires_openai_auth.
|
||||
|
||||
Setting requires_openai_auth on a custom [model_providers.headroom] block
|
||||
forces codex to demand OpenAI OAuth login for every headroom-routed request.
|
||||
Headroom is a local proxy — it must never carry this flag.
|
||||
"""
|
||||
section = build_provider_section(port=8787, name="OpenAI via Headroom proxy")
|
||||
|
||||
assert 'name = "OpenAI via Headroom proxy"' in section
|
||||
assert 'base_url = "http://127.0.0.1:8787/v1"' in section
|
||||
assert "requires_openai_auth = true" in section
|
||||
assert "requires_openai_auth" not in section, (
|
||||
f"requires_openai_auth must be absent from the headroom provider section; got:\n{section}"
|
||||
)
|
||||
assert "supports_websockets = true" in section
|
||||
assert 'env_key = "OPENAI_API_KEY"' not in section
|
||||
|
||||
|
|
|
|||
|
|
@ -334,7 +334,10 @@ def test_init_codex_config_routes_messages_through_headroom(
|
|||
config_path = tmp_path / ".codex" / "config.toml"
|
||||
content = config_path.read_text(encoding="utf-8")
|
||||
assert 'env_key = "OPENAI_API_KEY"' not in content
|
||||
assert "requires_openai_auth = true" in content
|
||||
# Bug 3 (#406): requires_openai_auth must be absent from headroom provider blocks.
|
||||
assert "requires_openai_auth" not in content, (
|
||||
f"requires_openai_auth must not appear in init-generated Codex config:\n{content}"
|
||||
)
|
||||
|
||||
_assert_delivery(
|
||||
codex_proxy_stack,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue