Skip to content

Commit

Permalink
Run test_asyncio and test_compiler sub-tests in parallel
Browse files Browse the repository at this point in the history
Summary:
These two tests are typically the long-poles in runs because they are modules with a lot of further sub-tests run serially. By breaking out the sub-tests as independent modules we can run a lot more in parallel.

The real win comes in the next diff but with this change alone on my devserver:
* With a debug build:
  * `time make testcinder` goes from ~25m -> ~19m.
  * `time make testcinder_jit` goes from ~26m -> ~18m.
* With a release build:
  * `time make testcinder` goes from ~6m15s -> ~4m45s.
  * `time make testcinder_jit` goes from ~6m -> ~5m30s.

While this is a bit hacky and annoyingly involves changing CPython test infra, I think the maintenance overhead is worth it. It's not a complicated change and I think the win in productivity with the diff above is significant.

Reviewed By: sinancepel

Differential Revision: D35383641

fbshipit-source-id: eaacb81
  • Loading branch information
jbower-fb authored and facebook-github-bot committed Apr 7, 2022
1 parent 09becce commit 3c6be01
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
28 changes: 25 additions & 3 deletions Lib/test/libregrtest/runtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@
# set of tests that we don't want to be executed when using regrtest
NOTTESTS = set()

# If these test directories are encountered recurse into them and treat each
# test_ .py or dir as a separate test module. This can increase parallelism.
# Beware this can't generally be done for any directory with sub-tests as the
# __init__.py may do things which alter what tests are to be run.
SPLITTESTDIRS = {
"test_asyncio",
"test_compiler",
}

# used by --findleaks, store for gc.garbage
FOUND_GARBAGE = []
Expand All @@ -87,16 +95,30 @@ def findtestdir(path=None):
return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir


def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
def findtests(
testdir=None,
stdtests=STDTESTS,
nottests=NOTTESTS,
splittestdirs=SPLITTESTDIRS,
base_mod="",
):
"""Return a list of all applicable test modules."""
testdir = findtestdir(testdir)
names = os.listdir(testdir)
tests = []
others = set(stdtests) | nottests
for name in names:
mod, ext = os.path.splitext(name)
if mod[:5] == "test_" and ext in (".py", "") and mod not in others:
tests.append(mod)
if mod[:5] == "test_" and mod not in others:
if mod in splittestdirs:
subdir = os.path.join(testdir, mod)
if len(base_mod):
mod = f"{base_mod}.{mod}"
else:
mod = f"test.{mod}"
tests.extend(findtests(subdir, [], nottests, splittestdirs, mod))
elif ext in (".py", ""):
tests.append(f"{base_mod}.{mod}" if len(base_mod) else mod)
return stdtests + sorted(tests)


Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_asyncio/test_sock_lowlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
from test import support


def tearDownModule():
asyncio.set_event_loop_policy(None)


class MyProto(asyncio.Protocol):
connected = None
done = None
Expand Down

0 comments on commit 3c6be01

Please sign in to comment.