Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TC-OPCREDS-3.4: Automate #33541

Merged
merged 26 commits into from
Nov 25, 2024
Merged
Changes from 16 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
65c76cf
chore(TC_OPCREDS_3.4): skeleton class
gvargas-csa May 22, 2024
64c0cdf
Merge branch 'master' into TC_OPCREDS_3_4
gvargas-csa Jun 5, 2024
440adc1
chore(TC_OPCREDS_3.4): implementation until step CSRRequest IsForUpda…
gvargas-csa Jul 10, 2024
c74e99b
chore(TC_OPCREDS_3.4): All test step are implement using the old way …
gvargas-csa Jul 15, 2024
5c4222b
chore(TC_OPCREDS_3.4): patch from restyled code
gvargas-csa Jul 15, 2024
3987fab
chore(TC_OPCREDS_3.4): restyled by autopep8
gvargas-csa Jul 15, 2024
a371c56
chore(TC_OPCREDS_3.4): fix code-lints
gvargas-csa Jul 16, 2024
ee0e41c
Merge branch 'master' into HEAD
gvargas-csa Aug 12, 2024
c4f4ae6
chore(TC_OPCREDS_3.4): add suggestions
gvargas-csa Aug 20, 2024
1f25d31
chore(TC_OPCREDS_3.4): steps _method instead print each step and add …
gvargas-csa Oct 10, 2024
458d42b
chore(TC_OPCREDS_3.4): fix restyled
gvargas-csa Oct 10, 2024
2d8d3a3
chore(TC_OPCREDS_3.4): fix re-implementation validate single entry certs
gvargas-csa Oct 22, 2024
36a1fae
chore(TC_OPCREDS_3.4): fix resyled
gvargas-csa Oct 22, 2024
334314a
chore(TC_OPCREDS_3.4): reverting commissioningBuilingBlocks without i…
gvargas-csa Oct 22, 2024
3749d16
Merge branch 'master' into HEAD
gvargas-csa Oct 22, 2024
9b14683
chore(TC_OPCREDS_3.4): fix matter_testing_support ModuleNotError
gvargas-csa Oct 22, 2024
92a29c7
chore(TC_OPCREDS_3.4): added and replaced some outcomes/methods for T…
gvargas-csa Nov 14, 2024
edf05c7
chore(TC_OPCREDS_3.4): fix restyled
gvargas-csa Nov 14, 2024
99a6829
chore(TC_OPCREDS_3.4): fix restyled
gvargas-csa Nov 14, 2024
5e35876
chore(TC_OPCREDS_3.4): added suggestions
gvargas-csa Nov 14, 2024
8fe7638
chore(TC_OPCREDS_3.4): added expected outcomes for some test step
gvargas-csa Nov 15, 2024
88f5426
chore(TC_OPCREDS_3.4): fix restyled
gvargas-csa Nov 15, 2024
a297071
chore(TC_OPCREDS_3.4): fix f-strings without any placeholder
gvargas-csa Nov 15, 2024
da59243
chore(TC_OPCREDS_3.4): implemented all expected outcomes for all steps
gvargas-csa Nov 15, 2024
96558a4
chore(TC_OPCREDS_3.4): fix restyled
gvargas-csa Nov 15, 2024
cd0c5c7
Update src/python_testing/TC_OPCREDS_3_4.py
gvargas-csa Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 254 additions & 0 deletions src/python_testing/TC_OPCREDS_3_4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
#
# Copyright (c) 2024 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments
# for details about the block below.
#
# === BEGIN CI TEST ARGUMENTS ===
# test-runner-runs: run1
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
# test-runner-run/run1/app: ${TYPE_OF_APP}
# 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 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
# === END CI TEST ARGUMENTS ===

import random

import chip.clusters as Clusters
from chip.interaction_model import InteractionModelError, Status
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from mobly import asserts


class TC_OPCREDS_3_4(MatterBaseTest):
def desc_TC_OPCREDS_3_4(self):
return " UpdateNOC-Error Condition [DUT-Server]"

gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
def steps_TC_OPCREDS_3_4(self):
return [TestStep(0, "Preconditions"),
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
TestStep(1, "TH1 fully commissions the DUT"),
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
TestStep(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read"),
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
TestStep(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster"),
TestStep(
4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"),
TestStep(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900"),
TestStep(
6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"),
TestStep(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false"),
TestStep(8, "TH1 generates a new NOC chain with ICAC with the following properties"),
TestStep(9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"),
TestStep(10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true"),
TestStep(11, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"),
TestStep(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root"),
TestStep(13, "TH1 generates a new NOC and ICAC"),
TestStep(14, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"),
TestStep(15, "TH1 generates a new NOC and ICAC"),
TestStep(16, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"),
TestStep(17, "TH1 generates a new NOC and ICAC"),
TestStep(18, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"),
TestStep(19, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to new_root_cert"),
TestStep(20, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"),
TestStep(21, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 0"),
TestStep(22, "TH1 sends an OpenCommissioningWindow command to the DUT"),
TestStep(23, "TH1 connects to the DUT over PASE and sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection."),
TestStep(24, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true"),
TestStep(25, "TH1 generates a new NOC chain with ICAC with the following properties: new NOC and ICAC using icac_pase"),
TestStep(26, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster over PASE")]

@async_test_body
async def test_TC_OPCREDS_3_4(self):
self.step(0)
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved

self.step(1)
opcreds = Clusters.OperationalCredentials

self.step(2)
cecille marked this conversation as resolved.
Show resolved Hide resolved
nocs = await self.read_single_attribute_check_success(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=True)
if nocs[0].noc:
noc_original = nocs[0].noc
else:
asserts.assert_true(False, "Unexpected fail reading NOC Value on NOCs response")
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved

if nocs[0].icac:
icac_original = nocs[0].icac
else:
asserts.assert_true(False, "Unexpected fail reading ICAC Value on NOCs response")

self.step(3)
trusted_root_list_original = await self.read_single_attribute_check_success(
dev_ctrl=self.default_controller,
node_id=self.dut_node_id, cluster=opcreds,
attribute=opcreds.Attributes.TrustedRootCertificates)
asserts.assert_equal(len(trusted_root_list_original), 1,
"Unexpected number of entries in the TrustedRootCertificates table")

self.step(4)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original)
try:
await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.fail("Unexpected error sending UpdateNOC command")
except InteractionModelError as e:
asserts.assert_equal(e.status, Status.FailsafeRequired, "Unexpected Failsafe status")

self.step(5)
cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
"Failure status returned from arm failsafe")

self.step(6)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr,
"Failure status returned from UpdateNOC")

self.step(7)
cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=False)
csr_not_updated = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved

self.step(8)
new_noc_chain = await self.default_controller.IssueNOCChain(csr_not_updated, self.dut_node_id)
noc_not_for_update = new_noc_chain.nocBytes
icac_not_for_update = new_noc_chain.icacBytes

self.step(9)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_not_for_update, ICACValue=icac_not_for_update)
try:
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.fail("Unexpected error sending UpdateNOC command")
except InteractionModelError as e:
asserts.assert_equal(e.status, Status.ConstraintError, "Failure status returned from UpdateNOC")

cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0)
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
"Failure status returned from arm failsafe")

cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
"Failure status returned from arm failsafe")

self.step(10)
cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=True)
csr_update = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)

self.step(11)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidPublicKey,
"Unexpected error code on AddNOC with mismatched CSR")

self.step(12)
th1_ca_new = self.certificate_authority_manager.NewCertificateAuthority()
th1_fabric_admin_new = th1_ca_new.NewFabricAdmin(vendorId=0xFFF1, fabricId=1)
cecille marked this conversation as resolved.
Show resolved Hide resolved
th1_new = th1_fabric_admin_new.NewController(nodeId=self.default_controller.nodeId+1)

self.step(13)
th1_certs_new = await th1_new.IssueNOCChain(csr_update, self.dut_node_id+1)
new_root_cert = th1_certs_new.rcacBytes
noc_update_new_root = th1_certs_new.nocBytes
icac_update_new_root = th1_certs_new.icacBytes

self.step(14)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC,
"NOCResponse with the StatusCode InvalidNOC")

self.step(15)
cmd = opcreds
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
# new NOC is generated from the NOCSR returned in csr_update with the matter-fabric-id set to a different
# value than noc_original. The NOC is signed by new ICA. Save as noc_update_bad_fabric_on_noc.
noc_update_bad_fabric_on_noc = th1_certs_new.nocBytes
# new ICAC is generated with the and matter-fabric-id omitted. ICAC is signed by the original key for
# trusted_root_original. Save as icac_update_bad_fabric_on_noc
icac_update_bad_fabric_on_noc = new_noc_chain.icacBytes

self.step(16)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_noc, ICACValue=icac_update_bad_fabric_on_noc)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC,
"NOCResponse with the StatusCode InvalidNOC")

self.step(17)
noc_update_bad_fabric_on_icac = th1_certs_new.nocBytes
icac_update_bad_fabric_on_icac = new_noc_chain.icacBytes

self.step(18)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_icac, ICACValue=icac_update_bad_fabric_on_icac)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC,
"NOCResponse with the StatusCode InvalidNOC")

self.step(19)
cmd = opcreds.Commands.AddTrustedRootCertificate(new_root_cert)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)

self.step(20)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr,
"Failure status returned from UpdateNOC")

self.step(21)
cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
"Failure status returned from arm failsafe")

self.step(22)
resp = await self.openCommissioningWindow(self.default_controller, self.dut_node_id)

self.step(23)
# self.FindAndEstablishPase(dev_ctrl=th1_new_fabric_ctrl, longDiscriminator=resp.randomDiscriminator,
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
# setupPinCode=resp.commissioningParameters.setupPinCode, nodeid=th1_dut_node_id)
# setupCode = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code
await self.default_controller.FindOrEstablishPASESession(setupCode=resp.commissioningParameters.setupQRCode, nodeid=self.dut_node_id)

cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900)
resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
"Error code status returned from arm failsafe")

self.step(24)
cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32))
csr_pase = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)

self.step(25)
new_noc_chain = await self.default_controller.IssueNOCChain(csr_pase, self.dut_node_id)
# cmd = opcreds.Commands.AddTrustedRootCertificate(trusted_root_original)
gvargas-csa marked this conversation as resolved.
Show resolved Hide resolved
# try:
# await self.send_single_cmd(dev_ctrl=th1_new, node_id=self.default_controller.nodeId+1, cmd=cmd)
# asserts.fail("Success when adding trusted root certificate")
# except InteractionModelError as e:
# asserts.assert_equal(e.status, Status.ConstraintError, "Unexpected when adding trusted root certificate")
noc_pase = csr_pase.NOCSRElements
icac_pase = new_noc_chain.icacBytes

self.step(26)
cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_pase, ICACValue=icac_pase)
try:
await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd)
asserts.fail("Unexpected error sending UpdateNOC command")
except InteractionModelError as e:
asserts.assert_equal(e.status, Status.UnsupportedAccess, "Failure status returned from UpdateNOC")


if __name__ == "__main__":
default_matter_test_main()
Loading