Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c6908e9
Add automatic device attribute dump on composition test failures:
j-ororke Sep 17, 2025
e2154ab
Restyled by autopep8
restyled-commits Sep 17, 2025
9c36c19
Remove duplicate on_fail() and unused import from TC_DeviceConformance
j-ororke Sep 17, 2025
5edf777
Removing unused logging import
j-ororke Sep 17, 2025
1438550
Change inheritance order to enable automatic device attribute dump on…
j-ororke Sep 17, 2025
9abde9b
Restyled by autopep8
restyled-commits Sep 17, 2025
dc5df9e
resolving linting errors and making sure that on test failures we emi…
j-ororke Sep 17, 2025
6756ca7
Restyled by autopep8
restyled-commits Sep 17, 2025
10f1ca6
Update basic_composition.py
j-ororke Sep 24, 2025
a026a85
Update basic_composition.py
j-ororke Sep 24, 2025
b1b1a4e
Merge branch 'master' into create_global_attr_log_function
j-ororke Sep 24, 2025
b149ff6
Restyled by autopep8
restyled-commits Sep 24, 2025
6992404
Move device attribute dumping from BasicCompositionTests to MatterBas…
j-ororke Oct 1, 2025
fee2649
Restyled by autopep8
restyled-commits Oct 1, 2025
855d881
Merge branch 'master' into create_global_attr_log_function
j-ororke Oct 1, 2025
13fb594
Merge branch 'master' into create_global_attr_log_function
j-ororke Oct 16, 2025
530ac3a
Fix Python 3.11 compatibility and improve test failure User Experience:
j-ororke Oct 16, 2025
f2fc773
removed duplicate log_structured_data function from basic_composition…
j-ororke Nov 6, 2025
7c93c8c
removed duplicate log_structured_data function from basic_composition…
j-ororke Nov 6, 2025
914426f
Restyled by autopep8
restyled-commits Nov 6, 2025
127cb15
Resolving linting error
j-ororke Nov 6, 2025
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
13 changes: 3 additions & 10 deletions src/python_testing/TC_DeviceBasicComposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def check_no_duplicates(obj: Any) -> None:
raise ValueError(f"Value {str(obj)} contains duplicate values")


class TC_DeviceBasicComposition(MatterBaseTest, BasicCompositionTests):
class TC_DeviceBasicComposition(BasicCompositionTests, MatterBaseTest):
@async_test_body
async def setup_class(self):
super().setup_class()
Expand Down Expand Up @@ -966,15 +966,8 @@ def test_TC_IDM_12_1(self):
json_str, txt_str = self.dump_wildcard(dump_device_composition_path)

# Structured dump so we can pull these back out of the logs
def log_structured_data(start_tag: str, dump_string):
lines = dump_string.splitlines()
logging.info(f'{start_tag}BEGIN ({len(lines)} lines)====')
for line in lines:
logging.info(f'{start_tag}{line}')
logging.info(f'{start_tag}END ====')

log_structured_data('==== json: ', json_str)
log_structured_data('==== txt: ', txt_str)
self.log_structured_data('==== json: ', json_str)
self.log_structured_data('==== txt: ', txt_str)

@async_test_body
async def test_TC_DESC_2_1(self):
Expand Down
2 changes: 1 addition & 1 deletion src/python_testing/TC_DeviceConformance.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main


class TC_DeviceConformance(MatterBaseTest, DeviceConformanceTests):
class TC_DeviceConformance(DeviceConformanceTests, MatterBaseTest):
@async_test_body
async def setup_class(self):
super().setup_class()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def setup_class(self):
self.stored_global_wildcard = None

def teardown_class(self):
"""Final teardown after all tests: log all problems.
"""Final teardown after all tests: log all problems and dump device attributes if available.
Test authors may overwrite this method in the derived class to perform teardown that is common for all tests
This function is called only once per class. To perform teardown after each test, use teardown_test.
Test authors that implement steps in this function need to be careful of step handling if there is
Expand All @@ -216,6 +216,9 @@ def teardown_class(self):

"""
if len(self.problems) > 0:
# Attempt to dump device attribute data for debugging when problems are found
self._dump_device_attributes_on_failure()

LOGGER.info("###########################################################")
LOGGER.info("Problems found:")
LOGGER.info("===============")
Expand All @@ -224,6 +227,42 @@ def teardown_class(self):
LOGGER.info("###########################################################")
super().teardown_class()

def _dump_device_attributes_on_failure(self):
"""
Dump device attribute data when problems are found for debugging purposes.

This method attempts to generate a device attribute dump if the test has
collected endpoint data. It's designed to be safe and not interfere with
the original test failure reporting.
"""
try:
# Check if we have endpoints_tlv data (from BasicCompositionTests or similar)
if hasattr(self, 'endpoints_tlv') and self.endpoints_tlv:
# Check if we have the dump_wildcard method (from BasicCompositionTests)
if hasattr(self, 'dump_wildcard'):
_, txt_str = self.dump_wildcard(None)
# Only dump the text format - it's more readable for debugging
self.log_structured_data('==== FAILURE_DUMP_txt: ', txt_str)
except (AttributeError, KeyError, ValueError, TypeError):
# Don't let data access or serialization errors interfere with the original test failure
pass

def log_structured_data(self, start_tag: str, dump_string: str):
"""Log structured data with a clear start and end marker.

This function is used to output device attribute dumps and other structured
data to logs in a format that can be easily extracted for debugging.

Args:
start_tag: A prefix tag to identify the type of data being logged
dump_string: The data to be logged
"""
lines = dump_string.splitlines()
LOGGER.info(f'{start_tag}BEGIN ({len(lines)} lines)====')
for line in lines:
LOGGER.info(f'{start_tag}{line}')
LOGGER.info(f'{start_tag}END ====')

def setup_test(self):
"""Set up for each individual test execution.

Expand Down
Loading