@@ -42,31 +42,41 @@ def logcat_thread():
4242 for line in self .logcat_process .stdout :
4343 self .logcat_queue .put (line .rstrip ("\n " ))
4444 self .logcat_process .stdout .close ()
45+
4546 self .logcat_thread = Thread (target = logcat_thread )
4647 self .logcat_thread .start ()
4748
48- from ctypes import CDLL , c_char_p , c_int
49- android_log_write = getattr (CDLL ("liblog.so" ), "__android_log_write" )
50- android_log_write .argtypes = (c_int , c_char_p , c_char_p )
51- ANDROID_LOG_INFO = 4
52-
53- # Separate tests using a marker line with a different tag.
54- tag , message = "python.test" , f"{ self .id ()} { time ()} "
55- android_log_write (
56- ANDROID_LOG_INFO , tag .encode ("UTF-8" ), message .encode ("UTF-8" ))
57- self .assert_log ("I" , tag , message , skip = True , timeout = 5 )
49+ try :
50+ from ctypes import CDLL , c_char_p , c_int
51+ android_log_write = getattr (CDLL ("liblog.so" ), "__android_log_write" )
52+ android_log_write .argtypes = (c_int , c_char_p , c_char_p )
53+ ANDROID_LOG_INFO = 4
54+
55+ # Separate tests using a marker line with a different tag.
56+ tag , message = "python.test" , f"{ self .id ()} { time ()} "
57+ android_log_write (
58+ ANDROID_LOG_INFO , tag .encode ("UTF-8" ), message .encode ("UTF-8" ))
59+ self .assert_log ("I" , tag , message , skip = True )
60+ except :
61+ # If setUp throws an exception, tearDown is not automatically
62+ # called. Avoid leaving a dangling thread which would keep the
63+ # Python process alive indefinitely.
64+ self .tearDown ()
65+ raise
5866
5967 def assert_logs (self , level , tag , expected , ** kwargs ):
6068 for line in expected :
6169 self .assert_log (level , tag , line , ** kwargs )
6270
63- def assert_log (self , level , tag , expected , * , skip = False , timeout = 0.5 ):
64- deadline = time () + timeout
71+ def assert_log (self , level , tag , expected , * , skip = False ):
72+ deadline = time () + LOOPBACK_TIMEOUT
6573 while True :
6674 try :
6775 line = self .logcat_queue .get (timeout = (deadline - time ()))
6876 except queue .Empty :
69- self .fail (f"line not found: { expected !r} " )
77+ raise self .failureException (
78+ f"line not found: { expected !r} "
79+ ) from None
7080 if match := re .fullmatch (fr"(.)/{ tag } : (.*)" , line ):
7181 try :
7282 self .assertEqual (level , match [1 ])
@@ -81,6 +91,9 @@ def tearDown(self):
8191 self .logcat_process .wait (LOOPBACK_TIMEOUT )
8292 self .logcat_thread .join (LOOPBACK_TIMEOUT )
8393
94+ # Avoid an irrelevant warning about threading._dangling.
95+ self .logcat_thread = None
96+
8497 @contextmanager
8598 def unbuffered (self , stream ):
8699 stream .reconfigure (write_through = True )
0 commit comments