Use bazel CI to repeat tests and identify flakes - #939
Conversation
This adds workflows that can run tests repeatedly in bazel to gain information about flaky tests. Since bazel targets can be annotated as flaky, distinct workflows are created to execute flaky and non-flaky tests separately. Any failures of tests annotated as non-flaky are a signal that the offending test should be annotated as flaky. The results from repeated executions of flaky tests will generate flakiness statistics and may aid in diagnosing the root cause of flakiness. Signed-off-by: Steve Peters <scpeters@intrinsic.ai>
Signed-off-by: Steve Peters <scpeters@intrinsic.ai>
Signed-off-by: Steve Peters <scpeters@intrinsic.ai>
* Rename jobs * Use --test_output=errors * Remove workflow_dispatch from outer workflows * Deduplicate inputs with yaml anchor Signed-off-by: Steve Peters <scpeters@intrinsic.ai>
Signed-off-by: Steve Peters <scpeters@intrinsic.ai>
| # `grep -q '^' fails if the query output is empty | ||
| bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))" \ | ||
| | grep -q '^' || exit 0 | ||
| bazel test --runs_per_test=${{ inputs.runs_per_test }} \ |
There was a problem hiding this comment.
bazel.yml uses -c opt to avoid perf related flakiness. This workflow uses fastbuild, so it tests different binaries and fills the disk cache with fastbuild artifacts. Should we add -c opt here for consistency?
| # Exit with success code 0 if no targets match the query | ||
| # `grep -q '^' fails if the query output is empty | ||
| bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))" \ | ||
| | grep -q '^' || exit 0 | ||
| bazel test --runs_per_test=${{ inputs.runs_per_test }} \ | ||
| --test_output=errors \ | ||
| $(bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))") |
There was a problem hiding this comment.
This step runs with bash -e and no pipefail. If bazel query itself fails, grep gets no input and the job exits 0 with no tests run. It also runs the query twice. Suggestion:
| # Exit with success code 0 if no targets match the query | |
| # `grep -q '^' fails if the query output is empty | |
| bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))" \ | |
| | grep -q '^' || exit 0 | |
| bazel test --runs_per_test=${{ inputs.runs_per_test }} \ | |
| --test_output=errors \ | |
| $(bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))") | |
| # Exit with success code 0 if no targets match the query | |
| targets=$(bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))") | |
| [ -n "$targets" ] || { echo "No matching test targets"; exit 0; } | |
| bazel test --runs_per_test=${{ inputs.runs_per_test }} \ | |
| --test_output=errors \ | |
| $targets |
| description: "0 to execute non-flaky tests, 1 to execute flaky tests" | ||
| default: 0 | ||
| required: false | ||
| type: string |
There was a problem hiding this comment.
Nit: the defaults are numbers but the type is string. Should we use type: number?
| ) | ||
|
|
||
| # Found with | ||
| # bazel test test:all --runs_per_test 10 |
There was a problem hiding this comment.
Nit: this comment was copied from test/BUILD.bazel. I think for these targets it should be //:all or //....
| "src/Node_TEST.cc", | ||
| ] | ||
|
|
||
| # Tests that should not be executed in parallel |
There was a problem hiding this comment.
nit: maybe expand on why this test should run exclusively?
🎉 New feature
Similar to gazebosim/gz-math#820
Summary
New workflows focused on detecting and characterizing flaky tests
This adds workflows that can run tests repeatedly in bazel to gain information about flaky tests. Since bazel targets can be annotated as flaky (see #866 for an example), distinct workflows are created to execute flaky and non-flaky tests separately.
Any failures of "non-flaky" tests indicate that the offending test should be annotated as flaky. The results from repeated executions of flaky tests provides flakiness statistics
and may aid in diagnosing the root cause of flakiness.
The workflows are implemented with a parameterized
Bazel repeat testsworkflow that is invoked viaworkflow_callby theBazel repeat flaky testsandBazel repeat non-flaky testsworkflows. For testing, the initial version (6624e08) of the flaky and non-flaky workflows are triggered on push to this branch in order to confirm that the workflows run properly, and are adjusted in 7d72098 to run on a schedule on Mondays and Fridays. I believe GitHub purges unused caches every 7 days, so this frequency prevents the bazel cache from being purged.Each workflow will be manually invokable via
workflow_dispatchonce this PR is merged, with theruns_per_testparameter exposed by each workflow, with a default value of10.Other fixes
In initial testing of this branch, I noticed that
Clock_TESTandNode_TESTare flaky when executed in this workflow, so I annotated them as flaky (4da1dd2) and then additionally added theexclusivetag toClock_TEST(a5ad8d2) to prevent that test to be executed in parallel since it seems particularly sensitive to system load.Backport Policy
We can backport this if we want, but the scheduled workflows will only run from
main.Test it
Review the CI results from 1fdf01d
Checklist
codecheckpassed (See contributing)Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining
Signed-off-byandGenerated-bymessages.Backports: If this is a backport, please use Rebase and Merge instead.