diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 8451017ba..bfb98c22a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -23,7 +23,7 @@ jobs: test/fetch-test-deps.sh --get-deps ubuntu - name: Generate coverage report run: | - contrib/coverage.bash ubuntu-ci + contrib/coverage.bash --os ubuntu-ci --jobs $(getconf _NPROCESSORS_ONLN) - name: Upload coverage report uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 5935ebadf..562224f6e 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -13,7 +13,7 @@ env: CMAKE_CONFIG_TYPE: Debug # `cmake --build` now implies `--config Debug`. # Approximate number of CPU cores in GitHub's runners as of 2026-03-18: # https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories - CTEST_PARALLEL_LEVEL: 0 # `ctest` now implies `--parallel 0` (number of logical CPUs). + CTEST_PARALLEL_LEVEL: 4 # `ctest` now implies `--parallel 4`. CTEST_NO_TESTS_ACTION: error # Make CTest fail if it cannot find any tests. (That should never happen.) CTEST_OUTPUT_ON_FAILURE: ON # CTest reports test program output on failure. @@ -52,7 +52,7 @@ jobs: if: matrix.buildsys == 'make' run: | make develop -kj Q= CXX=${{ matrix.cxx }} - sudo make install -j Q= + sudo make install Q= - name: Build & install using CMake if: matrix.buildsys == 'cmake' # Since GitHub's runners are basically kitchen sinks, @@ -98,7 +98,7 @@ jobs: - name: Run tests using our script if: matrix.buildsys == 'make' run: | - CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }} + CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }} --jobs $(getconf _NPROCESSORS_ONLN) - name: Run tests using CTest if: matrix.buildsys == 'cmake' run: | @@ -311,7 +311,7 @@ jobs: test/fetch-test-deps.sh --get-deps ${{ matrix.os }} - name: Run tests run: | - test/run-tests.sh --os ${{ matrix.os }} + test/run-tests.sh --os ${{ matrix.os }} --jobs $(getconf _NPROCESSORS_ONLN) cygwin: strategy: @@ -344,11 +344,11 @@ jobs: pkg-config - name: Build & install using Make run: | # Cygwin does not support `make develop` sanitizers ASan or UBSan - make -kj Q= - make install -j Q= + make -k -j $(getconf _NPROCESSORS_ONLN) Q= + make install Q= - name: Run tests run: | - test/run-tests.sh --only-internal + test/run-tests.sh --jobs $(getconf _NPROCESSORS_ONLN) --only-internal freebsd: runs-on: ubuntu-latest @@ -371,6 +371,6 @@ jobs: .github/scripts/install_deps.sh freebsd run: | # Leak detection is not supported on FreeBSD, so disable it. cmake -B build --preset develop -DTESTS_OS_NAME=freebsd - cmake --build build --verbose -- -k -j 4 + cmake --build build --verbose -- -k -j $(getconf NPROCESSORS_ONLN) ASAN_OPTIONS=detect_leaks=0 ctest --test-dir build --schedule-random --label-exclude external cmake --install build --verbose diff --git a/contrib/coverage.bash b/contrib/coverage.bash index 46fd1adf9..fd1405507 100755 --- a/contrib/coverage.bash +++ b/contrib/coverage.bash @@ -1,17 +1,57 @@ #!/usr/bin/env bash set -e +usage() { + cat <<"EOF" +Generates LCOV code coverage report for RGBDS. +Options: + -h, --help show this help message + -o, --open open the HTML report in the preferred application + --os specify for test/run-tests.sh (e.g. `macos-14`) + --jobs build with `make -j` +EOF +} + +# Parse options in pure Bash because macOS `getopt` is stuck +# in what util-linux `getopt` calls `GETOPT_COMPATIBLE` mode +runtests_args= +make_jobs= +open_report=false +while [[ $# -gt 0 ]]; do + case "$1" in + -h|--help) + usage + exit 0 + ;; + -o|--open) + open_report=true + ;; + --jobs) + shift + runtests_args="$runtests_args --jobs $1" + make_jobs="-j$1" + ;; + --os) + shift + runtests_os="$runtests_args --os $1" + ;; + *) + echo "$(basename "$0"): unknown option '$1'" + exit 1 + ;; + esac + shift +done + # Build RGBDS with gcov support -make coverage -j +# shellcheck disable=SC2086 # (This word splitting is intentional.) +make coverage $make_jobs -# Run the tests +# Run the tests, forwarding all script arguments pushd test ./fetch-test-deps.sh -if [[ $# -eq 0 ]]; then - ./run-tests.sh -else - ./run-tests.sh --os "$1" -fi +# shellcheck disable=SC2086 # (This word splitting is intentional.) +./run-tests.sh $runtests_args popd # Generate coverage logs @@ -24,12 +64,14 @@ lcov -c --no-external -d . -o "$COVERAGE_INFO" lcov -r "$COVERAGE_INFO" src/asm/parser.{hpp,cpp} src/link/script.{hpp,cpp} -o "$COVERAGE_INFO" genhtml --dark-mode --num-spaces 4 -f -s -o coverage/ "$COVERAGE_INFO" -# Check whether running from coverage.yml workflow -if [ "$1" != "ubuntu-ci" ]; then - # Open report in web browser +if "$open_report"; then + # Open the report in preferred web browser if [ "$(uname)" == "Darwin" ]; then open coverage/index.html else xdg-open coverage/index.html fi +else + # Output the path to the report + echo "Open $PWD/coverage/index.html" fi diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4a305a72f..8717ebcc1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -33,7 +33,7 @@ foreach(component "asm" "link" "fix" "gfx") COMMAND bash -- test.sh WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${component}") set_tests_properties("rgb${component}" PROPERTIES REQUIRED_FILES "$" - PROCESSORS 1 + PROCESSORS 1 # This test is entirely serial. LABELS "rgb${component}") endforeach() set_tests_properties(rgbgfx PROPERTIES REQUIRED_FILES "$;$;$") @@ -44,9 +44,9 @@ add_test(NAME fetch-test-deps set_tests_properties(fetch-test-deps PROPERTIES FIXTURES_SETUP "external-repos" LABELS "external") add_test(NAME external - COMMAND bash -- run-tests.sh --only-external ${ONLY_FREE} ${OS_NAME} + COMMAND bash -- run-tests.sh --jobs $ENV{CTEST_PARALLEL_LEVEL} --only-external ${ONLY_FREE} ${OS_NAME} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") set_tests_properties(external PROPERTIES DEPENDS "rgbasm;rgblink;rgbfix;rgbgfx" # Only attempt building whole projects if each tool passes muster on its own. - PROCESSORS 4 + PROCESSORS $ENV{CTEST_PARALLEL_LEVEL} FIXTURES_REQUIRED "external-repos" LABELS "external") # Allow filtering out external tests. diff --git a/test/run-tests.sh b/test/run-tests.sh index d473b4317..f1553cfdb 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -19,6 +19,7 @@ Options: --os skip tests known to fail on (e.g. `macos-14`) --installed-rgbds use the system installed RGBDS (only compatible with external codebases) + --jobs build external codebases with `make -j` EOF } @@ -29,6 +30,7 @@ internal=true external=true installedrgbds=false osname= +make_jobs= FETCH_TEST_DEPS="fetch-test-deps.sh" RGBDS_PATH="RGBDS=../../" while [[ $# -gt 0 ]]; do @@ -52,6 +54,10 @@ while [[ $# -gt 0 ]]; do installedrgbds=true RGBDS_PATH= ;; + --jobs) + shift + make_jobs="-j$1" + ;; --os) shift osname="$1" @@ -117,8 +123,9 @@ test_downstream() { # owner repo make-target build-file build-hash echo >&2 'Please run `'"$FETCH_TEST_DEPS"'` before running the test suite' return 1 fi - make clean $RGBDS_PATH - make -j4 "$3" $RGBDS_PATH + make clean "$RGBDS_PATH" + # shellcheck disable=SC2086 # (This word splitting is intentional.) + make $make_jobs "$3" "$RGBDS_PATH" hash="$(sha1sum -b "$4" | head -c 40)" if [ "$hash" != "$5" ]; then echo >&2 'SHA-1 hash of '"$4"' did not match: '"$hash"