test_spec_definitions.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. #!/usr/bin/env -S python3 -B
  2. #
  3. # Copyright (c) 2022 Project CHIP Authors
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the 'License');
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an 'AS IS' BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. import io
  17. import unittest
  18. from matter_yamltests.definitions import Attribute, Bitmap, Command, Enum, Event, ParseSource, SpecDefinitions, Struct
  19. source_cluster = '''<?xml version="1.0"?>
  20. <configurator>
  21. <cluster>
  22. <name>Test</name>
  23. <code>0x1234</code>
  24. </cluster>
  25. </configurator>
  26. '''
  27. source_command = '''<?xml version="1.0"?>
  28. <configurator>
  29. <cluster>
  30. <name>Test</name>
  31. <code>0x1234</code>
  32. <command source="client" code="0x0" name="TestCommand"></command>
  33. </cluster>
  34. </configurator>
  35. '''
  36. source_response = '''<?xml version="1.0"?>
  37. <configurator>
  38. <cluster>
  39. <name>Test</name>
  40. <code>0x1234</code>
  41. <command source="server" code="0x0" name="TestCommandResponse">
  42. <arg name="arg1" type="int8u"/>
  43. </command>
  44. </cluster>
  45. </configurator>
  46. '''
  47. source_response_with_nullable = '''<?xml version="1.0"?>
  48. <configurator>
  49. <cluster>
  50. <name>Test</name>
  51. <code>0x1234</code>
  52. <command source="server" code="0x0" name="TestCommandResponse">
  53. <arg name="arg1" type="int8u"/>
  54. <arg name="arg2" type="int8u" isNullable="true"/>
  55. </command>
  56. </cluster>
  57. </configurator>
  58. '''
  59. source_attribute = '''<?xml version="1.0"?>
  60. <configurator>
  61. <global>
  62. <attribute side="server" code="0xFFFD" type="boolean">TestGlobalAttribute</attribute>
  63. </global>
  64. <cluster>
  65. <name>Test</name>
  66. <code>0x1234</code>
  67. <globalAttribute side="server" code="0xFFFD" value="true"/>
  68. <attribute code="0x0" type="boolean">TestAttribute</attribute>
  69. </cluster>
  70. </configurator>
  71. '''
  72. source_event = '''<?xml version="1.0"?>
  73. <configurator>
  74. <cluster>
  75. <name>Test</name>
  76. <code>0x1234</code>
  77. <event code="0x0" name="TestEvent" priority="info" side="server"></event>
  78. <event code="0x1" name="TestEventFabricScoped" priority="info" side="server" isFabricSensitive="true"></event>
  79. </cluster>
  80. </configurator>
  81. '''
  82. source_bitmap = '''<?xml version="1.0"?>
  83. <configurator>
  84. <bitmap name="TestBitmap" type="bitmap8">
  85. <cluster code="0x1234"/>
  86. <field name="a" mask="0x1"/>
  87. </bitmap>
  88. <bitmap name="TestWrongBitmap" type="bitmap8">
  89. <cluster code="0x4321"/>
  90. <field name="a" mask="0x1"/>
  91. </bitmap>
  92. <cluster>
  93. <name>Test</name>
  94. <code>0x1234</code>
  95. </cluster>
  96. <cluster>
  97. <name>TestWrong</name>
  98. <code>0x4321</code>
  99. </cluster>
  100. </configurator>
  101. '''
  102. source_enum = '''<?xml version="1.0"?>
  103. <configurator>
  104. <enum name="TestEnum" type="enum8">
  105. <cluster code="0x1234"/>
  106. <item name="a" value="0x00"/>
  107. </enum>
  108. <enum name="TestWrongEnum" type="enum8">
  109. <cluster code="0x4321"/>
  110. <item name="a" value="0x00"/>
  111. </enum>
  112. <cluster>
  113. <name>Test</name>
  114. <code>0x1234</code>
  115. </cluster>
  116. <cluster>
  117. <name>TestWrong</name>
  118. <code>0x4321</code>
  119. </cluster>
  120. </configurator>
  121. '''
  122. source_struct = '''<?xml version="1.0"?>
  123. <configurator>
  124. <struct name="TestStruct">
  125. <cluster code="0x1234"/>
  126. <item name="a" type="boolean"/>
  127. </struct>
  128. <struct name="TestStructFabricScoped" isFabricScoped="true">
  129. <cluster code="0x1234"/>
  130. <item name="a" type="boolean"/>
  131. </struct>
  132. <struct name="TestWrongStruct">
  133. <cluster code="0x4321"/>
  134. <item name="a" type="boolean"/>
  135. </struct>
  136. <cluster>
  137. <name>Test</name>
  138. <code>0x1234</code>
  139. </cluster>
  140. <cluster>
  141. <name>TestWrong</name>
  142. <code>0x4321</code>
  143. </cluster>
  144. </configurator>
  145. '''
  146. class TestSpecDefinitions(unittest.TestCase):
  147. def test_cluster_name(self):
  148. definitions = SpecDefinitions(
  149. [ParseSource(source=io.StringIO(source_cluster), name='source_cluster')])
  150. self.assertIsNone(definitions.get_cluster_name(0x4321))
  151. self.assertEqual(definitions.get_cluster_name(0x1234), 'Test')
  152. def test_command_name(self):
  153. definitions = SpecDefinitions(
  154. [ParseSource(source=io.StringIO(source_command), name='source_command')])
  155. self.assertIsNone(definitions.get_command_name(0x4321, 0x0))
  156. self.assertIsNone(definitions.get_command_name(0x1234, 0x1))
  157. self.assertEqual(definitions.get_command_name(
  158. 0x1234, 0x0), 'TestCommand')
  159. def test_response_name(self):
  160. definitions = SpecDefinitions(
  161. [ParseSource(source=io.StringIO(source_response), name='source_response')])
  162. self.assertIsNone(definitions.get_response_name(0x4321, 0x0))
  163. self.assertIsNone(definitions.get_response_name(0x1234, 0x1))
  164. self.assertEqual(definitions.get_response_name(
  165. 0x1234, 0x0), 'TestCommandResponse')
  166. def test_response_name_with_nullable(self):
  167. definitions = SpecDefinitions(
  168. [ParseSource(source=io.StringIO(source_response_with_nullable), name='source_response_with_nullable')])
  169. cluster_name = 'Test'
  170. response_name = 'TestCommandResponse'
  171. self.assertEqual(definitions.get_cluster_name(0x1234), cluster_name)
  172. self.assertEqual(definitions.get_response_name(
  173. 0x1234, 0x0), response_name)
  174. response = definitions.get_response_by_name(
  175. cluster_name, response_name)
  176. for field in response.fields:
  177. if field.name == 'arg1':
  178. self.assertFalse(definitions.is_nullable(field))
  179. else:
  180. self.assertTrue(definitions.is_nullable(field))
  181. def test_attribute_name(self):
  182. definitions = SpecDefinitions(
  183. [ParseSource(source=io.StringIO(source_attribute), name='source_attribute')])
  184. self.assertIsNone(definitions.get_attribute_name(0x4321, 0x0))
  185. self.assertIsNone(definitions.get_attribute_name(0x4321, 0xFFFD))
  186. self.assertIsNone(definitions.get_attribute_name(0x1234, 0x1))
  187. self.assertEqual(definitions.get_attribute_name(
  188. 0x1234, 0x0), 'TestAttribute')
  189. self.assertEqual(definitions.get_attribute_name(
  190. 0x1234, 0xFFFD), 'TestGlobalAttribute')
  191. def test_event_name(self):
  192. definitions = SpecDefinitions(
  193. [ParseSource(source=io.StringIO(source_event), name='source_event')])
  194. self.assertIsNone(definitions.get_event_name(0x4321, 0x0))
  195. self.assertIsNone(definitions.get_event_name(0x1234, 0x2))
  196. self.assertEqual(definitions.get_event_name(0x1234, 0x0), 'TestEvent')
  197. self.assertEqual(definitions.get_event_name(
  198. 0x1234, 0x1), 'TestEventFabricScoped')
  199. def test_get_command_by_name(self):
  200. definitions = SpecDefinitions(
  201. [ParseSource(source=io.StringIO(source_command), name='source_command')])
  202. self.assertIsNone(definitions.get_command_by_name(
  203. 'WrongName', 'TestCommand'))
  204. self.assertIsNone(definitions.get_command_by_name(
  205. 'Test', 'TestWrongCommand'))
  206. self.assertIsNone(
  207. definitions.get_response_by_name('Test', 'TestCommand'))
  208. self.assertIsInstance(definitions.get_command_by_name(
  209. 'Test', 'TestCommand'), Command)
  210. self.assertIsNone(
  211. definitions.get_command_by_name('test', 'TestCommand'))
  212. self.assertIsNone(
  213. definitions.get_command_by_name('Test', 'testcommand'))
  214. def test_get_response_by_name(self):
  215. definitions = SpecDefinitions(
  216. [ParseSource(source=io.StringIO(source_response), name='source_response')])
  217. self.assertIsNone(definitions.get_response_by_name(
  218. 'WrongName', 'TestCommandResponse'))
  219. self.assertIsNone(definitions.get_response_by_name(
  220. 'Test', 'TestWrongCommandResponse'))
  221. self.assertIsNone(definitions.get_command_by_name(
  222. 'Test', 'TestCommandResponse'))
  223. self.assertIsInstance(definitions.get_response_by_name(
  224. 'Test', 'TestCommandResponse'), Struct)
  225. self.assertIsNone(definitions.get_response_by_name(
  226. 'test', 'TestCommandResponse'))
  227. self.assertIsNone(definitions.get_response_by_name(
  228. 'Test', 'testcommandresponse'))
  229. def test_get_attribute_by_name(self):
  230. definitions = SpecDefinitions(
  231. [ParseSource(source=io.StringIO(source_attribute), name='source_attribute')])
  232. self.assertIsNone(definitions.get_attribute_by_name(
  233. 'WrongName', 'TestAttribute'))
  234. self.assertIsNone(definitions.get_attribute_by_name(
  235. 'WrongName', 'TestGlobalAttribute'))
  236. self.assertIsNone(definitions.get_attribute_by_name(
  237. 'Test', 'TestWrongAttribute'))
  238. self.assertIsInstance(definitions.get_attribute_by_name(
  239. 'Test', 'TestAttribute'), Attribute)
  240. self.assertIsInstance(definitions.get_attribute_by_name(
  241. 'Test', 'TestGlobalAttribute'), Attribute)
  242. self.assertIsNone(definitions.get_attribute_by_name(
  243. 'test', 'TestAttribute'))
  244. self.assertIsNone(definitions.get_attribute_by_name(
  245. 'test', 'TestGlobalAttribute'))
  246. self.assertIsNone(definitions.get_attribute_by_name(
  247. 'Test', 'testattribute'))
  248. self.assertIsNone(definitions.get_attribute_by_name(
  249. 'Test', 'testglobalattribute'))
  250. def test_get_event_by_name(self):
  251. definitions = SpecDefinitions(
  252. [ParseSource(source=io.StringIO(source_event), name='source_event')])
  253. self.assertIsNone(definitions.get_event_by_name(
  254. 'WrongName', 'TestEvent'))
  255. self.assertIsNone(definitions.get_event_by_name(
  256. 'Test', 'TestWrongEvent'))
  257. self.assertIsInstance(
  258. definitions.get_event_by_name('Test', 'TestEvent'), Event)
  259. self.assertIsNone(definitions.get_event_by_name('test', 'TestEvent'))
  260. self.assertIsNone(definitions.get_event_by_name('Test', 'testevent'))
  261. def test_get_bitmap_by_name(self):
  262. definitions = SpecDefinitions(
  263. [ParseSource(source=io.StringIO(source_bitmap), name='source_bitmap')])
  264. self.assertIsNone(definitions.get_bitmap_by_name(
  265. 'WrongName', 'TestBitmap'))
  266. self.assertIsNone(definitions.get_bitmap_by_name(
  267. 'Test', 'TestWrongBitmap'))
  268. self.assertIsInstance(definitions.get_bitmap_by_name(
  269. 'Test', 'TestBitmap'), Bitmap)
  270. self.assertIsNone(definitions.get_bitmap_by_name('test', 'TestBitmap'))
  271. self.assertIsNone(definitions.get_bitmap_by_name('Test', 'testbitmap'))
  272. def test_get_enum_by_name(self):
  273. definitions = SpecDefinitions(
  274. [ParseSource(source=io.StringIO(source_enum), name='source_enum')])
  275. self.assertIsNone(definitions.get_enum_by_name(
  276. 'WrongName', 'TestEnum'))
  277. self.assertIsNone(definitions.get_enum_by_name(
  278. 'Test', 'TestWrongEnum'))
  279. self.assertIsInstance(
  280. definitions.get_enum_by_name('Test', 'TestEnum'), Enum)
  281. self.assertIsNone(definitions.get_enum_by_name('test', 'TestEnum'))
  282. self.assertIsNone(definitions.get_enum_by_name('Test', 'testenum'))
  283. def test_get_struct_by_name(self):
  284. definitions = SpecDefinitions(
  285. [ParseSource(source=io.StringIO(source_struct), name='source_struct')])
  286. self.assertIsNone(definitions.get_struct_by_name(
  287. 'WrongName', 'TestStruct'))
  288. self.assertIsNone(definitions.get_struct_by_name(
  289. 'Test', 'TestWrongStruct'))
  290. self.assertIsInstance(definitions.get_struct_by_name(
  291. 'Test', 'TestStruct'), Struct)
  292. self.assertIsNone(definitions.get_struct_by_name('test', 'TestStruct'))
  293. self.assertIsNone(definitions.get_struct_by_name('Test', 'teststruct'))
  294. def test_get_type_by_name(self):
  295. definitions = SpecDefinitions(
  296. [ParseSource(source=io.StringIO(source_command), name='source_command')])
  297. self.assertIsNone(definitions.get_type_by_name('Test', 'TestCommand'))
  298. definitions = SpecDefinitions(
  299. [ParseSource(source=io.StringIO(source_response), name='source_response')])
  300. self.assertIsInstance(definitions.get_type_by_name(
  301. 'Test', 'TestCommandResponse'), Struct)
  302. definitions = SpecDefinitions(
  303. [ParseSource(source=io.StringIO(source_attribute), name='source_attribute')])
  304. self.assertIsNone(definitions.get_type_by_name(
  305. 'Test', 'TestAttribute'))
  306. definitions = SpecDefinitions(
  307. [ParseSource(source=io.StringIO(source_event), name='source_event')])
  308. self.assertIsInstance(
  309. definitions.get_type_by_name('Test', 'TestEvent'), Event)
  310. definitions = SpecDefinitions(
  311. [ParseSource(source=io.StringIO(source_bitmap), name='source_bitmap')])
  312. self.assertIsInstance(definitions.get_type_by_name(
  313. 'Test', 'TestBitmap'), Bitmap)
  314. definitions = SpecDefinitions(
  315. [ParseSource(source=io.StringIO(source_enum), name='source_enum')])
  316. self.assertIsInstance(
  317. definitions.get_type_by_name('Test', 'TestEnum'), Enum)
  318. definitions = SpecDefinitions(
  319. [ParseSource(source=io.StringIO(source_struct), name='source_struct')])
  320. self.assertIsInstance(definitions.get_type_by_name(
  321. 'Test', 'TestStruct'), Struct)
  322. def test_struct_is_fabric_scoped(self):
  323. definitions = SpecDefinitions(
  324. [ParseSource(source=io.StringIO(source_struct), name='source_struct')])
  325. struct = definitions.get_struct_by_name('Test', 'TestStruct')
  326. self.assertFalse(definitions.is_fabric_scoped(struct))
  327. struct = definitions.get_struct_by_name(
  328. 'Test', 'TestStructFabricScoped')
  329. self.assertTrue(definitions.is_fabric_scoped(struct))
  330. def test_event_is_fabric_scoped(self):
  331. definitions = SpecDefinitions(
  332. [ParseSource(source=io.StringIO(source_event), name='source_event')])
  333. event = definitions.get_event_by_name('Test', 'TestEvent')
  334. self.assertFalse(definitions.is_fabric_scoped(event))
  335. event = definitions.get_event_by_name(
  336. 'Test', 'TestEventFabricScoped')
  337. self.assertTrue(definitions.is_fabric_scoped(event))
  338. def test_get_cluster_id_by_name(self):
  339. definitions = SpecDefinitions(
  340. [ParseSource(source=io.StringIO(source_cluster), name='source_cluster')])
  341. cluster_id = definitions.get_cluster_id_by_name('Test')
  342. self.assertEqual(cluster_id, 0x1234)
  343. cluster_id = definitions.get_cluster_id_by_name('test')
  344. self.assertIsNone(cluster_id)
  345. def test_get_command_names(self):
  346. definitions = SpecDefinitions(
  347. [ParseSource(source=io.StringIO(source_command), name='source_command')])
  348. commands = definitions.get_command_names('Test')
  349. self.assertEqual(commands, ['TestCommand'])
  350. commands = definitions.get_command_names('test')
  351. self.assertEqual(commands, [])
  352. def test_get_attribute_names(self):
  353. definitions = SpecDefinitions(
  354. [ParseSource(source=io.StringIO(source_attribute), name='source_attribute')])
  355. attributes = definitions.get_attribute_names('Test')
  356. self.assertEqual(attributes, ['TestAttribute', 'TestGlobalAttribute'])
  357. attributes = definitions.get_attribute_names('test')
  358. self.assertEqual(attributes, [])
  359. def test_get_event_names(self):
  360. definitions = SpecDefinitions(
  361. [ParseSource(source=io.StringIO(source_event), name='source_event')])
  362. events = definitions.get_event_names('Test')
  363. self.assertEqual(events, ['TestEvent', 'TestEventFabricScoped'])
  364. events = definitions.get_event_names('test')
  365. self.assertEqual(events, [])
  366. if __name__ == '__main__':
  367. unittest.main()