test: update and add tests for all updated subsystems
This commit is contained in:
@@ -13,6 +13,7 @@ from daemon.handlers.network import (
|
||||
get_interfaces,
|
||||
reload_interface,
|
||||
save_interface,
|
||||
set_sysctl,
|
||||
)
|
||||
from lib import network as _net
|
||||
|
||||
@@ -65,8 +66,8 @@ class TestSaveInterface:
|
||||
)
|
||||
|
||||
data_dir = tmp_network / "data" / "networkd"
|
||||
assert (data_dir / "50-eth0.network").exists()
|
||||
content = (data_dir / "50-eth0.network").read_text()
|
||||
assert (data_dir / "99-eth0.network").exists()
|
||||
content = (data_dir / "99-eth0.network").read_text()
|
||||
assert "Name=eth0" in content
|
||||
assert "Address=10.0.0.1/24" in content
|
||||
|
||||
@@ -78,6 +79,54 @@ class TestSaveInterface:
|
||||
with pytest.raises(ValueError, match="body"):
|
||||
save_interface(None, None)
|
||||
|
||||
def test_save_interface_rejects_invalid_name(self, tmp_network):
|
||||
invalid_names = [
|
||||
"../../etc/passwd",
|
||||
"eth 0",
|
||||
"",
|
||||
"eth/0",
|
||||
"eth..0",
|
||||
]
|
||||
for invalid in invalid_names:
|
||||
with (
|
||||
patch("daemon.handlers.network.run") as mock_run,
|
||||
patch(
|
||||
"daemon.handlers.network.DATA_DIR",
|
||||
tmp_network / "data" / "networkd",
|
||||
),
|
||||
):
|
||||
mock_run.return_value = (
|
||||
"1: eth0 ethernet routable\n State: routable\n"
|
||||
)
|
||||
with pytest.raises(ValueError, match="name"):
|
||||
save_interface(None, {"name": invalid})
|
||||
|
||||
|
||||
class TestReloadInterfaceValidation:
|
||||
def test_reload_interface_rejects_invalid_name(self):
|
||||
invalid_names = [
|
||||
"../../etc/passwd",
|
||||
"eth 0",
|
||||
"",
|
||||
"eth/0",
|
||||
]
|
||||
for invalid in invalid_names:
|
||||
with pytest.raises(ValueError, match="name"):
|
||||
reload_interface(None, {"name": invalid})
|
||||
|
||||
|
||||
class TestGetInterfaceValidation:
|
||||
def test_get_interface_rejects_invalid_name(self, tmp_network):
|
||||
invalid_names = [
|
||||
"../../etc/passwd",
|
||||
"eth 0",
|
||||
"",
|
||||
"eth/0",
|
||||
]
|
||||
for invalid in invalid_names:
|
||||
with pytest.raises(ValueError, match="name"):
|
||||
get_interface(None, {"name": invalid})
|
||||
|
||||
|
||||
class TestReloadInterface:
|
||||
def test_reload_interface(self):
|
||||
@@ -117,7 +166,7 @@ class TestApplyAll:
|
||||
patch("daemon.handlers.network.collect_upstream_dns", return_value=[]),
|
||||
):
|
||||
mock_gen.return_value = {
|
||||
"generated": [_net.DATA_DIR / "50-eth0.network"],
|
||||
"generated": [_net.DATA_DIR / "99-eth0.network"],
|
||||
"cleaned": [],
|
||||
}
|
||||
mock_run.return_value = ""
|
||||
@@ -146,7 +195,7 @@ class TestApplyAll:
|
||||
patch("daemon.handlers.network.collect_upstream_dns") as mock_collect,
|
||||
):
|
||||
mock_gen.return_value = {
|
||||
"generated": [_net.DATA_DIR / "50-eth0.network"],
|
||||
"generated": [_net.DATA_DIR / "99-eth0.network"],
|
||||
"cleaned": [],
|
||||
}
|
||||
mock_run.return_value = ""
|
||||
@@ -169,7 +218,7 @@ class TestApplyAll:
|
||||
patch("daemon.handlers.network.collect_upstream_dns") as mock_collect,
|
||||
):
|
||||
mock_gen.return_value = {
|
||||
"generated": [_net.DATA_DIR / "50-eth0.network"],
|
||||
"generated": [_net.DATA_DIR / "99-eth0.network"],
|
||||
"cleaned": [],
|
||||
}
|
||||
mock_run.return_value = ""
|
||||
@@ -190,7 +239,7 @@ class TestApplyAll:
|
||||
patch("daemon.handlers.network.collect_upstream_dns", return_value=[]),
|
||||
):
|
||||
mock_gen.return_value = {
|
||||
"generated": [_net.DATA_DIR / "50-eth0.network"],
|
||||
"generated": [_net.DATA_DIR / "99-eth0.network"],
|
||||
"cleaned": [],
|
||||
}
|
||||
mock_run.return_value = ""
|
||||
@@ -295,3 +344,50 @@ class TestInferEndpoints:
|
||||
assert "zones" in result
|
||||
assert result["zones"]["wg0"] == "wan"
|
||||
assert result["zones"]["eth0"] == "lan"
|
||||
|
||||
|
||||
class TestSetSysctl:
|
||||
def test_set_sysctl_success(self):
|
||||
with (
|
||||
patch("daemon.handlers.network.run") as mock_run,
|
||||
patch.object(Path, "read_text", return_value="1"),
|
||||
):
|
||||
mock_run.return_value = "" # sysctl -w call
|
||||
result = set_sysctl(None, {"name": "net.ipv4.ip_forward", "value": "1"})
|
||||
|
||||
assert result["name"] == "net.ipv4.ip_forward"
|
||||
assert result["value"] == "1"
|
||||
assert mock_run.call_count == 1
|
||||
assert mock_run.call_args_list[0].args == (
|
||||
["sysctl", "-w", "net.ipv4.ip_forward=1"],
|
||||
)
|
||||
assert mock_run.call_args_list[0].kwargs == {"sudo": True}
|
||||
|
||||
def test_set_sysctl_rejects_slash_in_name(self):
|
||||
with pytest.raises(ValueError, match="valid sysctl key"):
|
||||
set_sysctl(None, {"name": "net.ipv4/ip_forward", "value": "1"})
|
||||
|
||||
def test_set_sysctl_rejects_double_dot(self):
|
||||
with pytest.raises(ValueError, match="valid sysctl key"):
|
||||
set_sysctl(None, {"name": "net..ipv4", "value": "1"})
|
||||
|
||||
def test_set_sysctl_requires_name(self):
|
||||
with pytest.raises(ValueError, match="name"):
|
||||
set_sysctl(None, {"value": "1"})
|
||||
|
||||
def test_set_sysctl_requires_value(self):
|
||||
with pytest.raises(ValueError, match="value"):
|
||||
set_sysctl(None, {"name": "net.ipv4.ip_forward"})
|
||||
|
||||
def test_set_sysctl_requires_body(self):
|
||||
with pytest.raises(ValueError, match="body"):
|
||||
set_sysctl(None, None)
|
||||
|
||||
def test_set_sysctl_verify_failure(self):
|
||||
with (
|
||||
patch("daemon.handlers.network.run") as mock_run,
|
||||
patch.object(Path, "read_text", return_value="0"),
|
||||
):
|
||||
mock_run.return_value = "" # sysctl -w call succeeds
|
||||
with pytest.raises(RuntimeError, match="verify failed"):
|
||||
set_sysctl(None, {"name": "net.ipv4.ip_forward", "value": "1"})
|
||||
|
||||
Reference in New Issue
Block a user