From 153c97966286964f0c3729e6281063321668f1f6 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Thu, 30 May 2024 09:23:18 -0700 Subject: [PATCH] test: Cleanup facts/network/* tests (#83256) Signed-off-by: Abhijeet Kasurde --- .../module_utils/facts/network/test_fc_wwn.py | 68 +++--- .../facts/network/test_generic_bsd.py | 206 +++++++++--------- .../facts/network/test_iscsi_get_initiator.py | 44 ++-- .../network/test_locally_reachable_ips.py | 63 ++---- 4 files changed, 186 insertions(+), 195 deletions(-) diff --git a/test/units/module_utils/facts/network/test_fc_wwn.py b/test/units/module_utils/facts/network/test_fc_wwn.py index 3f4bd9a96b8..ec22c19bbd2 100644 --- a/test/units/module_utils/facts/network/test_fc_wwn.py +++ b/test/units/module_utils/facts/network/test_fc_wwn.py @@ -5,7 +5,7 @@ from __future__ import annotations from ansible.module_utils.facts.network import fc_wwn -from unittest.mock import Mock +import pytest # AIX lsdev @@ -100,31 +100,45 @@ def mock_get_bin_path(cmd, required=False, opt_dirs=None, warning=None): return cmds.get(cmd, None) -def mock_run_command(cmd): - rc = 0 - COMMANDS = { - '/usr/sbin/lsdev': LSDEV_OUTPUT, - '/usr/sbin/lscfg': LSCFG_OUTPUT, - '/usr/sbin/fcinfo': FCINFO_OUTPUT, - '/usr/bin/ioscan': IOSCAN_OUT, - '/opt/fcms/bin/fcmsutil': FCMSUTIL_OUT, - } - result = COMMANDS.get(cmd.split()[0]) - if result is None: - rc = 1 - result = 'Error' - return (rc, result, '') - - -def test_get_fc_wwn_info(mocker): - module = Mock() +@pytest.mark.parametrize( + ("test_input", "expected"), + [ + pytest.param( + { + "platform": "aix6", + "mock_run_command": [(0, LSDEV_OUTPUT, ""), (0, LSCFG_OUTPUT, "")], + }, + ["10000090FA551508"], + id="aix6", + ), + pytest.param( + { + "platform": "sunos5", + "mock_run_command": [ + (0, FCINFO_OUTPUT, ""), + ], + }, + ["10000090fa1658de"], + id="sunos5", + ), + pytest.param( + { + "platform": "hp-ux11", + "mock_run_command": [(0, IOSCAN_OUT, ""), (0, FCMSUTIL_OUT, "")], + }, + ["0x50060b00006975ec"], + id="hp-ux11", + ), + ], +) +def test_get_fc_wwn_info(mocker, test_input, expected): + module = mocker.MagicMock() inst = fc_wwn.FcWwnInitiatorFactCollector() - mocker.patch.object(module, 'get_bin_path', side_effect=mock_get_bin_path) - mocker.patch.object(module, 'run_command', side_effect=mock_run_command) - - d = {'aix6': ['10000090FA551508'], 'sunos5': ['10000090fa1658de'], 'hp-ux11': ['0x50060b00006975ec']} - for key, value in d.items(): - mocker.patch('sys.platform', key) - wwn_expected = {"fibre_channel_wwn": value} - assert wwn_expected == inst.collect(module=module) + mocker.patch("sys.platform", test_input["platform"]) + mocker.patch.object(module, "get_bin_path", side_effect=mock_get_bin_path) + mocker.patch.object( + module, "run_command", side_effect=test_input["mock_run_command"] + ) + wwn_expected = {"fibre_channel_wwn": expected} + assert wwn_expected == inst.collect(module=module) diff --git a/test/units/module_utils/facts/network/test_generic_bsd.py b/test/units/module_utils/facts/network/test_generic_bsd.py index ee104c38e5e..c66b00cc56d 100644 --- a/test/units/module_utils/facts/network/test_generic_bsd.py +++ b/test/units/module_utils/facts/network/test_generic_bsd.py @@ -1,28 +1,15 @@ # -*- coding: utf-8 -*- -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . -# +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import annotations -from unittest.mock import Mock -import unittest +import pytest from ansible.module_utils.facts.network import generic_bsd -def get_bin_path(command, warning=None): +def mock_get_bin_path(command, warning=None): cmds = { 'ifconfig': 'fake/ifconfig', 'route': 'fake/route', @@ -30,7 +17,7 @@ def get_bin_path(command, warning=None): return cmds.get(command, None) -netbsd_ifconfig_a_out_7_1 = r''' +NETBSD_IFCONFIG_A_OUT_7_1 = r''' lo0: flags=8049 mtu 33624 inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 @@ -48,7 +35,7 @@ re0: flags=8843 mtu 1500 inet6 fe80::5054:ff:fe63:55af%re0 prefixlen 64 scopeid 0x2 ''' -netbsd_ifconfig_a_out_post_7_1 = r''' +NETBSD_IFCONFIG_A_OUT_POST_7_1 = r''' lo0: flags=0x8049 mtu 33624 inet 127.0.0.1/8 flags 0x0 inet6 ::1/128 flags 0x20 @@ -101,84 +88,81 @@ NETBSD_EXPECTED = {'all_ipv4_addresses': ['192.168.122.205'], 'type': 'ether'}} -def run_command_old_ifconfig(command): - if command == 'fake/route': - return 0, 'Foo', '' - if command == ['fake/ifconfig', '-a']: - return 0, netbsd_ifconfig_a_out_7_1, '' - return 1, '', '' - - -def run_command_post_7_1_ifconfig(command): - if command == 'fake/route': - return 0, 'Foo', '' - if command == ['fake/ifconfig', '-a']: - return 0, netbsd_ifconfig_a_out_post_7_1, '' - return 1, '', '' - - -class TestGenericBsdNetworkNetBSD(unittest.TestCase): - gather_subset = ['all'] - - def setUp(self): - self.maxDiff = None - self.longMessage = True - - # TODO: extract module run_command/get_bin_path usage to methods I can mock without mocking all of run_command - def test(self): - module = self._mock_module() - module.get_bin_path.side_effect = get_bin_path - module.run_command.side_effect = run_command_old_ifconfig - - bsd_net = generic_bsd.GenericBsdIfconfigNetwork(module) - - res = bsd_net.populate() - self.assertDictEqual(res, NETBSD_EXPECTED) - - def test_ifconfig_post_7_1(self): - module = self._mock_module() - module.get_bin_path.side_effect = get_bin_path - module.run_command.side_effect = run_command_post_7_1_ifconfig - - bsd_net = generic_bsd.GenericBsdIfconfigNetwork(module) - - res = bsd_net.populate() - self.assertDictEqual(res, NETBSD_EXPECTED) - - def test_netbsd_ifconfig_old_and_new(self): - module_new = self._mock_module() - module_new.get_bin_path.side_effect = get_bin_path - module_new.run_command.side_effect = run_command_post_7_1_ifconfig - - bsd_net_new = generic_bsd.GenericBsdIfconfigNetwork(module_new) - res_new = bsd_net_new.populate() - - module_old = self._mock_module() - module_old.get_bin_path.side_effect = get_bin_path - module_old.run_command.side_effect = run_command_old_ifconfig - - bsd_net_old = generic_bsd.GenericBsdIfconfigNetwork(module_old) - res_old = bsd_net_old.populate() - - self.assertDictEqual(res_old, res_new) - self.assertDictEqual(res_old, NETBSD_EXPECTED) - self.assertDictEqual(res_new, NETBSD_EXPECTED) - - def _mock_module(self): - mock_module = Mock() - mock_module.params = {'gather_subset': self.gather_subset, - 'gather_timeout': 5, - 'filter': '*'} - mock_module.get_bin_path = Mock(return_value=None) - return mock_module - - def test_ensure_correct_netmask_parsing(self): - n = generic_bsd.GenericBsdIfconfigNetwork(None) - lines = [ - 'inet 192.168.7.113 netmask 0xffffff00 broadcast 192.168.7.255', - 'inet 10.109.188.206 --> 10.109.188.206 netmask 0xffffe000', - ] - expected = [ +@pytest.mark.parametrize( + ("test_input", "expected"), + [ + pytest.param( + { + "mock_run_command": [ + (0, "Foo", ""), + (0, "Foo", ""), + (0, NETBSD_IFCONFIG_A_OUT_7_1, ""), + ], + }, + NETBSD_EXPECTED, + id="old-ifconfig", + ), + pytest.param( + { + "mock_run_command": [ + (0, "Foo", ""), + (0, "Foo", ""), + (0, NETBSD_IFCONFIG_A_OUT_POST_7_1, ""), + ], + }, + NETBSD_EXPECTED, + id="post-7-1-ifconfig", + ), + ], +) +def test_generic_bsd_ifconfig(mocker, test_input, expected): + module = mocker.MagicMock() + mocker.patch.object(module, "get_bin_path", side_effect=mock_get_bin_path) + mocker.patch.object( + module, "run_command", side_effect=test_input["mock_run_command"] + ) + + bsd_net = generic_bsd.GenericBsdIfconfigNetwork(module) + res = bsd_net.populate() + assert res == expected + + +def test_compare_old_new_ifconfig(mocker): + old_ifconfig_module = mocker.MagicMock() + mocker.patch.object(old_ifconfig_module, "get_bin_path", side_effect=mock_get_bin_path) + mocker.patch.object( + old_ifconfig_module, + "run_command", + side_effect=[ + (0, "Foo", ""), + (0, "Foo", ""), + (0, NETBSD_IFCONFIG_A_OUT_7_1, ""), + ], + ) + old_bsd_net = generic_bsd.GenericBsdIfconfigNetwork(old_ifconfig_module) + old_res = old_bsd_net.populate() + + new_ifconfig_module = mocker.MagicMock() + mocker.patch.object(new_ifconfig_module, "get_bin_path", side_effect=mock_get_bin_path) + mocker.patch.object( + new_ifconfig_module, + "run_command", + side_effect=[ + (0, "Foo", ""), + (0, "Foo", ""), + (0, NETBSD_IFCONFIG_A_OUT_POST_7_1, ""), + ], + ) + new_bsd_net = generic_bsd.GenericBsdIfconfigNetwork(new_ifconfig_module) + new_res = new_bsd_net.populate() + assert old_res == new_res + + +@pytest.mark.parametrize( + ("test_input", "expected"), + [ + pytest.param( + "inet 192.168.7.113 netmask 0xffffff00 broadcast 192.168.7.255", ( { 'ipv4': [ @@ -186,12 +170,16 @@ class TestGenericBsdNetworkNetBSD(unittest.TestCase): 'address': '192.168.7.113', 'netmask': '255.255.255.0', 'network': '192.168.7.0', - 'broadcast': '192.168.7.255' + 'broadcast': '192.168.7.255', } ] }, {'all_ipv4_addresses': ['192.168.7.113']}, ), + id="ifconfig-output-1", + ), + pytest.param( + "inet 10.109.188.206 --> 10.109.188.206 netmask 0xffffe000", ( { 'ipv4': [ @@ -199,17 +187,21 @@ class TestGenericBsdNetworkNetBSD(unittest.TestCase): 'address': '10.109.188.206', 'netmask': '255.255.224.0', 'network': '10.109.160.0', - 'broadcast': '10.109.191.255' + 'broadcast': '10.109.191.255', } ] }, {'all_ipv4_addresses': ['10.109.188.206']}, ), - ] - for i, line in enumerate(lines): - words = line.split() - current_if = {'ipv4': []} - ips = {'all_ipv4_addresses': []} - n.parse_inet_line(words, current_if, ips) - self.assertDictEqual(current_if, expected[i][0]) - self.assertDictEqual(ips, expected[i][1]) + id="ifconfig-output-2", + ), + ], +) +def test_ensure_correct_netmask_parsing(test_input, expected): + n = generic_bsd.GenericBsdIfconfigNetwork(None) + words = test_input.split() + current_if = {"ipv4": []} + ips = {"all_ipv4_addresses": []} + n.parse_inet_line(words, current_if, ips) + assert current_if == expected[0] + assert ips == expected[1] diff --git a/test/units/module_utils/facts/network/test_iscsi_get_initiator.py b/test/units/module_utils/facts/network/test_iscsi_get_initiator.py index 16ec7d95171..f45befa662d 100644 --- a/test/units/module_utils/facts/network/test_iscsi_get_initiator.py +++ b/test/units/module_utils/facts/network/test_iscsi_get_initiator.py @@ -5,7 +5,7 @@ from __future__ import annotations from ansible.module_utils.facts.network import iscsi -from unittest.mock import Mock +import pytest # AIX # lsattr -E -l iscsi0 @@ -36,18 +36,34 @@ SLP Scope list for iSLPD : """ -def test_get_iscsi_info(mocker): - module = Mock() +@pytest.mark.parametrize( + ("test_input", "expected"), + [ + pytest.param( + { + "platform": "aix6", + "iscsi_path": "/usr/sbin/lsattr", + "return_command": LSATTR_OUTPUT + }, + {"iscsi_iqn": "iqn.localhost.hostid.7f000002"}, + id="aix", + ), + pytest.param( + { + "platform": "hp-ux", + "iscsi_path": "/opt/iscsi/bin/iscsiutil", + "return_command": ISCSIUTIL_OUTPUT + }, + {"iscsi_iqn": " iqn.2001-04.com.hp.stor:svcio"}, + id="hpux", + ) + ] +) +def test_get_iscsi_info(mocker, test_input, expected): + module = mocker.MagicMock() inst = iscsi.IscsiInitiatorNetworkCollector() - mocker.patch('sys.platform', 'aix6') - mocker.patch.object(module, 'get_bin_path', return_value='/usr/sbin/lsattr') - mocker.patch.object(module, 'run_command', return_value=(0, LSATTR_OUTPUT, '')) - aix_iscsi_expected = {"iscsi_iqn": "iqn.localhost.hostid.7f000002"} - assert aix_iscsi_expected == inst.collect(module=module) - - mocker.patch('sys.platform', 'hp-ux') - mocker.patch.object(module, 'get_bin_path', return_value='/opt/iscsi/bin/iscsiutil') - mocker.patch.object(module, 'run_command', return_value=(0, ISCSIUTIL_OUTPUT, '')) - hpux_iscsi_expected = {"iscsi_iqn": " iqn.2001-04.com.hp.stor:svcio"} - assert hpux_iscsi_expected == inst.collect(module=module) + mocker.patch('sys.platform', test_input['platform']) + mocker.patch.object(module, 'get_bin_path', return_value=test_input['iscsi_path']) + mocker.patch.object(module, 'run_command', return_value=(0, test_input['return_command'], '')) + assert expected == inst.collect(module=module) diff --git a/test/units/module_utils/facts/network/test_locally_reachable_ips.py b/test/units/module_utils/facts/network/test_locally_reachable_ips.py index 4c3643ae23f..4e25278b0bf 100644 --- a/test/units/module_utils/facts/network/test_locally_reachable_ips.py +++ b/test/units/module_utils/facts/network/test_locally_reachable_ips.py @@ -1,25 +1,8 @@ -# This file is part of Ansible -# -*- coding: utf-8 -*- -# -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . -# +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import annotations -from unittest.mock import Mock -import unittest from ansible.module_utils.facts.network import linux # ip -4 route show table local @@ -58,34 +41,20 @@ IP_ROUTE_SHOW_LOCAL_EXPECTED = { } -class TestLocalRoutesLinux(unittest.TestCase): - gather_subset = ['all'] +def mock_get_bin_path(command): + cmds = {"ip": "fake/ip"} + return cmds.get(command, None) - def get_bin_path(self, command): - if command == 'ip': - return 'fake/ip' - return None - def run_command(self, command): - if command == ['fake/ip', '-4', 'route', 'show', 'table', 'local']: - return 0, IP4_ROUTE_SHOW_LOCAL, '' - if command == ['fake/ip', '-6', 'route', 'show', 'table', 'local']: - return 0, IP6_ROUTE_SHOW_LOCAL, '' - return 1, '', '' +def test_linux_local_routes(mocker): + module = mocker.MagicMock() + mocker.patch.object(module, "get_bin_path", side_effect=mock_get_bin_path) + mocker.patch.object( + module, + "run_command", + side_effect=[(0, IP4_ROUTE_SHOW_LOCAL, ""), (0, IP6_ROUTE_SHOW_LOCAL, "")], + ) - def test(self): - module = self._mock_module() - module.get_bin_path.side_effect = self.get_bin_path - module.run_command.side_effect = self.run_command - - net = linux.LinuxNetwork(module) - res = net.get_locally_reachable_ips('fake/ip') - self.assertDictEqual(res, IP_ROUTE_SHOW_LOCAL_EXPECTED) - - def _mock_module(self): - mock_module = Mock() - mock_module.params = {'gather_subset': self.gather_subset, - 'gather_timeout': 5, - 'filter': '*'} - mock_module.get_bin_path = Mock(return_value=None) - return mock_module + net = linux.LinuxNetwork(module) + res = net.get_locally_reachable_ips(mock_get_bin_path("ip")) + assert res == IP_ROUTE_SHOW_LOCAL_EXPECTED