diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 176304e8..78d710e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 30 container: - image: ci.trafficserver.apache.org:5000/proxy-verifier/ubuntu:24.04 + image: ci.trafficserver.apache.org/proxy-verifier/ubuntu:24.04 steps: - name: Check out repository uses: actions/checkout@v6 @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 30 container: - image: ci.trafficserver.apache.org:5000/proxy-verifier/ubuntu:24.04 + image: ci.trafficserver.apache.org/proxy-verifier/ubuntu:24.04 env: RAT_VERSION: 0.17 RAT_SHA256: 401939ebe5a52c6ed524029897bf914eaaba503d36c069ebcdbd8847a9e7cf93 @@ -85,14 +85,14 @@ jobs: --input-exclude "tests/unit_tests/catch.hpp" \ --input-exclude "tests/autests/gold_tests/autest-site/default_url_file" \ --input-exclude-std GIT HIDDEN_DIR HIDDEN_FILE -- \ - "${GITHUB_WORKSPACE}" | tee RAT.txt + "${GITHUB_WORKSPACE}" | tee "${RUNNER_TEMP}/RAT.txt" - name: Upload RAT report if: always() uses: actions/upload-artifact@v6 with: name: rat-report - path: RAT.txt + path: ${{ runner.temp }}/RAT.txt if-no-files-found: ignore unit-tests: @@ -100,7 +100,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 60 container: - image: ci.trafficserver.apache.org:5000/proxy-verifier/ubuntu:24.04 + image: ci.trafficserver.apache.org/proxy-verifier/ubuntu:24.04 steps: - name: Check out repository uses: actions/checkout@v6 @@ -127,7 +127,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 60 container: - image: ci.trafficserver.apache.org:5000/proxy-verifier/ubuntu:24.04 + image: ci.trafficserver.apache.org/proxy-verifier/ubuntu:24.04 steps: - name: Check out repository uses: actions/checkout@v6 @@ -139,18 +139,22 @@ jobs: run: cmake --build --preset dev-external --parallel - name: Run AuTests - run: ./build/dev-external/autest.sh --clean=none -j"$(nproc)" + run: ./build/dev-external/autest.sh -v --clean=none -j"$(nproc)" - - name: Collect AuTest logs + - name: Collect AuTest sandbox if: failure() run: | mkdir -p artifacts - cp -a /tmp/proxy-verifier-autest artifacts/ 2>/dev/null || true + if [[ -d /tmp/proxy-verifier-autest ]]; then + tar --create --gzip \ + --file="${GITHUB_WORKSPACE}/artifacts/autest-sandbox.tar.gz" \ + --directory=/tmp proxy-verifier-autest + fi - - name: Upload AuTest logs + - name: Upload AuTest sandbox if: failure() uses: actions/upload-artifact@v6 with: - name: autest-logs - path: artifacts + name: autest-sandbox + path: artifacts/autest-sandbox.tar.gz if-no-files-found: ignore diff --git a/tests/autests/autest-parallel.py.in b/tests/autests/autest-parallel.py.in index 035fccfd..52c35391 100644 --- a/tests/autests/autest-parallel.py.in +++ b/tests/autests/autest-parallel.py.in @@ -288,6 +288,7 @@ def run_worker( sandbox_base: Path, extra_args: List[str], port_offset_step: int, + verbose: bool, collect_timings: bool, ) -> TestResult: start_time = time.time() @@ -298,6 +299,10 @@ def run_worker( env = os.environ.copy() env["AUTEST_PORT_OFFSET"] = str(worker_id * port_offset_step) + if verbose: + timestamp = time.strftime("%H:%M:%S") + print(f"[{timestamp}] Worker:{worker_id:2d} Starting {len(tests)} tests", flush=True) + try: if collect_timings: output_chunks = [] @@ -312,19 +317,53 @@ def run_worker( else: result.failed += 1 result.failed_tests.append(test_name) + if verbose: + timestamp = time.strftime("%H:%M:%S") + print(f"[{timestamp}] Worker:{worker_id:2d} {status:4s} {duration:6.1f}s {test_name}", flush=True) result.output = "\n".join(output_chunks) result.return_code = 0 if result.failed == 0 else 1 else: - proc = subprocess.run( - build_autest_command(test_dir, sandbox, extra_args, tests), - cwd=SOURCE_AUTEST_DIR, - capture_output=True, - text=True, - env=env, - timeout=3600, - ) - result.output = proc.stdout + proc.stderr - result.return_code = proc.returncode + cmd = build_autest_command(test_dir, sandbox, extra_args, tests) + if verbose: + proc = subprocess.Popen( + cmd, + cwd=SOURCE_AUTEST_DIR, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + env=env, + ) + output_lines = [] + try: + if proc.stdout is not None: + for line in proc.stdout: + output_lines.append(line) + clean = strip_ansi(line).strip() + if clean.startswith("Running Test") or "Passed" in clean or "Failed" in clean: + timestamp = time.strftime("%H:%M:%S") + print(f"[{timestamp}] Worker:{worker_id:2d} {clean}", flush=True) + proc.wait(timeout=60) + finally: + if proc.poll() is None: + proc.terminate() + try: + proc.wait(timeout=5) + except subprocess.TimeoutExpired: + proc.kill() + proc.wait() + result.output = "".join(output_lines) + result.return_code = proc.returncode + else: + proc = subprocess.run( + cmd, + cwd=SOURCE_AUTEST_DIR, + capture_output=True, + text=True, + env=env, + timeout=3600, + ) + result.output = proc.stdout + proc.stderr + result.return_code = proc.returncode parsed = parse_autest_output(result.output) result.passed = parsed["passed"] result.failed = parsed["failed"] @@ -456,6 +495,7 @@ def main() -> None: parser.add_argument("-f", "--filters", nargs="+", action="extend", dest="filters", help="Filter tests by name or glob") parser.add_argument("-D", "--directory", default="gold_tests", help="AuTest test directory") parser.add_argument("--port-offset-step", type=int, default=1000, help="Port offset between workers") + parser.add_argument("-v", "--verbose", action="store_true", help="Stream test progress") parser.add_argument("--collect-timings", action="store_true", help="Run tests one at a time per worker") parser.add_argument("--timings-file", type=Path, default=None, help="Timing data JSON file") parser.add_argument("--no-timing", action="store_true", help="Disable timing-based load balancing") @@ -547,6 +587,7 @@ def main() -> None: sandbox_base, extra_args, args.port_offset_step, + args.verbose, args.collect_timings, ) futures[future] = worker_id diff --git a/tests/autests/gold_tests/http2_abort/replay_files/client_goaway_after_headers.yaml b/tests/autests/gold_tests/http2_abort/replay_files/client_goaway_after_headers.yaml index bab8726d..8589f27a 100644 --- a/tests/autests/gold_tests/http2_abort/replay_files/client_goaway_after_headers.yaml +++ b/tests/autests/gold_tests/http2_abort/replay_files/client_goaway_after_headers.yaml @@ -1,6 +1,6 @@ # @file # -# Copyright 2023, Verizon Media +# Copyright 2026, Verizon Media # SPDX-License-Identifier: Apache-2.0 # @@ -11,6 +11,8 @@ sessions: stack: http2 tls: sni: test_sni + # Let the proxy process GOAWAY before AuTest tears down background processes. + keep-connection-open: 2s transactions: - client-request: frames: diff --git a/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_data.yaml b/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_data.yaml index 4347e3f7..e96b2507 100644 --- a/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_data.yaml +++ b/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_data.yaml @@ -1,6 +1,6 @@ # @file # -# Copyright 2023, Verizon Media +# Copyright 2026, Verizon Media # SPDX-License-Identifier: Apache-2.0 # @@ -11,6 +11,8 @@ sessions: stack: http2 tls: sni: test_sni + # Let the proxy process the reset before AuTest tears down background processes. + keep-connection-open: 2s transactions: - client-request: frames: diff --git a/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_headers.yaml b/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_headers.yaml index 84c81e8c..65cd9f25 100644 --- a/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_headers.yaml +++ b/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_after_headers.yaml @@ -1,6 +1,6 @@ # @file # -# Copyright 2023, Verizon Media +# Copyright 2026, Verizon Media # SPDX-License-Identifier: Apache-2.0 # @@ -11,6 +11,8 @@ sessions: stack: http2 tls: sni: test_sni + # Let the proxy process the reset before AuTest tears down background processes. + keep-connection-open: 2s transactions: - client-request: frames: diff --git a/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_mixed_data.yaml b/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_mixed_data.yaml index f5b1f43d..5c63fedf 100644 --- a/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_mixed_data.yaml +++ b/tests/autests/gold_tests/http2_abort/replay_files/client_rst_stream_mixed_data.yaml @@ -1,6 +1,6 @@ # @file # -# Copyright 2023, Verizon Media +# Copyright 2026, Verizon Media # SPDX-License-Identifier: Apache-2.0 # @@ -11,6 +11,8 @@ sessions: stack: http2 tls: sni: test_sni + # Let the proxy process the reset before AuTest tears down background processes. + keep-connection-open: 2s transactions: - client-request: frames: