From f02df8965089a2e893123b643ccbc42e2d11ea04 Mon Sep 17 00:00:00 2001 From: Harshith-GRL <145322529+Harshith-GRL@users.noreply.github.com> Date: Thu, 5 Sep 2024 03:06:25 +0530 Subject: [PATCH] Updated DoorLock Python scripts and DRLK_2_1 yaml. (#35182) * Updated DoorLock Python scripts and DRLK_2_1 yaml. * TC_DRLK_2_X.py - updated as per latest test plan * TC_BOOLCFG_3_1.py - Test description is changed. * TC_PWRTL_2_1.py - Added missing step for subset check as per latest test plan. * Test_TC_DRLK_2_1.yaml - Script is updated with latest changes from test plan. * Restyled by whitespace * Restyled by prettier-yaml * Restyled by autopep8 * Lint errors are fixed * ednpoint will be taken from command line args * Teardown function added for all scripts --------- Co-authored-by: Restyled.io --- .../certification/Test_TC_DRLK_2_1.yaml | 192 ++++++++---------- src/python_testing/TC_BOOLCFG_3_1.py | 2 +- src/python_testing/TC_DRLK_2_12.py | 7 +- src/python_testing/TC_DRLK_2_13.py | 4 +- src/python_testing/TC_DRLK_2_2.py | 7 +- src/python_testing/TC_DRLK_2_3.py | 7 +- src/python_testing/TC_PWRTL_2_1.py | 19 +- src/python_testing/drlk_2_x_common.py | 178 +++++++++------- 8 files changed, 223 insertions(+), 193 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml index 38465c434078bb..8954d44a658d97 100755 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml @@ -35,8 +35,35 @@ tests: - name: "nodeId" value: nodeId - - label: "Precondition: Create new user" - PICS: DRLK.S.F00 && DRLK.S.F07 + - label: "Step 1a: TH reads LockState attribute from DUT" + PICS: DRLK.S.A0000 + command: "readAttribute" + attribute: "LockState" + response: + saveAs: LockStateValue + constraints: + type: enum8 + minValue: 0 + maxValue: 3 + + - label: "Step 1b: TH writes LockState attribute as 1" + PICS: DRLK.S.A0000 + command: "writeAttribute" + attribute: "LockState" + arguments: + value: 1 + response: + error: UNSUPPORTED_WRITE + + - label: "Step 1c: TH reads LockState attribute from DUT" + PICS: DRLK.S.A0000 + command: "readAttribute" + attribute: "LockState" + response: + value: LockStateValue + + - label: "Step 1d: TH sends SetUser Command to DUT" + PICS: DRLK.S.F08 && DRLK.S.C1a.Rsp command: "SetUser" timedInteractionTimeoutMs: 1000 arguments: @@ -56,38 +83,34 @@ tests: - name: "CredentialRule" value: 0 - - label: "Precondition: Read the user back and verify its fields" - PICS: DRLK.S.F00 && DRLK.S.F07 - command: "GetUser" - arguments: - values: - - name: "UserIndex" - value: 1 + - label: + "Step 1e: TH reads MinPINCodeLength attribute and saves the value as + min_pin_code_length" + PICS: DRLK.S.F08 && DRLK.S.F00 + command: "readAttribute" + attribute: "MinPINCodeLength" response: - values: - - name: "UserIndex" - value: 1 - - name: "UserName" - value: "xxx" - - name: "UserUniqueID" - value: 6452 - - name: "UserStatus" - value: 1 - - name: "UserType" - value: 0 - - name: "CredentialRule" - value: 0 - - name: "Credentials" - value: [] - - name: "CreatorFabricIndex" - value: 1 - - name: "LastModifiedFabricIndex" - value: 1 - - name: "NextUserIndex" - value: null + saveAs: min_pin_code_length + constraints: + type: int8u + minValue: 0 + maxValue: 255 - - label: "Precondition: Create new PIN credential and lock/unlock user" - PICS: DRLK.S.F00 && DRLK.S.F07 + - label: + "Step 1f: TH reads MaxPINCodeLength attribute and saves the value as + max_pin_code_length" + PICS: DRLK.S.F08 && DRLK.S.F00 + command: "readAttribute" + attribute: "MaxPINCodeLength" + response: + saveAs: max_pin_code_length + constraints: + type: int8u + minValue: 0 + maxValue: 255 + + - label: "Step 1g: TH sends SetCredential Command" + PICS: DRLK.S.F00 && DRLK.S.F08 && DRLK.S.C22.Rsp && DRLK.S.C23.Tx command: "SetCredential" timedInteractionTimeoutMs: 1000 arguments: @@ -104,64 +127,9 @@ tests: value: null - name: "UserType" value: null - response: - values: - - name: "Status" - value: 0 - - name: "UserIndex" - value: null - - name: "NextCredentialIndex" - value: 2 - - - label: "Precondition: Verify created PIN credential" - PICS: DRLK.S.F00 && DRLK.S.F07 - command: "GetCredentialStatus" - arguments: - values: - - name: "Credential" - value: { CredentialType: 1, CredentialIndex: 1 } - response: - values: - - name: "CredentialExists" - value: true - - name: "UserIndex" - value: 1 - - name: "CreatorFabricIndex" - value: 1 - - name: "LastModifiedFabricIndex" - value: 1 - - name: "NextCredentialIndex" - value: null - - - label: "Step 1a: TH reads LockState attribute from DUT" - PICS: DRLK.S.A0000 - command: "readAttribute" - attribute: "LockState" - response: - saveAs: LockStateValue - constraints: - type: enum8 - minValue: 0 - maxValue: 3 - - - label: "Step 1b: TH writes LockState attribute as 1" - PICS: DRLK.S.A0000 - command: "writeAttribute" - attribute: "LockState" - arguments: - value: 1 - response: - error: UNSUPPORTED_WRITE - - - label: "Step 1c: TH reads LockState attribute from DUT" - PICS: DRLK.S.A0000 - command: "readAttribute" - attribute: "LockState" - response: - value: LockStateValue - label: - "Step 1d: TH sends a Lock Door command to the DUT. If DRLK.S.F00(PIN) + "Step 1h: TH sends a Lock Door command to the DUT. If DRLK.S.F00(PIN) & DRLK.S.F07(COTA), include a Valid PINCode in the Lock Door command." PICS: DRLK.S.C00.Rsp && DRLK.S.F00 && DRLK.S.F07 && DRLK.S.A0000 command: "LockDoor" @@ -171,7 +139,8 @@ tests: - name: "PINCode" value: "123456" - - label: "Step 1d: TH sends a Lock Door command to the DUT." + - label: + "Step 1h: TH sends a Lock Door command to the DUT without pin_code." PICS: DRLK.S.C00.Rsp && !DRLK.S.F00 && !DRLK.S.F07 && DRLK.S.A0000 command: "LockDoor" timedInteractionTimeoutMs: 1000 @@ -184,23 +153,16 @@ tests: values: - name: "ms" value: WaitAfterLockAandUnlockDoor - - - label: "Step 1d: TH reads LockState attribute from DUT" + - label: "Step 1h: TH reads LockState attribute from DUT" PICS: DRLK.S.A0000 command: "readAttribute" attribute: "LockState" response: value: 1 - - label: - "Step 1e: TH sends a Unlock Door command to the DUT. If + "Step 1i: TH sends a Unlock Door command to the DUT. If DRLK.S.F00(PIN) & DRLK.S.F07(COTA), include a Valid PINCode in the Unlock Door command" - PICS: DRLK.S.C01.Rsp && !DRLK.S.F00 && !DRLK.S.F07 && DRLK.S.A0000 - command: "UnlockDoor" - timedInteractionTimeoutMs: 1000 - - - label: "Step 1e: TH sends a Unlock Door command to the DUT." PICS: DRLK.S.C01.Rsp && DRLK.S.F00 && DRLK.S.F07 && DRLK.S.A0000 command: "UnlockDoor" timedInteractionTimeoutMs: 1000 @@ -209,6 +171,12 @@ tests: - name: "PINCode" value: "123456" + - label: + "Step 1i: TH sends a Unlock Door command to the DUT without pincode." + PICS: DRLK.S.C01.Rsp && !DRLK.S.F00 && !DRLK.S.F07 && DRLK.S.A0000 + command: "UnlockDoor" + timedInteractionTimeoutMs: 1000 + - label: "Wait after Unlock Door" PICS: DRLK.S.C00.Rsp cluster: "DelayCommands" @@ -218,14 +186,14 @@ tests: - name: "ms" value: WaitAfterLockAandUnlockDoor - - label: "Step 1e: TH reads LockState attribute from DUT" + - label: "Step 1i: TH reads LockState attribute from DUT" PICS: DRLK.S.A0000 command: "readAttribute" attribute: "LockState" response: value: 2 - - label: "Step 1f: Simulate a not fully locked scenario on the DUT." + - label: "Step 1j: Simulate a not fully locked scenario on the DUT." PICS: DRLK.S.A0000 && DRLK.S.M.SimulateNotFullyLocked && PICS_SKIP_SAMPLE_APP @@ -1366,6 +1334,26 @@ tests: response: value: Current_WrongCode_EntryLimit + - label: "Step 31b: TH writes WrongCodeEntryLimit attribute as 8" + PICS: + " ( DRLK.S.F00 || DRLK.S.F01 ) && DRLK.S.A0030 && + DRLK.S.M.WrongCodeEntryLimitAttributeWritable " + command: "writeAttribute" + attribute: "WrongCodeEntryLimit" + arguments: + value: 8 + + - label: "Step 31b: TH writes WrongCodeEntryLimit attribute as 8" + PICS: + " ( DRLK.S.F00 || DRLK.S.F01 ) && DRLK.S.A0030 && + !DRLK.S.M.WrongCodeEntryLimitAttributeWritable " + command: "writeAttribute" + attribute: "WrongCodeEntryLimit" + arguments: + value: 8 + response: + error: UNSUPPORTED_WRITE + - label: "Step 32a: TH reads UserCodeTemporary DisableTime attribute from DUT TH saves the values as Current_UserCode TemporaryDisableTime" @@ -1552,7 +1540,7 @@ tests: value: NumberOfCredentialsSupportedPerUserValue - label: "Step 36: TH sends ClearCredential Command to DUT" - PICS: DRLK.S.F00 && DRLK.S.F07 && DRLK.S.C26.Rsp + PICS: DRLK.S.F00 && DRLK.S.F08 && DRLK.S.C26.Rsp command: "ClearCredential" timedInteractionTimeoutMs: 1000 arguments: @@ -1562,7 +1550,7 @@ tests: - label: "Step 37: TH sends ClearUser Command to DUT with the UserIndex as 1" - PICS: DRLK.S.F07 && DRLK.S.C1d.Rsp + PICS: DRLK.S.F08 && DRLK.S.C1d.Rsp command: "ClearUser" timedInteractionTimeoutMs: 1000 arguments: diff --git a/src/python_testing/TC_BOOLCFG_3_1.py b/src/python_testing/TC_BOOLCFG_3_1.py index 8e42140b35424c..7446afd4b49715 100644 --- a/src/python_testing/TC_BOOLCFG_3_1.py +++ b/src/python_testing/TC_BOOLCFG_3_1.py @@ -45,7 +45,7 @@ def steps_TC_BOOLCFG_3_1(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), TestStep("2a", "Read FeatureMap attribute"), - TestStep("2b", "Verify SENS feature is supported"), + TestStep("2b", "Verify SENSLVL feature is supported"), TestStep("2c", "Read AttributeList attribute"), TestStep(3, "Read SupportedSensitivityLevels attribute"), TestStep(4, "Read DefaultSensitivityLevel attribute, if supported"), diff --git a/src/python_testing/TC_DRLK_2_12.py b/src/python_testing/TC_DRLK_2_12.py index 4578aa01cd2ba0..3321ea303bf3f3 100644 --- a/src/python_testing/TC_DRLK_2_12.py +++ b/src/python_testing/TC_DRLK_2_12.py @@ -31,6 +31,8 @@ from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main # Configurable parameters: +# - userIndex: userIndex to use when creating a user on the DUT for testing purposes +# defaults to 1. Add `--int-arg user_index:` to command line to override # - CredentialIndex: CredentialIndex to use when creating a Credential on the DUT for testing purposes # defaults to 1. Add `--int-arg credential_index:` to command line to override # - UserCodeTemporaryDisableTime: Value used to configure DUT for testing purposes. @@ -42,14 +44,15 @@ class TC_DRLK_2_12(MatterBaseTest, DRLK_COMMON): - def setup_class(self): - return super().setup_class() @async_test_body async def teardown_test(self): await self.teardown() return super().teardown_test() + def setup_class(self): + return super().setup_class() + def pics_TC_DRLK_2_12(self) -> list[str]: return ["DRLK.S.F0c"] diff --git a/src/python_testing/TC_DRLK_2_13.py b/src/python_testing/TC_DRLK_2_13.py index 5e1cdf6dcf6601..78f6ef0a0cae68 100644 --- a/src/python_testing/TC_DRLK_2_13.py +++ b/src/python_testing/TC_DRLK_2_13.py @@ -23,7 +23,7 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === import logging @@ -357,7 +357,7 @@ async def test_TC_DRLK_2_13(self): self.groupIdentifier = bytes.fromhex("89d085fc302ca53e279bfcdecdf3c4ad") self.groupResolvingKey = bytes.fromhex("89d0859bfcdecdf3c4adfc302ca53e27") self.common_cluster_endpoint = 0 - self.app_cluster_endpoint = 1 + self.app_cluster_endpoint = self.matter_test_config.endpoint self.alirouser = "AliroUser" self.alirocredentialissuerkey = bytes.fromhex( "047a4c882d753924cdf3779a3c84fec2debaa6f0b3084450878acc7ddcce7856ae57b1ebbe2561015103dd7474c2a183675378ec55f1e465ac3436bf3dd5ca54d4") diff --git a/src/python_testing/TC_DRLK_2_2.py b/src/python_testing/TC_DRLK_2_2.py index e7f3e6fa8e421e..9a04e9d5fd1904 100644 --- a/src/python_testing/TC_DRLK_2_2.py +++ b/src/python_testing/TC_DRLK_2_2.py @@ -31,6 +31,8 @@ from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main # Configurable parameters: +# - userIndex: userIndex to use when creating a user on the DUT for testing purposes +# defaults to 1. Add `--int-arg user_index:` to command line to override # - CredentialIndex: CredentialIndex to use when creating a Credential on the DUT for testing purposes # defaults to 1. Add `--int-arg credential_index:` to command line to override # - UserCodeTemporaryDisableTime: Value used to configure DUT for testing purposes. @@ -42,14 +44,15 @@ class TC_DRLK_2_2(MatterBaseTest, DRLK_COMMON): - def setup_class(self): - return super().setup_class() @async_test_body async def teardown_test(self): await self.teardown() return super().teardown_test() + def setup_class(self): + return super().setup_class() + def pics_TC_DRLK_2_2(self) -> list[str]: return ["DRLK.S"] diff --git a/src/python_testing/TC_DRLK_2_3.py b/src/python_testing/TC_DRLK_2_3.py index 8c6f40f19c5449..3171ed28b4f9ad 100644 --- a/src/python_testing/TC_DRLK_2_3.py +++ b/src/python_testing/TC_DRLK_2_3.py @@ -31,6 +31,8 @@ from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main # Configurable parameters: +# - userIndex: userIndex to use when creating a user on the DUT for testing purposes +# defaults to 1. Add `--int-arg user_index:` to command line to override # - CredentialIndex: CredentialIndex to use when creating a Credential on the DUT for testing purposes # defaults to 1. Add `--int-arg credential_index:` to command line to override # - UserCodeTemporaryDisableTime: Value used to configure DUT for testing purposes. @@ -42,14 +44,15 @@ class TC_DRLK_2_3(MatterBaseTest, DRLK_COMMON): - def setup_class(self): - return super().setup_class() @async_test_body async def teardown_test(self): await self.teardown() return super().teardown_test() + def setup_class(self): + return super().setup_class() + def pics_TC_DRLK_2_3(self) -> list[str]: return ["DRLK.S"] diff --git a/src/python_testing/TC_PWRTL_2_1.py b/src/python_testing/TC_PWRTL_2_1.py index 7216031a9374f4..579398642a5320 100644 --- a/src/python_testing/TC_PWRTL_2_1.py +++ b/src/python_testing/TC_PWRTL_2_1.py @@ -30,7 +30,6 @@ import logging import chip.clusters as Clusters -from chip.clusters.Types import NullValue from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts @@ -56,13 +55,8 @@ async def test_TC_PWRTL_2_1(self): self.print_step(2, "Read AvailableAttributes attribute") available_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.AvailableEndpoints) - if available_endpoints == NullValue: - logging.info("AvailableEndpoints is null") - else: - logging.info("AvailableEndpoints: %s" % (available_endpoints)) - - asserts.assert_less_equal(len(available_endpoints), 21, - "AvailableEndpoints length %d must be less than 21!" % len(available_endpoints)) + asserts.assert_less_equal(len(available_endpoints), 20, + "AvailableEndpoints length %d must be less than 21!" % len(available_endpoints)) if not self.check_pics("PWRTL.S.A0001"): logging.info("Test skipped because PICS PWRTL.S.A0001 is not set") @@ -71,10 +65,11 @@ async def test_TC_PWRTL_2_1(self): self.print_step(3, "Read ActiveEndpoints attribute") active_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.ActiveEndpoints) logging.info("ActiveEndpoints: %s" % (active_endpoints)) - - if available_endpoints == NullValue: - asserts.assert_true(active_endpoints == NullValue, - "ActiveEndpoints should be null when AvailableEndpoints is null: %s" % active_endpoints) + asserts.assert_less_equal(len(active_endpoints), 20, + "ActiveEndpoints length %d must be less than 21!" % len(active_endpoints)) + # Verify that ActiveEndpoints is a subset of AvailableEndpoints + asserts.assert_true(set(active_endpoints).issubset(set(available_endpoints)), + "ActiveEndpoints should be a subset of AvailableEndpoints") if __name__ == "__main__": diff --git a/src/python_testing/drlk_2_x_common.py b/src/python_testing/drlk_2_x_common.py index a8368c5cc96507..c25365bf993d8f 100644 --- a/src/python_testing/drlk_2_x_common.py +++ b/src/python_testing/drlk_2_x_common.py @@ -73,33 +73,60 @@ async def send_clear_credential_cmd(self, credential) -> None: await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.ClearCredential(credential=credential), endpoint=self.endpoint, timedRequestTimeoutMs=1000) - ret = await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.GetCredentialStatus(credential=self.createdCredential), + ret = await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.GetCredentialStatus(credential=credential), endpoint=self.endpoint) asserts.assert_true(type_matches(ret, Clusters.Objects.DoorLock.Commands.GetCredentialStatusResponse), "Unexpected return type for GetCredentialStatus") asserts.assert_false(ret.credentialExists, "Error clearing Credential (credentialExists==True)") - async def cleanup_users_and_credentials(self): - self.print_step("Cleanup", "Clear created User and Credential on the DUT") - if self.createdCredential: - await self.send_clear_credential_cmd(self.createdCredential) - logging.info("Credential cleared at CredentialIndex %d" % (self.createdCredential.credentialIndex)) - self.createdCredential = None - - async def generate_pincode(self, maxPincodeLength): - return ''.join(random.choices(string.digits, k=maxPincodeLength)) + async def cleanup_users_and_credentials(self, user_clear_step, clear_credential_step, credentials, userIndex): + if (self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F08") + and self.check_pics("DRLK.S.C26.Rsp")): + if clear_credential_step: + self.print_step(clear_credential_step, "TH sends ClearCredential Command to DUT") + await self.send_clear_credential_cmd(credentials) + if self.check_pics("DRLK.S.C1d.Rsp") and self.check_pics("DRLK.S.F08"): + if user_clear_step: + self.print_step(user_clear_step, "TH sends ClearUser Command to DUT with the UserIndex as 1") + await self.send_drlk_cmd_expect_success( + command=Clusters.Objects.DoorLock.Commands.ClearUser(userIndex=userIndex)) + self.clear_credential_and_user_flag = False + + async def set_user_command(self): + await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.SetUser( + operationType=Clusters.DoorLock.Enums.DataOperationTypeEnum.kAdd, + userIndex=self.user_index, + userName="xxx", + userUniqueID=6452, + userStatus=Clusters.DoorLock.Enums.UserStatusEnum.kOccupiedEnabled, + credentialRule=Clusters.DoorLock.Enums.CredentialRuleEnum.kSingle + ), + endpoint=self.endpoint, + timedRequestTimeoutMs=1000 + ) + + async def read_and_verify_pincode_length(self, attribute, failure_message: str, min_range=0, max_range=255): + pin_code_length = await self.read_drlk_attribute_expect_success(attribute=attribute) + verify_pin_code_length = True if min_range <= pin_code_length <= max_range else False + asserts.assert_true(verify_pin_code_length, f"{failure_message}, got value {pin_code_length}") + return pin_code_length + + async def generate_pincode(self, maxPincodeLength, minPincodeLength): + length_of_pincode = random.randint(minPincodeLength, maxPincodeLength) + return ''.join(random.choices(string.digits, k=length_of_pincode)) async def teardown(self): - await self.cleanup_users_and_credentials() + if self.clear_credential_and_user_flag: + await self.cleanup_users_and_credentials(user_clear_step=None, clear_credential_step=None, + credentials=self.createdCredential, userIndex=self.user_index) async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lockUnlockText, doAutoRelockTest): is_ci = self.check_pics('PICS_SDK_CI_ONLY') - - self.createdCredential = None - - self.endpoint = self.user_params.get("endpoint", 1) + self.clear_credential_and_user_flag = True # Allow for user overrides of these values + self.user_index = self.user_params.get("user_index", 1) + self.endpoint = self.user_params.get("endpoint", 1) credentialIndex = self.user_params.get("credential_index", 1) userCodeTemporaryDisableTime = self.user_params.get("user_code_temporary_disable_time", 15) wrongCodeEntryLimit = self.user_params.get("wrong_code_entry_limit", 3) @@ -110,40 +137,12 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo cluster = Clusters.Objects.DoorLock attributes = Clusters.DoorLock.Attributes - validPincode = None + pin_code = None invalidPincode = None - + credential = cluster.Structs.CredentialStruct(credentialIndex=credentialIndex, + credentialType=Clusters.DoorLock.Enums.CredentialTypeEnum.kPin) + self.createdCredential = credential self.print_step(0, "Commissioning, already done") - - if self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F07"): - self.print_step("Preconditions.1a", - "TH reads MaxPINCodeLength attribute from DUT and generates a valid PINCode") - maxPincodeLength_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.MaxPINCodeLength) - logging.info("MaxPINCodeLength value is %s" % (maxPincodeLength_dut)) - - validPincodeString = await self.generate_pincode(maxPincodeLength_dut) - while True: - invalidPincodeString = await self.generate_pincode(maxPincodeLength_dut) - if invalidPincodeString != validPincodeString: - break - logging.info("Valid PinCode=%s, Invalid PinCode=%s" % (validPincodeString, invalidPincodeString)) - - validPincode = bytes(validPincodeString, 'ascii') - invalidPincode = bytes(invalidPincodeString, 'ascii') - - self.print_step("Preconditions.1b", - "TH sends SetCredential command to DUT to set up User and Credential at CredentialIndex {}".format(str(credentialIndex))) - credential = cluster.Structs.CredentialStruct(credentialIndex=credentialIndex, - credentialType=Clusters.DoorLock.Enums.CredentialTypeEnum.kPin) - ret = await self.send_set_credential_cmd(Clusters.DoorLock.Enums.DataOperationTypeEnum.kAdd, - credential, - validPincode, - NullValue, - NullValue, - NullValue) - logging.info("Credential created at CredentialIndex %d, UserIndex %d." % (credentialIndex, ret.userIndex)) - self.createdCredential = credential - requirePinForRemoteOperation_dut = False if self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F07"): self.print_step("1", "TH writes the RequirePINforRemoteOperation attribute value as false on the DUT") @@ -174,13 +173,44 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo await self.send_drlk_cmd_expect_error(command=command, error=Status.Failure) else: await self.send_drlk_cmd_expect_success(command=command) - - self.print_step("4", "TH sends %s Command to the DUT with valid PINCode" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) - await self.send_drlk_cmd_expect_success(command=command) else: asserts.assert_true(False, "%sResponse is a mandatory command response and must be supported in PICS" % lockUnlockText) + if self.check_pics("DRLK.S.F08"): + if self.check_pics("DRLK.S.C1a.Rsp"): + self.print_step("4a", "TH writes the RequirePINforRemoteOperation attribute value as true on the DUT") + await self.set_user_command() + if self.check_pics("DRLK.S.F00"): + self.print_step("4b", "TH reads MinPINCodeLength attribute and saves the value") + min_pin_code_length = await self.read_and_verify_pincode_length( + attribute=Clusters.DoorLock.Attributes.MinPINCodeLength, + failure_message="MinPINCodeLength attribute must be between 0 to 255" + ) + self.print_step("4c", "TH reads MaxPINCodeLength attribute and saves the value") + max_pin_code_length = await self.read_and_verify_pincode_length( + attribute=Clusters.DoorLock.Attributes.MaxPINCodeLength, + failure_message="MinPINCodeLength attribute must be between 0 to 255" + ) + self.print_step("4d", "Generate credential data and store as pin_code,Th sends SetCredential command" + "using pin_code") + credential_data_generated = await self.generate_pincode(max_pin_code_length, min_pin_code_length) + pin_code = bytes(credential_data_generated, "ascii") + if self.check_pics("DRLK.S.C22.Rsp") and self.check_pics("DRLK.S.C23.Tx"): + set_cred_response = await self.send_set_credential_cmd(userIndex=self.user_index, + operationType=Clusters.DoorLock.Enums.DataOperationTypeEnum.kAdd, + credential=credential, + credentialData=pin_code, + userStatus=NullValue, + userType=NullValue + ) + asserts.assert_true( + type_matches(set_cred_response, Clusters.Objects.DoorLock.Commands.SetCredentialResponse), + "Unexpected return type for SetCredential") + self.print_step("4e", f"TH sends {lockUnlockText} Command to the DUT with PINCode as pin_code.") + if self.check_pics(lockUnlockCmdRspPICS): + command = lockUnlockCommand(PINCode=pin_code) + await self.send_drlk_cmd_expect_success(command=command) + if self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F07"): self.print_step("5", "TH writes the RequirePINforRemoteOperation attribute value as true on the DUT") attribute = attributes.RequirePINforRemoteOperation(True) @@ -197,7 +227,13 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if self.check_pics("DRLK.S.M.RequirePINForRemoteOperationAttributeWritable"): self.print_step("6a", "TH verifies that RequirePINforRemoteOperation is TRUE") asserts.assert_true(requirePinForRemoteOperation_dut, "RequirePINforRemoteOperation is expected to be TRUE") - + # generate InvalidPincode + while True: + invalidPincodeString = await self.generate_pincode(max_pin_code_length, min_pin_code_length) + invalidPincode = bytes(invalidPincodeString, "ascii") + if invalidPincodeString != pin_code: + break + logging.info(" pin_code=%s, Invalid PinCode=%s" % (pin_code, invalidPincodeString)) if self.check_pics("DRLK.S.F00") and self.check_pics(lockUnlockCmdRspPICS) and self.check_pics("DRLK.S.A0033"): self.print_step("7", "TH sends %s Command to the DUT with an invalid PINCode" % lockUnlockText) command = lockUnlockCommand(PINCode=invalidPincode) @@ -212,7 +248,7 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if self.check_pics(lockUnlockCmdRspPICS) and self.check_pics("DRLK.S.A0033"): self.print_step("9", "TH sends %s Command to the DUT with valid PINCode" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_success(command=command) if self.check_pics("DRLK.S.F00") or self.check_pics("DRLK.S.F01"): @@ -248,7 +284,7 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo await self.send_drlk_cmd_expect_error(command=command, error=Status.Failure) self.print_step("13", "TH sends %s Command to the DUT with valid PINCode. Verify failure or no response" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_error(command=command, error=Status.Failure) if self.check_pics("DRLK.S.A0031"): @@ -257,9 +293,14 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if not doAutoRelockTest: self.print_step("15", "Send %s with valid Pincode and verify success" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + credentials = cluster.Structs.CredentialStruct(credentialIndex=credentialIndex, + credentialType=Clusters.DoorLock.Enums.CredentialTypeEnum.kPin) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_success(command=command) + await self.cleanup_users_and_credentials(user_clear_step="17", clear_credential_step="16", + credentials=credentials, userIndex=self.user_index) + if doAutoRelockTest: if self.check_pics("DRLK.S.A0023"): self.print_step("15", "TH writes the AutoRelockTime attribute value on the DUT") @@ -275,22 +316,19 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if self.check_pics(lockUnlockCmdRspPICS): self.print_step("17", "Send %s with valid Pincode and verify success" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_success(command=command) - - if self.check_pics("DRLK.S.A0023"): - self.print_step("18a", "Wait for AutoRelockTime seconds") - # Add additional wait time buffer for motor movement, etc. - time.sleep(autoRelockTime_dut + 5) - - if self.check_pics("DRLK.S.A0000"): - self.print_step("18b", "TH reads LockState attribute after AutoRelockTime Expires") - lockstate_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.LockState) - logging.info("Current LockState is %s" % (lockstate_dut)) - asserts.assert_equal(lockstate_dut, Clusters.DoorLock.Enums.DlLockState.kLocked, - "LockState expected to be value==Locked") - - await self.cleanup_users_and_credentials() + # Add additional wait time buffer for motor movement, etc. + time.sleep(autoRelockTime_dut + 5) + + if self.check_pics("DRLK.S.A0000"): + self.print_step("18", "TH reads LockState attribute after AutoRelockTime Expires") + lockstate_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.LockState) + logging.info("Current LockState is %s" % (lockstate_dut)) + asserts.assert_equal(lockstate_dut, Clusters.DoorLock.Enums.DlLockState.kLocked, + "LockState expected to be value==Locked") + await self.cleanup_users_and_credentials(user_clear_step="20", clear_credential_step="19", + credentials=credential, userIndex=1) async def run_drlk_test_2_2(self): await self.run_drlk_test_common(lockUnlockCommand=Clusters.Objects.DoorLock.Commands.LockDoor,