148 lines
4.8 KiB
Python
148 lines
4.8 KiB
Python
"""Helper utilities for resource handler Robot smoke tests.
|
|
|
|
Each command prints a single ``<command>-ok`` token on success so the
|
|
calling Robot test can assert on ``stdout``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from datetime import datetime
|
|
from unittest.mock import MagicMock, PropertyMock
|
|
|
|
from cleveragents.domain.models.core.resource import (
|
|
PhysVirt,
|
|
Resource,
|
|
ResourceCapabilities,
|
|
)
|
|
from cleveragents.infrastructure.sandbox.factory import SandboxFactory
|
|
from cleveragents.infrastructure.sandbox.manager import SandboxManager
|
|
from cleveragents.infrastructure.sandbox.protocol import (
|
|
SandboxContext,
|
|
SandboxStatus,
|
|
)
|
|
from cleveragents.resource.handlers.fs_directory import FsDirectoryHandler
|
|
from cleveragents.resource.handlers.git_checkout import GitCheckoutHandler
|
|
from cleveragents.resource.handlers.protocol import ResourceHandler
|
|
from cleveragents.resource.handlers.resolver import (
|
|
HandlerResolutionError,
|
|
clear_handler_cache,
|
|
resolve_handler,
|
|
)
|
|
from cleveragents.tool.context import BoundResource
|
|
|
|
|
|
def _make_resource(rtype: str, location: str) -> Resource:
|
|
"""Create a test resource with a valid ULID."""
|
|
return Resource(
|
|
resource_id="01KJ5C5TPMP8GGX3QC83E2MAQS",
|
|
resource_type_name=rtype,
|
|
classification=PhysVirt.PHYSICAL,
|
|
location=location,
|
|
capabilities=ResourceCapabilities(
|
|
readable=True, writable=True, sandboxable=True
|
|
),
|
|
)
|
|
|
|
|
|
def _make_mock_manager() -> SandboxManager:
|
|
"""Create a SandboxManager with a mock factory."""
|
|
mock_factory = MagicMock(spec=SandboxFactory)
|
|
mock_sandbox = MagicMock()
|
|
mock_sandbox.sandbox_id = "sb-robot-001"
|
|
type(mock_sandbox).status = PropertyMock(return_value=SandboxStatus.CREATED)
|
|
mock_sandbox.context = SandboxContext(
|
|
sandbox_id="sb-robot-001",
|
|
sandbox_path="/tmp/sandbox/sb-robot-001",
|
|
original_path="/tmp/original",
|
|
resource_id="res-robot",
|
|
plan_id="plan-robot",
|
|
created_at=datetime.now(),
|
|
)
|
|
mock_sandbox.create.return_value = mock_sandbox.context
|
|
mock_factory.create_sandbox.return_value = mock_sandbox
|
|
return SandboxManager(factory=mock_factory, cleanup_on_exit=False)
|
|
|
|
|
|
def _protocol_check() -> None:
|
|
"""Verify both handlers satisfy the ResourceHandler protocol."""
|
|
git = GitCheckoutHandler()
|
|
fs = FsDirectoryHandler()
|
|
assert isinstance(git, ResourceHandler), "GitCheckoutHandler not a ResourceHandler"
|
|
assert isinstance(fs, ResourceHandler), "FsDirectoryHandler not a ResourceHandler"
|
|
print("protocol-check-ok")
|
|
|
|
|
|
def _git_resolve() -> None:
|
|
"""Verify GitCheckoutHandler resolves a resource."""
|
|
resource = _make_resource("git-checkout", "/tmp/test-repo")
|
|
manager = _make_mock_manager()
|
|
handler = GitCheckoutHandler()
|
|
bound = handler.resolve(
|
|
resource=resource,
|
|
plan_id="PLAN_ROBOT",
|
|
slot_name="repo",
|
|
sandbox_manager=manager,
|
|
)
|
|
assert isinstance(bound, BoundResource)
|
|
assert bound.sandbox_path, "sandbox_path empty"
|
|
assert bound.resource_type == "git-checkout"
|
|
print("git-resolve-ok")
|
|
|
|
|
|
def _fs_resolve() -> None:
|
|
"""Verify FsDirectoryHandler resolves a resource."""
|
|
resource = _make_resource("fs-directory", "/tmp/test-dir")
|
|
manager = _make_mock_manager()
|
|
handler = FsDirectoryHandler()
|
|
bound = handler.resolve(
|
|
resource=resource,
|
|
plan_id="PLAN_ROBOT",
|
|
slot_name="workdir",
|
|
sandbox_manager=manager,
|
|
)
|
|
assert isinstance(bound, BoundResource)
|
|
assert bound.sandbox_path, "sandbox_path empty"
|
|
assert bound.resource_type == "fs-directory"
|
|
print("fs-resolve-ok")
|
|
|
|
|
|
def _resolver_import() -> None:
|
|
"""Verify handler resolver loads handlers from module:class strings."""
|
|
clear_handler_cache()
|
|
git = resolve_handler(
|
|
"cleveragents.resource.handlers.git_checkout:GitCheckoutHandler"
|
|
)
|
|
assert isinstance(git, GitCheckoutHandler)
|
|
fs = resolve_handler(
|
|
"cleveragents.resource.handlers.fs_directory:FsDirectoryHandler"
|
|
)
|
|
assert isinstance(fs, FsDirectoryHandler)
|
|
print("resolver-import-ok")
|
|
|
|
|
|
def _resolver_error() -> None:
|
|
"""Verify handler resolver raises on bad references."""
|
|
clear_handler_cache()
|
|
try:
|
|
resolve_handler("nonexistent.module:FakeClass")
|
|
print("resolver-error-FAIL")
|
|
except HandlerResolutionError:
|
|
print("resolver-error-ok")
|
|
|
|
|
|
_COMMANDS = {
|
|
"protocol-check": _protocol_check,
|
|
"git-resolve": _git_resolve,
|
|
"fs-resolve": _fs_resolve,
|
|
"resolver-import": _resolver_import,
|
|
"resolver-error": _resolver_error,
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2 or sys.argv[1] not in _COMMANDS:
|
|
print(f"Usage: {sys.argv[0]} <{'|'.join(_COMMANDS)}>", file=sys.stderr)
|
|
sys.exit(1)
|
|
_COMMANDS[sys.argv[1]]()
|