@@ -422,6 +422,42 @@ def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2):
422
422
time .sleep (0.05 )
423
423
self ._raise_assertion_error ('Expected messages "{}" does not partially match log:\n \n {}\n \n ' .format (str (expected_msgs ), print_log ))
424
424
425
+ def wait_for_debug_log (self , expected_msgs , timeout = 10 , ignore_case = False ) -> int :
426
+ """
427
+ Block until we see a particular debug log message fragment or until we exceed the timeout.
428
+ Return:
429
+ the number of log lines we encountered when matching
430
+ """
431
+ time_end = time .time () + timeout * self .timeout_factor
432
+ prev_size = self .debug_log_bytes ()
433
+ re_flags = re .MULTILINE | (re .IGNORECASE if ignore_case else 0 )
434
+
435
+ while True :
436
+ found = True
437
+ with open (self .debug_log_path , encoding = 'utf-8' ) as dl :
438
+ dl .seek (prev_size )
439
+ log = dl .read ()
440
+
441
+ for expected_msg in expected_msgs :
442
+ if re .search (re .escape (expected_msg ), log , flags = re_flags ) is None :
443
+ found = False
444
+
445
+ if found :
446
+ num_logs = len (log .splitlines ())
447
+ return num_logs
448
+
449
+ if time .time () >= time_end :
450
+ print_log = " - " + "\n - " .join (log .splitlines ())
451
+ break
452
+
453
+ # No sleep here because we want to detect the message fragment as fast as
454
+ # possible.
455
+
456
+ self ._raise_assertion_error (
457
+ 'Expected messages "{}" does not partially match log:\n \n {}\n \n ' .format (
458
+ str (expected_msgs ), print_log ))
459
+ return - 1 # useless return to satisfy linter
460
+
425
461
@contextlib .contextmanager
426
462
def profile_with_perf (self , profile_name : str ):
427
463
"""
0 commit comments