Ci/trustworthy system tests - #403
Open
pvkumara wants to merge 3 commits into
Open
Conversation
Separate infrastructure failures, test assertions, and advisory metric changes so CI blocks only on real test or integrity failures while preserving comparable performance evidence.
Preserve explicit infrastructure intent through pytest call reports so simulator startup crashes cannot be misreported as algorithm assertions.
Expose trajectory and takeoff sweeps in workflow dispatch so CI validation can run minimal algorithm samples before expanding to expensive matrices.
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.
What features did you add and/or bugs did you address?
No linked GitHub issue. This is
ci/trustworthy-system-tests→develop. It closes the original PR #384 / run 32786410874 metrics-job bug (same red X later PRs still hit on develop).This is not a new hole and not AirSim, OptiTrack, or GPU. The tests passed. The red X is the old metrics-job bug: a parser crash that CI then mislabels as a metric regression.
What actually happened on run 32786410874:
build_packagesand it passedparse_metrics.pydied immediately:The report job still does
pip install tabulateonly. The parser now importsharness.run_meta→discovery.py→yaml. No PyYAML → crash → noreport.md→ the summary says “No metrics report generated.”The next step is
Fail on regression. It treats any exit code 1 as:There was no baseline (
No matching workflow run found with any artifactsondevelop), and no numeric comparison ran. The banner is wrong.This PR is the unmerged fix for that exact failure. Until it lands, develop still runs the old policy.
It also makes the rest of CI outcomes trustworthy so a missing package, a dead simulator, a missing image, or a 20% Hz/CPU change cannot be scored as “the algorithm got worse”:
Separate assertion, infrastructure, collection/integrity, and advisory metric failures.
Compare metrics only when two runs have the same completed campaign fingerprint (same tests and same CLI/config: sim, robot count, trajectories, velocities, etc.).
Do not fail CI on numeric metric deltas. Fail CI on real test failures, infrastructure/prerequisite failures, or a broken report.
Capture a bounded, secret-free
diagnostics/bundle when bring-up or readiness fails.Let maintainers run a minimal flight campaign from
workflow_dispatch(trajectory_types,takeoff_velocities) before a full matrix.Please add videos and images to demonstrate the feature. Please upload videos to somewhere persistent (e.g. YouTube or Vimeo) for archival purposes.
No flight video (this is CI/report-job reliability, not a vehicle feature). Useful screenshots if attaching: run 32786410874 annotations (green Run Tests, red Metrics Report,
No module named 'yaml', “Metric regression detected”); after this lands, a PR Test Metrics comment that treats numeric deltas as advisory (not “Fail on regression”).How did you implement it?
Three commits:
Make system-test outcomes trustworthy and actionableClassify readiness failures as infrastructureAllow focused manual flight campaignsDirect fix for #384 / run 32786410874
tests/report-requirements.txt(PyYAML+tabulate), notpip install tabulateonly. That is theNo module named 'yaml'fix.parse_metrics.pynumeric deltas are advisory and exit 0. Parser/integrity failures exit 2 and write a real error intoreport.md.Metric regression detectedis removed. A missing baseline or a parser crash is no longer labeled a metric regression.Failure classes (
run_meta.jsonschema v2)tests/harness/run_meta.pyrecordsfailure_class(assertion/infrastructure/collection/ci_integrity/no_tests/none) and a campaign fingerprint over selected sim tests plus behavior-changing options (--sim,--num-robots,--trajectory-types,--takeoff-velocities, tolerances, etc.). Setup/teardown failures and@pytest.mark.infrastructure/ “infrastructure prerequisite” / “simulator process failure” messages stay infrastructure, not algorithm assertions.Advisory metrics
parse_metrics.pyalways exits 0 on numeric deltas. Parser/integrity failures exit 2. Timeouts/missing values are not scored as numeric regressions. Per-robot keys stay visible (no replica pooling).Baseline selection
Dropped
dawidd6/action-download-artifact. CI downloads recent successfultest-results-*artifacts withgh, thenharness.baseline.select_baseline_pathpicks the newest completed, fingerprint-identical campaign.Diagnostics
harness.diagnostics.collect_failure_diagnosticswritestests/results/<run>/diagnostics/<test>.json: last 200 container log lines, tmux panes, ROS node/topic lists, GPU snapshot, last 30 commands. Secrets are excluded (SAFE_ENV_KEYSonly).Fail-fast readiness
wait_for_first_messagetakes ahealth_check. Liveliness/sensors abort if the AirSim/Isaac process dies while waiting for/clock. OptiTrack missing SDK/images fail as infrastructure instead of skip/timeout.Identity and image prep
/pytestrefuses to run if the PR head SHA is unresolved (no default-branch fallback). Image prep writesimage-preparation.json(pulled/cache-retagged/locally-built/missing/delegated-to-build-docker).Config-only CLI
airstack up --config-onlyvalidates launch intent without requiring Docker,omni_pass.env, or the Pegasus submodule — used by launch-intent contract tests.How do you run and use it?
There is no new robot/sim stack feature to launch. This changes how CI classifies and reports results.
To inspect launch config without Docker/credentials (host):
To exercise the report job on a PR (GitHub UI / comment, not a local stack launch):
/pytest -m liveliness --sim isaacsim --num-robots 1 --stress-iterations 1(write access, same-repo only), ormarks,sim,num_robots, and optionallytrajectory_types=Circle/takeoff_velocities=0.5for a minimal campaign.Then: Checks → the workflow run → Run Tests for pytest logs; Metrics Report / job Summary for the markdown report; run Summary → Artifacts →
test-results-*forsummary.txt,run_meta.json,metrics.json, anddiagnostics/on failure.From the repo root, on
ci/trustworthy-system-tests:On the PR comment (not local bash):
Expected benefit vs develop: a
build_packages-only run no longer dies withNo module named 'yaml'and then printsMetric regression detected. Maintainer looks atreport.md/ the PR Test Metrics comment, not a fake regression banner.Testing with PyTest
Hermetic unit/contract tests (no GPU, no stack bring-up). They assert classification, fingerprinting, baseline selection, advisory exits, bounded diagnostics, and workflow YAML policy. No new flight metrics; existing Hz/compute/timing metrics stay recorded but are advisory.
New / extended files:
tests/meta/test_campaign_reporting_contract.py— assertion vs infrastructure, fingerprint includes robot count, baseline ignores mismatches, timeout ≠ regression,parse_metricsexits 0 on deltas / 2 on parser crash (test_metric_delta_cli_is_advisory,test_report_parser_crash_remains_blocking)tests/meta/test_diagnostics_contract.py— secret-free bounded bundle; dead sim process abort; OptiTrack missing SDK is infrastructuretests/meta/test_workflow_contract.py— no SHA fallback, cancel-in-progress on/pytest,report-requirements.txtinstead ofpip install tabulate, noMetric regression detected, fingerprint baseline download, minimal sweep inputstest_metrics_reporting_contract.py,test_collection_contract.py,test_launch_intent_contract.pyThe two tests that specifically gate run 32786410874:
test_report_job_installs_declared_dependenciesandtest_metric_deltas_are_advisory_but_parser_errors_block.airstack test -m ...AIRSTACK_ROOT="$(pwd)" pytest tests/ -m unit -vOr only the contracts for this bug:
AIRSTACK_ROOT="$(pwd)" pytest tests/meta/test_workflow_contract.py tests/meta/test_campaign_reporting_contract.py -vEquivalent via the CLI wrapper:
airstack test -m unit -vAll selected tests PASSED.
For the #384 bug specifically, a maintainer should confirm:
test_report_job_installs_declared_dependenciesPASSES — workflow containspip install -r tests/report-requirements.txtand does not contain a barepip install tabulate; the requirements file listsPyYAMLandtabulate.test_metric_deltas_are_advisory_but_parser_errors_blockPASSES — step name isFail on report integrity error; stringMetric regression detectedis absent.test_metric_delta_cli_is_advisoryPASSES —parse_metrics.main()exits 0 when the report marks a numeric change.test_report_parser_crash_remains_blockingPASSES — a parser crash exits 2 and writes “Report generation failed”, not a fake regression banner.After merge, a run like 32786410874 should either produce
report.mdor fail as report integrity with a real traceback — never “Metric regression detected” on a missing Python package, and never a claim thatbuild_packagesmade the algorithm worse.Documentation
n — nav already points at the pages we edited.
Yes for this change:
tests/README.md— artifact layout, advisory comparison, dispatch inputs, report job behaviordocs/development/intermediate/testing/ci_cd.md— what fails the build, baseline fingerprinting, diagnostics, troubleshooting.agents/skills/run-system-tests/SKILL.md— agent-facing interpretation ofrun_meta.json/ diagnosticsIs there sufficient visual media?
No new diagrams beyond the existing CI flowchart (report job now finalizes the Check Run after posting). Screenshots of a metrics comment would help review.
Versioning
.envfile according to semantic versioning?No. This does not change Docker image contents (no robot/sim/GCS Dockerfile or workspace package change).
check-version-incrementshould not require a bump for harness/workflow/docs-only work.