Skip to content

Commit c8bdffe

Browse files
authored
Allow custom error messages in snippet waitForEvent. (#989)
1 parent 6aa5809 commit c8bdffe

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

mobly/snippet/callback_handler_base.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"""Module for the base class to handle Mobly Snippet Lib's callback events."""
1515
import abc
1616
import time
17+
from typing import Callable
1718

1819
from mobly.snippet import callback_event
1920
from mobly.snippet import errors
@@ -178,7 +179,13 @@ def waitAndGet(self, event_name, timeout=None):
178179
raw_event = self.callEventWaitAndGetRpc(self._id, event_name, timeout)
179180
return callback_event.from_dict(raw_event)
180181

181-
def waitForEvent(self, event_name, predicate, timeout=None):
182+
def waitForEvent(
183+
self,
184+
event_name: str,
185+
predicate: Callable[[callback_event.CallbackEvent], bool],
186+
timeout: float | None = None,
187+
message: str | None = None,
188+
) -> callback_event.CallbackEvent:
182189
"""Waits for an event of the specific name that satisfies the predicate.
183190
184191
This call will block until the expected event has been received or time
@@ -194,13 +201,13 @@ def waitForEvent(self, event_name, predicate, timeout=None):
194201
195202
Args:
196203
event_name: str, the name of the event to wait for.
197-
predicate: function, a function that takes an event (dictionary) and
198-
returns a bool.
204+
predicate: function, the predicate used to test events.
199205
timeout: float, the number of seconds to wait before giving up. If None,
200206
it will be set to self.default_timeout_sec.
207+
message: str, an optional error message to include if there is a timeout.
201208
202209
Returns:
203-
dictionary, the event that satisfies the predicate if received.
210+
CallbackEvent, the event that satisfies the predicate if received.
204211
205212
Raises:
206213
errors.CallbackHandlerTimeoutError: raised if no event that satisfies the
@@ -225,10 +232,11 @@ def waitForEvent(self, event_name, predicate, timeout=None):
225232
if predicate(event):
226233
return event
227234

235+
custom_error = '' if message is None else f' Details: {message}.'
228236
raise errors.CallbackHandlerTimeoutError(
229237
self._device,
230238
f'Timed out after {timeout}s waiting for an "{event_name}" event that '
231-
f'satisfies the predicate "{predicate.__name__}".',
239+
f'satisfies the predicate "{predicate.__name__}".{custom_error}',
232240
)
233241

234242
def getAll(self, event_name):

tests/mobly/snippet/callback_handler_base_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,24 @@ def some_condition(event):
153153
event = handler.waitForEvent('AsyncTaskResult', some_condition, 0.01)
154154
self.assert_event_correct(event, MOCK_RAW_EVENT)
155155

156+
def test_wait_for_event_negative_with_custom_message(self):
157+
handler = FakeCallbackHandler()
158+
handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(
159+
return_value=MOCK_RAW_EVENT
160+
)
161+
162+
expected_msg = (
163+
'Timed out after 0.01s waiting for an "AsyncTaskResult" event that'
164+
' satisfies the predicate "<lambda>". Details: Failed for test.'
165+
)
166+
167+
with self.assertRaisesRegex(
168+
errors.CallbackHandlerTimeoutError, expected_msg
169+
):
170+
handler.waitForEvent(
171+
'AsyncTaskResult', lambda _: False, 0.01, 'Failed for test'
172+
)
173+
156174
def test_wait_for_event_negative(self):
157175
handler = FakeCallbackHandler()
158176
handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(

0 commit comments

Comments
 (0)