From 22af21fd3f01f6c11fcb9a4b931eb50dd8a471c8 Mon Sep 17 00:00:00 2001 From: "cliang01.li" Date: Sun, 24 Dec 2023 18:50:45 -0800 Subject: [PATCH 1/5] 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 From 18d4b3511a9b2d6bff3e7d568cd4499410bc0cfd Mon Sep 17 00:00:00 2001 From: "cliang01.li" Date: Sun, 24 Dec 2023 19:52:04 -0800 Subject: [PATCH 2/5] fix sonar cloud issues --- unittests/conftest.py | 16 ++++----- unittests/test_dss_host.py | 57 +++++++++++++++++-------------- unittests/test_dss_target.py | 66 +++++++++++++++++++++--------------- 3 files changed, 77 insertions(+), 62 deletions(-) diff --git a/unittests/conftest.py b/unittests/conftest.py index 58c33fa7..30345c79 100644 --- a/unittests/conftest.py +++ b/unittests/conftest.py @@ -223,7 +223,7 @@ def get_sample_lshw_output(): "link" : "no", "multicast" : "yes", "port" : "fibre", - "ip": "192.168.1.2" + "ip": "192.168.1.x" }, "capabilities" : { "pciexpress" : "PCI Express", @@ -255,7 +255,7 @@ def get_sample_nvme_list_subsys(): { "Name" : "nvme0", "Transport" : "rdma", - "Address" : "traddr=192.168.1.2 trsvcid=1024", + "Address" : "traddr=192.168.1.x trsvcid=1024", "State" : "live" } ] @@ -269,7 +269,7 @@ def get_sample_nvme_list_subsys(): { "Name" : "nvme1", "Transport" : "rdma", - "Address" : "traddr=192.168.1.2 trsvcid=1024", + "Address" : "traddr=192.168.1.x trsvcid=1024", "State" : "live" } ] @@ -283,7 +283,7 @@ def get_sample_nvme_list_subsys(): { "Name" : "nvme2", "Transport" : "rdma", - "Address" : "traddr=192.168.1.2 trsvcid=1024", + "Address" : "traddr=192.168.1.x trsvcid=1024", "State" : "live" } ] @@ -297,7 +297,7 @@ def get_sample_nvme_list_subsys(): { "Name" : "nvme3", "Transport" : "rdma", - "Address" : "traddr=192.168.1.2 trsvcid=1024", + "Address" : "traddr=192.168.1.x trsvcid=1024", "State" : "live" } ] @@ -313,7 +313,7 @@ def mock_exec_cmd(cmd): 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", "" + return 0, "192.168.1.x/24", "" elif cmd.startswith("ls /sys/class/pci_bus/") \ and cmd.endswith("firmware_rev"): return 0, "/sys/class/pci_bus/0000:17/" +\ @@ -357,13 +357,13 @@ def mock_interfaces(): def mock_ifaddresses(interface): - return [[{'addr': '1.2.3.4'}]] + return [[{'addr': '1.x.x.x'}]] class MockArgs(): def __init__(self, *args, **kwargs): - self.addrs = ['1.2.3.4'] + self.addrs = ['1.x.x.x'] self.ports = [1234] self.command = "config_host" self.gen2 = False diff --git a/unittests/test_dss_host.py b/unittests/test_dss_host.py index 348b66b6..e2eebb42 100644 --- a/unittests/test_dss_host.py +++ b/unittests/test_dss_host.py @@ -48,6 +48,20 @@ ) +def mock_functions(mocker, *args): + for arg in args: + if arg == "host.scripts.dss_host.exec_cmd": + mocker.patch(arg, mock_exec_cmd) + elif arg == "os.path.dirname": + mocker.patch(arg, mock_os_dirname_host) + elif arg == "host.scripts.dss_host.exec_cmd_remote": + mocker.patch(arg, mock_exec_cmd_remote) + elif arg == "argparse.ArgumentParser": + mocker.patch(arg, MockArgParser) + else: + mocker.patch(arg) + + @pytest.mark.usefixtures( "get_sample_ipv4_addr", "get_sample_ipv6_addr", @@ -76,29 +90,27 @@ def test_decode(self): 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) + mock_functions(mocker, "host.scripts.dss_host.exec_cmd", + "os.path.dirname") 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) + mock_functions(mocker, "host.scripts.dss_host.exec_cmd", + "os.path.dirname") 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) + mock_functions(mocker, "host.scripts.dss_host.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) + mock_functions(mocker, "host.scripts.dss_host.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) + mock_functions(mocker, "host.scripts.dss_host.exec_cmd") res = mountpt_to_nqn_addr_map() assert len(res) == 4 for dev in res.keys(): @@ -106,35 +118,28 @@ def test_mountpt_to_nqn_addr_map(self, mocker): assert "addr" in res[dev] def test_subnet_drive_map(self, mocker): - mocker.patch("host.scripts.dss_host.exec_cmd", mock_exec_cmd) + mock_functions(mocker, "host.scripts.dss_host.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) + mock_functions(mocker, "host.scripts.dss_host.exec_cmd", + "host.scripts.dss_host.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") + mock_functions(mocker, "builtins.open", "os.chmod") config_minio_dist(["ip", "port", "dev_start", "dev"], 1) def test_config_minio_sa(self, mocker): - mocker.patch("builtins.open") + mock_functions(mocker, "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") + mock_functions(mocker, "argparse.ArgumentParser", + "host.scripts.dss_host.exec_cmd", + "host.scripts.dss_host.exec_cmd_remote", + "builtins.open", "os.chmod", "os.chdir", + "os.path.exists", "json.load", "json.dump") d = dss_host_args() diff --git a/unittests/test_dss_target.py b/unittests/test_dss_target.py index 7bcc4c1d..fd912310 100644 --- a/unittests/test_dss_target.py +++ b/unittests/test_dss_target.py @@ -41,13 +41,25 @@ ) import pytest from conftest import ( - mock_exec_cmd, mock_os_dirname_host, - mock_exec_cmd_remote, - MockArgParser, MockArgs, + mock_exec_cmd, mock_interfaces, mock_ifaddresses ) +def mock_functions(mocker, *args): + for arg in args: + if arg == "target.dss_target.exec_cmd": + mocker.patch(arg, mock_exec_cmd) + elif arg == "target.dss_target.interfaces": + mocker.patch(arg, mock_interfaces) + elif arg == "target.dss_target.ifaddresses": + mocker.patch(arg, mock_ifaddresses) + elif arg == "target.dss_target.AF_INET": + mocker.patch(arg, 0) + else: + mocker.patch(arg) + + class TestDSSTarget(): def test_random_with_N_digits(self): num_digits = 10 @@ -64,20 +76,18 @@ def test_generate_core_mask_vmmode(self): 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") + mock_functions(mocker, "target.dss_target.exec_cmd", + "builtins.open", "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") + mock_functions(mocker, "target.dss_target.exec_cmd", + "builtins.open", "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) + mock_functions(mocker, "target.dss_target.exec_cmd") r = get_nvme_list_numa() assert len(r) > 0 @@ -86,44 +96,44 @@ def test_ip4_addresses(self, mocker): assert len(r) > 0 def test_only_mtu9k(self, mocker): - mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + mock_functions(mocker, "target.dss_target.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"]) + r = get_rdma_ips({"nic": "1.x.x.x"}, ["1.x.x.x"]) assert len(r) > 0 def test_get_numa_boundary(self, mocker): - mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + mock_functions(mocker, "target.dss_target.exec_cmd") r = get_numa_boundary() - assert r == 1.0 + assert int(r) == 1 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"]) + mock_functions(mocker, "target.dss_target.exec_cmd", + "target.dss_target.interfaces", + "target.dss_target.ifaddresses", + "target.dss_target.AF_INET") + r1, r2 = get_numa_ip(["1.x.x.x"]) 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"], [], []) + mock_functions(mocker, "target.dss_target.exec_cmd", + "target.dss_target.interfaces", + "target.dss_target.ifaddresses", + "target.dss_target.AF_INET", + "builtins.open") + r = create_nvmf_config_file("", ["1.x.x.x"], [], []) assert r == 0 def test_get_vlan_ips(self, mocker): - mocker.patch("target.dss_target.exec_cmd", mock_exec_cmd) + mock_functions(mocker, "target.dss_target.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) + mock_functions(mocker, "target.dss_target.exec_cmd", + "builtins.open") r = setup_hugepage() assert r == 0 From dbdf2a9aeb762da4b744c9f3b669130bd99f5fe6 Mon Sep 17 00:00:00 2001 From: "cliang01.li" Date: Sun, 24 Dec 2023 22:59:10 -0800 Subject: [PATCH 3/5] fix sonar cloud issues --- unittests/conftest.py | 76 +++++++++++++++++++++++------------- unittests/test_dss_host.py | 45 +++++++++++---------- unittests/test_dss_target.py | 54 ++++++++++++------------- 3 files changed, 100 insertions(+), 75 deletions(-) diff --git a/unittests/conftest.py b/unittests/conftest.py index 30345c79..da734b33 100644 --- a/unittests/conftest.py +++ b/unittests/conftest.py @@ -37,6 +37,9 @@ import secrets +default_mock_ip = '1.x.x.x' + + @pytest.fixture(scope="session") def get_sample_nvme_devices(): sample_nvme_list_output = """\ @@ -307,36 +310,53 @@ def get_sample_nvme_list_subsys(): """ +def get_ls_pci_bus(cmd): + begin = "/sys/class/pci_bus/0000:17/" +\ + "device/0000:17:00.0/nvme/nvme1/" + if cmd.endswith("firmware_rev"): + return begin + "firmware_rev" + else: + return begin + "serial" + + +def get_cat_sys_class_net(cmd): + if cmd.endswith("mtu"): + return "9000" + else: + return "0" + + def mock_exec_cmd(cmd): + ls_pci_bus = "ls /sys/class/pci_bus/" + cat_sys_class_net = "cat /sys/class/net/" + nvme_list_subsys = "nvme list-subsys -o json" + lspci_mm_n_D = "lspci -mm -n -D | grep 0108 " + lshw = "lshw -c network -json" + ip_d = "ip -d link show dev" + res = "" + if cmd == "uname -r": - return 0, "5.1.0", "" - elif cmd.startswith("nvme list-subsys -o json"): - return 0, get_sample_nvme_list_subsys(), "" + res = "5.1.0" + elif cmd.startswith(nvme_list_subsys): + res = get_sample_nvme_list_subsys() elif cmd.startswith("ip -4 addr | grep"): - return 0, "192.168.1.x/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", "" + res = "192.168.1.x/24" + elif cmd.startswith(ls_pci_bus): + res = get_ls_pci_bus(cmd) + elif cmd.startswith(lspci_mm_n_D): + res = "0000:17:00.0" + elif cmd.startswith(cat_sys_class_net): + res = get_cat_sys_class_net(cmd) elif cmd == "lscpu": - return 0, get_sample_lscpu_output(), "" - elif cmd.startswith("cat /sys/class/net/") and cmd.endswith("numa_node"): - return 0, "0", "" + res = get_sample_lscpu_output() 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, "", "" + res = "128" + elif cmd == lshw: + res = get_sample_lshw_output() + elif cmd.startswith(ip_d): + res = "vlanid 1234" + + return 0 ,res, "" def mock_os_dirname_host(name): @@ -357,13 +377,13 @@ def mock_interfaces(): def mock_ifaddresses(interface): - return [[{'addr': '1.x.x.x'}]] + return [[{'addr': default_mock_ip}]] class MockArgs(): def __init__(self, *args, **kwargs): - self.addrs = ['1.x.x.x'] + self.addrs = [default_mock_ip] self.ports = [1234] self.command = "config_host" self.gen2 = False @@ -378,10 +398,12 @@ def __init__(self, *args, **kwargs): class MockArgParser(): def __init__(self, *args, **kwargs): + # mock function, do nothing pass def parse_args(self, *args, **kwargs): return MockArgs() def add_argument(self, *args, **kwargs): + # mock function, do nothing pass diff --git a/unittests/test_dss_host.py b/unittests/test_dss_host.py index e2eebb42..d8202de8 100644 --- a/unittests/test_dss_host.py +++ b/unittests/test_dss_host.py @@ -48,15 +48,23 @@ ) +EXEC = "host.scripts.dss_host.exec_cmd" +DIRNAME = "os.path.dirname" +EXEC_REMOTE = "host.scripts.dss_host.exec_cmd_remote" +ARG_PARSER = "argparse.ArgumentParser" +OPEN = "builtins.open" +CHMOD = "os.chmod" + + def mock_functions(mocker, *args): for arg in args: - if arg == "host.scripts.dss_host.exec_cmd": + if arg == EXEC: mocker.patch(arg, mock_exec_cmd) - elif arg == "os.path.dirname": + elif arg == DIRNAME: mocker.patch(arg, mock_os_dirname_host) - elif arg == "host.scripts.dss_host.exec_cmd_remote": + elif arg == EXEC_REMOTE: mocker.patch(arg, mock_exec_cmd_remote) - elif arg == "argparse.ArgumentParser": + elif arg == ARG_PARSER: mocker.patch(arg, MockArgParser) else: mocker.patch(arg) @@ -90,27 +98,25 @@ def test_decode(self): assert isinstance(decode(bytes), str) def test_build_driver(self, mocker): - mock_functions(mocker, "host.scripts.dss_host.exec_cmd", - "os.path.dirname") + mock_functions(mocker, EXEC, DIRNAME) build_driver() def test_install_kernel_driver(self, mocker): - mock_functions(mocker, "host.scripts.dss_host.exec_cmd", - "os.path.dirname") + mock_functions(mocker, EXEC, DIRNAME) install_kernel_driver(512) def test_get_ips_for_vlan(self, mocker): - mock_functions(mocker, "host.scripts.dss_host.exec_cmd_remote") + mock_functions(mocker, EXEC_REMOTE) res = get_ips_for_vlan("1234", "host", ["pw"]) assert len(res) > 0 def test_drive_to_addr_map(self, mocker): - mock_functions(mocker, "host.scripts.dss_host.exec_cmd") + mock_functions(mocker, EXEC) res = drive_to_addr_map() assert len(res) == 4 def test_mountpt_to_nqn_addr_map(self, mocker): - mock_functions(mocker, "host.scripts.dss_host.exec_cmd") + mock_functions(mocker, EXEC) res = mountpt_to_nqn_addr_map() assert len(res) == 4 for dev in res.keys(): @@ -118,28 +124,25 @@ def test_mountpt_to_nqn_addr_map(self, mocker): assert "addr" in res[dev] def test_subnet_drive_map(self, mocker): - mock_functions(mocker, "host.scripts.dss_host.exec_cmd") + mock_functions(mocker, EXEC) res = subnet_drive_map() assert len(res) > 0 def test_discover_dist(self, mocker): - mock_functions(mocker, "host.scripts.dss_host.exec_cmd", - "host.scripts.dss_host.exec_cmd_remote") + mock_functions(mocker, EXEC, EXEC_REMOTE) res = discover_dist(1234, ["1234"], ["1234"], "pw") assert len(res) > 0 def test_config_minio_dist(self, mocker): - mock_functions(mocker, "builtins.open", "os.chmod") + mock_functions(mocker, OPEN, CHMOD) config_minio_dist(["ip", "port", "dev_start", "dev"], 1) def test_config_minio_sa(self, mocker): - mock_functions(mocker, "builtins.open") + mock_functions(mocker, OPEN) config_minio_sa(["ip", "port", "dev_start", "dev"], 1) def test_dss_host_args_config_host(self, mocker): - mock_functions(mocker, "argparse.ArgumentParser", - "host.scripts.dss_host.exec_cmd", - "host.scripts.dss_host.exec_cmd_remote", - "builtins.open", "os.chmod", "os.chdir", + mock_functions(mocker, ARG_PARSER, EXEC, + EXEC_REMOTE, OPEN, CHMOD, "os.chdir", "os.path.exists", "json.load", "json.dump") - d = dss_host_args() + dss_host_args() diff --git a/unittests/test_dss_target.py b/unittests/test_dss_target.py index fd912310..2cbf5181 100644 --- a/unittests/test_dss_target.py +++ b/unittests/test_dss_target.py @@ -41,20 +41,28 @@ ) import pytest from conftest import ( - mock_exec_cmd, + mock_exec_cmd, default_mock_ip, mock_interfaces, mock_ifaddresses ) +EXEC = "target.dss_target.exec_cmd" +INTERFACE = "target.dss_target.interfaces" +IFADDRESS = "target.dss_target.ifaddresses" +AFINET = "target.dss_target.AF_INET" +OPEN = "builtins.open" +READLINES = "typing.IO.readlines" + + def mock_functions(mocker, *args): for arg in args: - if arg == "target.dss_target.exec_cmd": + if arg == EXEC: mocker.patch(arg, mock_exec_cmd) - elif arg == "target.dss_target.interfaces": + elif arg == INTERFACE: mocker.patch(arg, mock_interfaces) - elif arg == "target.dss_target.ifaddresses": + elif arg == IFADDRESS: mocker.patch(arg, mock_ifaddresses) - elif arg == "target.dss_target.AF_INET": + elif arg == AFINET: mocker.patch(arg, 0) else: mocker.patch(arg) @@ -76,18 +84,16 @@ def test_generate_core_mask_vmmode(self): return 0 == generate_core_mask_vmmode(core_count) def test_get_pcie_address_firmware_mapping(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd", - "builtins.open", "typing.IO.readlines") + mock_functions(mocker, EXEC, OPEN, READLINES) r1, r2 = get_pcie_address_firmware_mapping() def test_get_pcie_address_serial_mapping(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd", - "builtins.open", "typing.IO.readlines") + mock_functions(mocker, EXEC, OPEN, READLINES) r = get_pcie_address_serial_mapping([]) assert len(r) > 0 def test_get_nvme_list_numa(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd") + mock_functions(mocker, EXEC) r = get_nvme_list_numa() assert len(r) > 0 @@ -96,44 +102,38 @@ def test_ip4_addresses(self, mocker): assert len(r) > 0 def test_only_mtu9k(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd") + mock_functions(mocker, EXEC) r = only_mtu9k({"ip": 100}) assert len(r) > 0 def test_get_rdma_ips(self, mocker): - r = get_rdma_ips({"nic": "1.x.x.x"}, ["1.x.x.x"]) + r = get_rdma_ips({"nic": default_mock_ip}, [default_mock_ip]) assert len(r) > 0 def test_get_numa_boundary(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd") + mock_functions(mocker, EXEC) r = get_numa_boundary() assert int(r) == 1 def test_get_numa_ip(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd", - "target.dss_target.interfaces", - "target.dss_target.ifaddresses", - "target.dss_target.AF_INET") - r1, r2 = get_numa_ip(["1.x.x.x"]) + mock_functions(mocker, EXEC, INTERFACE, + IFADDRESS, AFINET) + r1, r2 = get_numa_ip([default_mock_ip]) assert len(r1) > 0 assert len(r2) == 0 def test_create_nvmf_config_file(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd", - "target.dss_target.interfaces", - "target.dss_target.ifaddresses", - "target.dss_target.AF_INET", - "builtins.open") - r = create_nvmf_config_file("", ["1.x.x.x"], [], []) + mock_functions(mocker, EXEC, INTERFACE, + IFADDRESS, AFINET, OPEN) + r = create_nvmf_config_file("", [default_mock_ip], [], []) assert r == 0 def test_get_vlan_ips(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd") + mock_functions(mocker, EXEC) r = get_vlan_ips("1234") assert r def test_setup_hugepage(self, mocker): - mock_functions(mocker, "target.dss_target.exec_cmd", - "builtins.open") + mock_functions(mocker, EXEC, OPEN) r = setup_hugepage() assert r == 0 From f9b69b7a4408cad00f729be0793b0f6f5f01db86 Mon Sep 17 00:00:00 2001 From: "cliang01.li" Date: Sun, 24 Dec 2023 23:19:38 -0800 Subject: [PATCH 4/5] fix pycodestyle issues --- unittests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/conftest.py b/unittests/conftest.py index da734b33..ffb99f93 100644 --- a/unittests/conftest.py +++ b/unittests/conftest.py @@ -356,7 +356,7 @@ def mock_exec_cmd(cmd): elif cmd.startswith(ip_d): res = "vlanid 1234" - return 0 ,res, "" + return 0, res, "" def mock_os_dirname_host(name): From 296730da91c101287a682f011e7454817e471f3e Mon Sep 17 00:00:00 2001 From: "cliang01.li" Date: Thu, 28 Dec 2023 21:33:39 -0800 Subject: [PATCH 5/5] fix sonar cloud issue: duplicated lines --- unittests/conftest.py | 159 +++-------------------------------- unittests/pytest_config.json | 6 ++ unittests/test_dss_host.py | 4 +- 3 files changed, 19 insertions(+), 150 deletions(-) create mode 100644 unittests/pytest_config.json diff --git a/unittests/conftest.py b/unittests/conftest.py index ffb99f93..b738ee3a 100644 --- a/unittests/conftest.py +++ b/unittests/conftest.py @@ -35,126 +35,35 @@ from faker import Faker import pytest import secrets +import json +import os default_mock_ip = '1.x.x.x' +json_path = os.path.dirname(os.path.abspath(__file__)) + "/pytest_config.json" +d = {} +with open(json_path, "r") as json_file: + d = json.load(json_file) +fake = Faker() @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 + return d["nvme_devices"] @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 + return d["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 + return d["lscpu"] @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 + return d["nvme_discover"] @pytest.fixture(scope="session") @@ -170,25 +79,21 @@ def get_temp_dir(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)] @@ -262,48 +167,6 @@ def get_sample_nvme_list_subsys(): "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.x 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.x 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.x trsvcid=1024", - "State" : "live" - } - ] } ] } diff --git a/unittests/pytest_config.json b/unittests/pytest_config.json new file mode 100644 index 00000000..afa5818e --- /dev/null +++ b/unittests/pytest_config.json @@ -0,0 +1,6 @@ +{ + "lscpu":" Architecture: x86_64\n CPU op-mode(s): 32-bit, 64-bit\n Byte Order: Little Endian\n CPU(s): 88\n On-line CPU(s) list: 0-87\n Thread(s) per core: 2\n Core(s) per socket: 22\n Socket(s): 2\n NUMA node(s): 2\n Vendor ID: GenuineIntel\n CPU family: 6\n Model: 85\n Model name: Intel(R) Xeon(R) Gold 6152 CPU @ 2.10GHz\n Stepping: 4\n CPU MHz: 2543.753\n CPU max MHz: 3700.0000\n CPU min MHz: 1000.0000\n BogoMIPS: 4200.00\n Virtualization: VT-x\n L1d cache: 32K\n L1i cache: 32K\n L2 cache: 1024K\n L3 cache: 30976K\n NUMA node0 CPU(s): 0-21,44-65\n NUMA node1 CPU(s): 22-43,66-87\n 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 ", + "nvme_devices":" Node SN Model Namespace Usage Format FW Rev\n ---------------- -------------------- ------------------------------------ ---- --------- -------------------------- ---------------- --------\n /dev/nvme0n1 DSS5066419069 SPDK bdev Controller 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07\n /dev/nvme1n1 DSS2690548027 SPDK bdev Controller 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07\n /dev/nvme2n1 DSS1137172735 SPDK bdev Controller 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07\n /dev/nvme3n1 DSS7754076932 SPDK bdev Controller 1 12.58 MB / 7.65 TB 512 B + 0 B 20.07\n /dev/nvme4n1 DSS5066419069 SPDK bdev Controller 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07\n /dev/nvme5n1 DSS2690548027 SPDK bdev Controller 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07\n /dev/nvme6n1 DSS1137172735 SPDK bdev Controller 1 13.63 MB / 7.65 TB 512 B + 0 B 20.07\n /dev/nvme7n1 DSS7754076932 SPDK bdev Controller 1 12.58 MB / 7.65 TB 512 B + 0 B 20.07\n ", + "nvme_discover":" Discovery Log Number of Records 1, Generation counter 4\n =====Discovery Log Entry 0======\n trtype: rdma\n adrfam: ipv4\n subtype: nvme subsystem\n treq: not required\n portid: 0\n trsvcid: 1024\n subnqn: nqn.2023-06.io:msl-dpe-perf35-kv_data1\n traddr: x.x.x.x\n rdma_prtype: not specified\n rdma_qptype: connected\n rdma_cms: rdma-cm\n rdma_pkey: 0x0000\n ", + "nvme_subsystems":" nvme-subsys0 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data1\n +- nvme0 rdma traddr=201.x.x.xxx trsvcid=1024 live\n +- nvme4 rdma traddr=203.x.x.xxx trsvcid=1024 live\n nvme-subsys1 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data2\n +- nvme1 rdma traddr=201.x.x.xxx trsvcid=1024 live\n +- nvme5 rdma traddr=203.x.x.xxx trsvcid=1024 live\n nvme-subsys2 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data3\n +- nvme2 rdma traddr=201.x.x.xxx trsvcid=1024 live\n +- nvme6 rdma traddr=203.x.x.xxx trsvcid=1024 live\n nvme-subsys3 - NQN=nqn.2023-06.io:msl-ssg-sm1-kv_data4\n +- nvme3 rdma traddr=201.x.x.xxx trsvcid=1024 live\n +- nvme7 rdma traddr=203.x.x.xxx trsvcid=1024 live\n " +} diff --git a/unittests/test_dss_host.py b/unittests/test_dss_host.py index d8202de8..38cec04f 100644 --- a/unittests/test_dss_host.py +++ b/unittests/test_dss_host.py @@ -113,12 +113,12 @@ def test_get_ips_for_vlan(self, mocker): def test_drive_to_addr_map(self, mocker): mock_functions(mocker, EXEC) res = drive_to_addr_map() - assert len(res) == 4 + assert len(res) == 1 def test_mountpt_to_nqn_addr_map(self, mocker): mock_functions(mocker, EXEC) res = mountpt_to_nqn_addr_map() - assert len(res) == 4 + assert len(res) == 1 for dev in res.keys(): assert "nqn" in res[dev] assert "addr" in res[dev]