blob: f050c8f6e51f9bf3d3811a9bbd14e2fab8bf382b [file] [log] [blame]
#!/usr/bin/env python3
# Copyright © 2022 Collabora Ltd.
# Authors:
# David Heidelberg <[email protected]>
#
# For the dependencies, see the requirements.txt
# SPDX-License-Identifier: MIT
"""
Helper script to update traces checksums
"""
import argparse
import bz2
import glob
import re
import json
import sys
from ruamel.yaml import YAML
import gitlab
from colorama import Fore, Style
from gitlab_common import (get_gitlab_project, read_token, wait_for_pipeline,
get_gitlab_pipeline_from_url, TOKEN_DIR, get_token_from_default_dir)
DESCRIPTION_FILE = "export PIGLIT_REPLAY_DESCRIPTION_FILE=.*/install/(.*)$"
DEVICE_NAME = "export PIGLIT_REPLAY_DEVICE_NAME='(.*)'$"
def gather_results(
project,
pipeline,
) -> None:
"""Gather results"""
target_jobs_regex = re.compile(".*-traces([:].*)?$")
for job in pipeline.jobs.list(all=True, sort="desc"):
if target_jobs_regex.match(job.name) and job.status == "failed":
cur_job = project.jobs.get(job.id)
# get variables
print(f"👁 {job.name}...")
log: list[str] = cur_job.trace().decode("unicode_escape", "ignore").splitlines()
filename: str = ''
dev_name: str = ''
for logline in log:
desc_file = re.search(DESCRIPTION_FILE, logline)
device_name = re.search(DEVICE_NAME, logline)
if desc_file:
filename = desc_file.group(1)
if device_name:
dev_name = device_name.group(1)
if not filename or not dev_name:
print(Fore.RED + "Couldn't find device name or YML file in the logs!" + Style.RESET_ALL)
return
print(f"👁 Found {dev_name} and file {filename}")
# find filename in Mesa source
traces_file = glob.glob('./**/' + filename, recursive=True)
# write into it
with open(traces_file[0], 'r', encoding='utf-8') as target_file:
yaml = YAML()
yaml.compact(seq_seq=False, seq_map=False)
yaml.version = 1,2
yaml.width = 2048 # do not break the text fields
yaml.default_flow_style = None
target = yaml.load(target_file)
# parse artifact
results_json_bz2 = cur_job.artifact("results/results.json.bz2")
results_json = bz2.decompress(results_json_bz2).decode("utf-8", errors="replace")
results = json.loads(results_json)
for _, value in results["tests"].items():
if (
not value['images'] or
not value['images'][0] or
"image_desc" not in value['images'][0]
):
continue
trace: str = value['images'][0]['image_desc']
checksum: str = value['images'][0]['checksum_render']
if not checksum:
print(Fore.RED + f"{dev_name}: {trace}: checksum is missing! Crash?" + Style.RESET_ALL)
continue
if checksum == "error":
print(Fore.RED + f"{dev_name}: {trace}: crashed" + Style.RESET_ALL)
continue
if target['traces'][trace][dev_name].get('checksum') == checksum:
continue
if "label" in target['traces'][trace][dev_name]:
print(
f"{dev_name}: {trace}: please verify that label "
f"{Fore.BLUE}{target['traces'][trace][dev_name]['label']}{Style.RESET_ALL} "
"is still valid"
)
print(Fore.GREEN + f'{dev_name}: {trace}: checksum updated' + Style.RESET_ALL)
target['traces'][trace][dev_name]['checksum'] = checksum
with open(traces_file[0], 'w', encoding='utf-8') as target_file:
yaml.dump(target, target_file)
def parse_args() -> None:
"""Parse args"""
parser = argparse.ArgumentParser(
description="Tool to generate patch from checksums ",
epilog="Example: update_traces_checksum.py --rev $(git rev-parse HEAD) "
)
parser.add_argument(
"--rev", metavar="revision", help="repository git revision",
)
parser.add_argument(
"--token",
metavar="token",
type=str,
default=get_token_from_default_dir(),
help="Use the provided GitLab token or token file, "
f"otherwise it's read from {TOKEN_DIR / 'gitlab-token'}",
)
parser.add_argument(
"--pipeline-url",
metavar="pipeline_url",
help="specify a pipeline url",
)
return parser.parse_args()
if __name__ == "__main__":
try:
args = parse_args()
token = read_token(args.token)
gl = gitlab.Gitlab(url="https://gitlab.freedesktop.org", private_token=token)
cur_project = get_gitlab_project(gl, "mesa")
if args.pipeline_url:
pipe, cur_project = get_gitlab_pipeline_from_url(gl, args.pipeline_url)
REV = pipe.sha
else:
if not args.rev:
print('error: the following arguments are required: --rev')
sys.exit(1)
print(f"Revision: {args.rev}")
(pipe, cur_project) = wait_for_pipeline([cur_project], args.rev)
print(f"Pipeline: {pipe.web_url}")
gather_results(cur_project, pipe)
sys.exit()
except KeyboardInterrupt:
sys.exit(1)