From c85675df05251e6b11b885a891723be0a5fc0ea8 Mon Sep 17 00:00:00 2001 From: Josh Poole Date: Tue, 15 Sep 2026 10:16:25 +0100 Subject: [PATCH] 20260915 - Actually run the unit tests in CI The build-blah2 test job has never executed a test. It ran them against the runtime image: cd /opt/blah2/bin/test/unit 2>/dev/null || { echo "No unit tests directory found"; exit 0; } but the runtime stage copies only /blah2/bin/blah2, so that directory has never existed there. Every run printed "No unit tests directory found" and exited 0, and the job reported success. Confirmed on run 34849707024, which is green and ran nothing. The tests are built into /opt/blah2/bin/test/unit by the blah2 stage, so they now run there, as part of the build. set -e makes a failing test fail the build, and the two emptiness checks make a missing or empty test directory fail it as well, so the previous silent-pass mode cannot come back. BLAH2_FFT_CACHE is pointed at a writable path because a test that measures FFT lengths has to agree with itself across instances, and the default cache location is a host mount that does not exist at build time. The workflow step is replaced with the opposite assertion: the runtime image must NOT contain test binaries. That keeps the deployed image lean and would catch someone "fixing" this by copying tests into it. Running them in the build rather than in a separate job avoids shipping the build-stage image, which carries vcpkg and the toolchain, between jobs. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/build-blah2.yml | 27 +++++++++++++-------------- Dockerfile | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-blah2.yml b/.github/workflows/build-blah2.yml index cdc4fcdb..37f82293 100644 --- a/.github/workflows/build-blah2.yml +++ b/.github/workflows/build-blah2.yml @@ -82,21 +82,20 @@ jobs: echo "Loaded images:" docker images | grep ${{ inputs.tag }} - - name: Run blah2 unit tests + # The unit tests now run inside the build stage (see Dockerfile), which is + # the only image that contains them. A failing test fails the build job, + # so there is nothing left to run here. + # + # This step used to run them against the runtime image, which ships the + # binary alone, so it always printed "No unit tests directory found" and + # exited 0. It reported success without executing a single test. + - name: Confirm the runtime image carries no test binaries run: | - echo "Running blah2 unit tests..." - docker run --rm blah2:${{ inputs.tag }} sh -c ' - cd /opt/blah2/bin/test/unit 2>/dev/null || { echo "No unit tests directory found"; exit 0; } - TEST_COUNT=0 - for test in *; do - if [ -x "$test" ] && [ -f "$test" ]; then - echo "Running: $test" - ./"$test" || exit 1 - TEST_COUNT=$((TEST_COUNT + 1)) - fi - done - echo "Ran $TEST_COUNT unit tests" - ' + if docker run --rm blah2:${{ inputs.tag }} sh -c 'test -d /opt/blah2/bin/test/unit'; then + echo "Unexpected: test binaries shipped in the runtime image" + exit 1 + fi + echo "Runtime image is test-free, as intended. Tests ran during the build." - name: Check image size run: | diff --git a/Dockerfile b/Dockerfile index 96a5702c..45d0057a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -114,6 +114,30 @@ RUN set -ex \ && cp -v /opt/blah2/bin/blah2 /blah2/bin/ \ && chmod +x /blah2/bin/blah2 +# Run the unit tests here, in the build stage, because this is the only image +# that has them: the runtime stage deliberately ships the binary alone. The +# workflow used to run them against the runtime image, where the directory does +# not exist, and swallowed that with `exit 0`, so no test had ever actually +# executed in CI. +# +# set -e means a failing test fails the build. The emptiness checks mean a +# missing or empty test directory fails the build too, rather than passing +# silently the way the old step did. +RUN set -eu; \ + cd /opt/blah2/bin/test/unit; \ + if [ -z "$(ls -A .)" ]; then echo "FAIL: no unit tests were built"; exit 1; fi; \ + export BLAH2_FFT_CACHE=/tmp/blah2-fft-length.cache; \ + count=0; \ + for t in *; do \ + if [ -f "$t" ] && [ -x "$t" ]; then \ + echo "==== $t ===="; \ + ./"$t"; \ + count=$((count+1)); \ + fi; \ + done; \ + if [ "$count" -eq 0 ]; then echo "FAIL: no executable unit tests found"; exit 1; fi; \ + echo "==== $count unit test binaries passed ====" + WORKDIR /blah2/bin # =============================================================================