@@ -42,31 +42,41 @@ def logcat_thread():
42
42
for line in self .logcat_process .stdout :
43
43
self .logcat_queue .put (line .rstrip ("\n " ))
44
44
self .logcat_process .stdout .close ()
45
+
45
46
self .logcat_thread = Thread (target = logcat_thread )
46
47
self .logcat_thread .start ()
47
48
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
58
66
59
67
def assert_logs (self , level , tag , expected , ** kwargs ):
60
68
for line in expected :
61
69
self .assert_log (level , tag , line , ** kwargs )
62
70
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
65
73
while True :
66
74
try :
67
75
line = self .logcat_queue .get (timeout = (deadline - time ()))
68
76
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
70
80
if match := re .fullmatch (fr"(.)/{ tag } : (.*)" , line ):
71
81
try :
72
82
self .assertEqual (level , match [1 ])
@@ -81,6 +91,9 @@ def tearDown(self):
81
91
self .logcat_process .wait (LOOPBACK_TIMEOUT )
82
92
self .logcat_thread .join (LOOPBACK_TIMEOUT )
83
93
94
+ # Avoid an irrelevant warning about threading._dangling.
95
+ self .logcat_thread = None
96
+
84
97
@contextmanager
85
98
def unbuffered (self , stream ):
86
99
stream .reconfigure (write_through = True )
0 commit comments