Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7f13df4

Browse files
mhsmithmiss-islington
authored andcommitted
gh-124666: Improve thread cleanup in test_android (GH-131427)
Ensures that failures in test setup don't result in dangling threads. (cherry picked from commit 01b5abb) Co-authored-by: Malcolm Smith <[email protected]>
1 parent 31767e6 commit 7f13df4

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

Lib/test/test_android.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)