Skip to content

Commit b501f3b

Browse files
Allow inheritance of MatterBaseTest (project-chip#39397)
* Allow inheritance of MatterBaseTest Change CADMIN tests to inherit from a base class rather than using an additional support class. This just makes the code a bit neater. It also means we can add cleanup steps in the base class, which is REALLY handy. Next PR will add a cleanup step for CADMIN. * remove some unused imports - linter * fix more lints * Restyled by isort * Address review comments * Restyled by isort * review comment CADMINSupport -> CADMINBaseTest * Restyled by isort --------- Co-authored-by: Restyled.io <[email protected]>
1 parent 9714900 commit b501f3b

File tree

7 files changed

+73
-131
lines changed

7 files changed

+73
-131
lines changed

src/python_testing/TC_CADMIN_1_11.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,12 @@
4242
from chip.ChipDeviceCtrl import CommissioningParameters
4343
from chip.exceptions import ChipStackError
4444
from chip.native import PyChipError
45-
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
45+
from chip.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4646
from mobly import asserts
47-
from support_modules.cadmin_support import CADMINSupport
47+
from support_modules.cadmin_support import CADMINBaseTest
4848

4949

50-
class TC_CADMIN_1_11(MatterBaseTest):
51-
def __init__(self, *args, **kwargs):
52-
super().__init__(*args, **kwargs)
53-
self.support = CADMINSupport(self)
54-
50+
class TC_CADMIN_1_11(CADMINBaseTest):
5551
async def OpenCommissioningWindow(self, th, expectedErrCode) -> CommissioningParameters:
5652
if expectedErrCode is None:
5753
params = await th.OpenCommissioningWindow(
@@ -209,7 +205,7 @@ async def test_TC_CADMIN_1_11(self):
209205

210206
# Read CurrentFabricIndex attribute from the Operational Credentials cluster
211207
self.step(10)
212-
th2_idx = await self.support.read_currentfabricindex(self.th2)
208+
th2_idx = await self.read_currentfabricindex(self.th2)
213209

214210
self.step(11)
215211
removeFabricCmd = Clusters.OperationalCredentials.Commands.RemoveFabric(th2_idx)

src/python_testing/TC_CADMIN_1_19.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,12 @@
3636
from chip import ChipDeviceCtrl
3737
from chip.exceptions import ChipStackError
3838
from chip.testing.event_attribute_reporting import AttributeSubscriptionHandler
39-
from chip.testing.matter_testing import AttributeValue, MatterBaseTest, TestStep, async_test_body, default_matter_test_main
39+
from chip.testing.matter_testing import AttributeValue, TestStep, async_test_body, default_matter_test_main
4040
from mobly import asserts
41-
from support_modules.cadmin_support import CADMINSupport
41+
from support_modules.cadmin_support import CADMINBaseTest
4242

4343

44-
class TC_CADMIN_1_19(MatterBaseTest):
45-
def __init__(self, *args, **kwargs):
46-
super().__init__(*args, **kwargs)
47-
self.support = CADMINSupport(self)
48-
44+
class TC_CADMIN_1_19(CADMINBaseTest):
4945
def steps_TC_CADMIN_1_19(self) -> list[TestStep]:
5046
return [
5147
TestStep(1, "Commissioning, already done", is_commissioning=True),
@@ -96,7 +92,7 @@ async def test_TC_CADMIN_1_19(self):
9692
self.max_window_duration = duration.maxCumulativeFailsafeSeconds
9793

9894
self.step(3)
99-
fabrics = await self.support.get_fabrics(th=self.th1, fabric_filtered=False)
95+
fabrics = await self.get_fabrics(th=self.th1, fabric_filtered=False)
10096
initial_number_of_fabrics = len(fabrics)
10197

10298
self.step(4)

src/python_testing/TC_CADMIN_1_22.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,12 @@
3737
import chip.clusters as Clusters
3838
from chip.ChipDeviceCtrl import CommissioningParameters
3939
from chip.exceptions import ChipStackError
40-
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
40+
from chip.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4141
from mobly import asserts
42-
from support_modules.cadmin_support import CADMINSupport
42+
from support_modules.cadmin_support import CADMINBaseTest
4343

4444

45-
class TC_CADMIN_1_22_24(MatterBaseTest):
46-
def __init__(self, *args, **kwargs):
47-
super().__init__(*args, **kwargs)
48-
self.support = CADMINSupport(self)
49-
45+
class TC_CADMIN_1_22_24(CADMINBaseTest):
5046
async def OpenCommissioningWindow(self) -> CommissioningParameters:
5147
try:
5248
params = await self.th1.OpenCommissioningWindow(
@@ -96,12 +92,12 @@ async def test_TC_CADMIN_1_22(self):
9692
revokeCmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning()
9793
await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=revokeCmd, timedRequestTimeoutMs=6000)
9894
# The failsafe cleanup is scheduled after the command completes, so give it a bit of time to do that
99-
window_status = await self.support.get_window_status(th=self.th1)
95+
window_status = await self.get_window_status(th=self.th1)
10096
asserts.assert_equal(window_status, Clusters.AdministratorCommissioning.Enums.CommissioningWindowStatusEnum.kWindowNotOpen,
10197
"Commissioning window is expected to be closed, but was found to be open")
10298

10399
self.step(4)
104-
window_status = await self.support.get_window_status(th=self.th1)
100+
window_status = await self.get_window_status(th=self.th1)
105101
asserts.assert_equal(window_status, Clusters.AdministratorCommissioning.Enums.CommissioningWindowStatusEnum.kWindowNotOpen,
106102
"Commissioning window is expected to be closed, but was found to be open")
107103

@@ -117,7 +113,7 @@ async def test_TC_CADMIN_1_22(self):
117113
"Expected to error as we provided failure value for opening commissioning window")
118114

119115
self.step(6)
120-
window_status2 = await self.support.get_window_status(th=self.th1)
116+
window_status2 = await self.get_window_status(th=self.th1)
121117
asserts.assert_equal(window_status2, Clusters.AdministratorCommissioning.Enums.CommissioningWindowStatusEnum.kWindowNotOpen,
122118
"Commissioning window is expected to be closed, but was found to be open")
123119

@@ -129,7 +125,7 @@ async def test_TC_CADMIN_1_22(self):
129125
revokeCmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning()
130126
await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=revokeCmd, timedRequestTimeoutMs=6000)
131127
# The failsafe cleanup is scheduled after the command completes, so give it a bit of time to do that
132-
window_status3 = await self.support.get_window_status(th=self.th1)
128+
window_status3 = await self.get_window_status(th=self.th1)
133129
asserts.assert_equal(window_status3, Clusters.AdministratorCommissioning.Enums.CommissioningWindowStatusEnum.kWindowNotOpen,
134130
"Commissioning window is expected to be closed, but was found to be open")
135131

@@ -146,7 +142,7 @@ async def test_TC_CADMIN_1_22(self):
146142
"Expected to error as we provided failure value for opening commissioning window")
147143

148144
self.step(10)
149-
window_status4 = await self.support.get_window_status(th=self.th1)
145+
window_status4 = await self.get_window_status(th=self.th1)
150146
asserts.assert_equal(window_status4, Clusters.AdministratorCommissioning.Enums.CommissioningWindowStatusEnum.kWindowNotOpen,
151147
"Commissioning window is expected to be closed, but was found to be open")
152148

src/python_testing/TC_CADMIN_1_3_4.py

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,16 @@
5353
import chip.clusters as Clusters
5454
from chip import ChipDeviceCtrl
5555
from chip.exceptions import ChipStackError
56-
from chip.testing.matter_testing import (MatterBaseTest, TestStep, default_matter_test_main, has_cluster, has_feature,
57-
run_if_endpoint_matches)
56+
from chip.testing.matter_testing import TestStep, default_matter_test_main, has_cluster, has_feature, run_if_endpoint_matches
5857
from chip.tlv import TLVReader
5958
from mobly import asserts
60-
from support_modules.cadmin_support import CADMINSupport
59+
from support_modules.cadmin_support import CADMINBaseTest
6160

6261
opcreds = Clusters.OperationalCredentials
6362
nonce = random.randbytes(32)
6463

6564

66-
class TC_CADMIN(MatterBaseTest):
67-
def __init__(self, *args, **kwargs):
68-
super().__init__(*args, **kwargs)
69-
self.support = CADMINSupport(self)
70-
65+
class TC_CADMIN(CADMINBaseTest):
7166
async def combined_commission_val_steps(self, commission_type: str):
7267
"""
7368
Combined test function for commissioning tests.
@@ -108,13 +103,13 @@ async def combined_commission_val_steps(self, commission_type: str):
108103

109104
self.step("3b")
110105
if commission_type == "ECM":
111-
service = await self.support.wait_for_correct_cm_value(
106+
service = await self.wait_for_correct_cm_value(
112107
expected_cm_value=2,
113108
expected_discriminator=1234
114109
)
115110
logging.info(f"Successfully found service with CM={service.txt_record.get('CM')}, D={service.txt_record.get('D')}")
116111
elif commission_type == "BCM":
117-
service = await self.support.wait_for_correct_cm_value(
112+
service = await self.wait_for_correct_cm_value(
118113
expected_cm_value=1,
119114
expected_discriminator=setupPayloadInfo[0].filter_value
120115
)
@@ -123,8 +118,8 @@ async def combined_commission_val_steps(self, commission_type: str):
123118
self.step("3c")
124119
BI_cluster = Clusters.BasicInformation
125120
self.nl_attribute = BI_cluster.Attributes.NodeLabel
126-
await self.support.write_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
127-
await self.support.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
121+
await self.write_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
122+
await self.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
128123

129124
self.step(4)
130125
# Establishing TH2
@@ -154,7 +149,7 @@ async def combined_commission_val_steps(self, commission_type: str):
154149

155150
self.step(5)
156151
# TH_CR1 reads the Fabrics attribute
157-
th1_fabric_info = await self.support.get_fabrics(th=self.th1)
152+
th1_fabric_info = await self.get_fabrics(th=self.th1)
158153
th1_cam_rcac = TLVReader(base64.b64decode(
159154
self.certificate_authority_manager.activeCaList[0]._persistentStorage._jsonData["sdk-config"]["f/1/r"])).get()["Any"][9]
160155
if th1_fabric_info[0].rootPublicKey != th1_cam_rcac:
@@ -164,7 +159,7 @@ async def combined_commission_val_steps(self, commission_type: str):
164159

165160
self.step(6)
166161
# TH_CR2 reads the Fabrics attribute
167-
th2_fabric_info = await self.support.get_fabrics(th=self.th2)
162+
th2_fabric_info = await self.get_fabrics(th=self.th2)
168163
if th2_fabric_info[0].rootPublicKey != th2_rcac_decoded:
169164
asserts.fail("Public keys from fabric and certs for TH2 are not the same.")
170165
if th2_fabric_info[0].nodeID != self.dut_node_id:
@@ -173,15 +168,15 @@ async def combined_commission_val_steps(self, commission_type: str):
173168
if commission_type == "ECM":
174169
self.step(7)
175170
# TH_CR1 writes and reads the Basic Information Cluster’s NodeLabel mandatory attribute of DUT_CE
176-
await self.support.write_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
177-
await self.support.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
171+
await self.write_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
172+
await self.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th1, attr_val=self.nl_attribute)
178173

179174
self.step(8)
180175
# TH_CR2 writes and reads the Basic Information Cluster’s NodeLabel mandatory attribute of DUT_CE
181-
val = await self.support.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th2, attr_val=self.nl_attribute)
176+
val = await self.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th2, attr_val=self.nl_attribute)
182177
self.print_step("basic information cluster node label attr value", val)
183-
await self.support.write_nl_attr(dut_node_id=self.dut_node_id, th=self.th2, attr_val=self.nl_attribute)
184-
await self.support.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th2, attr_val=self.nl_attribute)
178+
await self.write_nl_attr(dut_node_id=self.dut_node_id, th=self.th2, attr_val=self.nl_attribute)
179+
await self.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th2, attr_val=self.nl_attribute)
185180

186181
self.step(9)
187182
# TH_CR2 opens a commissioning window on DUT_CE for 180 seconds using ECM

src/python_testing/TC_CADMIN_1_9.py

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -32,57 +32,45 @@
3232
# === END CI TEST ARGUMENTS ===
3333

3434
import logging
35-
import random
35+
from copy import deepcopy
3636
from time import sleep
3737

3838
import chip.clusters as Clusters
3939
from chip import ChipDeviceCtrl
40-
from chip.ChipDeviceCtrl import CommissioningParameters
4140
from chip.exceptions import ChipStackError
4241
from chip.native import PyChipError
43-
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
42+
from chip.testing.matter_testing import CustomCommissioningParameters, TestStep, async_test_body, default_matter_test_main
4443
from mobly import asserts
45-
from support_modules.cadmin_support import CADMINSupport
46-
47-
48-
class TC_CADMIN_1_9(MatterBaseTest):
49-
def __init__(self, *args, **kwargs):
50-
super().__init__(*args, **kwargs)
51-
self.support = CADMINSupport(self)
52-
53-
async def OpenCommissioningWindow(self) -> CommissioningParameters:
54-
try:
55-
cluster = Clusters.GeneralCommissioning
56-
attribute = cluster.Attributes.BasicCommissioningInfo
57-
duration = await self.read_single_attribute_check_success(endpoint=0, cluster=cluster, attribute=attribute)
58-
return await self.support.open_commissioning_window(
59-
th=self.th1,
60-
timeout=duration.maxCumulativeFailsafeSeconds,
61-
node_id=self.dut_node_id,
62-
discriminator=self.discriminator
63-
)
64-
except Exception as e:
65-
logging.exception('Error running OpenCommissioningWindow %s', e)
66-
asserts.assert_true(False, 'Failed to open commissioning window')
44+
from support_modules.cadmin_support import CADMINBaseTest
45+
46+
47+
class TC_CADMIN_1_9(CADMINBaseTest):
48+
async def OpenCommissioningWindowForMaxTime(self) -> CustomCommissioningParameters:
49+
cluster = Clusters.GeneralCommissioning
50+
attribute = cluster.Attributes.BasicCommissioningInfo
51+
duration = await self.read_single_attribute_check_success(endpoint=0, cluster=cluster, attribute=attribute)
52+
return await self.open_commissioning_window(dev_ctrl=self.th1, node_id=self.dut_node_id, timeout=duration.maxCumulativeFailsafeSeconds)
6753

68-
async def CommissionOnNetwork(self, setup_code: int):
54+
async def CommissionOnNetwork(self, params: CustomCommissioningParameters):
6955
ctx = asserts.assert_raises(ChipStackError)
7056
with ctx:
7157
await self.th2.CommissionOnNetwork(
7258
nodeId=self.dut_node_id,
73-
setupPinCode=setup_code,
59+
setupPinCode=params.commissioningParameters.setupPinCode,
7460
filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR,
75-
filter=self.discriminator
61+
filter=params.randomDiscriminator
7662
)
7763
errcode = PyChipError.from_code(ctx.exception.err)
7864
return errcode
7965

80-
async def CommissionAttempt(self, setupPinCode: int, expectedErrCode: int):
66+
async def CommissionAttempt(self, params: CustomCommissioningParameters, expectedErrCode: int):
8167
if expectedErrCode == 3:
8268
for cycle in range(20):
8369
logging.info("-----------------Current Iteration {}-------------------------".format(cycle+1))
84-
setup_code = self.support.generate_unique_random_value(setupPinCode) # Updated to use support module
85-
errcode = await self.CommissionOnNetwork(setup_code)
70+
new_params = deepcopy(params)
71+
new_params.commissioningParameters.setupPinCode = self.generate_unique_random_value(
72+
params.commissioningParameters.setupPinCode)
73+
errcode = await self.CommissionOnNetwork(new_params)
8674
logging.info('Commissioning complete done. Successful? {}, errorcode = {}, cycle={}'.format(
8775
errcode.is_success, errcode, (cycle+1)))
8876
asserts.assert_false(errcode.is_success, 'Commissioning complete did not error as expected')
@@ -91,7 +79,7 @@ async def CommissionAttempt(self, setupPinCode: int, expectedErrCode: int):
9179

9280
elif expectedErrCode == 50:
9381
logging.info("-----------------Attempting connection expecting timeout-------------------------")
94-
errcode = await self.CommissionOnNetwork(setupPinCode)
82+
errcode = await self.CommissionOnNetwork(params)
9583
logging.info('Commissioning complete done. Successful? {}, errorcode = {}'.format(errcode.is_success, errcode))
9684
asserts.assert_false(errcode.is_success, 'Commissioning complete did not error as expected')
9785
# TODO: Adding try or except clause here as the errcode code be either 50 for timeout or 3 for incorrect state at this time
@@ -118,23 +106,21 @@ async def test_TC_CADMIN_1_9(self):
118106

119107
# Establishing TH1 and TH2
120108
self.th1 = self.default_controller
121-
self.discriminator = random.randint(0, 4095)
122109
th2_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority()
123110
th2_fabric_admin = th2_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=self.th1.fabricId + 1)
124111
self.th2 = th2_fabric_admin.NewController(nodeId=2, useTestCommissioner=True)
125112

126113
self.step(2)
127-
params = await self.OpenCommissioningWindow()
128-
setupPinCode = params.setupPinCode
114+
params = await self.OpenCommissioningWindowForMaxTime()
129115

130116
self.step(3)
131-
await self.CommissionAttempt(setupPinCode, expectedErrCode=0x03)
117+
await self.CommissionAttempt(params, expectedErrCode=0x03)
132118

133119
self.step(4)
134-
await self.CommissionAttempt(setupPinCode, expectedErrCode=0x32)
120+
await self.CommissionAttempt(params, expectedErrCode=0x32)
135121

136122
self.step(5)
137-
params = await self.OpenCommissioningWindow()
123+
params = await self.OpenCommissioningWindowForMaxTime()
138124

139125
self.step(6)
140126
revokeCmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning()

src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,15 +1141,24 @@ def _find_test_class():
11411141
Raises:
11421142
SystemExit: Raised if the number of test classes is not exactly one.
11431143
"""
1144-
subclasses = utils.find_subclasses_in_module([MatterBaseTest], sys.modules['__main__'])
1145-
subclasses = [c for c in subclasses if c.__name__ != "MatterBaseTest"]
1146-
if len(subclasses) != 1:
1144+
def get_subclasses(cls: Any):
1145+
subclasses = utils.find_subclasses_in_module([cls], sys.modules['__main__'])
1146+
subclasses = [c for c in subclasses if c.__name__ != cls.__name__]
1147+
return subclasses
1148+
1149+
def has_subclasses(cls: Any):
1150+
return get_subclasses(cls) != []
1151+
1152+
subclasses_matter_test_base = get_subclasses(MatterBaseTest)
1153+
leaf_subclasses = [s for s in subclasses_matter_test_base if not has_subclasses(s)]
1154+
1155+
if len(leaf_subclasses) != 1:
11471156
print(
11481157
'Exactly one subclass of `MatterBaseTest` should be in the main file. Found %s.' %
1149-
str([subclass.__name__ for subclass in subclasses]))
1158+
str([subclass.__name__ for subclass in leaf_subclasses]))
11501159
sys.exit(1)
11511160

1152-
return subclasses[0]
1161+
return leaf_subclasses[0]
11531162

11541163

11551164
def int_decimal_or_hex(s: str) -> int:

0 commit comments

Comments
 (0)