style: ruff format and the lint rules of the driver standard

Mechanical: ruff format, and ruff check --fix with the rule set every NAPALM
driver uses (E, F, I, UP, B at line length 100, Python 3.10). What ruff
cannot fix comes in the next commit.
This commit is contained in:
Christian Manivong committed 2026-10-22 19:09:42 +02:00
1 parent 0ba5081824
commit 38391891ec
8 files changed
+593 -360

No files matched your search

+5 -5
View File
@@ -58,11 +58,11 @@ with Driver(
# OS-specific methods (from napalm-device-types OSDriver) # OS-specific methods (from napalm-device-types OSDriver)
packages = dev.get_packages() packages = dev.get_packages()
updates = dev.get_pending_updates() updates = dev.get_pending_updates()
services = dev.get_services() services = dev.get_services()
users = dev.get_os_users() users = dev.get_os_users()
procs = dev.get_processes() procs = dev.get_processes()
jobs = dev.get_cron_jobs() jobs = dev.get_cron_jobs()
# Upgrade specific packages # Upgrade specific packages
result = dev.apply_updates(["openssh-server", "curl"]) result = dev.apply_updates(["openssh-server", "curl"])
@@ -121,7 +121,7 @@ apt → dnf → yum → apk → pacman
Force a specific package manager: Force a specific package manager:
```python ```python
optional_args={"pkg_manager": "dnf"} optional_args = {"pkg_manager": "dnf"}
``` ```
## SSH user permissions ## SSH user permissions
+376 -272
View File
File diff suppressed because it is too large. Load diff
+8 -1
View File
@@ -63,4 +63,11 @@ include = ["napalm_linux*"]
[tool.ruff] [tool.ruff]
line-length = 100 line-length = 100
target-version = "py39" target-version = "py310"
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B"]
[tool.ruff.lint.per-file-ignores]
# Recorded device output keeps its lines.
"tests/**" = ["E501"]
+3 -1
View File
@@ -70,7 +70,9 @@ class FakeTransport:
def _driver(*, root=False, sudo_password=None): def _driver(*, root=False, sudo_password=None):
driver = LinuxDriver("h", "u", "p", optional_args={"sudo_password": sudo_password}) driver = LinuxDriver("h", "u", "p", optional_args={"sudo_password": sudo_password})
transport = FakeTransport() transport = FakeTransport()
driver._device = SimpleNamespace(remote_conn_pre=SimpleNamespace(get_transport=lambda: transport)) driver._device = SimpleNamespace(
remote_conn_pre=SimpleNamespace(get_transport=lambda: transport)
)
driver._root = root driver._root = root
return driver, transport return driver, transport
+3 -1
View File
@@ -203,7 +203,9 @@ class TestManagementPeer:
return d return d
def test_the_client_side_of_ssh_connection(self): def test_the_client_side_of_ssh_connection(self):
assert self._driver("10.7.224.20 51234 10.0.0.5 22\n").get_management_peer() == "10.7.224.20" assert (
self._driver("10.7.224.20 51234 10.0.0.5 22\n").get_management_peer() == "10.7.224.20"
)
def test_an_ipv6_client(self): def test_an_ipv6_client(self):
assert self._driver("fd00::20 51234 fd00::5 22\n").get_management_peer() == "fd00::20" assert self._driver("fd00::20 51234 fd00::5 22\n").get_management_peer() == "fd00::20"
+194 -78
View File
@@ -1,9 +1,10 @@
"""Unit tests for LinuxDriver – parsing helpers (no real SSH connection needed).""" """Unit tests for LinuxDriver – parsing helpers (no real SSH connection needed)."""
import re import re
from unittest.mock import MagicMock, patch
import pytest import pytest
from unittest.mock import MagicMock, patch
from napalm_linux.linux import ( from napalm_linux.linux import (
_YUM_SECURITY_COMMAND, _YUM_SECURITY_COMMAND,
LinuxDriver, LinuxDriver,
@@ -11,7 +12,6 @@ from napalm_linux.linux import (
_split_status, _split_status,
) )
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Fixture – driver without a real connection # Fixture – driver without a real connection
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -327,11 +327,7 @@ PASSWD_OUT = (
"daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\n" "daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\n"
) )
GROUP_OUT = ( GROUP_OUT = "sudo:x:27:admin\ndocker:x:999:admin\nadm:x:4:admin\n"
"sudo:x:27:admin\n"
"docker:x:999:admin\n"
"adm:x:4:admin\n"
)
def test_get_os_users(driver): def test_get_os_users(driver):
@@ -477,8 +473,7 @@ DNF_UPGRADE_SUCCESS = (
) )
DNF_UPGRADE_ERROR = ( DNF_UPGRADE_ERROR = (
"Last metadata expiration check: 0:01:23 ago.\n" "Last metadata expiration check: 0:01:23 ago.\nError: No match for argument: nonexistent-pkg\n"
"Error: No match for argument: nonexistent-pkg\n"
) )
@@ -532,6 +527,7 @@ def test_type_label_is_linux():
def test_type_label_overrides_os_driver(): def test_type_label_overrides_os_driver():
from napalm_device_types import OSDriver from napalm_device_types import OSDriver
assert OSDriver.TYPE_LABEL == "OS" assert OSDriver.TYPE_LABEL == "OS"
assert LinuxDriver.TYPE_LABEL != OSDriver.TYPE_LABEL assert LinuxDriver.TYPE_LABEL != OSDriver.TYPE_LABEL
@@ -555,18 +551,31 @@ def _dmi_output(
# Mirrors the real shell output: DMIBEGIN sentinel followed by 9 fields. # Mirrors the real shell output: DMIBEGIN sentinel followed by 9 fields.
# The sentinel prevents _send()'s .strip() from eating leading blank lines # The sentinel prevents _send()'s .strip() from eating leading blank lines
# (which occur on ARM where all DMI files are absent). # (which occur on ARM where all DMI files are absent).
return "\n".join([ return "\n".join(
"DMIBEGIN", [
sys_vendor, product_name, product_version, product_serial, "DMIBEGIN",
product_uuid, detect_virt, dt_model, cpuinfo_serial, cpuinfo_model, sys_vendor,
]) product_name,
product_version,
product_serial,
product_uuid,
detect_virt,
dt_model,
cpuinfo_serial,
cpuinfo_model,
]
)
class TestCollectPlatformInfo: class TestCollectPlatformInfo:
def test_baremetal_dell(self, driver): def test_baremetal_dell(self, driver):
raw = _dmi_output( raw = _dmi_output(
"Dell Inc.", "PowerEdge R720", "Not Specified", "ABC123", "Dell Inc.",
"8a2e3f00-dead-beef-0000-123456789abc", "none", "PowerEdge R720",
"Not Specified",
"ABC123",
"8a2e3f00-dead-beef-0000-123456789abc",
"none",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -577,8 +586,12 @@ class TestCollectPlatformInfo:
def test_baremetal_lenovo_product_version_preferred(self, driver): def test_baremetal_lenovo_product_version_preferred(self, driver):
raw = _dmi_output( raw = _dmi_output(
"LENOVO", "10M8000VUS", "ThinkCentre M910x", "MP1234", "LENOVO",
"8a2e3f00-dead-beef-0000-123456789abc", "none", "10M8000VUS",
"ThinkCentre M910x",
"MP1234",
"8a2e3f00-dead-beef-0000-123456789abc",
"none",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -589,8 +602,12 @@ class TestCollectPlatformInfo:
def test_vm_kvm(self, driver): def test_vm_kvm(self, driver):
raw = _dmi_output( raw = _dmi_output(
"QEMU", "Standard PC (i440FX + PIIX, 1996)", "pc-i440fx-9.1", "", "QEMU",
"4c4c4544-0000-2010-8020-b4c04f534a31", "kvm", "Standard PC (i440FX + PIIX, 1996)",
"pc-i440fx-9.1",
"",
"4c4c4544-0000-2010-8020-b4c04f534a31",
"kvm",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -601,8 +618,12 @@ class TestCollectPlatformInfo:
def test_vm_vmware(self, driver): def test_vm_vmware(self, driver):
raw = _dmi_output( raw = _dmi_output(
"VMware, Inc.", "VMware Virtual Platform", "None", "VMware-42 12 34 56", "VMware, Inc.",
"4244560c-dead-beef-0000-abcdef123456", "vmware", "VMware Virtual Platform",
"None",
"VMware-42 12 34 56",
"4244560c-dead-beef-0000-abcdef123456",
"vmware",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -613,8 +634,12 @@ class TestCollectPlatformInfo:
def test_vm_hyperv(self, driver): def test_vm_hyperv(self, driver):
raw = _dmi_output( raw = _dmi_output(
"Microsoft Corporation", "Virtual Machine", "Hyper-V UEFI Release v4.1", "", "Microsoft Corporation",
"7C5B4B1F-1234-5678-ABCD-000000000001", "microsoft", "Virtual Machine",
"Hyper-V UEFI Release v4.1",
"",
"7C5B4B1F-1234-5678-ABCD-000000000001",
"microsoft",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -625,8 +650,12 @@ class TestCollectPlatformInfo:
def test_junk_dmi_values_filtered(self, driver): def test_junk_dmi_values_filtered(self, driver):
raw = _dmi_output( raw = _dmi_output(
"To Be Filled By O.E.M.", "To Be Filled By O.E.M.", "Not Specified", "To Be Filled By O.E.M.",
"To Be Filled By O.E.M.", "", "none", "To Be Filled By O.E.M.",
"Not Specified",
"To Be Filled By O.E.M.",
"",
"none",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -637,8 +666,12 @@ class TestCollectPlatformInfo:
def test_vm_kvm_fallback_via_dmi_when_detect_virt_unavailable(self, driver): def test_vm_kvm_fallback_via_dmi_when_detect_virt_unavailable(self, driver):
# systemd-detect-virt returns "none" (not installed), sys_vendor reveals QEMU # systemd-detect-virt returns "none" (not installed), sys_vendor reveals QEMU
raw = _dmi_output( raw = _dmi_output(
"QEMU", "Standard PC (i440FX + PIIX, 1996)", "", "", "QEMU",
"4c4c4544-0000-2010-8020-b4c04f534a31", "none", "Standard PC (i440FX + PIIX, 1996)",
"",
"",
"4c4c4544-0000-2010-8020-b4c04f534a31",
"none",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -648,8 +681,12 @@ class TestCollectPlatformInfo:
def test_container_docker(self, driver): def test_container_docker(self, driver):
raw = _dmi_output( raw = _dmi_output(
"QEMU", "Standard PC (i440FX + PIIX, 1996)", "", "", "QEMU",
"4c4c4544-0000-2010-8020-b4c04f534a31", "docker", "Standard PC (i440FX + PIIX, 1996)",
"",
"",
"4c4c4544-0000-2010-8020-b4c04f534a31",
"docker",
) )
with patch.object(driver, "_send", return_value=raw): with patch.object(driver, "_send", return_value=raw):
info = driver._collect_platform_info() info = driver._collect_platform_info()
@@ -674,7 +711,12 @@ class TestCollectPlatformInfo:
def test_arm_device_tree_fallback(self, driver): def test_arm_device_tree_fallback(self, driver):
raw = _dmi_output( raw = _dmi_output(
"", "", "", "", "", "none", "",
"",
"",
"",
"",
"none",
dt_model="Raspberry Pi 4 Model B Rev 1.4", dt_model="Raspberry Pi 4 Model B Rev 1.4",
cpuinfo_serial="100000002a6d96dc", cpuinfo_serial="100000002a6d96dc",
cpuinfo_model="Raspberry Pi 4 Model B Rev 1.4", cpuinfo_model="Raspberry Pi 4 Model B Rev 1.4",
@@ -688,7 +730,12 @@ class TestCollectPlatformInfo:
def test_arm_cpuinfo_model_when_no_dt(self, driver): def test_arm_cpuinfo_model_when_no_dt(self, driver):
raw = _dmi_output( raw = _dmi_output(
"", "", "", "", "", "none", "",
"",
"",
"",
"",
"none",
dt_model="", dt_model="",
cpuinfo_serial="0000000012345678", cpuinfo_serial="0000000012345678",
cpuinfo_model="Raspberry Pi 3 Model B Plus Rev 1.3", cpuinfo_model="Raspberry Pi 3 Model B Plus Rev 1.3",
@@ -713,7 +760,12 @@ class TestCollectPlatformInfo:
# d="none\nnone" which shifted subsequent lines off by one. # d="none\nnone" which shifted subsequent lines off by one.
# With the ${d:-none} fix this no longer happens. # With the ${d:-none} fix this no longer happens.
raw = _dmi_output( raw = _dmi_output(
"", "", "", "", "", "none", "",
"",
"",
"",
"",
"none",
dt_model="", dt_model="",
cpuinfo_serial="0000000012345678", cpuinfo_serial="0000000012345678",
cpuinfo_model="Raspberry Pi 3 Model B Rev 1.2", cpuinfo_model="Raspberry Pi 3 Model B Rev 1.2",
@@ -726,8 +778,12 @@ class TestCollectPlatformInfo:
def test_arm_fallback_ignored_when_dmi_present(self, driver): def test_arm_fallback_ignored_when_dmi_present(self, driver):
raw = _dmi_output( raw = _dmi_output(
"Dell Inc.", "PowerEdge R720", "Not Specified", "XYZ999", "Dell Inc.",
"8a2e3f00-dead-beef-0000-123456789abc", "none", "PowerEdge R720",
"Not Specified",
"XYZ999",
"8a2e3f00-dead-beef-0000-123456789abc",
"none",
dt_model="some-dt-model", dt_model="some-dt-model",
cpuinfo_serial="deadbeef", cpuinfo_serial="deadbeef",
cpuinfo_model="some cpuinfo model", cpuinfo_model="some cpuinfo model",
@@ -744,20 +800,23 @@ class TestCollectPlatformInfo:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@pytest.mark.parametrize("model,expected", [ @pytest.mark.parametrize(
("Raspberry Pi 4 Model B Rev 1.4", "Raspberry Pi Foundation"), "model,expected",
("Raspberry Pi 3 Model B Rev 1.2", "Raspberry Pi Foundation"), [
("ODROID-N2L", "Hardkernel"), ("Raspberry Pi 4 Model B Rev 1.4", "Raspberry Pi Foundation"),
("NVIDIA Jetson Nano Developer Kit", "NVIDIA"), ("Raspberry Pi 3 Model B Rev 1.2", "Raspberry Pi Foundation"),
("Rock Pi 4C", "Radxa"), ("ODROID-N2L", "Hardkernel"),
("Orange Pi 5 Plus", "Xunlong Software"), ("NVIDIA Jetson Nano Developer Kit", "NVIDIA"),
("Banana Pi BPI-R3", "SinoVoip"), ("Rock Pi 4C", "Radxa"),
("NanoPi R4S", "FriendlyElec"), ("Orange Pi 5 Plus", "Xunlong Software"),
("PINE64 RockPro64", "Pine64"), ("Banana Pi BPI-R3", "SinoVoip"),
("BeagleBone Black", "BeagleBoard.org"), ("NanoPi R4S", "FriendlyElec"),
("Unknown Board 1.0", "Unknown Board"), ("PINE64 RockPro64", "Pine64"),
("SomeSingleWordBoard", "SomeSingleWordBoard"), ("BeagleBone Black", "BeagleBoard.org"),
]) ("Unknown Board 1.0", "Unknown Board"),
("SomeSingleWordBoard", "SomeSingleWordBoard"),
],
)
def test_arm_vendor_from_model(model, expected): def test_arm_vendor_from_model(model, expected):
assert _arm_vendor_from_model(model) == expected assert _arm_vendor_from_model(model) == expected
@@ -768,11 +827,27 @@ def test_arm_vendor_from_model(model, expected):
def test_get_facts_baremetal_vendor_model_serial(driver): def test_get_facts_baremetal_vendor_model_serial(driver):
platform = {"vendor": "Dell Inc.", "model": "PowerEdge R720", "serial": "ABC123", "is_vm": False} platform = {
with patch.object(driver, "_collect_platform_info", return_value=platform), \ "vendor": "Dell Inc.",
patch.object(driver, "_parse_uptime", return_value=86400), \ "model": "PowerEdge R720",
patch.object(driver, "_send", side_effect=["myhost", "myhost.example.com", "Debian GNU/Linux 12", "eth0\neth1", "serial": "ABC123",
"6.1.0-18-amd64"]): "is_vm": False,
}
with (
patch.object(driver, "_collect_platform_info", return_value=platform),
patch.object(driver, "_parse_uptime", return_value=86400),
patch.object(
driver,
"_send",
side_effect=[
"myhost",
"myhost.example.com",
"Debian GNU/Linux 12",
"eth0\neth1",
"6.1.0-18-amd64",
],
),
):
facts = driver.get_facts() facts = driver.get_facts()
assert facts["vendor"] == "Dell Inc." assert facts["vendor"] == "Dell Inc."
assert facts["model"] == "PowerEdge R720" assert facts["model"] == "PowerEdge R720"
@@ -785,13 +860,20 @@ def test_get_facts_baremetal_vendor_model_serial(driver):
def test_get_facts_vm_kvm(driver): def test_get_facts_vm_kvm(driver):
platform = { platform = {
"vendor": "KVM", "model": "Virtual Machine", "vendor": "KVM",
"serial": "4c4c4544-0000-2010-8020-b4c04f534a31", "is_vm": True, "model": "Virtual Machine",
"serial": "4c4c4544-0000-2010-8020-b4c04f534a31",
"is_vm": True,
} }
with patch.object(driver, "_collect_platform_info", return_value=platform), \ with (
patch.object(driver, "_parse_uptime", return_value=3600), \ patch.object(driver, "_collect_platform_info", return_value=platform),
patch.object(driver, "_send", side_effect=["vmhost", "vmhost.local", "Ubuntu 22.04 LTS", "eth0", patch.object(driver, "_parse_uptime", return_value=3600),
"5.15.0-91-generic"]): patch.object(
driver,
"_send",
side_effect=["vmhost", "vmhost.local", "Ubuntu 22.04 LTS", "eth0", "5.15.0-91-generic"],
),
):
facts = driver.get_facts() facts = driver.get_facts()
assert facts["vendor"] == "KVM" assert facts["vendor"] == "KVM"
assert facts["model"] == "Virtual Machine" assert facts["model"] == "Virtual Machine"
@@ -800,9 +882,15 @@ def test_get_facts_vm_kvm(driver):
def test_get_facts_fallback_vendor_when_dmi_empty(driver): def test_get_facts_fallback_vendor_when_dmi_empty(driver):
platform = {"vendor": "", "model": "", "serial": "", "is_vm": False} platform = {"vendor": "", "model": "", "serial": "", "is_vm": False}
with patch.object(driver, "_collect_platform_info", return_value=platform), \ with (
patch.object(driver, "_parse_uptime", return_value=0), \ patch.object(driver, "_collect_platform_info", return_value=platform),
patch.object(driver, "_send", side_effect=["host", "host.local", "Alpine Linux 3.19", "eth0", "6.6.7-0-lts"]): patch.object(driver, "_parse_uptime", return_value=0),
patch.object(
driver,
"_send",
side_effect=["host", "host.local", "Alpine Linux 3.19", "eth0", "6.6.7-0-lts"],
),
):
facts = driver.get_facts() facts = driver.get_facts()
assert facts["vendor"] == "Linux" # fallback to VENDOR class attribute assert facts["vendor"] == "Linux" # fallback to VENDOR class attribute
@@ -813,7 +901,12 @@ class TestNoDockerOfItsOwn:
only the fix that lets the login user use Docker stays.""" only the fix that lets the login user use Docker stays."""
def test_the_cli_methods_are_gone(self): def test_the_cli_methods_are_gone(self):
for name in ("get_docker_info", "get_docker_outdated", "reconstruct_docker_run", "_docker_bin"): for name in (
"get_docker_info",
"get_docker_outdated",
"reconstruct_docker_run",
"_docker_bin",
):
assert not hasattr(LinuxDriver, name), name assert not hasattr(LinuxDriver, name), name
def test_the_engine_access_and_the_permission_fix_stay(self): def test_the_engine_access_and_the_permission_fix_stay(self):
@@ -1019,7 +1112,9 @@ class TestReadToTheEnd:
def test_the_echoed_command_does_not_count_as_the_marker(self, driver): def test_the_echoed_command_does_not_count_as_the_marker(self, driver):
"""Its literal ``$?`` is no number.""" """Its literal ``$?`` is no number."""
channel = _Channel(["sudo true; echo __NETORK_RC=$?\n", "__NETORK_RC=0\nchris@vault-01:~$ "]) channel = _Channel(
["sudo true; echo __NETORK_RC=$?\n", "__NETORK_RC=0\nchris@vault-01:~$ "]
)
driver._device = channel driver._device = channel
assert _split_status(driver._send(_TRUE_WITH_STATUS))[1] == 0 assert _split_status(driver._send(_TRUE_WITH_STATUS))[1] == 0
@@ -1043,7 +1138,7 @@ class TestReadToTheEnd:
) )
def test_every_status_marker_is_waited_for(self, driver, command): def test_every_status_marker_is_waited_for(self, driver, command):
marker = re.search(r"echo (__[A-Z_]+=)", command).group(1) marker = re.search(r"echo (__[A-Z_]+=)", command).group(1)
channel = _Channel([f"x <a@b>\n", f"{marker}0\nchris@host:~$ "]) channel = _Channel(["x <a@b>\n", f"{marker}0\nchris@host:~$ "])
driver._device = channel driver._device = channel
output = driver._send(command) output = driver._send(command)
@@ -1167,7 +1262,11 @@ def _kernel_wire(report: str) -> str:
import base64 import base64
import gzip import gzip
return "KFACTS_BEGIN\n" + base64.encodebytes(gzip.compress(report.encode())).decode() + "KFACTS_END" return (
"KFACTS_BEGIN\n"
+ base64.encodebytes(gzip.compress(report.encode())).decode()
+ "KFACTS_END"
)
def test_get_kernel_facts_carries_the_shared_command_across(driver): def test_get_kernel_facts_carries_the_shared_command_across(driver):
@@ -1369,12 +1468,16 @@ class TestAvailableUpdates:
driver._pkg_manager = "dnf" driver._pkg_manager = "dnf"
driver._device.send_command.side_effect = [ driver._device.send_command.side_effect = [
"0", # id -u "0", # id -u
("openssl-libs.x86_64 1:3.1.4-2.fc40 updates\n" (
"vim-enhanced.x86_64 2:9.1.083-1.fc40 updates\n__NETORK_RC=100"), "openssl-libs.x86_64 1:3.1.4-2.fc40 updates\n"
"vim-enhanced.x86_64 2:9.1.083-1.fc40 updates\n__NETORK_RC=100"
),
# DNF_SECURITY_COMMAND pipes through cat: the outer status is cat's, dnf's own # DNF_SECURITY_COMMAND pipes through cat: the outer status is cat's, dnf's own
# is in the __DNF_RC marker. # is in the __DNF_RC marker.
("FEDORA-2024-1a2b3c4d5e Important/Sec. openssl-libs-1:3.1.4-2.fc40.x86_64\n" (
"__DNF_RC=0\n__NETORK_RC=0"), "FEDORA-2024-1a2b3c4d5e Important/Sec. openssl-libs-1:3.1.4-2.fc40.x86_64\n"
"__DNF_RC=0\n__NETORK_RC=0"
),
] ]
updates = {u["name"]: u for u in driver.get_available_updates()} updates = {u["name"]: u for u in driver.get_available_updates()}
@@ -1402,10 +1505,14 @@ class TestAvailableUpdates:
driver._pkg_manager = "yum" driver._pkg_manager = "yum"
driver._device.send_command.side_effect = [ driver._device.send_command.side_effect = [
"0", # id -u "0", # id -u
("openssl-libs.x86_64 1:1.0.2k-26.el7_9 updates\n" (
"vim-enhanced.x86_64 2:7.4.629-8.el7_9 updates\n__NETORK_RC=100"), "openssl-libs.x86_64 1:1.0.2k-26.el7_9 updates\n"
("RHSA-2023:3556 Important/Sec. openssl-libs-1:1.0.2k-26.el7_9.x86_64\n" "vim-enhanced.x86_64 2:7.4.629-8.el7_9 updates\n__NETORK_RC=100"
"__DNF_RC=0\n__NETORK_RC=0"), ),
(
"RHSA-2023:3556 Important/Sec. openssl-libs-1:1.0.2k-26.el7_9.x86_64\n"
"__DNF_RC=0\n__NETORK_RC=0"
),
] ]
updates = {u["name"]: u for u in driver.get_available_updates()} updates = {u["name"]: u for u in driver.get_available_updates()}
@@ -1449,7 +1556,10 @@ class TestAvailableUpdates:
def test_dnf_that_failed_raises(self, driver): def test_dnf_that_failed_raises(self, driver):
driver._pkg_manager = "dnf" driver._pkg_manager = "dnf"
driver._device.send_command.side_effect = ["0", "Error: Failed to download metadata\n__NETORK_RC=1"] driver._device.send_command.side_effect = [
"0",
"Error: Failed to download metadata\n__NETORK_RC=1",
]
with pytest.raises(RuntimeError): with pytest.raises(RuntimeError):
driver.get_available_updates() driver.get_available_updates()
@@ -1461,7 +1571,10 @@ class TestRefreshAvailableUpdates:
def test_apt_refreshes_its_index_as_root(self, driver): def test_apt_refreshes_its_index_as_root(self, driver):
driver._pkg_manager = "apt" driver._pkg_manager = "apt"
driver._device.send_command.side_effect = ["0", "Hit:1 http://archive.ubuntu.com noble InRelease\n__NETORK_RC=0"] driver._device.send_command.side_effect = [
"0",
"Hit:1 http://archive.ubuntu.com noble InRelease\n__NETORK_RC=0",
]
result = driver.refresh_available_updates() result = driver.refresh_available_updates()
@@ -1470,7 +1583,10 @@ class TestRefreshAvailableUpdates:
def test_without_a_sudo_password_it_never_waits_for_one(self, driver): def test_without_a_sudo_password_it_never_waits_for_one(self, driver):
driver._pkg_manager = "apt" driver._pkg_manager = "apt"
driver._device.send_command.side_effect = ["1000", "sudo: a password is required\n__NETORK_RC=1"] driver._device.send_command.side_effect = [
"1000",
"sudo: a password is required\n__NETORK_RC=1",
]
result = driver.refresh_available_updates() result = driver.refresh_available_updates()
+3 -1
View File
@@ -27,7 +27,9 @@ OTHER_KEY = paramiko.ECDSAKey.generate()
def _device() -> MagicMock: def _device() -> MagicMock:
device = MagicMock() device = MagicMock()
device.send_command.return_value = "/usr/bin/apt" device.send_command.return_value = "/usr/bin/apt"
device.remote_conn_pre.get_transport.return_value.get_remote_server_key.return_value = SERVER_KEY device.remote_conn_pre.get_transport.return_value.get_remote_server_key.return_value = (
SERVER_KEY
)
return device return device
+1 -1
View File
@@ -30,7 +30,7 @@ class Channel:
"""An exec channel answering with *output* and *status*; it refuses a line """An exec channel answering with *output* and *status*; it refuses a line
that holds the password, which is what ``ps`` would show.""" that holds the password, which is what ``ps`` would show."""
def __init__(self, host: "Transport"): def __init__(self, host: Transport):
self.host = host self.host = host
self.command = "" self.command = ""
self.stdin = b"" self.stdin = b""