Skip to content

Commit 1b546b7

Browse files
committed
implement more of the test.
1 parent d65edf1 commit 1b546b7

File tree

2 files changed

+149
-20
lines changed

2 files changed

+149
-20
lines changed

src/python_testing/TC_CCTRL.py

+106-8
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ async def setup_class(self):
7474
new_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority()
7575
new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=2)
7676
paa_path = str(self.matter_test_config.paa_trust_store_path)
77-
print(f"paa_path = {paa_path} ------------------------------------------------")
7877
self.TH_server_controller = new_fabric_admin.NewController(nodeId=112233, paaTrustStorePath=paa_path)
7978
self.server_nodeid = 1111
8079
await self.TH_server_controller.CommissionOnNetwork(nodeId=self.server_nodeid, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator)
@@ -88,17 +87,23 @@ def teardown_class(self):
8887

8988
os.remove(self.kvs)
9089
super().teardown_class()
91-
9290

93-
#@per_endpoint_test(has_cluster(Clusters.CommissionerControl))
94-
@async_test_body
91+
@per_endpoint_test(has_cluster(Clusters.CommissionerControl))
9592
async def test_TC_CCTRL_3_1(self):
93+
self.is_ci = self.check_pics('PICS_SDK_CI_ONLY')
94+
95+
#self.step(1)
9696
th_server_fabrics = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0)
97+
#self.step(2)
9798
th_server_vid = await self.read_single_attribute_check_success(cluster=Clusters.BasicInformation, attribute=Clusters.BasicInformation.Attributes.VendorID, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0)
99+
#self.step(3)
98100
th_server_pid = await self.read_single_attribute_check_success(cluster=Clusters.BasicInformation, attribute=Clusters.BasicInformation.Attributes.ProductID, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0)
99101

100-
# TODO: Read event, not yet implemented in mock
102+
#self.step(4)
103+
event_path = [(self.matter_test_config.endpoint, Clusters.CommissionerControl.Events.CommissioningRequestResult, 1)]
104+
events = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path)
101105

106+
#self.step(5)
102107
ipaddr = ipaddress.IPv6Address('::1')
103108
cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=1, responseTimeoutSeconds=30, ipAddress=ipaddr.packed, port=self.port)
104109
try:
@@ -107,8 +112,8 @@ async def test_TC_CCTRL_3_1(self):
107112
except InteractionModelError as e:
108113
asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned")
109114

115+
#self.step(6)
110116
params = await self.openCommissioningWindow(dev_ctrl=self.default_controller, node_id=self.dut_node_id)
111-
112117
pase_nodeid = self.dut_node_id + 1
113118
await self.default_controller.FindOrEstablishPASESession(setupCode=params.commissioningParameters.setupQRCode, nodeid=pase_nodeid)
114119
try:
@@ -117,19 +122,112 @@ async def test_TC_CCTRL_3_1(self):
117122
except InteractionModelError as e:
118123
asserts.assert_equal(e.status, Status.UnsupportedAccess, "Incorrect error returned")
119124

125+
# self.step(7)
120126
good_request_id = 0x1234567887654321
121127
cmd = Clusters.CommissionerControl.Commands.RequestCommissioningApproval(requestId=good_request_id, vendorId=th_server_vid, productId=th_server_pid)
122128
try:
123129
await self.send_single_cmd(cmd=cmd, node_id=pase_nodeid)
124-
asserts.fail("Unexpected success on CommissionNode")
130+
asserts.fail("Unexpected success on RequestCommissioningApproval over PASE")
125131
except InteractionModelError as e:
126132
asserts.assert_equal(e.status, Status.UnsupportedAccess, "Incorrect error returned")
127133

134+
#self.step(8)
135+
if not events:
136+
new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path)
137+
else:
138+
event_nums = [e.Header.EventNumber for e in events]
139+
new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path, eventNumberFilter=max(event_nums)+1)
140+
asserts.assert_equal(new_event, [], "Unexpected event")
128141

129-
# TODO: read event - need to implement in the mock
130142

143+
#self.step(9)
144+
bad_vid = 0x6006
145+
cmd = Clusters.CommissionerControl.Commands.RequestCommissioningApproval(requestId=good_request_id, vendorId=bad_vid, productId=th_server_pid)
131146
# If no exception is raised, this is success
132147
await self.send_single_cmd(cmd)
133148

149+
#self.step(10)
150+
if not self.is_ci:
151+
self.wait_for_use_input("Approve Commissioning approval request using manufacturer specified mechanism")
152+
153+
#self.step(11)
154+
if not events:
155+
new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path)
156+
else:
157+
event_nums = [e.Header.EventNumber for e in events]
158+
new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path, eventNumberFilter=max(event_nums)+1)
159+
asserts.assert_equal(len(new_event), 1, "Unexpected event list len")
160+
asserts.assert_equal(new_event[0].Data.statusCode, 0, "Unexpected status code")
161+
asserts.assert_equal(new_event[0].Data.clientNodeId, self.matter_test_config.controller_node_id, "Unexpected client node id")
162+
asserts.assert_equal(new_event[0].Data.requestId, good_request_id, "Unexpected request ID")
163+
164+
#self.step(12)
165+
bad_request_id = 0x1234567887654322
166+
cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=bad_request_id, responseTimeoutSeconds=30)
167+
try:
168+
await self.send_single_cmd(cmd=cmd)
169+
asserts.fail("Unexpected success on CommissionNode")
170+
except InteractionModelError as e:
171+
asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned")
172+
173+
#self.step(13)
174+
cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=29)
175+
try:
176+
await self.send_single_cmd(cmd=cmd)
177+
asserts.fail("Unexpected success on CommissionNode")
178+
except InteractionModelError as e:
179+
asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned")
180+
181+
#self.step(14)
182+
cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=121)
183+
try:
184+
await self.send_single_cmd(cmd=cmd)
185+
asserts.fail("Unexpected success on CommissionNode")
186+
except InteractionModelError as e:
187+
asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned")
188+
189+
#self.step(15)
190+
cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=30)
191+
resp = await self.send_single_cmd(cmd)
192+
asserts.assert_equal(type(resp), Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow, "Incorrect response type")
193+
194+
#self.step(16)
195+
#TODO: we do not have a direct line to OpenEnhancedCommissioningWindow. Need to add plumbing
196+
# For now, open with anything so the below command is ok
197+
await self.openCommissioningWindow(dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid)
198+
199+
#self.step(17)
200+
logging.info("Test now waits for 30 seconds")
201+
#time.sleep(30)
202+
203+
#self.step(18)
204+
print(f'server node id {self.server_nodeid}')
205+
th_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0)
206+
asserts.assert_equal(len(th_server_fabrics), len(th_server_fabrics_new), "Unexpected number of fabrics on TH_SERVER")
207+
208+
#self.step(19)
209+
cmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning()
210+
await self.send_single_cmd(cmd, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, timedRequestTimeoutMs=5000, endpoint=0)
211+
212+
#self.step(20)
213+
good_request_id = 0x1234567812345678
214+
cmd = Clusters.CommissionerControl.Commands.RequestCommissioningApproval(requestId=good_request_id, vendorId=th_server_vid, productId=th_server_pid, label="Test Ecosystem")
215+
self.send_single_cmd(cmd)
216+
217+
#self.step(21)
218+
if not self.is_ci:
219+
self.wait_for_use_input("Approve Commissioning approval request using manufacturer specified mechanism")
220+
221+
#self.step(22)
222+
events = new_event
223+
event_nums = [e.Header.EventNumber for e in events]
224+
new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path, eventNumberFilter=max(event_nums)+1)
225+
asserts.assert_equal(len(new_event), 1, "Unexpected event list len")
226+
asserts.assert_equal(new_event[0].Data.statusCode, 0, "Unexpected status code")
227+
asserts.assert_equal(new_event[0].Data.clientNodeId, self.matter_test_config.controller_node_id, "Unexpected client node id")
228+
asserts.assert_equal(new_event[0].Data.requestId, good_request_id, "Unexpected request ID")
229+
230+
231+
134232
if __name__ == "__main__":
135233
default_matter_test_main()

src/python_testing/test_testing/test_TC_CCNTL.py

+43-12
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,50 @@
3535
os.path.join(os.path.dirname(__file__), '..')))
3636
from matter_testing_support import get_default_paa_trust_store, run_tests_no_exit
3737

38-
call_count = 0
38+
invoke_call_count = 0
39+
event_call_count = 0
3940

40-
def dynamic_return(*args, **argv):
41-
print("using Mock invoke")
42-
global call_count
43-
call_count += 1
41+
def dynamic_invoke_return(*args, **argv):
42+
global invoke_call_count
43+
invoke_call_count += 1
4444

45-
if call_count == 1: # Commission node with no prior request, return failure
45+
if invoke_call_count == 1: # Commission node with no prior request, return failure
4646
raise InteractionModelError(status=Status.Failure)
47-
elif call_count == 2: # Commission node over pase - return unsupported access
47+
elif invoke_call_count == 2: # Commission node over pase - return unsupported access
4848
raise InteractionModelError(status=Status.UnsupportedAccess)
49-
elif call_count == 3: # request commissioning approval over pase - return unsupported access
49+
elif invoke_call_count == 3: # request commissioning approval over pase - return unsupported access
5050
raise InteractionModelError(status=Status.UnsupportedAccess)
51-
elif call_count == 4: # good RequestCommissioningApproval over CASE
51+
elif invoke_call_count == 4: # good RequestCommissioningApproval over CASE with bad vid
5252
return None
53+
elif invoke_call_count == 5: # CommissionNode with bad request id
54+
raise InteractionModelError(status=Status.Failure)
55+
elif invoke_call_count == 6: # CommissionNode with bad timeout (low)
56+
raise InteractionModelError(status=Status.Failure)
57+
elif invoke_call_count == 7: # CommissionNode with bad timeout (high)
58+
raise InteractionModelError(status=Status.Failure)
59+
elif invoke_call_count == 8: #CommissionNode
60+
return Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow(commissioningTimeout=30, PAKEPasscodeVerifier=b'', discriminator=2222, iterations=10000, salt=bytes('SaltyMcSaltersons', 'utf-8'))
61+
else:
62+
raise InteractionModelError(Status.Failure)
63+
64+
def dynamic_event_return(*args, **argv):
65+
global event_call_count
66+
event_call_count += 1
67+
68+
if event_call_count == 1: # reading events, start empty - no events
69+
return []
70+
elif event_call_count == 2: # read event with filter - expect empty
71+
return []
72+
elif event_call_count == 3: # returned event
73+
header = Attribute.EventHeader(EndpointId=0, ClusterId=Clusters.CommissionerControl.id, EventId=Clusters.CommissionerControl.Events.CommissioningRequestResult.event_id, EventNumber=1)
74+
data = Clusters.CommissionerControl.Events.CommissioningRequestResult(requestId=0x1234567887654321, clientNodeId=112233, statusCode=0)
75+
result = Attribute.EventReadResult(Header=header, Status=Status.Success, Data=data)
76+
return [result]
77+
elif event_call_count == 4: # returmed event with new request id
78+
header = Attribute.EventHeader(EndpointId=0, ClusterId=Clusters.CommissionerControl.id, EventId=Clusters.CommissionerControl.Events.CommissioningRequestResult.event_id, EventNumber=1)
79+
data = Clusters.CommissionerControl.Events.CommissioningRequestResult(requestId=0x1234567812345678, clientNodeId=112233, statusCode=0)
80+
result = Attribute.EventReadResult(Header=header, Status=Status.Success, Data=data)
81+
return [result]
5382
else:
5483
raise InteractionModelError(Status.Failure)
5584

@@ -79,14 +108,15 @@ def wildcard() -> Attribute.AsyncReadTransaction.ReadResponse:
79108

80109
class MyMock(MockTestRunner):
81110
# TODO consolidate with above
82-
def run_test_with_mock(self, dynamic_invoke_return: typing.Callable, read_cache: Attribute.AsyncReadTransaction.ReadResponse, hooks=None):
111+
def run_test_with_mock(self, dynamic_invoke_return: typing.Callable, dynamic_event_return: typing.Callable, read_cache: Attribute.AsyncReadTransaction.ReadResponse, hooks=None):
83112
''' Effects is a list of callable functions with *args, **kwargs parameters. It can either throw an InteractionModelException or return the command response.'''
84113
self.default_controller.Read = AsyncMock(return_value=read_cache)
85114
self.default_controller.SendCommand = AsyncMock(return_value=None, side_effect=dynamic_invoke_return)
86115
# It doesn't actually matter what we return here because I'm going to catch the next pase session connection anyway
87116
params = ChipDeviceCtrl.CommissioningParameters(setupPinCode=0, setupManualCode='', setupQRCode='')
88117
self.default_controller.OpenCommissioningWindow = AsyncMock(return_value=params)
89118
self.default_controller.FindOrEstablishPASESession = AsyncMock(return_value=None)
119+
self.default_controller.ReadEvent = AsyncMock(return_value=[], side_effect=dynamic_event_return)
90120

91121
return run_tests_no_exit(self.test_class, self.config, hooks, self.default_controller, self.stack)
92122

@@ -96,9 +126,10 @@ def main():
96126
paa_path = get_default_paa_trust_store(root)
97127
print(f'paa = {paa_path}')
98128

99-
test_runner = MyMock('TC_CCTRL', 'TC_CCTRL', 'test_TC_CCTRL_3_1', 1, paa_trust_store_path=paa_path)
129+
pics = {"PICS_SDK_CI_ONLY": True }
130+
test_runner = MyMock('TC_CCTRL', 'TC_CCTRL', 'test_TC_CCTRL_3_1', 1, paa_trust_store_path=paa_path, pics=pics)
100131

101-
test_runner.run_test_with_mock(dynamic_return, wildcard())
132+
test_runner.run_test_with_mock(dynamic_invoke_return, dynamic_event_return, wildcard())
102133
test_runner.Shutdown()
103134

104135
if __name__ == "__main__":

0 commit comments

Comments
 (0)