diff --git a/cyber_sandbox_creator/creator.py b/cyber_sandbox_creator/creator.py index 182234fc80c0d85be856167136bc8f63bd9ed736..b7c6633b33f9d5195d70ef5712922c420e301309 100644 --- a/cyber_sandbox_creator/creator.py +++ b/cyber_sandbox_creator/creator.py @@ -1,4 +1,3 @@ -import os from pathlib import Path from typing import Union, Optional @@ -8,13 +7,12 @@ from cyber_sandbox_creator.ansible_generator.preconfig import Preconfig from cyber_sandbox_creator.ansible_generator.provisioning import Provision CSC_PATH: Path = Path(__file__).parent.resolve() -CONFIGURATION_PATH: Path = CSC_PATH / "conf/configuration.yml" -FLAVORS_PATH: Path = CSC_PATH / "conf/flavors.yml" +CONFIGURATION_PATH: Path = CSC_PATH.joinpath("conf/configuration.yml") +FLAVORS_PATH: Path = CSC_PATH.joinpath("conf/flavors.yml") def _process_topology_path(topology: Union[str, Path]) -> Path: """Validate and resolve topology path""" - print(Path("test").resolve()) try: if isinstance(topology, str): topology_path: Path = Path(topology).resolve() @@ -24,7 +22,7 @@ def _process_topology_path(topology: Union[str, Path]) -> Path: raise TypeError("Topology definition file path has invalid type " f"\"{type(topology)}\"") if not topology_path.is_file(): - raise IOError(f"File \"{topology_path}\" does not exist") + raise OSError(f"File \"{topology_path}\" does not exist") except OSError: raise ValueError(f"Invalid path to topology file \"{topology}\"") @@ -35,8 +33,8 @@ def _process_output_path(output_dir: Optional[Union[str, Path]], topology_path: Path) -> Path: """Validate and resolve output directory path""" try: - if output_dir is None or not output_dir: - sandbox_path: Path = topology_path.parent / "sandbox" + if output_dir is None or output_dir == "": + sandbox_path: Path = topology_path.parent.joinpath("sandbox") elif isinstance(output_dir, str): sandbox_path: Path = Path(output_dir).resolve() elif isinstance(output_dir, Path): @@ -44,33 +42,33 @@ def _process_output_path(output_dir: Optional[Union[str, Path]], else: raise TypeError("Output directory path has invalid type " f"\"{type(output_dir)}\"") + if sandbox_path.is_file(): + raise OSError(f"\"{sandbox_path}\" is a file") except OSError: raise ValueError(f"Invalid output directory \"{output_dir}\"") return sandbox_path -def _process_provisioning_path(provisioning_dir: Optional[Union[str, Path]], - output_path: Path) -> Optional[Path]: +def _process_provisioning_path(provisioning_dir: Optional[Union[str, Path]]) \ + -> Optional[Path]: """Validate and resolve user provisioning directory path""" try: - if provisioning_dir is None or not provisioning_dir: - provisioning_path = None - elif isinstance(provisioning_dir, str): + if provisioning_dir is None or provisioning_dir == "": + return None + if isinstance(provisioning_dir, str): provisioning_path: Path = Path(provisioning_dir).resolve() elif isinstance(provisioning_dir, Path): provisioning_path: Path = provisioning_dir.resolve() else: raise TypeError("Provisioning directory path has invalid type " - f"\"{type(output_path)}\"") - if provisioning_path is not None: - if not provisioning_path.is_dir(): - raise IOError(f"Directory \"{provisioning_path}\" does not " - "exist") - playbook_path: Path = provisioning_path / "playbook.yml" - if not playbook_path.is_file(): - raise IOError("Provisioning directory should contain " - "\"playbook.yml\"") + f"\"{type(provisioning_dir)}\"") + if not provisioning_path.is_dir(): + raise ValueError(f"Directory \"{provisioning_path}\" does not exist") + playbook_path: Path = provisioning_path.joinpath("playbook.yml") + if not playbook_path.is_file(): + raise ValueError("Provisioning directory should contain " + "\"playbook.yml\"") except OSError: raise ValueError("Invalid path to provisioning directory " f"\"{provisioning_dir}\"") @@ -78,21 +76,21 @@ def _process_provisioning_path(provisioning_dir: Optional[Union[str, Path]], return provisioning_path -def _process_extra_vars_path(extra_vars: Optional[Union[str, Path]], - output_path: Path) -> Optional[Path]: +def _process_extra_vars_path(extra_vars: Optional[Union[str, Path]]) -> \ + Optional[Path]: """Validate and resolve path to Ansible extra vars file""" try: - if extra_vars is None or not extra_vars: - extra_vars_path = None - elif isinstance(extra_vars, str): + if extra_vars is None or extra_vars == "": + return None + if isinstance(extra_vars, str): extra_vars_path: Path = Path(extra_vars).resolve() elif isinstance(extra_vars, Path): extra_vars_path: Path = extra_vars.resolve() else: raise TypeError("Extra vars file path has invalid type " - f"\"{type(output_path)}\"") + f"\"{type(extra_vars)}\"") if extra_vars_path is not None and not extra_vars_path.is_file(): - raise IOError(f"File \"{extra_vars_path}\" does not exist") + raise OSError(f"File \"{extra_vars_path}\" does not exist") except OSError: raise ValueError("Invalid path to extra variables file " f"\"{extra_vars}\"") @@ -148,9 +146,8 @@ def create(topology: Union[str, Path], topology_path: Path = _process_topology_path(topology) output_path: Path = _process_output_path(output_dir, topology_path) - provisioning_path: Path = _process_provisioning_path(provisioning_dir, - output_path) - extra_vars_path: Path = _process_extra_vars_path(extra_vars, output_path) + provisioning_path: Path = _process_provisioning_path(provisioning_dir) + extra_vars_path: Path = _process_extra_vars_path(extra_vars) try: sandbox_definition: Sandbox = Sandbox(topology_path, CONFIGURATION_PATH, diff --git a/tests/unit_tests/resources/playbook.yml b/tests/unit_tests/resources/playbook.yml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/unit_tests/resources/test_file.yml b/tests/unit_tests/resources/test_file.yml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/unit_tests/test_creator.py b/tests/unit_tests/test_creator.py new file mode 100644 index 0000000000000000000000000000000000000000..c69e8a827d1beb81256faec55a7d3761d524bcb3 --- /dev/null +++ b/tests/unit_tests/test_creator.py @@ -0,0 +1,120 @@ +from unittest import TestCase +from pathlib import Path + +from cyber_sandbox_creator import creator + + +class TestInputValidation(TestCase): + TEST_DIR_PATH: Path = Path(__file__).parent.joinpath("resources") + TEST_DIR_STR: str = TEST_DIR_PATH.as_posix() + TEST_FILE_PATH: Path = TEST_DIR_PATH.joinpath("test_file.yml") + TEST_FILE_STR: str = TEST_FILE_PATH.as_posix() + MISSING_FILE_PATH: Path = Path("missing_file") + MISSING_FILE_STR: str = "missing_file" + + # _process_topology_path + def test_process_topology_path_valid_str(self): + output: Path = creator._process_topology_path(self.TEST_FILE_STR) + self.assertEqual(Path(self.TEST_FILE_STR).resolve(), output) + + def test_process_topology_path_valid_path(self): + output: Path = creator._process_topology_path(self.TEST_FILE_PATH) + self.assertEqual(self.TEST_FILE_PATH.resolve(), output) + + def test_process_topology_path_invalid_type_int(self): + with self.assertRaises(TypeError): + creator._process_topology_path(1) + + def test_process_topology_path_invalid_type_none(self): + with self.assertRaises(TypeError): + creator._process_topology_path() + + def test_process_topology_path_missing_file_str(self): + with self.assertRaises(ValueError): + creator._process_topology_path(self.MISSING_FILE_STR) + + def test_process_topology_path_invalid_file(self): + with self.assertRaises(ValueError): + creator._process_topology_path(self.TEST_FILE_PATH.parent) + + # _process_output_path + def test_process_output_path_valid_none(self): + output: Path = creator._process_output_path(None, self.TEST_DIR_PATH) + self.assertEqual(self.TEST_DIR_PATH.parent.joinpath("sandbox"), output) + + def test_process_output_path_valid_empty(self): + output: Path = creator._process_output_path("", self.TEST_DIR_PATH) + self.assertEqual(self.TEST_DIR_PATH.parent.joinpath("sandbox"), output) + + def test_process_output_path_valid_path(self): + output: Path = creator._process_output_path(self.TEST_DIR_PATH, + self.TEST_DIR_PATH) + self.assertEqual(self.TEST_DIR_PATH, output) + + def test_process_output_path_valid_str(self): + output: Path = creator._process_output_path( + self.TEST_DIR_PATH.as_posix(), self.TEST_DIR_PATH) + self.assertEqual(self.TEST_DIR_PATH, output) + + def test_process_output_path_invalid_type(self): + with self.assertRaises(TypeError): + creator._process_output_path(1, self.TEST_DIR_PATH) + + def test_process_output_path_invalid_file(self): + with self.assertRaises(ValueError): + creator._process_output_path(self.TEST_FILE_PATH, + self.TEST_DIR_PATH) + + # _process_provisioning_path + def test_process_provisioning_path_valid_none(self): + output = creator._process_provisioning_path(None) + self.assertEqual(None, output) + + def test_process_provisioning_path_valid_empty(self): + output = creator._process_provisioning_path("") + self.assertEqual(None, output) + + def test_process_provisioning_path_valid_path(self): + output = creator._process_provisioning_path(self.TEST_DIR_PATH) + self.assertEqual(self.TEST_DIR_PATH, output) + + def test_process_provisioning_path_valid_str(self): + output = creator._process_provisioning_path(self.TEST_DIR_STR) + self.assertEqual(self.TEST_DIR_PATH, output) + + def test_process_provisioning_path_invalid_type(self): + with self.assertRaises(TypeError): + creator._process_provisioning_path(1) + + def test_process_provisioning_path_invalid_not_dir(self): + with self.assertRaises(ValueError): + creator._process_provisioning_path(self.TEST_FILE_PATH) + + def test_process_provisioning_path_invalid_without_playbook(self): + with self.assertRaises(ValueError): + creator._process_provisioning_path(self.TEST_DIR_PATH.parent) + + # _process_extra_vars_path + def test_process_extra_vars_path_valid_none(self): + output = creator._process_extra_vars_path(None) + self.assertEqual(None, output) + + def test_process_extra_vars_path_valid_empty(self): + output = creator._process_extra_vars_path("") + self.assertEqual(None, output) + + def test_process_extra_vars_path_valid_path(self): + output: Path = creator._process_extra_vars_path(self.TEST_FILE_PATH) + self.assertEqual(self.TEST_FILE_PATH, output) + + def test_process_extra_vars_path_valid_str(self): + output: Path = creator._process_extra_vars_path(self.TEST_FILE_STR) + self.assertEqual(self.TEST_FILE_PATH, output) + + def test_process_extra_vars_path_invalid_type(self): + with self.assertRaises(TypeError): + creator._process_extra_vars_path(1) + + def test_process_extra_vars_path_invalid_missing(self): + with self.assertRaises(ValueError): + creator._process_extra_vars_path(self.MISSING_FILE_STR)