You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/tests/update_fixtures.py

137 lines
3.8 KiB

#!/usr/bin/env python3
from __future__ import annotations
import json
import subprocess
from typing import Iterable
import click
from ui_tests import update_fixtures
from ui_tests.common import FIXTURES_FILE, get_current_fixtures
@click.group()
def cli():
pass
@cli.command()
@click.option("-r", "--remove-missing", is_flag=True, help="Remove missing tests")
def local(remove_missing: bool) -> None:
"""Update fixtures file with results from latest local test run."""
print("Updating from local test run...")
changes_amount = update_fixtures(remove_missing)
print(f"Updated fixtures.json with data from {changes_amount} tests.")
def _get_current_git_branch() -> str:
return (
subprocess.check_output(["git", "branch", "--show-current"])
.decode("ascii")
.strip()
)
@cli.command()
@click.option(
"-g",
"--github",
is_flag=True,
help="Fetch from GitHub Actions instead of GitLab CI",
)
@click.option("-b", "--branch", help="Branch name")
@click.option(
"-o",
"--only-jobs",
help="Job names which to process",
multiple=True,
)
@click.option(
"-e",
"--exclude-jobs",
help="Not take these jobs",
multiple=True,
)
@click.option("-r", "--remove-missing", is_flag=True, help="Remove missing tests")
def ci(
github: bool,
branch: str | None,
only_jobs: Iterable[str] | None,
exclude_jobs: Iterable[str] | None,
remove_missing: bool,
) -> None:
"""Update fixtures file with results from CI."""
print("Updating from CI...")
if only_jobs and exclude_jobs:
raise click.UsageError("Cannot use both --only-jobs and --exclude-jobs")
if branch is None:
branch = _get_current_git_branch()
print(f"Branch: {branch}")
if only_jobs:
print(f"Only jobs: {only_jobs}")
if exclude_jobs:
print(f"Exclude jobs: {exclude_jobs}")
if github:
from github import get_branch_ui_fixtures_results
ui_results = get_branch_ui_fixtures_results(branch, only_jobs, exclude_jobs)
else:
from gitlab import get_branch_ui_fixtures_results, get_jobs_of_interest
jobs_of_interest = get_jobs_of_interest(only_jobs, exclude_jobs)
ui_results = get_branch_ui_fixtures_results(branch, jobs_of_interest)
current_fixtures = get_current_fixtures()
is_error = False
differing_total = 0
for job_name, ui_res_dict in ui_results.items():
print(f"Updating results from {job_name}...")
if not ui_res_dict:
is_error = True
print("No results found.")
continue
model = next(iter(ui_res_dict.keys()))
group = next(iter(ui_res_dict[model].keys()))
current_model = current_fixtures.setdefault(model, {})
current_group = current_model.setdefault(group, {}) # type: ignore
if remove_missing:
# get rid of tests that were not run in CI
removed = 0
for key in list(current_group.keys()):
if key not in ui_res_dict[model][group]:
current_group.pop(key)
removed += 1
print(f"Removed {removed} tests.")
differing = 0
for test_name, res in ui_res_dict[model][group].items():
if current_group.get(test_name) != res:
differing += 1
current_group[test_name] = res
print(f"Updated {differing} tests.")
differing_total += differing
print(80 * "-")
print(f"Updated {differing_total} tests in total.")
FIXTURES_FILE.write_text(
json.dumps(current_fixtures, indent=0, sort_keys=True) + "\n"
)
print("Updated fixtures.json with data from CI.")
if is_error:
print(80 * "-")
raise click.ClickException("Some jobs did not have any results.")
if __name__ == "__main__":
cli()