fix: persist workspace Python environments

This commit is contained in:
wuyang
2026-07-26 20:20:37 +08:00
parent bc30a480ad
commit 2fbb5698ac
14 changed files with 170 additions and 20 deletions
+7 -1
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
import pytest
from fastapi import HTTPException
from agent_platform.auth import decode_openwebui_identity, verify_service_bearer
from agent_platform.auth import UserIdentity, decode_openwebui_identity, issue_internal_identity, verify_service_bearer
def test_signed_identity_is_verified(identity_jwt: str, settings) -> None:
@@ -18,6 +18,12 @@ def test_invalid_identity_is_rejected(settings) -> None:
assert error.value.status_code == 401
def test_internal_identity_can_be_reissued_from_verified_claims(settings) -> None:
expected = UserIdentity("user-123", "user@example.test", "Test User", "user")
token = issue_internal_identity(expected, settings.openwebui_forward_jwt_secret)
assert decode_openwebui_identity(token, settings.openwebui_forward_jwt_secret) == expected
def test_service_bearer_uses_exact_match() -> None:
verify_service_bearer("Bearer expected", "expected")
with pytest.raises(HTTPException) as error:
+36
View File
@@ -36,6 +36,31 @@ async def test_real_docker_workspaces_are_isolated(settings) -> None:
escaped = await provider.exec(users[0], "test ! -e /var/run/docker.sock", ".", 10)
assert escaped.ok
environment = await provider.exec(
users[0],
'test "$HOME" = /workspace/.agent/home'
' && test "$PYTHONUSERBASE" = /workspace/.agent/home/.local'
' && case "$PATH" in /workspace/.venv/bin:*) exit 0;; *) exit 1;; esac',
".",
10,
)
assert environment.ok, environment.output
virtualenv = await provider.exec(
users[0],
"python3 -m venv .venv && .venv/bin/python -m pip --version",
".",
30,
)
assert virtualenv.ok, virtualenv.output
assert "/workspace/.venv/" in virtualenv.output
hidden = await provider.list_files(users[0], ".", 4, 100)
assert ".agent" not in hidden.output
assert ".venv" not in hidden.output
piped_failure = await provider.exec(users[0], "false | tail -n 1", ".", 10)
assert not piped_failure.ok
assert piped_failure.exit_code == 1
git_init = "git init -q && git config user.email test@example.invalid && git config user.name Integration"
assert (await provider.exec(users[0], git_init, ".", 10)).ok
assert (await provider.write_file(users[0], "tracked.txt", "before\n")).ok
@@ -64,6 +89,17 @@ async def test_real_docker_workspaces_are_isolated(settings) -> None:
assert polled.exit_code == 0
assert "background-done" in polled.output
failed = await provider.start_process(users[0], "false | tail -n 1", ".")
failed_process_id = failed.metadata["process_id"]
failed_poll = await provider.poll_process(users[0], failed_process_id)
for _ in range(20):
if not failed_poll.metadata.get("running"):
break
await asyncio.sleep(0.1)
failed_poll = await provider.poll_process(users[0], failed_process_id)
assert not failed_poll.ok
assert failed_poll.exit_code == 1
container = client.containers.get(workspace_ref(users[0]).container_name)
container.reload()
second_container = client.containers.get(workspace_ref(users[1]).container_name)
+31
View File
@@ -0,0 +1,31 @@
from __future__ import annotations
from typing import cast
import httpx
from agent_platform.auth import UserIdentity, decode_openwebui_identity
from agent_platform.runtime.tools import ToolContext, ToolRegistry
from agent_platform.store import RuntimeStore
async def test_gateway_call_uses_a_fresh_identity_token(settings) -> None:
captured: dict[str, str] = {}
async def handle(request: httpx.Request) -> httpx.Response:
captured["authorization"] = request.headers["Authorization"]
captured["identity"] = request.headers["X-OpenWebUI-User-Jwt"]
return httpx.Response(200, json={"ok": True, "output": "ready"})
identity = UserIdentity("user-123", "user@example.test", "Test User", "user")
async with httpx.AsyncClient(transport=httpx.MockTransport(handle)) as client:
registry = ToolRegistry(settings, cast(RuntimeStore, None), client=client)
result = await registry.execute(
"workspace_status",
{},
ToolContext(identity=identity, chat_id="chat-123"),
)
assert result["ok"] is True
assert captured["authorization"] == f"Bearer {settings.internal_gateway_key}"
assert decode_openwebui_identity(captured["identity"], settings.openwebui_forward_jwt_secret) == identity