From c602628fb96e21f03ce43440da82c2947efa4d3a Mon Sep 17 00:00:00 2001 From: Katie Worton Date: Wed, 15 Nov 2023 13:30:16 +0000 Subject: [PATCH] squadutilslib: Add get_reproducer_from_testrun Add get_reproducer_from_testrun to allow downloading and returning of a reproducer from a given testrun ID. This function downloads the reproducer for the given testrun to a provided filename. The optional `local` flag can be provided to download the tuxmake or tuxrun reproducer command rather than the tuxsuite reproducer command. This function will be used in a script to download the reproducer file for a build or test from a TestRun, which is useful for reproducing builds and tests. Update get_reproducer to use the get_reproducer_from_testrun function to download the reproducer from the testrun. Signed-off-by: Katie Worton --- squadutilslib.py | 73 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/squadutilslib.py b/squadutilslib.py index 0eb167a..6791404 100644 --- a/squadutilslib.py +++ b/squadutilslib.py @@ -58,6 +58,62 @@ def get_file(path, filename=None): raise Exception(f"Path {path} not found") +def get_reproducer_from_testrun(testrun_id, filename, plan=False, local=False): + """Given a testrun, download its reproducer.""" + testrun = TestRun(testrun_id) + is_test_reproducer = None + reproducer = None + + if local and plan: + logger.error("Error: not valid to request both plan=True and local=True.") + raise ReproducerNotFound + + # If there is a download_url try to treat it as a build + if testrun.metadata.download_url: + try: + if local: + reproducer_file = get_file( + testrun.metadata.download_url + "/tuxmake_reproducer.sh", filename + ) + elif plan: + reproducer_file = get_file( + testrun.metadata.download_url + "/tux_plan.yaml", filename + ) + else: + reproducer_file = get_file( + testrun.metadata.download_url + "/tuxsuite_reproducer.sh", filename + ) + is_test_reproducer = False + with open(reproducer_file) as f: + reproducer = f.read() + except HTTPError: + pass + + if not reproducer: + # If no build reproducer was found, treat it as a test + try: + if local: + reproducer_file = get_file( + testrun.metadata.job_url + "/reproducer", filename + ) + elif plan: + reproducer_file = get_file( + testrun.metadata.job_url + "/tux_plan", filename + ) + else: + reproducer_file = get_file( + testrun.metadata.job_url + "/tuxsuite_reproducer", filename + ) + is_test_reproducer = True + with open(reproducer_file) as f: + reproducer = f.read() + except HTTPError: + logger.error("No build or test reproducer found.") + raise ReproducerNotFound + + return reproducer, is_test_reproducer + + def filter_projects(projects, pattern): filtered = [] for p in projects: @@ -193,20 +249,11 @@ def get_reproducer( # In theory there should only be one of those logger.debug(f"Testrun id: {testrun.id}") - try: - if local: - reproducer = get_file( - f"{testrun.job_url}/reproducer", filename=filename - ) - else: - reproducer = get_file( - f"{testrun.job_url}/tuxsuite_reproducer", filename=filename - ) - except HTTPError: - logger.error(f"Reproducer not found at {testrun.job_url}!") - raise ReproducerNotFound + reproducer, is_test_reproducer = get_reproducer_from_testrun( + testrun_id=testrun.id, filename=filename, plan=False, local=local + ) return ( - Path(reproducer).read_text(encoding="utf-8"), + reproducer, Build(getid(testrun.build)).metadata.git_describe, testrun.metadata.build_name, )