mirror of
https://github.com/rust-vmm/rust-vmm-ci.git
synced 2026-08-05 03:08:31 +00:00
test: Format with black
Signed-off-by: Jonathan Woollett-Light <jcawl@amazon.co.uk>
This commit is contained in:
committed by
Jonathan Woollett-Light
parent
285971e8c7
commit
56bfdc97bb
@@ -64,11 +64,11 @@ CONTAINER_VERSION = "v24"
|
||||
# This represents the version of the Buildkite Docker plugin.
|
||||
DOCKER_PLUGIN_VERSION = "v5.3.0"
|
||||
|
||||
X86_AGENT_TAGS = os.getenv('X86_LINUX_AGENT_TAGS')
|
||||
AARCH64_AGENT_TAGS = os.getenv('AARCH64_LINUX_AGENT_TAGS')
|
||||
DOCKER_PLUGIN_CONFIG = os.getenv('DOCKER_PLUGIN_CONFIG')
|
||||
TESTS_TO_SKIP = os.getenv('TESTS_TO_SKIP')
|
||||
TIMEOUTS_MIN = os.getenv('TIMEOUTS_MIN')
|
||||
X86_AGENT_TAGS = os.getenv("X86_LINUX_AGENT_TAGS")
|
||||
AARCH64_AGENT_TAGS = os.getenv("AARCH64_LINUX_AGENT_TAGS")
|
||||
DOCKER_PLUGIN_CONFIG = os.getenv("DOCKER_PLUGIN_CONFIG")
|
||||
TESTS_TO_SKIP = os.getenv("TESTS_TO_SKIP")
|
||||
TIMEOUTS_MIN = os.getenv("TIMEOUTS_MIN")
|
||||
# This env allows setting the hypervisor on which the tests are running at the
|
||||
# pipeline level. This will not override the hypervisor tag in case one is
|
||||
# already specified in the test definition.
|
||||
@@ -76,7 +76,7 @@ TIMEOUTS_MIN = os.getenv('TIMEOUTS_MIN')
|
||||
# experiencing some timeouts mostly with the mshv hosts right now, and we are
|
||||
# fixing the default to kvm to work around that problem.
|
||||
# More details here: https://github.com/rust-vmm/community/issues/137
|
||||
DEFAULT_AGENT_TAG_HYPERVISOR = os.getenv('DEFAULT_AGENT_TAG_HYPERVISOR', 'kvm')
|
||||
DEFAULT_AGENT_TAG_HYPERVISOR = os.getenv("DEFAULT_AGENT_TAG_HYPERVISOR", "kvm")
|
||||
|
||||
PARENT_DIR = pathlib.Path(__file__).parent.resolve()
|
||||
|
||||
@@ -99,59 +99,59 @@ class BuildkiteStep:
|
||||
# dictionaries are ordered. For readability reasons, this order should
|
||||
# not be changed.
|
||||
self.step_config = {
|
||||
'label': None,
|
||||
'command': None,
|
||||
'retry': {'automatic': False},
|
||||
'agents': {'os': 'linux'},
|
||||
'plugins': [
|
||||
"label": None,
|
||||
"command": None,
|
||||
"retry": {"automatic": False},
|
||||
"agents": {"os": "linux"},
|
||||
"plugins": [
|
||||
{
|
||||
f"docker#{DOCKER_PLUGIN_VERSION}": {
|
||||
'image': f"rustvmm/dev:{CONTAINER_VERSION}",
|
||||
'always-pull': True
|
||||
"image": f"rustvmm/dev:{CONTAINER_VERSION}",
|
||||
"always-pull": True,
|
||||
}
|
||||
}
|
||||
],
|
||||
'timeout_in_minutes': 15
|
||||
"timeout_in_minutes": 15,
|
||||
}
|
||||
|
||||
def _set_platform(self, platform):
|
||||
""" Set platform if given in the json input. """
|
||||
"""Set platform if given in the json input."""
|
||||
|
||||
if platform:
|
||||
# We need to change `aarch64` to `arm` because of the way we are
|
||||
# setting the tags on the host.
|
||||
if platform == 'aarch64':
|
||||
platform = 'arm'
|
||||
self.step_config['agents']['platform'] = f"{platform}.metal"
|
||||
if platform == "aarch64":
|
||||
platform = "arm"
|
||||
self.step_config["agents"]["platform"] = f"{platform}.metal"
|
||||
|
||||
def _set_hypervisor(self, hypervisor):
|
||||
""" Set hypervisor if given in the json input. """
|
||||
supported_hypervisors = ['kvm', 'mshv']
|
||||
"""Set hypervisor if given in the json input."""
|
||||
supported_hypervisors = ["kvm", "mshv"]
|
||||
if hypervisor:
|
||||
if hypervisor in supported_hypervisors:
|
||||
self.step_config['agents']['hypervisor'] = hypervisor
|
||||
self.step_config["agents"]["hypervisor"] = hypervisor
|
||||
|
||||
def _set_conditional(self, conditional):
|
||||
""" Set conditional if given in the json input. """
|
||||
"""Set conditional if given in the json input."""
|
||||
|
||||
if conditional:
|
||||
self.step_config['if'] = conditional
|
||||
self.step_config["if"] = conditional
|
||||
|
||||
def _set_timeout_in_minutes(self, timeout):
|
||||
""" Set the timeout if given in the json input. """
|
||||
"""Set the timeout if given in the json input."""
|
||||
if timeout:
|
||||
self.step_config['timeout_in_minutes'] = timeout
|
||||
self.step_config["timeout_in_minutes"] = timeout
|
||||
|
||||
def _set_agent_queue(self, queue):
|
||||
"""Set the agent queue if provided in the json input."""
|
||||
if queue:
|
||||
self.step_config['agents']['queue'] = queue
|
||||
self.step_config["agents"]["queue"] = queue
|
||||
|
||||
def _add_docker_config(self, cfg):
|
||||
""" Add configuration for docker if given in the json input. """
|
||||
"""Add configuration for docker if given in the json input."""
|
||||
|
||||
if cfg:
|
||||
target = self.step_config['plugins'][0][f"docker#{DOCKER_PLUGIN_VERSION}"]
|
||||
target = self.step_config["plugins"][0][f"docker#{DOCKER_PLUGIN_VERSION}"]
|
||||
for key, val in cfg.items():
|
||||
target[key] = val
|
||||
|
||||
@@ -164,13 +164,11 @@ class BuildkiteStep:
|
||||
if env_var:
|
||||
env_cfg = json.loads(env_var)
|
||||
|
||||
tests = env_cfg.get('tests')
|
||||
assert tests, \
|
||||
f"Environment variable {env_var} is missing the `tests` key."
|
||||
tests = env_cfg.get("tests")
|
||||
assert tests, f"Environment variable {env_var} is missing the `tests` key."
|
||||
|
||||
cfg = env_cfg.get('cfg')
|
||||
assert cfg, \
|
||||
f"Environment variable {env_var} is missing the `cfg` key."
|
||||
cfg = env_cfg.get("cfg")
|
||||
assert cfg, f"Environment variable {env_var} is missing the `cfg` key."
|
||||
|
||||
if test_name in tests:
|
||||
if override:
|
||||
@@ -186,17 +184,17 @@ class BuildkiteStep:
|
||||
"""
|
||||
|
||||
env_var = None
|
||||
platform = self.step_config['agents'].get('platform')
|
||||
platform = self.step_config["agents"].get("platform")
|
||||
|
||||
# Since the platform is optional, only override the config if the
|
||||
# platform was provided.
|
||||
if platform:
|
||||
if platform == 'x86_64.metal' and X86_AGENT_TAGS:
|
||||
if platform == "x86_64.metal" and X86_AGENT_TAGS:
|
||||
env_var = X86_AGENT_TAGS
|
||||
if platform == 'arm.metal' and AARCH64_AGENT_TAGS:
|
||||
if platform == "arm.metal" and AARCH64_AGENT_TAGS:
|
||||
env_var = AARCH64_AGENT_TAGS
|
||||
|
||||
target = self.step_config['agents']
|
||||
target = self.step_config["agents"]
|
||||
self._env_change_config(test_name, env_var, target, override=True)
|
||||
|
||||
def _env_add_docker_config(self, test_name):
|
||||
@@ -205,7 +203,7 @@ class BuildkiteStep:
|
||||
`DOCKER_PLUGIN_CONFIG` environment variable.
|
||||
"""
|
||||
|
||||
target = self.step_config['plugins'][0][f"docker#{DOCKER_PLUGIN_VERSION}"]
|
||||
target = self.step_config["plugins"][0][f"docker#{DOCKER_PLUGIN_VERSION}"]
|
||||
self._env_change_config(test_name, DOCKER_PLUGIN_CONFIG, target)
|
||||
|
||||
def _env_override_timeout(self, test_name):
|
||||
@@ -221,28 +219,25 @@ class BuildkiteStep:
|
||||
Further configuration from environment variables may be added.
|
||||
"""
|
||||
|
||||
test_name = input.get('test_name')
|
||||
command = input.get('command')
|
||||
platform = input.get('platform')
|
||||
hypervisor = input.get('hypervisor')
|
||||
docker = input.get('docker_plugin')
|
||||
conditional = input.get('conditional')
|
||||
timeout = input.get('timeout_in_minutes')
|
||||
queue = input.get('queue')
|
||||
test_name = input.get("test_name")
|
||||
command = input.get("command")
|
||||
platform = input.get("platform")
|
||||
hypervisor = input.get("hypervisor")
|
||||
docker = input.get("docker_plugin")
|
||||
conditional = input.get("conditional")
|
||||
timeout = input.get("timeout_in_minutes")
|
||||
queue = input.get("queue")
|
||||
|
||||
# Mandatory keys.
|
||||
assert test_name, "Step is missing test name."
|
||||
platform_string = f"-{platform}" if platform else ""
|
||||
self.step_config['label'] = f"{test_name}{platform_string}"
|
||||
self.step_config["label"] = f"{test_name}{platform_string}"
|
||||
|
||||
assert command, "Step is missing command."
|
||||
if "{target_platform}" in command:
|
||||
assert platform, \
|
||||
"Command requires platform, but platform is missing."
|
||||
command = command.replace(
|
||||
"{target_platform}", platform
|
||||
)
|
||||
self.step_config['command'] = command
|
||||
assert platform, "Command requires platform, but platform is missing."
|
||||
command = command.replace("{target_platform}", platform)
|
||||
self.step_config["command"] = command
|
||||
|
||||
# Optional keys.
|
||||
self._set_platform(platform)
|
||||
@@ -262,9 +257,19 @@ class BuildkiteStep:
|
||||
# forwarding the key, values without any change.
|
||||
# We need to filter for keys that have special meaning and which we
|
||||
# don't want to re-add.
|
||||
special_keys = ['conditional', 'docker_plugin', 'platform', 'test_name', 'queue', 'hypervisor']
|
||||
additional_keys = {k: v for k, v in input.items() if not (k in self.step_config) and
|
||||
not(k in special_keys)}
|
||||
special_keys = [
|
||||
"conditional",
|
||||
"docker_plugin",
|
||||
"platform",
|
||||
"test_name",
|
||||
"queue",
|
||||
"hypervisor",
|
||||
]
|
||||
additional_keys = {
|
||||
k: v
|
||||
for k, v in input.items()
|
||||
if not (k in self.step_config) and not (k in special_keys)
|
||||
}
|
||||
if additional_keys:
|
||||
self.step_config.update(additional_keys)
|
||||
|
||||
@@ -283,15 +288,15 @@ class BuildkiteConfig:
|
||||
self.bk_config = None
|
||||
|
||||
def build(self, input):
|
||||
""" Build the final Buildkite configuration fron the json input. """
|
||||
"""Build the final Buildkite configuration fron the json input."""
|
||||
|
||||
self.bk_config = {'steps': []}
|
||||
tests = input.get('tests')
|
||||
self.bk_config = {"steps": []}
|
||||
tests = input.get("tests")
|
||||
assert tests, "Input is missing list of tests."
|
||||
|
||||
for test in tests:
|
||||
platforms = test.get('platform')
|
||||
test_name = test.get('test_name')
|
||||
platforms = test.get("platform")
|
||||
test_name = test.get("test_name")
|
||||
|
||||
if TESTS_TO_SKIP:
|
||||
tests_to_skip = json.loads(TESTS_TO_SKIP)
|
||||
@@ -305,20 +310,20 @@ class BuildkiteConfig:
|
||||
|
||||
for platform in platforms:
|
||||
step_input = copy.deepcopy(test)
|
||||
step_input['platform'] = platform
|
||||
if not step_input.get('hypervisor'):
|
||||
step_input['hypervisor'] = DEFAULT_AGENT_TAG_HYPERVISOR
|
||||
step_input["platform"] = platform
|
||||
if not step_input.get("hypervisor"):
|
||||
step_input["hypervisor"] = DEFAULT_AGENT_TAG_HYPERVISOR
|
||||
|
||||
step = BuildkiteStep()
|
||||
step_output = step.build(step_input)
|
||||
self.bk_config['steps'].append(step_output)
|
||||
self.bk_config["steps"].append(step_output)
|
||||
|
||||
# Return the object's attributes and their values as a dictionary.
|
||||
return self.bk_config
|
||||
|
||||
|
||||
def generate_pipeline(config_file):
|
||||
""" Generate the pipeline yaml file from a json configuration file. """
|
||||
"""Generate the pipeline yaml file from a json configuration file."""
|
||||
|
||||
with open(config_file) as json_file:
|
||||
json_cfg = json.load(json_file)
|
||||
@@ -329,7 +334,7 @@ def generate_pipeline(config_file):
|
||||
yaml.dump(output, sys.stdout, sort_keys=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
help_text = dedent(
|
||||
"""
|
||||
This script supports overriding the following configurations through
|
||||
@@ -345,17 +350,18 @@ if __name__ == '__main__':
|
||||
- TIMEOUTS_MIN: overrides the timeout value for specific tests.
|
||||
"""
|
||||
)
|
||||
parser = ArgumentParser(description=help_text,
|
||||
formatter_class=RawTextHelpFormatter)
|
||||
parser = ArgumentParser(description=help_text, formatter_class=RawTextHelpFormatter)
|
||||
# By default we're generating the rust-vmm-ci pipeline with the test
|
||||
# configuration committed to this repository.
|
||||
# This parameter is useful for generating the pipeline for repositories
|
||||
# that have custom pipelines, and it helps with keeping the container
|
||||
# version the same across pipelines.
|
||||
parser.add_argument('-t', '--test-description',
|
||||
metavar="JSON_FILE",
|
||||
help='The path to the JSON file containing the test'
|
||||
' description for the CI.',
|
||||
default=f'{PARENT_DIR}/test_description.json')
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--test-description",
|
||||
metavar="JSON_FILE",
|
||||
help="The path to the JSON file containing the test" " description for the CI.",
|
||||
default=f"{PARENT_DIR}/test_description.json",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
generate_pipeline(args.test_description)
|
||||
|
||||
14
.github/workflows/black.yaml
vendored
Normal file
14
.github/workflows/black.yaml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
black:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install black
|
||||
run: pip install black
|
||||
|
||||
- name: Run black
|
||||
run: black . --check
|
||||
@@ -15,28 +15,22 @@ def pytest_addoption(parser):
|
||||
"--profile",
|
||||
default=PROFILE_CI,
|
||||
choices=[PROFILE_CI, PROFILE_DEVEL],
|
||||
help="Profile for running the test: {} or {}".format(
|
||||
PROFILE_CI,
|
||||
PROFILE_DEVEL
|
||||
)
|
||||
help="Profile for running the test: {} or {}".format(PROFILE_CI, PROFILE_DEVEL),
|
||||
)
|
||||
parser.addoption(
|
||||
"--no-cleanup",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Keep the coverage report in `kcov_output` directory. If this "
|
||||
"flag is not provided, both coverage related directories are "
|
||||
"removed."
|
||||
"flag is not provided, both coverage related directories are "
|
||||
"removed.",
|
||||
)
|
||||
|
||||
parser.addoption(
|
||||
"--test-scope",
|
||||
default=WORKSPACE,
|
||||
choices=[WORKSPACE, CRATE],
|
||||
help="Defines the scope of running tests: {} or {}".format(
|
||||
WORKSPACE,
|
||||
CRATE
|
||||
)
|
||||
help="Defines the scope of running tests: {} or {}".format(WORKSPACE, CRATE),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -14,14 +14,12 @@ import subprocess
|
||||
|
||||
from utils import get_repo_root_path
|
||||
|
||||
REMOTE = \
|
||||
os.environ.get('BUILDKITE_REPO') or \
|
||||
os.environ.get('REMOTE') or \
|
||||
"origin"
|
||||
BASE_BRANCH = \
|
||||
os.environ.get('BUILDKITE_PULL_REQUEST_BASE_BRANCH') or \
|
||||
os.environ.get('BASE_BRANCH') or \
|
||||
"main"
|
||||
REMOTE = os.environ.get("BUILDKITE_REPO") or os.environ.get("REMOTE") or "origin"
|
||||
BASE_BRANCH = (
|
||||
os.environ.get("BUILDKITE_PULL_REQUEST_BASE_BRANCH")
|
||||
or os.environ.get("BASE_BRANCH")
|
||||
or "main"
|
||||
)
|
||||
# File used for saving the results of cargo bench
|
||||
# when running on the PR branch.
|
||||
PR_BENCH_RESULTS_FILE = "pr_bench_results"
|
||||
@@ -67,12 +65,9 @@ def test_bench():
|
||||
# This is a bit of a &*%^ way of checking if the benchmark does not
|
||||
# exist. Hopefully it will be possible to check it in another way
|
||||
# ...soon
|
||||
print(
|
||||
"There are no benchmarks in main. No comparison can happen."
|
||||
)
|
||||
print("There are no benchmarks in main. No comparison can happen.")
|
||||
else:
|
||||
assert return_code == 0, "stdout: {}\n stderr: {}".format(
|
||||
stdout, stderr)
|
||||
assert return_code == 0, "stdout: {}\n stderr: {}".format(stdout, stderr)
|
||||
|
||||
|
||||
def _run_cargo_bench(baseline):
|
||||
@@ -80,43 +75,44 @@ def _run_cargo_bench(baseline):
|
||||
process = subprocess.run(
|
||||
"cargo bench --bench main --all-features -- --noplot "
|
||||
"--save-baseline {}".format(baseline),
|
||||
shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE
|
||||
shell=True,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
return process.returncode, process.stdout.decode('utf-8'),\
|
||||
process.stderr.decode('utf-8')
|
||||
return (
|
||||
process.returncode,
|
||||
process.stdout.decode("utf-8"),
|
||||
process.stderr.decode("utf-8"),
|
||||
)
|
||||
|
||||
|
||||
def _run_critcmp():
|
||||
p = subprocess.run(
|
||||
"critcmp {} {}".format(
|
||||
UPSTREAM_BENCH_RESULTS_FILE, PR_BENCH_RESULTS_FILE
|
||||
),
|
||||
shell=True, check=True,
|
||||
"critcmp {} {}".format(UPSTREAM_BENCH_RESULTS_FILE, PR_BENCH_RESULTS_FILE),
|
||||
shell=True,
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
|
||||
print(p.stdout.decode('utf-8'))
|
||||
print('ERRORS')
|
||||
print(p.stderr.decode('utf-8'))
|
||||
print(p.stdout.decode("utf-8"))
|
||||
print("ERRORS")
|
||||
print(p.stderr.decode("utf-8"))
|
||||
|
||||
|
||||
def _git_checkout_upstream_branch():
|
||||
subprocess.run(
|
||||
"git fetch {} {}".format(REMOTE, BASE_BRANCH),
|
||||
shell=True, check=True
|
||||
)
|
||||
subprocess.run(
|
||||
"git checkout FETCH_HEAD",
|
||||
shell=True, check=True
|
||||
"git fetch {} {}".format(REMOTE, BASE_BRANCH), shell=True, check=True
|
||||
)
|
||||
subprocess.run("git checkout FETCH_HEAD", shell=True, check=True)
|
||||
|
||||
|
||||
def _git_checkout_pr_branch():
|
||||
subprocess.run(
|
||||
"git checkout -",
|
||||
shell=True, check=True,
|
||||
shell=True,
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
|
||||
@@ -16,14 +16,12 @@ from utils import get_cmd_output
|
||||
|
||||
COMMIT_TITLE_MAX_LEN = 60
|
||||
COMMIT_BODY_LINE_MAX_LEN = 75
|
||||
REMOTE = \
|
||||
os.environ.get('BUILDKITE_REPO') or \
|
||||
os.environ.get('REMOTE') or \
|
||||
"origin"
|
||||
BASE_BRANCH = \
|
||||
os.environ.get('BUILDKITE_PULL_REQUEST_BASE_BRANCH') or \
|
||||
os.environ.get('BASE_BRANCH') or \
|
||||
"main"
|
||||
REMOTE = os.environ.get("BUILDKITE_REPO") or os.environ.get("REMOTE") or "origin"
|
||||
BASE_BRANCH = (
|
||||
os.environ.get("BUILDKITE_PULL_REQUEST_BASE_BRANCH")
|
||||
or os.environ.get("BASE_BRANCH")
|
||||
or "main"
|
||||
)
|
||||
|
||||
|
||||
def test_commit_format():
|
||||
@@ -50,8 +48,7 @@ def test_commit_format():
|
||||
) from None
|
||||
# Get hashes of PR's commits in their abbreviated form for
|
||||
# a prettier printing.
|
||||
shas_cmd = "git log --no-merges --pretty=%h --no-decorate " \
|
||||
"FETCH_HEAD..HEAD"
|
||||
shas_cmd = "git log --no-merges --pretty=%h --no-decorate " "FETCH_HEAD..HEAD"
|
||||
shas = get_cmd_output(shas_cmd)
|
||||
|
||||
for sha in shas.split():
|
||||
@@ -63,18 +60,20 @@ def test_commit_format():
|
||||
message_cmd = "git show --pretty=format:%B -s " + sha
|
||||
message = get_cmd_output(message_cmd)
|
||||
message_lines = message.split("\n")
|
||||
assert len(message_lines) >= 3,\
|
||||
"The commit '{}' should contain at least 3 lines: title, " \
|
||||
"blank line and a sign-off one." \
|
||||
.format(sha)
|
||||
assert len(message_lines) >= 3, (
|
||||
"The commit '{}' should contain at least 3 lines: title, "
|
||||
"blank line and a sign-off one.".format(sha)
|
||||
)
|
||||
title = message_lines[0]
|
||||
assert message_lines[1] == "",\
|
||||
"For commit '{}', title is divided into multiple lines. " \
|
||||
"Please keep it one line long and make sure you add a blank " \
|
||||
assert message_lines[1] == "", (
|
||||
"For commit '{}', title is divided into multiple lines. "
|
||||
"Please keep it one line long and make sure you add a blank "
|
||||
"line between title and description.".format(sha)
|
||||
assert len(title) <= COMMIT_TITLE_MAX_LEN,\
|
||||
"For commit '{}', title exceeds {} chars. " \
|
||||
)
|
||||
assert len(title) <= COMMIT_TITLE_MAX_LEN, (
|
||||
"For commit '{}', title exceeds {} chars. "
|
||||
"Please keep it shorter.".format(sha, COMMIT_TITLE_MAX_LEN)
|
||||
)
|
||||
|
||||
found_signed_off = False
|
||||
|
||||
@@ -85,11 +84,13 @@ def test_commit_format():
|
||||
# the commit message ended and we don't want to check
|
||||
# line lengths anymore for the current commit.
|
||||
break
|
||||
assert len(line) <= COMMIT_BODY_LINE_MAX_LEN,\
|
||||
"For commit '{}', message line '{}' exceeds {} chars. " \
|
||||
"Please keep it shorter or split it in " \
|
||||
"multiple lines.".format(sha, line,
|
||||
COMMIT_BODY_LINE_MAX_LEN)
|
||||
assert found_signed_off, "Commit '{}' is not signed. " \
|
||||
"Please run 'git commit -s --amend' " \
|
||||
"on it.".format(sha)
|
||||
assert len(line) <= COMMIT_BODY_LINE_MAX_LEN, (
|
||||
"For commit '{}', message line '{}' exceeds {} chars. "
|
||||
"Please keep it shorter or split it in "
|
||||
"multiple lines.".format(sha, line, COMMIT_BODY_LINE_MAX_LEN)
|
||||
)
|
||||
assert found_signed_off, (
|
||||
"Commit '{}' is not signed. "
|
||||
"Please run 'git commit -s --amend' "
|
||||
"on it.".format(sha)
|
||||
)
|
||||
|
||||
@@ -51,15 +51,16 @@ def _read_test_config():
|
||||
assert "exclude_path" in coverage_config
|
||||
assert "crate_features" in coverage_config
|
||||
|
||||
assert ' ' not in coverage_config["crate_features"], \
|
||||
"spaces are not allowed in crate_features value"
|
||||
assert (
|
||||
" " not in coverage_config["crate_features"]
|
||||
), "spaces are not allowed in crate_features value"
|
||||
|
||||
return coverage_config
|
||||
|
||||
|
||||
def _write_coverage_config(coverage_config):
|
||||
"""Updates the coverage config file as per `coverage_config`"""
|
||||
with open(COVERAGE_CONFIG_PATH, 'w') as outfile:
|
||||
with open(COVERAGE_CONFIG_PATH, "w") as outfile:
|
||||
json.dump(coverage_config, outfile)
|
||||
|
||||
|
||||
@@ -78,48 +79,43 @@ def _get_current_coverage(coverage_config, no_cleanup, test_scope):
|
||||
shutil.rmtree(kcov_output_dir, ignore_errors=True)
|
||||
shutil.rmtree(kcov_build_dir, ignore_errors=True)
|
||||
|
||||
exclude_pattern = (
|
||||
'${CARGO_HOME:-$HOME/.cargo/},'
|
||||
'usr/lib/,'
|
||||
'lib/'
|
||||
)
|
||||
exclude_pattern = "${CARGO_HOME:-$HOME/.cargo/}," "usr/lib/," "lib/"
|
||||
exclude_region = "'mod tests {'"
|
||||
additional_exclude_path = coverage_config["exclude_path"]
|
||||
if additional_exclude_path:
|
||||
exclude_pattern += ',' + additional_exclude_path
|
||||
exclude_pattern += "," + additional_exclude_path
|
||||
|
||||
additional_kcov_param = ''
|
||||
additional_kcov_param = ""
|
||||
|
||||
if test_scope == pytest.workspace:
|
||||
additional_kcov_param += '--all '
|
||||
additional_kcov_param += "--all "
|
||||
|
||||
crate_features = coverage_config["crate_features"]
|
||||
if crate_features:
|
||||
additional_kcov_param += '--features=' + crate_features
|
||||
additional_kcov_param += "--features=" + crate_features
|
||||
|
||||
kcov_cmd = "CARGO_TARGET_DIR={} cargo kcov {} " \
|
||||
"--output {} -- " \
|
||||
"--exclude-region={} " \
|
||||
"--exclude-pattern={} " \
|
||||
"--verify".format(
|
||||
kcov_build_dir,
|
||||
additional_kcov_param,
|
||||
kcov_output_dir,
|
||||
exclude_region,
|
||||
exclude_pattern
|
||||
)
|
||||
kcov_cmd = (
|
||||
"CARGO_TARGET_DIR={} cargo kcov {} "
|
||||
"--output {} -- "
|
||||
"--exclude-region={} "
|
||||
"--exclude-pattern={} "
|
||||
"--verify".format(
|
||||
kcov_build_dir,
|
||||
additional_kcov_param,
|
||||
kcov_output_dir,
|
||||
exclude_region,
|
||||
exclude_pattern,
|
||||
)
|
||||
)
|
||||
|
||||
# Pytest closes stdin by default, but some tests might need it to be open.
|
||||
# In the future, should the need arise, we can feed custom data to stdin.
|
||||
subprocess.run(kcov_cmd, shell=True, check=True, input=b'')
|
||||
subprocess.run(kcov_cmd, shell=True, check=True, input=b"")
|
||||
|
||||
# Read the coverage reported by kcov.
|
||||
coverage_file = os.path.join(kcov_output_dir, 'index.js')
|
||||
coverage_file = os.path.join(kcov_output_dir, "index.js")
|
||||
with open(coverage_file) as cov_output:
|
||||
coverage = float(re.findall(
|
||||
r'"covered":"(\d+\.\d)"',
|
||||
cov_output.read()
|
||||
)[0])
|
||||
coverage = float(re.findall(r'"covered":"(\d+\.\d)"', cov_output.read())[0])
|
||||
|
||||
# Remove coverage related directories.
|
||||
# If user provided `--no-cleanup` flag, `kcov_output_dir`
|
||||
@@ -140,14 +136,12 @@ def test_coverage(profile, no_cleanup, test_scope):
|
||||
if previous_coverage < current_coverage:
|
||||
if profile == pytest.profile_ci:
|
||||
# In the CI Profile we expect the coverage to be manually updated.
|
||||
assert False, \
|
||||
"Coverage is increased from {} to {}. " \
|
||||
"Please update the coverage in coverage_config_{}.json."\
|
||||
.format(
|
||||
previous_coverage,
|
||||
current_coverage,
|
||||
platform.machine()
|
||||
assert False, (
|
||||
"Coverage is increased from {} to {}. "
|
||||
"Please update the coverage in coverage_config_{}.json.".format(
|
||||
previous_coverage, current_coverage, platform.machine()
|
||||
)
|
||||
)
|
||||
elif profile == pytest.profile_devel:
|
||||
coverage_config["coverage_score"] = current_coverage
|
||||
_write_coverage_config(coverage_config)
|
||||
@@ -157,5 +151,7 @@ def test_coverage(profile, no_cleanup, test_scope):
|
||||
# `pytest_addoption`.
|
||||
assert False, "Invalid test profile."
|
||||
elif previous_coverage > current_coverage:
|
||||
assert False, "Coverage drops by {:.2f}%. Please add unit tests for " \
|
||||
"the uncovered lines.".format(diff)
|
||||
assert False, (
|
||||
"Coverage drops by {:.2f}%. Please add unit tests for "
|
||||
"the uncovered lines.".format(diff)
|
||||
)
|
||||
|
||||
@@ -15,7 +15,6 @@ def get_repo_root_path():
|
||||
|
||||
def get_cmd_output(cmd):
|
||||
"""Returns stdout content of `cmd` command."""
|
||||
cmd_out = subprocess.run(cmd, shell=True, check=True,
|
||||
stdout=subprocess.PIPE)
|
||||
stdout = cmd_out.stdout.decode('utf-8')
|
||||
cmd_out = subprocess.run(cmd, shell=True, check=True, stdout=subprocess.PIPE)
|
||||
stdout = cmd_out.stdout.decode("utf-8")
|
||||
return stdout
|
||||
|
||||
16
test_run.py
16
test_run.py
@@ -21,19 +21,18 @@ class TestsContainer(unittest.TestCase):
|
||||
def make_test_function(command):
|
||||
def test(self):
|
||||
subprocess.run(command, shell=True, check=True)
|
||||
|
||||
return test
|
||||
|
||||
|
||||
def retrieve_test_list(
|
||||
config_file=f"{PARENT_DIR}/.buildkite/test_description.json"
|
||||
):
|
||||
def retrieve_test_list(config_file=f"{PARENT_DIR}/.buildkite/test_description.json"):
|
||||
with open(config_file) as jsonFile:
|
||||
test_list = json.load(jsonFile)
|
||||
jsonFile.close()
|
||||
return test_list
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
help_text = dedent(
|
||||
"""
|
||||
This script allows running all the tests at once on the local machine.
|
||||
@@ -44,15 +43,14 @@ if __name__ == '__main__':
|
||||
base branch, and these tests may not work as expected.
|
||||
"""
|
||||
)
|
||||
parser = ArgumentParser(description=help_text,
|
||||
formatter_class=RawTextHelpFormatter)
|
||||
parser = ArgumentParser(description=help_text, formatter_class=RawTextHelpFormatter)
|
||||
parser.parse_args()
|
||||
|
||||
test_config = retrieve_test_list()
|
||||
for test in test_config['tests']:
|
||||
command = test['command']
|
||||
for test in test_config["tests"]:
|
||||
command = test["command"]
|
||||
command = command.replace("{target_platform}", platform.machine())
|
||||
test_func = make_test_function(command)
|
||||
setattr(TestsContainer, 'test_{}'.format(test['test_name']), test_func)
|
||||
setattr(TestsContainer, "test_{}".format(test["test_name"]), test_func)
|
||||
|
||||
unittest.main(verbosity=2)
|
||||
|
||||
Reference in New Issue
Block a user