ci: Drop the git dependency in tracie
authorRohan Garg <rohan.garg@collabora.com>
Fri, 28 Feb 2020 12:48:53 +0000 (13:48 +0100)
committerTomeu Vizoso <tomeu.vizoso@collabora.com>
Tue, 17 Mar 2020 06:23:27 +0000 (07:23 +0100)
Instead of using git, use python and the Gitlab API
to fetch traces. This helps us slim down our ramdisks
in preparation for integrating trace replay on LAVA
devices.

Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4000>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4000>

.gitlab-ci.yml
.gitlab-ci/container/x86_build.sh
.gitlab-ci/container/x86_test-gl.sh
.gitlab-ci/tracie-runner-gl.sh
.gitlab-ci/tracie-runner-vk.sh
.gitlab-ci/tracie/renderdoc_dump_images.py
.gitlab-ci/tracie/tests/test.sh
.gitlab-ci/tracie/tracie.py [new file with mode: 0644]
.gitlab-ci/tracie/tracie.sh [deleted file]

index 55c39cce466bc6a844d778c1d0a8df43a19152e3..07a9a5cbe75690b841403b21fd232bea9ec6eda0 100644 (file)
@@ -782,7 +782,7 @@ radv-polaris10-fossils:
   cache:
     key: ${CI_JOB_NAME}
     paths:
-      - .git-lfs-storage/
+      - traces-db/
 
 .traces-test-gl:
   extends:
index 3ee0dad6463b6abd639722db675090b5de46ddc5..641ef07f2dc330eb8891d6f0fe5f986baa5342c6 100644 (file)
@@ -82,6 +82,8 @@ apt-get install -y --no-remove \
       pkg-config \
       python-mako \
       python3-mako \
+      python3-pil \
+      python3-requests \
       qemu-user \
       scons \
       x11proto-dri2-dev \
index 2b94a2ef5c29938c03fdd181d6c40f73f2ac5018..747e0b21166351a574700df4f0493d554b393b35 100644 (file)
@@ -34,7 +34,6 @@ apt-get install -y --no-remove \
       g++ \
       gcc \
       git \
-      git-lfs \
       libexpat1 \
       libgbm-dev \
       libgles2-mesa-dev \
@@ -64,6 +63,7 @@ apt-get install -y --no-remove \
       python3-mako \
       python3-numpy \
       python3-pil \
+      python3-requests \
       python3-six \
       python3-yaml \
       python3.7 \
index 28331e83cd3479b907c63862f7295494e76a6184..cb7113cfcbdfa9b9e39f8493544695bb63ccb254 100755 (executable)
@@ -5,7 +5,7 @@ set -ex
 ARTIFACTS="$(pwd)/artifacts"
 
 # Set up the driver environment.
-export LD_LIBRARY_PATH="$(pwd)/install/lib/"
+export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$(pwd)/install/lib/"
 
 # Set environment for renderdoc libraries.
 export PYTHONPATH="$PYTHONPATH:/renderdoc/build/lib"
@@ -25,10 +25,4 @@ export WAFFLE_PLATFORM=surfaceless_egl
 # Perform a self-test to ensure tracie is working properly.
 "$ARTIFACTS/tracie/tests/test.sh"
 
-ret=0
-
-"$ARTIFACTS/tracie/tracie.sh" "$ARTIFACTS/traces.yml" renderdoc || ret=1
-
-"$ARTIFACTS/tracie/tracie.sh" "$ARTIFACTS/traces.yml" apitrace || ret=1
-
-exit $ret
+python3 $ARTIFACTS/tracie/tracie.py --file $ARTIFACTS/traces.yml --device-name $DEVICE_NAME
index 81ac001578f77a00e3289e695a12262b4c41fb73..e3f8c5d5319b197658fd78d9c575aff2129bfc78 100755 (executable)
@@ -22,7 +22,6 @@ ret=0
 # file:
 # https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section
 PATH="/gfxreconstruct/build/bin:$PATH" \
-    "$ARTIFACTS/tracie/tracie.sh"  "$ARTIFACTS/traces.yml" gfxreconstruct \
-    || ret=1
+    python3 $ARTIFACTS/tracie/tracie.py --file $ARTIFACTS/traces.yml --device-name $DEVICE_NAME
 
 exit $ret
index 689ee2d0a87e0f87f64f70d4eb39507569906dde..93e24b9ca252ff9ee100d6e70070171c2dbd7b76 100755 (executable)
 #
 # SPDX-License-Identifier: MIT
 
+import atexit
+import os
+import shutil
 import sys
+import tempfile
 from pathlib import Path
 
+def cleanup(dirpath):
+        shutil.rmtree(dirpath)
+
+dirpath = tempfile.mkdtemp()
+atexit.register(cleanup, dirpath)
+RENDERDOC_DEBUG_FILE = dirpath + "/renderdoc.log"
+
+# Needs to be in the environment before importing the module
+os.environ['RENDERDOC_DEBUG_LOG_FILE'] = RENDERDOC_DEBUG_FILE
 import renderdoc as rd
 
 def findDrawWithEventId(controller, eventId):
@@ -75,11 +88,16 @@ def loadCapture(filename):
     if not cap.LocalReplaySupport():
         raise RuntimeError("Capture cannot be replayed")
 
-    status,controller = cap.OpenCapture(rd.ReplayOptions(), None)
+    status, controller = cap.OpenCapture(rd.ReplayOptions(), None)
 
     if status != rd.ReplayStatus.Succeeded:
+        if os.path.exists(RENDERDOC_DEBUG_FILE):
+            print(open(RENDERDOC_DEBUG_FILE, "r").read())
         raise RuntimeError("Couldn't initialise replay: " + str(status))
 
+    if os.path.exists(RENDERDOC_DEBUG_FILE):
+        open(RENDERDOC_DEBUG_FILE, "w").write("")
+
     return (cap, controller)
 
 def renderdoc_dump_images(filename, eventIds, outputDir):
index 4d52578c47e2b615e921228fe1e3efb6b7c2aa4c..cd0f08e4efdb79ce88ead3be20a2a04fb33cfea5 100755 (executable)
@@ -4,25 +4,6 @@ TRACIE_DIR="$(dirname "$(readlink -f "$0")")/.."
 TEST_DIR=""
 TEST_EXIT=0
 
-create_repo() {
-    repo="$(mktemp -d $TEST_DIR/repo.XXXXXXXXXX)"
-    cp -R "$TEST_DIR"/tests/test-data/* "$repo"
-    (
-     cd "$repo";
-     git init -q .;
-     git config user.email "me@example.com"
-     git config user.name "Me me"
-     git lfs track '*.testtrace' > /dev/null;
-     git add .;
-     git commit -q -a -m 'initial';
-    )
-    echo $repo
-}
-
-destroy_repo() {
-    [ -d "$1"/.git ] && rm -rf "$1"
-}
-
 assert() {
     if ! $1; then
         echo "Assertion failed:  \"$1\""
@@ -32,22 +13,22 @@ assert() {
 
 run_tracie() {
     # Run tests for the .testtrace types, using the "gl-test-device" and "vk-test-device" device names.
-    DEVICE_NAME=gl-test-device CI_PROJECT_DIR="$TEST_DIR" \
-        "$TEST_DIR/tracie.sh" "$TEST_DIR/tests/traces.yml" testtrace && \
-    DEVICE_NAME=vk-test-device CI_PROJECT_DIR="$TEST_DIR" \
-        "$TEST_DIR/tracie.sh" "$TEST_DIR/tests/traces.yml" testtrace
+    python3 $TEST_DIR/tracie.py --file $TEST_DIR/tests/traces.yml --device-name gl-test-device && \
+    python3 $TEST_DIR/tracie.py --file $TEST_DIR/tests/traces.yml --device-name vk-test-device
 }
 
 cleanup() {
-    rm -rf "$TEST_DIR"
+    [ "$TEST_DIR" = "/tmp/*" ] && rm -rf "$TEST_DIR"
 }
 
 prepare_for_run() {
     TEST_DIR="$(mktemp -d -t tracie.test.XXXXXXXXXX)"
-    # Copy all the tracie scripts to the test dir and later make that the
-    # CI_PROJECT_DIR for the run-tests.sh script. This avoids polluting the
-    # normal working dir with test result artifacts.
+    # Copy all the tracie scripts to the test dir for the run-tests.sh script.
+    # This avoids polluting the normal working dir with test result artifacts.
     cp -R "$TRACIE_DIR"/. "$TEST_DIR"
+    cd "$TEST_DIR"
+    mkdir traces-db
+    mv tests/test-data/* traces-db/.
     trap cleanup EXIT
     # Ensure we have a clean environment.
     unset TRACIE_STORE_IMAGES
@@ -76,89 +57,41 @@ run_test() {
 }
 
 tracie_succeeds_if_all_images_match() {
-    repo="$(create_repo)"
-    cd "$repo"
-
     run_tracie
     assert "[ $? = 0 ]"
-
-    destroy_repo "$repo"
 }
 
 tracie_fails_on_image_mismatch() {
-    repo="$(create_repo)"
-    cd "$repo"
-
     sed -i 's/5efda83854befe0155ff8517a58d5b51/8e0a801367e1714463475a824dab363b/g' \
         "$TEST_DIR/tests/traces.yml"
 
     run_tracie
     assert "[ $? != 0 ]"
-
-    destroy_repo "$repo"
-}
-
-tracie_ignores_unspecified_trace_types() {
-    repo="$(create_repo)"
-    cd "$repo"
-
-    echo "  - path: trace1/empty.trace" >> "$TEST_DIR/tests/traces.yml"
-    echo "    expectations:" >> "$TEST_DIR/tests/traces.yml"
-    echo "    - device: gl-test-device" >> "$TEST_DIR/tests/traces.yml"
-    echo "      checksum: 000000000000000" >> "$TEST_DIR/tests/traces.yml"
-    # For the tests we only scan for the .testtrace type,
-    # so the .trace file added below should be ignored.
-    echo "empty" > trace1/empty.trace
-    git lfs track '*.trace'
-    git add trace1
-    git commit -a -m 'break'
-
-    run_tracie
-    assert "[ $? = 0 ]"
-
-    destroy_repo "$repo"
 }
 
 tracie_skips_traces_without_checksum() {
-    repo="$(create_repo)"
-    cd "$repo"
-
     echo "  - path: trace1/red.testtrace" >> "$TEST_DIR/tests/traces.yml"
     echo "    expectations:" >> "$TEST_DIR/tests/traces.yml"
     echo "    - device: bla" >> "$TEST_DIR/tests/traces.yml"
     echo "      checksum: 000000000000000" >> "$TEST_DIR/tests/traces.yml"
     # red.testtrace should be skipped, since it doesn't
     # have any checksums for our device
-    echo "ff0000ff" > trace1/red.testtrace
-    git add trace1
-    git commit -a -m 'red'
+    echo "ff0000ff" > traces-db/trace1/red.testtrace
 
     run_tracie
     assert "[ $? = 0 ]"
-
-    destroy_repo "$repo"
 }
 
 tracie_fails_on_dump_image_error() {
-    repo="$(create_repo)"
-    cd "$repo"
-
     # "invalid" should fail to parse as rgba and
     # cause an error
-    echo "invalid" > trace1/magenta.testtrace
-    git add trace1
-    git commit -a -m 'invalid'
+    echo "invalid" > traces-db/trace1/magenta.testtrace
 
     run_tracie
     assert "[ $? != 0 ]"
-
-    destroy_repo "$repo"
 }
 
 tracie_stores_only_logs_on_checksum_match() {
-    repo="$(create_repo)"
-    cd "$repo"
-
     run_tracie
     assert "[ $? = 0 ]"
 
@@ -169,14 +102,9 @@ tracie_stores_only_logs_on_checksum_match() {
     assert "[ ! -f "$TEST_DIR/results/trace2/test/vk-test-device/olive.testtrace-0.png" ]"
 
     ls -lR "$TEST_DIR"
-
-    destroy_repo "$repo"
 }
 
 tracie_stores_images_on_checksum_mismatch() {
-    repo="$(create_repo)"
-    cd "$repo"
-
     sed -i 's/5efda83854befe0155ff8517a58d5b51/8e0a801367e1714463475a824dab363b/g' \
         "$TEST_DIR/tests/traces.yml"
 
@@ -185,14 +113,9 @@ tracie_stores_images_on_checksum_mismatch() {
 
     assert "[ ! -f "$TEST_DIR/results/trace1/test/gl-test-device/magenta.testtrace-0.png" ]"
     assert "[ -f "$TEST_DIR/results/trace2/test/vk-test-device/olive.testtrace-0.png" ]"
-
-    destroy_repo "$repo"
 }
 
 tracie_stores_images_on_request() {
-    repo="$(create_repo)"
-    cd "$repo"
-
     (export TRACIE_STORE_IMAGES=1; run_tracie)
     assert "[ $? = 0 ]"
 
@@ -200,13 +123,10 @@ tracie_stores_images_on_request() {
     assert "[ -f "$TEST_DIR/results/trace2/test/vk-test-device/olive.testtrace-0.png" ]"
 
     ls -lR "$TEST_DIR"
-
-    destroy_repo "$repo"
 }
 
 run_test tracie_succeeds_if_all_images_match
 run_test tracie_fails_on_image_mismatch
-run_test tracie_ignores_unspecified_trace_types
 run_test tracie_skips_traces_without_checksum
 run_test tracie_fails_on_dump_image_error
 run_test tracie_stores_only_logs_on_checksum_match
diff --git a/.gitlab-ci/tracie/tracie.py b/.gitlab-ci/tracie/tracie.py
new file mode 100644 (file)
index 0000000..445f566
--- /dev/null
@@ -0,0 +1,167 @@
+import argparse
+import enum
+import glob
+import hashlib
+import os
+import requests
+import sys
+import tempfile
+import time
+import yaml
+
+from pathlib import Path
+from PIL import Image
+from urllib import parse
+
+import dump_trace_images
+
+TRACES_DB_PATH = os.getcwd() + "/traces-db/"
+RESULTS_PATH = os.getcwd() + "/results/"
+
+def replay(trace_path, device_name):
+    success = dump_trace_images.dump_from_trace(trace_path, [], device_name)
+
+    if not success:
+        print("[check_image] Trace %s couldn't be replayed. See above logs for more information." % (str(trace_path)))
+        return None, None, None
+    else:
+        base_path = trace_path.parent
+        file_name = trace_path.name
+        files = glob.glob(str(base_path / "test" / device_name / (file_name + "-*" + ".png")))
+        assert(files)
+        image_file = files[0]
+        files = glob.glob(str(base_path / "test" / device_name / (file_name + ".log")))
+        assert(files)
+        log_file = files[0]
+        return hashlib.md5(Image.open(image_file).tobytes()).hexdigest(), image_file, log_file
+
+def download_metadata(repo_url, repo_commit, trace_path):
+    # The GitLab API doesn't want the .git postfix
+    url = repo_url
+    if url.endswith(".git"):
+        url = url[:-4]
+    url = parse.urlparse(url)
+
+    url_path = url.path
+    if url_path.startswith("/"):
+        url_path = url_path[1:]
+
+    gitlab_api_url = url.scheme + "://" + url.netloc + "/api/v4/projects/" + parse.quote_plus(url_path)
+
+    r = requests.get(gitlab_api_url + "/repository/files/%s/raw?ref=%s" % (parse.quote_plus(trace_path), repo_commit))
+    metadata_raw = r.text.strip().split('\n')
+    metadata = dict(line.split(' ', 1) for line in metadata_raw[1:])
+    oid = metadata["oid"][7:] if metadata["oid"].startswith('sha256:') else metadata["oid"]
+    size = int(metadata['size'])
+
+    return oid, size
+
+def download_trace(repo_url, repo_commit, trace_path, oid, size):
+    headers = {
+        "Accept": "application/vnd.git-lfs+json",
+        "Content-Type": "application/vnd.git-lfs+json"
+    }
+    json = {
+        "operation": "download",
+        "transfers": [ "basic" ],
+        "ref": { "name": "refs/heads/%s" % repo_commit },
+        "objects": [
+            {
+                "oid": oid,
+                "size": size
+            }
+        ]
+    }
+
+    # The LFS API really wants the .git postfix...
+    if not repo_url.endswith(".git"):
+        repo_url += ".git"
+
+    r = requests.post(repo_url + "/info/lfs/objects/batch", headers=headers, json=json)
+    url = r.json()["objects"][0]["actions"]["download"]["href"]
+    open(TRACES_DB_PATH + trace_path, "wb").write(requests.get(url).content)
+
+def checksum(filename, hash_factory=hashlib.sha256, chunk_num_blocks=128):
+    h = hash_factory()
+    with open(filename,'rb') as f:
+        for chunk in iter(lambda: f.read(chunk_num_blocks*h.block_size), b''):
+            h.update(chunk)
+    return h.digest()
+
+def ensure_trace(repo_url, repo_commit, trace):
+    trace_path = TRACES_DB_PATH + trace['path']
+    if repo_url is None:
+        assert(repo_commit is None)
+        assert(os.path.exists(trace_path))
+        return
+
+    os.makedirs(os.path.dirname(trace_path), exist_ok=True)
+
+    if os.path.exists(trace_path):
+        local_oid = checksum(trace_path)
+
+    remote_oid, size = download_metadata(repo_url, repo_commit, trace['path'])
+
+    if not os.path.exists(trace_path) or local_oid != remote_oid:
+        print("[check_image] Downloading trace %s" % (trace['path']), end=" ", flush=True)
+        download_time = time.time()
+        download_trace(repo_url, repo_commit, trace['path'], remote_oid, size)
+        print("took %ds." % (time.time() - download_time), flush=True)
+
+def check_trace(repo_url, repo_commit, device_name, trace, expectation):
+    ensure_trace(repo_url, repo_commit, trace)
+
+    trace_path = Path(TRACES_DB_PATH + trace['path'])
+    checksum, image_file, log_file = replay(trace_path, device_name)
+    if checksum is None:
+            return False
+    elif checksum == expectation['checksum']:
+            print("[check_image] Images match for %s" % (trace['path']))
+            ok = True
+    else:
+            print("[check_image] Images differ for %s (expected: %s, actual: %s)" %
+                  (trace['path'], expectation['checksum'], checksum))
+            print("[check_image] For more information see "
+                  "https://gitlab.freedesktop.org/mesa/mesa/blob/master/.gitlab-ci/tracie/README.md")
+            ok = False
+
+    trace_dir = os.path.split(trace['path'])[0]
+    results_path = os.path.join(RESULTS_PATH, trace_dir, "test", device_name)
+    os.makedirs(results_path, exist_ok=True)
+    os.rename(log_file, os.path.join(results_path, os.path.split(log_file)[1]))
+    if not ok or os.environ.get('TRACIE_STORE_IMAGES', '0') == '1':
+            os.rename(image_file, os.path.join(results_path, os.path.split(image_file)[1]))
+
+    return ok
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--file', required=True,
+                        help='the name of the traces.yml file listing traces and their checksums for each device')
+    parser.add_argument('--device-name', required=True,
+                        help="the name of the graphics device used to replay traces")
+
+    args = parser.parse_args()
+
+    with open(args.file, 'r') as f:
+        y = yaml.safe_load(f)
+
+    if "traces-db" in y:
+        repo = y["traces-db"]["repo"]
+        commit_id = y["traces-db"]["commit"]
+    else:
+        repo = None
+        commit_id = None
+
+    traces = y['traces']
+    all_ok = True
+    for trace in traces:
+        for expectation in trace['expectations']:
+                if expectation['device'] == args.device_name:
+                        ok = check_trace(repo, commit_id, args.device_name, trace, expectation)
+                        all_ok = all_ok and ok
+
+    sys.exit(0 if all_ok else 1)
+
+if __name__ == "__main__":
+    main()
diff --git a/.gitlab-ci/tracie/tracie.sh b/.gitlab-ci/tracie/tracie.sh
deleted file mode 100755 (executable)
index afae5be..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env bash
-
-TRACIE_SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
-TRACES_YAML="$(readlink -f "$1")"
-TRACE_TYPE="$2"
-
-# Clone the traces-db repo without a checkout. Since we are dealing with
-# git-lfs repositories, such clones are very lightweight. We check out
-# individual files as needed at a later stage (see fetch_trace).
-clone_traces_db_no_checkout()
-{
-    local repo="$1"
-    local commit="$2"
-    rm -rf traces-db
-    git clone --no-checkout -c lfs.storage="$CI_PROJECT_DIR/.git-lfs-storage" "$repo" traces-db
-    (cd traces-db; git reset "$commit" || git reset "origin/$commit")
-}
-
-query_traces_yaml()
-{
-    python3 "$TRACIE_SCRIPT_DIR/query_traces_yaml.py" \
-        --file "$TRACES_YAML" "$@"
-}
-
-create_clean_git()
-{
-    rm -rf .clean_git
-    cp -R .git .clean_git
-}
-
-restore_clean_git()
-{
-    rm -rf .git
-    cp -R .clean_git .git
-}
-
-fetch_trace()
-{
-    local trace="${1//,/?}"
-    echo -n "[fetch_trace] Fetching $1... "
-    local output=$(git lfs pull -I "$trace" 2>&1)
-    local ret=0
-    if [[ $? -ne 0 || ! -f "$1" ]]; then
-        echo "ERROR"
-        echo "$output"
-        ret=1
-    else
-        echo "OK"
-    fi
-    # Restore a clean .git directory, effectively removing any downloaded
-    # git-lfs objects, in order to limit required storage. Note that the
-    # checked out trace file is still present at this point. We remove it
-    # when we are done with the trace replay at a later stage.
-    restore_clean_git
-    return $ret
-}
-
-get_dumped_file()
-{
-    local trace="$1"
-    local tracedir="$(dirname "$trace")"
-    local tracename="$(basename "$trace")"
-
-    find "$tracedir/test/$DEVICE_NAME" -name "$tracename*.$2"
-}
-
-check_image()
-{
-    local trace="$1"
-    local image="$2"
-
-    checksum=$(python3 "$TRACIE_SCRIPT_DIR/image_checksum.py" "$image")
-    expected=$(query_traces_yaml checksum --device-name "$DEVICE_NAME" "$trace")
-    if [[ "$checksum" = "$expected" ]]; then
-        echo "[check_image] Images match for $trace"
-        return 0
-    else
-        echo "[check_image] Images differ for $trace (expected: $expected, actual: $checksum)"
-        echo "[check_image] For more information see https://gitlab.freedesktop.org/mesa/mesa/blob/master/.gitlab-ci/tracie/README.md"
-        return 1
-    fi
-}
-
-archive_artifact()
-{
-    mkdir -p "$CI_PROJECT_DIR/results"
-    cp --parents "$1" "$CI_PROJECT_DIR/results"
-}
-
-if [[ -n "$(query_traces_yaml traces_db_repo)" ]]; then
-    clone_traces_db_no_checkout "$(query_traces_yaml traces_db_repo)" \
-                                "$(query_traces_yaml traces_db_commit)"
-    cd traces-db
-else
-    echo "Warning: No traces-db entry in $TRACES_YAML, assuming traces-db is current directory"
-fi
-
-# During git operations various git objects get created which
-# may take up significant space. Store a clean .git instance,
-# which we restore after various git operations to keep our
-# storage consumption low.
-create_clean_git
-
-ret=0
-
-for trace in $(query_traces_yaml traces --device-name "$DEVICE_NAME" --trace-types "$TRACE_TYPE")
-do
-    [[ -n "$(query_traces_yaml checksum --device-name "$DEVICE_NAME" "$trace")" ]] ||
-        { echo "[fetch_trace] Skipping $trace since it has no checksums for $DEVICE_NAME"; continue; }
-    fetch_trace "$trace" || exit $?
-    python3 "$TRACIE_SCRIPT_DIR/dump_trace_images.py" --device-name "$DEVICE_NAME" "$trace" || exit $?
-    image="$(get_dumped_file "$trace" png)"
-    check_image "$trace" "$image" && check_succeeded=true || { ret=1; check_succeeded=false; }
-    if [[ "$check_succeeded" = false || "$TRACIE_STORE_IMAGES" = "1" ]]; then
-        archive_artifact "$image"
-    fi
-    archive_artifact "$(get_dumped_file "$trace" log)"
-    # Remove the downloaded trace file to reduce the total amount of storage
-    # that is required.
-    rm "$trace"
-done
-
-exit $ret