]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-129441: Fix some flakiness in test_instrumentation (gh-141881) (gh-141913)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 24 Nov 2025 16:44:54 +0000 (17:44 +0100)
committerGitHub <noreply@github.com>
Mon, 24 Nov 2025 16:44:54 +0000 (16:44 +0000)
Most of the `self.assertTrue(self.called)` checks are flaky because
the worker threads may sometimes finish before the main thread calls
`self.during_threads()`.
(cherry picked from commit 71126ab19c76d8227fc3b9c7c59b957ca82af4dd)

Co-authored-by: Sam Gross <colesbury@gmail.com>
Lib/test/test_free_threading/test_monitoring.py

index 4fbd3f3415cb322609d640f16467e0281afc5632..2cd6e7b035ecb41b0ccde6cffacdb0433d01279a 100644 (file)
@@ -35,10 +35,10 @@ class InstrumentationMultiThreadedMixin:
             return n
         return self.work(n - 1, funcs) + self.work(n - 2, funcs)
 
-    def start_work(self, n, funcs):
+    def start_work(self, n, funcs, barrier):
         # With the GIL builds we need to make sure that the hooks have
         # a chance to run as it's possible to run w/o releasing the GIL.
-        time.sleep(0.1)
+        barrier.wait()
         self.work(n, funcs)
 
     def after_test(self):
@@ -53,14 +53,16 @@ class InstrumentationMultiThreadedMixin:
             exec("def f(): pass", x)
             funcs.append(x["f"])
 
+        barrier = Barrier(self.thread_count + 1)
         threads = []
         for i in range(self.thread_count):
             # Each thread gets a copy of the func list to avoid contention
-            t = Thread(target=self.start_work, args=(self.fib, list(funcs)))
+            t = Thread(target=self.start_work, args=(self.fib, list(funcs), barrier))
             t.start()
             threads.append(t)
 
         self.after_threads()
+        barrier.wait()
 
         while True:
             any_alive = False
@@ -120,7 +122,6 @@ class MonitoringMultiThreaded(
     def setUp(self):
         super().setUp()
         self.set = False
-        self.called = False
         monitoring.register_callback(
             self.tool_id, monitoring.events.LINE, self.callback
         )
@@ -130,10 +131,7 @@ class MonitoringMultiThreaded(
         super().tearDown()
 
     def callback(self, *args):
-        self.called = True
-
-    def after_test(self):
-        self.assertTrue(self.called)
+        pass
 
     def during_threads(self):
         if self.set:
@@ -151,16 +149,11 @@ class SetTraceMultiThreaded(InstrumentationMultiThreadedMixin, TestCase):
 
     def setUp(self):
         self.set = False
-        self.called = False
-
-    def after_test(self):
-        self.assertTrue(self.called)
 
     def tearDown(self):
         sys.settrace(None)
 
     def trace_func(self, frame, event, arg):
-        self.called = True
         return self.trace_func
 
     def during_threads(self):
@@ -177,16 +170,11 @@ class SetProfileMultiThreaded(InstrumentationMultiThreadedMixin, TestCase):
 
     def setUp(self):
         self.set = False
-        self.called = False
-
-    def after_test(self):
-        self.assertTrue(self.called)
 
     def tearDown(self):
         sys.setprofile(None)
 
     def trace_func(self, frame, event, arg):
-        self.called = True
         return self.trace_func
 
     def during_threads(self):
@@ -203,16 +191,11 @@ class SetProfileAllThreadsMultiThreaded(InstrumentationMultiThreadedMixin, TestC
 
     def setUp(self):
         self.set = False
-        self.called = False
-
-    def after_test(self):
-        self.assertTrue(self.called)
 
     def tearDown(self):
         threading.setprofile_all_threads(None)
 
     def trace_func(self, frame, event, arg):
-        self.called = True
         return self.trace_func
 
     def during_threads(self):