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

Add error handling for invalid/unknown parameter type #42

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

medley56
Copy link
Owner

@medley56 medley56 commented Mar 28, 2024

Handle Errors for Unsupported/Invalid Parameter Types

  • Add error handling for unknown and invalid parameter type element during XTCE parsing

Checklist

  • Changes are fully implemented without dangling issues or TODO items
  • Deprecated/superseded code is removed or marked with deprecation warning
  • Current dependencies have been properly specified and old dependencies removed
  • New code/functionality has accompanying tests and any old tests have been updated to match any new assumptions
  • The changelog.md has been updated

@medley56 medley56 linked an issue Mar 28, 2024 that may be closed by this pull request
@medley56 medley56 force-pushed the 13-add-error-handling-for-unsupported-parametertype-element branch from 5bb4ae0 to 67b561e Compare March 28, 2024 20:07
@medley56 medley56 marked this pull request as ready for review March 28, 2024 20:09
@@ -1791,6 +1805,8 @@ def test_parsing_xtce_document(test_data_dir):
with open(test_data_dir / "test_xtce.xml") as x:
xdef = xtcedef.XtcePacketDefinition(x, ns=TEST_NAMESPACE)

xdef._populate_sequence_container_cache()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? It looks like you've already added it to the __init__()

This seems like it could be confusing/a gotcha if we are required to call private methods in downstream things to clear/reinitialize anything.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good catch. I was playing around to see if we could get away with not populating the whole cache ahead of time (do it on the first packet parse) but it's necessary to sort out container inheritance so I added it back into the init method.

Will fix.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an easy way to manipulate this through code rather than adding these xml files? I had a hard time finding the invalid portion here because there is so much base verbosity you need to define a valid XTCE in the first place, whereas if you could do something like (wrapping it all in a fixture or something else to help automate some of the cleanup)

# Load in a base/template xtce
test_xtce = load_xml()
# Replace a single entry you want in the tree with your invalid portion
test_xtce["parameter_type"].name = "INVALID_NAME"
# Write this out to a temporary buffer
with bytesIO() as f:
    test_xtce.write(f)
    # Reload with this package's loading routine
    f.seek(0)
    xdef = xtcedef.XtcePacketDefinition(f, ns=TEST_NAMESPACE)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm this is an interesting idea. I'll explore this.

Copy link
Owner Author

@medley56 medley56 Mar 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't polished it but this is what I came up with as a first pass. To be honest, this is super ugly and I'm not sure it's worth it. If I can make this a little more streamlined I'll be happier. I also think I now need to make a more generic test_xtce.xml file that is more suitable to these changes.

def test_invalid_parameter_type_error(test_data_dir):
    """Test proper reporting of an invalid parameter type element"""
    with io.BytesIO() as temp:
        with open(test_data_dir / 'test_xtce.xml', mode='r') as x:
            etree = ElementTree.parse(x)
            parameter_type_set = etree.find(".//xtce:ParameterTypeSet", TEST_NAMESPACE)
            invalid_type = ElementTree.Element(f"{{{XTCE_URI}}}InvalidParameterType")
            invalid_type.set("name", "TEST_INVALID_Type")
            parameter_type_set.append(invalid_type)

            parameter_set = etree.find(".//xtce:ParameterSet", TEST_NAMESPACE)
            invalid_parameter_ref = ElementTree.Element(f"{{{XTCE_URI}}}Parameter")
            invalid_parameter_ref.set("name", "TEST_INVALID")
            invalid_parameter_ref.set("parameterTypeRef", "TEST_INVALID_Type")
            parameter_set.append(invalid_parameter_ref)

            entry_list = etree.find(".//xtce:SequenceContainer[@name='JPSS_ATT_EPHEM']/xtce:EntryList", TEST_NAMESPACE)
            parameter_instance = ElementTree.Element(f"{{{XTCE_URI}}}ParameterRefEntry")
            parameter_instance.set("parameterRef", "TEST_INVALID")
            entry_list.append(parameter_instance)
        etree.write(temp)

        temp.seek(0)
        with pytest.raises(xtcedef.InvalidParameterTypeError):
            xtcedef.XtcePacketDefinition(temp, ns=TEST_NAMESPACE)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, that isn't a lot more descriptive than the added XTCE files you had, and hopefully there aren't a lot of extra files that we need to make for the various test scenarios.

One additional thing in case it sparks some idea for you is whether you can simplify the test to only go through the single method you're interested in testing rather than parsing the full document.

def test_parse_sequence_container():
    # Open a base test file to give you a good instance
    with open(test_data_dir / 'test_xtce.xml', mode='r') as x:
        packet_def = xtcedef.XtcePacketDefinition(temp, ns=TEST_NAMESPACE)

    # Create a simple ETree subsection for your individual test
    small_etree_sequence_container = etree.ETree(
        """<xtce:ParameterRefType><other inline elements ...>"""
    )
    with pytest.raises():
        packet_def.parse_sequence_container(small_etree_sequence_container)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good thought. The problem there is that the changes I need to make to the document are in all different places, not in a contiguous chunk. Still, that notion would simplify the fixture a bit.

I haven't given up on this yet because I would like to reduce the number of test data files whenever possible.

@medley56 medley56 force-pushed the 13-add-error-handling-for-unsupported-parametertype-element branch from 67b561e to 0979d6c Compare March 29, 2024 03:13
@medley56 medley56 self-assigned this Apr 1, 2024
@medley56 medley56 force-pushed the 13-add-error-handling-for-unsupported-parametertype-element branch from 0979d6c to ad538a3 Compare April 1, 2024 18:07
@medley56 medley56 added this to the Version 4.3.0 Release milestone Apr 2, 2024
@medley56 medley56 added the enhancement New feature or request label Apr 2, 2024
@medley56
Copy link
Owner Author

medley56 commented Apr 2, 2024

I want to get the testing right for this so I'm moving this PR to the 4.3.0 milestone so I can release 4.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add error handling for unsupported ParameterType element
2 participants