示例#1
0
def test_element_get_at(sample_nist_component_def: component.ComponentDefinition):
    """Test element get method."""
    element = Element(sample_nist_component_def)

    # field alias should succeed
    assert element.get_at(
        ElementPath('component-definition.metadata.last-modified')
    ) == sample_nist_component_def.metadata.last_modified

    # field name should fail
    assert element.get_at(ElementPath('component-definition.metadata.last_modified')) is None

    assert element.get() == sample_nist_component_def
    assert element.get_at() == element.get()
    assert element.get_at(ElementPath('component-definition.metadata')) == sample_nist_component_def.metadata
    assert element.get_at(
        ElementPath('component-definition.metadata.title')
    ) == sample_nist_component_def.metadata.title
    assert element.get_at(ElementPath('component-definition.components')) == sample_nist_component_def.components
    assert element.get_at(ElementPath('component-definition.components.*')) == sample_nist_component_def.components
    assert element.get_at(
        ElementPath('component-definition.metadata.parties.*')
    ) == sample_nist_component_def.metadata.parties
    assert element.get_at(ElementPath('component-definition.metadata.parties.0')
                          ) == sample_nist_component_def.metadata.parties[0]
    assert element.get_at(ElementPath('component-definition.metadata.parties.0.uuid')
                          ) == sample_nist_component_def.metadata.parties[0].uuid

    for index in range(len(sample_nist_component_def.components)):
        path_str = f'component-definition.components.{index}'
        assert element.get_at(ElementPath(path_str)) == sample_nist_component_def.components[index]

    # invalid indexing
    assert element.get_at(ElementPath('component-definition.metadata.title.0')) is None

    # invalid path with missing root model
    assert element.get_at(ElementPath('metadata.title')) is None

    # element_path with parent path
    parent_path = ElementPath('component-definition.metadata')
    element_path = ElementPath('metadata.parties.*', parent_path)
    assert element.get_at(element_path) == sample_nist_component_def.metadata.parties

    # element_path with parent path
    parent_path = ElementPath('component-definition.components.*')
    element_path = ElementPath('component.control-implementations.*', parent_path)
    component_list = element.get_at(parent_path)
    for component_item in component_list:
        component_element = Element(component_item)
        assert component_element.get_at(element_path) == component_item.control_implementations

    # element_path in a list with parent path
    parent_path = ElementPath('component-definition.components.*')
    element_path = ElementPath('component.control-implementations.0', parent_path)
    component_list = element.get_at(parent_path)
    for component_item in component_list:
        component_element = Element(component_item)
        assert component_element.get_at(element_path) == component_item.control_implementations[0]
def test_element_get_at(sample_target_def: target.TargetDefinition):
    """Test element get method."""
    element = Element(sample_target_def)

    # field alias should succeed
    assert element.get_at(
        ElementPath('target-definition.metadata.last-modified')
    ) == sample_target_def.metadata.last_modified

    # field name should fail
    assert element.get_at(ElementPath('target-definition.metadata.last_modified')) is None

    assert element.get() == sample_target_def
    assert element.get_at() == element.get()
    assert element.get_at(ElementPath('target-definition.metadata')) == sample_target_def.metadata
    assert element.get_at(ElementPath('target-definition.metadata.title')) == sample_target_def.metadata.title
    assert element.get_at(ElementPath('target-definition.targets')) == sample_target_def.targets
    assert element.get_at(ElementPath('target-definition.targets.*')) == sample_target_def.targets
    assert element.get_at(ElementPath('target-definition.metadata.parties.*')) == sample_target_def.metadata.parties
    assert element.get_at(ElementPath('target-definition.metadata.parties.0')) == sample_target_def.metadata.parties[0]
    assert element.get_at(ElementPath('target-definition.metadata.parties.0.uuid')
                          ) == sample_target_def.metadata.parties[0].uuid

    for uuid in sample_target_def.targets:
        path_str = f'target-definition.targets.{uuid}'
        assert element.get_at(ElementPath(path_str)) == sample_target_def.targets[uuid]

    # invalid indexing
    assert element.get_at(ElementPath('target-definition.metadata.title.0')) is None

    # invalid path with missing root model
    assert element.get_at(ElementPath('metadata.title')) is None

    # element_path with parent path
    parent_path = ElementPath('target-definition.metadata')
    element_path = ElementPath('metadta.parties.*', parent_path)
    assert element.get_at(element_path) == sample_target_def.metadata.parties

    # element_path with parent path
    parent_path = ElementPath('target-definition.targets.*')
    element_path = ElementPath('target.target-control-implementations.*', parent_path)
    targets = element.get_at(parent_path)
    for key in targets:
        target = targets[key]
        target_element = Element(target)
        assert target_element.get_at(element_path) == target.target_control_implementations

    # element_path in a list with parent path
    parent_path = ElementPath('target-definition.targets.*')
    element_path = ElementPath('target.target-control-implementations.0', parent_path)
    targets = element.get_at(parent_path)
    for key in targets:
        target = targets[key]
        target_element = Element(target)
        assert target_element.get_at(element_path) == target.target_control_implementations[0]
示例#3
0
def test_write_file_action_yaml(tmp_yaml_file: pathlib.Path,
                                sample_nist_component_def):
    """Test write yaml action."""
    element = Element(sample_nist_component_def, 'component-definition')

    try:
        # string path should error
        wa = WriteFileAction(tmp_yaml_file.as_posix(), element,
                             FileContentType.YAML)
    except TrestleError:
        pass

    try:
        # invalid file extension should error
        wa = WriteFileAction(tmp_yaml_file, element, FileContentType.JSON)
    except TrestleError:
        pass

    try:
        # writing to a non-existing file will error
        wa = WriteFileAction(tmp_yaml_file, element, FileContentType.YAML)
        wa.execute()
    except TrestleError:
        pass

    tmp_yaml_file.touch()
    wa = WriteFileAction(tmp_yaml_file, element, FileContentType.YAML)
    wa.execute()
    test_utils.verify_file_content(tmp_yaml_file, element.get())
示例#4
0
def test_split_chained_sub_model_plans(
        tmp_path: pathlib.Path, simplified_nist_catalog: oscatalog.Catalog,
        keep_cwd: pathlib.Path) -> None:
    """Test for split_model method with chained sum models like catalog.metadata.parties.*."""
    # Assume we are running a command like below
    # trestle split -f catalog.json -e catalog.metadata.parties.*
    # see https://github.com/IBM/compliance-trestle/issues/172
    content_type = FileContentType.JSON

    # prepare trestle project dir with the file
    catalog_dir, catalog_file = test_utils.prepare_trestle_project_dir(
        tmp_path, content_type, simplified_nist_catalog,
        test_utils.CATALOGS_DIR)

    # read the model from file
    catalog = oscatalog.Catalog.oscal_read(catalog_file)
    element = Element(catalog)
    element_args = ['catalog.metadata.parties.*']
    element_paths = cmd_utils.parse_element_args(
        None, element_args, catalog_dir.relative_to(tmp_path))
    assert 2 == len(element_paths)

    expected_plan = Plan()

    # prepare to extract metadata and parties
    metadata_file = catalog_dir / element_paths[0].to_file_path(content_type)
    metadata_field_alias = element_paths[0].get_element_name()
    metadata = element.get_at(element_paths[0])
    meta_element = Element(metadata, metadata_field_alias)

    # extract parties
    parties_dir = catalog_dir / 'catalog/metadata/parties'
    for i, party in enumerate(meta_element.get_at(element_paths[1], False)):
        prefix = str(i).zfill(const.FILE_DIGIT_PREFIX_LENGTH)
        sub_model_actions = SplitCmd.prepare_sub_model_split_actions(
            party, parties_dir, prefix, content_type)
        expected_plan.add_actions(sub_model_actions)

    # stripped metadata
    stripped_metadata = metadata.stripped_instance(
        stripped_fields_aliases=['parties'])
    expected_plan.add_action(CreatePathAction(metadata_file))
    expected_plan.add_action(
        WriteFileAction(metadata_file,
                        Element(stripped_metadata, metadata_field_alias),
                        content_type))

    # stripped catalog
    root_file = catalog_dir / element_paths[0].to_root_path(content_type)
    remaining_root = element.get().stripped_instance(metadata_field_alias)
    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(catalog, element_paths, catalog_dir,
                                      content_type, '', None)
    assert expected_plan == split_plan
def test_write_action_json(tmp_json_file, sample_target_def):
    """Test write json action."""
    element = Element(sample_target_def, 'target-definition')

    with open(tmp_json_file, 'w+') as writer:
        wa = WriteAction(writer, element, FileContentType.JSON)
        wa.execute()
        test_utils.verify_file_content(tmp_json_file, element.get())

    os.remove(tmp_json_file)
def test_write_action_yaml(tmp_yaml_file, sample_target):
    """Test write yaml action."""
    element = Element(sample_target)

    with open(tmp_yaml_file, 'w+') as writer:
        wa = WriteAction(writer, element, FileContentType.YAML)
        wa.execute()
        test_utils.verify_file_content(tmp_yaml_file, element.get())

    os.remove(tmp_yaml_file)
def test_element_get_at(sample_target: target.TargetDefinition):
    """Test element get method."""
    element = Element(sample_target)

    assert element.get() == sample_target
    assert element.get_at() == element.get()
    assert element.get_at(ElementPath('metadata')) == sample_target.metadata
    assert element.get_at(
        ElementPath('metadata.title')) == sample_target.metadata.title
    assert element.get_at(ElementPath('targets')) == sample_target.targets
    assert element.get_at(ElementPath('targets.*')) == sample_target.targets
    assert element.get_at(
        ElementPath('metadata.parties.*')) == sample_target.metadata.parties
    assert element.get_at(
        ElementPath('metadata.parties.0')) == sample_target.metadata.parties[0]
    assert element.get_at(ElementPath(
        'metadata.parties.0.uuid')) == sample_target.metadata.parties[0].uuid

    # invalid indexing
    assert element.get_at(ElementPath('metadata.title.0')) is None
示例#8
0
def test_write_action_json(tmp_json_file, sample_nist_component_def):
    """Test write json action."""
    element = Element(sample_nist_component_def, 'component-definition')

    with open(tmp_json_file, 'w+', encoding=const.FILE_ENCODING) as writer:
        wa = WriteAction(writer, element, FileContentType.JSON)
        wa.execute()
        writer.flush()
        writer.close()

    test_utils.verify_file_content(tmp_json_file, element.get())

    os.remove(tmp_json_file)
示例#9
0
def test_write_file_rollback(tmp_yaml_file: pathlib.Path, sample_target):
    """Test rollback."""
    element = Element(sample_target)
    tmp_yaml_file.touch()
    wa = WriteFileAction(tmp_yaml_file, element, FileContentType.YAML)
    wa.execute()
    test_utils.verify_file_content(tmp_yaml_file, element.get())

    # verify the file content is not empty
    with open(tmp_yaml_file, 'r', encoding='utf8') as read_file:
        assert read_file.tell() >= 0

    wa.rollback()

    # verify the file content is empty
    with open(tmp_yaml_file, 'r', encoding='utf8') as read_file:
        assert read_file.tell() == 0
示例#10
0
def test_write_file_rollback(tmp_yaml_file: pathlib.Path,
                             sample_nist_component_def):
    """Test rollback."""
    element = Element(sample_nist_component_def, 'component-definition')
    tmp_yaml_file.touch()
    wa = WriteFileAction(tmp_yaml_file, element, FileContentType.YAML)
    wa.execute()
    test_utils.verify_file_content(tmp_yaml_file, element.get())

    # verify the file content is not empty
    with open(tmp_yaml_file, 'r', encoding=const.FILE_ENCODING) as read_file:
        assert read_file.tell() >= 0

    wa.rollback()

    # verify the file content is empty
    with open(tmp_yaml_file, 'r', encoding=const.FILE_ENCODING) as read_file:
        assert read_file.tell() == 0
示例#11
0
    def add(element_path: ElementPath, parent_element: Element, include_optional: bool) -> None:
        """For a element_path, add a child model to the parent_element of a given parent_model.

        Args:
            element_path: element path of the item to create within the model
            parent_element: the parent element that will host the created element
            include_optional: whether to create optional attributes in the created element

        Notes:
            First we find the child model at the specified element path and instantiate it with default values.
            Then we check if there's already existing element at that path, in which case we append the child model
            to the existing list of dict.
            Then we set up an action plan to update the model (specified by file_path) in memory, create a file
            at the same location and write the file.
            We update the parent_element to prepare for next adds in the chain
        """
        if '*' in element_path.get_full_path_parts():
            raise err.TrestleError('trestle add does not support Wildcard element path.')
        # Get child model
        try:
            child_model = element_path.get_type(type(parent_element.get()))

            # Create child element with sample values
            child_object = gens.generate_sample_model(child_model, include_optional=include_optional)

            if parent_element.get_at(element_path) is not None:
                # The element already exists
                if type(parent_element.get_at(element_path)) is list:
                    child_object = parent_element.get_at(element_path) + child_object
                elif type(parent_element.get_at(element_path)) is dict:
                    child_object = {**parent_element.get_at(element_path), **child_object}
                else:
                    raise err.TrestleError('Already exists and is not a list or dictionary.')

        except Exception as e:
            raise err.TrestleError(f'Bad element path. {str(e)}')

        update_action = UpdateAction(
            sub_element=child_object, dest_element=parent_element, sub_element_path=element_path
        )
        parent_element = parent_element.set_at(element_path, child_object)

        return update_action, parent_element
示例#12
0
def test_split_model_plans(
        tmp_path: pathlib.Path,
        sample_nist_component_def: component.ComponentDefinition) -> None:
    """Test for split_model method."""
    # Assume we are running a command like below
    # trestle split -f component-definition.yaml -e component-definition.metadata
    content_type = FileContentType.YAML

    # prepare trestle project dir with the file
    component_def_dir, component_def_file = test_utils.prepare_trestle_project_dir(
        tmp_path, content_type, sample_nist_component_def,
        test_utils.COMPONENT_DEF_DIR)

    # read the model from file
    component_def = component.ComponentDefinition.oscal_read(
        component_def_file)
    element = Element(component_def)
    element_args = ['component-definition.metadata']
    element_paths = cmd_utils.parse_element_args(None, element_args)

    # extract values
    metadata_file = component_def_dir / element_paths[0].to_file_path(
        content_type)
    metadata = element.get_at(element_paths[0])

    root_file = component_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(component_def, element_paths,
                                      component_def_dir, content_type, '',
                                      None)
    assert expected_plan == split_plan
示例#13
0
def test_split_model(tmp_dir, sample_target_def: ostarget.TargetDefinition):
    """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_dir, 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
示例#14
0
def test_split_multi_level_dict(
        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.yaml -e target-definition.targets.*.target-control-implementations.*

    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)

    file_ext = FileContentType.to_file_extension(content_type)

    # read the model from file
    target_def: ostarget.TargetDefinition = ostarget.TargetDefinition.oscal_read(
        target_def_file)
    element = Element(target_def)
    element_args = [
        'target-definition.targets.*.target-control-implementations.*'
    ]
    element_paths = test_utils.prepare_element_paths(target_def_dir,
                                                     element_args)

    expected_plan = Plan()

    # extract values
    targets: dict = element.get_at(element_paths[0])
    targets_dir = target_def_dir / element_paths[0].to_file_path()

    # split every targets
    for key in targets:
        # individual target dir
        target: ostarget.Target = targets[key]
        target_element = Element(targets[key])
        model_type = utils.classname_to_alias(type(target).__name__, 'json')
        dir_prefix = key
        target_dir_name = f'{dir_prefix}{const.IDX_SEP}{model_type}'
        target_file = targets_dir / f'{target_dir_name}{file_ext}'

        # target control impl dir for the target
        target_ctrl_impls: dict = target_element.get_at(element_paths[1])
        targets_ctrl_dir = targets_dir / element_paths[1].to_file_path(
            root_dir=target_dir_name)

        for i, target_ctrl_impl in enumerate(target_ctrl_impls):
            model_type = utils.classname_to_alias(
                type(target_ctrl_impl).__name__, 'json')
            file_prefix = str(i).zfill(const.FILE_DIGIT_PREFIX_LENGTH)
            file_name = f'{file_prefix}{const.IDX_SEP}{model_type}{file_ext}'
            file_path = targets_ctrl_dir / file_name
            expected_plan.add_action(CreatePathAction(file_path))
            expected_plan.add_action(
                WriteFileAction(file_path, Element(target_ctrl_impl),
                                content_type))

        # write stripped target model
        stripped_target = target.stripped_instance(
            stripped_fields_aliases=[element_paths[1].get_element_name()])
        expected_plan.add_action(CreatePathAction(target_file))
        expected_plan.add_action(
            WriteFileAction(target_file, Element(stripped_target),
                            content_type))

    root_file = target_def_dir / f'target-definition{file_ext}'
    remaining_root = element.get().stripped_instance(
        stripped_fields_aliases=[element_paths[0].get_element_name()])
    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
示例#15
0
def test_subsequent_split_model(
        tmp_path: pathlib.Path,
        sample_target_def: ostarget.TargetDefinition) -> None:
    """Test subsequent split of sub models."""
    # 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)

    # first split the target-def into metadata
    target_def = ostarget.TargetDefinition.oscal_read(target_def_file)
    element = Element(target_def, 'target-definition')
    element_args = ['target-definition.metadata']
    element_paths = test_utils.prepare_element_paths(target_def_dir,
                                                     element_args)
    metadata_file = target_def_dir / element_paths[0].to_file_path(
        content_type)
    metadata: ostarget.Metadata = element.get_at(element_paths[0])
    root_file = target_def_dir / element_paths[0].to_root_path(content_type)
    metadata_field_alias = element_paths[0].get_element_name()
    stripped_root = element.get().stripped_instance(
        stripped_fields_aliases=[metadata_field_alias])
    root_wrapper_alias = utils.classname_to_alias(
        stripped_root.__class__.__name__, 'json')

    first_plan = Plan()
    first_plan.add_action(CreatePathAction(metadata_file))
    first_plan.add_action(
        WriteFileAction(metadata_file, Element(metadata, metadata_field_alias),
                        content_type))
    first_plan.add_action(CreatePathAction(root_file, True))
    first_plan.add_action(
        WriteFileAction(root_file, Element(stripped_root, root_wrapper_alias),
                        content_type))
    first_plan.execute()  # this will split the files in the temp directory

    # now, prepare the expected plan to split metadta at parties
    second_plan = Plan()
    metadata_file_dir = target_def_dir / element_paths[0].to_root_path()
    metadata2 = ostarget.Metadata.oscal_read(metadata_file)
    element = Element(metadata2, metadata_field_alias)

    element_args = ['metadata.parties.*']
    element_paths = test_utils.prepare_element_paths(target_def_dir,
                                                     element_args)
    parties_dir = metadata_file_dir / element_paths[0].to_file_path()
    for i, party in enumerate(element.get_at(element_paths[0])):
        prefix = str(i).zfill(const.FILE_DIGIT_PREFIX_LENGTH)
        sub_model_actions = SplitCmd.prepare_sub_model_split_actions(
            party, parties_dir, prefix, content_type)
        second_plan.add_actions(sub_model_actions)

    # stripped metadata
    stripped_metadata = metadata2.stripped_instance(
        stripped_fields_aliases=['parties'])
    second_plan.add_action(CreatePathAction(metadata_file, True))
    second_plan.add_action(
        WriteFileAction(metadata_file,
                        Element(stripped_metadata, metadata_field_alias),
                        content_type))

    # call the split command and compare the plans
    split_plan = SplitCmd.split_model(metadata, element_paths,
                                      metadata_file_dir, content_type)
    assert second_plan == split_plan
示例#16
0
def test_split_multi_level_dict_plans(
        tmp_path: pathlib.Path,
        sample_nist_component_def: component.ComponentDefinition,
        keep_cwd) -> None:
    """Test for split_model method."""
    # Assume we are running a command like below
    # trestle split -f target.yaml -e component-definition.components.*.control-implementations.*

    content_type = FileContentType.YAML

    # prepare trestle project dir with the file
    component_def_dir, component_def_file = test_utils.prepare_trestle_project_dir(
        tmp_path, content_type, sample_nist_component_def,
        test_utils.COMPONENT_DEF_DIR)

    file_ext = FileContentType.to_file_extension(content_type)

    # read the model from file
    component_def: component.ComponentDefinition = component.ComponentDefinition.oscal_read(
        component_def_file)
    element = Element(component_def)
    element_args = [
        'component-definition.components.*.control-implementations.*'
    ]
    element_paths = cmd_utils.parse_element_args(
        None, element_args, component_def_dir.relative_to(tmp_path))

    expected_plan = Plan()

    # extract values
    components: list = element.get_at(element_paths[0])
    components_dir = component_def_dir / element_paths[0].to_file_path()

    # split every targets
    for index, comp_obj in enumerate(components):
        # individual target dir
        component_element = Element(comp_obj)
        model_type = str_utils.classname_to_alias(
            type(comp_obj).__name__, AliasMode.JSON)
        dir_prefix = str(index).zfill(const.FILE_DIGIT_PREFIX_LENGTH)
        component_dir_name = f'{dir_prefix}{const.IDX_SEP}{model_type}'
        component_file = components_dir / f'{component_dir_name}{file_ext}'

        # target control impl dir for the target
        component_ctrl_impls: list = component_element.get_at(element_paths[1])
        component_ctrl_dir = components_dir / element_paths[1].to_file_path(
            root_dir=component_dir_name)

        for i, component_ctrl_impl in enumerate(component_ctrl_impls):
            model_type = str_utils.classname_to_alias(
                type(component_ctrl_impl).__name__, AliasMode.JSON)
            file_prefix = str(i).zfill(const.FILE_DIGIT_PREFIX_LENGTH)
            file_name = f'{file_prefix}{const.IDX_SEP}{model_type}{file_ext}'
            file_path = component_ctrl_dir / file_name
            expected_plan.add_action(CreatePathAction(file_path))
            expected_plan.add_action(
                WriteFileAction(file_path, Element(component_ctrl_impl),
                                content_type))

        # write stripped target model
        stripped_target = comp_obj.stripped_instance(
            stripped_fields_aliases=[element_paths[1].get_element_name()])
        expected_plan.add_action(CreatePathAction(component_file))
        expected_plan.add_action(
            WriteFileAction(component_file, Element(stripped_target),
                            content_type))

    root_file = component_def_dir / f'component-definition{file_ext}'
    remaining_root = element.get().stripped_instance(
        stripped_fields_aliases=[element_paths[0].get_element_name()])
    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(component_def, element_paths,
                                      component_def_dir, content_type, '',
                                      None)
    assert expected_plan == split_plan