- tests/: 55 тестов web-панели, авторизации, сети и обновлений, все страницы рендерятся на замоканных virsh/systemctl; - GitHub Actions: pyflakes + pytest на Python 3.11–3.13, shellcheck, сборка ISO amd64/arm64 по тегу v* или вручную; - Makefile: make check / make test / make iso; - docs/IMAGE.md и README: установка с ISO, продакшен-настройки, разработка; - updates/versions.json: описание версии 0.10.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
68 строки
2.8 KiB
Python
68 строки
2.8 KiB
Python
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
import network_core
|
|
import restore_network
|
|
import update_core
|
|
|
|
|
|
def test_parse_port_range():
|
|
assert network_core.parse_port_range("80") == (80, 80)
|
|
assert network_core.parse_port_range("10000-10010") == (10000, 10010)
|
|
assert network_core.parse_port_range("10000:10010") == (10000, 10010)
|
|
for bad in ("", "0", "70000", "20-10", "abc", "80;rm"):
|
|
with pytest.raises(network_core.NetworkError):
|
|
network_core.parse_port_range(bad)
|
|
|
|
|
|
def test_add_port_forward_rejects_overlap(data_dirs):
|
|
network_core.add_port_forward("web01", "192.168.100.51", "8000-8010", "8000-8010", "tcp")
|
|
with pytest.raises(network_core.NetworkError):
|
|
network_core.add_port_forward("web01", "192.168.100.52", "8005", "80", "tcp")
|
|
network_core.add_port_forward("web01", "192.168.100.52", "8005", "80", "udp")
|
|
|
|
|
|
def test_add_port_forward_rejects_mismatched_ranges(data_dirs):
|
|
with pytest.raises(network_core.NetworkError):
|
|
network_core.add_port_forward("web01", "192.168.100.51", "8000-8010", "80", "tcp")
|
|
|
|
|
|
def test_render_nft_rules_range(data_dirs):
|
|
network_core.add_port_forward("web01", "192.168.100.51", "10000-10002", "20000-20002", "udp")
|
|
rules = network_core.render_nft_rules()
|
|
assert 'iifname "eth0" udp dport 10000-10002 dnat to 192.168.100.51:20000-20002' in rules
|
|
assert "masquerade" in rules
|
|
|
|
|
|
def test_restore_network_noop_without_config(data_dirs, capsys):
|
|
assert restore_network.main() == 0
|
|
assert "nothing to restore" in capsys.readouterr().out
|
|
|
|
|
|
def test_restore_network_applies_rules(data_dirs):
|
|
data_dirs["network"].joinpath("port_forwards.json").write_text(json.dumps([
|
|
{"id": "1", "vm_name": "web01", "guest_ip": "192.168.100.51", "external_port_start": 2222, "external_port_end": 2222, "guest_port_start": 22, "guest_port_end": 22, "protocol": "tcp"},
|
|
]))
|
|
assert restore_network.main() == 0
|
|
assert "dport 2222 dnat to 192.168.100.51:22" in (data_dirs["nft"] / "virtuality.nft").read_text()
|
|
|
|
|
|
def test_version_tuple_ordering():
|
|
assert update_core.version_tuple("0.9.6") < update_core.version_tuple("0.10.0")
|
|
assert update_core.version_tuple("v1.0") == update_core.version_tuple("1.0.0")
|
|
|
|
|
|
def test_missing_versions():
|
|
manifest = {"versions": [{"version": v} for v in ("0.9.5", "0.9.6", "0.10.0", "0.10.1")]}
|
|
missed = update_core.missing_versions("0.9.6", "0.10.1", manifest)
|
|
assert [item["version"] for item in missed] == ["0.10.0", "0.10.1"]
|
|
|
|
|
|
def test_versions_manifest_matches_version_file():
|
|
root = Path(__file__).resolve().parents[1]
|
|
version = (root / "VERSION").read_text().strip()
|
|
manifest = json.loads((root / "updates" / "versions.json").read_text())
|
|
assert version in [item["version"] for item in manifest["versions"]]
|