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

Updated spec_parsing.py to now use the data model directory from python package #36596

Merged
merged 45 commits into from
Dec 13, 2024
Merged
Changes from 8 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
38f47de
Added modified spec_parsing.py to now use the data model package
vatsalghelani-csa Nov 21, 2024
946f316
Restyled by autopep8
restyled-commits Nov 21, 2024
a51f664
Restyled by isort
restyled-commits Nov 21, 2024
923470f
Fixing the cosmetic changes
vatsalghelani-csa Nov 21, 2024
99fcef5
Use chip.testing as a module to extract, work via PosixPath directory
vatsalghelani-csa Nov 25, 2024
d14f4e0
Restyled by autopep8
restyled-commits Nov 25, 2024
c57a3c1
Restyled by isort
restyled-commits Nov 25, 2024
0d9eb87
Fixed correct directory search
vatsalghelani-csa Nov 25, 2024
296c91f
Solving the wrapping for try-catch according to comments
vatsalghelani-csa Nov 26, 2024
d07b52f
Restyled by autopep8
restyled-commits Nov 26, 2024
c849ea9
Added fixes for both a pre-built location or a full path
vatsalghelani-csa Dec 3, 2024
e3adddd
Fix comment
vatsalghelani-csa Dec 3, 2024
e9ba668
Restyled by autopep8
restyled-commits Dec 3, 2024
f08316e
Adding importlib.resources capability
vatsalghelani-csa Dec 4, 2024
70e3622
Restyled by autopep8
restyled-commits Dec 4, 2024
1b3494e
Restyled by isort
restyled-commits Dec 4, 2024
d28c40e
Fixed _spec_ path error
vatsalghelani-csa Dec 4, 2024
891c278
Fixed to use module as string
vatsalghelani-csa Dec 4, 2024
fd5ab83
Removed unused import
vatsalghelani-csa Dec 4, 2024
68ab20e
Added fixes for path issues
vatsalghelani-csa Dec 5, 2024
0a3d947
Fixing the xml not found error
vatsalghelani-csa Dec 5, 2024
bd4172f
Restyled by autopep8
restyled-commits Dec 5, 2024
5b758e6
Fixed code lint error
vatsalghelani-csa Dec 5, 2024
aa5564e
Fixed code lint error tree
vatsalghelani-csa Dec 5, 2024
79a7db4
Fixed importlib errors
vatsalghelani-csa Dec 6, 2024
fb9f680
Fixed code lint
vatsalghelani-csa Dec 6, 2024
4120e42
Fixed errors
vatsalghelani-csa Dec 6, 2024
4a986d1
Restyled by autopep8
restyled-commits Dec 6, 2024
3c5442e
Some type updates and iteration logic updates to be consistent
andy31415 Dec 9, 2024
0793ba0
Remove unused method
andy31415 Dec 9, 2024
35edf22
Fix logic to match existing usage: we need clusters to be part of the…
andy31415 Dec 9, 2024
ec01ebb
Restyled by autopep8
restyled-commits Dec 9, 2024
1e7a1e2
Restyled by isort
restyled-commits Dec 9, 2024
931a746
remove unused import
andy31415 Dec 9, 2024
222c742
Cleanup some odd comments
andy31415 Dec 9, 2024
100ac23
Another update to avoid using globs
andy31415 Dec 9, 2024
2f2352a
Fix up types and return
andy31415 Dec 9, 2024
cd7a9de
Remove unused import
andy31415 Dec 9, 2024
c1611d2
Another dep cleanup
andy31415 Dec 9, 2024
b8b50fa
Remove one test step: unclear about the value of throwing a specparse…
andy31415 Dec 9, 2024
4bcc9a1
Remove unused import
andy31415 Dec 9, 2024
bb0ace9
update logic to throw specparsing when no XMLs found ... this preserv…
andreilitvin Dec 10, 2024
9853752
Make data model directory consistent with cluster logic
andreilitvin Dec 10, 2024
37f230e
Comments update
andreilitvin Dec 10, 2024
ddde2d9
Added warning levels for checking xml
vatsalghelani-csa Dec 13, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@

import glob
import logging
import os
import pathlib
import typing
import xml.etree.ElementTree as ElementTree
from copy import deepcopy
from dataclasses import dataclass
from enum import Enum, auto
from typing import Callable, Optional
from typing import Callable, Optional, Union

import chip.clusters as Clusters
import chip.testing
import chip.testing.conformance as conformance_support
from chip.testing.conformance import (OPTIONAL_CONFORM, TOP_LEVEL_CONFORMANCE_TAGS, ConformanceDecision, ConformanceException,
ConformanceParseParameters, feature, is_disallowed, mandatory, optional, or_operation,
Expand Down Expand Up @@ -518,50 +519,75 @@ class DataModelLevel(str, Enum):
kDeviceType = 'device_types'


def _get_data_model_root() -> str:
"""Attempts to find ${CHIP_ROOT}/data_model or equivalent."""
def _get_data_model_root() -> pathlib.PosixPath:
"""Attempts to find the 'data_model' directory inside the 'chip.testing' package."""
try:
# Locate the directory where the 'chip.testing' module is located
package_dir = pathlib.Path(chip.testing.__file__).parent

# Since this class is generally in a module, we have to rely on being bootstrapped or
# we use CWD if we cannot
choices = [os.getcwd()]
# Construct the path to the 'data_model' directory (assuming this structure)
data_model_root = package_dir / 'data_model'

if 'PW_PROJECT_ROOT' in os.environ:
choices.insert(0, os.environ['PW_PROJECT_ROOT'])
if not data_model_root.exists():
raise FileNotFoundError(f"Data model directory not found in the package at {data_model_root}.")

for c in choices:
data_model_path = os.path.join(c, 'data_model')
if os.path.exists(os.path.join(data_model_path, 'master', 'scraper_version')):
return data_model_path
raise FileNotFoundError('Cannot find a CHIP_ROOT/data_model path. Tried %r as prefixes.' % choices)
return data_model_root

except Exception as e:
raise FileNotFoundError(f"Failed to find the data model root: {e}")
vatsalghelani-csa marked this conversation as resolved.
Show resolved Hide resolved

def get_data_model_directory(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str], data_model_level: DataModelLevel) -> str:
if data_model_directory == PrebuiltDataModelDirectory.k1_3:
return os.path.join(_get_data_model_root(), '1.3', data_model_level)
elif data_model_directory == PrebuiltDataModelDirectory.k1_4:
return os.path.join(_get_data_model_root(), '1.4', data_model_level)
elif data_model_directory == PrebuiltDataModelDirectory.kMaster:
return os.path.join(_get_data_model_root(), 'master', data_model_level)

def get_data_model_directory(data_model_directory: Union[PrebuiltDataModelDirectory, str], data_model_level: str) -> pathlib.PosixPath:
"""
Get the directory of the data model for a specific version and level from the installed package.
"""
data_model_root = _get_data_model_root()

# Build path based on the version and data model level
if isinstance(data_model_directory, PrebuiltDataModelDirectory):
andy31415 marked this conversation as resolved.
Show resolved Hide resolved
version_map = {
PrebuiltDataModelDirectory.k1_3: '1.3',
PrebuiltDataModelDirectory.k1_4: '1.4',
PrebuiltDataModelDirectory.kMaster: 'master',
}

version = version_map.get(data_model_directory)
if not version:
raise ValueError(f"Unsupported data model directory: {data_model_directory}")

return data_model_root / version / data_model_level
else:
return data_model_directory
# If it's a custom directory, return it directly
vatsalghelani-csa marked this conversation as resolved.
Show resolved Hide resolved
return pathlib.Path(data_model_directory)


def build_xml_clusters(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.k1_4) -> tuple[dict[uint, XmlCluster], list[ProblemNotice]]:
dir = get_data_model_directory(data_model_directory, DataModelLevel.kCluster)
def build_xml_clusters(data_model_directory: Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.k1_4) -> tuple[dict[int, XmlCluster], list[ProblemNotice]]:
# Get the data model directory path inside the package
dir = get_data_model_directory(data_model_directory, 'clusters')

clusters: dict[int, XmlCluster] = {}
pure_base_clusters: dict[str, XmlCluster] = {}
ids_by_name: dict[str, int] = {}
problems: list[ProblemNotice] = []
files = glob.glob(f'{dir}/*.xml')
if not files:
raise SpecParsingException(f'No data model files found in specified directory {dir}')

for xml in files:
logging.info(f'Parsing file {xml}')
tree = ElementTree.parse(f'{xml}')
root = tree.getroot()
add_cluster_data_from_xml(root, clusters, pure_base_clusters, ids_by_name, problems)
try:
# Use pathlib.Path to list all XML files in the data model directory
xml_files = [f for f in dir.glob('**/*.xml')] # Recursively find all .xml files

if not xml_files:
raise SpecParsingException(f'No XML files found in the specified package directory {dir}')

# Parse each XML file found inside the package
for xml in xml_files:
logging.info(f'Parsing file {xml}')
# Open and parse each XML file from the directory
with xml.open('r') as file:
tree = ElementTree.parse(file)
root = tree.getroot()
add_cluster_data_from_xml(root, clusters, pure_base_clusters, ids_by_name, problems)

except Exception as e:
raise SpecParsingException(f"Error reading XML files from the package: {e}")
vatsalghelani-csa marked this conversation as resolved.
Show resolved Hide resolved

# There are a few clusters where the conformance columns are listed as desc. These clusters need specific, targeted tests
# to properly assess conformance. Here, we list them as Optional to allow these for the general test. Targeted tests are described below.
Expand All @@ -578,6 +604,7 @@ def remove_problem(location: typing.Union[CommandPathLocation, FeaturePathLocati
mask = clusters[descriptor_id].feature_map[code]
clusters[descriptor_id].features[mask].conformance = optional()
remove_problem(FeaturePathLocation(endpoint_id=0, cluster_id=descriptor_id, feature_code=code))

action_id = Clusters.Actions.id
for c in Clusters.ClusterObjects.ALL_ACCEPTED_COMMANDS[action_id]:
clusters[action_id].accepted_commands[c].conformance = optional()
Expand Down
Loading