From 91af60c47b79eff241cf545a4e193c3d2c946fb7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 27 Sep 2023 10:28:20 +0300 Subject: [PATCH 1/5] WIP: gh-109700: Make stress tests on interpreter creation more stressful --- Lib/test/test_interpreters.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py index 90932c0f66f38f..6681fe13910f73 100644 --- a/Lib/test/test_interpreters.py +++ b/Lib/test/test_interpreters.py @@ -475,16 +475,22 @@ def test_create_many_sequential(self): for _ in range(100): interp = interpreters.create() alive.append(interp) + del alive + support.gc_collect() @support.requires_resource('cpu') def test_create_many_threaded(self): alive = [] + start = threading.Event() def task(): + start.wait(10) interp = interpreters.create() alive.append(interp) - threads = (threading.Thread(target=task) for _ in range(200)) + threads = [threading.Thread(target=task) for _ in range(200)] with threading_helper.start_threads(threads): - pass + start.set() + del alive + support.gc_collect() class TestIsShareable(TestBase): From 18031c93bf6f8647747aff75e7e89508da0a5e02 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 27 Sep 2023 11:09:58 +0300 Subject: [PATCH 2/5] Use less threads. --- Lib/test/test_interpreters.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py index 6681fe13910f73..839973f6e0b739 100644 --- a/Lib/test/test_interpreters.py +++ b/Lib/test/test_interpreters.py @@ -483,10 +483,12 @@ def test_create_many_threaded(self): alive = [] start = threading.Event() def task(): - start.wait(10) - interp = interpreters.create() - alive.append(interp) - threads = [threading.Thread(target=task) for _ in range(200)] + if not start.wait(10): + raise TimeoutError + for _ in range(20): + interp = interpreters.create() + alive.append(interp) + threads = [threading.Thread(target=task) for _ in range(10)] with threading_helper.start_threads(threads): start.set() del alive From 6aecbf923374aed3c75003a38afe87d0fbf6ddae Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 8 Nov 2023 23:03:15 +0200 Subject: [PATCH 3/5] Mark test_create_many_threaded with bigmemtest. --- Lib/test/test_interpreters.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py index e61bf07054d748..1a9ae81faad956 100644 --- a/Lib/test/test_interpreters.py +++ b/Lib/test/test_interpreters.py @@ -591,16 +591,17 @@ def test_create_many_sequential(self): support.gc_collect() @support.requires_resource('cpu') - def test_create_many_threaded(self): + @support.bigmemtest(size=6.39*2**30, memuse=1, dry_run=False) + def test_create_many_threaded(self, size): alive = [] start = threading.Event() def task(): + # try to create all interpreters simultaneously if not start.wait(10): raise TimeoutError - for _ in range(20): - interp = interpreters.create() - alive.append(interp) - threads = [threading.Thread(target=task) for _ in range(10)] + interp = interpreters.create() + alive.append(interp) + threads = [threading.Thread(target=task) for _ in range(200)] with threading_helper.start_threads(threads): start.set() del alive From 5dd48d6aa1de25905ad43e13001aa72f596aa3ee Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 May 2025 20:36:50 +0300 Subject: [PATCH 4/5] Add guards also for other stress tests. --- Lib/test/test_interpreters/test_stress.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_interpreters/test_stress.py b/Lib/test/test_interpreters/test_stress.py index 88436ac4e1b57d..b7655615423e0b 100644 --- a/Lib/test/test_interpreters/test_stress.py +++ b/Lib/test/test_interpreters/test_stress.py @@ -16,14 +16,17 @@ class StressTests(TestBase): # but not so many that any test takes too long. @support.requires_resource('cpu') - def test_create_many_sequential(self): + @support.bigmemtest(size=100, memuse=6.2*2**20, dry_run=False) + def test_create_many_sequential(self, size): alive = [] - for _ in range(100): + for _ in range(size): interp = interpreters.create() alive.append(interp) + del alive + support.gc_collect() @support.requires_resource('cpu') - @support.bigmemtest(size=6.39*2**30, memuse=1, dry_run=False) + @support.bigmemtest(size=200, memuse=32*2**20, dry_run=False) def test_create_many_threaded(self, size): alive = [] start = threading.Event() @@ -33,7 +36,7 @@ def task(): raise TimeoutError interp = interpreters.create() alive.append(interp) - threads = [threading.Thread(target=task) for _ in range(200)] + threads = [threading.Thread(target=task) for _ in range(size)] with threading_helper.start_threads(threads): start.set() del alive @@ -41,7 +44,9 @@ def task(): @support.requires_resource('cpu') @threading_helper.requires_working_threading() - def test_many_threads_running_interp_in_other_interp(self): + @support.bigmemtest(size=200, memuse=32*2**20, dry_run=False) + def test_many_threads_running_interp_in_other_interp(self, size): + start = threading.Event() interp = interpreters.create() script = f"""if True: @@ -50,6 +55,9 @@ def test_many_threads_running_interp_in_other_interp(self): """ def run(): + # try to create all interpreters simultaneously + if not start.wait(10): + raise TimeoutError interp = interpreters.create() alreadyrunning = (f'{interpreters.InterpreterError}: ' 'interpreter already running') @@ -64,9 +72,9 @@ def run(): else: success = True - threads = (threading.Thread(target=run) for _ in range(200)) + threads = [threading.Thread(target=run) for _ in range(size)] with threading_helper.start_threads(threads): - pass + start.set() if __name__ == '__main__': From b3cf0b30ba81da65a14078d8a5338389ea373277 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 May 2025 21:14:46 +0300 Subject: [PATCH 5/5] Polishing. --- Lib/test/test_interpreters/test_stress.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_interpreters/test_stress.py b/Lib/test/test_interpreters/test_stress.py index b7655615423e0b..fae2f38cb5534b 100644 --- a/Lib/test/test_interpreters/test_stress.py +++ b/Lib/test/test_interpreters/test_stress.py @@ -16,23 +16,21 @@ class StressTests(TestBase): # but not so many that any test takes too long. @support.requires_resource('cpu') - @support.bigmemtest(size=100, memuse=6.2*2**20, dry_run=False) - def test_create_many_sequential(self, size): + def test_create_many_sequential(self): alive = [] - for _ in range(size): + for _ in range(100): interp = interpreters.create() alive.append(interp) del alive support.gc_collect() - @support.requires_resource('cpu') @support.bigmemtest(size=200, memuse=32*2**20, dry_run=False) def test_create_many_threaded(self, size): alive = [] start = threading.Event() def task(): # try to create all interpreters simultaneously - if not start.wait(10): + if not start.wait(support.SHORT_TIMEOUT): raise TimeoutError interp = interpreters.create() alive.append(interp) @@ -42,9 +40,8 @@ def task(): del alive support.gc_collect() - @support.requires_resource('cpu') @threading_helper.requires_working_threading() - @support.bigmemtest(size=200, memuse=32*2**20, dry_run=False) + @support.bigmemtest(size=200, memuse=34*2**20, dry_run=False) def test_many_threads_running_interp_in_other_interp(self, size): start = threading.Event() interp = interpreters.create() @@ -55,12 +52,12 @@ def test_many_threads_running_interp_in_other_interp(self, size): """ def run(): - # try to create all interpreters simultaneously - if not start.wait(10): - raise TimeoutError interp = interpreters.create() alreadyrunning = (f'{interpreters.InterpreterError}: ' 'interpreter already running') + # try to run all interpreters simultaneously + if not start.wait(support.SHORT_TIMEOUT): + raise TimeoutError success = False while not success: try: @@ -75,6 +72,7 @@ def run(): threads = [threading.Thread(target=run) for _ in range(size)] with threading_helper.start_threads(threads): start.set() + support.gc_collect() if __name__ == '__main__':