fix: use repository name for workspace mount target
WORKSPACE_NAME was computed from os.path.basename(repo_path), so when a
workspace path ended in a directory like 'main', the container mount target
became /home/user/main instead of /home/user/{repo-name}.
- Use GitRepository.name for WORKSPACE_NAME/REPO_NAME in manifest and
legacy dockerfile flows
- Add unit test verifying prepare_manifest_instance uses repo.name even
when the workspace path basename differs
Quality gates:
- pytest tests/unit: 213 passed
- ruff: clean on changed files
- mypy: clean on changed files
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
"""Unit tests for the tool instance service."""
|
||||
|
||||
from unittest.mock import MagicMock, AsyncMock
|
||||
|
||||
import pytest
|
||||
|
||||
from src.services.tool.instance_service import modify_compose_file
|
||||
from src.services.tool.instance_service import modify_compose_file, prepare_manifest_instance
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@@ -42,3 +44,77 @@ class TestModifyComposeFile:
|
||||
|
||||
content = compose_path.read_text()
|
||||
assert "working_dir: /home/user/workspace" in content
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
async def test_prepare_manifest_instance_uses_repo_name_not_workspace_dir():
|
||||
"""WORKSPACE_NAME must be the repository name, not the workspace path basename."""
|
||||
repo = MagicMock()
|
||||
repo.name = "my-cool-repo"
|
||||
repo.path = "/data/repos/main"
|
||||
|
||||
tool_type = MagicMock()
|
||||
tool_type.name = "pi-agent"
|
||||
tool_type.manifest_id = "manifest-uuid"
|
||||
|
||||
manifest_def = MagicMock()
|
||||
manifest_def.id = "manifest-uuid"
|
||||
manifest_def.manifest = {
|
||||
"base_image": "ubuntu:24.04",
|
||||
"interface_type": "terminal",
|
||||
"user": {"name": "user", "uid": 1001, "gid": 1001},
|
||||
"mounts": [{"name": "workspace", "target": "~/{{WORKSPACE_NAME}}", "source_type": "repo"}],
|
||||
}
|
||||
manifest_def.base_definition_id = None
|
||||
|
||||
instance = MagicMock()
|
||||
instance.id = "instance-uuid"
|
||||
instance.name = "pi-agent-my-cool-repo-abc123"
|
||||
instance.repository_id = "repo-uuid"
|
||||
instance.tool_type_id = "tooltype-uuid"
|
||||
instance.port = 0
|
||||
instance.selected_config_profile_id = None
|
||||
instance.workspace_id = None
|
||||
|
||||
session = AsyncMock()
|
||||
|
||||
async def session_get(model, obj_id):
|
||||
if model.__name__ == "ToolType":
|
||||
return tool_type
|
||||
if model.__name__ == "ToolDefinitionManifest":
|
||||
return manifest_def
|
||||
if model.__name__ == "GitRepository":
|
||||
return repo
|
||||
return None
|
||||
|
||||
session.get.side_effect = session_get
|
||||
|
||||
# Patch docker images check to report the image already exists so we skip
|
||||
# the actual Docker build.
|
||||
import subprocess
|
||||
from src.services.tool import instance_service
|
||||
|
||||
original_run = subprocess.run
|
||||
def fake_run(cmd, **kwargs):
|
||||
class Result:
|
||||
returncode = 0
|
||||
stdout = "image-id"
|
||||
stderr = ""
|
||||
return Result()
|
||||
|
||||
instance_service.subprocess.run = fake_run
|
||||
try:
|
||||
image_tag, compose_content, manifest, home_dir = await prepare_manifest_instance(
|
||||
session=session,
|
||||
instance=instance,
|
||||
instance_dir="/tmp/instance",
|
||||
repo_path="/data/repos/main",
|
||||
env_vars={},
|
||||
extra_volumes=[],
|
||||
working_directory=None,
|
||||
)
|
||||
finally:
|
||||
instance_service.subprocess.run = original_run
|
||||
|
||||
assert "WORKSPACE_NAME: my-cool-repo" in compose_content
|
||||
assert "/data/repos/main:/home/user/my-cool-repo" in compose_content
|
||||
|
||||
Reference in New Issue
Block a user