Skip to content

Commit de5c5e6

Browse files
cecilletersal
andauthored
Fix key error when using TLV dictionary in DeviceConformance test. (#37268) (#37465)
* Change reference from TLV endpoint * Change test endpoint function * Fix issue with attr list * Add handling for TLV attributes Co-authored-by: Moises Terrones <moises.tersal@gmail.com>
1 parent 19c3a7b commit de5c5e6

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

src/python_testing/TC_DeviceConformance.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ def _has_device_type_supporting_macl(self):
6060
# Currently this is just NIM. We may later be able to pull this from the device type scrape using the ManagedAclAllowed condition,
6161
# but these are not currently exposed directly by the device.
6262
allowed_ids = [self._get_device_type_id('network infrastructure manager')]
63-
for endpoint in self.endpoints_tlv.values():
63+
for endpoint in self.endpoints.values():
6464
desc = Clusters.Descriptor
65-
device_types = [dt.deviceType for dt in endpoint[desc.id][desc.Attributes.DeviceTypeList.attribute_id]]
65+
device_types = [dt.deviceType for dt in endpoint[desc][desc.Attributes.DeviceTypeList]]
6666
if set(allowed_ids).intersection(set(device_types)):
6767
# TODO: it's unclear if this needs to be present on every endpoint. Right now, this assumes one is sufficient.
6868
return True

src/python_testing/TestConformanceTest.py

+54-20
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# limitations under the License.
1616
#
1717

18-
from typing import Any
18+
from typing import Any, Optional
1919

2020
import chip.clusters as Clusters
2121
from basic_composition_support import arls_populated
@@ -142,6 +142,12 @@ async def test_provisional_cluster(self):
142142
success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=False)
143143
asserts.assert_true(success, "Unexpected failure parsing endpoint with no clusters marked as provisional")
144144

145+
def _get_field_by_label(self, cl_object: Clusters.ClusterObjects.ClusterObject, label: str) -> Optional[Clusters.ClusterObjects.ClusterObjectFieldDescriptor]:
146+
for field in cl_object.descriptor.Fields:
147+
if field.Label == label:
148+
return field
149+
return None
150+
145151
def _create_minimal_cluster(self, cluster_id: int) -> dict[int, Any]:
146152
attrs = {}
147153
attrs[GlobalAttributeIds.FEATURE_MAP_ID] = 0
@@ -160,37 +166,61 @@ def _create_minimal_cluster(self, cluster_id: int) -> dict[int, Any]:
160166
attrs[GlobalAttributeIds.CLUSTER_REVISION_ID] = self.xml_clusters[cluster_id].revision
161167
return attrs
162168

163-
def _create_minimal_dt(self, device_type_id: int) -> dict[int, dict[int, Any]]:
164-
''' Creates the internals of an endpoint_tlv with the minimal set of clusters, with the minimal set of attributes and commands. Global attributes only.
169+
def _create_minimal_dt(self, device_type_id: int, is_tlv_endpoint: bool = True) -> dict[int, dict[int, Any]]:
170+
''' Creates the internals of an endpoint with the minimal set of clusters, with the minimal set of attributes and commands. Global attributes only.
165171
Does NOT take into account overrides yet.
166172
'''
167-
endpoint_tlv = {}
173+
endpoint = {}
168174
required_servers = [id for id, c in self.xml_device_types[device_type_id].server_clusters.items()
169175
if is_mandatory(c.conformance)]
170176
required_clients = [id for id, c in self.xml_device_types[device_type_id].client_clusters.items()
171177
if is_mandatory(c.conformance)]
172178
device_type_revision = self.xml_device_types[device_type_id].revision
173179

174180
for s in required_servers:
175-
endpoint_tlv[s] = self._create_minimal_cluster(s)
181+
endpoint[s] = self._create_minimal_cluster(s)
176182

177183
# Descriptor
178184
attr = Clusters.Descriptor.Attributes
185+
structs = Clusters.Descriptor.Structs
179186
attrs = {}
180-
attrs[attr.FeatureMap.attribute_id] = 0
181-
attrs[attr.AcceptedCommandList.attribute_id] = []
182-
attrs[attr.GeneratedCommandList.attribute_id] = []
183-
attrs[attr.ClusterRevision.attribute_id] = self.xml_clusters[Clusters.Descriptor.id].revision
184-
attrs[attr.DeviceTypeList.attribute_id] = [
185-
Clusters.Descriptor.Structs.DeviceTypeStruct(deviceType=device_type_id, revision=device_type_revision)]
186-
attrs[attr.ServerList.attribute_id] = required_servers
187-
attrs[attr.ClientList.attribute_id] = required_clients
188-
attrs[attr.PartsList.attribute_id] = []
189-
attrs[attr.AttributeList.attribute_id] = []
190-
attrs[attr.AttributeList.attribute_id] = list(attrs.keys())
191-
192-
endpoint_tlv[Clusters.Descriptor.id] = attrs
193-
return endpoint_tlv
187+
188+
attributes = [
189+
attr.FeatureMap,
190+
attr.AcceptedCommandList,
191+
attr.GeneratedCommandList,
192+
attr.ClusterRevision,
193+
attr.DeviceTypeList,
194+
attr.ServerList,
195+
attr.ClientList,
196+
attr.PartsList,
197+
]
198+
199+
attribute_values = [
200+
(0, 0), # FeatureMap
201+
([], []), # AcceptedCommandList
202+
([], []), # GeneratedCommandList
203+
(self.xml_clusters[Clusters.Descriptor.id].revision,
204+
self.xml_clusters[Clusters.Descriptor.id].revision), # ClusterRevision
205+
([{self._get_field_by_label(structs.DeviceTypeStruct, "deviceType").Tag: device_type_id,
206+
self._get_field_by_label(structs.DeviceTypeStruct, "revision").Tag: device_type_revision}],
207+
[Clusters.Descriptor.Structs.DeviceTypeStruct(
208+
deviceType=device_type_id, revision=device_type_revision)]), # DeviceTypeList
209+
(required_servers, required_servers), # ServerList
210+
(required_clients, required_clients), # ClientList
211+
([], []), # PartsList
212+
]
213+
214+
for attribute_name, attribute_value in zip(attributes, attribute_values):
215+
key = attribute_name.attribute_id if is_tlv_endpoint else attribute_name
216+
attrs[key] = attribute_value[0] if is_tlv_endpoint else attribute_value[1]
217+
218+
# Append the attribute list now that is populated.
219+
attrs[attr.AttributeList.attribute_id if is_tlv_endpoint else attr.AttributeList] = list(attrs.keys())
220+
221+
endpoint[Clusters.Descriptor.id if is_tlv_endpoint else Clusters.Descriptor] = attrs
222+
223+
return endpoint
194224

195225
def add_macl(self, root_endpoint: dict[int, dict[int, Any]], populate_arl: bool = False, populate_commissioning_arl: bool = False):
196226
ac = Clusters.AccessControl
@@ -220,6 +250,10 @@ async def test_macl_handling(self):
220250
root = self._create_minimal_dt(device_type_id=root_node_id)
221251
nim = self._create_minimal_dt(device_type_id=nim_id)
222252
self.endpoints_tlv = {0: root, 1: nim}
253+
254+
root_no_tlv = self._create_minimal_dt(device_type_id=root_node_id, is_tlv_endpoint=False)
255+
nim_no_tlv = self._create_minimal_dt(device_type_id=nim_id, is_tlv_endpoint=False)
256+
self.endpoints = {0: root_no_tlv, 1: nim_no_tlv}
223257
asserts.assert_true(self._has_device_type_supporting_macl(), "Did not find supported device in generated device")
224258

225259
success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=True)
@@ -233,7 +267,7 @@ async def test_macl_handling(self):
233267
asserts.assert_true(success, "Unexpected failure with NIM and MACL")
234268

235269
# A MACL is not allowed when there is no NIM
236-
self.endpoints_tlv[1] = self._create_minimal_dt(device_type_id=on_off_id)
270+
self.endpoints[1] = self._create_minimal_dt(device_type_id=on_off_id, is_tlv_endpoint=False)
237271
success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=True)
238272
self.problems.extend(problems)
239273
asserts.assert_false(success, "Unexpected success with On/Off and MACL")

0 commit comments

Comments
 (0)