Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Handle None return during link creation #104

Merged
merged 4 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions capella2polarion/converters/link_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ def create_links_for_work_item(
new: cabc.Iterable[str]
if isinstance(refs, common.ElementList):
new = refs.by_uuid # type: ignore[assignment]
elif refs is None:
logger.info(
'For model element %r attribute "%s" is not set',
obj._short_repr_(),
link_config.capella_attr,
)
continue
else:
assert hasattr(refs, "uuid"), "No 'uuid' on value"
new = [refs.uuid]
Expand All @@ -82,14 +89,11 @@ def create_links_for_work_item(
self._create(work_item.id, role_id, new, {})
)
except Exception as error:
error_text = f"{type(error).__name__} {str(error)}"
link_errors.extend(
[
f"Requested attribute: {link_config.capella_attr}",
error_text,
"--------",
]
error_message = make_link_logging_message(
f"{type(error).__name__} {str(error)}",
link_config.capella_attr,
)
link_errors.extend(error_message)

if link_errors:
for link_error in link_errors:
Expand Down Expand Up @@ -380,11 +384,20 @@ def _sorted_unordered_html_list(

def _resolve_attribute(
obj: common.GenericElement, attr_id: str
) -> common.ElementList[common.GenericElement] | common.GenericElement:
) -> common.ElementList[common.GenericElement] | common.GenericElement | None:
attr_name, _, map_id = attr_id.partition(".")
objs = getattr(obj, attr_name)
if map_id:
if map_id and objs is not None:
if isinstance(objs, common.GenericElement):
return _resolve_attribute(objs, map_id)
objs = objs.map(map_id)
return objs


def make_link_logging_message(message: str, capella_attr: str) -> list[str]:
"""Return a list of strings for a link logging message."""
return [
f"Requested attribute: {capella_attr!r}",
message,
"--------",
]
38 changes: 33 additions & 5 deletions tests/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,17 +459,22 @@ def test_create_links_custom_exchanges_resolver(
assert links == [expected]

@staticmethod
def test_create_links_missing_attribute(
def test_create_links_logs_error_when_no_uuid_is_found_on_value(
base_object: BaseObjectContainer, caplog: pytest.LogCaptureFixture
):
expected = (
"Link creation for \"<FakeModelObject 'Fake 1' (uuid1)>\" failed:"
"\n\tRequested attribute: attribute"
"\n\tRequested attribute: 'attribute'"
"\n\tAssertionError No 'uuid' on value"
"\n\t--------"
)
no_uuid = FakeModelObject("")
del no_uuid.uuid
base_object.mc.converter_session["uuid1"].capella_element.attribute = (
no_uuid
)

with caplog.at_level(logging.DEBUG):
with caplog.at_level(logging.ERROR):
link_serializer = link_converter.LinkSerializer(
base_object.pw.polarion_data_repo,
base_object.mc.converter_session,
Expand All @@ -481,13 +486,36 @@ def test_create_links_missing_attribute(
assert not links
assert caplog.messages[0] == expected

@staticmethod
def test_create_links_logs_warning_model_element_behind_attribute_is_none(
base_object: BaseObjectContainer, caplog: pytest.LogCaptureFixture
):
expected = (
"For model element \"<FakeModelObject 'Fake 1' (uuid1)>\" "
'attribute "attribute" is not set'
)

with caplog.at_level(logging.INFO):
link_serializer = link_converter.LinkSerializer(
base_object.pw.polarion_data_repo,
base_object.mc.converter_session,
base_object.pw.polarion_params.project_id,
base_object.c2pcli.capella_model,
)
links = link_serializer.create_links_for_work_item("uuid1")

assert not links
assert len(caplog.records) == 1
assert caplog.records[0].levelno == 20
assert caplog.records[0].message == expected

@staticmethod
def test_create_links_no_new_links_with_errors(
base_object: BaseObjectContainer, caplog: pytest.LogCaptureFixture
):
expected = (
"Link creation for \"<FakeModelObject 'Fake 2' (uuid2)>\" failed:"
"\n\tRequested attribute: non_existent_attr"
"\n\tRequested attribute: 'non_existent_attr'"
"\n\t"
)

Expand Down Expand Up @@ -538,7 +566,7 @@ def test_create_links_with_new_links_and_errors(
expected = (
"Link creation for \"<FakeModelObject 'Fake 2' (uuid2)>\" "
"partially successful. Some links were not created:"
"\n\tRequested attribute: non_existent_attr"
"\n\tRequested attribute: 'non_existent_attr'"
"\n\t"
)

Expand Down
Loading