From 80f7986d0201e28babee7b8645e62e6ea813f5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=A9gevand?= <77852424+jmeg-sfy@users.noreply.github.com> Date: Mon, 20 Sep 2021 22:40:37 +0200 Subject: [PATCH] WindowCovering add mandatory commands test case (#9496) * WC: Add new test cases * WC: Add Mandatory Command support in all cluster app * WC: Add autogen test case generated + add WindowCovering handler in all cluster app * WC: Add missing StopMotion as weak callback definition * Restyled by whitespace * Restyled by clang-format * Restyled by prettier-yaml * WC: Yaml remove useless returnValue checks * WC: Update autogen Zap Co-authored-by: Restyled.io --- .../all-clusters-common/all-clusters-app.zap | 8 +- .../esp32/main/CMakeLists.txt | 1 + .../chip-tool/templates/tests-commands.zapt | 2 +- .../window-covering-server.cpp | 12 + .../certification/Test_TC_WNCV_3_1.yaml | 110 +++ .../certification/Test_TC_WNCV_3_2.yaml | 110 +++ .../certification/Test_TC_WNCV_3_3.yaml | 87 +++ .../CHIP/templates/clusters-tests.zapt | 2 +- .../Framework/CHIPTests/CHIPClustersTests.m | 180 +++++ .../zap-generated/IMClusterCommandHandler.cpp | 63 ++ .../chip-tool/zap-generated/test/Commands.h | 684 ++++++++++++++++++ 11 files changed, 1253 insertions(+), 6 deletions(-) create mode 100644 src/app/tests/suites/certification/Test_TC_WNCV_3_1.yaml create mode 100644 src/app/tests/suites/certification/Test_TC_WNCV_3_2.yaml create mode 100644 src/app/tests/suites/certification/Test_TC_WNCV_3_3.yaml diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 2f011c4d2d6210..472f1ac14d7a49 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -9286,7 +9286,7 @@ "code": 0, "mfgCode": null, "source": "client", - "incoming": 0, + "incoming": 1, "outgoing": 0 }, { @@ -9294,7 +9294,7 @@ "code": 1, "mfgCode": null, "source": "client", - "incoming": 0, + "incoming": 1, "outgoing": 0 }, { @@ -9302,7 +9302,7 @@ "code": 2, "mfgCode": null, "source": "client", - "incoming": 0, + "incoming": 1, "outgoing": 0 }, { @@ -17539,4 +17539,4 @@ } ], "log": [] -} \ No newline at end of file +} diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index c9d6e71f59761d..2dac27489c7759 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -43,6 +43,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/application-launcher-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/audio-output-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/barrier-control-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/window-covering-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-commissioning-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/groups-server" diff --git a/examples/chip-tool/templates/tests-commands.zapt b/examples/chip-tool/templates/tests-commands.zapt index e3731da7fb7b72..1355716b89d44a 100644 --- a/examples/chip-tool/templates/tests-commands.zapt +++ b/examples/chip-tool/templates/tests-commands.zapt @@ -4,5 +4,5 @@ #include -{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, TestOperationalCredentialsCluster, Test_TC_LVL_1_1, Test_TC_CC_1_1, Test_TC_RH_1_1, Test_TC_MC_1_1, Test_TC_TSTAT_1_1, Test_TC_PCC_1_1, Test_TC_TSUIC_1_1"}} +{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_WNCV_3_1, Test_TC_WNCV_3_2, Test_TC_WNCV_3_3, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, TestOperationalCredentialsCluster, Test_TC_LVL_1_1, Test_TC_CC_1_1, Test_TC_RH_1_1, Test_TC_MC_1_1, Test_TC_TSTAT_1_1, Test_TC_PCC_1_1, Test_TC_TSUIC_1_1"}} diff --git a/src/app/clusters/window-covering-server/window-covering-server.cpp b/src/app/clusters/window-covering-server/window-covering-server.cpp index fe2bb77300de97..9429511432df5d 100644 --- a/src/app/clusters/window-covering-server/window-covering-server.cpp +++ b/src/app/clusters/window-covering-server/window-covering-server.cpp @@ -411,6 +411,18 @@ bool emberAfWindowCoveringClusterDownOrCloseCallback(chip::EndpointId endpoint, return true; } +/** + * @brief Cluster StopMotion Command callback (from client) + */ +bool __attribute__((weak)) +emberAfWindowCoveringClusterStopMotionCallback(chip::EndpointId endpoint, chip::app::CommandHandler * commandObj) +{ + emberAfWindowCoveringClusterPrint("StopMotion command received"); + + emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS); + return true; +} + /** * @brief Cluster GoToLiftValue Command callback (from client) */ diff --git a/src/app/tests/suites/certification/Test_TC_WNCV_3_1.yaml b/src/app/tests/suites/certification/Test_TC_WNCV_3_1.yaml new file mode 100644 index 00000000000000..e2be049d3e4bf5 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_WNCV_3_1.yaml @@ -0,0 +1,110 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# 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. + +name: Window Covering [TC-WNCV-3.1] UpOrOpen Verification with server as DUT + +# TODO: WindowCovering tests TC-WNCV-3.1 finalize featuremap conditional dependencies + +config: + cluster: "Window Covering" + endpoint: 1 + +tests: + ### Step 1x -> Initialize Position + ### MANDATORY Command + - label: "1a: TH adjusts the the DUT to a non-open position" + command: "DownOrClose" + + ### Depends on the FeatureMap + - label: + "1b: If (PA & LF) TH reads CurrentPositionLiftPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on the FeatureMap + - label: + "1b: If (PA & TL) TH reads CurrentPositionTiltPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionTiltPercent100ths" + response: + constraints: + type: uint16 + + ### Step 2x -> Check Command instant effect + ### MANDATORY Command + - label: "2a: TH sends UpOrOpen command to DUT" + command: "UpOrOpen" + + ### Depends on the FeatureMap + - label: + "2b: If (PA & LF) TH reads TargetPositionLiftPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "TargetPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on the FeatureMap + - label: + "2c: If (PA & TL) TH reads TargetPositionTiltPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "TargetPositionTiltPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on a sleep/wait command how to do this with a real device + - label: "2d: Wait for the movement to finish" + disabled: true + + ### Step 3x -> Check longer period effect + ### MANDATORY reads + - label: "3a: TH reads OperationalStatus attribute from DUT" + command: "readAttribute" + attribute: "OperationalStatus" + response: + value: 0 + + ### Depends on the FeatureMap + - label: + "3b: If (PA & LF) TH reads CurrentPositionLiftPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on the FeatureMap + - label: + "3c: If (PA & TL) TH reads CurrentPositionTiltPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionTiltPercent100ths" + response: + constraints: + type: uint16 diff --git a/src/app/tests/suites/certification/Test_TC_WNCV_3_2.yaml b/src/app/tests/suites/certification/Test_TC_WNCV_3_2.yaml new file mode 100644 index 00000000000000..5ce21bd067de37 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_WNCV_3_2.yaml @@ -0,0 +1,110 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# 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. + +name: Window Covering [TC-WNCV-3.2] DownOrClose Verification with server as DUT + +# TODO: WindowCovering tests TC-WNCV-3.2 finalize featuremap conditional dependencies + +config: + cluster: "Window Covering" + endpoint: 1 + +tests: + ### Step 1x -> Initialize Position + ### MANDATORY Command + - label: "1a: TH adjusts the the DUT to a non-closed position" + command: "UpOrOpen" + + ### Depends on the FeatureMap + - label: + "1b: If (PA & LF) TH reads CurrentPositionLiftPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on the FeatureMap + - label: + "1b: If (PA & TL) TH reads CurrentPositionTiltPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionTiltPercent100ths" + response: + constraints: + type: uint16 + + ### Step 2x -> Check Command instant effect + ### MANDATORY Command + - label: "2a: TH sends DownOrClose command to DUT" + command: "DownOrClose" + + ### Depends on the FeatureMap + - label: + "2b: If (PA & LF) TH reads TargetPositionLiftPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "TargetPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on the FeatureMap + - label: + "2c: If (PA & TL) TH reads TargetPositionTiltPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "TargetPositionTiltPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on a sleep/wait command how to do this with a real device + - label: "2d: Wait for the movement to finish" + disabled: true + + ### Step 3x -> Check longer period effect + ### MANDATORY reads + - label: "3a: TH reads OperationalStatus attribute from DUT" + command: "readAttribute" + attribute: "OperationalStatus" + response: + value: 0 + + ### Depends on the FeatureMap + - label: + "3b: If (PA & LF) TH reads CurrentPositionLiftPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + ### Depends on the FeatureMap + - label: + "3c: If (PA & TL) TH reads CurrentPositionTiltPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionTiltPercent100ths" + response: + constraints: + type: uint16 diff --git a/src/app/tests/suites/certification/Test_TC_WNCV_3_3.yaml b/src/app/tests/suites/certification/Test_TC_WNCV_3_3.yaml new file mode 100644 index 00000000000000..679eb86a997a31 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_WNCV_3_3.yaml @@ -0,0 +1,87 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# 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. + +name: Window Covering [TC-WNCV-3.3] StopMotion Verification with server as DUT + +# TODO: WindowCovering tests TC-WNCV-3.3 finalize featuremap conditional dependencies + +config: + cluster: "Window Covering" + endpoint: 1 + +tests: + ### Step 1x -> Initialize Position + ### MANDATORY Command + - label: "1a: TH adjusts the the DUT to a non-open position" + command: "UpOrOpen" + + ### Depends on a sleep/wait command how to do this with a real device + - label: "1b: Wait for the movement to start and go on for a few seconds" + disabled: true + + ### Step 2x -> Check Command instant effects + longer effects + ### MANDATORY Command + - label: "2a: TH sends StopMotion command to DUT" + command: "StopMotion" + + ### MANDATORY reads + - label: "2b: TH reads OperationalStatus attribute from DUT" + command: "readAttribute" + attribute: "OperationalStatus" + response: + value: 0 + + ### 2c Check equality with a tolerance between Target & Current for Lift + ### Depends on the FeatureMap + - label: + "2c-1: If (PA & LF) TH reads TargetPositionLiftPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "TargetPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + - label: + "2c-2: If (PA & LF) TH reads CurrentPositionLiftPercent100ths + attribute from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionLiftPercent100ths" + response: + constraints: + type: uint16 + + ### 2d Check equality with a tolerance between Target & Current for Tilt + ### Depends on the FeatureMap + - label: + "2d-1: If (PA & TL) TH reads TargetPositionTiltPercent100ths attribute + from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "TargetPositionTiltPercent100ths" + response: + constraints: + type: uint16 + + - label: + "2d-2: If (PA & TL) TH reads CurrentPositionTiltPercent100ths + attribute from DUT" + disabled: true # Step applied conditionnally with an !expected response value + command: "readAttribute" + attribute: "CurrentPositionTiltPercent100ths" + response: + constraints: + type: uint16 diff --git a/src/darwin/Framework/CHIP/templates/clusters-tests.zapt b/src/darwin/Framework/CHIP/templates/clusters-tests.zapt index 367f713396b94d..8eb1dcf43edf72 100644 --- a/src/darwin/Framework/CHIP/templates/clusters-tests.zapt +++ b/src/darwin/Framework/CHIP/templates/clusters-tests.zapt @@ -143,7 +143,7 @@ CHIPDevice * GetPairedDevice(uint64_t deviceId) [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } -{{>test_cluster tests="TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, TestOperationalCredentialsCluster, Test_TC_LVL_1_1, Test_TC_CC_1_1, Test_TC_RH_1_1, Test_TC_MC_1_1, Test_TC_TSTAT_1_1, Test_TC_PCC_1_1, Test_TC_TSUIC_1_1"}} +{{>test_cluster tests="TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_WNCV_3_1, Test_TC_WNCV_3_2, Test_TC_WNCV_3_3, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, TestOperationalCredentialsCluster, Test_TC_LVL_1_1, Test_TC_CC_1_1, Test_TC_RH_1_1, Test_TC_MC_1_1, Test_TC_TSTAT_1_1, Test_TC_PCC_1_1, Test_TC_TSUIC_1_1"}} {{#chip_client_clusters}} {{#unless (isStrEqual "Test Cluster" name)}} diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index 08a49d4149884e..2dade3454ed228 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -5844,6 +5844,186 @@ - (void)testSendClusterTest_TC_WNCV_2_1_000010_ReadAttribute [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } +- (void)testSendClusterTest_TC_WNCV_3_1_000000_DownOrClose +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"1a: TH adjusts the the DUT to a non-open position"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster downOrClose:^(NSError * err, NSDictionary * values) { + NSLog(@"1a: TH adjusts the the DUT to a non-open position Error: %@", err); + + XCTAssertEqual(err.code, 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTest_TC_WNCV_3_1_000001_UpOrOpen +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"2a: TH sends UpOrOpen command to DUT"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster upOrOpen:^(NSError * err, NSDictionary * values) { + NSLog(@"2a: TH sends UpOrOpen command to DUT Error: %@", err); + + XCTAssertEqual(err.code, 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTest_TC_WNCV_3_1_000002_ReadAttribute +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"3a: TH reads OperationalStatus attribute from DUT"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeOperationalStatusWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"3a: TH reads OperationalStatus attribute from DUT Error: %@", err); + + XCTAssertEqual(err.code, 0); + + XCTAssertEqual([values[@"value"] unsignedCharValue], 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + +- (void)testSendClusterTest_TC_WNCV_3_2_000000_UpOrOpen +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"1a: TH adjusts the the DUT to a non-closed position"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster upOrOpen:^(NSError * err, NSDictionary * values) { + NSLog(@"1a: TH adjusts the the DUT to a non-closed position Error: %@", err); + + XCTAssertEqual(err.code, 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTest_TC_WNCV_3_2_000001_DownOrClose +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"2a: TH sends DownOrClose command to DUT"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster downOrClose:^(NSError * err, NSDictionary * values) { + NSLog(@"2a: TH sends DownOrClose command to DUT Error: %@", err); + + XCTAssertEqual(err.code, 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTest_TC_WNCV_3_2_000002_ReadAttribute +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"3a: TH reads OperationalStatus attribute from DUT"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeOperationalStatusWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"3a: TH reads OperationalStatus attribute from DUT Error: %@", err); + + XCTAssertEqual(err.code, 0); + + XCTAssertEqual([values[@"value"] unsignedCharValue], 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + +- (void)testSendClusterTest_TC_WNCV_3_3_000000_UpOrOpen +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"1a: TH adjusts the the DUT to a non-open position"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster upOrOpen:^(NSError * err, NSDictionary * values) { + NSLog(@"1a: TH adjusts the the DUT to a non-open position Error: %@", err); + + XCTAssertEqual(err.code, 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTest_TC_WNCV_3_3_000001_StopMotion +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"2a: TH sends StopMotion command to DUT"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster stopMotion:^(NSError * err, NSDictionary * values) { + NSLog(@"2a: TH sends StopMotion command to DUT Error: %@", err); + + XCTAssertEqual(err.code, 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTest_TC_WNCV_3_3_000002_ReadAttribute +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"2b: TH reads OperationalStatus attribute from DUT"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestWindowCovering * cluster = [[CHIPTestWindowCovering alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeOperationalStatusWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"2b: TH reads OperationalStatus attribute from DUT Error: %@", err); + + XCTAssertEqual(err.code, 0); + + XCTAssertEqual([values[@"value"] unsignedCharValue], 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + - (void)testSendClusterTest_TC_BI_1_1_000000_ReadAttribute { XCTestExpectation * expectation = [self expectationWithDescription:@"read the global attribute: ClusterRevision"]; diff --git a/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp index 52f9a14d036c58..334f37b49cbbdf 100644 --- a/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp @@ -7090,6 +7090,66 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, } // namespace WiFiNetworkDiagnostics +namespace WindowCovering { + +void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::WindowCovering::Commands::Ids::DownOrClose: { + + wasHandled = emberAfWindowCoveringClusterDownOrCloseCallback(aEndpointId, apCommandObj); + break; + } + case Clusters::WindowCovering::Commands::Ids::StopMotion: { + + wasHandled = emberAfWindowCoveringClusterStopMotionCallback(aEndpointId, apCommandObj); + break; + } + case Clusters::WindowCovering::Commands::Ids::UpOrOpen: { + + wasHandled = emberAfWindowCoveringClusterUpOrOpenCallback(aEndpointId, apCommandObj); + break; + } + default: { + // Unrecognized command ID, error status will apply. + ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::WindowCovering::Id, aCommandId); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::WindowCovering::Id, aCommandId, (CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError.Format(), TLVUnpackError.Format(), currentDecodeTagId); + // A command with no arguments would never write currentDecodeTagId. If + // progress logging is also disabled, it would look unused. Silence that + // warning. + UNUSED_VAR(currentDecodeTagId); + } +} + +} // namespace WindowCovering + } // namespace clusters void DispatchSingleClusterCommand(ClusterId aClusterId, CommandId aCommandId, EndpointId aEndPointId, TLV::TLVReader & aReader, @@ -7171,6 +7231,9 @@ void DispatchSingleClusterCommand(ClusterId aClusterId, CommandId aCommandId, En case Clusters::WiFiNetworkDiagnostics::Id: clusters::WiFiNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); break; + case Clusters::WindowCovering::Id: + clusters::WindowCovering::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; default: // Unrecognized cluster ID, error status will apply. CommandPathParams returnStatusParam = { aEndPointId, diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 5446522fb82c08..82b6a199d7a038 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -20176,6 +20176,687 @@ class Test_TC_WNCV_2_1 : public TestCommand } }; +class Test_TC_WNCV_3_1 : public TestCommand +{ +public: + Test_TC_WNCV_3_1() : TestCommand("Test_TC_WNCV_3_1"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "Test_TC_WNCV_3_1: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterWindowCoveringCommandDownOrClose_0(); + break; + case 1: + err = TestSendClusterWindowCoveringCommandUpOrOpen_1(); + break; + case 2: + err = TestSendClusterWindowCoveringCommandReadAttribute_2(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "Test_TC_WNCV_3_1: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 3; + + // + // Tests methods + // + + // Test 1a: TH adjusts the the DUT to a non-open position + using SuccessCallback_0 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_0{ + OnTestSendClusterWindowCoveringCommandDownOrClose_0_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_0{ + OnTestSendClusterWindowCoveringCommandDownOrClose_0_FailureResponse, this + }; + + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandDownOrClose_0() + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-open position: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.DownOrClose(mOnSuccessCallback_0.Cancel(), mOnFailureCallback_0.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandDownOrClose_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-open position: Failure Response"); + + Test_TC_WNCV_3_1 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandDownOrClose_0_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-open position: Success Response"); + + Test_TC_WNCV_3_1 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test 2a: TH sends UpOrOpen command to DUT + using SuccessCallback_1 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_1{ + OnTestSendClusterWindowCoveringCommandUpOrOpen_1_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_1{ + OnTestSendClusterWindowCoveringCommandUpOrOpen_1_FailureResponse, this + }; + + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandUpOrOpen_1() + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends UpOrOpen command to DUT: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.UpOrOpen(mOnSuccessCallback_1.Cancel(), mOnFailureCallback_1.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandUpOrOpen_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends UpOrOpen command to DUT: Failure Response"); + + Test_TC_WNCV_3_1 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandUpOrOpen_1_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends UpOrOpen command to DUT: Success Response"); + + Test_TC_WNCV_3_1 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test 3a: TH reads OperationalStatus attribute from DUT + using SuccessCallback_2 = void (*)(void * context, uint8_t operationalStatus); + chip::Callback::Callback mOnSuccessCallback_2{ + OnTestSendClusterWindowCoveringCommandReadAttribute_2_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_2{ + OnTestSendClusterWindowCoveringCommandReadAttribute_2_FailureResponse, this + }; + + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_2() + { + ChipLogProgress(chipTool, "Window Covering - 3a: TH reads OperationalStatus attribute from DUT: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeOperationalStatus(mOnSuccessCallback_2.Cancel(), mOnFailureCallback_2.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandReadAttribute_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 3a: TH reads OperationalStatus attribute from DUT: Failure Response"); + + Test_TC_WNCV_3_1 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandReadAttribute_2_SuccessResponse(void * context, uint8_t operationalStatus) + { + ChipLogProgress(chipTool, "Window Covering - 3a: TH reads OperationalStatus attribute from DUT: Success Response"); + + Test_TC_WNCV_3_1 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (operationalStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class Test_TC_WNCV_3_2 : public TestCommand +{ +public: + Test_TC_WNCV_3_2() : TestCommand("Test_TC_WNCV_3_2"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "Test_TC_WNCV_3_2: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterWindowCoveringCommandUpOrOpen_0(); + break; + case 1: + err = TestSendClusterWindowCoveringCommandDownOrClose_1(); + break; + case 2: + err = TestSendClusterWindowCoveringCommandReadAttribute_2(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "Test_TC_WNCV_3_2: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 3; + + // + // Tests methods + // + + // Test 1a: TH adjusts the the DUT to a non-closed position + using SuccessCallback_0 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_0{ + OnTestSendClusterWindowCoveringCommandUpOrOpen_0_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_0{ + OnTestSendClusterWindowCoveringCommandUpOrOpen_0_FailureResponse, this + }; + + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandUpOrOpen_0() + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-closed position: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.UpOrOpen(mOnSuccessCallback_0.Cancel(), mOnFailureCallback_0.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandUpOrOpen_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-closed position: Failure Response"); + + Test_TC_WNCV_3_2 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandUpOrOpen_0_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-closed position: Success Response"); + + Test_TC_WNCV_3_2 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test 2a: TH sends DownOrClose command to DUT + using SuccessCallback_1 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_1{ + OnTestSendClusterWindowCoveringCommandDownOrClose_1_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_1{ + OnTestSendClusterWindowCoveringCommandDownOrClose_1_FailureResponse, this + }; + + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandDownOrClose_1() + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends DownOrClose command to DUT: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.DownOrClose(mOnSuccessCallback_1.Cancel(), mOnFailureCallback_1.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandDownOrClose_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends DownOrClose command to DUT: Failure Response"); + + Test_TC_WNCV_3_2 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandDownOrClose_1_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends DownOrClose command to DUT: Success Response"); + + Test_TC_WNCV_3_2 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test 3a: TH reads OperationalStatus attribute from DUT + using SuccessCallback_2 = void (*)(void * context, uint8_t operationalStatus); + chip::Callback::Callback mOnSuccessCallback_2{ + OnTestSendClusterWindowCoveringCommandReadAttribute_2_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_2{ + OnTestSendClusterWindowCoveringCommandReadAttribute_2_FailureResponse, this + }; + + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_2() + { + ChipLogProgress(chipTool, "Window Covering - 3a: TH reads OperationalStatus attribute from DUT: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeOperationalStatus(mOnSuccessCallback_2.Cancel(), mOnFailureCallback_2.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandReadAttribute_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 3a: TH reads OperationalStatus attribute from DUT: Failure Response"); + + Test_TC_WNCV_3_2 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandReadAttribute_2_SuccessResponse(void * context, uint8_t operationalStatus) + { + ChipLogProgress(chipTool, "Window Covering - 3a: TH reads OperationalStatus attribute from DUT: Success Response"); + + Test_TC_WNCV_3_2 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (operationalStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class Test_TC_WNCV_3_3 : public TestCommand +{ +public: + Test_TC_WNCV_3_3() : TestCommand("Test_TC_WNCV_3_3"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "Test_TC_WNCV_3_3: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterWindowCoveringCommandUpOrOpen_0(); + break; + case 1: + err = TestSendClusterWindowCoveringCommandStopMotion_1(); + break; + case 2: + err = TestSendClusterWindowCoveringCommandReadAttribute_2(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "Test_TC_WNCV_3_3: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 3; + + // + // Tests methods + // + + // Test 1a: TH adjusts the the DUT to a non-open position + using SuccessCallback_0 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_0{ + OnTestSendClusterWindowCoveringCommandUpOrOpen_0_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_0{ + OnTestSendClusterWindowCoveringCommandUpOrOpen_0_FailureResponse, this + }; + + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandUpOrOpen_0() + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-open position: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.UpOrOpen(mOnSuccessCallback_0.Cancel(), mOnFailureCallback_0.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandUpOrOpen_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-open position: Failure Response"); + + Test_TC_WNCV_3_3 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandUpOrOpen_0_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Window Covering - 1a: TH adjusts the the DUT to a non-open position: Success Response"); + + Test_TC_WNCV_3_3 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test 2a: TH sends StopMotion command to DUT + using SuccessCallback_1 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_1{ + OnTestSendClusterWindowCoveringCommandStopMotion_1_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_1{ + OnTestSendClusterWindowCoveringCommandStopMotion_1_FailureResponse, this + }; + + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandStopMotion_1() + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends StopMotion command to DUT: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.StopMotion(mOnSuccessCallback_1.Cancel(), mOnFailureCallback_1.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandStopMotion_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends StopMotion command to DUT: Failure Response"); + + Test_TC_WNCV_3_3 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandStopMotion_1_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Window Covering - 2a: TH sends StopMotion command to DUT: Success Response"); + + Test_TC_WNCV_3_3 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test 2b: TH reads OperationalStatus attribute from DUT + using SuccessCallback_2 = void (*)(void * context, uint8_t operationalStatus); + chip::Callback::Callback mOnSuccessCallback_2{ + OnTestSendClusterWindowCoveringCommandReadAttribute_2_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_2{ + OnTestSendClusterWindowCoveringCommandReadAttribute_2_FailureResponse, this + }; + + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_2() + { + ChipLogProgress(chipTool, "Window Covering - 2b: TH reads OperationalStatus attribute from DUT: Sending command..."); + + chip::Controller::WindowCoveringClusterTest cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeOperationalStatus(mOnSuccessCallback_2.Cancel(), mOnFailureCallback_2.Cancel()); + + return err; + } + + static void OnTestSendClusterWindowCoveringCommandReadAttribute_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Window Covering - 2b: TH reads OperationalStatus attribute from DUT: Failure Response"); + + Test_TC_WNCV_3_3 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterWindowCoveringCommandReadAttribute_2_SuccessResponse(void * context, uint8_t operationalStatus) + { + ChipLogProgress(chipTool, "Window Covering - 2b: TH reads OperationalStatus attribute from DUT: Success Response"); + + Test_TC_WNCV_3_3 * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (operationalStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + class Test_TC_BI_1_1 : public TestCommand { public: @@ -21301,6 +21982,9 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), + make_unique(), + make_unique(), + make_unique(), make_unique(), make_unique(), make_unique(),