blob: 87bd7a740ba7864486325387f263a398e812682a [file] [log] [blame]
#
# Copyright (c) 2023 Project CHIP Authors
# All rights reserved.
#
# 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 logging
import os
import chip.clusters as Clusters
from chip.interaction_model import InteractionModelError, Status
from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from mobly import asserts
logger = logging.getLogger(__name__)
kRootEndpointId = 0
cluster = Clusters.Objects.IcdManagement
commands = cluster.Commands
monitoredRegistration = cluster.Structs.MonitoringRegistrationStruct
# Step 2 Registration entry
kStep2CheckInNodeId = 101
kStep2MonitoredSubjectStep2 = 1001
kStep2Key = b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
class TC_ICDM_3_1(MatterBaseTest):
#
# Class Helper functions
#
async def _read_icdm_attribute_expect_success(self, attribute):
return await self.read_single_attribute_check_success(endpoint=kRootEndpointId, cluster=cluster, attribute=attribute)
async def _send_single_icdm_command(self, command):
return await self.send_single_cmd(command, endpoint=kRootEndpointId)
#
# Test Harness Helpers
#
def desc_TC_ICDM_3_1(self) -> str:
"""Returns a description of this test"""
return "[TC-ICDM-3.1] Register/Unregister Clients with DUT as Server"
def steps_TC_ICDM_3_1(self) -> list[TestStep]:
steps = [
TestStep("0a", "Commissioning, already done",
is_commissioning=True),
TestStep(
"0b", "TH reads from the DUT the RegisteredClients attribute. RegisteredClients is empty."),
TestStep(
"1a", "TH reads from the DUT the ClientsSupportedPerFabric attribute."),
TestStep(
"1b", "TH reads from the DUT the ICDCounter attribute."),
TestStep(2, "TH sends RegisterClient command."),
TestStep(3, "TH reads from the DUT the RegisteredClients attribute."),
TestStep(
4, "If len(RegisteredClients) is less than ClientsSupportedPerFabric, TH repeats RegisterClient command with different CheckInNodeID(s) until the number of entries in RegisteredClients equals ClientsSupportedPerFabric."),
TestStep(5, "TH reads from the DUT the RegisteredClients attribute."),
TestStep(
6, "TH sends RegisterClient command with a different CheckInNodeID."),
TestStep(
7, "TTH sends UnregisterClient command with the CheckInNodeID from Step 6."),
TestStep(
8, "TH sends UnregisterClient command with the CheckInNodeID from Step 2."),
TestStep(
9, "TH reads from the DUT the RegisteredClients attribute."),
TestStep(
10, "Repeat Step 9 with the rest of CheckInNodeIDs from the list of RegisteredClients from Step 4, if any."),
TestStep(11, "TH reads from the DUT the RegisteredClients attribute."),
TestStep(
12, "TH sends UnregisterClient command with the CheckInNodeID from Step 2."),
]
return steps
def pics_TC_ICDM_3_1(self) -> list[str]:
""" This function returns a list of PICS for this test case that must be True for the test to be run"""
pics = [
"ICDM.S",
"ICDM.S.F00"
]
return pics
#
# ICDM 3.1 Test Body
#
@async_test_body
async def test_TC_ICDM_3_1(self):
cluster = Clusters.Objects.IcdManagement
attributes = cluster.Attributes
# Pre-Condition: Commissioning
self.step("0a")
# Pre-Condition: Empty RegisteredClients attribute for all registrations
self.step("0b")
registeredClients = await self._read_icdm_attribute_expect_success(
attributes.RegisteredClients)
for client in registeredClients:
try:
await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client.checkInNodeID))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.Success, "Unexpected error returned")
pass
self.step("1a")
if self.pics_guard(self.check_pics("ICDM.S.A0005")):
clientsSupportedPerFabric = await self._read_icdm_attribute_expect_success(
attributes.ClientsSupportedPerFabric)
self.step("1b")
if self.pics_guard(self.check_pics("ICDM.S.A0005")):
icdCounter = await self._read_icdm_attribute_expect_success(attributes.ICDCounter)
self.step(2)
if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")):
try:
response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=kStep2CheckInNodeId, monitoredSubject=kStep2MonitoredSubjectStep2, key=kStep2Key))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.Success, "Unexpected error returned")
pass
# Validate response contains the ICDCounter
asserts.assert_greater_equal(response.ICDCounter, icdCounter,
"The ICDCounter in the response does not match the read ICDCounter.")
self.step(3)
if self.pics_guard(self.check_pics("ICDM.S.A0003")):
registeredClients = await self._read_icdm_attribute_expect_success(
attributes.RegisteredClients)
# Validate list size
asserts.assert_equal(len(registeredClients), 1,
"The expected length of RegisteredClients is 1. List has the wrong size.")
# Validate entry values
asserts.assert_equal(
registeredClients[0].checkInNodeID, kStep2CheckInNodeId, "The read attribute does not match the registered value.")
asserts.assert_equal(
registeredClients[0].monitoredSubject, kStep2MonitoredSubjectStep2, "The read attribute does not match the registered value.")
self.step(4)
if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")):
if (len(registeredClients) < clientsSupportedPerFabric):
newClients = []
# Generate new clients data
for i in range(clientsSupportedPerFabric - len(registeredClients)):
newClients.append({
"checkInNodeID": i + 1,
"monitoredSubject": i + 1,
"key": os.urandom(16)
})
for client in newClients:
try:
response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client["checkInNodeID"], monitoredSubject=client["monitoredSubject"], key=client["key"]))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.Success, "Unexpected error returned")
pass
# Validate response contains the ICDCounter
asserts.assert_greater_equal(response.ICDCounter, icdCounter,
"The ICDCounter in the response does not match the read ICDCounter.")
self.step(5)
if self.pics_guard(self.check_pics("ICDM.S.A0003")):
registeredClients = await self._read_icdm_attribute_expect_success(
attributes.RegisteredClients)
# Validate list size
asserts.assert_equal(len(registeredClients[1:]), len(newClients),
"The expected length of RegisteredClients is clientsSupportedPerFabric. List has the wrong size.")
for client, expectedClient in zip(registeredClients[1:], newClients):
asserts.assert_equal(
client.checkInNodeID, expectedClient["checkInNodeID"], "The read attribute does not match the registered value.")
asserts.assert_equal(
client.monitoredSubject, expectedClient["monitoredSubject"], "The read attribute does not match the registered value.")
self.step(6)
if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")):
try:
response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=0xFFFF, monitoredSubject=0xFFFF, key=os.urandom(16)))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.ResourceExhausted, "Unexpected error returned")
pass
self.step(7)
if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")):
try:
await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=0xFFFF))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.NotFound, "Unexpected error returned")
pass
self.step(8)
if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")):
try:
await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=kStep2CheckInNodeId))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.Success, "Unexpected error returned")
pass
self.step(9)
if self.pics_guard(self.check_pics("ICDM.S.A0003")):
registeredClients = await self._read_icdm_attribute_expect_success(
attributes.RegisteredClients)
for client in registeredClients:
asserts.assert_not_equal(client.checkInNodeID, kStep2CheckInNodeId,
"CheckInNodeID was unregistered. It should not be present in the attribute list.")
self.step(10)
if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")):
for client in newClients:
try:
await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client["checkInNodeID"]))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.Success, "Unexpected error returned")
pass
self.step(11)
if self.pics_guard(self.check_pics("ICDM.S.A0003")):
registeredClients = await self._read_icdm_attribute_expect_success(
attributes.RegisteredClients)
asserts.assert_true(
not registeredClients, "This list should empty. An element did not get deleted.")
self.step(12)
if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")):
try:
await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=kStep2CheckInNodeId))
except InteractionModelError as e:
asserts.assert_equal(
e.status, Status.NotFound, "Unexpected error returned")
pass
if __name__ == "__main__":
default_matter_test_main()