# -*- coding: utf-8 -*- # Copyright (c) Contributors to the 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 absolute_import, division, print_function __metaclass__ = type from ansible_collections.community.general.plugins.modules import lvg_rename from ansible_collections.community.general.tests.unit.compat.mock import patch from ansible_collections.community.general.tests.unit.plugins.modules.utils import ( AnsibleFailJson, AnsibleExitJson, ModuleTestCase, set_module_args) VGS_OUTPUT = '''\ vg_data_testhost1;XKZ5gn-YhWY-NlrT-QCFN-qmMG-VGT9-7uOmex vg_sys_testhost2;xgy2SJ-YlYd-fde2-e3oG-zdXL-0xGf-ihqG2H ''' class TestLvgRename(ModuleTestCase): """Tests for lvg_rename internals""" module = lvg_rename module_path = 'ansible_collections.community.general.plugins.modules.lvg_rename' def setUp(self): """Prepare mocks for module testing""" super(TestLvgRename, self).setUp() self.mock_run_responses = {} patched_module_get_bin_path = patch('%s.AnsibleModule.get_bin_path' % (self.module_path)) self.mock_module_get_bin_path = patched_module_get_bin_path.start() self.mock_module_get_bin_path.return_value = '/mocpath' self.addCleanup(patched_module_get_bin_path.stop) patched_module_run_command = patch('%s.AnsibleModule.run_command' % (self.module_path)) self.mock_module_run_command = patched_module_run_command.start() self.addCleanup(patched_module_run_command.stop) def test_vg_not_found_by_name(self): """When the VG by the specified by vg name not found, the module should exit with error""" failed = True self.mock_module_run_command.side_effect = [(0, VGS_OUTPUT, '')] expected_msg = 'Both current (vg_missing) and new (vg_data_testhost2) VG are missing.' module_args = { 'vg': 'vg_missing', 'vg_new': 'vg_data_testhost2', } set_module_args(args=module_args) with self.assertRaises(AnsibleFailJson) as result: self.module.main() self.assertEqual(len(self.mock_module_run_command.mock_calls), 1) self.assertIs(result.exception.args[0]['failed'], failed) self.assertEqual(result.exception.args[0]['msg'], expected_msg) def test_vg_not_found_by_uuid(self): """When the VG by the specified vg UUID not found, the module should exit with error""" failed = True self.mock_module_run_command.side_effect = [(0, VGS_OUTPUT, '')] expected_msg = 'Both current (Yfj4YG-c8nI-z7w5-B7Fw-i2eM-HqlF-ApFVp0) and new (vg_data_testhost2) VG are missing.' module_args = { 'vg': 'Yfj4YG-c8nI-z7w5-B7Fw-i2eM-HqlF-ApFVp0', 'vg_new': 'vg_data_testhost2', } set_module_args(args=module_args) with self.assertRaises(AnsibleFailJson) as result: self.module.main() self.assertEqual(len(self.mock_module_run_command.mock_calls), 1) self.assertIs(result.exception.args[0]['failed'], failed) self.assertEqual(result.exception.args[0]['msg'], expected_msg) def test_vg_and_vg_new_both_exists(self): """When a VG found for both vg and vg_new options, the module should exit with error""" failed = True self.mock_module_run_command.side_effect = [(0, VGS_OUTPUT, '')] expected_msg = 'The new VG name (vg_sys_testhost2) is already in use.' module_args = { 'vg': 'vg_data_testhost1', 'vg_new': 'vg_sys_testhost2', } set_module_args(args=module_args) with self.assertRaises(AnsibleFailJson) as result: self.module.main() self.assertEqual(len(self.mock_module_run_command.mock_calls), 1) self.assertIs(result.exception.args[0]['failed'], failed) self.assertEqual(result.exception.args[0]['msg'], expected_msg) def test_vg_needs_renaming(self): """When the VG found for vg option and there is no VG for vg_new option, the module should call vgrename""" changed = True self.mock_module_run_command.side_effect = [ (0, VGS_OUTPUT, ''), (0, ' Volume group "vg_data_testhost1" successfully renamed to "vg_data_testhost2"', '') ] expected_msg = ' Volume group "vg_data_testhost1" successfully renamed to "vg_data_testhost2"' module_args = { 'vg': '/dev/vg_data_testhost1', 'vg_new': 'vg_data_testhost2', } set_module_args(args=module_args) with self.assertRaises(AnsibleExitJson) as result: self.module.main() self.assertEqual(len(self.mock_module_run_command.mock_calls), 2) self.assertIs(result.exception.args[0]['changed'], changed) self.assertEqual(result.exception.args[0]['msg'], expected_msg) def test_vg_needs_renaming_in_check_mode(self): """When running in check mode and the VG found for vg option and there is no VG for vg_new option, the module should not call vgrename""" changed = True self.mock_module_run_command.side_effect = [(0, VGS_OUTPUT, '')] expected_msg = 'Running in check mode. The module would rename VG /dev/vg_data_testhost1 to vg_data_testhost2.' module_args = { 'vg': '/dev/vg_data_testhost1', 'vg_new': 'vg_data_testhost2', '_ansible_check_mode': True, } set_module_args(args=module_args) with self.assertRaises(AnsibleExitJson) as result: self.module.main() self.assertEqual(len(self.mock_module_run_command.mock_calls), 1) self.assertIs(result.exception.args[0]['changed'], changed) self.assertEqual(result.exception.args[0]['msg'], expected_msg) def test_vg_needs_no_renaming(self): """When the VG not found for vg option and the VG found for vg_new option, the module should not call vgrename""" changed = False self.mock_module_run_command.side_effect = [(0, VGS_OUTPUT, '')] expected_msg = 'The new VG (vg_data_testhost1) already exists, nothing to do.' module_args = { 'vg': 'vg_data_testhostX', 'vg_new': 'vg_data_testhost1', } set_module_args(args=module_args) with self.assertRaises(AnsibleExitJson) as result: self.module.main() self.assertEqual(len(self.mock_module_run_command.mock_calls), 1) self.assertIs(result.exception.args[0]['changed'], changed) self.assertEqual(result.exception.args[0]['msg'], expected_msg)