blob: 80280282a8f3ccb97ac6ceeae89430746597803f [file] [log] [blame]
#!/usr/bin/env python3
import subprocess
from subprocess import Popen
from os import system
from sys import argv, exit, platform, executable, version_info
# Use the Python provided to execute the script, or fall back to a sane default
if version_info >= (3, 5, 0):
python_name = executable
else:
if platform == 'win32':
python_name = 'py -3'
else:
python_name = 'python3'
# Slow test suites
CMDLINE = 'PythonCmdline'
SAMPLES = 'SamplesSuite'
TYPESHED = 'TypeshedSuite'
PEP561 = 'TestPEP561'
EVALUATION = 'PythonEvaluation'
DAEMON = 'testdaemon'
STUBGEN_CMD = 'StubgenCmdLine'
STUBGEN_PY = 'StubgenPythonSuite'
MYPYC_RUN = 'TestRun'
MYPYC_RUN_MULTI = 'TestRunMultiFile'
MYPYC_EXTERNAL = 'TestExternal'
MYPYC_COMMAND_LINE = 'TestCommandLine'
ERROR_STREAM = 'ErrorStreamSuite'
STUBTEST = 'StubtestUnit'
STUBTEST_MISC = 'StubtestMiscUnit'
STUBTEST_INTEGRATION = 'StubtestIntegration'
ALL_NON_FAST = [
CMDLINE,
SAMPLES,
TYPESHED,
PEP561,
EVALUATION,
DAEMON,
STUBGEN_CMD,
STUBGEN_PY,
MYPYC_RUN,
MYPYC_RUN_MULTI,
MYPYC_EXTERNAL,
MYPYC_COMMAND_LINE,
ERROR_STREAM,
STUBTEST,
STUBTEST_MISC,
STUBTEST_INTEGRATION,
]
# These must be enabled by explicitly including 'mypyc-extra' on the command line.
MYPYC_OPT_IN = [MYPYC_RUN,
MYPYC_RUN_MULTI]
# These must be enabled by explicitly including 'stubtest' on the command line.
STUBTEST_OPT_IN = [STUBTEST, STUBTEST_MISC, STUBTEST_INTEGRATION]
# We split the pytest run into three parts to improve test
# parallelization. Each run should have tests that each take a roughly similar
# time to run.
cmds = {
# Self type check
'self': python_name + ' -m mypy --config-file mypy_self_check.ini -p mypy',
# Lint
'lint': 'flake8 -j0',
# Fast test cases only (this is the bulk of the test suite)
'pytest-fast': 'pytest -k "not (%s)"' % ' or '.join(ALL_NON_FAST),
# Test cases that invoke mypy (with small inputs)
'pytest-cmdline': 'pytest -k "%s"' % ' or '.join([CMDLINE,
EVALUATION,
STUBGEN_CMD,
STUBGEN_PY]),
# Test cases that may take seconds to run each
'pytest-slow': 'pytest -k "%s"' % ' or '.join(
[SAMPLES,
TYPESHED,
PEP561,
DAEMON,
MYPYC_EXTERNAL,
MYPYC_COMMAND_LINE,
ERROR_STREAM]),
# Mypyc tests that aren't run by default, since they are slow and rarely
# fail for commits that don't touch mypyc
'mypyc-extra': 'pytest -k "%s"' % ' or '.join(MYPYC_OPT_IN),
'stubtest': 'pytest -k "%s"' % ' or '.join(STUBTEST_OPT_IN),
}
# Stop run immediately if these commands fail
FAST_FAIL = ['self', 'lint']
DEFAULT_COMMANDS = [cmd for cmd in cmds if cmd != 'mypyc-extra']
assert all(cmd in cmds for cmd in FAST_FAIL)
def run_cmd(name: str) -> int:
status = 0
cmd = cmds[name]
print('run %s: %s' % (name, cmd))
res = (system(cmd) & 0x7F00) >> 8
if res:
print('\nFAILED: %s' % name)
status = res
if name in FAST_FAIL:
exit(status)
return status
def start_background_cmd(name: str) -> Popen:
cmd = cmds[name]
proc = subprocess.Popen(cmd,
shell=True,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE)
return proc
def wait_background_cmd(name: str, proc: Popen) -> int:
output = proc.communicate()[0]
status = proc.returncode
print('run %s: %s' % (name, cmds[name]))
if status:
print(output.decode().rstrip())
print('\nFAILED: %s' % name)
if name in FAST_FAIL:
exit(status)
return status
def main() -> None:
prog, *args = argv
if not set(args).issubset(cmds):
print("usage:", prog, " ".join('[%s]' % k for k in cmds))
print()
print('Run the given tests. If given no arguments, run everything except mypyc-extra.')
exit(1)
if not args:
args = DEFAULT_COMMANDS[:]
status = 0
if 'self' in args and 'lint' in args:
# Perform lint and self check in parallel as it's faster.
proc = start_background_cmd('lint')
cmd_status = run_cmd('self')
if cmd_status:
status = cmd_status
cmd_status = wait_background_cmd('lint', proc)
if cmd_status:
status = cmd_status
args = [arg for arg in args if arg not in ('self', 'lint')]
for arg in args:
cmd_status = run_cmd(arg)
if cmd_status:
status = cmd_status
exit(status)
if __name__ == '__main__':
main()