Skip to content

Commit 159cd5f

Browse files
authored
Merge branch 'master' into feature/basic-app-install-flow
2 parents 3ae484e + 1fe5d3c commit 159cd5f

File tree

4 files changed

+97
-4
lines changed

4 files changed

+97
-4
lines changed

examples/kotlin-matter-controller/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ the top Matter directory:
109109
```
110110

111111
The Java executable file `kotlin-matter-controller` will be generated at
112-
`out/android-x86-kotlin-matter-controller/bin/`
112+
`out/linux-x64-kotlin-matter-controller/bin/`
113113

114114
Run the kotlin-matter-controller
115115

scripts/setup/requirements.nxp.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
crc>=7.0.0
12
jsonschema>=4.17.0
23
pycrypto>=2.6.1
34
pycryptodome>=3.20.0

src/python_testing/TestConformanceSupport.py

+56-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import xml.etree.ElementTree as ElementTree
1919

20-
from conformance_support import ConformanceDecision, ConformanceParseParameters, parse_callable_from_xml
20+
from conformance_support import ConformanceDecision, ConformanceException, ConformanceParseParameters, parse_callable_from_xml
2121
from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main
2222
from mobly import asserts
2323

@@ -616,6 +616,61 @@ def test_conformance_otherwise(self):
616616
asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.PROVISIONAL)
617617
asserts.assert_equal(str(xml_callable), 'AB & !CD, P')
618618

619+
def test_conformance_greater(self):
620+
# AB, [CD]
621+
xml = ('<mandatoryConform>'
622+
'<greaterTerm>'
623+
'<attribute name="attr1" />'
624+
'<literal value="1" />'
625+
'</greaterTerm>'
626+
'</mandatoryConform>')
627+
et = ElementTree.fromstring(xml)
628+
xml_callable = parse_callable_from_xml(et, self.params)
629+
# TODO: switch this to check greater than once the update to the base is done (#33422)
630+
asserts.assert_equal(xml_callable(0x00, [], []), ConformanceDecision.OPTIONAL)
631+
asserts.assert_equal(str(xml_callable), 'attr1 > 1')
632+
633+
# Ensure that we can only have greater terms with exactly 2 value
634+
xml = ('<mandatoryConform>'
635+
'<greaterTerm>'
636+
'<attribute name="attr1" />'
637+
'<attribute name="attr2" />'
638+
'<literal value="1" />'
639+
'</greaterTerm>'
640+
'</mandatoryConform>')
641+
et = ElementTree.fromstring(xml)
642+
try:
643+
xml_callable = parse_callable_from_xml(et, self.params)
644+
asserts.fail("Incorrectly parsed bad greaterTerm XML with > 2 values")
645+
except ConformanceException:
646+
pass
647+
648+
xml = ('<mandatoryConform>'
649+
'<greaterTerm>'
650+
'<attribute name="attr1" />'
651+
'</greaterTerm>'
652+
'</mandatoryConform>')
653+
et = ElementTree.fromstring(xml)
654+
try:
655+
xml_callable = parse_callable_from_xml(et, self.params)
656+
asserts.fail("Incorrectly parsed bad greaterTerm XML with < 2 values")
657+
except ConformanceException:
658+
pass
659+
660+
# Only attributes and literals allowed because arithmetic operations require values
661+
xml = ('<mandatoryConform>'
662+
'<greaterTerm>'
663+
'<feature name="AB" />'
664+
'<literal value="1" />'
665+
'</greaterTerm>'
666+
'</mandatoryConform>')
667+
et = ElementTree.fromstring(xml)
668+
try:
669+
xml_callable = parse_callable_from_xml(et, self.params)
670+
asserts.fail("Incorrectly parsed greater term with feature value")
671+
except ConformanceException:
672+
pass
673+
619674

620675
if __name__ == "__main__":
621676
default_matter_test_main()

src/python_testing/conformance_support.py

+39-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@
3333
AND_TERM = 'andTerm'
3434
OR_TERM = 'orTerm'
3535
NOT_TERM = 'notTerm'
36+
GREATER_TERM = 'greaterTerm'
3637
FEATURE_TAG = 'feature'
3738
ATTRIBUTE_TAG = 'attribute'
3839
COMMAND_TAG = 'command'
3940
CONDITION_TAG = 'condition'
41+
LITERAL_TAG = 'literal'
4042

4143

4244
class ConformanceException(Exception):
@@ -123,6 +125,18 @@ def __str__(self):
123125
return 'P'
124126

125127

128+
class literal:
129+
def __init__(self, value: str):
130+
self.value = int(value)
131+
132+
def __call__(self):
133+
# This should never be called
134+
raise ConformanceException('Literal conformance function should not be called - this is simply a value holder')
135+
136+
def __str__(self):
137+
return str(self.value)
138+
139+
126140
class feature:
127141
def __init__(self, requiredFeature: uint, code: str):
128142
self.requiredFeature = requiredFeature
@@ -267,8 +281,25 @@ def __str__(self):
267281
op_strs = [str(op) for op in self.op_list]
268282
return f'({" | ".join(op_strs)})'
269283

270-
# TODO: add xor operation once it's required
271-
# TODO: how would equal and unequal operations work here?
284+
285+
class greater_operation:
286+
def _type_ok(self, op: Callable):
287+
return type(op) == attribute or type(op) == literal
288+
289+
def __init__(self, op1: Callable, op2: Callable):
290+
if not self._type_ok(op1) or not self._type_ok(op2):
291+
raise ConformanceException('Arithmetic operations can only have attribute or literal value children')
292+
self.op1 = op1
293+
self.op2 = op2
294+
295+
def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision:
296+
# For now, this is fully optional, need to implement this properly later, but it requires access to the actual attribute values
297+
# We need to reach into the attribute, but can't use it directly because the attribute callable is an EXISTENCE check and
298+
# the arithmetic functions require a value.
299+
return ConformanceDecision.OPTIONAL
300+
301+
def __str__(self):
302+
return f'{str(self.op1)} > {str(self.op2)}'
272303

273304

274305
class otherwise:
@@ -325,6 +356,8 @@ def parse_callable_from_xml(element: ElementTree.Element, params: ConformancePar
325356
return command(params.command_map[element.get('name')], element.get('name'))
326357
elif element.tag == CONDITION_TAG and element.get('name').lower() == 'zigbee':
327358
return zigbee()
359+
elif element.tag == LITERAL_TAG:
360+
return literal(element.get('value'))
328361
else:
329362
raise ConformanceException(
330363
f'Unexpected xml conformance element with no children {str(element.tag)} {str(element.attrib)}')
@@ -354,5 +387,9 @@ def parse_callable_from_xml(element: ElementTree.Element, params: ConformancePar
354387
return not_operation(ops[0])
355388
elif element.tag == OTHERWISE_CONFORM:
356389
return otherwise(ops)
390+
elif element.tag == GREATER_TERM:
391+
if len(ops) != 2:
392+
raise ConformanceException(f'Greater than term found with more than two subelements {list(element)}')
393+
return greater_operation(ops[0], ops[1])
357394
else:
358395
raise ConformanceException(f'Unexpected conformance tag with children {element}')

0 commit comments

Comments
 (0)