mirror of
https://github.com/Katakate/k7.git
synced 2026-09-21 09:33:19 +00:00
13fafe0997
Per-key node pins, k7d-fc pause/resume/exec, and HA-soak fixes. Playbook pins k7d 0.7.0. GitHub .deb, Launchpad PPA, and PyPI k7-sdk are 0.4.0.
123 lines
4.0 KiB
Python
123 lines
4.0 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
import yaml
|
|
|
|
from k7.core.models import ExecResult, OperationResult, SandboxConfig, SandboxInfo
|
|
|
|
|
|
class TestSandboxConfigFromDict:
|
|
def test_minimal_fields(self):
|
|
cfg = SandboxConfig.from_dict({"name": "test", "image": "alpine:latest"})
|
|
assert cfg.name == "test"
|
|
assert cfg.image == "alpine:latest"
|
|
assert cfg.namespace == "default"
|
|
assert cfg.limits == {}
|
|
|
|
def test_all_fields(self):
|
|
data = {
|
|
"name": "full",
|
|
"image": "ubuntu:22.04",
|
|
"namespace": "prod",
|
|
"runtime_class_name": "kata-qemu",
|
|
"root_disk_size": "20Gi",
|
|
"backend": "kata-qemu-longhorn",
|
|
"env_file": ".env",
|
|
"egress_whitelist": ["10.0.0.0/8"],
|
|
"limits": {"cpu": "2", "memory": "4Gi"},
|
|
"before_script": "apt update",
|
|
"entrypoint": ["/bin/sh"],
|
|
"cmd": ["-c", "echo hi"],
|
|
"pod_non_root": True,
|
|
"container_non_root": True,
|
|
"cap_drop": ["ALL"],
|
|
"cap_add": ["NET_ADMIN"],
|
|
"node_name": "k7-node-01",
|
|
}
|
|
cfg = SandboxConfig.from_dict(data)
|
|
assert cfg.backend == "kata-qemu-longhorn"
|
|
assert cfg.egress_whitelist == ["10.0.0.0/8"]
|
|
assert cfg.limits == {"cpu": "2", "memory": "4Gi"}
|
|
assert cfg.pod_non_root is True
|
|
assert cfg.cap_add == ["NET_ADMIN"]
|
|
assert cfg.node_name == "k7-node-01"
|
|
|
|
def test_ignores_unknown_keys(self):
|
|
cfg = SandboxConfig.from_dict({"name": "x", "image": "img", "unknown_field": 42, "another": "val"})
|
|
assert cfg.name == "x"
|
|
assert not hasattr(cfg, "unknown_field")
|
|
|
|
def test_none_input(self):
|
|
with pytest.raises(TypeError):
|
|
SandboxConfig.from_dict(None)
|
|
|
|
def test_limits_default_to_empty_dict(self):
|
|
cfg = SandboxConfig(name="t", image="i", limits=None)
|
|
assert cfg.limits == {}
|
|
|
|
|
|
class TestSandboxConfigFromYaml:
|
|
def test_round_trip_via_file(self, tmp_path: Path):
|
|
data = {"name": "yaml-test", "image": "alpine:latest", "namespace": "ci"}
|
|
yaml_file = tmp_path / "sandbox.yaml"
|
|
yaml_file.write_text(yaml.dump(data))
|
|
|
|
cfg = SandboxConfig.from_yaml(str(yaml_file))
|
|
assert cfg.name == "yaml-test"
|
|
assert cfg.namespace == "ci"
|
|
|
|
def test_missing_file(self):
|
|
with pytest.raises(FileNotFoundError):
|
|
SandboxConfig.from_yaml("/nonexistent/path.yaml")
|
|
|
|
|
|
class TestSandboxConfigToDict:
|
|
def test_round_trip(self):
|
|
original = SandboxConfig(
|
|
name="rt",
|
|
image="img",
|
|
namespace="ns",
|
|
limits={"cpu": "1"},
|
|
before_script="echo hi",
|
|
)
|
|
d = original.to_dict()
|
|
assert d["name"] == "rt"
|
|
assert d["limits"] == {"cpu": "1"}
|
|
assert isinstance(d, dict)
|
|
|
|
def test_from_dict_to_dict_preserves_data(self):
|
|
data = {"name": "a", "image": "b", "limits": {"memory": "2Gi"}}
|
|
cfg = SandboxConfig.from_dict(data)
|
|
result = cfg.to_dict()
|
|
assert result["name"] == "a"
|
|
assert result["limits"] == {"memory": "2Gi"}
|
|
|
|
|
|
class TestOtherModels:
|
|
def test_sandbox_info_to_dict(self):
|
|
info = SandboxInfo(
|
|
name="s1",
|
|
namespace="default",
|
|
status="Running",
|
|
ready="1/1",
|
|
restarts=0,
|
|
age="5m",
|
|
image="alpine",
|
|
backend="kata-firecracker-devmapper",
|
|
)
|
|
d = info.to_dict()
|
|
assert d["name"] == "s1"
|
|
assert d["backend"] == "kata-firecracker-devmapper"
|
|
|
|
def test_exec_result_to_dict(self):
|
|
r = ExecResult(exit_code=0, stdout="hello", stderr="", duration_ms=123)
|
|
d = r.to_dict()
|
|
assert d["exit_code"] == 0
|
|
assert d["stdout"] == "hello"
|
|
|
|
def test_operation_result_to_dict(self):
|
|
r = OperationResult(success=True, message="done", data={"key": "val"})
|
|
d = r.to_dict()
|
|
assert d["success"] is True
|
|
assert d["data"] == {"key": "val"}
|