From 60e01ce0e83677fabd5bee27f58505721cba0daa Mon Sep 17 00:00:00 2001 From: Martin Milata Date: Fri, 22 Mar 2024 17:45:26 +0100 Subject: [PATCH] feat(tests): update_fixtures.py: github actions support --- tests/github.py | 66 ++++++++++++++++++++++++++++++++++++++++ tests/update_fixtures.py | 21 ++++++++++--- 2 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 tests/github.py diff --git a/tests/github.py b/tests/github.py new file mode 100644 index 000000000..4353d45a5 --- /dev/null +++ b/tests/github.py @@ -0,0 +1,66 @@ +""" +Helper functions for communication with GitHub. + +Allowing for interaction with the test results, e.g. with UI tests. +""" + +from __future__ import annotations + +from pathlib import Path +from typing import Any, Iterable, Iterator + +import requests + +AnyDict = dict[Any, Any] + +HERE = Path(__file__).parent + +LIST_RUNS_TEMPLATE = "https://api.github.com/repos/trezor/trezor-firmware/actions/workflows/{workflow}/runs?branch={branch}" +FIXTURES_TEMPLATE = "https://data.trezor.io/dev/firmware/ui_report/{run}/{model}-{lang}-{job}/fixtures.results.json" + +MODELS = ["T2T1", "T2B1", "T3T1"] +LANGUAGES = ["en", "cs", "de", "es", "fr"] +JOBS = ["core_device_test", "core_click_test", "core_persistence_test"] + + +def get_branch_ui_fixtures_results( + branch_name: str, + only_jobs: Iterable[str] | None, + exclude_jobs: Iterable[str] | None, +) -> dict[str, AnyDict]: + print(f"Checking branch {branch_name}") + + response = requests.get( + LIST_RUNS_TEMPLATE.format(branch=branch_name, workflow="core.yml") + ) + response.raise_for_status() + run_id = response.json()["workflow_runs"][0]["id"] + + def yield_key_value() -> Iterator[tuple[str, AnyDict]]: + for model in MODELS: + for lang in LANGUAGES: + for job in JOBS: + job_instance = f"{model}-{lang}-{job}" + + if only_jobs and all( + (job not in job_instance) for job in only_jobs + ): + continue + if exclude_jobs and any( + (job in job_instance) for job in exclude_jobs + ): + continue + + response = requests.get( + FIXTURES_TEMPLATE.format( + run=run_id, model=model, lang=lang, job=job + ) + ) + if response.status_code != 200: + print( + f"Failed to get fixtures for {job_instance}: {response.status_code}" + ) + continue + yield job_instance, response.json() + + return dict(yield_key_value()) diff --git a/tests/update_fixtures.py b/tests/update_fixtures.py index 79fe08067..bb3e95812 100755 --- a/tests/update_fixtures.py +++ b/tests/update_fixtures.py @@ -8,7 +8,6 @@ from typing import Iterable import click -from gitlab import UI_JOB_NAMES, get_branch_ui_fixtures_results, get_jobs_of_interest from ui_tests import update_fixtures from ui_tests.common import FIXTURES_FILE, get_current_fixtures @@ -36,23 +35,28 @@ def _get_current_git_branch() -> str: @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", - type=click.Choice(UI_JOB_NAMES), help="Job names which to process", multiple=True, ) @click.option( "-e", "--exclude-jobs", - type=click.Choice(UI_JOB_NAMES), 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, @@ -73,8 +77,15 @@ def ci( if exclude_jobs: print(f"Exclude jobs: {exclude_jobs}") - jobs_of_interest = get_jobs_of_interest(only_jobs, exclude_jobs) - ui_results = get_branch_ui_fixtures_results(branch, jobs_of_interest) + 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()