Open
Conversation
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



[FEATURE] AI-Accessible Test Artifacts & Structured Test Report Endpoint
In raising this pull request, I confirm the following (please check boxes):
My familiarity with the project is as follows (check one):
What does this PR do?
This PR introduces artifact capture and upload from CI test VMs to GCS, along with a set of new download endpoints and a structured JSON report endpoint designed to make test results fully accessible — including to AI agents.
A demo video is attached below showcasing all the new features end to end.
PR.Showcase.mp4
Objective
Right now, when a test run fails, debugging is hard. You can see that something went wrong, but you can't easily grab the binary that was tested, see what it actually printed, or get the coredump if it crashed. Everything lives ephemerally on the VM and disappears. This PR fixes that by persisting the important artifacts to GCS and making them accessible via clean download URLs.
The
ai.jsonendpoint was also something I wanted to add to make it possible for AI agents (or any automated tooling) to consume a full structured report of a test run — with direct download links to every artifact — without needing to scrape HTML.Changes
install/ci-vm/ci-linux/ci/runCI/tmp/combined_stdout.log, and preserves the original exit code faithfully. This means you get a single unified log of everything ccextractor printed across all test cases in a run.test_artifacts/{test_id}/:ccextractorbinary itself/tmp/coredumps/, if one was producedtestIDis now passed as VM instance metadata so the CI script knows where to namespace the uploads.mod_ci/controllers.pytestIDis now included in the metadata passed to both Linux and Windows VM instances at creation time.os.rename()→os.replace()in upload handlers.os.renamecan fail silently or raise an error when source and destination are on different filesystems (which can happen with temp directories).os.replacehandles this correctly.mod_test/controllers.pydownload_build_log_fileto usesend_from_directorydirectly instead of going throughserve_file_download, which was doing unnecessary GCS signed URL generation for a file that's already on disk._artifact_redirecthelper that looks up a blob in GCS, generates a short-lived signed URL, and redirects to it — or returns 404 if the blob doesn't exist. All new download endpoints use this./<test_id>/binary— downloads the ccextractor binary used in the test (tries Linux name first, then Windows)/<test_id>/coredump— downloads the coredump if one was captured/<test_id>/combined-stdout— downloads the unified stdout/stderr log/<test_id>/regression/<regression_test_id>/<output_id>/output-got— downloads the actual output file for a specific test case/<test_id>/regression/<regression_test_id>/<output_id>/output-expected— downloads the expected output file for a specific test case/<test_id>/sample/<sample_id>— downloads the sample file used in a regression test/<test_id>/ai.json— returns a full structured JSON report of the test run (see below)utility.pyos.path.joinwas used to build GCS blob paths. Since GCS paths are always forward-slash separated andos.path.joinbehaves differently on Windows, this is now done with a manual/.join` with empty-part filtering.GCS_SIGNED_URL_EXPIRY_LIMITfrom''(an empty string that would crashtimedelta) to30.The
ai.jsonEndpointGET /<test_id>/ai.jsonreturns a JSON object that looks roughly like:{ "test_id": 123, "commit": "abc123", "platform": "linux", "branch": "master", "status": "completed", "binary_url": "https://...", "coredump_url": null, "log_url": "https://...", "combined_stdout_url": "https://...", "summary": { "total": 50, "passed": 48, "failed": 2 }, "test_cases": [ { "regression_test_id": 7, "category": "...", "sample_filename": "sample.ts", "sample_url": "https://...", "arguments": "-out=ttxt", "result": "Fail", "exit_code": 1, "expected_exit_code": 0, "runtime_ms": 4231, "how_to_reproduce": "./ccextractor -out=ttxt sample.ts", "outputs": [ { "output_id": 3, "correct_extension": ".ttxt", "expected_url": "https://...", "got_url": "https://...", "diff_url": "https://..." } ] } ], "how_to_reproduce": "Download the binary and sample, then run: ./ccextractor {arguments} {sample_filename}" }Every URL in the response is a signed GCS download link valid for 30 minutes. The intent is that this endpoint gives an AI agent (or any automated system) everything it needs to fully investigate a test failure — the binary, the sample, the expected and actual outputs, the diff, and the full stdout log — without any additional context.
Notes
/tmp/combined_stdout.logpath, which is fine given each test run gets its own VM.