diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index c2015d037578ae..80bb8f62da70f7 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -9550,6 +9550,9 @@ PICS: the same endpoint?" id: RVCCLEANM.S.F00 + - label: "Does the device read the global attribute: EventList from the DUT" + id: RVCCLEANM.S.Afffa + # # server / attributes # @@ -9723,6 +9726,9 @@ PICS: the same endpoint?" id: RVCRUNM.S.F00 + - label: "Does the device read the global attribute: EventList from the DUT" + id: RVCRUNM.S.Afffa + #Attributes - label: "Does the device implement the SupportedModes attribute?" id: RVCRUNM.S.A0000 diff --git a/src/app/tests/suites/certification/Test_TC_RVCCLEANM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RVCCLEANM_1_1.yaml index de9ad5afadc025..ccc1f23c71d3eb 100644 --- a/src/app/tests/suites/certification/Test_TC_RVCCLEANM_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_RVCCLEANM_1_1.yaml @@ -11,89 +11,122 @@ # 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. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default -name: 92.1.1. [TC-RVCCLEANM-1.1] Global attributes with DUT as Server +name: 78.1.1. [TC-RVCCLEANM-1.1] Global attributes with server as DUT PICS: - RVCCLEANM.S config: nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 + cluster: "RVC Clean Mode" + endpoint: 1 tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - verification: | - ./chip-tool rvcleanm read cluster-revision 1 1 - - Verify " ClusterRevision attribute has the value 2 " and reflects the highest revision number 2 on the TH(Chip-tool) and below is the sample log provided for the raspi platform: - - [1645775623.658997][3277:3282] CHIP:TOO: ClusterRevision: 1 - disabled: true - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - verification: | - ./chip-tool rvcleanm read feature-map 1 1 - On the reference app we see featureMap value 1, This value changes depending on DUT implementing the features - Verify FeatureMap attribute On the TH(Chip-tool) Log - - [1649052001.646939][8355:8360] CHIP:TOO: FeatureMap: 1 - disabled: true - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - verification: | - ./chip-tool rvcleanm read attribute-list 1 1 - - Verify " AttributeList "should include the mandatory attributes (values 0, 2, 3) and - global attributes (value 65533, 65532, 65531, 65530, 65529 and 65528) - list may include optional attribute(value 0x0004), if RVCCLEANM.S.A0004(StartUpMode) supports, - list contains feature dependent attribute (values 0x0005),if RVCCLEANM.S.F00(DEPONOFF) is true on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: + - label: "Step 1: Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Step 2: TH reads the ClusterRevision attribute from the DUT" + command: "readAttribute" + attribute: "ClusterRevision" + response: + value: 1 + constraints: + type: int16u + + - label: "TH reads the FeatureMap attribute from the DUT" + PICS: " !RVCCLEANM.S.F00 " + command: "readAttribute" + attribute: "FeatureMap" + response: + value: 0 + constraints: + type: bitmap32 - [1676288620.483812][4014:4016] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0050 Attribute 0x0000_FFFB DataVersion: 2649295313 - [1676288620.483850][4014:4016] CHIP:TOO: AttributeList: 13 entries - [1676288620.483861][4014:4016] CHIP:TOO: [1]: 0 - [1676288620.483870][4014:4016] CHIP:TOO: [2]: 1 - [1676288620.483878][4014:4016] CHIP:TOO: [3]: 65528 - [1676288620.483886][4014:4016] CHIP:TOO: [4]: 65529 - [1676288620.483892][4014:4016] CHIP:TOO: [5]: 65530 - [1676288620.483899][4014:4016] CHIP:TOO: [6]: 65531 - [1676288620.483906][4014:4016] CHIP:TOO: [7]: 4293984257 - [1676288620.483915][4014:4016] CHIP:TOO: [8]: 2 - [1676288620.483922][4014:4016] CHIP:TOO: [9]: 3 - [1676288620.483929][4014:4016] CHIP:TOO: [10]: 4 - [1676288620.483934][4014:4016] CHIP:TOO: [11]: 5 - [1676288620.483941][4014:4016] CHIP:TOO: [12]: 65532 - [1676288620.483947][4014:4016] CHIP:TOO: [13]: 65533 - [1676288620.484034][4014:4016] CHIP:EM: <<< [E:29816i M:167554497 (Ack:41020138)] (S) Msg TX to 1:000000000 - - - *NOTE* : This sample attribute list reflects the currently implemented attributes on the all-clusters-app. - disabled: true - - - label: "Step 5: TH reads from the DUT the AcceptedCommandList attribute." - verification: | - ./chip-tool rvcleanm read accepted-command-list 1 1 + - label: + "Given RVCCLEANM.S.F00(DEPONOFF) ensure featuremap has the correct bit + set" + PICS: RVCCLEANM.S.F00 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x1] + + - label: "Step 4a: TH reads the AttributeList attribute from the DUT" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - Verify the "AcceptedCommandList" contains feature dependent commands + - label: + "TH reads the optional attribute(StartUpMode) in AttributeList from + the DUT" + PICS: RVCCLEANM.S.A0002 + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [2] - [1650274602.826352][8965:8970] CHIP:TOO: AcceptedCommandList: 1 entries - [1650274602.826442][8965:8970] CHIP:TOO: [1]: 0 - disabled: true + - label: + "Read the Feature dependent(RVCCLEANM.S.F00 - DEPONOFF) and optional + attribute(OnMode) is in AttributeList from the DUT" + PICS: RVCCLEANM.S.F00 + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [3] - - label: "Step 6: TH reads from the DUT the GeneratedCommandList attribute." - verification: | - ./chip-tool rvcleanm read generated-command-list 1 1 + - label: + "Read the Feature dependent(RVCCLEANM.S.F00 - DEPONOFF) and optional + attribute(OnMode) is not in AttributeList from the DUT" + PICS: " !RVCCLEANM.S.F00 " + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + excludes: [3] + + - label: "Read the global attribute: EventList from the DUT" + PICS: RVCCLEANM.S.Afffa + command: "readAttribute" + attribute: "EventList" + response: + value: [] + constraints: + type: list - Verify "GeneratedCommandList" contains feature dependent commands + - label: + "Read the global attribute AcceptedCommandList. Check if it contains + id 0x0 (ChangeToMode)" + PICS: RVCCLEANM.S.C00.Rsp + command: "readAttribute" + attribute: "AcceptedCommandList" + response: + value: [0] + constraints: + type: list - [1650274662.075309][8972:8977] CHIP:TOO: GeneratedCommandList: 0 entries - disabled: true + - label: + "Read the global attribute: GeneratedCommandList. Check if it contains + id 0x1 (ChangeToModeResponse)" + PICS: RVCCLEANM.S.C01.Tx + command: "readAttribute" + attribute: "GeneratedCommandList" + response: + value: [1] + constraints: + type: list diff --git a/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_1_1.yaml index 8e0d66f1ba34d9..d9f42eba8131fe 100644 --- a/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_1_1.yaml @@ -19,7 +19,7 @@ PICS: config: nodeId: 0x12344321 - cluster: "Robotic Vacuum Operational State" + cluster: "Rvc Operational State" endpoint: 1 tests: diff --git a/src/app/tests/suites/certification/Test_TC_RVCRUNM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RVCRUNM_1_1.yaml index 5ee4e7bdb9c9e6..928d4176f24911 100644 --- a/src/app/tests/suites/certification/Test_TC_RVCRUNM_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_RVCRUNM_1_1.yaml @@ -11,90 +11,122 @@ # 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. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default -name: 87.1.1. [TC-RVCRUNM-1.1] Global attributes with DUT as Server +name: 78.1.1. [TC-RVCRUNM-1.1] Global attributes with server as DUT PICS: - RVCRUNM.S config: nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 + cluster: "RVC Run Mode" + endpoint: 1 tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - verification: | - ./chip-tool rvcrunm read cluster-revision 1 1 - - Verify " ClusterRevision attribute has the value 2 " and reflects the highest revision number 2 on the TH(Chip-tool) and below is the sample log provided for the raspi platform: - - [1645775623.658997][3277:3282] CHIP:TOO: ClusterRevision: 1 - disabled: true - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - verification: | - ./chip-tool rvcrunm read feature-map 1 1 - On the reference app we see featureMap value 1, This value changes depending on DUT implementing the features - Verify FeatureMap attribute On the TH(Chip-tool) Log - - [1649052001.646939][8355:8360] CHIP:TOO: FeatureMap: 1 - disabled: true - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - verification: | - ./chip-tool rvcrunm read attribute-list 1 1 - - Verify " AttributeList "should include the mandatory attributes (values 0, 2, 3) and - global attributes (value 65533, 65532, 65531, 65530, 65529 and 65528) - list may include optional attribute(value 0x0004), if RVCRUNM.S.A0004(StartUpMode) supports, - list contains feature dependent attribute (values 0x0005),if RVCRUNM.S.F00(DEPONOFF) is true on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH reads the ClusterRevision attribute from the DUT" + command: "readAttribute" + attribute: "ClusterRevision" + response: + value: 1 + constraints: + type: int16u + + - label: "TH reads the FeatureMap attribute from the DUT" + PICS: " !RVCRUNM.S.F00 " + command: "readAttribute" + attribute: "FeatureMap" + response: + value: 0 + constraints: + type: bitmap32 - [1676288620.483812][4014:4016] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0050 Attribute 0x0000_FFFB DataVersion: 2649295313 - [1676288620.483850][4014:4016] CHIP:TOO: AttributeList: 13 entries - [1676288620.483861][4014:4016] CHIP:TOO: [1]: 0 - [1676288620.483870][4014:4016] CHIP:TOO: [2]: 1 - [1676288620.483878][4014:4016] CHIP:TOO: [3]: 65528 - [1676288620.483886][4014:4016] CHIP:TOO: [4]: 65529 - [1676288620.483892][4014:4016] CHIP:TOO: [5]: 65530 - [1676288620.483899][4014:4016] CHIP:TOO: [6]: 65531 - [1676288620.483906][4014:4016] CHIP:TOO: [7]: 4293984257 - [1676288620.483915][4014:4016] CHIP:TOO: [8]: 2 - [1676288620.483922][4014:4016] CHIP:TOO: [9]: 3 - [1676288620.483929][4014:4016] CHIP:TOO: [10]: 4 - [1676288620.483934][4014:4016] CHIP:TOO: [11]: 5 - [1676288620.483941][4014:4016] CHIP:TOO: [12]: 65532 - [1676288620.483947][4014:4016] CHIP:TOO: [13]: 65533 - [1676288620.484034][4014:4016] CHIP:EM: <<< [E:29816i M:167554497 (Ack:41020138)] (S) Msg TX to 1:000000000 - - - *NOTE* : This sample attribute list reflects the currently implemented attributes on the all-clusters-app. - disabled: true - - - label: "Step 5: TH reads from the DUT the AcceptedCommandList attribute." - verification: | - ./chip-tool rvcrunm read accepted-command-list 1 1 + - label: + "Given RVCRUNM.S.F00(DEPONOFF) ensure featuremap has the correct bit + set" + PICS: RVCRUNM.S.F00 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x1] + + - label: "TH reads the AttributeList attribute from the DUT" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - Verify the "AcceptedCommandList" contains feature dependent commands + - label: + "TH reads the optional attribute(StartUpMode) in AttributeList from + the DUT" + PICS: RVCRUNM.S.A0002 + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [2] - [1650274602.826352][8965:8970] CHIP:TOO: AcceptedCommandList: 1 entries - [1650274602.826442][8965:8970] CHIP:TOO: [1]: 0 - disabled: true + - label: + "Read the Feature dependent(RVCRUNM.S.F00 - DEPONOFF) and optional + attribute(OnMode) is in AttributeList from the DUT" + PICS: RVCRUNM.S.F00 + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [3] - - label: "Step 6: TH reads from the DUT the GeneratedCommandList attribute." - verification: | - ./chip-tool rvcrunm read generated-command-list 1 1 + - label: + "Read the Feature dependent(RVCRUNM.S.F00 - DEPONOFF) and optional + attribute(OnMode) is not in AttributeList from the DUT" + PICS: " !RVCRUNM.S.F00 " + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + excludes: [3] + + - label: "Read the global attribute: EventList from the DUT" + PICS: RVCRUNM.S.Afffa + command: "readAttribute" + attribute: "EventList" + response: + value: [] + constraints: + type: list - Verify "GeneratedCommandList" contains feature dependent commands - Value is 0 on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: + - label: + "Read the global attribute AcceptedCommandList. Check if it contains + id 0x0 (ChangeToMode)" + PICS: RVCRUNM.S.C00.Rsp + command: "readAttribute" + attribute: "AcceptedCommandList" + response: + value: [0] + constraints: + type: list - [1650274662.075309][8972:8977] CHIP:TOO: GeneratedCommandList: 0 entries - disabled: true + - label: + "Read the global attribute: GeneratedCommandList. Check if it contains + id 0x1 (ChangeToModeResponse)" + PICS: RVCRUNM.S.C01.Tx + command: "readAttribute" + attribute: "GeneratedCommandList" + response: + value: [1] + constraints: + type: list diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index d23c78d100b04d..fec8d2be4b5d1d 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2613,6 +2613,7 @@ RVCCLEANM.S.A0000=1 RVCCLEANM.S.A0001=1 RVCCLEANM.S.A0002=1 RVCCLEANM.S.A0003=1 +RVCCLEANM.S.Afffa=1 #Feature RVCCLEANM.S.F00=1 @@ -2658,6 +2659,7 @@ RVCRUNM.S.A0000=1 RVCRUNM.S.A0001=1 RVCRUNM.S.A0002=1 RVCRUNM.S.A0003=1 +RVCRUNM.S.Afffa=1 #Commands RVCRUNM.S.C00.Rsp=1 diff --git a/src/python_testing/TC_RVCCLEANM_1_2.py b/src/python_testing/TC_RVCCLEANM_1_2.py new file mode 100644 index 00000000000000..9090a3948bfcc8 --- /dev/null +++ b/src/python_testing/TC_RVCCLEANM_1_2.py @@ -0,0 +1,115 @@ +# +# 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 chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: + + +class TC_RVCCLEANM_1_2(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcCleanMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + @async_test_body + async def test_TC_RVCCLEANM_1_2(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + + attributes = Clusters.RvcCleanMode.Attributes + + self.print_step(1, "Commissioning, already done") + + if self.check_pics("RVCCLEANM.S.A0000"): + self.print_step(2, "Read SupportedModes attribute") + supported_modes = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.SupportedModes) + + logging.info("SupportedModes: %s" % (supported_modes)) + + asserts.assert_greater_equal(len(supported_modes), 1, "SupportedModes must have at least one entry!") + + modes = [] + for m in supported_modes: + if m.mode in modes: + asserts.fail("SupportedModes must have unique mode values!") + else: + modes.append(m.mode) + + labels = [] + for m in supported_modes: + if m.label in labels: + asserts.fail("SupportedModes must have unique mode label values!") + else: + labels.append(m.label) + + # common mode tags + commonTags = {0x0: 'Auto', + 0x1: 'Quick', + 0x2: 'Quiet', + 0x3: 'LowNoise', + 0x4: 'LowEnergy', + 0x5: 'Vacation', + 0x6: 'Min', + 0x7: 'Max', + 0x8: 'Night', + 0x9: 'Day'} + + cleanTags = [tag.value for tag in Clusters.RvcCleanMode.Enums.ModeTag + if tag is not Clusters.RvcCleanMode.Enums.ModeTag.kUnknownEnumValue] + + for m in supported_modes: + for t in m.modeTags: + is_mfg = (0x8000 <= t.value and t.value <= 0xBFFF) + asserts.assert_true(t.value in commonTags.keys() or t.value in cleanTags or is_mfg, + "Found a SupportedModes entry with invalid mode tag value!") + + if self.check_pics("RVCCLEANM.S.A0001"): + self.print_step(3, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + asserts.assert_true(current_mode in modes, "CurrentMode is not a supported mode!") + + if self.check_pics("RVCCLEANM.S.A0003"): + self.print_step(4, "Read OnMode attribute") + on_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.OnMode) + + logging.info("OnMode: %s" % (on_mode)) + asserts.assert_true(on_mode in modes or on_mode == NullValue, "OnMode is not a supported mode!") + + if self.check_pics("RVCCLEANM.S.A0002"): + self.print_step(5, "Read StartUpMode attribute") + startup_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.StartUpMode) + + logging.info("StartUpMode: %s" % (startup_mode)) + asserts.assert_true(startup_mode in modes or startup_mode == NullValue, "StartUpMode is not a supported mode!") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCCLEANM_2_1.py b/src/python_testing/TC_RVCCLEANM_2_1.py new file mode 100644 index 00000000000000..3c58a7e11795ea --- /dev/null +++ b/src/python_testing/TC_RVCCLEANM_2_1.py @@ -0,0 +1,162 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: PIXIT_MODEOK: PIXIT_MODEFAIL: + + +class TC_RVCCLEANM_2_1(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcCleanMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcCleanMode.Commands.ChangeToModeResponse: + ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcCleanMode.Commands.ChangeToMode(newMode=newMode), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.RvcCleanMode.Commands.ChangeToModeResponse), + "Unexpected return type for ChangeToMode") + return ret + + @async_test_body + async def test_TC_RVCCLEANM_2_1(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + asserts.assert_true('PIXIT_MODEOK' in self.matter_test_config.global_test_params, + "PIXIT_MODEOK must be included on the command line in " + "the --int-arg flag as PIXIT_MODEOK:") + asserts.assert_true('PIXIT_MODEFAIL' in self.matter_test_config.global_test_params, + "PIXIT_MODEFAIL must be included on the command line in " + "the --int-arg flag as PIXIT_MODEFAIL:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + self.modeok = self.matter_test_config.global_test_params['PIXIT_MODEOK'] + self.modefail = self.matter_test_config.global_test_params['PIXIT_MODEFAIL'] + + asserts.assert_true(self.check_pics("RVCCLEANM.S.A0000"), "RVCCLEANM.S.A0000 must be supported") + asserts.assert_true(self.check_pics("RVCCLEANM.S.A0001"), "RVCCLEANM.S.A0001 must be supported") + asserts.assert_true(self.check_pics("RVCCLEANM.S.C00.Rsp"), "RVCCLEANM.S.C00.Rsp must be supported") + asserts.assert_true(self.check_pics("RVCCLEANM.S.C01.Tx"), "RVCCLEANM.S.C01.Tx must be supported") + + attributes = Clusters.RvcCleanMode.Attributes + + self.print_step(1, "Commissioning, already done") + + self.print_step(2, "Read SupportedModes attribute") + supported_modes = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.SupportedModes) + + logging.info("SupportedModes: %s" % (supported_modes)) + + asserts.assert_greater_equal(len(supported_modes), 2, "SupportedModes must have at least two entries!") + + modes = [m.mode for m in supported_modes] + + self.print_step(3, "Read CurrentMode attribute") + + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + # pick a value that's not on the list of supported modes + invalid_mode = max(modes) + 1 + + from enum import Enum + + class CommonCodes(Enum): + SUCCESS = 0x00 + UNSUPPORTED_MODE = 0x01 + GENERIC_FAILURE = 0x02 + + rvcCleanCodes = [code.value for code in Clusters.RvcCleanMode.Enums.StatusCode + if code is not Clusters.RvcCleanMode.Enums.StatusCode.kUnknownEnumValue] + + self.print_step(4, "Send ChangeToMode command with NewMode set to %d" % (old_current_mode)) + + ret = await self.send_change_to_mode_cmd(newMode=old_current_mode) + asserts.assert_true(ret.status == CommonCodes.SUCCESS.value, "Changing the mode to the current mode should be a no-op") + + self.print_step(5, "Manually put the device in a state from which it will FAIL to transition to mode %d" % (self.modefail)) + input("Press Enter when done.\n") + + self.print_step(6, "Read CurrentMode attribute") + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + self.print_step(7, "Send ChangeToMode command with NewMode set to %d" % (self.modefail)) + + ret = await self.send_change_to_mode_cmd(newMode=self.modefail) + st = ret.status + is_mfg_code = st in range(0x80, 0xC0) + is_err_code = (st == CommonCodes.GENERIC_FAILURE.value) or (st in rvcCleanCodes) or is_mfg_code + asserts.assert_true(is_err_code, "Changing to mode %d must fail due to the current state of the device" % (self.modefail)) + st_text_len = len(ret.statusText) + asserts.assert_true(st_text_len in range(1, 65), "StatusText length (%d) must be between 1 and 64" % (st_text_len)) + + self.print_step(8, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(current_mode == old_current_mode, "CurrentMode changed after failed ChangeToMode command!") + + self.print_step(9, "Manually put the device in a state from which it will SUCCESSFULLY transition to mode %d" % (self.modeok)) + input("Press Enter when done.\n") + + self.print_step(10, "Read CurrentMode attribute") + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + self.print_step(11, "Send ChangeToMode command with NewMode set to %d" % (self.modeok)) + + ret = await self.send_change_to_mode_cmd(newMode=self.modeok) + asserts.assert_true(ret.status == CommonCodes.SUCCESS.value, + "Changing to mode %d must succeed due to the current state of the device" % (self.modeok)) + + self.print_step(12, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(current_mode == self.modeok, + "CurrentMode doesn't match the argument of the successful ChangeToMode command!") + + self.print_step(13, "Send ChangeToMode command with NewMode set to %d" % (invalid_mode)) + + ret = await self.send_change_to_mode_cmd(newMode=invalid_mode) + asserts.assert_true(ret.status == CommonCodes.UNSUPPORTED_MODE.value, + "Attempt to change to invalid mode %d didn't fail as expected" % (invalid_mode)) + + self.print_step(14, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(current_mode == self.modeok, "CurrentMode changed after failed ChangeToMode command!") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCCLEANM_3_2.py b/src/python_testing/TC_RVCCLEANM_3_2.py new file mode 100644 index 00000000000000..1d5d24beea5ac1 --- /dev/null +++ b/src/python_testing/TC_RVCCLEANM_3_2.py @@ -0,0 +1,115 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: + + +class TC_RVCCLEANM_3_2(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcCleanMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcCleanMode.Commands.ChangeToModeResponse: + ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcCleanMode.Commands.ChangeToMode(newMode=newMode), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.RvcCleanMode.Commands.ChangeToModeResponse), + "Unexpected return type for ChangeToMode") + return ret + + @async_test_body + async def test_TC_RVCCLEANM_3_2(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + + asserts.assert_true(self.check_pics("RVCCLEANM.S.A0000"), "RVCCLEANM.S.A0000 must be supported") + asserts.assert_true(self.check_pics("RVCCLEANM.S.A0001"), "RVCCLEANM.S.A0001 must be supported") + asserts.assert_true(self.check_pics("RVCCLEANM.S.A0002"), "RVCCLEANM.S.A0002 must be supported") + asserts.assert_true(self.check_pics("RVCCLEANM.S.C00.Rsp"), "RVCCLEANM.S.C00.Rsp must be supported") + asserts.assert_true(self.check_pics("RVCCLEANM.S.C01.Tx"), "RVCCLEANM.S.C01.Tx must be supported") + + attributes = Clusters.RvcCleanMode.Attributes + + from enum import Enum + + class CommonCodes(Enum): + SUCCESS = 0x00 + UNSUPPORTED_MODE = 0x01 + GENERIC_FAILURE = 0x02 + + self.print_step(1, "Commissioning, already done") + + self.print_step(2, "Read StartUpMode attribute") + + startup_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.StartUpMode) + + logging.info("StartUpMode: %s" % (startup_mode)) + + self.print_step(3, "Read CurrentMode attribute") + + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + if old_current_mode == startup_mode: + + self.print_step(4, "Read SupportedModes attribute") + supported_modes = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.SupportedModes) + + logging.info("SupportedModes: %s" % (supported_modes)) + + asserts.assert_greater_equal(len(supported_modes), 2, "SupportedModes must have at least two entries!") + + new_mode = None + + for m in supported_modes: + if m.mode != startup_mode: + new_mode = m.mode + break + + self.print_step(5, "Send ChangeToMode command with NewMode set to %d" % (new_mode)) + + ret = await self.send_change_to_mode_cmd(newMode=new_mode) + asserts.assert_true(ret.status == CommonCodes.SUCCESS.value, "Changing the mode should succeed") + + self.default_controller.ExpireSessions(self.dut_node_id) + + self.print_step(6, "Physically power cycle the device") + input("Press Enter when done.\n") + + self.print_step(7, "Read CurrentMode attribute") + + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(startup_mode == current_mode, "CurrentMode must match StartUpMode after a power cycle") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCOPSTATE_2_1.py b/src/python_testing/TC_RVCOPSTATE_2_1.py new file mode 100644 index 00000000000000..acd0ba35b6a4f4 --- /dev/null +++ b/src/python_testing/TC_RVCOPSTATE_2_1.py @@ -0,0 +1,133 @@ +# +# 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 chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: + + +class TC_RVCOPSTATE_2_1(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcOperationalState + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + @async_test_body + async def test_TC_RVCOPSTATE_2_1(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + + attributes = Clusters.RvcOperationalState.Attributes + + self.print_step(1, "Commissioning, already done") + + if self.check_pics("RVCOPSTATE.S.A0000"): + self.print_step(2, "Read PhaseList attribute") + phase_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.PhaseList) + + if phase_list == NullValue: + logging.info("PhaseList is null") + else: + logging.info("PhaseList: %s" % (phase_list)) + + phase_list_len = len(phase_list) + + asserts.assert_less_equal(phase_list_len, 32, "PhaseList must have no more than 32 entries!") + + if self.check_pics("RVCOPSTATE.S.A0001"): + self.print_step(3, "Read CurrentPhase attribute") + current_phase = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentPhase) + logging.info("CurrentPhase: %s" % (current_phase)) + + if phase_list == NullValue: + asserts.assert_true(current_phase == NullValue, "CurrentPhase should be null") + else: + asserts.assert_true(0 <= current_phase and current_phase <= (phase_list_len - 1), + "CurrentPhase must be between 0 and (phase-list-size - 1)") + + if self.check_pics("RVCOPSTATE.S.A0002"): + self.print_step(4, "Read CountdownTime attribute") + countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.CountdownTime) + + logging.info("CountdownTime: %s" % (countdown_time)) + if countdown_time is not NullValue: + asserts.assert_true(countdown_time >= 0 and countdown_time <= 259200, "CountdownTime must be between 0 and 259200") + + if self.check_pics("RVCOPSTATE.S.A0003"): + self.print_step(5, "Read OperationalStateList attribute") + operational_state_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.OperationalStateList) + + logging.info("OperationalStateList: %s" % (operational_state_list)) + + state_ids = [s.operationalStateID for s in operational_state_list] + + defined_states = [state.value for state in Clusters.OperationalState.Enums.OperationalStateEnum + if state is not Clusters.OperationalState.Enums.OperationalStateEnum.kUnknownEnumValue] + defined_states.extend(state.value for state in Clusters.RvcOperationalState.Enums.OperationalStateEnum + if state is not Clusters.RvcOperationalState.Enums.OperationalStateEnum.kUnknownEnumValue) + + for state_id in state_ids: + in_range = (0x8000 <= state_id and state_id <= 0xBFFF) + asserts.assert_true(state_id in defined_states or in_range, + "Found a OperationalStateList entry with invalid ID value!") + if state_id == Clusters.OperationalState.Enums.OperationalStateEnum.kError: + error_present_in_list = True + asserts.assert_true(error_present_in_list, "The OperationalStateList does not have an ID entry of Error(0x03)") + + if self.check_pics("RVCOPSTATE.S.A0004"): + self.print_step(6, "Read OperationalState attribute") + operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.OperationalState) + + logging.info("OperationalState: %s" % (operational_state)) + + in_range = (0x8000 <= operational_state and operational_state <= 0xBFFF) + asserts.assert_true(operational_state in defined_states or in_range, "OperationalState has an invalid ID value!") + + if self.check_pics("RVCOPSTATE.S.A0005"): + self.print_step(7, "Read OperationalError attribute") + operational_error = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.OperationalError) + + logging.info("OperationalError: %s" % (operational_error)) + + # Defined Errors + defined_errors = [error.value for error in Clusters.OperationalState.Enums.ErrorStateEnum + if error is not Clusters.OperationalState.Enums.ErrorStateEnum.kUnknownEnumValue] + defined_errors.extend(error.value for error in Clusters.RvcOperationalState.Enums.ErrorStateEnum + if error is not Clusters.RvcOperationalState.Enums.ErrorStateEnum.kUnknownEnumValue) + + in_range = (0x8000 <= operational_error.errorStateID and operational_error.errorStateID <= 0xBFFF) + asserts.assert_true(operational_error.errorStateID in defined_errors + or in_range, "OperationalError has an invalid ID value!") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCOPSTATE_2_3.py b/src/python_testing/TC_RVCOPSTATE_2_3.py new file mode 100644 index 00000000000000..288e40f7099ba3 --- /dev/null +++ b/src/python_testing/TC_RVCOPSTATE_2_3.py @@ -0,0 +1,156 @@ +# +# 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 time + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: + + +class TC_RVCOPSTATE_2_3(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcOperationalState + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_pause_cmd(self) -> Clusters.Objects.RvcOperationalState.Commands.Pause: + ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcOperationalState.Commands.Pause(), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.RvcOperationalState.Commands.OperationalCommandResponse), + "Unexpected return type for Pause") + return ret + + async def send_resume_cmd(self) -> Clusters.Objects.RvcOperationalState.Commands.Resume: + ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcOperationalState.Commands.Resume(), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.RvcOperationalState.Commands.OperationalCommandResponse), + "Unexpected return type for Resume") + return ret + + @async_test_body + async def test_TC_RVCOPSTATE_2_3(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + + asserts.assert_true(self.check_pics("RVCOPSTATE.S.A0002"), "RVCOPSTATE.S.A0002 must be supported") + asserts.assert_true(self.check_pics("RVCOPSTATE.S.A0003"), "RVCOPSTATE.S.A0003 must be supported") + asserts.assert_true(self.check_pics("RVCOPSTATE.S.A0004"), "RVCOPSTATE.S.A0004 must be supported") + asserts.assert_true(self.check_pics("RVCOPSTATE.S.C00.Rsp"), "RVCOPSTATE.S.C00.Rsp must be supported") + asserts.assert_true(self.check_pics("RVCOPSTATE.S.C03.Rsp"), "RVCOPSTATE.S.C03.Rsp must be supported") + + attributes = Clusters.RvcOperationalState.Attributes + + self.print_step(1, "Commissioning, already done") + + self.print_step(2, "Manually put the device in a state where it can receive a Pause command") + input("Press Enter when done.\n") + + self.print_step(3, "Read OperationalStateList attribute") + op_state_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.OperationalStateList) + + logging.info("OperationalStateList: %s" % (op_state_list)) + + defined_states = [state.value for state in Clusters.OperationalState.Enums.OperationalStateEnum + if state is not Clusters.OperationalState.Enums.OperationalStateEnum.kUnknownEnumValue] + + state_ids = [s.operationalStateID for s in op_state_list] + + asserts.assert_true(all(id in state_ids for id in defined_states), "OperationalStateList is missing a required entry") + + self.print_step(4, "Send Pause command") + ret = await self.send_pause_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, + "ErrorStateID should be NoError(0x00)") + + self.print_step(5, "Read OperationalState attribute") + operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.OperationalState) + logging.info("OperationalState: %s" % (operational_state)) + asserts.assert_equal(operational_state, Clusters.OperationalState.Enums.OperationalStateEnum.kPaused, + "OperationalState ID should be Paused(0x02)") + + self.print_step(6, "Read CountdownTime attribute") + initial_countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.CountdownTime) + logging.info("CountdownTime: %s" % (initial_countdown_time)) + if initial_countdown_time is not NullValue: + in_range = (1 <= initial_countdown_time and initial_countdown_time <= 259200) + asserts.assert_true(initial_countdown_time is NullValue or in_range, "invalid CountdownTime") + + self.print_step(7, "Waiting for 5 seconds") + time.sleep(5) + + self.print_step(8, "Read CountdownTime attribute") + countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CountdownTime) + logging.info("CountdownTime: %s" % (countdown_time)) + asserts.assert_true(countdown_time != 0 or countdown_time == NullValue, "invalid CountdownTime") + asserts.assert_equal(countdown_time, initial_countdown_time, + "CountdownTime does not equal to the intial CountdownTime %s" % initial_countdown_time) + + self.print_step(9, "Send Pause command") + ret = await self.send_pause_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, + "ErrorStateID should be NoError(0x00)") + + self.print_step(10, "Send Resume command") + ret = await self.send_resume_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, + "ErrorStateID should be NoError(0x00)") + + self.print_step(11, "Read OperationalState attribute") + operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.OperationalState) + logging.info("OperationalState: %s" % (operational_state)) + asserts.assert_equal(operational_state, Clusters.OperationalState.Enums.OperationalStateEnum.kRunning, + "OperationalState ID should be Running(0x01)") + + self.print_step(12, "Send Resume command") + ret = await self.send_resume_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, + "errorStateID should be NoError(0x00)") + + self.print_step(13, "Manually put the device in a state where it cannot receive a Pause command") + input("Press Enter when done.\n") + + self.print_step(14, "Send Pause command") + ret = await self.send_pause_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, + Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, + "errorStateID should be CommandInvalidInState(0x03)") + + self.print_step(15, "Manually put the device in a state where it cannot receive a Resume command") + input("Press Enter when done.\n") + + self.print_step(16, "Send Resume command") + ret = await self.send_resume_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, + Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, + "errorStateID should be CommandInvalidInState(0x03)") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCRUNM_1_2.py b/src/python_testing/TC_RVCRUNM_1_2.py new file mode 100644 index 00000000000000..7029e70163217f --- /dev/null +++ b/src/python_testing/TC_RVCRUNM_1_2.py @@ -0,0 +1,121 @@ +# +# 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 chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: + + +class TC_RVCRUNM_1_2(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcRunMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + @async_test_body + async def test_TC_RVCRUNM_1_2(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + + attributes = Clusters.RvcRunMode.Attributes + + self.print_step(1, "Commissioning, already done") + + if self.check_pics("RVCRUNM.S.A0000"): + self.print_step(2, "Read SupportedModes attribute") + supported_modes = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.SupportedModes) + + logging.info("SupportedModes: %s" % (supported_modes)) + + asserts.assert_greater_equal(len(supported_modes), 2, "SupportedModes must have at least two entries!") + + modes = [] + for m in supported_modes: + if m.mode in modes: + asserts.fail("SupportedModes must have unique mode values!") + else: + modes.append(m.mode) + + labels = [] + for m in supported_modes: + if m.label in labels: + asserts.fail("SupportedModes must have unique mode label values!") + else: + labels.append(m.label) + + # common mode tags + commonTags = {0x0: 'Auto', + 0x1: 'Quick', + 0x2: 'Quiet', + 0x3: 'LowNoise', + 0x4: 'LowEnergy', + 0x5: 'Vacation', + 0x6: 'Min', + 0x7: 'Max', + 0x8: 'Night', + 0x9: 'Day'} + + runTags = [tag.value for tag in Clusters.RvcRunMode.Enums.ModeTag + if tag is not Clusters.RvcRunMode.Enums.ModeTag.kUnknownEnumValue] + + for m in supported_modes: + for t in m.modeTags: + is_mfg = (0x8000 <= t.value and t.value <= 0xBFFF) + asserts.assert_true(t.value in commonTags.keys() or t.value in runTags or is_mfg, + "Found a SupportedModes entry with invalid mode tag value!") + if t.value == Clusters.RvcRunMode.Enums.ModeTag.kIdle: + idle_present = True + if t.value == Clusters.RvcRunMode.Enums.ModeTag.kCleaning: + cleaning_present = True + asserts.assert_true(idle_present, "The Supported Modes does not have an entry of Idle(0x4000)") + asserts.assert_true(cleaning_present, "The Supported Modes does not have an entry of Cleaning(0x4001)") + + if self.check_pics("RVCRUNM.S.A0001"): + self.print_step(3, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + asserts.assert_true(current_mode in modes, "CurrentMode is not a supported mode!") + + if self.check_pics("RVCRUNM.S.A0003"): + self.print_step(4, "Read OnMode attribute") + on_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.OnMode) + + logging.info("OnMode: %s" % (on_mode)) + asserts.assert_true(on_mode in modes or on_mode == NullValue, "OnMode is not a supported mode!") + + if self.check_pics("RVCRUNM.S.A0002"): + self.print_step(5, "Read StartUpMode attribute") + startup_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.StartUpMode) + + logging.info("StartUpMode: %s" % (startup_mode)) + asserts.assert_true(startup_mode in modes or startup_mode == NullValue, "StartUpMode is not a supported mode!") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCRUNM_2_1.py b/src/python_testing/TC_RVCRUNM_2_1.py new file mode 100644 index 00000000000000..bc9ff11da23db9 --- /dev/null +++ b/src/python_testing/TC_RVCRUNM_2_1.py @@ -0,0 +1,162 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: PIXIT_MODEOK: PIXIT_MODEFAIL: + + +class TC_RVCRUNM_2_1(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcRunMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcRunMode.Commands.ChangeToModeResponse: + ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcRunMode.Commands.ChangeToMode(newMode=newMode), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.RvcRunMode.Commands.ChangeToModeResponse), + "Unexpected return type for ChangeToMode") + return ret + + @async_test_body + async def test_TC_RVCRUNM_2_1(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + asserts.assert_true('PIXIT_MODEOK' in self.matter_test_config.global_test_params, + "PIXIT_MODEOK must be included on the command line in " + "the --int-arg flag as PIXIT_MODEOK:") + asserts.assert_true('PIXIT_MODEFAIL' in self.matter_test_config.global_test_params, + "PIXIT_MODEFAIL must be included on the command line in " + "the --int-arg flag as PIXIT_MODEFAIL:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + self.modeok = self.matter_test_config.global_test_params['PIXIT_MODEOK'] + self.modefail = self.matter_test_config.global_test_params['PIXIT_MODEFAIL'] + + asserts.assert_true(self.check_pics("RVCRUNM.S.A0000"), "RVCRUNM.S.A0000 must be supported") + asserts.assert_true(self.check_pics("RVCRUNM.S.A0001"), "RVCRUNM.S.A0001 must be supported") + asserts.assert_true(self.check_pics("RVCRUNM.S.C00.Rsp"), "RVCRUNM.S.C00.Rsp must be supported") + asserts.assert_true(self.check_pics("RVCRUNM.S.C01.Tx"), "RVCRUNM.S.C01.Tx must be supported") + + attributes = Clusters.RvcRunMode.Attributes + + self.print_step(1, "Commissioning, already done") + + self.print_step(2, "Read SupportedModes attribute") + supported_modes = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.SupportedModes) + + logging.info("SupportedModes: %s" % (supported_modes)) + + asserts.assert_greater_equal(len(supported_modes), 2, "SupportedModes must have at least two entries!") + + modes = [m.mode for m in supported_modes] + + self.print_step(3, "Read CurrentMode attribute") + + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + # pick a value that's not on the list of supported modes + invalid_mode = max(modes) + 1 + + from enum import Enum + + class CommonCodes(Enum): + SUCCESS = 0x00 + UNSUPPORTED_MODE = 0x01 + GENERIC_FAILURE = 0x02 + + rvcRunCodes = [code.value for code in Clusters.RvcRunMode.Enums.StatusCode + if code is not Clusters.RvcRunMode.Enums.StatusCode.kUnknownEnumValue] + + self.print_step(4, "Send ChangeToMode command with NewMode set to %d" % (old_current_mode)) + + ret = await self.send_change_to_mode_cmd(newMode=old_current_mode) + asserts.assert_true(ret.status == CommonCodes.SUCCESS.value, "Changing the mode to the current mode should be a no-op") + + self.print_step(5, "Manually put the device in a state from which it will FAIL to transition to mode %d" % (self.modefail)) + input("Press Enter when done.\n") + + self.print_step(6, "Read CurrentMode attribute") + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + self.print_step(7, "Send ChangeToMode command with NewMode set to %d" % (self.modefail)) + + ret = await self.send_change_to_mode_cmd(newMode=self.modefail) + st = ret.status + is_mfg_code = st in range(0x80, 0xC0) + is_err_code = (st == CommonCodes.GENERIC_FAILURE.value) or (st in rvcRunCodes) or is_mfg_code + asserts.assert_true(is_err_code, "Changing to mode %d must fail due to the current state of the device" % (self.modefail)) + st_text_len = len(ret.statusText) + asserts.assert_true(st_text_len in range(1, 65), "StatusText length (%d) must be between 1 and 64" % (st_text_len)) + + self.print_step(8, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(current_mode == old_current_mode, "CurrentMode changed after failed ChangeToMode command!") + + self.print_step(9, "Manually put the device in a state from which it will SUCCESSFULLY transition to mode %d" % (self.modeok)) + input("Press Enter when done.\n") + + self.print_step(10, "Read CurrentMode attribute") + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + self.print_step(11, "Send ChangeToMode command with NewMode set to %d" % (self.modeok)) + + ret = await self.send_change_to_mode_cmd(newMode=self.modeok) + asserts.assert_true(ret.status == CommonCodes.SUCCESS.value, + "Changing to mode %d must succeed due to the current state of the device" % (self.modeok)) + + self.print_step(12, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(current_mode == self.modeok, + "CurrentMode doesn't match the argument of the successful ChangeToMode command!") + + self.print_step(13, "Send ChangeToMode command with NewMode set to %d" % (invalid_mode)) + + ret = await self.send_change_to_mode_cmd(newMode=invalid_mode) + asserts.assert_true(ret.status == CommonCodes.UNSUPPORTED_MODE.value, + "Attempt to change to invalid mode %d didn't fail as expected" % (invalid_mode)) + + self.print_step(14, "Read CurrentMode attribute") + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(current_mode == self.modeok, "CurrentMode changed after failed ChangeToMode command!") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCRUNM_3_2.py b/src/python_testing/TC_RVCRUNM_3_2.py new file mode 100644 index 00000000000000..09cfebec90d6eb --- /dev/null +++ b/src/python_testing/TC_RVCRUNM_3_2.py @@ -0,0 +1,115 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: + + +class TC_RVCRUNM_3_2(MatterBaseTest): + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcRunMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcRunMode.Commands.ChangeToModeResponse: + ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcRunMode.Commands.ChangeToMode(newMode=newMode), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.RvcRunMode.Commands.ChangeToModeResponse), + "Unexpected return type for ChangeToMode") + return ret + + @async_test_body + async def test_TC_RVCRUNM_3_2(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + + asserts.assert_true(self.check_pics("RVCRUNM.S.A0000"), "RVCRUNM.S.A0000 must be supported") + asserts.assert_true(self.check_pics("RVCRUNM.S.A0001"), "RVCRUNM.S.A0001 must be supported") + asserts.assert_true(self.check_pics("RVCRUNM.S.A0002"), "RVCRUNM.S.A0002 must be supported") + asserts.assert_true(self.check_pics("RVCRUNM.S.C00.Rsp"), "RVCRUNM.S.C00.Rsp must be supported") + asserts.assert_true(self.check_pics("RVCRUNM.S.C01.Tx"), "RVCRUNM.S.C01.Tx must be supported") + + attributes = Clusters.RvcRunMode.Attributes + + from enum import Enum + + class CommonCodes(Enum): + SUCCESS = 0x00 + UNSUPPORTED_MODE = 0x01 + GENERIC_FAILURE = 0x02 + + self.print_step(1, "Commissioning, already done") + + self.print_step(2, "Read StartUpMode attribute") + + startup_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.StartUpMode) + + logging.info("StartUpMode: %s" % (startup_mode)) + + self.print_step(3, "Read CurrentMode attribute") + + old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (old_current_mode)) + + if old_current_mode == startup_mode: + + self.print_step(4, "Read SupportedModes attribute") + supported_modes = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.SupportedModes) + + logging.info("SupportedModes: %s" % (supported_modes)) + + asserts.assert_greater_equal(len(supported_modes), 2, "SupportedModes must have at least two entries!") + + new_mode = None + + for m in supported_modes: + if m.mode != startup_mode: + new_mode = m.mode + break + + self.print_step(5, "Send ChangeToMode command with NewMode set to %d" % (new_mode)) + + ret = await self.send_change_to_mode_cmd(newMode=new_mode) + asserts.assert_true(ret.status == CommonCodes.SUCCESS.value, "Changing the mode should succeed") + + self.default_controller.ExpireSessions(self.dut_node_id) + + self.print_step(6, "Physically power cycle the device") + input("Press Enter when done.\n") + + self.print_step(7, "Read CurrentMode attribute") + + current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info("CurrentMode: %s" % (current_mode)) + + asserts.assert_true(startup_mode == current_mode, "CurrentMode must match StartUpMode after a power cycle") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 2c0cce594e24a3..2ede95292b00a3 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -138030,7 +138030,7 @@ class Test_TC_RVCCLEANM_1_1Suite : public TestCommand { public: Test_TC_RVCCLEANM_1_1Suite(CredentialIssuerCommands * credsIssuerConfig) : - TestCommand("Test_TC_RVCCLEANM_1_1", 0, credsIssuerConfig) + TestCommand("Test_TC_RVCCLEANM_1_1", 11, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -138063,6 +138063,120 @@ class Test_TC_RVCCLEANM_1_1Suite : public TestCommand switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint16_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckValue("clusterRevision", value, 1U)); + VerifyOrReturn(CheckConstraintType("value", "int16u", "int16u")); + } + break; + case 2: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint32_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckValue("featureMap", value, 0UL)); + VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); + } + break; + case 3: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint32_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); + VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 1UL)); + } + break; + case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintContains("value", value, 0UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 1UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65528UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65529UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65530UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65531UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65532UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65533UL)); + } + break; + case 5: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintContains("value", value, 2UL)); + } + break; + case 6: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintContains("value", value, 3UL)); + } + break; + case 7: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintExcludes("value", value, 3UL)); + } + break; + case 8: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNoMoreListItems("eventList", iter_0, 0)); + } + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + } + break; + case 9: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNextListItemDecodes("acceptedCommandList", iter_0, 0)); + VerifyOrReturn(CheckValue("acceptedCommandList[0]", iter_0.GetValue(), 0UL)); + VerifyOrReturn(CheckNoMoreListItems("acceptedCommandList", iter_0, 1)); + } + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + } + break; + case 10: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNextListItemDecodes("generatedCommandList", iter_0, 0)); + VerifyOrReturn(CheckValue("generatedCommandList[0]", iter_0.GetValue(), 1UL)); + VerifyOrReturn(CheckNoMoreListItems("generatedCommandList", iter_0, 1)); + } + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + } + break; default: LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); } @@ -138077,7 +138191,77 @@ class Test_TC_RVCCLEANM_1_1Suite : public TestCommand { using namespace chip::app::Clusters; switch (testIndex) - {} + { + case 0: { + LogStep(0, "Step 1: Wait for the commissioned device to be retrieved"); + ListFreer listFreer; + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee(kIdentityAlpha, value); + } + case 1: { + LogStep(1, "Step 2: TH reads the ClusterRevision attribute from the DUT"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::ClusterRevision::Id, + true, chip::NullOptional); + } + case 2: { + LogStep(2, "TH reads the FeatureMap attribute from the DUT"); + VerifyOrDo(!ShouldSkip(" !RVCCLEANM.S.F00 "), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 3: { + LogStep(3, "Given RVCCLEANM.S.F00(DEPONOFF) ensure featuremap has the correct bit set"); + VerifyOrDo(!ShouldSkip("RVCCLEANM.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 4: { + LogStep(4, "Step 4a: TH reads the AttributeList attribute from the DUT"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::AttributeList::Id, + true, chip::NullOptional); + } + case 5: { + LogStep(5, "TH reads the optional attribute(StartUpMode) in AttributeList from the DUT"); + VerifyOrDo(!ShouldSkip("RVCCLEANM.S.A0002"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::AttributeList::Id, + true, chip::NullOptional); + } + case 6: { + LogStep(6, + "Read the Feature dependent(RVCCLEANM.S.F00 - DEPONOFF) and optional attribute(OnMode) is in AttributeList " + "from the DUT"); + VerifyOrDo(!ShouldSkip("RVCCLEANM.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::AttributeList::Id, + true, chip::NullOptional); + } + case 7: { + LogStep(7, + "Read the Feature dependent(RVCCLEANM.S.F00 - DEPONOFF) and optional attribute(OnMode) is not in AttributeList " + "from the DUT"); + VerifyOrDo(!ShouldSkip(" !RVCCLEANM.S.F00 "), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::AttributeList::Id, + true, chip::NullOptional); + } + case 8: { + LogStep(8, "Read the global attribute: EventList from the DUT"); + VerifyOrDo(!ShouldSkip("RVCCLEANM.S.Afffa"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, RvcCleanMode::Attributes::EventList::Id, true, + chip::NullOptional); + } + case 9: { + LogStep(9, "Read the global attribute AcceptedCommandList. Check if it contains id 0x0 (ChangeToMode)"); + VerifyOrDo(!ShouldSkip("RVCCLEANM.S.C00.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, + RvcCleanMode::Attributes::AcceptedCommandList::Id, true, chip::NullOptional); + } + case 10: { + LogStep(10, "Read the global attribute: GeneratedCommandList. Check if it contains id 0x1 (ChangeToModeResponse)"); + VerifyOrDo(!ShouldSkip("RVCCLEANM.S.C01.Tx"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcCleanMode::Id, + RvcCleanMode::Attributes::GeneratedCommandList::Id, true, chip::NullOptional); + } + } return CHIP_NO_ERROR; } }; @@ -138534,7 +138718,7 @@ class Test_TC_RVCRUNM_1_1Suite : public TestCommand { public: Test_TC_RVCRUNM_1_1Suite(CredentialIssuerCommands * credsIssuerConfig) : - TestCommand("Test_TC_RVCRUNM_1_1", 0, credsIssuerConfig) + TestCommand("Test_TC_RVCRUNM_1_1", 11, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -138567,6 +138751,120 @@ class Test_TC_RVCRUNM_1_1Suite : public TestCommand switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint16_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckValue("clusterRevision", value, 1U)); + VerifyOrReturn(CheckConstraintType("value", "int16u", "int16u")); + } + break; + case 2: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint32_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckValue("featureMap", value, 0UL)); + VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); + } + break; + case 3: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint32_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); + VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 1UL)); + } + break; + case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintContains("value", value, 0UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 1UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65528UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65529UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65530UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65531UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65532UL)); + VerifyOrReturn(CheckConstraintContains("value", value, 65533UL)); + } + break; + case 5: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintContains("value", value, 2UL)); + } + break; + case 6: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintContains("value", value, 3UL)); + } + break; + case 7: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + VerifyOrReturn(CheckConstraintExcludes("value", value, 3UL)); + } + break; + case 8: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNoMoreListItems("eventList", iter_0, 0)); + } + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + } + break; + case 9: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNextListItemDecodes("acceptedCommandList", iter_0, 0)); + VerifyOrReturn(CheckValue("acceptedCommandList[0]", iter_0.GetValue(), 0UL)); + VerifyOrReturn(CheckNoMoreListItems("acceptedCommandList", iter_0, 1)); + } + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + } + break; + case 10: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNextListItemDecodes("generatedCommandList", iter_0, 0)); + VerifyOrReturn(CheckValue("generatedCommandList[0]", iter_0.GetValue(), 1UL)); + VerifyOrReturn(CheckNoMoreListItems("generatedCommandList", iter_0, 1)); + } + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + } + break; default: LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); } @@ -138581,7 +138879,77 @@ class Test_TC_RVCRUNM_1_1Suite : public TestCommand { using namespace chip::app::Clusters; switch (testIndex) - {} + { + case 0: { + LogStep(0, "Wait for the commissioned device to be retrieved"); + ListFreer listFreer; + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee(kIdentityAlpha, value); + } + case 1: { + LogStep(1, "TH reads the ClusterRevision attribute from the DUT"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::ClusterRevision::Id, true, + chip::NullOptional); + } + case 2: { + LogStep(2, "TH reads the FeatureMap attribute from the DUT"); + VerifyOrDo(!ShouldSkip(" !RVCRUNM.S.F00 "), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 3: { + LogStep(3, "Given RVCRUNM.S.F00(DEPONOFF) ensure featuremap has the correct bit set"); + VerifyOrDo(!ShouldSkip("RVCRUNM.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 4: { + LogStep(4, "TH reads the AttributeList attribute from the DUT"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::AttributeList::Id, true, + chip::NullOptional); + } + case 5: { + LogStep(5, "TH reads the optional attribute(StartUpMode) in AttributeList from the DUT"); + VerifyOrDo(!ShouldSkip("RVCRUNM.S.A0002"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::AttributeList::Id, true, + chip::NullOptional); + } + case 6: { + LogStep(6, + "Read the Feature dependent(RVCRUNM.S.F00 - DEPONOFF) and optional attribute(OnMode) is in AttributeList from " + "the DUT"); + VerifyOrDo(!ShouldSkip("RVCRUNM.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::AttributeList::Id, true, + chip::NullOptional); + } + case 7: { + LogStep(7, + "Read the Feature dependent(RVCRUNM.S.F00 - DEPONOFF) and optional attribute(OnMode) is not in AttributeList " + "from the DUT"); + VerifyOrDo(!ShouldSkip(" !RVCRUNM.S.F00 "), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::AttributeList::Id, true, + chip::NullOptional); + } + case 8: { + LogStep(8, "Read the global attribute: EventList from the DUT"); + VerifyOrDo(!ShouldSkip("RVCRUNM.S.Afffa"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::EventList::Id, true, + chip::NullOptional); + } + case 9: { + LogStep(9, "Read the global attribute AcceptedCommandList. Check if it contains id 0x0 (ChangeToMode)"); + VerifyOrDo(!ShouldSkip("RVCRUNM.S.C00.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::AcceptedCommandList::Id, + true, chip::NullOptional); + } + case 10: { + LogStep(10, "Read the global attribute: GeneratedCommandList. Check if it contains id 0x1 (ChangeToModeResponse)"); + VerifyOrDo(!ShouldSkip("RVCRUNM.S.C01.Tx"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), RvcRunMode::Id, RvcRunMode::Attributes::GeneratedCommandList::Id, + true, chip::NullOptional); + } + } return CHIP_NO_ERROR; } };