Skip to content

Commit 7725b56

Browse files
committed
test: home_all retries home(-1) and dumps stat on timeout
CI run hit 'timeout waiting for all joints homed after 60.0s' on qtdragon only; locally homing completes in <4s on all four sims. Likely cause: same task_mode revert race as ensure_mode catches for MODE_AUTO, except home() lives outside that helper, so a mid-sequence mode flip back to a non-MANUAL mode silently drops the home command. Wrap the post-c.home(-1) wait in a poll loop that re-asserts MANUAL and re-issues home(-1) every HOME_REISSUE_S (10s). Final timeout now also dumps homed[], task_state, task_mode and exec_state so the next CI failure has actionable diagnostics.
1 parent 839460c commit 7725b56

1 file changed

Lines changed: 32 additions & 9 deletions

File tree

tests/ui-smoke/_lib/drive.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,28 +86,51 @@ def wait_until(stat, predicate, timeout, label):
8686
return False
8787

8888

89+
HOME_REISSUE_S = 10.0
90+
91+
8992
def home_all(cmd, stat, timeout):
9093
"""Home every joint. Uses c.home(-1) which respects HOME_SEQUENCE
9194
if configured. Caller must have already ensured task_state is ON
9295
via ensure_state; otherwise the home command is rejected with
9396
'cannot be executed until the machine is out of E-stop and turned
9497
on'. Mode change uses ensure_mode so a GUI that reverts mode mid-
95-
sequence (gmoccapy) is detected and retried."""
98+
sequence (gmoccapy) is detected and retried. The outer poll loop
99+
re-issues c.home(-1) every HOME_REISSUE_S in case a GUI swallowed
100+
the first one by switching mode after we set it (qtdragon CI)."""
96101
if not ensure_mode(cmd, stat, linuxcnc.MODE_MANUAL, "MODE_MANUAL"):
97102
return False
98103
cmd.teleop_enable(0)
99104
cmd.wait_complete()
100105
stat.poll()
101106
njoints = stat.joints
102107
cmd.home(-1)
103-
if not wait_until(
104-
stat,
105-
lambda s: all(s.homed[i] for i in range(njoints)),
106-
timeout, "all joints homed"):
107-
return False
108-
cmd.teleop_enable(1)
109-
cmd.wait_complete()
110-
return True
108+
109+
deadline = time.monotonic() + timeout
110+
next_reissue = time.monotonic() + HOME_REISSUE_S
111+
while time.monotonic() < deadline:
112+
stat.poll()
113+
if all(stat.homed[i] for i in range(njoints)):
114+
cmd.teleop_enable(1)
115+
cmd.wait_complete()
116+
return True
117+
if time.monotonic() >= next_reissue:
118+
# Re-assert MANUAL in case it got reverted, then re-home.
119+
cmd.mode(linuxcnc.MODE_MANUAL)
120+
cmd.wait_complete()
121+
cmd.home(-1)
122+
sys.stderr.write(
123+
f"WARN: re-issued home(-1); homed={list(stat.homed[:njoints])} "
124+
f"task_state={stat.task_state} task_mode={stat.task_mode}\n")
125+
next_reissue = time.monotonic() + HOME_REISSUE_S
126+
time.sleep(POLL_INTERVAL_S)
127+
stat.poll()
128+
sys.stderr.write(
129+
f"UI_SMOKE_FAIL: timeout waiting for all joints homed after "
130+
f"{timeout}s; homed={list(stat.homed[:njoints])} "
131+
f"task_state={stat.task_state} task_mode={stat.task_mode} "
132+
f"exec_state={stat.exec_state} njoints={njoints}\n")
133+
return False
111134

112135

113136
def wait_state(stat, target_state, timeout, label):

0 commit comments

Comments
 (0)