# Copyright (c) Ansible project # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later from __future__ import annotations from unittest.mock import Mock, mock_open, patch from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( ModuleTestCase, set_module_args, ) from ansible_collections.community.general.plugins.modules.modprobe import Modprobe, build_module class TestLoadModule(ModuleTestCase): def setUp(self): super().setUp() self.mock_module_loaded = patch( "ansible_collections.community.general.plugins.modules.modprobe.Modprobe.module_loaded" ) self.mock_run_command = patch("ansible.module_utils.basic.AnsibleModule.run_command") self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.module_loaded = self.mock_module_loaded.start() self.run_command = self.mock_run_command.start() self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_module_loaded.stop() self.mock_run_command.stop() self.mock_get_bin_path.stop() def test_load_module_success(self): with set_module_args( dict( name="test", state="present", ) ): module = build_module() self.get_bin_path.side_effect = ["modprobe"] self.module_loaded.side_effect = [True] self.run_command.side_effect = [(0, "", "")] modprobe = Modprobe(module) modprobe.load_module() assert modprobe.result == { "changed": True, "name": "test", "params": "", "state": "present", } def test_load_module_unchanged(self): with set_module_args( dict( name="test", state="present", ) ): module = build_module() module.warn = Mock() self.get_bin_path.side_effect = ["modprobe"] self.module_loaded.side_effect = [False] self.run_command.side_effect = [(0, "", ""), (1, "", "")] modprobe = Modprobe(module) modprobe.load_module() module.warn.assert_called_once_with("") class TestUnloadModule(ModuleTestCase): def setUp(self): super().setUp() self.mock_module_loaded = patch( "ansible_collections.community.general.plugins.modules.modprobe.Modprobe.module_loaded" ) self.mock_run_command = patch("ansible.module_utils.basic.AnsibleModule.run_command") self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.module_loaded = self.mock_module_loaded.start() self.run_command = self.mock_run_command.start() self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_module_loaded.stop() self.mock_run_command.stop() self.mock_get_bin_path.stop() def test_unload_module_success(self): with set_module_args( dict( name="test", state="absent", ) ): module = build_module() self.get_bin_path.side_effect = ["modprobe"] self.module_loaded.side_effect = [False] self.run_command.side_effect = [(0, "", "")] modprobe = Modprobe(module) modprobe.unload_module() assert modprobe.result == { "changed": True, "name": "test", "params": "", "state": "absent", } def test_unload_module_failure(self): with set_module_args( dict( name="test", state="absent", ) ): module = build_module() module.fail_json = Mock() self.get_bin_path.side_effect = ["modprobe"] self.module_loaded.side_effect = [True] self.run_command.side_effect = [(1, "", "")] modprobe = Modprobe(module) modprobe.unload_module() dummy_result = { "changed": False, "name": "test", "state": "absent", "params": "", } module.fail_json.assert_called_once_with(msg="", rc=1, stdout="", stderr="", **dummy_result) class TestModuleIsLoadedPersistently(ModuleTestCase): def setUp(self): super().setUp() self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_get_bin_path.stop() def test_module_is_loaded(self): with set_module_args(dict(name="dummy", state="present", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open(read_data="dummy") ) as mocked_file: with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modules_files"): modprobe.modules_files = ["/etc/modules-load.d/dummy.conf"] assert modprobe.module_is_loaded_persistently mocked_file.assert_called_once_with("/etc/modules-load.d/dummy.conf") def test_module_is_not_loaded_empty_file(self): with set_module_args(dict(name="dummy", state="present", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open(read_data="") ) as mocked_file: with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modules_files"): modprobe.modules_files = ["/etc/modules-load.d/dummy.conf"] assert not modprobe.module_is_loaded_persistently mocked_file.assert_called_once_with("/etc/modules-load.d/dummy.conf") def test_module_is_not_loaded_no_files(self): with set_module_args(dict(name="dummy", state="present", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modules_files"): modprobe.modules_files = [] assert not modprobe.module_is_loaded_persistently class TestPermanentParams(ModuleTestCase): def setUp(self): super().setUp() self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_get_bin_path.stop() def test_module_permanent_params_exist(self): files_content = [ "options dummy numdummies=4\noptions dummy dummy_parameter1=6", "options dummy dummy_parameter2=5 #Comment\noptions notdummy notdummy_param=5", ] mock_files_content = [mock_open(read_data=content).return_value for content in files_content] with set_module_args(dict(name="dummy", state="present", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open() ) as mocked_file: mocked_file.side_effect = mock_files_content with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modprobe_files"): modprobe.modprobe_files = ["/etc/modprobe.d/dummy1.conf", "/etc/modprobe.d/dummy2.conf"] assert modprobe.permanent_params == {"numdummies=4", "dummy_parameter1=6", "dummy_parameter2=5"} def test_module_permanent_params_empty(self): files_content = ["", ""] mock_files_content = [mock_open(read_data=content).return_value for content in files_content] with set_module_args(dict(name="dummy", state="present", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open(read_data="") ) as mocked_file: mocked_file.side_effect = mock_files_content with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modprobe_files"): modprobe.modprobe_files = ["/etc/modprobe.d/dummy1.conf", "/etc/modprobe.d/dummy2.conf"] assert modprobe.permanent_params == set() class TestCreateModuleFIle(ModuleTestCase): def setUp(self): super().setUp() self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_get_bin_path.stop() def test_create_file(self): with set_module_args(dict(name="dummy", state="present", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open() ) as mocked_file: modprobe.create_module_file() mocked_file.assert_called_once_with("/etc/modules-load.d/dummy.conf", "w") mocked_file().write.assert_called_once_with("dummy\n") class TestCreateModuleOptionsFIle(ModuleTestCase): def setUp(self): super().setUp() self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_get_bin_path.stop() def test_create_file(self): with set_module_args(dict(name="dummy", state="present", params="numdummies=4", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open() ) as mocked_file: modprobe.create_module_options_file() mocked_file.assert_called_once_with("/etc/modprobe.d/dummy.conf", "w") mocked_file().write.assert_called_once_with("options dummy numdummies=4\n") class TestDisableOldParams(ModuleTestCase): def setUp(self): super().setUp() self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_get_bin_path.stop() def test_disable_old_params_file_changed(self): mock_data = "options dummy numdummies=4" with set_module_args(dict(name="dummy", state="present", params="numdummies=4", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open(read_data=mock_data) ) as mocked_file: with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modprobe_files"): modprobe.modprobe_files = ["/etc/modprobe.d/dummy1.conf"] modprobe.disable_old_params() mocked_file.assert_called_with("/etc/modprobe.d/dummy1.conf", "w") mocked_file().write.assert_called_once_with("#options dummy numdummies=4") def test_disable_old_params_file_unchanged(self): mock_data = "options notdummy numdummies=4" with set_module_args(dict(name="dummy", state="present", params="numdummies=4", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open(read_data=mock_data) ) as mocked_file: with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modprobe_files"): modprobe.modprobe_files = ["/etc/modprobe.d/dummy1.conf"] modprobe.disable_old_params() mocked_file.assert_called_once_with("/etc/modprobe.d/dummy1.conf") class TestDisableModulePermanent(ModuleTestCase): def setUp(self): super().setUp() self.mock_get_bin_path = patch("ansible.module_utils.basic.AnsibleModule.get_bin_path") self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super().tearDown() self.mock_get_bin_path.stop() def test_disable_module_permanent_file_changed(self): with set_module_args(dict(name="dummy", state="present", params="numdummies=4", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open(read_data="dummy") ) as mocked_file: with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modules_files"): modprobe.modules_files = ["/etc/modules-load.d/dummy.conf"] modprobe.disable_module_permanent() mocked_file.assert_called_with("/etc/modules-load.d/dummy.conf", "w") mocked_file().write.assert_called_once_with("#dummy") def test_disable_module_permanent_file_unchanged(self): with set_module_args(dict(name="dummy", state="present", params="numdummies=4", persistent="present")): module = build_module() self.get_bin_path.side_effect = ["modprobe"] modprobe = Modprobe(module) with patch( "ansible_collections.community.general.plugins.modules.modprobe.open", mock_open(read_data="notdummy") ) as mocked_file: with patch("ansible_collections.community.general.plugins.modules.modprobe.Modprobe.modules_files"): modprobe.modules_files = ["/etc/modules-load.d/dummy.conf"] modprobe.disable_module_permanent() mocked_file.assert_called_once_with("/etc/modules-load.d/dummy.conf")