2020-10-16 08:46:28 +03:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
|
|
#
|
|
|
|
# This software may be used and distributed according to the terms of the
|
|
|
|
# GNU General Public License version 2.
|
|
|
|
|
|
|
|
|
|
|
|
import concurrent.futures
|
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
def extraargs(manifestpath):
|
|
|
|
"""Extra CLI args for 'cargo test'"""
|
|
|
|
args = []
|
|
|
|
with open(manifestpath, "rb") as f:
|
|
|
|
manifest = f.read()
|
|
|
|
if b"fb =" in manifest:
|
|
|
|
args += ["--features=fb"]
|
|
|
|
return args
|
|
|
|
|
|
|
|
|
|
|
|
def runtest(manifestpath):
|
|
|
|
cargo = os.getenv("CARGO", "cargo")
|
|
|
|
name = os.path.dirname(manifestpath)
|
|
|
|
try:
|
|
|
|
os.unlink(os.path.join(name, "Cargo.lock"))
|
|
|
|
except OSError:
|
|
|
|
pass
|
|
|
|
args = [cargo, "test", "-q", "--no-fail-fast"] + extraargs(manifestpath)
|
|
|
|
try:
|
|
|
|
subprocess.check_output(args, cwd=name, stderr=subprocess.PIPE)
|
|
|
|
return None
|
|
|
|
except subprocess.CalledProcessError as ex:
|
|
|
|
if b"failures:" in ex.stdout:
|
|
|
|
# Only show stdout which contains test failure information.
|
|
|
|
# stderr might have warnings and are noisy.
|
|
|
|
return (1, name, ex.stdout.decode("utf-8", "ignore"))
|
|
|
|
elif b"linking with `cc` failed" in ex.stderr:
|
|
|
|
# Could happen when python cannot be found.
|
|
|
|
# Do not consider it as fatal.
|
|
|
|
return (0, name, ex.stderr.decode("utf-8", "ignore"))
|
2020-10-20 03:05:23 +03:00
|
|
|
elif b"LLVM ERROR: invalid" in ex.stderr:
|
|
|
|
# ex. LLVM ERROR: invalid sh_type for string table section [index
|
|
|
|
# 45]: expected SHT_STRTAB, but got SHT_NULL
|
|
|
|
# Not fatal.
|
|
|
|
return (0, name, ex.stderr.decode("utf-8", "ignore"))
|
2020-10-16 08:46:28 +03:00
|
|
|
elif b"could not compile" in ex.stderr:
|
|
|
|
# Only show stderr with information about how it fails
|
|
|
|
# to compile.
|
|
|
|
return (1, name, ex.stderr.decode("utf-8", "ignore"))
|
|
|
|
else:
|
|
|
|
# Could be flaky tests on Windows. For example:
|
|
|
|
#
|
|
|
|
# warning: Error finalizing incremental compilation session directory `...`: Access is denied. (os error 5)
|
|
|
|
# warning: 1 warning emitted
|
|
|
|
# warning: Error finalizing incremental compilation session directory `...`: Access is denied. (os error 5)
|
|
|
|
# warning: 1 warning emitted
|
|
|
|
# error: test failed, to rerun pass '--lib'
|
|
|
|
# Caused by:
|
|
|
|
# process didn't exit successfully: `...\cpython_async-53e9eb016c0c638f.exe --quiet` (exit code: 0xc0000135, STATUS_DLL_NOT_FOUND)
|
|
|
|
#
|
|
|
|
# running 1 test
|
|
|
|
# test src\stream.rs - stream::TStream (line 22) ... ok
|
|
|
|
#
|
|
|
|
# test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
|
|
|
|
#
|
|
|
|
# Do not consider it as fatal.
|
|
|
|
return (
|
|
|
|
0,
|
|
|
|
name,
|
|
|
|
ex.stderr.decode("utf-8", "ignore")
|
|
|
|
+ ex.stdout.decode("utf-8", "ignore"),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def runtests():
|
|
|
|
manifestpaths = list(glob.glob("*/Cargo.toml"))
|
|
|
|
details = []
|
|
|
|
finalexitcode = 0
|
|
|
|
write = sys.stdout.write
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
|
|
|
|
futures = [executor.submit(runtest, p) for p in manifestpaths]
|
|
|
|
for future in concurrent.futures.as_completed(futures):
|
|
|
|
result = future.result()
|
|
|
|
if result is None:
|
|
|
|
continue
|
|
|
|
code, name, output = result
|
|
|
|
finalexitcode |= code
|
|
|
|
# Only print failed tests.
|
|
|
|
if code == 0:
|
|
|
|
write(
|
|
|
|
"%s: test has non-zero exit code but isn't considered as failed\n"
|
|
|
|
% name
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
write("%s: test failed\n" % name)
|
|
|
|
details.append("Details for %s:\n%s\n%s" % (name, output, "-" * 80))
|
|
|
|
if details:
|
|
|
|
write("\n\n%s" % "\n".join(details))
|
|
|
|
sys.stdout.flush()
|
|
|
|
return finalexitcode
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
sys.exit(runtests())
|