From 7391f464de2dd61c8d6bb4b309eac4f0e2bc0d80 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 29 Dec 2025 17:23:00 -0800 Subject: [PATCH] get mutation tests running on macOS (#2998) * install mull on macOS * runs * run in ci * more readable * fail early * who doesn't have curl * fix that? * uv sourcing * unset that * mit * cleanup --- .github/workflows/tests.yml | 8 +++++++- .gitignore | 1 + opendbc/safety/tests/libsafety/SConscript | 10 ++++++---- opendbc/safety/tests/mutation.sh | 14 +++++++++----- setup.sh | 15 ++++++++++++++- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2744fd56..c5ecf348 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,8 +43,14 @@ jobs: mutation: name: Safety mutation tests - runs-on: ${{ github.repository == 'commaai/opendbc' && 'namespace-profile-amd64-8x16' || 'ubuntu-latest' }} + runs-on: ${{ matrix.os }} timeout-minutes: 45 + strategy: + fail-fast: false + matrix: + include: + - os: ${{ github.repository == 'commaai/opendbc' && 'namespace-profile-amd64-8x16' || 'ubuntu-latest' }} + - os: ${{ github.repository == 'commaai/opendbc' && 'namespace-profile-macos-8x14' || 'macos-latest' }} env: GIT_REF: ${{ github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.event.before || format('origin/{0}', github.event.repository.default_branch) }} steps: diff --git a/.gitignore b/.gitignore index 33007330..5b2213fd 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ cppcheck-addon-ctu-file-list opendbc/safety/tests/coverage-out compile_commands.json +.mull/ diff --git a/opendbc/safety/tests/libsafety/SConscript b/opendbc/safety/tests/libsafety/SConscript index e9bd59db..c4b2a5d9 100644 --- a/opendbc/safety/tests/libsafety/SConscript +++ b/opendbc/safety/tests/libsafety/SConscript @@ -47,11 +47,16 @@ if GetOption('ubsan'): # mutation env menv = env.Clone() +if system == "Darwin": + menv.PrependENVPath('PATH', '/opt/homebrew/opt/llvm@17/bin') + mull_plugin = Dir('#').abspath + '/.mull/lib/mull-ir-frontend-17' +else: + mull_plugin = '/usr/lib/mull-ir-frontend-17' menv['CC'] = 'clang-17' flags = [ '-fprofile-instr-generate', '-fcoverage-mapping', - '-fpass-plugin=/usr/lib/mull-ir-frontend-17', + f'-fpass-plugin={mull_plugin}', '-g', '-grecord-command-line', ] @@ -61,9 +66,6 @@ menv['CFLAGS'].remove('-fprofile-arcs') menv['CFLAGS'].remove('-ftest-coverage') for build_env, suffix in ((env, ""), (menv, "_mutation")): - # TODO: add macOS support - if (build_env == menv) and (system == "Darwin"): - continue safety = build_env.SharedObject(f"safety{suffix}.os", "safety.c") libsafety = build_env.SharedLibrary(f"libsafety{suffix}.so", [safety]) diff --git a/opendbc/safety/tests/mutation.sh b/opendbc/safety/tests/mutation.sh index 29bca601..c0513357 100755 --- a/opendbc/safety/tests/mutation.sh +++ b/opendbc/safety/tests/mutation.sh @@ -8,10 +8,14 @@ source $DIR/../../../setup.sh GIT_REF="${GIT_REF:-origin/master}" GIT_ROOT=$(git rev-parse --show-toplevel) -MULL_OPS="mutators: [cxx_increment, cxx_decrement, cxx_comparison, cxx_boundary, cxx_bitwise_assignment, cxx_bitwise, cxx_arithmetic_assignment, cxx_arithmetic, cxx_remove_negation]" -echo -e "$MULL_OPS" > $GIT_ROOT/mull.yml -scons -j$(nproc) -D -echo -e "timeout: 1000000\ngitDiffRef: $GIT_REF\ngitProjectRoot: $GIT_ROOT" >> $GIT_ROOT/mull.yml +cat > $GIT_ROOT/mull.yml < /dev/null 2>&1; then curl -1sLf 'https://dl.cloudsmith.io/public/mull-project/mull-stable/setup.deb.sh' | sudo -E bash sudo apt-get update && sudo apt-get install -y clang-17 mull-17 fi +elif [ "$(uname -s)" = "Darwin" ]; then + if ! brew list llvm@17 &>/dev/null; then + brew install llvm@17 + fi + if [ ! -f "$BASEDIR/.mull/bin/mull-runner-17" ]; then + MULL_VERSION="0.26.1" + MULL_ZIP="Mull-17-${MULL_VERSION}-LLVM-17.0-macOS-arm64-14.7.4.zip" + MULL_DIR="Mull-17-${MULL_VERSION}-LLVM-17.0-macOS-arm64-14.7.4" + curl -LO "https://github.com/mull-project/mull/releases/download/${MULL_VERSION}/${MULL_ZIP}" + unzip -o "$MULL_ZIP" + mv "$MULL_DIR" "$BASEDIR/.mull" + rm "$MULL_ZIP" + fi + export PATH="$BASEDIR/.mull/bin:$PATH" fi if ! command -v uv &>/dev/null; then