fix: raise when an update reader cannot read, and report host status
CI / test (3.10) (push) Successful in 26s
CI / test (3.11) (push) Successful in 25s
CI / test (3.12) (push) Successful in 26s
CI / test (3.10) (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 24s
CI / test (3.12) (pull_request) Successful in 26s
CI / test (3.10) (push) Successful in 26s
CI / test (3.11) (push) Successful in 25s
CI / test (3.12) (push) Successful in 26s
CI / test (3.10) (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 24s
CI / test (3.12) (pull_request) Successful in 26s
netOrk reads an empty update list as "no updates" and closes every patch clock on the host. A refused sudo, a failing pkg, syspatch or freebsd-update, or a pkg database pkg cannot read used to come back as that empty list. Each of these now raises. Only pkg's "is not installed" still means no packages. BsdDriver takes on napalm-device-types' HostStatusMixin. On FreeBSD it reports a host whose installed kernel differs from the running one as needing a reboot (device-types 4.1). OpenBSD stays unknown. Closes #4
This commit is contained in:
+79
-1
@@ -267,6 +267,15 @@ class TestPackages:
|
||||
assert driver.get_packages() == []
|
||||
assert driver.calls == [("pkg -N", False)]
|
||||
|
||||
def test_a_pkg_that_cannot_read_its_database_raises(self):
|
||||
"""Any other failure is "could not read", never "no packages"."""
|
||||
driver = _channel(
|
||||
FreeBSDDriver,
|
||||
{"pkg -N": ("pkg: sqlite error ...: database disk image is malformed", 1)},
|
||||
)
|
||||
with pytest.raises(RuntimeError, match="malformed"):
|
||||
driver.get_packages()
|
||||
|
||||
def test_openbsd_packages(self):
|
||||
driver = _channel(OpenBSDDriver, {"pkg_info": _read("openbsd-vm", "pkg_info_full.txt")})
|
||||
assert any(p["name"] == "pcre2" for p in driver.get_packages())
|
||||
@@ -359,7 +368,7 @@ class TestAvailableUpdates:
|
||||
driver = _channel(
|
||||
FreeBSDDriver,
|
||||
{
|
||||
"pkg -N": ("", 1),
|
||||
"pkg -N": ("pkg: pkg is not installed", 1),
|
||||
("freebsd-update --not-running-from-cron updatesready", True): ("", 2),
|
||||
},
|
||||
)
|
||||
@@ -532,3 +541,72 @@ class TestSnmp:
|
||||
def test_no_agent_running_means_no_config(self):
|
||||
driver = _channel(OpenBSDDriver, {"pgrep -f /usr/local/sbin/snmpd": ("", 1)})
|
||||
assert driver.get_snmp_config() is None
|
||||
|
||||
|
||||
class TestHostStatus:
|
||||
"""napalm-device-types' host status, carried over the exec channel; on
|
||||
FreeBSD it compares the installed with the running kernel (4.1.0)."""
|
||||
|
||||
REPORT = (
|
||||
"HSTAT_BEGIN\n[kernel]\n15.1-RELEASE\n[modules]\n"
|
||||
"[freebsd-kernel]\n15.1-RELEASE-p5\n[freebsd-running]\n15.1-RELEASE-p4\n"
|
||||
"[timers]\nHSTAT_END\n"
|
||||
)
|
||||
|
||||
def test_a_patched_kernel_waits_for_a_reboot(self):
|
||||
from napalm_device_types.host_status import HOST_STATUS_COMMAND
|
||||
|
||||
driver = _channel(FreeBSDDriver, {HOST_STATUS_COMMAND: self.REPORT})
|
||||
status = driver.get_host_status()
|
||||
assert status["reboot_required"] is True
|
||||
assert driver.calls == [(HOST_STATUS_COMMAND, False)] # read-only, no root
|
||||
|
||||
@pytest.mark.parametrize("cls", [FreeBSDDriver, OpenBSDDriver])
|
||||
def test_both_have_it(self, cls):
|
||||
assert callable(getattr(cls, "get_host_status", None))
|
||||
|
||||
|
||||
class TestAFailedReadRaises:
|
||||
"""A reader that could not read raises; [] would tell netOrk "no updates"
|
||||
and close every patch clock on the host (napalm-bsd#4)."""
|
||||
|
||||
def test_freebsd_without_root(self):
|
||||
driver = _channel(
|
||||
FreeBSDDriver,
|
||||
{"pkg -N": "", ("pkg upgrade -n", True): ("", 1)},
|
||||
)
|
||||
with pytest.raises(RuntimeError, match="pkg upgrade -n"):
|
||||
driver.get_available_updates()
|
||||
|
||||
def test_a_failed_audit_leaves_security_unknown(self):
|
||||
"""pkg audit exits 1 for "vulnerable packages found" and for errors alike;
|
||||
only a list of packages makes the 1 a verdict."""
|
||||
driver = _channel(
|
||||
FreeBSDDriver,
|
||||
{
|
||||
"pkg -N": "",
|
||||
("pkg upgrade -n", True): _read("freebsd-vm", "sudo_pkg_upgrade_n_latest.txt"),
|
||||
("pkg audit -Fq", True): ("", 1),
|
||||
"pkg repos -l": "FreeBSD-ports\nFreeBSD-base\n",
|
||||
},
|
||||
)
|
||||
assert {u["security"] for u in driver.get_available_updates()} == {None}
|
||||
|
||||
def test_classic_freebsd_update_error(self):
|
||||
driver = _channel(
|
||||
FreeBSDDriver,
|
||||
{
|
||||
"pkg -N": ("pkg: pkg is not installed", 1),
|
||||
("freebsd-update --not-running-from-cron updatesready", True): ("", 1),
|
||||
},
|
||||
)
|
||||
with pytest.raises(RuntimeError, match="freebsd-update"):
|
||||
driver.get_available_updates()
|
||||
|
||||
@pytest.mark.parametrize("failing", ["pkg_add -u -n -v", "syspatch -c"])
|
||||
def test_openbsd_without_root(self, failing):
|
||||
answers = {("pkg_add -u -n -v", True): "", ("syspatch -c", True): ""}
|
||||
answers[(failing, True)] = ("", 1)
|
||||
driver = _channel(OpenBSDDriver, answers)
|
||||
with pytest.raises(RuntimeError, match=failing.split()[0]):
|
||||
driver.get_available_updates()
|
||||
|
||||
Reference in New Issue
Block a user