Skip to content

Commit

Permalink
[matter_yamltests] Add an optional definition property to pseudo clus…
Browse files Browse the repository at this point in the history
…ter in order to benefits from the built-in error reporting (#25061)
  • Loading branch information
vivien-apple authored and pull[bot] committed Nov 20, 2023
1 parent 794e163 commit 1075132
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 7 deletions.
15 changes: 13 additions & 2 deletions scripts/py_matter_yamltests/matter_yamltests/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
import enum
import functools
import glob
from typing import List
import io
from typing import List, Optional

from matter_idl.matter_idl_types import *
from matter_idl.zapxml import ParseSource, ParseXmls

from .pseudo_clusters.pseudo_clusters import PseudoClusters


class _ItemType(enum.Enum):
Cluster = 0
Expand Down Expand Up @@ -240,7 +243,7 @@ def __enforce_casing(self, target_name: str, targets: list):
f'Unknown target {target_name}. Did you mean {name} ?')


def SpecDefinitionsFromPaths(paths: str):
def SpecDefinitionsFromPaths(paths: str, pseudo_clusters: Optional[PseudoClusters] = PseudoClusters([])):
def sort_with_global_attribute_first(a, b):
if a.endswith('global-attributes.xml'):
return -1
Expand All @@ -262,4 +265,12 @@ def sort_with_global_attribute_first(a, b):

filenames.sort(key=functools.cmp_to_key(sort_with_global_attribute_first))
sources = [ParseSource(source=name) for name in filenames]

for pseudo_cluster in pseudo_clusters.clusters:
if pseudo_cluster.definition is not None:
name = pseudo_cluster.name
definition = pseudo_cluster.definition
sources = (
sources + [ParseSource(source=io.StringIO(definition), name=name)])

return SpecDefinitions(sources)
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,36 @@
from ..pseudo_cluster import PseudoCluster
from .accessory_server_bridge import AccessoryServerBridge

_DEFINITION = '''<?xml version="1.0"?>
<configurator>
<cluster>
<name>DelayCommands</name>
<code>0xFFF1FD02</code>
<command source="client" code="0" name="WaitForCommissioning">
</command>
<command source="client" code="1" name="WaitForCommissionee">
<arg name="nodeId" type="node_id"/>
<arg name="expireExistingSession" type="bool" optional="true"/>
</command>
<command source="client" code="2" name="WaitForMs">
<arg name="ms" type="int16u"/>
</command>
<command source="client" code="3" name="WaitForMessage">
<arg name="registerKey" type="char_string"/>
<arg name="message" type="char_string"/>
</command>
</cluster>
</configurator>
'''


class DelayCommands(PseudoCluster):
name = 'DelayCommands'
definition = _DEFINITION

async def WaitForMs(self, request):
duration_in_ms = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,28 @@

from ..pseudo_cluster import PseudoCluster

_DEFINITION = '''<?xml version="1.0"?>
<configurator>
<cluster>
<name>LogCommands</name>
<code>0xFFF1FD01</code>
<command source="client" code="0" name="Log">
<arg name="message" type="char_string"/>
</command>
<command source="client" code="1" name="UserPrompt">
<arg name="message" type="char_string"/>
<arg name="expectedValue" type="char_string" optional="true"/>
</command>
</cluster>
</configurator>
'''


class LogCommands(PseudoCluster):
name = 'LogCommands'
definition = _DEFINITION

async def UserPrompt(self, request):
pass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,53 @@
from ..pseudo_cluster import PseudoCluster
from .accessory_server_bridge import AccessoryServerBridge

_DEFINITION = '''<?xml version="1.0"?>
<configurator>
<cluster>
<name>SystemCommands</name>
<code>0xFFF1FD03</code>
<command source="client" code="0" name="Start">
<arg name="registerKey" type="char_string" optional="true"/>
<arg name="discriminator" type="int16u" optional="true"/>
<arg name="port" type="int16u" optional="true"/>
<arg name="minCommissioningTimeout" type="int16u" optional="true"/>
<arg name="kvs" type="char_string" optional="true"/>
<arg name="filepath" type="char_string" optional="true"/>
<arg name="otaDownloadPath" type="char_string" optional="true"/>
</command>
<command source="client" code="1" name="Stop">
<arg name="registerKey" type="char_string" optional="true"/>
</command>
<command source="client" code="2" name="Reboot">
<arg name="registerKey" type="char_string" optional="true"/>
</command>
<command source="client" code="3" name="FactoryReset">
<arg name="registerKey" type="char_string" optional="true"/>
</command>
<command source="client" code="4" name="CreateOtaImage">
<arg name="otaImageFilePath" type="char_string"/>
<arg name="rawImageFilePath" type="char_string"/>
<arg name="rawImageContent" type="char_string"/>
</command>
<command source="client" code="5" name="CompareFiles">
<arg name="file1" type="char_string"/>
<arg name="file2" type="char_string"/>
</command>
</cluster>
</configurator>
'''


class SystemCommands(PseudoCluster):
name = 'SystemCommands'
definition = _DEFINITION

async def Start(self, request):
AccessoryServerBridge.start(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ class CustomCommand(PseudoCluster):
async def MyCustomMethod(self, request):
pass
async def MyCustomMethod(self, request):
pass
It can then be called from any test step as:
- label: "Call a custom method"
Expand All @@ -46,8 +43,37 @@ async def MyCustomMethod(self, request):
values:
- name: "MyCustomParameter"
value: "this_is_a_custom_value"
A pseudo cluster can optionally declare a definition in order to benefit
from automatic command names checking and argument names validation.
For example, the 'CustomCommands' pseudo cluster can be implemented as:
_DEFINITION = '''<?xml version="1.0"?>
<configurator>
<cluster>
<name>CustomCommands</name>
<code>0xFFF1FD00</code>
<command source="client" code="0" name="MyCustomMethod">
<arg name="MyCustomParameter" type="char_string"/>
</command>
</cluster>
</configurator>
'''
class CustomCommand(PseudoCluster):
name = 'CustomCommands'
definition = _DEFINITION
async def MyCustomMethod(self, request):
pass
"""

@abstractproperty
def name(self):
pass

@property
def definition(self):
return None
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

class PseudoClusters:
def __init__(self, clusters: list[PseudoCluster]):
self.__clusters = clusters
self.clusters = clusters

def supports(self, request) -> bool:
return False if self.__get_command(request) is None else True
Expand All @@ -38,7 +38,7 @@ async def execute(self, request):
return status, []

def __get_command(self, request):
for cluster in self.__clusters:
for cluster in self.clusters:
if request.cluster == cluster.name and getattr(cluster, request.command, None):
return getattr(cluster, request.command)
return None
Expand Down

0 comments on commit 1075132

Please sign in to comment.