diff --git a/salt/tests/unit/modules/files/test_metalk8s.yaml b/salt/tests/unit/modules/files/test_metalk8s.yaml index 7e0be0fb8f..4bb1e8ac3a 100644 --- a/salt/tests/unit/modules/files/test_metalk8s.yaml +++ b/salt/tests/unit/modules/files/test_metalk8s.yaml @@ -1,144 +1,72 @@ get_archives: - - archives: "/my/path/iso" - infos: {"version": "2.5.0", "name": "MetalK8s"} - is_files: True - result: { - "metalk8s-2.5.0": { - "iso": "/my/path/iso", - "version": "2.5.0", - "name": "MetalK8s", - "path": "/srv/scality/metalk8s-2.5.0" - } - } + # 0. Ok - 1 existing ISO passed as argument + - archives: /my/path/iso + infos: &get_archives_infos_iso + version: 2.5.0 + name: MetalK8s + iso: /my/path/iso + path: /srv/scality/metalk8s-2.5.0 + result: + metalk8s-2.5.0: *get_archives_infos_iso + # 1. Ok - 1 existing ISO from pillar entries - archives: null pillar_archives: - "/my/path/iso" - infos: {"version": "2.5.0", "name": "MetalK8s"} - is_files: True - result: { - "metalk8s-2.5.0": { - "iso": "/my/path/iso", - "version": "2.5.0", - "name": "MetalK8s", - "path": "/srv/scality/metalk8s-2.5.0" - } - } + infos: *get_archives_infos_iso + result: + metalk8s-2.5.0: *get_archives_infos_iso + # 2. Ok - 1 existing directory passed as argument - archives: "/my/path" - infos: {"version": "2.5.0", "name": "MetalK8s"} - is_dirs: True - result: { - "metalk8s-2.5.0": { - "iso": null, - "version": "2.5.0", - "name": "MetalK8s", - "path": "/my/path" - } - } + infos: &get_archives_infos_dir + <<: *get_archives_infos_iso + iso: null + path: /my/path + result: + metalk8s-2.5.0: *get_archives_infos_dir + # 3. Nok - 1 ISO and 1 directory with the same version - archives: - "/my/path" - "/my/path/iso" - infos: {"version": "2.5.0", "name": "MetalK8s"} - is_dirs: - - True - - False - is_files: True - result: { - "metalk8s-2.5.0": { - "iso": "/my/path/iso", - "version": "2.5.0", - "name": "MetalK8s", - "path": "/srv/scality/metalk8s-2.5.0" - } - } + infos: + - <<: *get_archives_infos_iso + iso: null + - *get_archives_infos_iso + raises: True + result: Two archives have the same version .* + # 4. Ok - 2 ISOs with different versions - archives: - "/my/path/iso" - - "/my/path" - infos: {"version": "2.5.0", "name": "MetalK8s"} - is_dirs: - - False - - True - is_files: True - result: { - "metalk8s-2.5.0": { - "iso": null, - "version": "2.5.0", - "name": "MetalK8s", - "path": "/my/path" - } - } - - archives: - - "/my/first/iso" - "/my/second/iso" infos: - - {"version": "2.5.0", "name": "MetalK8s"} - - {"version": "2.5.1", "name": "MetalK8s"} - is_files: True - result: { - "metalk8s-2.5.0": { - "iso": "/my/first/iso", - "version": "2.5.0", - "name": "MetalK8s", - "path": "/srv/scality/metalk8s-2.5.0" - }, - "metalk8s-2.5.1": { - "iso": "/my/second/iso", - "version": "2.5.1", - "name": "MetalK8s", - "path": "/srv/scality/metalk8s-2.5.1" - } - } + - *get_archives_infos_dir + - version: 2.5.1 + name: MetalK8s + iso: /my/second/iso + path: /srv/scality/metalk8s-2.5.1 + result: + metalk8s-2.5.0: *get_archives_infos_dir + metalk8s-2.5.1: + iso: /my/second/iso + version: 2.5.1 + name: MetalK8s + path: /srv/scality/metalk8s-2.5.1 + # 5. Nok - Archive path that does not exist - archives: - - "/my/path/does/not/exists" + - "/my/path/does/not/exist" infos: null - result: {} + invalid_path: True + raises: True + result: Invalid archive path + # 6. Ok - No archives - archives: null infos: null result: {} + # 7. Nok - Invalid `archives` argument - archives: {"invalid": "archives", "style": "123"} infos: null raises: True result: "Invalid archives: list or string expected, got .*" - - archives: - - "/my/first/iso" - - "/my/first/path" - - "/my/path/does/not/exists" - - "/my/second/path" - - "/my/second/iso" - infos: - - {"version": "2.5.1", "name": "MetalK8s"} - - {"version": "2.5.0", "name": "MetalK8s"} - - {"version": "2.5.1", "name": "MetalK8s"} - - {"version": "2.5.2", "name": "MetalK8s"} - is_dirs: - - False - - True - - False - - True - - False - is_files: - - True - - False - - True - result: { - "metalk8s-2.5.0": { - "iso": null, - "version": "2.5.0", - "name": "MetalK8s", - "path": "/my/first/path" - }, - "metalk8s-2.5.1": { - "iso": null, - "version": "2.5.1", - "name": "MetalK8s", - "path": "/my/second/path" - }, - "metalk8s-2.5.2": { - "iso": "/my/second/iso", - "version": "2.5.2", - "name": "MetalK8s", - "path": "/srv/scality/metalk8s-2.5.2" - } - } + check_pillar_keys: - keys: "my-simple-key" pillar_content: { @@ -437,3 +365,63 @@ manage_static_pod_manifest: atomic_copy_raises: Could not copy! error: >- Failed to commit change: Could not copy! + +archive_info_from_product_txt: + # 0. Ok - A valid ISO archive + - archive: /my/iso + is_file: True + info: + version: 2.8.0 + name: MetalK8s + result: + version: 2.8.0 + name: MetalK8s + iso: /my/iso + path: /srv/scality/metalk8s-2.8.0 + # 1. Ok - A valid directory archive + - archive: /my/directory + is_dir: True + info: + version: 2.8.0 + name: MetalK8s + result: + version: 2.8.0 + name: MetalK8s + iso: null + path: /my/directory + # 2. Nok - Invalid path + - archive: /my/invalid + info: null + raises: True + result: Invalid archive path /my/invalid, should be an iso or a directory. + +configure_archive: + # 0. Ok - + - archive: /my/archive + config: + archives: [] + result: Archive '/my/archive' added to bootstrap configuration + # 1. Ok - + - archive: /my/archive + remove: True + config: + archives: + - /my/archive + result: Archive '/my/archive' removed from bootstrap configuration + # 2. Ok - + - archive: /my/archive + config: + archives: + - /my/archive + result: Archive '/my/archive' already present in bootstrap configuration + # 3. Ok - + - archive: /my/archive + remove: True + config: + archives: [] + result: Archive '/my/archive' already absent in bootstrap configuration + # 4. Nok - + - archive: /my/archive + invalid_path: True + raises: True + result: Invalid archive path diff --git a/salt/tests/unit/modules/test_metalk8s.py b/salt/tests/unit/modules/test_metalk8s.py index 40711f5202..3fedd9762c 100644 --- a/salt/tests/unit/modules/test_metalk8s.py +++ b/salt/tests/unit/modules/test_metalk8s.py @@ -222,42 +222,35 @@ def test_get_archives( archives, infos, result, - is_dirs=False, - is_files=False, + invalid_path=False, raises=False, - pillar_archives=None, + pillar_archives=None ): """ Tests the return of `get_archives` function """ - infos_mock = MagicMock() - is_dirs_mock = MagicMock() - is_files_mock = MagicMock() - - for mock, var in [ - (infos_mock, infos), - (is_dirs_mock, is_dirs), - (is_files_mock, is_files), - ]: - if isinstance(var, list): - mock.side_effect = var - else: - mock.return_value = var + if invalid_path: + infos_mock = MagicMock( + side_effect=CommandExecutionError("Invalid archive path") + ) + elif isinstance(infos, list): + infos_mock = MagicMock(side_effect=infos) + else: + infos_mock = MagicMock(return_value=infos) pillar_dict = {"metalk8s": {}} if pillar_archives is not None: - pillar_dict["metalk8s"]["archives"] = pillar_archives - - with patch("os.path.isdir", is_dirs_mock), patch( - "os.path.isfile", is_files_mock - ), patch("metalk8s.archive_info_from_tree", infos_mock), patch( - "metalk8s.archive_info_from_iso", infos_mock - ), patch.dict( - metalk8s.__pillar__, pillar_dict - ): + pillar_dict['metalk8s']['archives'] = pillar_archives + + with patch( + "metalk8s.archive_info_from_product_txt", infos_mock + ), patch.dict(metalk8s.__pillar__, pillar_dict): if raises: self.assertRaisesRegex( - CommandExecutionError, result, metalk8s.get_archives, archives + CommandExecutionError, + result, + metalk8s.get_archives, + archives ) else: self.assertEqual(metalk8s.get_archives(archives), result) @@ -532,3 +525,106 @@ def test_get_from_map( ), compile_template_mock.call_args[1] ) + + @utils.parameterized_from_cases( + YAML_TESTS_CASES["archive_info_from_product_txt"] + ) + def test_archive_info_from_product_txt(self, archive, info, result, + is_file=False, is_dir=False, raises=False): + info_mock = MagicMock(return_value=info) + + with patch("os.path.isdir", MagicMock(return_value=is_dir)), \ + patch("os.path.isfile", MagicMock(return_value=is_file)), \ + patch("metalk8s.archive_info_from_tree", info_mock), \ + patch("metalk8s.archive_info_from_iso", info_mock): + if raises: + self.assertRaisesRegex( + CommandExecutionError, + result, + metalk8s.archive_info_from_product_txt, + archive + ) + else: + self.assertEqual( + metalk8s.archive_info_from_product_txt(archive), + result + ) + + + @utils.parameterized_from_cases(YAML_TESTS_CASES["configure_archive"]) + def test_configure_archive(self, archive, result, remove=None, config=None, + invalid_path=False, raises=False): + """ + Tests the return of `configure_archive` function + """ + info_mock = MagicMock() + if invalid_path: + info_mock.side_effect = CommandExecutionError( + "Invalid archive path" + ) + + with patch("metalk8s.archive_info_from_product_txt", info_mock), \ + patch("metalk8s._read_bootstrap_config", MagicMock(return_value=config)), \ + patch("metalk8s._write_bootstrap_config", MagicMock()): + if raises: + self.assertRaisesRegex( + CommandExecutionError, + result, + metalk8s.configure_archive, + archive, + remove, + ) + else: + self.assertEqual( + metalk8s.configure_archive( + archive, remove=remove + ), + result + ) + + @parameterized.expand([ + param(), + param(True, "Failed to write bootstrap config file") + ]) + def test__write_bootstrap_config(self, raises=False, result=None): + open_mock = mock_open() + if raises: + open_mock.side_effect = Exception( + "A wild exception appears!" + ) + + with patch("salt.utils.files.fopen", open_mock): + if raises: + self.assertRaisesRegex( + CommandExecutionError, + result, + metalk8s._write_bootstrap_config, + None + ) + else: + self.assertEqual( + metalk8s._write_bootstrap_config(None), + None, + ) + + @parameterized.expand([ + param(), + param(True, "Failed to load bootstrap config file") + ]) + def test__read_bootstrap_config(self, raises=False, result=None): + open_mock = mock_open(read_data="config") + if raises: + open_mock.side_effect = IOError("Weird I/O error!") + + with patch("salt.utils.files.fopen", open_mock): + if raises: + self.assertRaisesRegex( + CommandExecutionError, + result, + metalk8s._read_bootstrap_config, + ) + else: + self.assertEqual( + metalk8s._read_bootstrap_config(), + "config", + )