diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 71fa7455798f0..38988f465681f 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -192,25 +192,24 @@ jobs: MSYS2_ARG_CONV_EXCL: "*" run: | mkdir -p build - ${{ inputs.run }} 2>&1 | tee build/bazel-console.log - - name: Parse Bazel log for failures + { + ${{ inputs.run }} + } 2>&1 | tee build/bazel-console.log + - name: Rerun failures with debug if: always() shell: bash - run: | - awk ' - /PASSED in/ {n=0; delete a; next} - /FAILED in/ {a[++n]=$1} - END {for (i=1; i<=n; i++) print a[i]} - ' build/bazel-console.log > build/bazel-failures.txt - - name: Rerun failures with debug - if: failure() && inputs.rerun-with-debug + run: ./scripts/github-actions/rerun-failures.sh '${{ inputs.run }}' '${{ inputs.rerun-with-debug }}' + - name: Collect failed test logs + if: failure() shell: bash - run: | - if [ -s build/bazel-failures.txt ]; then - base_cmd=$(echo "${{ inputs.run }}" | sed 's| //[^ ]*||g') - targets=$(cat build/bazel-failures.txt | tr '\n' ' ') - $base_cmd --test_env=SE_DEBUG=true --flaky_test_attempts=1 $targets - fi + run: ./scripts/github-actions/collect-test-logs.sh + - name: Upload failed test logs + if: failure() + uses: actions/upload-artifact@v5 + with: + name: test-logs-${{ inputs.os }}-${{ inputs.name }}-${{ inputs.browser }} + retention-days: 7 + path: build/failures/** - name: Start SSH session if: failure() && runner.debug == '1' uses: mxschmitt/action-tmate@v3 @@ -229,15 +228,6 @@ jobs: if: ${{ always() && inputs.artifact-name != 'ignore-artifacts' }} run: | git diff > changes.patch - - name: "Upload test logs" - if: failure() - uses: actions/upload-artifact@v5 - with: - name: test-logs-${{ inputs.os }}-${{ inputs.name }}-${{ inputs.browser }} - retention-days: 7 - path: | - bazel-testlogs/**/*.log - build/bazel-failures.txt - name: "Upload changes" if: ${{ always() && inputs.artifact-name != 'ignore-artifacts' }} uses: actions/upload-artifact@v4 diff --git a/.github/workflows/ci-dotnet.yml b/.github/workflows/ci-dotnet.yml index c98d969d72bf2..77e6c704b92ea 100644 --- a/.github/workflows/ci-dotnet.yml +++ b/.github/workflows/ci-dotnet.yml @@ -22,6 +22,7 @@ jobs: with: name: Browser Tests java-version: 17 + rerun-with-debug: true os: windows run: | bazel test //dotnet/test/common:ElementFindingTest-firefox //dotnet/test/common:ElementFindingTest-chrome diff --git a/dotnet/test/common/AssemblyFixture.cs b/dotnet/test/common/AssemblyFixture.cs index d8605f5f4203e..842b7d166640b 100644 --- a/dotnet/test/common/AssemblyFixture.cs +++ b/dotnet/test/common/AssemblyFixture.cs @@ -34,8 +34,6 @@ public AssemblyFixture() [OneTimeSetUp] public async Task RunBeforeAnyTestAsync() { - Internal.Logging.Log.SetLevel(Internal.Logging.LogEventLevel.Trace); - await EnvironmentManager.Instance.WebServer.StartAsync(); if (EnvironmentManager.Instance.Browser == Browser.Remote) { diff --git a/dotnet/test/common/ElementFindingTest.cs b/dotnet/test/common/ElementFindingTest.cs index 4ff8f7bab9b89..5dff174be7750 100644 --- a/dotnet/test/common/ElementFindingTest.cs +++ b/dotnet/test/common/ElementFindingTest.cs @@ -35,6 +35,7 @@ public void ShouldBeAbleToFindASingleElementById() driver.Url = xhtmlTestPage; IWebElement element = driver.FindElement(By.Id("linkId")); Assert.That(element.GetAttribute("id"), Is.EqualTo("linkId")); + Assert.That("true", Is.EqualTo("Intentionally failing for CI debug rerun")); } [Test] diff --git a/scripts/github-actions/collect-test-logs.sh b/scripts/github-actions/collect-test-logs.sh new file mode 100755 index 0000000000000..4a35360f0164a --- /dev/null +++ b/scripts/github-actions/collect-test-logs.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Collects failed test logs from Bazel testlogs directory +# Reads targets from build/failures/_run2.txt if present, otherwise _run1.txt + +set -euxo pipefail + +TESTLOGS_ROOT=$(bazel info bazel-testlogs) + +LIST_FILE="" +if [ -s build/failures/_run2.txt ]; then + LIST_FILE="build/failures/_run2.txt" +elif [ -s build/failures/_run1.txt ]; then + LIST_FILE="build/failures/_run1.txt" +else + exit 0 +fi + +echo "Failures to collect from $LIST_FILE:" +cat "$LIST_FILE" + +while IFS= read -r target; do + [ -z "$target" ] && continue + + # Convert //path/to:target to path/to/target + rel_path=$(tr ':' '/' <<< "${target#//}") + + log_source="$TESTLOGS_ROOT/${rel_path}/test.log" + + if [ -f "$log_source" ]; then + # Convert path separators to underscores for safe filename + safe_name="${target#//}" + safe_name="${safe_name//[\/:]/_}" + echo "Copying log for $target..." + cp "$log_source" "build/failures/${safe_name}.log" + else + echo "Warning: No log found for $target at $log_source" >&2 + fi +done < "$LIST_FILE" diff --git a/scripts/github-actions/rerun-failures.sh b/scripts/github-actions/rerun-failures.sh new file mode 100755 index 0000000000000..685b5eba4119a --- /dev/null +++ b/scripts/github-actions/rerun-failures.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Parse Bazel console log for failures and optionally rerun with debug. + +set -euo pipefail + +RUN_CMD="${1:-}" +RERUN_WITH_DEBUG="${2:-false}" + +mkdir -p build/failures +awk '$1 ~ /^\/\// && $2 ~ /(FAILED|TIMEOUT|INCOMPLETE)/ && $3 == "in" { print $1 }' build/bazel-console.log > build/failures/_run1.txt + +if [ "$RERUN_WITH_DEBUG" != "true" ]; then + exit 0 +fi + +if [ ! -s build/failures/_run1.txt ]; then + echo "No failed tests to rerun." + exit 0 +fi + +base_cmd=$(echo "$RUN_CMD" | sed 's| //[^ ]*||g') +targets=$(tr '\n' ' ' < build/failures/_run1.txt) +echo "Rerunning tests: $base_cmd --test_env=SE_DEBUG=true --flaky_test_attempts=1 $targets" +set +e +{ + $base_cmd --test_env=SE_DEBUG=true --flaky_test_attempts=1 $targets +} 2>&1 | tee build/bazel-console2.log +status=$? +set -e +awk '$1 ~ /^\/\// && $2 ~ /FAILED/ && $3 == "in" { print $1 }' build/bazel-console2.log > build/failures/_run2.txt +exit $status