@@ -38,31 +38,41 @@ def logcat_thread():
38
38
for line in self .logcat_process .stdout :
39
39
self .logcat_queue .put (line .rstrip ("\n " ))
40
40
self .logcat_process .stdout .close ()
41
+
41
42
self .logcat_thread = Thread (target = logcat_thread )
42
43
self .logcat_thread .start ()
43
44
44
- from ctypes import CDLL , c_char_p , c_int
45
- android_log_write = getattr (CDLL ("liblog.so" ), "__android_log_write" )
46
- android_log_write .argtypes = (c_int , c_char_p , c_char_p )
47
- ANDROID_LOG_INFO = 4
48
-
49
- # Separate tests using a marker line with a different tag.
50
- tag , message = "python.test" , f"{ self .id ()} { time ()} "
51
- android_log_write (
52
- ANDROID_LOG_INFO , tag .encode ("UTF-8" ), message .encode ("UTF-8" ))
53
- self .assert_log ("I" , tag , message , skip = True , timeout = 5 )
45
+ try :
46
+ from ctypes import CDLL , c_char_p , c_int
47
+ android_log_write = getattr (CDLL ("liblog.so" ), "__android_log_write" )
48
+ android_log_write .argtypes = (c_int , c_char_p , c_char_p )
49
+ ANDROID_LOG_INFO = 4
50
+
51
+ # Separate tests using a marker line with a different tag.
52
+ tag , message = "python.test" , f"{ self .id ()} { time ()} "
53
+ android_log_write (
54
+ ANDROID_LOG_INFO , tag .encode ("UTF-8" ), message .encode ("UTF-8" ))
55
+ self .assert_log ("I" , tag , message , skip = True )
56
+ except :
57
+ # If setUp throws an exception, tearDown is not automatically
58
+ # called. Avoid leaving a dangling thread which would keep the
59
+ # Python process alive indefinitely.
60
+ self .tearDown ()
61
+ raise
54
62
55
63
def assert_logs (self , level , tag , expected , ** kwargs ):
56
64
for line in expected :
57
65
self .assert_log (level , tag , line , ** kwargs )
58
66
59
- def assert_log (self , level , tag , expected , * , skip = False , timeout = 0.5 ):
60
- deadline = time () + timeout
67
+ def assert_log (self , level , tag , expected , * , skip = False ):
68
+ deadline = time () + LOOPBACK_TIMEOUT
61
69
while True :
62
70
try :
63
71
line = self .logcat_queue .get (timeout = (deadline - time ()))
64
72
except queue .Empty :
65
- self .fail (f"line not found: { expected !r} " )
73
+ raise self .failureException (
74
+ f"line not found: { expected !r} "
75
+ ) from None
66
76
if match := re .fullmatch (fr"(.)/{ tag } : (.*)" , line ):
67
77
try :
68
78
self .assertEqual (level , match [1 ])
@@ -77,6 +87,9 @@ def tearDown(self):
77
87
self .logcat_process .wait (LOOPBACK_TIMEOUT )
78
88
self .logcat_thread .join (LOOPBACK_TIMEOUT )
79
89
90
+ # Avoid an irrelevant warning about threading._dangling.
91
+ self .logcat_thread = None
92
+
80
93
@contextmanager
81
94
def unbuffered (self , stream ):
82
95
stream .reconfigure (write_through = True )
0 commit comments