summaryrefslogtreecommitdiffstats
path: root/Lib/test/_test_multiprocessing.py
diff options
context:
space:
mode:
authorPetr Viktorin <encukou@gmail.com>2024-02-21 12:54:57 (GMT)
committerGitHub <noreply@github.com>2024-02-21 12:54:57 (GMT)
commit4a9e6497c2cae40647589497e033b0b590a180ba (patch)
treeff535e2eee24ed9b466ca4cbf5f9e54888296fad /Lib/test/_test_multiprocessing.py
parentb052fa381fa2ce6820332d56fb22cd7156529d24 (diff)
downloadcpython-4a9e6497c2cae40647589497e033b0b590a180ba.zip
cpython-4a9e6497c2cae40647589497e033b0b590a180ba.tar.gz
cpython-4a9e6497c2cae40647589497e033b0b590a180ba.tar.bz2
gh-104090: Add exit code to multiprocessing ResourceTracker (GH-115410)
This builds on https://github.com/python/cpython/pull/106807, which adds a return code to ResourceTracker, to make future debugging easier. Testing this “in situ” proved difficult, since the global ResourceTracker is involved in test infrastructure. So, the tests here create a new instance and feed it fake data. --------- Co-authored-by: Yonatan Bitton <yonatan.bitton@perception-point.io> Co-authored-by: Yonatan Bitton <bityob@gmail.com> Co-authored-by: Antoine Pitrou <antoine@python.org>
Diffstat (limited to 'Lib/test/_test_multiprocessing.py')
-rw-r--r--Lib/test/_test_multiprocessing.py35
1 files changed, 34 insertions, 1 deletions
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index 94ce85c..e4183ee 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -5609,8 +5609,9 @@ class TestResourceTracker(unittest.TestCase):
'''
for rtype in resource_tracker._CLEANUP_FUNCS:
with self.subTest(rtype=rtype):
- if rtype == "noop":
+ if rtype in ("noop", "dummy"):
# Artefact resource type used by the resource_tracker
+ # or tests
continue
r, w = os.pipe()
p = subprocess.Popen([sys.executable,
@@ -5730,6 +5731,38 @@ class TestResourceTracker(unittest.TestCase):
with self.assertRaises(ValueError):
resource_tracker.register(too_long_name_resource, rtype)
+ def _test_resource_tracker_leak_resources(self, cleanup):
+ # We use a separate instance for testing, since the main global
+ # _resource_tracker may be used to watch test infrastructure.
+ from multiprocessing.resource_tracker import ResourceTracker
+ tracker = ResourceTracker()
+ tracker.ensure_running()
+ self.assertTrue(tracker._check_alive())
+
+ self.assertIsNone(tracker._exitcode)
+ tracker.register('somename', 'dummy')
+ if cleanup:
+ tracker.unregister('somename', 'dummy')
+ expected_exit_code = 0
+ else:
+ expected_exit_code = 1
+
+ self.assertTrue(tracker._check_alive())
+ self.assertIsNone(tracker._exitcode)
+ tracker._stop()
+ self.assertEqual(tracker._exitcode, expected_exit_code)
+
+ def test_resource_tracker_exit_code(self):
+ """
+ Test the exit code of the resource tracker.
+
+ If no leaked resources were found, exit code should be 0, otherwise 1
+ """
+ for cleanup in [True, False]:
+ with self.subTest(cleanup=cleanup):
+ self._test_resource_tracker_leak_resources(
+ cleanup=cleanup,
+ )
class TestSimpleQueue(unittest.TestCase):