From fa83b47bc7a1577ed7f537f3bde7921f4c4b35e1 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Sat, 28 Sep 2024 09:55:59 -0700 Subject: [PATCH 01/14] TC-VALCC-3.1: Allow immediate open of valve If the valve can be opened before the command is complete or before the next read is done, the test will fail because it expects the transitioning phase to happen. In the spec: When the movement is complete, the device SHALL set the CurrentState attribute to the Open value. ^ this can happen before the end of the command. --- src/python_testing/TC_VALCC_3_1.py | 54 ++++++++++++++++-------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index e24c09db66c35d..9bb3dd8d306ce5 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -45,11 +45,13 @@ def steps_TC_VALCC_3_1(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), TestStep(2, "Send Open command"), - TestStep(3, "Read TargetState attribute"), - TestStep(4, "Read CurrentState attribute"), + TestStep(3, "Read CurrentState and TargetState attribute until CurrentState is Open", + "Target state is Open while CurrentState is Transitioning"), + TestStep(4, "Read CurrentState and TargetState attribute", "CurrentState is Open, TargetState is NULL"), TestStep(5, "Send Close command"), - TestStep(6, "Read TargetState attribute"), - TestStep(7, "Read CurrentState attribute"), + TestStep(6, "Read CurrentState and TargetState attribute until CurrentState is Open", + "Target state is Closed while CurrentState is Transitioning"), + TestStep(7, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), ] return steps @@ -65,7 +67,8 @@ async def test_TC_VALCC_3_1(self): endpoint = self.user_params.get("endpoint", 1) self.step(1) - attributes = Clusters.ValveConfigurationAndControl.Attributes + cluster = Clusters.ValveConfigurationAndControl + attributes = cluster.Attributes self.step(2) try: @@ -75,24 +78,26 @@ async def test_TC_VALCC_3_1(self): pass self.step(3) - target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) - - asserts.assert_true(target_state_dut is not NullValue, "TargetState is null") - asserts.assert_equal(target_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kOpen, - "TargetState is not the expected value") - self.step(4) + # Read target state first in case the current state goes to open between these calls. + # The test re-reads target state after CurrentState goes to open. + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") - while current_state_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning: + while current_state_dut is cluster.Enums.ValveStateEnum.kTransitioning: + asserts.assert_equal(target_state_dut, cluster.Enums.ValveStateEnum.kOpen, "TargetState is incorrect") time.sleep(1) + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") + asserts.assert_true(target_state_dut is not NullValue, "TargetState is null") - asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kOpen, - "CurrentState is not the expected value") + self.step(4) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kOpen, "CurrentState is incorrect") + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) + asserts.assert_true(target_state_dut is NullValue, "TargetState is not null") self.step(5) try: @@ -103,23 +108,22 @@ async def test_TC_VALCC_3_1(self): self.step(6) target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) - - asserts.assert_true(target_state_dut is not NullValue, "TargetState is null") - asserts.assert_equal(target_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kClosed, - "TargetState is not the expected value") - - self.step(7) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") - while current_state_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning: + while current_state_dut is cluster.Enums.ValveStateEnum.kTransitioning: + asserts.assert_equal(target_state_dut, cluster.Enums.ValveStateEnum.kClosed, "TargetState is incorrect") time.sleep(1) + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") + asserts.assert_true(target_state_dut is not NullValue, "TargetState is null") - asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kClosed, - "CurrentState is not the expected value") + self.step(7) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kClosed, "CurrentState is incorrect") + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) + asserts.assert_true(target_state_dut is NullValue, "TargetState is not null") if __name__ == "__main__": From 18c061332ac23446da0ed22d8047e4806c73c09d Mon Sep 17 00:00:00 2001 From: cecille Date: Fri, 4 Oct 2024 09:59:50 -0400 Subject: [PATCH 02/14] fixup for 3.1 test --- src/python_testing/TC_VALCC_3_1.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index 9bb3dd8d306ce5..7c4f9e6def0964 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -29,7 +29,7 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from matter_testing_support import AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -44,13 +44,14 @@ def desc_TC_VALCC_3_1(self) -> str: def steps_TC_VALCC_3_1(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Send Open command"), - TestStep(3, "Read CurrentState and TargetState attribute until CurrentState is Open", - "Target state is Open while CurrentState is Transitioning"), + TestStep(2, "Set up a subscription to all attributes on the DUT"), + TestStep(2, "Send Open command", "DUT returns SUCCESS"), + TestStep(3, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Open (ordering does not matter)", + "Expected attribute reports are received"), TestStep(4, "Read CurrentState and TargetState attribute", "CurrentState is Open, TargetState is NULL"), - TestStep(5, "Send Close command"), - TestStep(6, "Read CurrentState and TargetState attribute until CurrentState is Open", - "Target state is Closed while CurrentState is Transitioning"), + TestStep(5, "Send Close command", "DUT returns SUCCESS"), + TestStep(3, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Closed (ordering does not matter)", + "Expected attribute reports are received"), TestStep(7, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), ] return steps @@ -69,6 +70,8 @@ async def test_TC_VALCC_3_1(self): self.step(1) cluster = Clusters.ValveConfigurationAndControl attributes = cluster.Attributes + attribute_subscription = ClusterAttributeChangeAccumulator(cluster) + await attribute_subscription.start(self.default_controller, self.dut_node_id, endpoint) self.step(2) try: @@ -79,6 +82,13 @@ async def test_TC_VALCC_3_1(self): self.step(3) + # Wait until the current state is open and the target state is Null. + # Wait for the entire duration of the test because this valve may be slow. The test will time out before this does. That's fine. + timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout + expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), AttributeValue( + endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kOpen)] + attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) + # Read target state first in case the current state goes to open between these calls. # The test re-reads target state after CurrentState goes to open. target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) From 7d45e45893f233ecf758f40dd49a2da037fc673a Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Mon, 7 Oct 2024 10:02:50 -0400 Subject: [PATCH 03/14] another fixup for 3.1 --- src/python_testing/TC_VALCC_3_1.py | 76 ++++++++++-------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index 7c4f9e6def0964..ab44cfbfc48418 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -45,14 +45,14 @@ def steps_TC_VALCC_3_1(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), TestStep(2, "Set up a subscription to all attributes on the DUT"), - TestStep(2, "Send Open command", "DUT returns SUCCESS"), - TestStep(3, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Open (ordering does not matter)", + TestStep(3, "Send Open command", "DUT returns SUCCESS"), + TestStep(4, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Open (ordering does not matter)", "Expected attribute reports are received"), - TestStep(4, "Read CurrentState and TargetState attribute", "CurrentState is Open, TargetState is NULL"), - TestStep(5, "Send Close command", "DUT returns SUCCESS"), - TestStep(3, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Closed (ordering does not matter)", + TestStep(5, "Read CurrentState and TargetState attribute", "CurrentState is Open, TargetState is NULL"), + TestStep(6, "Send Close command", "DUT returns SUCCESS"), + TestStep(7, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Closed (ordering does not matter)", "Expected attribute reports are received"), - TestStep(7, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), + TestStep(8, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), ] return steps @@ -67,21 +67,18 @@ async def test_TC_VALCC_3_1(self): endpoint = self.user_params.get("endpoint", 1) - self.step(1) + self.step(1) # commissioning - already done + + self.step(2) cluster = Clusters.ValveConfigurationAndControl attributes = cluster.Attributes attribute_subscription = ClusterAttributeChangeAccumulator(cluster) await attribute_subscription.start(self.default_controller, self.dut_node_id, endpoint) - self.step(2) - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - self.step(3) + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) + self.step(4) # Wait until the current state is open and the target state is Null. # Wait for the entire duration of the test because this valve may be slow. The test will time out before this does. That's fine. timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout @@ -89,51 +86,26 @@ async def test_TC_VALCC_3_1(self): endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kOpen)] attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) - # Read target state first in case the current state goes to open between these calls. - # The test re-reads target state after CurrentState goes to open. - target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - - while current_state_dut is cluster.Enums.ValveStateEnum.kTransitioning: - asserts.assert_equal(target_state_dut, cluster.Enums.ValveStateEnum.kOpen, "TargetState is incorrect") - time.sleep(1) - - target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") - asserts.assert_true(target_state_dut is not NullValue, "TargetState is null") - - self.step(4) - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kOpen, "CurrentState is incorrect") - target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) - asserts.assert_true(target_state_dut is NullValue, "TargetState is not null") - self.step(5) - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - - self.step(6) target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kOpen, "CurrentState is not open") + asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") - while current_state_dut is cluster.Enums.ValveStateEnum.kTransitioning: - asserts.assert_equal(target_state_dut, cluster.Enums.ValveStateEnum.kClosed, "TargetState is incorrect") - time.sleep(1) - - target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") - asserts.assert_true(target_state_dut is not NullValue, "TargetState is null") + self.step(6) + attribute_subscription.reset() + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) self.step(7) - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kClosed, "CurrentState is incorrect") + expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), AttributeValue( + endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kClosed)] + attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) + + self.step(8) target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) - asserts.assert_true(target_state_dut is NullValue, "TargetState is not null") + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kClosed, "CurrentState is not closed") + asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") if __name__ == "__main__": From 109f4002a71fbd02eaaf64dbd95f6cb3389f6c35 Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 7 Oct 2024 12:41:32 -0400 Subject: [PATCH 04/14] Add close at start of test --- .../linux/ValveControlDelegate.cpp | 3 -- ...valve-configuration-and-control-server.cpp | 21 +++++++++--- src/python_testing/TC_VALCC_3_1.py | 34 ++++++++++++------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/examples/all-clusters-app/linux/ValveControlDelegate.cpp b/examples/all-clusters-app/linux/ValveControlDelegate.cpp index f161ee65eae504..ed006eaa14baec 100644 --- a/examples/all-clusters-app/linux/ValveControlDelegate.cpp +++ b/examples/all-clusters-app/linux/ValveControlDelegate.cpp @@ -38,7 +38,6 @@ DataModel::Nullable ValveControlDelegate::HandleOpenValve(DataMod // In this demo application, the transition is considered instant, // so current level is set to the requested level and current state is set to kOpen. currentLevel = sLevel; - Attributes::CurrentState::Set(kValveEndpoint, ValveConfigurationAndControl::ValveStateEnum::kOpen); return DataModel::Nullable(currentLevel); } @@ -48,8 +47,6 @@ CHIP_ERROR ValveControlDelegate::HandleCloseValve() sLastOpenDuration = 0; sLevel = 0; ReturnErrorOnFailure(ValveConfigurationAndControl::UpdateCurrentLevel(kValveEndpoint, sLevel)); - ReturnErrorOnFailure( - ValveConfigurationAndControl::UpdateCurrentState(kValveEndpoint, ValveConfigurationAndControl::ValveStateEnum::kClosed)); ChipLogProgress(NotSpecified, "Valve closed"); return CHIP_NO_ERROR; } diff --git a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp index f6fa4e8fee6332..5fc2cac59efe7e 100644 --- a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp +++ b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp @@ -360,9 +360,8 @@ CHIP_ERROR SetValveLevel(EndpointId ep, DataModel::Nullable level, Data if (!isDelegateNull(delegate)) { DataModel::Nullable cLevel = delegate->HandleOpenValve(level); - if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel)) - { - VerifyOrReturnError(Status::Success == CurrentLevel::Set(ep, cLevel), attribute_error); + if (!cLevel.IsNull()) { + UpdateCurrentLevel(ep, cLevel.Value()); } } // start countdown @@ -376,14 +375,26 @@ CHIP_ERROR UpdateCurrentLevel(EndpointId ep, Percent currentLevel) if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel)) { VerifyOrReturnError(Status::Success == CurrentLevel::Set(ep, currentLevel), CHIP_IM_GLOBAL_STATUS(ConstraintError)); - return CHIP_NO_ERROR; } - return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + DataModel::Nullable targetLevel = DataModel::NullNullable; + TargetLevel::Get(ep, targetLevel); + if (!targetLevel.IsNull() && currentLevel == targetLevel.Value()) { + targetLevel = DataModel::NullNullable; + TargetLevel::Set(ep, targetLevel); + UpdateCurrentState(ep, currentLevel == 0 ? ValveStateEnum::kClosed : ValveStateEnum::kOpen); + } + return CHIP_NO_ERROR; } CHIP_ERROR UpdateCurrentState(EndpointId ep, ValveConfigurationAndControl::ValveStateEnum currentState) { VerifyOrReturnError(Status::Success == CurrentState::Set(ep, currentState), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + DataModel::Nullable targetState = DataModel::NullNullable; + TargetState::Get(ep, targetState); + if (currentState == targetState.ValueOr(ValveStateEnum::kUnknownEnumValue)) { + targetState = DataModel::NullNullable; + TargetState::Set(ep, targetState); + } emitValveStateChangedEvent(ep, currentState); return CHIP_NO_ERROR; } diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index ab44cfbfc48418..04678c7856afe9 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -45,14 +45,15 @@ def steps_TC_VALCC_3_1(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), TestStep(2, "Set up a subscription to all attributes on the DUT"), - TestStep(3, "Send Open command", "DUT returns SUCCESS"), - TestStep(4, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Open (ordering does not matter)", + TestStep(3, "Send a close command to the DUT and wait until the CurrentState is closed", "DUT returns SUCCESS"), + TestStep(4, "Send Open command", "DUT returns SUCCESS"), + TestStep(5, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Open (ordering does not matter)", "Expected attribute reports are received"), - TestStep(5, "Read CurrentState and TargetState attribute", "CurrentState is Open, TargetState is NULL"), - TestStep(6, "Send Close command", "DUT returns SUCCESS"), - TestStep(7, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Closed (ordering does not matter)", + TestStep(6, "Read CurrentState and TargetState attribute", "CurrentState is Open, TargetState is NULL"), + TestStep(7, "Send Close command", "DUT returns SUCCESS"), + TestStep(8, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Closed (ordering does not matter)", "Expected attribute reports are received"), - TestStep(8, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), + TestStep(9, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), ] return steps @@ -76,9 +77,18 @@ async def test_TC_VALCC_3_1(self): await attribute_subscription.start(self.default_controller, self.dut_node_id, endpoint) self.step(3) - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) + await self.send_single_cmd(cmd=cluster.Commands.Close(), endpoint=endpoint) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + if current_state_dut != cluster.Enums.ValveStateEnum.kClosed: + current_state_closed = AttributeValue( + endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kClosed) + attribute_subscription.await_all_final_values_reported(expected_final_values=[current_state_closed]) self.step(4) + attribute_subscription.reset() + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) + + self.step(5) # Wait until the current state is open and the target state is Null. # Wait for the entire duration of the test because this valve may be slow. The test will time out before this does. That's fine. timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout @@ -86,22 +96,22 @@ async def test_TC_VALCC_3_1(self): endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kOpen)] attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) - self.step(5) + self.step(6) target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kOpen, "CurrentState is not open") asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") - self.step(6) + self.step(7) attribute_subscription.reset() - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) + await self.send_single_cmd(cmd=cluster.Commands.Close(), endpoint=endpoint) - self.step(7) + self.step(8) expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), AttributeValue( endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kClosed)] attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) - self.step(8) + self.step(9) target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kClosed, "CurrentState is not closed") From c735c6a22fcb013e9ea755d088f9f09d49b49544 Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 7 Oct 2024 13:19:17 -0400 Subject: [PATCH 05/14] linter --- src/python_testing/TC_VALCC_3_1.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index 04678c7856afe9..622bec7c33a6d7 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -24,11 +24,8 @@ # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === -import time - import chip.clusters as Clusters from chip.clusters.Types import NullValue -from chip.interaction_model import InteractionModelError, Status from matter_testing_support import AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts From 7009dd36c839a9ef6b8c4870aa585275c873c499 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 7 Oct 2024 17:19:46 +0000 Subject: [PATCH 06/14] Restyled by clang-format --- .../valve-configuration-and-control-server.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp index 5fc2cac59efe7e..c5dd805f3bc13b 100644 --- a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp +++ b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp @@ -360,7 +360,8 @@ CHIP_ERROR SetValveLevel(EndpointId ep, DataModel::Nullable level, Data if (!isDelegateNull(delegate)) { DataModel::Nullable cLevel = delegate->HandleOpenValve(level); - if (!cLevel.IsNull()) { + if (!cLevel.IsNull()) + { UpdateCurrentLevel(ep, cLevel.Value()); } } @@ -378,7 +379,8 @@ CHIP_ERROR UpdateCurrentLevel(EndpointId ep, Percent currentLevel) } DataModel::Nullable targetLevel = DataModel::NullNullable; TargetLevel::Get(ep, targetLevel); - if (!targetLevel.IsNull() && currentLevel == targetLevel.Value()) { + if (!targetLevel.IsNull() && currentLevel == targetLevel.Value()) + { targetLevel = DataModel::NullNullable; TargetLevel::Set(ep, targetLevel); UpdateCurrentState(ep, currentLevel == 0 ? ValveStateEnum::kClosed : ValveStateEnum::kOpen); @@ -391,7 +393,8 @@ CHIP_ERROR UpdateCurrentState(EndpointId ep, ValveConfigurationAndControl::Valve VerifyOrReturnError(Status::Success == CurrentState::Set(ep, currentState), CHIP_IM_GLOBAL_STATUS(ConstraintError)); DataModel::Nullable targetState = DataModel::NullNullable; TargetState::Get(ep, targetState); - if (currentState == targetState.ValueOr(ValveStateEnum::kUnknownEnumValue)) { + if (currentState == targetState.ValueOr(ValveStateEnum::kUnknownEnumValue)) + { targetState = DataModel::NullNullable; TargetState::Set(ep, targetState); } From 3ab061b3cb457ea8423f1cb8117d93bf6d089566 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 7 Oct 2024 17:19:47 +0000 Subject: [PATCH 07/14] Restyled by isort --- src/python_testing/TC_VALCC_3_1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index 622bec7c33a6d7..5129ae61d95fcc 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -26,7 +26,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue -from matter_testing_support import AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from matter_testing_support import (AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, + default_matter_test_main) from mobly import asserts From fa25f334255cccc0284cbb36793793a412d0128e Mon Sep 17 00:00:00 2001 From: cecille Date: Tue, 22 Oct 2024 15:54:16 -0400 Subject: [PATCH 08/14] Add back the feature check --- .../valve-configuration-and-control-server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp index c5dd805f3bc13b..fd89ab135d384c 100644 --- a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp +++ b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp @@ -360,7 +360,7 @@ CHIP_ERROR SetValveLevel(EndpointId ep, DataModel::Nullable level, Data if (!isDelegateNull(delegate)) { DataModel::Nullable cLevel = delegate->HandleOpenValve(level); - if (!cLevel.IsNull()) + if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel) && !cLevel.IsNull()) { UpdateCurrentLevel(ep, cLevel.Value()); } From b858bfee91a05c5e2fc1a1610c75de7d458c7d52 Mon Sep 17 00:00:00 2001 From: cecille Date: Tue, 22 Oct 2024 17:20:28 -0400 Subject: [PATCH 09/14] TC-VALCC-3.3: Allow immediate open --- src/python_testing/TC_VALCC_3_1.py | 7 +- src/python_testing/TC_VALCC_3_3.py | 144 +++++++++++++++-------------- 2 files changed, 79 insertions(+), 72 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index 5129ae61d95fcc..5170369471a210 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -75,12 +75,15 @@ async def test_TC_VALCC_3_1(self): await attribute_subscription.start(self.default_controller, self.dut_node_id, endpoint) self.step(3) + # Wait for the entire duration of the test because this valve may be slow. The test will time out before this does. That's fine. + timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout await self.send_single_cmd(cmd=cluster.Commands.Close(), endpoint=endpoint) current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) if current_state_dut != cluster.Enums.ValveStateEnum.kClosed: current_state_closed = AttributeValue( endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kClosed) - attribute_subscription.await_all_final_values_reported(expected_final_values=[current_state_closed]) + attribute_subscription.await_all_final_values_reported( + expected_final_values=[current_state_closed], timeout_sec=timeout) self.step(4) attribute_subscription.reset() @@ -88,8 +91,6 @@ async def test_TC_VALCC_3_1(self): self.step(5) # Wait until the current state is open and the target state is Null. - # Wait for the entire duration of the test because this valve may be slow. The test will time out before this does. That's fine. - timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), AttributeValue( endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kOpen)] attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) diff --git a/src/python_testing/TC_VALCC_3_3.py b/src/python_testing/TC_VALCC_3_3.py index ddf3ba83d1b5c7..8eefebb04eb805 100644 --- a/src/python_testing/TC_VALCC_3_3.py +++ b/src/python_testing/TC_VALCC_3_3.py @@ -30,7 +30,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from matter_testing_support import (AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, + default_matter_test_main) from mobly import asserts @@ -45,14 +46,22 @@ def desc_TC_VALCC_3_3(self) -> str: def steps_TC_VALCC_3_3(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Read AttributeList attribute"), - TestStep(3, "Read DefaultOpenLevel attribute, if supported"), - TestStep(4, "Send Open command"), - TestStep(5, "Read TargetLevel attribute"), - TestStep(6, "Read CurrentLevel attribute"), - TestStep(7, "Send Close command"), - TestStep(8, "Read TargetLevel attribute"), - TestStep(9, "Read CurrentLevel attribute"), + TestStep(2, "Read AttributeList attribute", "Verify that the DUT response contains the AttributeList attribute."), + TestStep(3, "If the DefaultOpenLevel is not supported, skip all remaining steps in this test"), + TestStep(4, "TH reads from the DUT the DefaultOpenLevel attribute. Store the value as defaultOpenLevel."), + TestStep(5, "Set up a subscription to all attributes on the DUT", "Subscription is successful"), + TestStep(6, "Send a close command to the DUT and wait until the CurrentState is reported as closed", "DUT returns SUCCESS"), + # TODO: this test should probably SET the default open attribute as well and un-set it at the end, so we're not testing against the default. + TestStep(7, "Send Open command with no fields populated", "DUT returns SUCCESS"), + TestStep(8, "Wait until TH receives the following data reports (ordering not checked): TargetState set to NULL, TargetLevel set to NULL, CurrentState set to Open, CurrentLevel set to defaultOpenLevel", + "Expected attribute reports are received"), + TestStep(9, "Read CurrentState and TargetState attribute", "CurrentState is Open, TargetState is NULL"), + TestStep(10, "Read CurrentLevel and TargetLevel attribute", "CurrentLevel is defaultOpenLevel, TargetLevel is NULL"), + TestStep(11, "Send Close command", "DUT returns SUCCESS"), + TestStep(12, "Wait until TH receives the following data reports (ordering not checked): TargetState set to NULL, TargetLevel set to NULL, CurrentState set to Closed, CurrentLevel set to 0", + "Expected attribute reports are received"), + TestStep(13, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), + TestStep(14, "Read CurrentLevel and TargetLevel attribute", "CurrentLevel is 0, TargetLevel is NULL"), ] return steps @@ -74,78 +83,75 @@ async def test_TC_VALCC_3_3(self): attribute_list = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) self.step(3) - if attributes.DefaultOpenLevel.attribute_id in attribute_list: - defaultOpenLevel = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultOpenLevel) - else: - logging.info("Test step skipped") + if attributes.DefaultOpenLevel.attribute_id not in attribute_list: + asserts.skip('Endpoint does not match test requirements') self.step(4) - if attributes.DefaultOpenLevel.attribute_id in attribute_list: - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - else: - logging.info("Test step skipped") + default_open_level = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultOpenLevel) self.step(5) - if attributes.DefaultOpenLevel.attribute_id in attribute_list: - target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) - - asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null") - asserts.assert_equal(target_level_dut, defaultOpenLevel, "TargetLevel is not the expected value") - else: - logging.info("Test step skipped") + cluster = Clusters.ValveConfigurationAndControl + attributes = cluster.Attributes + attribute_subscription = ClusterAttributeChangeAccumulator(cluster) + await attribute_subscription.start(self.default_controller, self.dut_node_id, endpoint) self.step(6) - if attributes.DefaultOpenLevel.attribute_id in attribute_list: - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - while current_level_dut != defaultOpenLevel: - time.sleep(1) - - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - asserts.assert_equal(current_level_dut, defaultOpenLevel, "CurrentLevel is not the expected value") - else: - logging.info("Test step skipped") + timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout + await self.send_single_cmd(cmd=cluster.Commands.Close(), endpoint=endpoint) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + if current_state_dut != cluster.Enums.ValveStateEnum.kClosed: + current_state_closed = AttributeValue( + endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kClosed) + attribute_subscription.await_all_final_values_reported( + expected_final_values=[current_state_closed], timeout_sec=timeout) self.step(7) - if attributes.DefaultOpenLevel.attribute_id in attribute_list: - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - else: - logging.info("Test step skipped") + attribute_subscription.reset() + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) self.step(8) - if attributes.DefaultOpenLevel.attribute_id in attribute_list: - target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) - - asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null") - asserts.assert_equal(target_level_dut, 0, "TargetLevel is not the expected value") - else: - logging.info("Test step skipped") + expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentState, + value=cluster.Enums.ValveStateEnum.kOpen), + AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, value=default_open_level)] + attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) self.step(9) - if attributes.DefaultOpenLevel.attribute_id in attribute_list: - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - while current_level_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning: - time.sleep(1) - - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - asserts.assert_equal(current_level_dut, 0, "CurrentLevel is not the expected value") - else: - logging.info("Test step skipped") + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kOpen, "CurrentState is not open") + asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") + + self.step(10) + target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) + current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) + asserts.assert_equal(current_level_dut, default_open_level, "CurrentLevel is not defaultOpenLevel") + asserts.assert_equal(target_level_dut, NullValue, "TargetLevel is not null") + + self.step(11) + attribute_subscription.reset() + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) + + self.step(12) + expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentState, + value=cluster.Enums.ValveStateEnum.kClosed), + AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, value=0)] + attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) + + self.step(13) + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kClosed, "CurrentState is not open") + asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") + + self.step(14) + target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) + current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) + asserts.assert_equal(current_level_dut, 0, "CurrentLevel is not 0") + asserts.assert_equal(target_level_dut, NullValue, "TargetLevel is not null") if __name__ == "__main__": From 9b66452472f7d0e96baf85d36fb302cbc7877235 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Sun, 27 Oct 2024 12:26:22 -0400 Subject: [PATCH 10/14] Linter --- src/python_testing/TC_VALCC_3_1.py | 1 - src/python_testing/TC_VALCC_3_3.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py index 744bcc8be84705..3f421c78bc983b 100644 --- a/src/python_testing/TC_VALCC_3_1.py +++ b/src/python_testing/TC_VALCC_3_1.py @@ -33,7 +33,6 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue -from chip.interaction_model import InteractionModelError, Status from chip.testing.matter_testing import (AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) from mobly import asserts diff --git a/src/python_testing/TC_VALCC_3_3.py b/src/python_testing/TC_VALCC_3_3.py index f0b08156aae09d..712156375fee2d 100644 --- a/src/python_testing/TC_VALCC_3_3.py +++ b/src/python_testing/TC_VALCC_3_3.py @@ -31,12 +31,8 @@ # quiet: true # === END CI TEST ARGUMENTS === -import logging -import time - import chip.clusters as Clusters from chip.clusters.Types import NullValue -from chip.interaction_model import InteractionModelError, Status from chip.testing.matter_testing import (AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) from mobly import asserts From d48e147234a4b35822a7cacadce4a5fa395eb02d Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Sun, 8 Dec 2024 12:55:27 -0500 Subject: [PATCH 11/14] Fix 3.2 --- src/python_testing/TC_VALCC_3_2.py | 141 +++++++++++++++-------------- 1 file changed, 74 insertions(+), 67 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_2.py b/src/python_testing/TC_VALCC_3_2.py index 6905e3bde8096f..7719664f04a64b 100644 --- a/src/python_testing/TC_VALCC_3_2.py +++ b/src/python_testing/TC_VALCC_3_2.py @@ -25,6 +25,7 @@ # --commissioning-method on-network # --discriminator 1234 # --passcode 20202021 +# --endpoint 1 # --trace-to json:${TRACE_TEST_JSON}.json # --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # factory-reset: true @@ -37,7 +38,7 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from chip.testing.matter_testing import AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -52,13 +53,20 @@ def desc_TC_VALCC_3_2(self) -> str: def steps_TC_VALCC_3_2(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Read FeatureMap attribute"), - TestStep(3, "Send Open command with TargetLevel set to 100"), - TestStep(4, "Read TargetLevel attribute"), - TestStep(5, "Read CurrentLevel attribute"), - TestStep(6, "Send Close command"), - TestStep(7, "Read TargetLevel attribute"), - TestStep(8, "Read CurrentLevel attribute"), + TestStep(2, "Set up a subscription to all attributes on the DUT"), + TestStep(3, "Send a close command to the DUT and wait until the CurrentState is closed", "DUT returns SUCCESS"), + + TestStep(4, "TH sends command Open command with TargetLevel field set to 100 and the remaining fields not populated.", + "Verify DUT responds w/ status SUCCESS(0x00)."), + TestStep(5, "Wait until TH receives data reports for TargetState set to NULL, TargetLevel set to NULL, CurrentState set to Open and CurrentLevel set to 100 (ordering does not matter)", + "Expected attribute reports are received"), + + TestStep(6, "Read CurrentState, CurrentLevel, TargetState and TargetLevel attributes", + "CurrentState is Open, CurrentLevel is 100, TargetState is NULL and TagetLevel is NULL"), + TestStep(7, "Send Close command", "DUT returns SUCCESS"), + TestStep(8, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Closed (ordering does not matter)", + "Expected attribute reports are received"), + TestStep(9, "Read CurrentState and TargetState attribute", "CurrentState is Closed, TargetState is NULL"), ] return steps @@ -75,79 +83,78 @@ async def test_TC_VALCC_3_2(self): self.step(1) attributes = Clusters.ValveConfigurationAndControl.Attributes - - self.step(2) + # TODO: replace with top-level check using run_if_endpoint_matches feature_map = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.FeatureMap) - is_lvl_feature_supported = feature_map & Clusters.ValveConfigurationAndControl.Bitmaps.Feature.kLevel + if not is_lvl_feature_supported: + asserts.skip('Endpoint does not match test requirements') + + self.step(2) + cluster = Clusters.ValveConfigurationAndControl + attributes = cluster.Attributes + attribute_subscription = ClusterAttributeChangeAccumulator(cluster) + await attribute_subscription.start(self.default_controller, self.dut_node_id, endpoint) self.step(3) - if is_lvl_feature_supported: - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(targetLevel=100), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - else: - logging.info("Test step skipped") + # Wait for the entire duration of the test because this valve may be slow. The test will time out before this does. That's fine. + timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout + await self.send_single_cmd(cmd=cluster.Commands.Close(), endpoint=endpoint) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + if current_state_dut != cluster.Enums.ValveStateEnum.kClosed: + current_state_closed = AttributeValue( + endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kClosed) + attribute_subscription.await_all_final_values_reported( + expected_final_values=[current_state_closed], timeout_sec=timeout) self.step(4) - if is_lvl_feature_supported: - target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) - - asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null") - asserts.assert_equal(target_level_dut, 100, "TargetLevel is not the expected value") - else: - logging.info("Test step skipped") + attribute_subscription.reset() + try: + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(targetLevel=100), endpoint=endpoint) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") + pass self.step(5) - if is_lvl_feature_supported: - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - while current_level_dut != 100: - time.sleep(1) - - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - asserts.assert_equal(current_level_dut, 100, "CurrentLevel is not the expected value") - else: - logging.info("Test step skipped") + # Wait until the current state is open and the target state is Null. + expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentState, + value=cluster.Enums.ValveStateEnum.kOpen), + AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, values=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, values=100)] + attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) self.step(6) - if is_lvl_feature_supported: - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - else: - logging.info("Test step skipped") + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) + current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kOpen, "CurrentState is not open") + asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") + asserts.assert_equal(current_level_dut, 100, "CurrentLevel is not 100") + asserts.assert_equal(target_level_dut, NullValue, "TargetLevel is not null") self.step(7) - if is_lvl_feature_supported: - target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) - - asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null") - asserts.assert_equal(target_level_dut, 0, "TargetLevel is not the expected value") - else: - logging.info("Test step skipped") + attribute_subscription.reset() + await self.send_single_cmd(cmd=cluster.Commands.Close(), endpoint=endpoint) self.step(8) - if is_lvl_feature_supported: - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - while current_level_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning: - time.sleep(1) - - current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) - asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null") - - asserts.assert_equal(current_level_dut, 0, "CurrentLevel is not the expected value") - else: - logging.info("Test step skipped") + expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentState, + value=cluster.Enums.ValveStateEnum.kClosed), + AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, values=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, values=0)] + attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) + attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) + + self.step(9) + target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel) + current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) + asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kClosed, "CurrentState is not closed") + asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") + asserts.assert_equal(current_level_dut, 100, "CurrentLevel is not 0") + asserts.assert_equal(target_level_dut, NullValue, "TargetLevel is not null") if __name__ == "__main__": From 801e054ae52aae2a5bdedc3a99f2c391cbadc082 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Sun, 8 Dec 2024 13:10:46 -0500 Subject: [PATCH 12/14] couple little fixes --- src/python_testing/TC_VALCC_3_2.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_2.py b/src/python_testing/TC_VALCC_3_2.py index 793593ea2e7f0e..5501612067472c 100644 --- a/src/python_testing/TC_VALCC_3_2.py +++ b/src/python_testing/TC_VALCC_3_2.py @@ -56,14 +56,12 @@ def steps_TC_VALCC_3_2(self) -> list[TestStep]: TestStep(1, "Commissioning, already done", is_commissioning=True), TestStep(2, "Set up a subscription to all attributes on the DUT"), TestStep(3, "Send a close command to the DUT and wait until the CurrentState is closed", "DUT returns SUCCESS"), - TestStep(4, "TH sends command Open command with TargetLevel field set to 100 and the remaining fields not populated.", "Verify DUT responds w/ status SUCCESS(0x00)."), TestStep(5, "Wait until TH receives data reports for TargetState set to NULL, TargetLevel set to NULL, CurrentState set to Open and CurrentLevel set to 100 (ordering does not matter)", "Expected attribute reports are received"), - TestStep(6, "Read CurrentState, CurrentLevel, TargetState and TargetLevel attributes", - "CurrentState is Open, CurrentLevel is 100, TargetState is NULL and TagetLevel is NULL"), + "CurrentState is Open, CurrentLevel is 100, TargetState is NULL and TargetLevel is NULL"), TestStep(7, "Send Close command", "DUT returns SUCCESS"), TestStep(8, "Wait until TH receives and data report for TargetState set to NULL and an attribute report for CurrentState set to Closed (ordering does not matter)", "Expected attribute reports are received"), @@ -81,6 +79,8 @@ def pics_TC_VALCC_3_2(self) -> list[str]: async def test_TC_VALCC_3_2(self): endpoint = self.get_endpoint(default=1) + asserts.assert_is_not_none( + endpoint, "Endpoint is required for this tests. The test endpoint is set using the --endpoint flag") self.step(1) attributes = Clusters.ValveConfigurationAndControl.Attributes @@ -120,8 +120,8 @@ async def test_TC_VALCC_3_2(self): expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kOpen), - AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, values=NullValue), - AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, values=100)] + AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, value=100)] attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) self.step(6) @@ -142,8 +142,8 @@ async def test_TC_VALCC_3_2(self): expected_final_state = [AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetState, value=NullValue), AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentState, value=cluster.Enums.ValveStateEnum.kClosed), - AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, values=NullValue), - AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, values=0)] + AttributeValue(endpoint_id=endpoint, attribute=attributes.TargetLevel, value=NullValue), + AttributeValue(endpoint_id=endpoint, attribute=attributes.CurrentLevel, value=0)] attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) attribute_subscription.await_all_final_values_reported(expected_final_values=expected_final_state, timeout_sec=timeout) @@ -154,7 +154,7 @@ async def test_TC_VALCC_3_2(self): current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel) asserts.assert_equal(current_state_dut, cluster.Enums.ValveStateEnum.kClosed, "CurrentState is not closed") asserts.assert_equal(target_state_dut, NullValue, "TargetState is not null") - asserts.assert_equal(current_level_dut, 100, "CurrentLevel is not 0") + asserts.assert_equal(current_level_dut, 0, "CurrentLevel is not 0") asserts.assert_equal(target_level_dut, NullValue, "TargetLevel is not null") From 0793cebf27a1758e5e36b63e95d6df4fe1d40314 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Sun, 8 Dec 2024 18:11:53 +0000 Subject: [PATCH 13/14] Restyled by isort --- src/python_testing/TC_VALCC_3_2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_VALCC_3_2.py b/src/python_testing/TC_VALCC_3_2.py index 5501612067472c..5852f9f7c00468 100644 --- a/src/python_testing/TC_VALCC_3_2.py +++ b/src/python_testing/TC_VALCC_3_2.py @@ -39,7 +39,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from chip.testing.matter_testing import (AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, + async_test_body, default_matter_test_main) from mobly import asserts From 1f3a1ea7aca10b0e7fd15aec24308ec312fb694d Mon Sep 17 00:00:00 2001 From: cecille Date: Thu, 12 Dec 2024 10:01:20 -0500 Subject: [PATCH 14/14] linter --- src/python_testing/TC_VALCC_3_2.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/python_testing/TC_VALCC_3_2.py b/src/python_testing/TC_VALCC_3_2.py index 5852f9f7c00468..5e22cda0ef39f0 100644 --- a/src/python_testing/TC_VALCC_3_2.py +++ b/src/python_testing/TC_VALCC_3_2.py @@ -33,9 +33,6 @@ # quiet: true # === END CI TEST ARGUMENTS === -import logging -import time - import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status