From 22af21fd3f01f6c11fcb9a4b931eb50dd8a471c8 Mon Sep 17 00:00:00 2001 From: "cliang01.li" Date: Sun, 24 Dec 2023 18:50:45 -0800 Subject: [PATCH] Add unittests for dss_host.py and dss_target.py --- unittests/conftest.py | 387 +++++++++++++++++++++++++++++++++++ unittests/test_dss_host.py | 140 +++++++++++++ unittests/test_dss_target.py | 129 ++++++++++++ 3 files changed, 656 insertions(+) create mode 100644 unittests/conftest.py create mode 100644 unittests/test_dss_host.py create mode 100644 unittests/test_dss_target.py diff --git a/unittests/conftest.py b/unittests/conftest.py new file mode 100644 index 00000000..58c33fa7 --- /dev/null +++ b/unittests/conftest.py @@ -0,0 +1,387 @@ +#!/usr/bin/python3 + +""" +# The Clear BSD License +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted (subject to the limitations in the disclaimer +# below) provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Samsung Electronics Co., Ltd. nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY +# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +# NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +from faker import Faker +import pytest +import secrets + + +@pytest.fixture(scope="session") +def get_sample_nvme_devices(): + sample_nvme_list_output = """\ + Node SN Model \ + Namespace Usage Format \ + FW Rev + ---------------- -------------------- ------------------------------------\ + ---- --------- -------------------------- ---------------- -------- + /dev/nvme0n1 DSS5066419069 SPDK bdev Controller \ + 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07 + /dev/nvme1n1 DSS2690548027 SPDK bdev Controller \ + 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07 + /dev/nvme2n1 DSS1137172735 SPDK bdev Controller \ + 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07 + /dev/nvme3n1 DSS7754076932 SPDK bdev Controller \ + 1 12.58 MB / 7.65 TB 512 B + 0 B 20.07 + /dev/nvme4n1 DSS5066419069 SPDK bdev Controller \ + 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07 + /dev/nvme5n1 DSS2690548027 SPDK bdev Controller \ + 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07 + /dev/nvme6n1 DSS1137172735 SPDK bdev Controller \ + 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07 + /dev/nvme7n1 DSS7754076932 SPDK bdev Controller \ + 1 12.58 MB / 7.65 TB 512 B + 0 B 20.07 + """ + return sample_nvme_list_output + + +@pytest.fixture(scope="session") +def get_sample_nvme_subsystems(): + sample_nvme_subsystems = """\ + nvme-subsys0 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data1 + \ + +- nvme0 rdma traddr=201.x.x.xxx trsvcid=1024 live + +- nvme4 rdma traddr=203.x.x.xxx trsvcid=1024 live + nvme-subsys1 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data2 + \ + +- nvme1 rdma traddr=201.x.x.xxx trsvcid=1024 live + +- nvme5 rdma traddr=203.x.x.xxx trsvcid=1024 live + nvme-subsys2 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data3 + \ + +- nvme2 rdma traddr=201.x.x.xxx trsvcid=1024 live + +- nvme6 rdma traddr=203.x.x.xxx trsvcid=1024 live + nvme-subsys3 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data4 + \ + +- nvme3 rdma traddr=201.x.x.xxx trsvcid=1024 live + +- nvme7 rdma traddr=203.x.x.xxx trsvcid=1024 live + """ + return sample_nvme_subsystems + + +def get_sample_lscpu_output(): + sample_lscpu_output = """\ + Architecture: x86_64 + CPU op-mode(s): 32-bit, 64-bit + Byte Order: Little Endian + CPU(s): 88 + On-line CPU(s) list: 0-87 + Thread(s) per core: 2 + Core(s) per socket: 22 + Socket(s): 2 + NUMA node(s): 2 + Vendor ID: GenuineIntel + CPU family: 6 + Model: 85 + Model name: Intel(R) Xeon(R) Gold 6152 CPU @ 2.10GHz + Stepping: 4 + CPU MHz: 2543.753 + CPU max MHz: 3700.0000 + CPU min MHz: 1000.0000 + BogoMIPS: 4200.00 + Virtualization: VT-x + L1d cache: 32K + L1i cache: 32K + L2 cache: 1024K + L3 cache: 30976K + NUMA node0 CPU(s): 0-21,44-65 + NUMA node1 CPU(s): 22-43,66-87 + Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr\ + mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe\ + syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs\ + bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni\ + pclmulqdq dtes64 monitor ds_cpl vmx smx tm2 ssse3 sdbg\ + fma cx16 xtpr pdcm pcid dca sse4_1 x2apic movbe\ + popcnt tsc_deadline_timer aes xsave avx rdrand\ + lahf_lm abm 3dnowprefetch cpuid_fault epb\ + cat_l3 cdp_l3 pti intel_ppin\ + ssbd mba ibrs ibpb stibp\ + vnmi ept vpid ept_ad\ + fsgsbase tsc_adjust bmi1 hle\ + avx2 smep bmi2 erms\ + rtm cqm mpx rdt_a\ + """ + return sample_lscpu_output + + +@pytest.fixture(scope="session") +def get_sample_nvme_discover_output(): + sample_nvme_dsicover_output = """\ + Discovery Log Number of Records 1, Generation counter 4 + =====Discovery Log Entry 0====== + trtype: rdma + adrfam: ipv4 + subtype: nvme subsystem + treq: not required + portid: 0 + trsvcid: 1024 + subnqn: nqn.2023-06.io:msl-dpe-perf35-kv_data1 + traddr: x.x.x.x + rdma_prtype: not specified + rdma_qptype: connected + rdma_cms: rdma-cm + rdma_pkey: 0x0000 + """ + return sample_nvme_dsicover_output + + +@pytest.fixture(scope="session") +def get_sample_dict_data(): + sample_dict = {"key " + str(i): secrets.randbelow(100) for i in range(10)} + return sample_dict + + +@pytest.fixture(scope="session") +def get_temp_dir(tmpdir): + return tmpdir + + +@pytest.fixture +def get_sample_ipv4_addr(): + fake = Faker() + return fake.ipv4() + + +@pytest.fixture +def get_sample_ipv6_addr(): + fake = Faker() + return fake.ipv6() + + +@pytest.fixture +def get_sample_ipv4_addr_list(): + fake = Faker() + return [fake.ipv4() for _ in range(4)] + + +@pytest.fixture +def get_sample_ipv6_addr_list(): + fake = Faker() + return [fake.ipv6() for _ in range(4)] + + +@pytest.fixture +def get_global_var(): + global rdd + rdd = "yes" + return rdd + + +def get_sample_lshw_output(): + return """\ + { + "id" : "network:0", + "class" : "network", + "claimed" : true, + "handle" : "PCI:0000:04:00.0", + "description" : "Ethernet interface", + "product" : "MT27800 Family [ConnectX-5]", + "vendor" : "Mellanox Technologies", + "physid" : "0", + "businfo" : "pci@0000:04:00.0", + "logicalname" : "p6p1", + "version" : "00", + "serial" : "b8:59:9f:2d:18:7e", + "width" : 64, + "clock" : 33000000, + "configuration" : { + "autonegotiation" : "on", + "broadcast" : "yes", + "driver" : "mlx5_core", + "driverversion" : "5.0-0", + "firmware" : "16.33.1048 (MT_0000000012)", + "latency" : "0", + "link" : "no", + "multicast" : "yes", + "port" : "fibre", + "ip": "192.168.1.2" + }, + "capabilities" : { + "pciexpress" : "PCI Express", + "vpd" : "Vital Product Data", + "msix" : "MSI-X", + "pm" : "Power Management", + "bus_master" : "bus mastering", + "cap_list" : "PCI capabilities listing", + "rom" : "extension ROM", + "ethernet" : true, + "physical" : "Physical interface", + "fibre" : "optical fibre", + "autonegotiation" : "Auto-negotiation" + } + } + """ + + +def get_sample_nvme_list_subsys(): + return """\ + { + "Subsystems" : [ + { + "Name" : "nvme-subsys0", + "NQN" : "nqn.2023-12.io:109-tcp-0-kv_data1" + }, + { + "Paths" : [ + { + "Name" : "nvme0", + "Transport" : "rdma", + "Address" : "traddr=192.168.1.2 trsvcid=1024", + "State" : "live" + } + ] + }, + { + "Name" : "nvme-subsys1", + "NQN" : "nqn.2023-12.io:109-tcp-0-kv_data2" + }, + { + "Paths" : [ + { + "Name" : "nvme1", + "Transport" : "rdma", + "Address" : "traddr=192.168.1.2 trsvcid=1024", + "State" : "live" + } + ] + }, + { + "Name" : "nvme-subsys2", + "NQN" : "nqn.2023-12.io:109-tcp-0-kv_data3" + }, + { + "Paths" : [ + { + "Name" : "nvme2", + "Transport" : "rdma", + "Address" : "traddr=192.168.1.2 trsvcid=1024", + "State" : "live" + } + ] + }, + { + "Name" : "nvme-subsys3", + "NQN" : "nqn.2023-12.io:109-tcp-0-kv_data4" + }, + { + "Paths" : [ + { + "Name" : "nvme3", + "Transport" : "rdma", + "Address" : "traddr=192.168.1.2 trsvcid=1024", + "State" : "live" + } + ] + } + ] +} + """ + + +def mock_exec_cmd(cmd): + if cmd == "uname -r": + return 0, "5.1.0", "" + elif cmd.startswith("nvme list-subsys -o json"): + return 0, get_sample_nvme_list_subsys(), "" + elif cmd.startswith("ip -4 addr | grep"): + return 0, "192.168.1.2/24", "" + elif cmd.startswith("ls /sys/class/pci_bus/") \ + and cmd.endswith("firmware_rev"): + return 0, "/sys/class/pci_bus/0000:17/" +\ + "device/0000:17:00.0/nvme/nvme1/firmware_rev", "" + elif cmd.startswith("ls /sys/class/pci_bus") and cmd.endswith("serial"): + return 0, "/sys/class/pci_bus/0000:17/" +\ + "device/0000:17:00.0/nvme/nvme1/serial", "" + elif cmd.startswith("lspci -mm -n -D | grep 0108 "): + return 0, "0000:17:00.0", "" + elif cmd.startswith("cat /sys/class/net/") and cmd.endswith("mtu"): + return 0, "9000", "" + elif cmd == "lscpu": + return 0, get_sample_lscpu_output(), "" + elif cmd.startswith("cat /sys/class/net/") and cmd.endswith("numa_node"): + return 0, "0", "" + elif cmd == "nproc": + return 0, "128", "" + elif cmd == "lshw -c network -json": + return 0, get_sample_lshw_output(), "" + elif cmd.startswith("ip -d link show dev"): + return 0, "vlanid 1234", "" + else: + return 0, "", "" + + +def mock_os_dirname_host(name): + return "/usr/dss/nkv-sdk/bin" + + +def mock_exec_cmd_remote(cmd, host, user, pw): + if cmd.startswith("lshw -c network -json"): + return 0, get_sample_lshw_output(), "" + elif cmd.startswith("ip -d link show dev"): + return 0, ["vlanid 1234"], "" + else: + return 0, "", "" + + +def mock_interfaces(): + return ['nic'] + + +def mock_ifaddresses(interface): + return [[{'addr': '1.2.3.4'}]] + + +class MockArgs(): + + def __init__(self, *args, **kwargs): + self.addrs = ['1.2.3.4'] + self.ports = [1234] + self.command = "config_host" + self.gen2 = False + self.vlan_ip_map = None + self.rdd_port = None + self.proto = "rdma" + self.memalign = 512 + self.qpair = 32 + self.kvpair = [] + + +class MockArgParser(): + + def __init__(self, *args, **kwargs): + pass + + def parse_args(self, *args, **kwargs): + return MockArgs() + + def add_argument(self, *args, **kwargs): + pass diff --git a/unittests/test_dss_host.py b/unittests/test_dss_host.py new file mode 100644 index 00000000..348b66b6 --- /dev/null +++ b/unittests/test_dss_host.py @@ -0,0 +1,140 @@ +#!/usr/bin/python3 + +""" +# The Clear BSD License +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted (subject to the limitations in the disclaimer +# below) provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Samsung Electronics Co., Ltd. nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY +# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +# NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +from host.scripts.dss_host import ( + is_ipv4, getSubnet, get_ip_port_nqn_info, decode, + build_driver, install_kernel_driver, get_ips_for_vlan, + drive_to_addr_map, mountpt_to_nqn_addr_map, subnet_drive_map, + discover_dist, config_minio_dist, config_minio_sa, dss_host_args +) +import pytest +import secrets +import os +from conftest import ( + mock_exec_cmd, mock_os_dirname_host, + mock_exec_cmd_remote, + MockArgParser +) + + +@pytest.mark.usefixtures( + "get_sample_ipv4_addr", + "get_sample_ipv6_addr", + "get_sample_nvme_discover_output" +) +class TestDSSHost(): + def test_is_ipv4(self, get_sample_ipv4_addr, get_sample_ipv6_addr): + assert bool(is_ipv4(get_sample_ipv4_addr)) + assert not is_ipv4(get_sample_ipv6_addr) + + def test_getSubnet(self, get_sample_ipv4_addr): + addr = get_sample_ipv4_addr + subnet = '.'.join(addr.split('.')[0:3]) + assert subnet == getSubnet(addr) + + def test_get_ip_port_nqn_info(self, get_sample_nvme_discover_output): + data = get_ip_port_nqn_info(get_sample_nvme_discover_output, "rdma") + proto = 'rdma' + port = '1024' + subsystem = 'nqn.2023-06.io:msl-dpe-perf35-kv_data1' + ip = 'x.x.x.x' + assert data == [[proto, port, subsystem, ip]] + + def test_decode(self): + bytes = bytearray(secrets.randbits(8) for _ in range(200)) + assert isinstance(decode(bytes), str) + + def test_build_driver(self, mocker): + mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + mocker.patch("os.path.dirname", mock_os_dirname_host) + build_driver() + + def test_install_kernel_driver(self, mocker): + cwd = os.getcwd() + mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + mocker.patch("os.path.dirname", mock_os_dirname_host) + install_kernel_driver(512) + + def test_get_ips_for_vlan(self, mocker): + mocker.patch("host.scripts.dss_host.exec_cmd_remote", + mock_exec_cmd_remote) + res = get_ips_for_vlan("1234", "host", ["pw"]) + assert len(res) > 0 + + def test_drive_to_addr_map(self, mocker): + mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + res = drive_to_addr_map() + assert len(res) == 4 + + def test_mountpt_to_nqn_addr_map(self, mocker): + mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + res = mountpt_to_nqn_addr_map() + assert len(res) == 4 + for dev in res.keys(): + assert "nqn" in res[dev] + assert "addr" in res[dev] + + def test_subnet_drive_map(self, mocker): + mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + res = subnet_drive_map() + assert len(res) > 0 + + def test_discover_dist(self, mocker): + mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + mocker.patch("host.scripts.dss_host.exec_cmd_remote", + mock_exec_cmd_remote) + res = discover_dist(1234, ["1234"], ["1234"], "pw") + assert len(res) > 0 + + def test_config_minio_dist(self, mocker): + mocker.patch("builtins.open") + mocker.patch("os.chmod") + config_minio_dist(["ip", "port", "dev_start", "dev"], 1) + + def test_config_minio_sa(self, mocker): + mocker.patch("builtins.open") + config_minio_sa(["ip", "port", "dev_start", "dev"], 1) + + def test_dss_host_args_config_host(self, mocker): + mocker.patch("argparse.ArgumentParser", MockArgParser) + mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + mocker.patch("host.scripts.dss_host.exec_cmd_remote", + mock_exec_cmd_remote) + mocker.patch("builtins.open") + mocker.patch("os.chmod") + mocker.patch("os.chdir") + mocker.patch("os.path.exists") + mocker.patch("json.load") + mocker.patch("json.dump") + d = dss_host_args() diff --git a/unittests/test_dss_target.py b/unittests/test_dss_target.py new file mode 100644 index 00000000..7bcc4c1d --- /dev/null +++ b/unittests/test_dss_target.py @@ -0,0 +1,129 @@ +#!/usr/bin/python3 + +""" +# The Clear BSD License +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted (subject to the limitations in the disclaimer +# below) provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Samsung Electronics Co., Ltd. nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY +# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +# NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +from target.dss_target import ( + random_with_N_digits, generate_core_mask, generate_core_mask_vmmode, + get_pcie_address_firmware_mapping, get_pcie_address_serial_mapping, + get_nvme_list_numa, ip4_addresses, only_mtu9k, get_rdma_ips, + get_numa_boundary, get_numa_ip, create_nvmf_config_file, get_vlan_ips, + setup_hugepage +) +import pytest +from conftest import ( + mock_exec_cmd, mock_os_dirname_host, + mock_exec_cmd_remote, + MockArgParser, MockArgs, + mock_interfaces, mock_ifaddresses +) + + +class TestDSSTarget(): + def test_random_with_N_digits(self): + num_digits = 10 + num = random_with_N_digits(10) + assert len(str(num)) == num_digits + + def test_generate_core_mask(self): + core_count = 12 + dedicated_core_percent = 0.6 + return 0 == generate_core_mask(core_count, dedicated_core_percent) + + def test_generate_core_mask_vmmode(self): + core_count = 12 + return 0 == generate_core_mask_vmmode(core_count) + + def test_get_pcie_address_firmware_mapping(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + mocker.patch("builtins.open") + mocker.patch("typing.IO.readlines") + r1, r2 = get_pcie_address_firmware_mapping() + + def test_get_pcie_address_serial_mapping(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + mocker.patch("builtins.open") + mocker.patch("typing.IO.readlines") + r = get_pcie_address_serial_mapping([]) + assert len(r) > 0 + + def test_get_nvme_list_numa(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + r = get_nvme_list_numa() + assert len(r) > 0 + + def test_ip4_addresses(self, mocker): + r = ip4_addresses() + assert len(r) > 0 + + def test_only_mtu9k(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + r = only_mtu9k({"ip": 100}) + assert len(r) > 0 + + def test_get_rdma_ips(self, mocker): + r = get_rdma_ips({"nic": "1.2.3.4"}, ["1.2.3.4"]) + assert len(r) > 0 + + def test_get_numa_boundary(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + r = get_numa_boundary() + assert r == 1.0 + + def test_get_numa_ip(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + mocker.patch("target.dss_target.interfaces", mock_interfaces) + mocker.patch("target.dss_target.ifaddresses", mock_ifaddresses) + mocker.patch("target.dss_target.AF_INET", 0) + r1, r2 = get_numa_ip(["1.2.3.4"]) + assert len(r1) > 0 + assert len(r2) == 0 + + def test_create_nvmf_config_file(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + mocker.patch("target.dss_target.interfaces", mock_interfaces) + mocker.patch("target.dss_target.ifaddresses", mock_ifaddresses) + mocker.patch("target.dss_target.AF_INET", 0) + mocker.patch("builtins.open") + r = create_nvmf_config_file("", ["1.2.3.4"], [], []) + assert r == 0 + + def test_get_vlan_ips(self, mocker): + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + r = get_vlan_ips("1234") + assert r + + def test_setup_hugepage(self, mocker): + mocker.patch("builtins.open") + mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + r = setup_hugepage() + assert r == 0