blob: 4a43d3fea717b399c317598fc0be5c9aeeb32b97 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (c) 2022 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import io
from typing import Optional, Union, List
try:
from idl.matter_idl_types import *
from idl.zapxml import ParseSource, ParseXmls
except:
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from idl.matter_idl_types import *
from idl.zapxml import ParseSource, ParseXmls
def XmlToIdl(what: Union[str, List[str]]) -> Idl:
if not isinstance(what, list):
what = [what]
sources = []
for idx, txt in enumerate(what):
sources.append(ParseSource(source=io.StringIO(txt), name=("Input %d" % (idx + 1))))
return ParseXmls(sources, include_meta_data=False)
class TestXmlParser(unittest.TestCase):
def testEmptyInput(self):
idl = XmlToIdl('<configurator/>')
self.assertEqual(idl, Idl())
def testCluster(self):
idl = XmlToIdl('''<?xml version="1.0"?>
<!-- Comments should be supported -->
<configurator>
<cluster>
<name>Test</name>
<code>0x1234</code>
<attribute side="server" code="11" type="INT32U" min="0" max="2" isNullable="true" reportable="true" writable="false">SomeIntAttribute</attribute>
<attribute side="server" code="22" define="SOME_DEFINE" type="INT8U" min="0" max="10" reportable="true" default="0" writable="true" optional="true">
<description>AttributeWithAccess</description>
<access op="read" role="operate" />
<access op="write" role="manage" />
</attribute>
<command source="client" code="33" name="GetSomeData" response="GetSomeDataResponse" optional="true">
<description>This is just a test: client to server</description>
<access op="invoke" role="administer" />
<arg name="firstInput" type="INT8U" />
<arg name="secondInput" type="INT16U" />
</command>
<command source="server" code="0x44" name="GetSomeDataResponse" disableDefaultResponse="true" optional="true">
<description>Reply from server</description>
<arg name="dataPoint1" type="INT8U" />
<arg name="dataPoint2" type="INT8U" optional="true" />
</command>
</cluster>
</configurator>
''')
self.assertEqual(idl,
Idl(clusters=[
Cluster(
side=ClusterSide.CLIENT,
name='Test',
code=0x1234,
attributes=[
Attribute(definition=Field(data_type=DataType(name='INT32U'), code=11, name='SomeIntAttribute',
qualities=FieldQuality.NULLABLE), qualities=AttributeQuality.READABLE,
readacl=AccessPrivilege.VIEW, writeacl=AccessPrivilege.OPERATE),
Attribute(definition=Field(data_type=DataType(name='INT8U'), code=22, name='AttributeWithAccess',
qualities=FieldQuality.OPTIONAL),
qualities=AttributeQuality.READABLE | AttributeQuality.WRITABLE, readacl=AccessPrivilege.OPERATE,
writeacl=AccessPrivilege.MANAGE)
],
structs=[
Struct(name='GetSomeDataRequest',
fields=[
Field(data_type=DataType(name='INT8U'), code=1, name='firstInput'),
Field(data_type=DataType(name='INT16U'), code=2, name='secondInput')
],
tag=StructTag.REQUEST),
Struct(name='GetSomeDataResponse',
fields=[
Field(data_type=DataType(name='INT8U'), code=1,
name='dataPoint1'),
Field(data_type=DataType(name='INT8U'), code=2, name='dataPoint2',
qualities=FieldQuality.OPTIONAL)
],
tag=StructTag.RESPONSE, code=0x44)
],
commands=[
Command(name='GetSomeData', code=33, input_param='GetSomeDataRequest', output_param='GetSomeDataResponse',
invokeacl=AccessPrivilege.ADMINISTER)
])
]))
def testBitmap(self):
idl = XmlToIdl('''<?xml version="1.0"?>
<configurator>
<cluster><name>Test1</name><code>0x0001</code></cluster>
<cluster><name>Test2</name><code>0x0002</code></cluster>
<bitmap name="MyBitmap" type="BITMAP32">
<cluster code="1"/>
<cluster code="0x02"/>
<field name="BitmapMask1" mask="0x1"/>
<field name="BitmapMask2" mask="0x2"/>
<field name="BitmapMask3" mask="0x4"/>
</bitmap>
</configurator>
''')
bitmap = Bitmap(
name='MyBitmap',
base_type='BITMAP32',
entries=[
ConstantEntry(name='BitmapMask1', code=1),
ConstantEntry(name='BitmapMask2', code=2),
ConstantEntry(name='BitmapMask3', code=4)
])
self.assertEqual(idl,
Idl(clusters=[
Cluster(side=ClusterSide.CLIENT, name='Test1', code=1, bitmaps=[bitmap]),
Cluster(side=ClusterSide.CLIENT, name='Test2', code=2, bitmaps=[bitmap]),
]))
def testFabricScopedAndSensitive(self):
idl = XmlToIdl('''<?xml version="1.0"?>
<configurator>
<cluster>
<name>Test</name>
<code>0x0001</code>
<event side="server" code="0x1234" name="FabricEvent" priority="info" isFabricSensitive="true" optional="false">
<description>This is a test event</description>
<field id="1" name="AdminNodeID" type="node_id" isNullable="true"/>
<access op="read" privilege="administer"/>
</event>
</cluster>
<struct name="FabricStruct" isFabricScoped="true">
<cluster code="1"/>
<item fieldId="1" name="Field1" type="int32u" isFabricSensitive="true"/>
<item fieldId="3" name="Field3" type="int32u" isFabricSensitive="true"/>
<item fieldId="10" name="Field10" type="int32u" />
</struct>
</configurator>
''')
self.assertEqual(idl,
Idl(clusters=[Cluster(side=ClusterSide.CLIENT,
name='Test',
code=1,
events=[Event(priority=EventPriority.INFO,
name='FabricEvent',
code=0x1234,
fields=[Field(data_type=DataType(name='node_id'),
code=1,
name='AdminNodeID',
qualities=FieldQuality.NULLABLE)],
readacl=AccessPrivilege.ADMINISTER,
qualities=EventQuality.FABRIC_SENSITIVE)],
structs=[Struct(name='FabricStruct',
fields=[Field(data_type=DataType(name='int32u'),
code=1,
name='Field1',
qualities=FieldQuality.FABRIC_SENSITIVE),
Field(data_type=DataType(name='int32u'),
code=3,
name='Field3',
qualities=FieldQuality.FABRIC_SENSITIVE),
Field(data_type=DataType(name='int32u',
max_length=None),
code=10,
name='Field10')],
qualities=StructQuality.FABRIC_SCOPED)],
)]))
def testStruct(self):
idl = XmlToIdl('''<?xml version="1.0"?>
<configurator>
<cluster><name>Test1</name><code>0x000A</code></cluster>
<cluster>
<name>Test2</name>
<code>20</code>
<attribute side="server" code="123" type="SomeStruct" isNullable="true" writable="false">
FabricAttribute
</attribute>
</cluster>
<struct name="SomeStruct" isFabricScoped="true">
<cluster code="10" />
<cluster code="0x0014" />
<item name="FirstMember" type="int16u" />
<item name="SecondMember" type="int32u" />
</struct>
</configurator>
''')
struct = Struct(
name='SomeStruct',
qualities=StructQuality.FABRIC_SCOPED,
fields=[
Field(data_type=DataType(name='int16u'), code=1, name='FirstMember'),
Field(data_type=DataType(name='int32u'), code=2, name='SecondMember')
]
)
self.assertEqual(idl,
Idl(clusters=[
Cluster(side=ClusterSide.CLIENT, name='Test1', code=10, structs=[struct]),
Cluster(side=ClusterSide.CLIENT, name='Test2', code=20,
structs=[struct],
attributes=[
Attribute(
definition=Field(
data_type=DataType(name='SomeStruct'),
code=123,
name='FabricAttribute',
qualities=FieldQuality.NULLABLE
),
qualities=AttributeQuality.READABLE,
readacl=AccessPrivilege.VIEW,
writeacl=AccessPrivilege.OPERATE)]), ]))
def testSkipsNotProcessedFields(self):
# Zap has extra fields that are generally not processed
# This includes such fields and ansures we do not consider them
idl = XmlToIdl('''<?xml version="1.0"?>
<!--
Some copyright here... testing that we skip over comments
-->
<configurator>
<domain name="CHIP"/>
<cluster>
<name>Window Covering</name>
<domain>Closures</domain>
<code>0x0102</code>
<define>WINDOW_COVERING_CLUSTER</define>
<description>Provides an interface for controlling and adjusting automatic window coverings. </description>
<!-- Abbreviations used in descriptions -->
<tag name="LF" description="Lift Control"/>
<tag name="TL" description="Tilt Control"/>
<tag name="PA_LF" description="Position Aware Lift"/>
<tag name="ABS" description="Absolute Positioning"/>
<tag name="PA_TL" description="Position Aware Tilt"/>
<client tick="false" init="false">true</client>
<server tick="false" init="false">true</server>
<!-- Window Covering Information Attribute Set -->
<!-- Conformance feature M -->
<attribute side="server" writable="false" code="0x0000" define="WC_TYPE"
type="Type" min="0x00" max="0x09" default="0x00" optional="false">Type</attribute>
</cluster>
</configurator>
''')
self.assertEqual(idl,
Idl(clusters=[
Cluster(side=ClusterSide.CLIENT, name='WindowCovering', code=0x102,
structs=[],
attributes=[
Attribute(
definition=Field(
data_type=DataType(name='Type'),
code=0,
name='Type',
),
qualities=AttributeQuality.READABLE,
readacl=AccessPrivilege.VIEW,
writeacl=AccessPrivilege.OPERATE)]), ]))
if __name__ == '__main__':
unittest.main()