From fea16046a88c0a5e8a9e4b789f0463c9c5f334d1 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Mon, 5 Feb 2024 11:48:52 -0500 Subject: [PATCH] python testing: Add PICS parser for xml (#31493) * python testing: Add PICS parser for xml Code blatently stolen from Jon Rhees. * Restyled by isort * remove some debug --------- Co-authored-by: Restyled.io --- .../TestMatterTestingSupport.py | 39 ++- src/python_testing/matter_testing_support.py | 33 ++- .../example_pics_xml_basic_info.xml | 250 ++++++++++++++++++ 3 files changed, 315 insertions(+), 7 deletions(-) create mode 100644 src/python_testing/test_testing/example_pics_xml_basic_info.xml diff --git a/src/python_testing/TestMatterTestingSupport.py b/src/python_testing/TestMatterTestingSupport.py index 9577b3bd112a3f..2ed29074a153bb 100644 --- a/src/python_testing/TestMatterTestingSupport.py +++ b/src/python_testing/TestMatterTestingSupport.py @@ -15,6 +15,7 @@ # limitations under the License. # +import os import time import typing from datetime import datetime, timedelta, timezone @@ -23,7 +24,8 @@ from chip.clusters.Types import Nullable, NullValue from chip.tlv import uint from matter_testing_support import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, - get_wait_seconds_from_set_time, parse_pics, type_matches, utc_time_in_matter_epoch) + get_wait_seconds_from_set_time, parse_pics, parse_pics_xml, type_matches, + utc_time_in_matter_epoch) from mobly import asserts, signals from taglist_and_topology_test_support import (TagProblem, create_device_type_list_for_root, create_device_type_lists, find_tag_list_problems, find_tree_roots, get_all_children, @@ -584,6 +586,41 @@ def test_root_node_tag_list_functions(self): problems = find_tag_list_problems(roots=[0], device_types={0: device_type_list}, endpoint_dict=endpoints) asserts.assert_equal(len(problems.keys()), 0, 'Unexpected problems found in root endpoint') + def pics_assert(self, pics: str, support: bool): + asserts.assert_equal(self.check_pics(pics), support, + f'Unexpected PICS value for {pics} - expected {support}, got {self.check_pics(pics)}') + + def test_xml_pics(self): + script_dir = os.path.dirname(os.path.realpath(__file__)) + with open(f'{script_dir}/test_testing/example_pics_xml_basic_info.xml') as f: + pics = parse_pics_xml(f.read()) + print(pics) + # force the parsed pics here to be in the config so we can check the check_pics function + self.matter_test_config.pics = pics + self.pics_assert('BINFO.S', True) + self.pics_assert('BINFO.S.A0000', True) + self.pics_assert('BINFO.S.A0001', True) + self.pics_assert('BINFO.S.A0002', True) + self.pics_assert('BINFO.S.A0003', True) + self.pics_assert('BINFO.S.A0004', True) + self.pics_assert('BINFO.S.A0005', True) + self.pics_assert('BINFO.S.A0006', True) + self.pics_assert('BINFO.S.A0007', True) + self.pics_assert('BINFO.S.A0008', True) + self.pics_assert('BINFO.S.A0009', True) + self.pics_assert('BINFO.S.A000a', True) + self.pics_assert('BINFO.S.A000b', True) + self.pics_assert('BINFO.S.A000c', True) + self.pics_assert('BINFO.S.A000d', True) + self.pics_assert('BINFO.S.A000e', True) + self.pics_assert('BINFO.S.A000f', True) + self.pics_assert('BINFO.S.A0010', True) + self.pics_assert('BINFO.S.A0011', False) + self.pics_assert('BINFO.S.A0012', True) + self.pics_assert('BINFO.S.A0013', True) + self.pics_assert('BINFO.S.A0014', False) + self.pics_assert('PICSDOESNOTEXIST', False) + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 5c3ec57504e0ac..4ddb4ce50fdf0e 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -18,6 +18,7 @@ import argparse import asyncio import builtins +import glob import inspect import json import logging @@ -29,6 +30,7 @@ import sys import typing import uuid +import xml.etree.ElementTree as ET from binascii import hexlify, unhexlify from dataclasses import asdict as dataclass_asdict from dataclasses import dataclass, field @@ -138,7 +140,7 @@ def get_default_paa_trust_store(root_path: pathlib.Path) -> pathlib.Path: return pathlib.Path.cwd() -def parse_pics(lines=typing.List[str]) -> dict[str, bool]: +def parse_pics(lines: typing.List[str]) -> dict[str, bool]: pics = {} for raw in lines: line, _, _ = raw.partition("#") @@ -156,11 +158,30 @@ def parse_pics(lines=typing.List[str]) -> dict[str, bool]: return pics -def read_pics_from_file(filename: str) -> dict[str, bool]: - """ Reads a dictionary of PICS from a file. """ - with open(filename, 'r') as f: - lines = f.readlines() - return parse_pics(lines) +def parse_pics_xml(contents: str) -> dict[str, bool]: + pics = {} + mytree = ET.fromstring(contents) + for pi in mytree.iter('picsItem'): + name = pi.find('itemNumber').text + support = pi.find('support').text + pics[name] = int(json.loads(support.lower())) == 1 + return pics + + +def read_pics_from_file(path: str) -> dict[str, bool]: + """ Reads a dictionary of PICS from a file (ci format) or directory (xml format). """ + if os.path.isdir(os.path.abspath(path)): + pics_dict = {} + for filename in glob.glob(f'{path}/*.xml'): + with open(filename, 'r') as f: + contents = f.read() + pics_dict.update(parse_pics_xml(contents)) + return pics_dict + + else: + with open(path, 'r') as f: + lines = f.readlines() + return parse_pics(lines) def type_matches(received_value, desired_type): diff --git a/src/python_testing/test_testing/example_pics_xml_basic_info.xml b/src/python_testing/test_testing/example_pics_xml_basic_info.xml new file mode 100644 index 00000000000000..3a8e279f3aa345 --- /dev/null +++ b/src/python_testing/test_testing/example_pics_xml_basic_info.xml @@ -0,0 +1,250 @@ + + + + + Basic Information Test Plan + + + + + + BINFO.S + Does the device implement the Basic Information Cluster as a server? + 9.1. Role - index.html[pdf] + O + true + + + + + + PIXIT.BINFO.PrimaryColor + ProductAppearance.PrimaryColor should reflect the product’s color + 10. PIXIT Definition - index.html[pdf] + M + 0x00 + + + PIXIT.BINFO.Finish + ProductAppearance.Finish should reflect the product’s finish + 10. PIXIT Definition - index.html[pdf] + M + 0x00 + + + + + + + + BINFO.S.A0000 + Does the DUT(server) support the DataModelRevision attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0001 + Does the DUT(server) support the VendorName attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0002 + Does the DUT(server) support the VendorID attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0003 + Does the DUT(server) support the ProductName attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0004 + Does the DUT(server) support the ProductID attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0005 + Does the DUT(server) support the NodeLabel attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0006 + Does the DUT(server) support the Location attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0007 + Does the DUT(server) support the HardwareVersion attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0008 + Does the DUT(server) support the HardwareVersionString attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0009 + Does the DUT(server) support the SoftwareVersion attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A000a + Does the DUT(server) support the SoftwareVersionString attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A000b + Does the DUT(server) support the ManufacturingDate attribute? + 9.2.1. Attributes - index.html[pdf] + O + true + + + BINFO.S.A000c + Does the DUT(server) support the PartNumber attribute? + 9.2.1. Attributes - index.html[pdf] + O + true + + + BINFO.S.A000d + Does the DUT(server) support the ProductURL attribute? + 9.2.1. Attributes - index.html[pdf] + O + true + + + BINFO.S.A000e + Does the DUT(server) support the ProductLabel attribute? + 9.2.1. Attributes - index.html[pdf] + O + true + + + BINFO.S.A000f + Does the DUT(server) support the SerialNumber attribute? + 9.2.1. Attributes - index.html[pdf] + O + true + + + BINFO.S.A0010 + Does the DUT(server) support the LocalConfigDisabled attribute? + 9.2.1. Attributes - index.html[pdf] + O + true + + + BINFO.S.A0011 + Does the DUT(server) support the Reachable attribute? + 9.2.1. Attributes - index.html[pdf] + O + false + + + BINFO.S.A0012 + Does the DUT(server) support the UniqueID attribute? + 9.2.1. Attributes - index.html[pdf] + O + true + + + BINFO.S.A0013 + Does the DUT(server) support the CapabilityMinima attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0014 + Does the DUT(server) support the ProductAppearance attribute? + 9.2.1. Attributes - index.html[pdf] + O + false + + + + + + BINFO.S.E00 + Does the DUT(server) support the StartUp event? + 9.2.2. Events - index.html[pdf] + M + true + + + BINFO.S.E01 + Does the DUT(server) support the ShutDown event? + 9.2.2. Events - index.html[pdf] + O + false + + + BINFO.S.E02 + Does the DUT(server) support the Leave event? + 9.2.2. Events - index.html[pdf] + O + false + + + BINFO.S.E03 + Does the DUT(server) support the ReachableChanged event? + 9.2.2. Events - index.html[pdf] + M + false + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file