Skip to content

Commit fa6aad3

Browse files
Update IDM_1_4 to be more accurate and correct (#31686)
* Post code freeze crunch fixes * Fix things * Restyled by autopep8 * Small fix * Restyled by autopep8 --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent e202049 commit fa6aad3

File tree

2 files changed

+48
-30
lines changed

2 files changed

+48
-30
lines changed

src/python_testing/TC_IDM_1_4.py

+37-29
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from chip import ChipUtility
2323
from chip.exceptions import ChipStackError
2424
from chip.interaction_model import InteractionModelError, Status
25-
from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches
25+
from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches
2626
from mobly import asserts
2727

2828

@@ -35,21 +35,33 @@ def must_use_timed_invoke(cls) -> bool:
3535

3636
class TC_IDM_1_4(MatterBaseTest):
3737

38+
def steps_TC_IDM_1_4(self) -> list[TestStep]:
39+
steps = [TestStep(1, "Get remote node's MaxPathsPerInvoke", is_commissioning=True),
40+
TestStep(2, "Sending `MaxPathsPerInvoke + 1` InvokeRequest if it fits into single MTU"),
41+
TestStep(3, "Sending two InvokeRequests with identical paths"),
42+
TestStep(4, "Sending two InvokeRequests with unique paths, but identical CommandRefs"),
43+
TestStep(5, "Verify DUT responds to InvokeRequestMessage containing two valid paths"),
44+
TestStep(6, "Verify DUT responds to InvokeRequestMessage containing one valid paths, and one InvokeRequest to unsupported endpoint"),
45+
TestStep(7, "Verify DUT responds to InvokeRequestMessage containing two valid paths. One of which requires timed invoke, and TimedRequest in InvokeResponseMessage set to true, but never sending preceding Timed Invoke Action"),
46+
TestStep(8, "Verify DUT responds to InvokeRequestMessage containing two valid paths. One of which requires timed invoke, and TimedRequest in InvokeResponseMessage set to true"),
47+
TestStep(9, "Verify DUT capable of responding to request with multiple InvokeResponseMessages")]
48+
return steps
49+
3850
@async_test_body
3951
async def test_TC_IDM_1_4(self):
4052
dev_ctrl = self.default_controller
4153
dut_node_id = self.dut_node_id
4254

4355
self.print_step(0, "Commissioning - already done")
4456

45-
self.print_step(1, "Get remote node's MaxPathsPerInvoke")
57+
self.step(1)
4658
session_parameters = dev_ctrl.GetRemoteSessionParameters(dut_node_id)
4759
max_paths_per_invoke = session_parameters.maxPathsPerInvoke
4860

49-
asserts.assert_greater_equal(max_paths_per_invoke, 1, "Unexpected error returned from unsupported endpoint")
50-
asserts.assert_less_equal(max_paths_per_invoke, 65535, "Unexpected error returned from unsupported endpoint")
61+
asserts.assert_greater_equal(max_paths_per_invoke, 1, "Max Paths per Invoke less than spec min")
62+
asserts.assert_less_equal(max_paths_per_invoke, 65535, "Max Paths per Invoke greater than spec max")
5163

52-
self.print_step(2, "Sending `MaxPathsPerInvoke + 1` InvokeRequest if it fits into single MTU")
64+
self.step(2)
5365
# In practice, it was noticed that we could only fit 57 commands before we hit the MTU limit as a result we
5466
# conservatively try putting up to 100 commands into an Invoke request. We are expecting one of 2 things to
5567
# happen if max_paths_per_invoke + 1 is greater than what cap_for_batch_commands is set to:
@@ -59,7 +71,7 @@ async def test_TC_IDM_1_4(self):
5971
# 2. Client (TH) able to send command. While unexpected we will hit two different test failure depending on
6072
# what the server does.
6173
# a. Server successfully handle command and send InvokeResponse with results of all individual commands
62-
# being failure. In this case, test fails on unexpected successes like this
74+
# being failure. In this case, test already will fail on unexpected successes.
6375
# b. Server fails to handle command that is between cap_for_batch_commands and max_paths_per_invoke + 1.
6476
# In this case, test fails as device should have actually succeeded and been caught in 2.a.
6577
cap_for_batch_commands = 100
@@ -80,42 +92,39 @@ async def test_TC_IDM_1_4(self):
8092
"Step 2 is always expected to try sending at least 2 command, something wrong with test logic")
8193
try:
8294
await dev_ctrl.TestOnlySendBatchCommands(dut_node_id, list_of_commands_to_send, remoteMaxPathsPerInvoke=number_of_commands_to_send)
83-
# If you get the assert below it is likely because cap_for_batch_commands is actually too low.
84-
# This might happen after TCP is enabled and DUT supports TCP.
95+
# This might happen after TCP is enabled and DUT supports TCP. See comment above `cap_for_batch_commands`
96+
# for more information.
97+
asserts.assert_not_equal(number_of_commands_to_send, cap_for_batch_commands,
98+
"Test needs to be updated! Soft cap `cap_for_batch_commands` used in test is no longer correct")
8599
asserts.fail(
86100
f"Unexpected success return from sending too many commands, we sent {number_of_commands_to_send}, test capped at {cap_for_batch_commands}")
87101
except InteractionModelError as e:
88-
# This check is for 2.a., mentioned above introduction of variable cap_for_batch_commands.
102+
# This check is for 2.b, mentioned above. If this assert occurs, test likely needs updating. Although DUT
103+
# is still going to fail since it seemingly is failing to process a smaller number then it is reporting
104+
# that it is capable of processing.
89105
asserts.assert_equal(number_of_commands_to_send, max_paths_per_invoke + 1,
90106
"Test didn't send as many command as max_paths_per_invoke + 1, likely due to MTU cap_for_batch_commands, but we still got an error from server. This should have been a success from server")
91107
asserts.assert_equal(e.status, Status.InvalidAction,
92108
"DUT sent back an unexpected error, we were expecting InvalidAction")
93-
self.print_step(2, "DUT successfully failed to process `MaxPathsPerInvoke + 1` InvokeRequests")
109+
logging.info("DUT successfully failed to process `MaxPathsPerInvoke + 1` InvokeRequests")
94110
except ChipStackError as e:
95111
chip_error_no_memory = 0x0b
96112
asserts.assert_equal(e.err, chip_error_no_memory, "Unexpected error while trying to send InvokeRequest")
97113
# TODO it is possible we want to confirm DUT can handle up to MTU max. But that is not in test plan as of right now.
98114
# Additionally CommandSender is not currently set up to enable caller to fill up to MTU. This might be coming soon,
99115
# just that it is not supported today.
100-
self.print_step(2, "DUTs reported MaxPathsPerInvoke + 1 is larger than what fits into MTU. Test step is skipped")
116+
logging.info("DUTs reported MaxPathsPerInvoke + 1 is larger than what fits into MTU. Test step is skipped")
101117

102118
if max_paths_per_invoke == 1:
103-
# TODO(#31139) After issue is resolved use that API properly to mark tests steps as skipped
104-
self.print_step(3, "Skipping test step as max_paths_per_invoke == 1")
105-
self.print_step(4, "Skipping test step as max_paths_per_invoke == 1")
106-
self.print_step(5, "Skipping test step as max_paths_per_invoke == 1")
107-
self.print_step(6, "Skipping test step as max_paths_per_invoke == 1")
108-
self.print_step(7, "Skipping test step as max_paths_per_invoke == 1")
109-
self.print_step(8, "Skipping test step as max_paths_per_invoke == 1")
110-
self.print_step(9, "Skipping test step as max_paths_per_invoke == 1")
119+
self.skip_all_remaining_steps(3)
111120
else:
112121
await self.steps_3_to_9(False)
113122

114123
async def steps_3_to_9(self, dummy_value):
115124
dev_ctrl = self.default_controller
116125
dut_node_id = self.dut_node_id
117126

118-
self.print_step(3, "Sending sending two InvokeRequests with idential paths")
127+
self.step(3)
119128
command = Clusters.BasicInformation.Commands.MfgSpecificPing()
120129
endpoint = 0
121130
invoke_request_1 = Clusters.Command.InvokeRequestInfo(endpoint, command)
@@ -127,7 +136,7 @@ async def steps_3_to_9(self, dummy_value):
127136
"DUT sent back an unexpected error, we were expecting InvalidAction")
128137
logging.info("DUT successfully failed to process two InvokeRequests that contains non-unique paths")
129138

130-
self.print_step(4, "Sending two InvokeRequests with unique paths, but identical CommandRefs")
139+
self.step(4)
131140
endpoint = 0
132141
command = Clusters.OperationalCredentials.Commands.CertificateChainRequest(
133142
Clusters.OperationalCredentials.Enums.CertificateChainTypeEnum.kDACCertificate)
@@ -144,7 +153,7 @@ async def steps_3_to_9(self, dummy_value):
144153
"DUT sent back an unexpected error, we were expecting InvalidAction")
145154
logging.info("DUT successfully failed to process two InvokeRequests that contains non-unique CommandRef")
146155

147-
self.print_step(5, "Verify DUT is able to responsed to InvokeRequestMessage that contains two valid paths")
156+
self.step(5)
148157
endpoint = 0
149158
command = Clusters.OperationalCredentials.Commands.CertificateChainRequest(
150159
Clusters.OperationalCredentials.Enums.CertificateChainTypeEnum.kDACCertificate)
@@ -164,8 +173,7 @@ async def steps_3_to_9(self, dummy_value):
164173
except InteractionModelError:
165174
asserts.fail("DUT failed to successfully responded to a InvokeRequest action with two valid commands")
166175

167-
self.print_step(
168-
6, "Verify DUT is able to responsed to InvokeRequestMessage that contains one paths InvokeRequest, and one InvokeRequest to unsupported endpoint")
176+
self.step(6)
169177
# First finding non-existent endpoint
170178
wildcard_descriptor = await dev_ctrl.ReadAttribute(dut_node_id, [(Clusters.Descriptor)])
171179
endpoints = list(wildcard_descriptor.keys())
@@ -195,7 +203,7 @@ async def steps_3_to_9(self, dummy_value):
195203
except InteractionModelError:
196204
asserts.fail("DUT failed to successfully responded to a InvokeRequest action with two valid commands")
197205

198-
self.print_step(7, "Verify DUT is able to responsed to InvokeRequestMessage that contains two valid paths. One of which requires timed invoke, and TimedRequest in InvokeResponseMessage set to true, but never sent preceding Timed Invoke Action")
206+
self.step(7)
199207
endpoint = 0
200208
command = Clusters.GroupKeyManagement.Commands.KeySetRead(0)
201209
invoke_request_1 = Clusters.Command.InvokeRequestInfo(endpoint, command)
@@ -214,7 +222,7 @@ async def steps_3_to_9(self, dummy_value):
214222
asserts.assert_equal(e.status, Status.TimedRequestMismatch,
215223
"Unexpected error response from Invoke with TimedRequest flag and no TimedInvoke")
216224

217-
self.print_step(8, "Verify DUT is able to responsed to InvokeRequestMessage that contains two valid paths. One of which requires timed invoke, and TimedRequest in InvokeResponseMessage set to true")
225+
self.step(8)
218226
endpoint = 0
219227
command = Clusters.GroupKeyManagement.Commands.KeySetRead(0)
220228
invoke_request_1 = Clusters.Command.InvokeRequestInfo(endpoint, command)
@@ -235,12 +243,12 @@ async def steps_3_to_9(self, dummy_value):
235243
window_not_open_cluster_error = 4
236244
asserts.assert_equal(result[1].clusterStatus, window_not_open_cluster_error,
237245
"Timed command, RevokeCommissioning, failed with incorrect cluster code")
238-
self.print_step(
239-
8, "DUT successfully responded to a InvokeRequest action with two valid commands. One of which required timed invoke, and TimedRequest in InvokeResponseMessage was set to true")
246+
logging.info("DUT successfully responded to a InvokeRequest action with two valid commands. One of which required timed invoke, and TimedRequest in InvokeResponseMessage was set to true")
240247
except InteractionModelError:
241248
asserts.fail("DUT failed with non-path specific error when path specific error was expected")
242249

243-
self.print_step(9, "Skipping test until https://github.com/project-chip/connectedhomeip/issues/31434 resolved")
250+
# Skipping test until https://github.com/project-chip/connectedhomeip/issues/31434 resolved
251+
self.skip_step(9)
244252

245253

246254
if __name__ == "__main__":

src/python_testing/matter_testing_support.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,6 @@ def mark_current_step_skipped(self):
888888
steps = self.get_test_steps(self.current_test_info.name)
889889
if self.current_step_index == 0:
890890
asserts.fail("Script error: mark_current_step_skipped cannot be called before step()")
891-
print(self.current_step_index-1)
892891
num = steps[self.current_step_index-1].test_plan_number
893892
except KeyError:
894893
num = self.current_step_index
@@ -906,6 +905,17 @@ def skip_step(self, step):
906905
self.step(step)
907906
self.mark_current_step_skipped()
908907

908+
def skip_all_remaining_steps(self, starting_step):
909+
''' Skips all remaining test steps starting with provided starting step
910+
911+
starting_step must be provided, and is not derived intentionally. By providing argument
912+
test is more deliberately identifying where test skips are starting from, making
913+
it easier to validate against the test plan for correctness.
914+
'''
915+
last_step = len(self.get_test_steps(self.current_test_info.name)) + 1
916+
for index in range(starting_step, last_step):
917+
self.skip_step(index)
918+
909919
def step(self, step: typing.Union[int, str]):
910920
test_name = self.current_test_info.name
911921
steps = self.get_test_steps(test_name)

0 commit comments

Comments
 (0)