Thanks, yep not sure how I missed running dts-check-format! Applied to next-dts with the dts-check-format fix squashed. On Thu, Nov 6, 2025 at 10:05 AM Andrew Bailey wrote: > Raises: > + InteractiveCommandExecutionError: If the ports has been started > but a port link will not come up. > nit: fails check-format because the line is too long. > > Reviewed-by: Andrew Bailey > > On Wed, Nov 5, 2025 at 2:50 PM Patrick Robb wrote: > >> When running our existing DTS testsuites on a new >> NIC we observed packets would not transmit from >> the traffic generator to the system under test >> even after DPDK testpmd and the NIC under test >> had indicated readiness. After investigation, we >> determined that the existing readiness check in DTS >> for testpmd start (checking that port is started) >> is insufficient, because on some systems the link >> will remain down for some measurable time, creating >> a race condition between the testpmd port's link >> coming up and the DTS execution reaching the packet >> transmission step. This change will ensure that >> testpmd start will block until the port is reporting >> that its link is up. In addition, the interval in >> between checking the link state has been reduced in >> order to speed up the execution. >> >> Signed-off-by: Patrick Robb >> Tested-by: Patrick Robb >> --- >> dts/api/testpmd/__init__.py | 9 ++++++++- >> 1 file changed, 8 insertions(+), 1 deletion(-) >> >> diff --git a/dts/api/testpmd/__init__.py b/dts/api/testpmd/__init__.py >> index aadb7f4e70..49a847494a 100644 >> --- a/dts/api/testpmd/__init__.py >> +++ b/dts/api/testpmd/__init__.py >> @@ -93,6 +93,9 @@ def _requires_started_ports(func: TestPmdMethod) -> >> TestPmdMethod: >> >> Args: >> func: The :class:`TestPmd` method to decorate. >> + >> + Raises: >> + InteractiveCommandExecutionError: If the ports has been started >> but a port link will not come up. >> """ >> >> @functools.wraps(func) >> @@ -100,6 +103,10 @@ def _wrapper(self: "TestPmd", *args: P.args, >> **kwargs: P.kwargs) -> Any: >> if not self.ports_started: >> self._logger.debug("Ports need to be started to continue.") >> self.start_all_ports() >> + if get_ctx().topology.type is not LinkTopology.NO_LINK: >> + for port in self.ports: >> + if not self.wait_link_status_up(port.id): >> + raise InteractiveCommandExecutionError(f"Port { >> port.id} link failed to come up.") >> >> return func(self, *args, **kwargs) >> >> @@ -265,7 +272,7 @@ def wait_link_status_up(self, port_id: int, >> timeout=SETTINGS.timeout) -> bool: >> port_info = self.send_command(f"show port info {port_id}") >> if "Link status: up" in port_info: >> break >> - time.sleep(0.5) >> + time.sleep(0.25) >> else: >> self._logger.error(f"The link for port {port_id} did not >> come up in the given timeout.") >> return "Link status: up" in port_info >> -- >> 2.49.0 >> >>