Skip to content

Commit

Permalink
feat: Allows regenerate and assemble object to accept and AuthoredObj…
Browse files Browse the repository at this point in the history
…ect type

In some instances AuthoredObject types are used outside of the scope of tasks.
Allowing the the tasks to directly take the AuthoredObject type allows these
configured objects to be reused. It also decouples the task from the model
specific AuthoredObject configuration.

BREAKING CHANGE: No user facing changes, but is a breaking change to the public API

Signed-off-by: Jennifer Power <barnabei.jennifer@gmail.com>
  • Loading branch information
jpower432 committed Dec 1, 2023
1 parent 81f723f commit 6766eca
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 260 deletions.
10 changes: 5 additions & 5 deletions tests/trestlebot/tasks/authored/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
from tests import testutils
from trestlebot.tasks.authored import types
from trestlebot.tasks.authored.base_authored import (
AuthoredObjectBase,
AuthoredObjectException,
AuthorObjectBase,
)
from trestlebot.tasks.authored.catalog import AuthoredCatalog
from trestlebot.tasks.authored.compdef import AuthoredComponentDefinition
Expand All @@ -41,7 +41,7 @@
def test_get_authored_catalog(tmp_trestle_dir: str) -> None:
"""Test get authored type for catalogs"""

authored_object: AuthorObjectBase = types.get_authored_object(
authored_object: AuthoredObjectBase = types.get_authored_object(
types.AuthoredType.CATALOG.value, tmp_trestle_dir, ""
)

Expand All @@ -52,7 +52,7 @@ def test_get_authored_catalog(tmp_trestle_dir: str) -> None:
def test_get_authored_profile(tmp_trestle_dir: str) -> None:
"""Test get authored type for catalogs"""

authored_object: AuthorObjectBase = types.get_authored_object(
authored_object: AuthoredObjectBase = types.get_authored_object(
types.AuthoredType.PROFILE.value, tmp_trestle_dir, ""
)

Expand All @@ -64,7 +64,7 @@ def test_get_authored_compdef(tmp_trestle_dir: str) -> None:
"""Test get authored type for catalogs"""

# Test with profile
authored_object: AuthorObjectBase = types.get_authored_object(
authored_object: AuthoredObjectBase = types.get_authored_object(
types.AuthoredType.COMPDEF.value, tmp_trestle_dir, ""
)

Expand All @@ -83,7 +83,7 @@ def test_get_authored_ssp(tmp_trestle_dir: str) -> None:
_ = types.get_authored_object(types.AuthoredType.SSP.value, tmp_trestle_dir, "")

# Test with profile
authored_object: AuthorObjectBase = types.get_authored_object(
authored_object: AuthoredObjectBase = types.get_authored_object(
types.AuthoredType.SSP.value, tmp_trestle_dir, ssp_index_path
)

Expand Down
101 changes: 34 additions & 67 deletions tests/trestlebot/tasks/test_assemble_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@

from tests import testutils
from trestlebot.tasks.assemble_task import AssembleTask
from trestlebot.tasks.authored.base_authored import AuthorObjectBase
from trestlebot.tasks.authored.types import AuthoredType
from trestlebot.tasks.authored.base_authored import AuthoredObjectBase
from trestlebot.tasks.authored.catalog import AuthoredCatalog
from trestlebot.tasks.authored.compdef import AuthoredComponentDefinition
from trestlebot.tasks.authored.profile import AuthoredProfile
from trestlebot.tasks.authored.ssp import AuthoredSSP, SSPIndex
from trestlebot.tasks.base_task import ModelFilter


Expand All @@ -58,23 +61,20 @@ def test_assemble_task_isolated(tmp_trestle_dir: str) -> None:
cat_generate = CatalogGenerate()
assert cat_generate._run(args) == 0

mock = Mock(spec=AuthorObjectBase)

assemble_task = AssembleTask(
tmp_trestle_dir,
AuthoredType.CATALOG.value,
cat_md_dir,
"",
)
mock = Mock(spec=AuthoredObjectBase)
mock.get_trestle_root.return_value = tmp_trestle_dir
assemble_task = AssembleTask(mock, cat_md_dir, "1.0.0")

with patch(
"trestlebot.tasks.authored.types.get_authored_object"
) as mock_get_authored_object:
mock_get_authored_object.return_value = mock
"trestlebot.tasks.authored.types.get_trestle_model_dir"
) as mock_get_trestle_model_dir:
mock_get_trestle_model_dir.return_value = "catalogs"

assert assemble_task.execute() == 0

mock.assemble.assert_called_once_with(markdown_path=md_path)
mock.assemble.assert_called_once_with(
markdown_path=md_path, version_tag="1.0.0"
)


@pytest.mark.parametrize(
Expand All @@ -94,21 +94,16 @@ def test_assemble_task_with_skip(tmp_trestle_dir: str, skip_list: List[str]) ->
cat_generate = CatalogGenerate()
assert cat_generate._run(args) == 0

mock = Mock(spec=AuthorObjectBase)

mock = Mock(spec=AuthoredObjectBase)
mock.get_trestle_root.return_value = tmp_trestle_dir
model_filter = ModelFilter(skip_list, ["*"])

assemble_task = AssembleTask(
working_dir=tmp_trestle_dir,
authored_model=AuthoredType.CATALOG.value,
markdown_dir=cat_md_dir,
model_filter=model_filter,
)
assemble_task = AssembleTask(mock, cat_md_dir, cat_md_dir, model_filter)

with patch(
"trestlebot.tasks.authored.types.get_authored_object"
) as mock_get_authored_object:
mock_get_authored_object.return_value = mock
"trestlebot.tasks.authored.types.get_trestle_model_dir"
) as mock_get_trestle_model_dir:
mock_get_trestle_model_dir.return_value = "catalogs"

assert assemble_task.execute() == 0
mock.assemble.assert_not_called()
Expand All @@ -128,12 +123,9 @@ def test_catalog_assemble_task(tmp_trestle_dir: str) -> None:
)
orig_time = cat.metadata.last_modified

assemble_task = AssembleTask(
tmp_trestle_dir,
AuthoredType.CATALOG.value,
cat_md_dir,
"",
)
catalog = AuthoredCatalog(tmp_trestle_dir)
assemble_task = AssembleTask(catalog, cat_md_dir)

assert assemble_task.execute() == 0

# Get new last modified time and verify catalog was modified
Expand All @@ -157,12 +149,9 @@ def test_profile_assemble_task(tmp_trestle_dir: str) -> None:
)
orig_time = prof.metadata.last_modified

assemble_task = AssembleTask(
tmp_trestle_dir,
AuthoredType.PROFILE.value,
prof_md_dir,
"",
)
profile = AuthoredProfile(tmp_trestle_dir)
assemble_task = AssembleTask(profile, prof_md_dir)

assert assemble_task.execute() == 0

# Get new last modified time adn verify profile was modified
Expand Down Expand Up @@ -191,12 +180,9 @@ def test_compdef_assemble_task(tmp_trestle_dir: str) -> None:
)
orig_time = comp.metadata.last_modified

assemble_task = AssembleTask(
tmp_trestle_dir,
AuthoredType.COMPDEF.value,
compdef_md_dir,
"",
)
compdef = AuthoredComponentDefinition(tmp_trestle_dir)
assemble_task = AssembleTask(compdef, compdef_md_dir)

assert assemble_task.execute() == 0

# Get new last modified time and verify component was modified
Expand All @@ -217,32 +203,13 @@ def test_ssp_assemble_task(tmp_trestle_dir: str) -> None:
ssp_generate = SSPGenerate()
assert ssp_generate._run(args) == 0

assemble_task = AssembleTask(
tmp_trestle_dir,
AuthoredType.SSP.value,
ssp_md_dir,
ssp_index_path,
)
ssp_index = SSPIndex(ssp_index_path)

ssp = AuthoredSSP(tmp_trestle_dir, ssp_index)
assemble_task = AssembleTask(ssp, ssp_md_dir)

assert assemble_task.execute() == 0

assert os.path.exists(
os.path.join(tmp_trestle_dir, "system-security-plans", test_ssp_output)
)


def test_ssp_assemble_task_no_index_path(tmp_trestle_dir: str) -> None:
"""Test ssp assemble at the task level with failure"""
trestle_root = pathlib.Path(tmp_trestle_dir)
md_path = os.path.join(ssp_md_dir, test_ssp_output)
args = testutils.setup_for_ssp(trestle_root, test_prof, [test_comp], md_path)
ssp_generate = SSPGenerate()
assert ssp_generate._run(args) == 0

assemble_task = AssembleTask(
tmp_trestle_dir,
AuthoredType.SSP.value,
ssp_md_dir,
"",
)
with pytest.raises(FileNotFoundError):
assemble_task.execute()
111 changes: 30 additions & 81 deletions tests/trestlebot/tasks/test_regenerate_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@
from trestle.core.commands.author.ssp import SSPAssemble, SSPGenerate

from tests import testutils
from trestlebot.tasks.authored.base_authored import AuthorObjectBase
from trestlebot.tasks.authored.types import AuthoredType
from trestlebot.tasks.authored.base_authored import AuthoredObjectBase
from trestlebot.tasks.authored.catalog import AuthoredCatalog
from trestlebot.tasks.authored.compdef import AuthoredComponentDefinition
from trestlebot.tasks.authored.profile import AuthoredProfile
from trestlebot.tasks.authored.ssp import AuthoredSSP, SSPIndex
from trestlebot.tasks.base_task import ModelFilter
from trestlebot.tasks.regenerate_task import RegenerateTask

Expand All @@ -49,19 +52,14 @@ def test_regenerate_task_isolated(tmp_trestle_dir: str) -> None:
md_path = os.path.join(cat_md_dir, test_cat)
_ = testutils.setup_for_catalog(trestle_root, test_cat, md_path)

mock = Mock(spec=AuthorObjectBase)

regenerate_task = RegenerateTask(
tmp_trestle_dir,
AuthoredType.CATALOG.value,
cat_md_dir,
"",
)
mock = Mock(spec=AuthoredObjectBase)
mock.get_trestle_root.return_value = tmp_trestle_dir
regenerate_task = RegenerateTask(mock, cat_md_dir)

with patch(
"trestlebot.tasks.authored.types.get_authored_object"
) as mock_get_authored_object:
mock_get_authored_object.return_value = mock
"trestlebot.tasks.authored.types.get_trestle_model_dir"
) as mock_get_trestle_model_dir:
mock_get_trestle_model_dir.return_value = "catalogs"

assert regenerate_task.execute() == 0

Expand All @@ -85,21 +83,17 @@ def test_regenerate_task_with_skip(tmp_trestle_dir: str, skip_list: List[str]) -
md_path = os.path.join(cat_md_dir, test_cat)
_ = testutils.setup_for_catalog(trestle_root, test_cat, md_path)

mock = Mock(spec=AuthorObjectBase)

mock = Mock(spec=AuthoredObjectBase)
mock.get_trestle_root.return_value = tmp_trestle_dir
model_filter = ModelFilter(skip_list, ["*"])

regenerate_task = RegenerateTask(
working_dir=tmp_trestle_dir,
authored_model=AuthoredType.CATALOG.value,
markdown_dir=cat_md_dir,
model_filter=model_filter,
mock, markdown_dir=cat_md_dir, model_filter=model_filter
)

with patch(
"trestlebot.tasks.authored.types.get_authored_object"
) as mock_get_authored_object:
mock_get_authored_object.return_value = mock
"trestlebot.tasks.authored.types.get_trestle_model_dir"
) as mock_get_trestle_model_dir:
mock_get_trestle_model_dir.return_value = "catalogs"

assert regenerate_task.execute() == 0

Expand All @@ -112,12 +106,9 @@ def test_catalog_regenerate_task(tmp_trestle_dir: str) -> None:
md_path = os.path.join(cat_md_dir, test_cat)
_ = testutils.setup_for_catalog(trestle_root, test_cat, md_path)

regenerate_task = RegenerateTask(
tmp_trestle_dir,
AuthoredType.CATALOG.value,
cat_md_dir,
"",
)
catalog = AuthoredCatalog(tmp_trestle_dir)
regenerate_task = RegenerateTask(catalog, cat_md_dir)

assert regenerate_task.execute() == 0
assert os.path.exists(os.path.join(tmp_trestle_dir, md_path))

Expand All @@ -128,12 +119,9 @@ def test_profile_regenerate_task(tmp_trestle_dir: str) -> None:
md_path = os.path.join(prof_md_dir, test_prof)
_ = testutils.setup_for_profile(trestle_root, test_prof, md_path)

regenerate_task = RegenerateTask(
tmp_trestle_dir,
AuthoredType.PROFILE.value,
prof_md_dir,
"",
)
profile = AuthoredProfile(tmp_trestle_dir)
regenerate_task = RegenerateTask(profile, prof_md_dir)

assert regenerate_task.execute() == 0
assert os.path.exists(os.path.join(tmp_trestle_dir, md_path))

Expand All @@ -145,12 +133,9 @@ def test_compdef_regenerate_task(tmp_trestle_dir: str) -> None:
md_path = os.path.join(compdef_md_dir, test_comp)
_ = testutils.setup_for_compdef(trestle_root, test_comp, md_path)

regenerate_task = RegenerateTask(
tmp_trestle_dir,
AuthoredType.COMPDEF.value,
compdef_md_dir,
"",
)
compdef = AuthoredComponentDefinition(tmp_trestle_dir)
regenerate_task = RegenerateTask(compdef, compdef_md_dir)

assert regenerate_task.execute() == 0

# The compdef is a special case where each component has a separate markdown directory
Expand Down Expand Up @@ -184,45 +169,9 @@ def test_ssp_regenerate_task(tmp_trestle_dir: str) -> None:
)
assert ssp_assemble._run(args) == 0

regenerate_task = RegenerateTask(
tmp_trestle_dir,
AuthoredType.SSP.value,
ssp_md_dir,
ssp_index_path,
)
ssp_index = SSPIndex(ssp_index_path)
ssp = AuthoredSSP(tmp_trestle_dir, ssp_index)
regenerate_task = RegenerateTask(ssp, ssp_md_dir)

assert regenerate_task.execute() == 0
assert os.path.exists(os.path.join(tmp_trestle_dir, md_path))


def test_ssp_regenerate_task_no_index_path(tmp_trestle_dir: str) -> None:
"""Test ssp regenerate at the task level with failure"""
trestle_root = pathlib.Path(tmp_trestle_dir)
md_path = os.path.join(ssp_md_dir, test_ssp_output)

# Create initial SSP for testing
args = testutils.setup_for_ssp(trestle_root, test_prof, [test_comp], md_path)
ssp_generate = SSPGenerate()
assert ssp_generate._run(args) == 0

# create ssp from the markdown
ssp_assemble = SSPAssemble()
args = argparse.Namespace(
trestle_root=tmp_trestle_dir,
markdown=md_path,
output=test_ssp_output,
verbose=0,
name=None,
version=None,
regenerate=False,
compdefs=args.compdefs,
)
assert ssp_assemble._run(args) == 0
regenerate_task = RegenerateTask(
tmp_trestle_dir,
AuthoredType.SSP.value,
ssp_md_dir,
"",
)

with pytest.raises(FileNotFoundError):
regenerate_task.execute()
Loading

0 comments on commit 6766eca

Please sign in to comment.