Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ All tests live directly in `integration/`; shared mechanics live in `utils/`.
| `test_case_06_*`, `test_case_08_*` | Pass a provider or model-location override to managed Codex after configure and from fresh state | ug rejects the override before Codex starts and preserves agent-owned state |
| `test_case_10_*`, `test_case_12_*` | Disable discovery and pass a provider or model-location override to managed Codex | ug still rejects both configured and fresh launches |
| `test_ug_configure_managed_codex_catalog_fallback` | Configure from an injected managed response containing a GPT model absent from Codex's bundled catalog | Actionable metadata warning; conservative catalog entry for the unknown model; real Codex prompt on the valid default model |
| `test_managed_fixture_codex_http_headers_in_managed_file` | Interactive PTY configure with injected managed `http_headers` for Codex | The specified header (`x-databricks-workspace`) lands in `model_providers.Databricks.http_headers` in `/etc/codex/managed_config.toml` with the exact admin value |
| `test_managed_fixture_claude_mps_defaults_accompany_discovery`, `test_managed_fixture_claude_parent_schema_defaults_accompany_discovery` | Launch Claude from injected managed defaults with MPS and Unity Catalog discovery | Both generated settings files retain every admin-authored default alongside the source header; only UC Opus/Sonnet family ids gain `[1m]` |
| `test_managed_fixture_claude_model_lifecycle`, `test_managed_fixture_codex_model_lifecycle` | Configure across no config -> static A -> static B -> MPS -> no config (stub-injected, `null` for no-config; MPS via a real provider service) | Each agent's model files reconcile to each static config (removed models pruned); switching to an MPS and a workspace with no managed config both clear ug's managed model settings so no stale list is enforced |
| `test_ug_installed_wheel_exposes_help_and_version` | Invoke freshly installed console command | Package version matches; public help works |
Expand All @@ -72,9 +73,9 @@ All tests live directly in `integration/`; shared mechanics live in `utils/`.
With both agents selected there are **46 live cases** (6 interactive TUI cases),
**4 managed-workspace cases** (marker `managed`, run against a separate workspace that
publishes a CodingAgentConfig), **1 two-workspace case** (marker `workspace_switch`),
**36 managed-fixture cases** (marker `managed_fixture`, with only
**37 managed-fixture cases** (marker `managed_fixture`, with only
the CodingAgentConfig input injected), and **5 installation checks**. The 24 numbered scenarios
cover configured and fresh state across the Claude and Codex managed-discovery matrix; twelve
cover configured and fresh state across the Claude and Codex managed-discovery matrix; thirteen
existing collected cases cover focused model, MCP, skills, and lifecycle shapes. Parametrization
varies
argument spelling or routing mode, never hides the agent/provider in the test name. Duplicate boot-only cases
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,10 @@ checks** with both agents. A separate **4 managed-workspace cases** (one per age
re-configure, and a cache-TTL journey; marker `managed`) run against a workspace that publishes a
CodingAgentConfig; see "Managed-workspace journeys" below. One **`workspace_switch` case**
uses two real workspaces and checks skills MCP cleanup and a completed Claude task.
A further **36 `managed_fixture`
A further **37 `managed_fixture`
cases** use `UCODE_MANAGED_CONFIG_STUB`. Twenty-four explicit configured/fresh Claude and Codex
discovery and source-override journeys fetch the published config once per agent, replace that
agent's static source with its dedicated MPS, and reuse the result. Twelve existing collected cases
agent's static source with its dedicated MPS, and reuse the result. Thirteen existing collected cases
cover focused model, MCP, skills, and lifecycle shapes, including per-agent model reconciliation
and managed skill cleanup. The two Claude default-model cases launch with injected MPS and Unity
Catalog sources and verify both generated settings files retain all admin-authored family defaults.
Expand Down
43 changes: 43 additions & 0 deletions tests/integration/test_ug_configure_managed_mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,46 @@ def test_managed_fixture_codex_mcp_written_to_managed_file(live_session, workspa
personal = tomllib.loads(personal_path.read_text()) if personal_path.exists() else {}
personal_servers = personal.get("mcp_servers") or {}
assert not any("github" in name.lower() for name in personal_servers), personal_servers


@pytest.mark.managed_fixture
@pytest.mark.codex
def test_managed_fixture_codex_http_headers_in_managed_file(live_session, workspace, tmp_path):
"""Scenario: an interactive configure with managed http_headers writes them into the OS-managed file.

Scope: managed-config content assertion in the same family as the MCP/skills/models
managed_fixture tests — verifies the http_headers field flows from the injected
CodingAgentConfig through `ug configure codex` into the OS-managed
/etc/codex/managed_config.toml under [model_providers.Databricks.http_headers].

Expected: after an interactive PTY configure, /etc/codex/managed_config.toml contains
model_providers.Databricks.http_headers with the admin-specified header
x-databricks-workspace = "eng-ml-inference", exactly as the injected managed config
dictates.
"""
session = live_session
managed_header_key = "x-databricks-workspace"
managed_header_value = "eng-ml-inference"
config = build_coding_agent_config(
"CODING_AGENT_CODEX",
build_codex_agent_config(
models=[CODEX_MODEL],
http_headers={managed_header_key: managed_header_value},
),
)
set_managed_config_stub(session, tmp_path, config)
command = [str(session.binary), "configure", "--workspace", workspace, "--skip-upgrade"]
with ConfigureTerminal(session, "codex", command, "managed-http-headers-codex") as configure:
configure.finish(timeout=300)

managed = tomllib.loads(session.run(CODEX_MANAGED_CONFIG_PATH, binary="cat", timeout=30).stdout)
provider = (managed.get("model_providers") or {}).get("Databricks") or {}
headers = provider.get("http_headers") or {}
assert managed_header_key in headers, (
f"Expected header {managed_header_key!r} in model_providers.Databricks.http_headers; "
f"got: {headers!r}\nFull managed config: {managed!r}"
)
assert headers[managed_header_key] == managed_header_value, (
f"Expected {managed_header_key!r} = {managed_header_value!r}, "
f"got {headers[managed_header_key]!r}"
)
9 changes: 8 additions & 1 deletion tests/integration/utils/managed.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,20 @@ def build_claude_agent_config(
return {"agent": "CODING_AGENT_CLAUDE_CODE", "config": config}


def build_codex_agent_config(*, models: list[str], smart_routing: bool = False) -> dict:
def build_codex_agent_config(
*,
models: list[str],
smart_routing: bool = False,
http_headers: dict[str, str] | None = None,
) -> dict:
config = {
"models": {"model_services": models},
"default_models": {"default_model": models[0]},
}
if smart_routing:
config["smart_routing"] = {"enabled": True}
if http_headers is not None:
config["http_headers"] = http_headers
return {"agent": "CODING_AGENT_CODEX", "config": config}


Expand Down
Loading