Skip to content

Commit b641cdb

Browse files
Add jfds_2.1 and jfds_2.2 test cases (project-chip#39901)
* Add jfds_2.1 and jfds_2.2 test cases * Restyled by isort * Comment unused import until steps are available --------- Co-authored-by: Restyled.io <[email protected]>
1 parent a351c4f commit b641cdb

File tree

2 files changed

+479
-0
lines changed

2 files changed

+479
-0
lines changed

src/python_testing/TC_JFDS_2_1.py

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#
2+
# Copyright (c) 2024 Project CHIP Authors
3+
# All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
# This test requires a TH_SERVER application. Please specify with --string-arg th_server_app_path:<path_to_app>
19+
20+
# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments
21+
# for details about the block below.
22+
#
23+
# === BEGIN CI TEST ARGUMENTS ===
24+
# test-runner-runs:
25+
# run1:
26+
# script-args: >
27+
# --string-arg jfa_server_app:${JF_ADMIN_APP}
28+
# --string-arg jfc_server_app:${JF_CONTROL_APP}
29+
# --trace-to json:${TRACE_TEST_JSON}.json
30+
# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
31+
# factory-reset: true
32+
# quiet: true
33+
# === END CI TEST ARGUMENTS ===
34+
35+
import base64
36+
import logging
37+
import os
38+
import random
39+
import tempfile
40+
from configparser import ConfigParser
41+
42+
import chip.clusters as Clusters
43+
from chip import CertificateAuthority
44+
from chip.storage import PersistentStorage
45+
from chip.testing.apps import AppServerSubprocess, JFControllerSubprocess
46+
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
47+
from mobly import asserts
48+
49+
50+
class TC_JFDS_2_1(MatterBaseTest):
51+
52+
@async_test_body
53+
async def setup_class(self):
54+
super().setup_class()
55+
56+
self.fabric_a_ctrl = None
57+
self.storage_fabric_a = self.user_params.get("fabric_a_storage", None)
58+
self.fabric_a_server_app = None
59+
60+
jfc_server_app = self.user_params.get("jfc_server_app", None)
61+
if not jfc_server_app:
62+
asserts.fail("This test requires a Joint Fabric Controller app. Specify app path with --string-arg jfc_server_app:<path_to_app>")
63+
if not os.path.exists(jfc_server_app):
64+
asserts.fail(f"The path {jfc_server_app} does not exist")
65+
66+
jfa_server_app = self.user_params.get("jfa_server_app", None)
67+
if not jfa_server_app:
68+
asserts.fail("This test requires a Joint Fabrics Admin app. Specify app path with --string-arg jfa_server_app:<path_to_app>")
69+
if not os.path.exists(jfa_server_app):
70+
asserts.fail(f"The path {jfa_server_app} does not exist")
71+
72+
# Create a temporary storage directory for both ecosystems to keep KVS files if not already provided by user.
73+
if self.storage_fabric_a is None:
74+
self.storage_directory_ecosystem_a = tempfile.TemporaryDirectory(prefix=self.__class__.__name__+"_A_")
75+
self.storage_fabric_a = self.storage_directory_ecosystem_a.name
76+
logging.info("Temporary storage directory: %s", self.storage_fabric_a)
77+
78+
#####################################################################################################################################
79+
#
80+
# Initialize Ecosystem A
81+
#
82+
#####################################################################################################################################
83+
self.jfadmin_fabric_a_passcode = random.randint(110220011, 110220999)
84+
self.jfctrl_fabric_a_vid = random.randint(0x0001, 0xFFF0)
85+
86+
# Start Fabric A JF-Administrator App
87+
self.fabric_a_admin = AppServerSubprocess(
88+
jfa_server_app,
89+
storage_dir=self.storage_fabric_a,
90+
port=random.randint(5001, 5999),
91+
discriminator=random.randint(0, 4095),
92+
passcode=self.jfadmin_fabric_a_passcode,
93+
extra_args=["--capabilities", "0x04", "--rpc-server-port", "33033"])
94+
self.fabric_a_admin.start(
95+
expected_output="Server initialization complete",
96+
timeout=10)
97+
98+
# Start Fabric A JF-Controller App
99+
self.fabric_a_ctrl = JFControllerSubprocess(
100+
jfc_server_app,
101+
rpc_server_port=33033,
102+
storage_dir=self.storage_fabric_a,
103+
vendor_id=self.jfctrl_fabric_a_vid)
104+
self.fabric_a_ctrl.start(
105+
expected_output="CHIP task running",
106+
timeout=10)
107+
108+
# Commission JF-ADMIN app with JF-Controller on Fabric A
109+
self.fabric_a_ctrl.send(
110+
message=f"pairing onnetwork 1 {self.jfadmin_fabric_a_passcode} --anchor true",
111+
expected_output="[JF] Anchor Administrator commissioned with sucess")
112+
113+
# Extract the Ecosystem A certificates and inject them in the storage that will be provided to a new Python Controller later
114+
jfcStorage = ConfigParser()
115+
jfcStorage.read(self.storage_fabric_a+'/chip_tool_config.alpha.ini')
116+
self.ecoACtrlStorage = {
117+
"sdk-config": {
118+
"ExampleOpCredsCAKey1": jfcStorage.get("Default", "ExampleOpCredsCAKey0"),
119+
"ExampleOpCredsICAKey1": jfcStorage.get("Default", "ExampleOpCredsICAKey0"),
120+
"ExampleCARootCert1": jfcStorage.get("Default", "ExampleCARootCert0"),
121+
"ExampleCAIntermediateCert1": jfcStorage.get("Default", "ExampleCAIntermediateCert0"),
122+
},
123+
"repl-config": {
124+
"caList": {
125+
"1": [
126+
{
127+
"fabricId": 1,
128+
"vendorId": self.jfctrl_fabric_a_vid
129+
}
130+
]
131+
}
132+
}
133+
}
134+
# Extract CATs to be provided to the Python Controller later
135+
self.ecoACATs = base64.b64decode(jfcStorage.get("Default", "CommissionerCATs"))[::-1].hex().strip('0')
136+
137+
def teardown_class(self):
138+
# Stop all Subprocesses that were started in this test case
139+
if self.fabric_a_admin is not None:
140+
self.fabric_a_admin.terminate()
141+
if self.fabric_a_ctrl is not None:
142+
self.fabric_a_ctrl.terminate()
143+
if self.fabric_a_server_app is not None:
144+
self.fabric_a_server_app.terminate()
145+
146+
super().teardown_class()
147+
148+
def steps_TC_JFDS_2_1(self) -> list[TestStep]:
149+
return [
150+
TestStep("1", "TH reads AnchorRootCA attribute from DUT",
151+
"Verify that a RootCA is returned"),
152+
TestStep("2", "TH reads AnchorNodeID attribute from DUT",
153+
"Verify that the DUT NodeId is returned"),
154+
TestStep("3", "TH reads AnchorVendorID attribute from DUT",
155+
"Verify that the VendorId of the DUT is returned")
156+
# TestStep("4", "{PLACEHOLDER_NOT_IMPLEMENTED]TH reads FriendlyName from DUT",
157+
# "Verify that the a valid string is returned")
158+
]
159+
160+
@async_test_body
161+
async def test_TC_JFDS_2_1(self):
162+
# Creating a Controller for Ecosystem A
163+
_fabric_a_persistent_storage = PersistentStorage(jsonData=self.ecoACtrlStorage)
164+
_certAuthorityManagerA = CertificateAuthority.CertificateAuthorityManager(
165+
chipStack=self.matter_stack._chip_stack,
166+
persistentStorage=_fabric_a_persistent_storage)
167+
_certAuthorityManagerA.LoadAuthoritiesFromStorage()
168+
devCtrlEcoA = _certAuthorityManagerA.activeCaList[0].adminList[0].NewController(
169+
nodeId=101,
170+
paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path),
171+
catTags=[int(self.ecoACATs, 16)])
172+
173+
self.step("1")
174+
response = await devCtrlEcoA.ReadAttribute(
175+
nodeid=1, attributes=[(1, Clusters.JointFabricDatastore.Attributes.AnchorRootCA)],
176+
returnClusterObject=True)
177+
asserts.assert_greater_equal(len(response[1][Clusters.JointFabricDatastore].anchorRootCA), 0)
178+
179+
self.step("2")
180+
response = await devCtrlEcoA.ReadAttribute(
181+
nodeid=1, attributes=[(1, Clusters.JointFabricDatastore.Attributes.AnchorNodeID)],
182+
returnClusterObject=True)
183+
asserts.assert_greater_equal(response[1][Clusters.JointFabricDatastore].anchorNodeID, 0)
184+
185+
self.step("3")
186+
response = await devCtrlEcoA.ReadAttribute(
187+
nodeid=1, attributes=[(1, Clusters.JointFabricDatastore.Attributes.AnchorVendorID)],
188+
returnClusterObject=True)
189+
asserts.assert_greater_equal(response[1][Clusters.JointFabricDatastore].anchorVendorID, 0)
190+
191+
192+
if __name__ == "__main__":
193+
default_matter_test_main()

0 commit comments

Comments
 (0)