def prepare_element_paths(base_dir, element_args) -> List[ElementPath]: """Prepare element paths for tests.""" cur_dir = pathlib.Path.cwd() os.chdir(base_dir) element_paths: List[ElementPath] = cmd_utils.parse_element_args(element_args, True) os.chdir(cur_dir) return element_paths
def test_parse_element_args(): """Unit test parse multiple element args.""" element_args = ['catalog.metadata', 'catalog.groups', 'catalog.controls'] p0 = ElementPath('catalog.metadata') p1 = ElementPath('catalog.groups') p2 = ElementPath('catalog.controls') expected_paths: List[ElementPath] = [p0, p1, p2] element_paths = cmd_utils.parse_element_args(element_args) assert expected_paths == element_paths # element args with wildcard element_args = [ 'catalog.metadata', 'catalog.groups.*.controls.*.controls.*', 'catalog.controls.*.controls.*' ] p0 = ElementPath('catalog.metadata') p1 = ElementPath('catalog.groups.*') p2 = ElementPath('controls.*', parent_path=p1) p3 = ElementPath('controls.*', parent_path=p2) p4 = ElementPath('catalog.controls.*') p5 = ElementPath('controls.*', parent_path=p4) expected: List[ElementPath] = [p0, p1, p2, p3, p4, p5] assert cmd_utils.parse_element_args(element_args) == expected
def _run(self, args: argparse.Namespace) -> int: """Split an OSCAL file into elements.""" logger.debug('Entering trestle split.') log.set_log_level_from_args(args) # get the Model args_raw = args.__dict__ if args_raw[const.ARG_FILE] is None: logger.error(f'Argument "-{const.ARG_FILE_SHORT}" is required') return 1 file_path = pathlib.Path(args_raw[const.ARG_FILE]) if not file_path.exists(): logger.error(f'File {file_path} does not exist.') return 1 content_type = FileContentType.to_content_type(file_path.suffix) # find the base directory of the file file_absolute_path = pathlib.Path(file_path.absolute()) base_dir = file_absolute_path.parent model_type, _ = fs.get_stripped_contextual_model(file_absolute_path) # FIXME: Handle list/dicts model: OscalBaseModel = model_type.oscal_read(file_path) element_paths: List[ElementPath] = cmd_utils.parse_element_args( args_raw[const.ARG_ELEMENT].split(',')) split_plan = self.split_model(model, element_paths, base_dir, content_type, root_file_name=args_raw[const.ARG_FILE]) # Simulate the plan # if it fails, it would throw errors and get out of this command split_plan.simulate() # If we are here then simulation passed # so move the original file to the trash trash.store(file_path, True) # execute the plan split_plan.execute() return 0
def test_split_model(tmp_path: pathlib.Path, sample_target_def: ostarget.TargetDefinition) -> None: """Test for split_model method.""" # Assume we are running a command like below # trestle split -f target-definition.yaml -e target-definition.metadata content_type = FileContentType.YAML # prepare trestle project dir with the file target_def_dir, target_def_file = test_utils.prepare_trestle_project_dir( tmp_path, content_type, sample_target_def, test_utils.TARGET_DEFS_DIR) # read the model from file target_def = ostarget.TargetDefinition.oscal_read(target_def_file) element = Element(target_def) element_args = ['target-definition.metadata'] element_paths = cmd_utils.parse_element_args(element_args) # extract values metadata_file = target_def_dir / element_paths[0].to_file_path( content_type) metadata = element.get_at(element_paths[0]) root_file = target_def_dir / element_paths[0].to_root_path(content_type) remaining_root = element.get().stripped_instance( element_paths[0].get_element_name()) # prepare the plan expected_plan = Plan() expected_plan.add_action(CreatePathAction(metadata_file)) expected_plan.add_action( WriteFileAction(metadata_file, Element(metadata), content_type)) expected_plan.add_action(CreatePathAction(root_file, True)) expected_plan.add_action( WriteFileAction(root_file, Element(remaining_root), content_type)) split_plan = SplitCmd.split_model(target_def, element_paths, target_def_dir, content_type) assert expected_plan == split_plan