generated from coulomb/repo-seed
Implement SAND-WP-0005: extension SDK and ext.vm-packer
Add SandboxExtension base class, extension SDK docs, vm-packer attach mode for build-machines VMs, profile.vm-haskell-build, SSH port support, tests, and migration docs.
This commit is contained in:
16
tests/test_extension_base.py
Normal file
16
tests/test_extension_base.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""Extension SDK base class tests."""
|
||||
|
||||
from sandboxer.extensions.base import SandboxExtension
|
||||
from sandboxer.extensions.compose_ssh import ComposeSSHExtension
|
||||
from sandboxer.extensions.vm_packer import VMPackerExtension
|
||||
|
||||
|
||||
def test_reference_extensions_subclass_base() -> None:
|
||||
assert issubclass(ComposeSSHExtension, SandboxExtension)
|
||||
assert issubclass(VMPackerExtension, SandboxExtension)
|
||||
|
||||
|
||||
def test_new_sandbox_id_from_inputs() -> None:
|
||||
assert SandboxExtension.new_sandbox_id({"sandbox_id": "fixed123"}) == "fixed123"
|
||||
generated = SandboxExtension.new_sandbox_id({})
|
||||
assert len(generated) == 8
|
||||
15
tests/test_extension_registry.py
Normal file
15
tests/test_extension_registry.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""Extension registry loads vm-packer."""
|
||||
|
||||
from sandboxer.extensions.registry import load_all_extensions, load_extension
|
||||
|
||||
|
||||
def test_load_vm_packer_extension() -> None:
|
||||
ext = load_extension("ext.vm-packer")
|
||||
assert ext.id == "ext.vm-packer"
|
||||
assert "vm_packer" in ext.handler
|
||||
|
||||
|
||||
def test_load_all_includes_vm_packer() -> None:
|
||||
extensions = load_all_extensions()
|
||||
assert "ext.compose-ssh" in extensions
|
||||
assert "ext.vm-packer" in extensions
|
||||
@@ -10,4 +10,10 @@ def test_destination_uses_ssh_config_when_user_unset() -> None:
|
||||
|
||||
def test_destination_includes_explicit_user() -> None:
|
||||
ssh = SSHConfig(host="92.205.130.254", user="tegwick")
|
||||
assert ssh.destination == "tegwick@92.205.130.254"
|
||||
assert ssh.destination == "tegwick@92.205.130.254"
|
||||
|
||||
|
||||
def test_ssh_base_includes_port() -> None:
|
||||
ssh = SSHConfig(host="localhost", user="build", port=12222)
|
||||
assert "-p" in ssh.ssh_base()
|
||||
assert "12222" in ssh.ssh_base()
|
||||
76
tests/test_vm_packer.py
Normal file
76
tests/test_vm_packer.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""VMPackerExtension unit tests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from sandboxer.extensions.vm_packer import VMPackerExtension
|
||||
from sandboxer.models import Profile
|
||||
|
||||
|
||||
def _profile() -> Profile:
|
||||
return Profile.model_validate(
|
||||
{
|
||||
"id": "profile.vm-haskell-build",
|
||||
"version": "1.0.0",
|
||||
"extension": "ext.vm-packer",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_provision_attach_via_alias(tmp_path: Path) -> None:
|
||||
repo = tmp_path / "proj"
|
||||
repo.mkdir()
|
||||
ext = VMPackerExtension()
|
||||
|
||||
with (
|
||||
patch("sandboxer.extensions.vm_packer.SSHConfig.run", return_value=(0, "")),
|
||||
patch("sandboxer.extensions.vm_packer.SSHConfig.rsync") as rsync,
|
||||
):
|
||||
handle = ext.provision(
|
||||
_profile(),
|
||||
{"vm": "haskell-build", "repo": str(repo)},
|
||||
"localhost",
|
||||
)
|
||||
|
||||
assert handle["vm_target"] == "haskell-build"
|
||||
assert handle["remote_dir"].startswith("/build/sbx-")
|
||||
rsync.assert_called_once()
|
||||
|
||||
|
||||
def test_provision_requires_vm_input() -> None:
|
||||
ext = VMPackerExtension()
|
||||
with pytest.raises(ValueError, match="inputs.vm"):
|
||||
ext.provision(_profile(), {}, "localhost")
|
||||
|
||||
|
||||
def test_wait_ready_success() -> None:
|
||||
ext = VMPackerExtension()
|
||||
handle = {
|
||||
"vm_host": "haskell-build",
|
||||
"remote_dir": "/build/sbx-abc12345",
|
||||
"host": "localhost",
|
||||
"ssh_user": "build",
|
||||
"ssh_port": "",
|
||||
}
|
||||
with patch("sandboxer.extensions.vm_packer.SSHConfig.run", return_value=(0, "ready\n")):
|
||||
reach = ext.wait_ready(handle)
|
||||
assert reach["remote_dir"] == "/build/sbx-abc12345"
|
||||
assert "haskell-build" in (reach["ssh"] or "")
|
||||
|
||||
|
||||
def test_teardown_preserves_vm() -> None:
|
||||
ext = VMPackerExtension()
|
||||
handle = {
|
||||
"vm_host": "localhost",
|
||||
"remote_dir": "/build/sbx-deadbeef",
|
||||
"ssh_user": "build",
|
||||
"ssh_port": "12222",
|
||||
}
|
||||
with patch("sandboxer.extensions.vm_packer.SSHConfig.run", return_value=(0, "")):
|
||||
report = ext.teardown(handle)
|
||||
assert report["vm_preserved"] == "true"
|
||||
assert report["workspace_removed"] == "True"
|
||||
Reference in New Issue
Block a user