Skip to content

Commit ea9d31a

Browse files
committed
Update test_arm tests with retries
1 parent 6db1913 commit ea9d31a

1 file changed

Lines changed: 60 additions & 16 deletions

File tree

radio/tests/test_arm.py

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
from .helpers import FakeTCP, NoDrone
77

8+
ARM_RETRY_MAX_ATTEMPTS = 5
9+
ARM_RETRY_DELAY_SECS = 2
10+
811

912
@pytest.fixture(scope="module", autouse=True)
1013
def run_once_before_all_tests():
@@ -51,14 +54,61 @@ def assert_drone_armed(droneStatus, armed: bool) -> None:
5154
assert bool(droneStatus.drone.master.motors_armed()) == armed
5255

5356

57+
def arm_with_retries(droneStatus) -> None:
58+
"""Retry direct arming for transient pre-arm check failures."""
59+
for _ in range(ARM_RETRY_MAX_ATTEMPTS):
60+
if droneStatus.drone.armed:
61+
return
62+
63+
droneStatus.drone.master.arducopter_arm()
64+
time.sleep(ARM_RETRY_DELAY_SECS)
65+
66+
if droneStatus.drone.armed and bool(droneStatus.drone.master.motors_armed()):
67+
return
68+
69+
raise AssertionError(
70+
f"Failed to arm after {ARM_RETRY_MAX_ATTEMPTS} attempts with "
71+
f"{ARM_RETRY_DELAY_SECS}s delay"
72+
)
73+
74+
75+
def emit_arm_with_retries(
76+
socketio_client: SocketIOTestClient, force: bool = False
77+
) -> dict:
78+
"""Retry arm_disarm emit until success or max attempts are reached."""
79+
payload = {"arm": True}
80+
if force:
81+
payload["force"] = True
82+
83+
last_response = None
84+
for _ in range(ARM_RETRY_MAX_ATTEMPTS):
85+
socketio_client.emit("arm_disarm", payload)
86+
received = socketio_client.get_received()
87+
88+
if not received:
89+
time.sleep(ARM_RETRY_DELAY_SECS)
90+
continue
91+
92+
last_response = received[0]["args"][0]
93+
if last_response.get("success"):
94+
return last_response
95+
96+
time.sleep(ARM_RETRY_DELAY_SECS)
97+
98+
if last_response is not None:
99+
return last_response
100+
101+
raise AssertionError("No response received for arm_disarm during retries")
102+
103+
54104
def test_arm_succeeds_when_disarmed(
55105
socketio_client: SocketIOTestClient, droneStatus
56106
) -> None:
57107
assert_drone_armed(droneStatus, armed=False)
58108

59-
socketio_client.emit("arm_disarm", {"arm": True})
109+
response = emit_arm_with_retries(socketio_client)
60110

61-
assert socketio_client.get_received()[0]["args"][0] == {
111+
assert response == {
62112
"success": True,
63113
"message": "Armed successfully",
64114
"data": {
@@ -73,8 +123,7 @@ def test_arm_succeeds_when_disarmed(
73123
def test_arm_fails_when_already_armed(
74124
socketio_client: SocketIOTestClient, droneStatus
75125
) -> None:
76-
droneStatus.drone.master.arducopter_arm()
77-
time.sleep(1)
126+
arm_with_retries(droneStatus)
78127
assert_drone_armed(droneStatus, armed=True)
79128

80129
socketio_client.emit("arm_disarm", {"arm": True})
@@ -94,8 +143,7 @@ def test_arm_fails_when_already_armed(
94143
def test_disarm_succeeds_when_armed(
95144
socketio_client: SocketIOTestClient, droneStatus
96145
) -> None:
97-
droneStatus.drone.master.arducopter_arm()
98-
time.sleep(1)
146+
arm_with_retries(droneStatus)
99147
assert_drone_armed(droneStatus, armed=True)
100148

101149
socketio_client.emit("arm_disarm", {"arm": False})
@@ -136,9 +184,9 @@ def test_force_arm_succeeds_when_disarmed(
136184
) -> None:
137185
assert_drone_armed(droneStatus, armed=False)
138186

139-
socketio_client.emit("arm_disarm", {"arm": True, "force": True})
187+
response = emit_arm_with_retries(socketio_client, force=True)
140188

141-
assert socketio_client.get_received()[0]["args"][0] == {
189+
assert response == {
142190
"success": True,
143191
"message": "Armed successfully",
144192
"data": {
@@ -153,8 +201,7 @@ def test_force_arm_succeeds_when_disarmed(
153201
def test_force_arm_fails_when_already_armed(
154202
socketio_client: SocketIOTestClient, droneStatus
155203
) -> None:
156-
droneStatus.drone.master.arducopter_arm()
157-
time.sleep(1)
204+
arm_with_retries(droneStatus)
158205
assert_drone_armed(droneStatus, armed=True)
159206

160207
socketio_client.emit("arm_disarm", {"arm": True, "force": True})
@@ -174,8 +221,7 @@ def test_force_arm_fails_when_already_armed(
174221
def test_force_disarm_succeeds_when_armed(
175222
socketio_client: SocketIOTestClient, droneStatus
176223
) -> None:
177-
droneStatus.drone.master.arducopter_arm()
178-
time.sleep(1)
224+
arm_with_retries(droneStatus)
179225
assert_drone_armed(droneStatus, armed=True)
180226

181227
socketio_client.emit("arm_disarm", {"arm": False, "force": True})
@@ -252,8 +298,7 @@ def test_force_arm_fails_with_serial_exception(
252298
def test_disarm_fails_with_serial_exception(
253299
socketio_client: SocketIOTestClient, droneStatus
254300
) -> None:
255-
droneStatus.drone.master.arducopter_arm()
256-
time.sleep(1)
301+
arm_with_retries(droneStatus)
257302
assert_drone_armed(droneStatus, armed=True)
258303

259304
with FakeTCP():
@@ -273,8 +318,7 @@ def test_disarm_fails_with_serial_exception(
273318
def test_force_disarm_fails_with_serial_exception(
274319
socketio_client: SocketIOTestClient, droneStatus
275320
) -> None:
276-
droneStatus.drone.master.arducopter_arm()
277-
time.sleep(1)
321+
arm_with_retries(droneStatus)
278322
assert_drone_armed(droneStatus, armed=True)
279323

280324
with FakeTCP():

0 commit comments

Comments
 (0)