From 964153e5898fd15ac01a19e89630b37f68c6a6f3 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 15:02:08 +0200 Subject: [PATCH 01/13] Add Test_TC_AIRQUAL_1_1.yaml --- .../certification/Test_TC_AIRQUAL_1_1.yaml | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml diff --git a/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml new file mode 100644 index 00000000000000..0a77b0e996ea3e --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml @@ -0,0 +1,125 @@ +# Copyright (c) 2023 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: 164.1.1. [TC-AIRQUAL-1.1] Global Attributes with DUT as Server + +PICS: + - AIRQUAL.S + +config: + nodeId: 0x12344321 + cluster: "Air Quality" + endpoint: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Read the global attribute: ClusterRevision" + command: "readAttribute" + attribute: "ClusterRevision" + response: + value: 1 + constraints: + type: int16u + + - label: "Read the global attribute: FeatureMap" + command: "readAttribute" + attribute: "FeatureMap" + PICS: + "!AIRQUAL.S.F00 && !AIRQUAL.S.F01 && !AIRQUAL.S.F02 && !AIRQUAL.S.F03" + response: + value: 0 + constraints: + type: bitmap32 + + - label: + "Given AIRQUAL.S.F00(Fair) ensure featuremap has the correct bit set" + command: "readAttribute" + attribute: "FeatureMap" + PICS: AIRQUAL.S.F00 + response: + constraints: + type: bitmap32 + hasMasksSet: [0x1] + + - label: + "Given AIRQUAL.S.F01(Moderate) ensure featuremap has the correct bit + set" + command: "readAttribute" + attribute: "FeatureMap" + PICS: AIRQUAL.S.F01 + response: + constraints: + type: bitmap32 + hasMasksSet: [0x2] + + - label: + "Given AIRQUAL.S.F02(VeryPoor) ensure featuremap has the correct bit + set" + command: "readAttribute" + attribute: "FeatureMap" + PICS: AIRQUAL.S.F02 + response: + constraints: + type: bitmap32 + hasMasksSet: [0x3] + + - label: + "Given AIRQUAL.S.F03(ExtremelyPoor) ensure featuremap has the correct + bit set" + command: "readAttribute" + attribute: "FeatureMap" + PICS: AIRQUAL.S.F03 + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4] + + - label: "Read the global attribute: AttributeList" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] + + - label: "Read the global attribute: AcceptedCommandList" + command: "readAttribute" + attribute: "AcceptedCommandList" + response: + constraints: + type: list + contains: [] + + - label: "Read the global attribute: GeneratedCommandList" + command: "readAttribute" + attribute: "GeneratedCommandList" + response: + value: [] + constraints: + type: list + + - label: "TH reads EventList attribute from DUT" + command: "readAttribute" + attribute: "EventList" + response: + value: [] + constraints: + type: list From 7962e760584b40cb16d69963a547db7ad899f0b7 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 15:15:44 +0200 Subject: [PATCH 02/13] Add Test_TC_AIRQUAL_2_1.yaml --- .../certification/Test_TC_AIRQUAL_2_1.yaml | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/app/tests/suites/certification/Test_TC_AIRQUAL_2_1.yaml diff --git a/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_1.yaml b/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_1.yaml new file mode 100644 index 00000000000000..3f5c638317bb52 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_1.yaml @@ -0,0 +1,42 @@ +# Copyright (c) 2023 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: 3.2.1. [TC-AIRQUAL-2.1] Attributes with server as DUT + +PICS: + - AIRQUAL.S + +config: + nodeId: 0x12344321 + cluster: "Air Quality" + endpoint: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH reads from the DUT the AirQuality attribute." + PICS: AIRQUAL.S.A0000 + command: "readAttribute" + attribute: "AirQuality" + response: + constraints: + type: enum8 + minValue: 0 + maxValue: 6 From 1f7692b647934ca907a941c93348e4d19d3f56f6 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 15:33:50 +0200 Subject: [PATCH 03/13] Add Test_TC_AIRQUAL_2_2.yaml --- .../certification/Test_TC_AIRQUAL_2_2.yaml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml diff --git a/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml b/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml new file mode 100644 index 00000000000000..644aa1d0333708 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml @@ -0,0 +1,70 @@ +# Copyright (c) 2023 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: 3.2.1. [TC-AIRQUAL-2.2] Attributes with server as DUT + +PICS: + - AIRQUAL.S + +config: + nodeId: 0x12344321 + cluster: "Air Quality" + endpoint: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH reads from the DUT the AirQuality attribute." + PICS: AIRQUAL.S.A0000 + command: "readAttribute" + attribute: "AirQuality" + response: + constraints: + type: enum8 + minValue: 0 + maxValue: 6 + + - label: "Operate on device to change the air quality significantly" + cluster: "LogCommands" + command: "UserPrompt" + PICS: PICS_USER_PROMPT && AIRQUAL.M.AirQualityChange + arguments: + values: + - name: "message" + value: "Please enter 'y' for success" + - name: "expectedValue" + value: "y" + + - label: "Wait 2s" + cluster: "DelayCommands" + command: "WaitForMs" + arguments: + values: + - name: "ms" + value: 2000 + + - label: + "After a few seconds, TH reads from the DUT the AirQuality attribute." + PICS: AIRQUAL.S.A0000 && AIRQUAL.M.AirQualityChange + command: "readAttribute" + attribute: "AirQuality" + response: + constraints: + notValue: ValueBeforeChange From 0e3e0dbecf004562c29de67991184faece3134b9 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 16:32:53 +0200 Subject: [PATCH 04/13] Save First Response --- src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml b/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml index 644aa1d0333708..38d72814bd67b1 100644 --- a/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml @@ -36,6 +36,7 @@ tests: command: "readAttribute" attribute: "AirQuality" response: + saveAs: ValueBeforeChange constraints: type: enum8 minValue: 0 From 7b2d769b5a441541ed75bc0d6ff0c0a252204d04 Mon Sep 17 00:00:00 2001 From: Graf Tobias <4622393+tobiasgraf@users.noreply.github.com> Date: Fri, 26 May 2023 16:33:59 +0200 Subject: [PATCH 05/13] Add AirQualiity Test Scripts To PICS and ciTests.json --- src/app/tests/suites/certification/PICS.yaml | 35 ++++++++++++++++++++ src/app/tests/suites/ciTests.json | 6 ++++ 2 files changed, 41 insertions(+) diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 56aea7c1c2416d..1670f6faca37b4 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -7700,3 +7700,38 @@ PICS: # - label: "Does the DUT(server) support the SetTimeZoneResponse command?" id: TIMESYNC.S.C03.Tx + + ##################################################################################### + # Air Quality Cluster Test Plan + - label: "Does the device implement the Air Quality cluster as a server?" + id: AIRQUAL.S + + - label: "Does the device implement the Air Quality cluster as a client?" + id: AIRQUAL.C + + # + # server / attributes + # + - label: "Does the device implement the AirQuality attribute?" + id: AIRQUAL.S.A0000 + + # + # server / features + # + - label: "Does the device support the Fair feature?" + id: AIRQUAL.S.F00 + + - label: "Does the device support the Moderate feature?" + id: AIRQUAL.S.F01 + + - label: "Does the device support the VeryPoor feature?" + id: AIRQUAL.S.F02 + + - label: "Does the device support the ExtremelyPoor feature?" + id: AIRQUAL.S.F03 + + # + # server / manual + # + - label: "Changes air quality significantly" + id: AIRQUAL.M.AirQualityChange \ No newline at end of file diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index f552cecf1cb2d4..74468e50698310 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -272,9 +272,15 @@ "Test_TC_G_2_1" ], "Scenes": ["Test_TC_S_1_1"], + "AirQuality": [ + "Test_TC_AIRQUAL_1_1", + "Test_TC_AIRQUAL_2_1", + "Test_TC_AIRQUAL_2_2" + ], "collection": [ "AccessControl", "AccessControlEnforcement", + "AirQuality", "BooleanState", "BridgedDeviceBasicInformation", "Actions", From 0f8c75b6a8a8098e897146076c53245f44bb31ac Mon Sep 17 00:00:00 2001 From: Graf Tobias <4622393+tobiasgraf@users.noreply.github.com> Date: Fri, 26 May 2023 16:34:22 +0200 Subject: [PATCH 06/13] Add Generated Code --- .../chip-tool/zap-generated/test/Commands.h | 443 +++++++++++ .../zap-generated/test/Commands.h | 710 ++++++++++++++++++ 2 files changed, 1153 insertions(+) diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index ae7a0472d2589b..debd3a0eaa208d 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -47,6 +47,9 @@ class TestList : public Command printf("Test_TC_ACL_2_10\n"); printf("Test_TC_ACE_1_1\n"); printf("Test_TC_ACE_1_5\n"); + printf("Test_TC_AIRQUAL_1_1\n"); + printf("Test_TC_AIRQUAL_2_1\n"); + printf("Test_TC_AIRQUAL_2_2\n"); printf("Test_TC_BOOL_1_1\n"); printf("Test_TC_BOOL_2_1\n"); printf("Test_TC_BRBINFO_1_1\n"); @@ -9433,6 +9436,443 @@ class Test_TC_ACE_1_5Suite : public TestCommand } }; +class Test_TC_AIRQUAL_1_1Suite : public TestCommand +{ +public: + Test_TC_AIRQUAL_1_1Suite(CredentialIssuerCommands * credsIssuerConfig) : + TestCommand("Test_TC_AIRQUAL_1_1", 11, credsIssuerConfig) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + + ~Test_TC_AIRQUAL_1_1Suite() {} + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; } + + // + // Tests methods + // + + void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override + { + bool shouldContinue = false; + + 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)); + { + uint32_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); + VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 2UL)); + } + break; + case 5: + 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, 3UL)); + } + break; + case 6: + 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, 4UL)); + } + 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(CheckConstraintContains("value", value, 0UL)); + 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 8: + 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")); + } + 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(CheckNoMoreListItems("generatedCommandList", iter_0, 0)); + } + 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(CheckNoMoreListItems("eventList", iter_0, 0)); + } + VerifyOrReturn(CheckConstraintType("value", "list", "list")); + } + break; + default: + LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); + } + + if (shouldContinue) + { + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + } + + CHIP_ERROR DoTestStep(uint16_t testIndex) override + { + 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, "Read the global attribute: ClusterRevision"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::ClusterRevision::Id, true, + chip::NullOptional); + } + case 2: { + LogStep(2, "Read the global attribute: FeatureMap"); + VerifyOrDo(!ShouldSkip("!AIRQUAL.S.F00 && !AIRQUAL.S.F01 && !AIRQUAL.S.F02 && !AIRQUAL.S.F03"), + return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 3: { + LogStep(3, "Given AIRQUAL.S.F00(Fair) ensure featuremap has the correct bit set"); + VerifyOrDo(!ShouldSkip("AIRQUAL.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 4: { + LogStep(4, "Given AIRQUAL.S.F01(Moderate) ensure featuremap has the correct bit set"); + VerifyOrDo(!ShouldSkip("AIRQUAL.S.F01"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 5: { + LogStep(5, "Given AIRQUAL.S.F02(VeryPoor) ensure featuremap has the correct bit set"); + VerifyOrDo(!ShouldSkip("AIRQUAL.S.F02"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 6: { + LogStep(6, "Given AIRQUAL.S.F03(ExtremelyPoor) ensure featuremap has the correct bit set"); + VerifyOrDo(!ShouldSkip("AIRQUAL.S.F03"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::FeatureMap::Id, true, + chip::NullOptional); + } + case 7: { + LogStep(7, "Read the global attribute: AttributeList"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::AttributeList::Id, true, + chip::NullOptional); + } + case 8: { + LogStep(8, "Read the global attribute: AcceptedCommandList"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::AcceptedCommandList::Id, + true, chip::NullOptional); + } + case 9: { + LogStep(9, "Read the global attribute: GeneratedCommandList"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::GeneratedCommandList::Id, + true, chip::NullOptional); + } + case 10: { + LogStep(10, "TH reads EventList attribute from DUT"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::EventList::Id, true, + chip::NullOptional); + } + } + return CHIP_NO_ERROR; + } +}; + +class Test_TC_AIRQUAL_2_1Suite : public TestCommand +{ +public: + Test_TC_AIRQUAL_2_1Suite(CredentialIssuerCommands * credsIssuerConfig) : + TestCommand("Test_TC_AIRQUAL_2_1", 2, credsIssuerConfig) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + + ~Test_TC_AIRQUAL_2_1Suite() {} + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; } + + // + // Tests methods + // + + void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override + { + bool shouldContinue = false; + + 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)); + { + chip::app::Clusters::AirQuality::AirQualityEnum value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "enum8", "enum8")); + VerifyOrReturn(CheckConstraintMinValue("value", value, 0U)); + VerifyOrReturn(CheckConstraintMaxValue("value", value, 6U)); + } + break; + default: + LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); + } + + if (shouldContinue) + { + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + } + + CHIP_ERROR DoTestStep(uint16_t testIndex) override + { + 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 from the DUT the AirQuality attribute."); + VerifyOrDo(!ShouldSkip("AIRQUAL.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::AirQuality::Id, true, + chip::NullOptional); + } + } + return CHIP_NO_ERROR; + } +}; + +class Test_TC_AIRQUAL_2_2Suite : public TestCommand +{ +public: + Test_TC_AIRQUAL_2_2Suite(CredentialIssuerCommands * credsIssuerConfig) : + TestCommand("Test_TC_AIRQUAL_2_2", 5, credsIssuerConfig) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + + ~Test_TC_AIRQUAL_2_2Suite() {} + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + chip::app::Clusters::AirQuality::AirQualityEnum ValueBeforeChange; + + chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; } + + // + // Tests methods + // + + void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override + { + bool shouldContinue = false; + + 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)); + { + chip::app::Clusters::AirQuality::AirQualityEnum value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "enum8", "enum8")); + VerifyOrReturn(CheckConstraintMinValue("value", value, 0U)); + VerifyOrReturn(CheckConstraintMaxValue("value", value, 6U)); + ValueBeforeChange = value; + } + break; + case 2: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 3: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::Clusters::AirQuality::AirQualityEnum value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintNotValue("value", value, ValueBeforeChange)); + } + break; + default: + LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); + } + + if (shouldContinue) + { + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + } + + CHIP_ERROR DoTestStep(uint16_t testIndex) override + { + 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 from the DUT the AirQuality attribute."); + VerifyOrDo(!ShouldSkip("AIRQUAL.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::AirQuality::Id, true, + chip::NullOptional); + } + case 2: { + LogStep(2, "Operate on device to change the air quality significantly"); + VerifyOrDo(!ShouldSkip("PICS_USER_PROMPT && AIRQUAL.M.AirQualityChange"), + return ContinueOnChipMainThread(CHIP_NO_ERROR)); + ListFreer listFreer; + chip::app::Clusters::LogCommands::Commands::UserPrompt::Type value; + value.message = chip::Span("Please enter 'y' for successgarbage: not in length on purpose", 28); + value.expectedValue.Emplace(); + value.expectedValue.Value() = chip::Span("ygarbage: not in length on purpose", 1); + return UserPrompt(kIdentityAlpha, value); + } + case 3: { + LogStep(3, "Wait 2s"); + ListFreer listFreer; + chip::app::Clusters::DelayCommands::Commands::WaitForMs::Type value; + value.ms = 2000UL; + return WaitForMs(kIdentityAlpha, value); + } + case 4: { + LogStep(4, "After a few seconds, TH reads from the DUT the AirQuality attribute."); + VerifyOrDo(!ShouldSkip("AIRQUAL.S.A0000 && AIRQUAL.M.AirQualityChange"), + return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::AirQuality::Id, true, + chip::NullOptional); + } + } + return CHIP_NO_ERROR; + } +}; + class Test_TC_BOOL_1_1Suite : public TestCommand { public: @@ -118598,6 +119038,9 @@ void registerCommandsTests(Commands & commands, CredentialIssuerCommands * creds make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index 2dfcdc6756da88..a0f6c91b7e20c5 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -43,6 +43,9 @@ class TestList : public Command { printf("Test_TC_ACL_2_3\n"); printf("Test_TC_ACE_1_1\n"); printf("Test_TC_ACE_1_5\n"); + printf("Test_TC_AIRQUAL_1_1\n"); + printf("Test_TC_AIRQUAL_2_1\n"); + printf("Test_TC_AIRQUAL_2_2\n"); printf("Test_TC_BOOL_1_1\n"); printf("Test_TC_BOOL_2_1\n"); printf("Test_TC_BRBINFO_1_1\n"); @@ -6402,6 +6405,710 @@ class Test_TC_ACE_1_5 : public TestCommandBridge { } }; +class Test_TC_AIRQUAL_1_1 : public TestCommandBridge { +public: + // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced + Test_TC_AIRQUAL_1_1() + : TestCommandBridge("Test_TC_AIRQUAL_1_1") + , mTestIndex(0) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) + + ~Test_TC_AIRQUAL_1_1() {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (0 == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Start: Test_TC_AIRQUAL_1_1\n"); + } + + if (mTestCount == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Complete: Test_TC_AIRQUAL_1_1\n"); + SetCommandExitStatus(CHIP_NO_ERROR); + return; + } + + Wait(); + + // 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: + ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrieved_0(); + break; + case 1: + ChipLogProgress(chipTool, " ***** Test Step 1 : Read the global attribute: ClusterRevision\n"); + err = TestReadTheGlobalAttributeClusterRevision_1(); + break; + case 2: + ChipLogProgress(chipTool, " ***** Test Step 2 : Read the global attribute: FeatureMap\n"); + if (ShouldSkip("!AIRQUAL.S.F00 && !AIRQUAL.S.F01 && !AIRQUAL.S.F02 && !AIRQUAL.S.F03")) { + NextTest(); + return; + } + err = TestReadTheGlobalAttributeFeatureMap_2(); + break; + case 3: + ChipLogProgress(chipTool, " ***** Test Step 3 : Given AIRQUAL.S.F00(Fair) ensure featuremap has the correct bit set\n"); + if (ShouldSkip("AIRQUAL.S.F00")) { + NextTest(); + return; + } + err = TestGivenAIRQUALSF00FairEnsureFeaturemapHasTheCorrectBitSet_3(); + break; + case 4: + ChipLogProgress( + chipTool, " ***** Test Step 4 : Given AIRQUAL.S.F01(Moderate) ensure featuremap has the correct bit set\n"); + if (ShouldSkip("AIRQUAL.S.F01")) { + NextTest(); + return; + } + err = TestGivenAIRQUALSF01ModerateEnsureFeaturemapHasTheCorrectBitSet_4(); + break; + case 5: + ChipLogProgress( + chipTool, " ***** Test Step 5 : Given AIRQUAL.S.F02(VeryPoor) ensure featuremap has the correct bit set\n"); + if (ShouldSkip("AIRQUAL.S.F02")) { + NextTest(); + return; + } + err = TestGivenAIRQUALSF02VeryPoorEnsureFeaturemapHasTheCorrectBitSet_5(); + break; + case 6: + ChipLogProgress( + chipTool, " ***** Test Step 6 : Given AIRQUAL.S.F03(ExtremelyPoor) ensure featuremap has the correct bit set\n"); + if (ShouldSkip("AIRQUAL.S.F03")) { + NextTest(); + return; + } + err = TestGivenAIRQUALSF03ExtremelyPoorEnsureFeaturemapHasTheCorrectBitSet_6(); + break; + case 7: + ChipLogProgress(chipTool, " ***** Test Step 7 : Read the global attribute: AttributeList\n"); + err = TestReadTheGlobalAttributeAttributeList_7(); + break; + case 8: + ChipLogProgress(chipTool, " ***** Test Step 8 : Read the global attribute: AcceptedCommandList\n"); + err = TestReadTheGlobalAttributeAcceptedCommandList_8(); + break; + case 9: + ChipLogProgress(chipTool, " ***** Test Step 9 : Read the global attribute: GeneratedCommandList\n"); + err = TestReadTheGlobalAttributeGeneratedCommandList_9(); + break; + case 10: + ChipLogProgress(chipTool, " ***** Test Step 10 : TH reads EventList attribute from DUT\n"); + err = TestThReadsEventListAttributeFromDut_10(); + break; + } + + if (CHIP_NO_ERROR != err) { + ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + + void OnStatusUpdate(const chip::app::StatusIB & status) override + { + switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 2: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 3: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 5: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 6: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 7: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 8: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 9: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 10: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + } + + // Go on to the next test. + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 11; + + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee("alpha", value); + } + + CHIP_ERROR TestReadTheGlobalAttributeClusterRevision_1() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read the global attribute: ClusterRevision Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = value; + VerifyOrReturn(CheckValue("ClusterRevision", actualValue, 1U)); + } + + VerifyOrReturn(CheckConstraintType("clusterRevision", "int16u", "int16u")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestReadTheGlobalAttributeFeatureMap_2() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read the global attribute: FeatureMap Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = value; + VerifyOrReturn(CheckValue("FeatureMap", actualValue, 0UL)); + } + + VerifyOrReturn(CheckConstraintType("featureMap", "bitmap32", "bitmap32")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestGivenAIRQUALSF00FairEnsureFeaturemapHasTheCorrectBitSet_3() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"Given AIRQUAL.S.F00(Fair) ensure featuremap has the correct bit set Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("featureMap", "bitmap32", "bitmap32")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestGivenAIRQUALSF01ModerateEnsureFeaturemapHasTheCorrectBitSet_4() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"Given AIRQUAL.S.F01(Moderate) ensure featuremap has the correct bit set Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("featureMap", "bitmap32", "bitmap32")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestGivenAIRQUALSF02VeryPoorEnsureFeaturemapHasTheCorrectBitSet_5() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"Given AIRQUAL.S.F02(VeryPoor) ensure featuremap has the correct bit set Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("featureMap", "bitmap32", "bitmap32")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestGivenAIRQUALSF03ExtremelyPoorEnsureFeaturemapHasTheCorrectBitSet_6() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"Given AIRQUAL.S.F03(ExtremelyPoor) ensure featuremap has the correct bit set Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("featureMap", "bitmap32", "bitmap32")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestReadTheGlobalAttributeAttributeList_7() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read the global attribute: AttributeList Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("attributeList", "list", "list")); + VerifyOrReturn(CheckConstraintContains("attributeList", value, 0UL)); + VerifyOrReturn(CheckConstraintContains("attributeList", value, 65528UL)); + VerifyOrReturn(CheckConstraintContains("attributeList", value, 65529UL)); + VerifyOrReturn(CheckConstraintContains("attributeList", value, 65530UL)); + VerifyOrReturn(CheckConstraintContains("attributeList", value, 65531UL)); + VerifyOrReturn(CheckConstraintContains("attributeList", value, 65532UL)); + VerifyOrReturn(CheckConstraintContains("attributeList", value, 65533UL)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestReadTheGlobalAttributeAcceptedCommandList_8() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read the global attribute: AcceptedCommandList Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("acceptedCommandList", "list", "list")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestReadTheGlobalAttributeGeneratedCommandList_9() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read the global attribute: GeneratedCommandList Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = value; + VerifyOrReturn(CheckValue("GeneratedCommandList", [actualValue count], static_cast(0))); + } + + VerifyOrReturn(CheckConstraintType("generatedCommandList", "list", "list")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestThReadsEventListAttributeFromDut_10() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH reads EventList attribute from DUT Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = value; + VerifyOrReturn(CheckValue("EventList", [actualValue count], static_cast(0))); + } + + VerifyOrReturn(CheckConstraintType("eventList", "list", "list")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } +}; + +class Test_TC_AIRQUAL_2_1 : public TestCommandBridge { +public: + // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced + Test_TC_AIRQUAL_2_1() + : TestCommandBridge("Test_TC_AIRQUAL_2_1") + , mTestIndex(0) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) + + ~Test_TC_AIRQUAL_2_1() {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (0 == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Start: Test_TC_AIRQUAL_2_1\n"); + } + + if (mTestCount == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Complete: Test_TC_AIRQUAL_2_1\n"); + SetCommandExitStatus(CHIP_NO_ERROR); + return; + } + + Wait(); + + // 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: + ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrieved_0(); + break; + case 1: + ChipLogProgress(chipTool, " ***** Test Step 1 : TH reads from the DUT the AirQuality attribute.\n"); + if (ShouldSkip("AIRQUAL.S.A0000")) { + NextTest(); + return; + } + err = TestThReadsFromTheDutTheAirQualityAttribute_1(); + break; + } + + if (CHIP_NO_ERROR != err) { + ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + + void OnStatusUpdate(const chip::app::StatusIB & status) override + { + switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + } + + // Go on to the next test. + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 2; + + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee("alpha", value); + } + + CHIP_ERROR TestThReadsFromTheDutTheAirQualityAttribute_1() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeAirQualityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH reads from the DUT the AirQuality attribute. Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("airQuality", "enum8", "enum8")); + VerifyOrReturn(CheckConstraintMinValue("airQuality", [value unsignedCharValue], 0U)); + VerifyOrReturn(CheckConstraintMaxValue("airQuality", [value unsignedCharValue], 6U)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } +}; + +class Test_TC_AIRQUAL_2_2 : public TestCommandBridge { +public: + // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced + Test_TC_AIRQUAL_2_2() + : TestCommandBridge("Test_TC_AIRQUAL_2_2") + , mTestIndex(0) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) + + ~Test_TC_AIRQUAL_2_2() {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (0 == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Start: Test_TC_AIRQUAL_2_2\n"); + } + + if (mTestCount == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Complete: Test_TC_AIRQUAL_2_2\n"); + SetCommandExitStatus(CHIP_NO_ERROR); + return; + } + + Wait(); + + // 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: + ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrieved_0(); + break; + case 1: + ChipLogProgress(chipTool, " ***** Test Step 1 : TH reads from the DUT the AirQuality attribute.\n"); + if (ShouldSkip("AIRQUAL.S.A0000")) { + NextTest(); + return; + } + err = TestThReadsFromTheDutTheAirQualityAttribute_1(); + break; + case 2: + ChipLogProgress(chipTool, " ***** Test Step 2 : Operate on device to change the air quality significantly\n"); + if (ShouldSkip("PICS_USER_PROMPT && AIRQUAL.M.AirQualityChange")) { + NextTest(); + return; + } + err = TestOperateOnDeviceToChangeTheAirQualitySignificantly_2(); + break; + case 3: + ChipLogProgress(chipTool, " ***** Test Step 3 : Wait 2s\n"); + err = TestWait2s_3(); + break; + case 4: + ChipLogProgress( + chipTool, " ***** Test Step 4 : After a few seconds, TH reads from the DUT the AirQuality attribute.\n"); + if (ShouldSkip("AIRQUAL.S.A0000 && AIRQUAL.M.AirQualityChange")) { + NextTest(); + return; + } + err = TestAfterAFewSecondsThReadsFromTheDutTheAirQualityAttribute_4(); + break; + } + + if (CHIP_NO_ERROR != err) { + ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + + void OnStatusUpdate(const chip::app::StatusIB & status) override + { + switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 2: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 3: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + } + + // Go on to the next test. + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 5; + + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee("alpha", value); + } + NSNumber * _Nonnull ValueBeforeChange; + + CHIP_ERROR TestThReadsFromTheDutTheAirQualityAttribute_1() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeAirQualityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH reads from the DUT the AirQuality attribute. Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("airQuality", "enum8", "enum8")); + VerifyOrReturn(CheckConstraintMinValue("airQuality", [value unsignedCharValue], 0U)); + VerifyOrReturn(CheckConstraintMaxValue("airQuality", [value unsignedCharValue], 6U)); + { + ValueBeforeChange = value; + } + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestOperateOnDeviceToChangeTheAirQualitySignificantly_2() + { + + chip::app::Clusters::LogCommands::Commands::UserPrompt::Type value; + value.message = chip::Span("Please enter 'y' for successgarbage: not in length on purpose", 28); + value.expectedValue.Emplace(); + value.expectedValue.Value() = chip::Span("ygarbage: not in length on purpose", 1); + return UserPrompt("alpha", value); + } + + CHIP_ERROR TestWait2s_3() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForMs::Type value; + value.ms = 2000UL; + return WaitForMs("alpha", value); + } + + CHIP_ERROR TestAfterAFewSecondsThReadsFromTheDutTheAirQualityAttribute_4() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeAirQualityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"After a few seconds, TH reads from the DUT the AirQuality attribute. Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintNotValue("airQuality", value, ValueBeforeChange)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } +}; + class Test_TC_BOOL_1_1 : public TestCommandBridge { public: // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced @@ -145976,6 +146683,9 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), + make_unique(), + make_unique(), + make_unique(), make_unique(), make_unique(), make_unique(), From 404f9f647f189ccbc966e30bd768615b9052e71a Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 16:42:35 +0200 Subject: [PATCH 07/13] Add CI PICS Values for Air Quality --- src/app/tests/suites/certification/ci-pics-values | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index 3cb6b999f9ea01..6bce747f2fa528 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2093,3 +2093,12 @@ TIMESYNC.S.C04.Rsp=1 TIMESYNC.S.C05.Rsp=1 TIMESYNC.S.C03.Tx=1 TIMESYNC.C=0 + +# Air Quality +AIRQUAL.S.F00=1 +AIRQUAL.S.F01=1 +AIRQUAL.S.F02=1 +AIRQUAL.S.F03=1 +AIRQUAL.S.A0000=1 +PICS_USER_PROMPT=1 +AIRQUAL.M.AirQualityChange=1 From ffadf80c052f98ee27ea686e5de6f76e8646889a Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 16:59:32 +0200 Subject: [PATCH 08/13] Update CI PICS Values --- src/app/tests/suites/certification/ci-pics-values | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index 6bce747f2fa528..9bfc4fd07e3d89 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2095,6 +2095,8 @@ TIMESYNC.S.C03.Tx=1 TIMESYNC.C=0 # Air Quality +AIRQUAL.C=0 +AIRQUAL.S=1 AIRQUAL.S.F00=1 AIRQUAL.S.F01=1 AIRQUAL.S.F02=1 From 9ecf194ede4805ca14b9725133fc7d102f4fa7af Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 17:13:34 +0200 Subject: [PATCH 09/13] Make Restyler Happy --- src/app/tests/suites/certification/PICS.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 1670f6faca37b4..967cc58ba621f3 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -7723,7 +7723,7 @@ PICS: - label: "Does the device support the Moderate feature?" id: AIRQUAL.S.F01 - + - label: "Does the device support the VeryPoor feature?" id: AIRQUAL.S.F02 @@ -7734,4 +7734,4 @@ PICS: # server / manual # - label: "Changes air quality significantly" - id: AIRQUAL.M.AirQualityChange \ No newline at end of file + id: AIRQUAL.M.AirQualityChange From 2e5797432840acbf23ca9e1d835fbd25bf4046fb Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Fri, 26 May 2023 20:02:55 +0200 Subject: [PATCH 10/13] =?UTF-8?q?Don=E2=80=99t=20Run=20the=20Last=202=20Te?= =?UTF-8?q?st=20Steps=20of=20TC-AIRQUAL-2.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those test steps are semi automated and can’t run in CI --- src/app/tests/suites/certification/ci-pics-values | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index 9bfc4fd07e3d89..20950f4bbe75f1 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2102,5 +2102,5 @@ AIRQUAL.S.F01=1 AIRQUAL.S.F02=1 AIRQUAL.S.F03=1 AIRQUAL.S.A0000=1 -PICS_USER_PROMPT=1 -AIRQUAL.M.AirQualityChange=1 +PICS_USER_PROMPT=0 +AIRQUAL.M.AirQualityChange=0 From 80ac9fd573732b4da917c7ab198eff9357536caf Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Wed, 31 May 2023 09:32:12 +0200 Subject: [PATCH 11/13] Remove Test_TC_AIRQUAL_2_2 --- .../certification/Test_TC_AIRQUAL_2_2.yaml | 71 ------- src/app/tests/suites/ciTests.json | 6 +- .../chip-tool/zap-generated/test/Commands.h | 130 ------------ .../zap-generated/test/Commands.h | 192 ------------------ 4 files changed, 1 insertion(+), 398 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml diff --git a/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml b/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml deleted file mode 100644 index 38d72814bd67b1..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_AIRQUAL_2_2.yaml +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2023 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: 3.2.1. [TC-AIRQUAL-2.2] Attributes with server as DUT - -PICS: - - AIRQUAL.S - -config: - nodeId: 0x12344321 - cluster: "Air Quality" - endpoint: 1 - -tests: - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "TH reads from the DUT the AirQuality attribute." - PICS: AIRQUAL.S.A0000 - command: "readAttribute" - attribute: "AirQuality" - response: - saveAs: ValueBeforeChange - constraints: - type: enum8 - minValue: 0 - maxValue: 6 - - - label: "Operate on device to change the air quality significantly" - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT && AIRQUAL.M.AirQualityChange - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait 2s" - cluster: "DelayCommands" - command: "WaitForMs" - arguments: - values: - - name: "ms" - value: 2000 - - - label: - "After a few seconds, TH reads from the DUT the AirQuality attribute." - PICS: AIRQUAL.S.A0000 && AIRQUAL.M.AirQualityChange - command: "readAttribute" - attribute: "AirQuality" - response: - constraints: - notValue: ValueBeforeChange diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index 9ccd90ed9d323f..1d588af8f3050c 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -273,11 +273,7 @@ "Test_TC_G_2_1" ], "Scenes": ["Test_TC_S_1_1"], - "AirQuality": [ - "Test_TC_AIRQUAL_1_1", - "Test_TC_AIRQUAL_2_1", - "Test_TC_AIRQUAL_2_2" - ], + "AirQuality": ["Test_TC_AIRQUAL_1_1", "Test_TC_AIRQUAL_2_1"], "collection": [ "AccessControl", "AccessControlEnforcement", diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index ca67839dedb261..91a57a4c83b018 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -49,7 +49,6 @@ class TestList : public Command printf("Test_TC_ACE_1_5\n"); printf("Test_TC_AIRQUAL_1_1\n"); printf("Test_TC_AIRQUAL_2_1\n"); - printf("Test_TC_AIRQUAL_2_2\n"); printf("Test_TC_BOOL_1_1\n"); printf("Test_TC_BOOL_2_1\n"); printf("Test_TC_BRBINFO_1_1\n"); @@ -9747,134 +9746,6 @@ class Test_TC_AIRQUAL_2_1Suite : public TestCommand } }; -class Test_TC_AIRQUAL_2_2Suite : public TestCommand -{ -public: - Test_TC_AIRQUAL_2_2Suite(CredentialIssuerCommands * credsIssuerConfig) : - TestCommand("Test_TC_AIRQUAL_2_2", 5, credsIssuerConfig) - { - AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); - AddArgument("cluster", &mCluster); - AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); - AddArgument("timeout", 0, UINT16_MAX, &mTimeout); - } - - ~Test_TC_AIRQUAL_2_2Suite() {} - - chip::System::Clock::Timeout GetWaitDuration() const override - { - return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); - } - -private: - chip::Optional mNodeId; - chip::Optional mCluster; - chip::Optional mEndpoint; - chip::Optional mTimeout; - - chip::app::Clusters::AirQuality::AirQualityEnum ValueBeforeChange; - - chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; } - - // - // Tests methods - // - - void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override - { - bool shouldContinue = false; - - 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)); - { - chip::app::Clusters::AirQuality::AirQualityEnum value; - VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); - VerifyOrReturn(CheckConstraintType("value", "enum8", "enum8")); - VerifyOrReturn(CheckConstraintMinValue("value", value, 0U)); - VerifyOrReturn(CheckConstraintMaxValue("value", value, 6U)); - ValueBeforeChange = value; - } - break; - case 2: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - shouldContinue = true; - break; - case 3: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - shouldContinue = true; - break; - case 4: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - { - chip::app::Clusters::AirQuality::AirQualityEnum value; - VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); - VerifyOrReturn(CheckConstraintNotValue("value", value, ValueBeforeChange)); - } - break; - default: - LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); - } - - if (shouldContinue) - { - ContinueOnChipMainThread(CHIP_NO_ERROR); - } - } - - CHIP_ERROR DoTestStep(uint16_t testIndex) override - { - 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 from the DUT the AirQuality attribute."); - VerifyOrDo(!ShouldSkip("AIRQUAL.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); - return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::AirQuality::Id, true, - chip::NullOptional); - } - case 2: { - LogStep(2, "Operate on device to change the air quality significantly"); - VerifyOrDo(!ShouldSkip("PICS_USER_PROMPT && AIRQUAL.M.AirQualityChange"), - return ContinueOnChipMainThread(CHIP_NO_ERROR)); - ListFreer listFreer; - chip::app::Clusters::LogCommands::Commands::UserPrompt::Type value; - value.message = chip::Span("Please enter 'y' for successgarbage: not in length on purpose", 28); - value.expectedValue.Emplace(); - value.expectedValue.Value() = chip::Span("ygarbage: not in length on purpose", 1); - return UserPrompt(kIdentityAlpha, value); - } - case 3: { - LogStep(3, "Wait 2s"); - ListFreer listFreer; - chip::app::Clusters::DelayCommands::Commands::WaitForMs::Type value; - value.ms = 2000UL; - return WaitForMs(kIdentityAlpha, value); - } - case 4: { - LogStep(4, "After a few seconds, TH reads from the DUT the AirQuality attribute."); - VerifyOrDo(!ShouldSkip("AIRQUAL.S.A0000 && AIRQUAL.M.AirQualityChange"), - return ContinueOnChipMainThread(CHIP_NO_ERROR)); - return ReadAttribute(kIdentityAlpha, GetEndpoint(1), AirQuality::Id, AirQuality::Attributes::AirQuality::Id, true, - chip::NullOptional); - } - } - return CHIP_NO_ERROR; - } -}; - class Test_TC_BOOL_1_1Suite : public TestCommand { public: @@ -122180,7 +122051,6 @@ void registerCommandsTests(Commands & commands, CredentialIssuerCommands * creds make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index a0f6c91b7e20c5..150bb691cb7ecc 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -45,7 +45,6 @@ class TestList : public Command { printf("Test_TC_ACE_1_5\n"); printf("Test_TC_AIRQUAL_1_1\n"); printf("Test_TC_AIRQUAL_2_1\n"); - printf("Test_TC_AIRQUAL_2_2\n"); printf("Test_TC_BOOL_1_1\n"); printf("Test_TC_BOOL_2_1\n"); printf("Test_TC_BRBINFO_1_1\n"); @@ -6919,196 +6918,6 @@ class Test_TC_AIRQUAL_2_1 : public TestCommandBridge { } }; -class Test_TC_AIRQUAL_2_2 : public TestCommandBridge { -public: - // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced - Test_TC_AIRQUAL_2_2() - : TestCommandBridge("Test_TC_AIRQUAL_2_2") - , mTestIndex(0) - { - AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); - AddArgument("cluster", &mCluster); - AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); - AddArgument("timeout", 0, UINT16_MAX, &mTimeout); - } - // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) - - ~Test_TC_AIRQUAL_2_2() {} - - /////////// TestCommand Interface ///////// - void NextTest() override - { - CHIP_ERROR err = CHIP_NO_ERROR; - - if (0 == mTestIndex) { - ChipLogProgress(chipTool, " **** Test Start: Test_TC_AIRQUAL_2_2\n"); - } - - if (mTestCount == mTestIndex) { - ChipLogProgress(chipTool, " **** Test Complete: Test_TC_AIRQUAL_2_2\n"); - SetCommandExitStatus(CHIP_NO_ERROR); - return; - } - - Wait(); - - // 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: - ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved\n"); - err = TestWaitForTheCommissionedDeviceToBeRetrieved_0(); - break; - case 1: - ChipLogProgress(chipTool, " ***** Test Step 1 : TH reads from the DUT the AirQuality attribute.\n"); - if (ShouldSkip("AIRQUAL.S.A0000")) { - NextTest(); - return; - } - err = TestThReadsFromTheDutTheAirQualityAttribute_1(); - break; - case 2: - ChipLogProgress(chipTool, " ***** Test Step 2 : Operate on device to change the air quality significantly\n"); - if (ShouldSkip("PICS_USER_PROMPT && AIRQUAL.M.AirQualityChange")) { - NextTest(); - return; - } - err = TestOperateOnDeviceToChangeTheAirQualitySignificantly_2(); - break; - case 3: - ChipLogProgress(chipTool, " ***** Test Step 3 : Wait 2s\n"); - err = TestWait2s_3(); - break; - case 4: - ChipLogProgress( - chipTool, " ***** Test Step 4 : After a few seconds, TH reads from the DUT the AirQuality attribute.\n"); - if (ShouldSkip("AIRQUAL.S.A0000 && AIRQUAL.M.AirQualityChange")) { - NextTest(); - return; - } - err = TestAfterAFewSecondsThReadsFromTheDutTheAirQualityAttribute_4(); - break; - } - - if (CHIP_NO_ERROR != err) { - ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); - SetCommandExitStatus(err); - } - } - - void OnStatusUpdate(const chip::app::StatusIB & status) override - { - switch (mTestIndex - 1) { - case 0: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 1: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 2: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 3: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 4: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - } - - // Go on to the next test. - ContinueOnChipMainThread(CHIP_NO_ERROR); - } - - chip::System::Clock::Timeout GetWaitDuration() const override - { - return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); - } - -private: - std::atomic_uint16_t mTestIndex; - const uint16_t mTestCount = 5; - - chip::Optional mNodeId; - chip::Optional mCluster; - chip::Optional mEndpoint; - chip::Optional mTimeout; - - CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0() - { - - chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; - value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; - return WaitForCommissionee("alpha", value); - } - NSNumber * _Nonnull ValueBeforeChange; - - CHIP_ERROR TestThReadsFromTheDutTheAirQualityAttribute_1() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeAirQualityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - NSLog(@"TH reads from the DUT the AirQuality attribute. Error: %@", err); - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - VerifyOrReturn(CheckConstraintType("airQuality", "enum8", "enum8")); - VerifyOrReturn(CheckConstraintMinValue("airQuality", [value unsignedCharValue], 0U)); - VerifyOrReturn(CheckConstraintMaxValue("airQuality", [value unsignedCharValue], 6U)); - { - ValueBeforeChange = value; - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestOperateOnDeviceToChangeTheAirQualitySignificantly_2() - { - - chip::app::Clusters::LogCommands::Commands::UserPrompt::Type value; - value.message = chip::Span("Please enter 'y' for successgarbage: not in length on purpose", 28); - value.expectedValue.Emplace(); - value.expectedValue.Value() = chip::Span("ygarbage: not in length on purpose", 1); - return UserPrompt("alpha", value); - } - - CHIP_ERROR TestWait2s_3() - { - - chip::app::Clusters::DelayCommands::Commands::WaitForMs::Type value; - value.ms = 2000UL; - return WaitForMs("alpha", value); - } - - CHIP_ERROR TestAfterAFewSecondsThReadsFromTheDutTheAirQualityAttribute_4() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeAirQualityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - NSLog(@"After a few seconds, TH reads from the DUT the AirQuality attribute. Error: %@", err); - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - VerifyOrReturn(CheckConstraintNotValue("airQuality", value, ValueBeforeChange)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } -}; - class Test_TC_BOOL_1_1 : public TestCommandBridge { public: // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced @@ -146685,7 +146494,6 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), - make_unique(), make_unique(), make_unique(), make_unique(), From 3c86474a0be7cb4f73094dcd671677a2db807698 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Wed, 31 May 2023 09:32:54 +0200 Subject: [PATCH 12/13] Fix Bitmasks --- src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml index 0a77b0e996ea3e..5552e06cc47f74 100644 --- a/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml @@ -79,7 +79,7 @@ tests: response: constraints: type: bitmap32 - hasMasksSet: [0x3] + hasMasksSet: [0x4] - label: "Given AIRQUAL.S.F03(ExtremelyPoor) ensure featuremap has the correct @@ -90,7 +90,7 @@ tests: response: constraints: type: bitmap32 - hasMasksSet: [0x4] + hasMasksSet: [0x8] - label: "Read the global attribute: AttributeList" command: "readAttribute" From d124b3492156197074d516129a8a086cafb3d3f4 Mon Sep 17 00:00:00 2001 From: Thomas Hartwig Date: Wed, 31 May 2023 09:46:12 +0200 Subject: [PATCH 13/13] Update Code Gen --- zzz_generated/chip-tool/zap-generated/test/Commands.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 91a57a4c83b018..94d0ef3097ac63 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -9520,7 +9520,7 @@ class Test_TC_AIRQUAL_1_1Suite : public TestCommand uint32_t value; VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); - VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 3UL)); + VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 4UL)); } break; case 6: @@ -9529,7 +9529,7 @@ class Test_TC_AIRQUAL_1_1Suite : public TestCommand uint32_t value; VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); - VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 4UL)); + VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 8UL)); } break; case 7: