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

[matter_yamltests] Add an optional definition property to pseudo clus… #25061

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
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 benefits
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
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