Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m2s
API Docs / doc-build (pull_request) Successful in 46s
Markdown link check / check (pull_request) Successful in 47s
C++ Tests / test-cgal (pull_request) Failing after 10m51s
C++ Tests / quality-gates (pull_request) Successful in 2m21s
Two reviewer-facing additions:
1. New `quality-gates` job in .gitea/workflows/cpp-tests.yml
──────────────────────────────────────────────────────────
Runs in parallel with test-cgal after test-fast. Installs
`codespell` + `shellcheck` (apt) into the existing ci-cpp container,
then executes four scripts strictly (exit 1 on any finding):
* license-headers.sh — 66/66 files carry SPDX MIT
* cgal-conventions.py — 0 violations across 6 CGAL public headers
* codespell.sh — 0 typos across docs + source + scripts
* shellcheck.sh — 0 findings across 16 shell scripts
Each ran at 0 findings locally for weeks before promotion. The
gates are now contractual: a regression fails the PR. Total
wall-time on the eulernest runner: ~30 s.
2. New code/deps/THIRD-PARTY-LICENSES.md
──────────────────────────────────────
Enumerates every vendored dependency under code/deps/, plus the
auto-fetched GoogleTest, plus the system-required Boost, with:
* upstream project + version + SPDX identifier
* compatibility note for MIT distribution
* a downstream-packager license matrix (header-only consumer
vs CLI binary) clarifying the LGPL §3 vs §4 distinction
relevant to CGAL's header-only consumption
Required for any future Linux-distribution packaging and for the
CGAL submission's compliance check. Cross-referenced from
doc/architecture/dependencies.md.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
96 lines
4.2 KiB
Bash
Executable File
96 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# scripts/quality/sanitizers.sh
|
||
#
|
||
# Build the fast test suite with AddressSanitizer + UndefinedBehaviorSanitizer
|
||
# and run it. Catches:
|
||
# * use-after-free, double-free, heap-buffer-overflow (ASan)
|
||
# * signed integer overflow, NaN propagation, alignment violations (UBSan)
|
||
# * Eigen / CGAL template-induced UB that escapes the regular build
|
||
#
|
||
# Local-only (not in CI): the sanitizer build is ~3× slower and brittle
|
||
# against system libraries. Run it before every release tag, after
|
||
# touching any Newton/Hessian code, or when investigating intermittent
|
||
# test failures.
|
||
#
|
||
# Usage:
|
||
# bash scripts/quality/sanitizers.sh # default: ASan + UBSan
|
||
# ASAN_OPTIONS=... UBSAN_OPTIONS=... bash scripts/quality/sanitizers.sh
|
||
#
|
||
# Exit codes:
|
||
# 0 every test passes under sanitizer instrumentation
|
||
# 1 a sanitizer report was triggered (test failure or runtime error)
|
||
# 2 prerequisite missing (no clang/gcc with sanitizer support)
|
||
|
||
set -euo pipefail
|
||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||
cd "$ROOT"
|
||
|
||
BUILD_DIR="build-sanitizers"
|
||
SAN_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -O1 -g"
|
||
|
||
# Default ASan/UBSan runtime options — print stack on first error,
|
||
# abort on first issue (so CI logs make the cause obvious).
|
||
export ASAN_OPTIONS="${ASAN_OPTIONS:-detect_leaks=1:abort_on_error=1:print_stacktrace=1}"
|
||
export UBSAN_OPTIONS="${UBSAN_OPTIONS:-print_stacktrace=1:halt_on_error=1}"
|
||
|
||
echo "========================================"
|
||
echo " Sanitizer build (ASan + UBSan)"
|
||
echo " flags : $SAN_FLAGS"
|
||
echo " ASAN : $ASAN_OPTIONS"
|
||
echo " UBSAN : $UBSAN_OPTIONS"
|
||
echo "========================================"
|
||
|
||
# ── Pick a compiler with sanitizer support ──────────────────────────────────
|
||
# Prefer clang (better diagnostics); fall back to gcc.
|
||
CXX_BIN=""
|
||
for cand in clang++-17 clang++-16 clang++-15 clang++ g++; do
|
||
if command -v "$cand" >/dev/null 2>&1; then
|
||
CXX_BIN="$cand"
|
||
break
|
||
fi
|
||
done
|
||
if [ -z "$CXX_BIN" ]; then
|
||
echo "FAIL: no clang++ / g++ found in PATH" >&2
|
||
exit 2
|
||
fi
|
||
echo "Using CXX = $CXX_BIN ($("$CXX_BIN" --version | head -1))"
|
||
echo
|
||
|
||
# ── Configure ────────────────────────────────────────────────────────────────
|
||
# CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=PRE_TEST: without this,
|
||
# gtest_discover_tests runs the (sanitizer-instrumented) test binary at
|
||
# *build* time to enumerate test cases. ASan aborts that subprocess
|
||
# the moment it sees any allocation in static-init, which fails the
|
||
# build before we can even get to ctest. PRE_TEST defers discovery to
|
||
# `ctest` invocation, which is exactly what we want.
|
||
cmake -S code -B "$BUILD_DIR" \
|
||
-DCMAKE_CXX_COMPILER="$CXX_BIN" \
|
||
-DCMAKE_CXX_FLAGS="$SAN_FLAGS" \
|
||
-DCMAKE_EXE_LINKER_FLAGS="$SAN_FLAGS" \
|
||
-DCMAKE_BUILD_TYPE=Debug \
|
||
-DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=PRE_TEST \
|
||
-Wno-dev
|
||
|
||
# ── Build the fast (non-CGAL) tests only ────────────────────────────────────
|
||
# CGAL tests would 4–5× the build time under sanitizers and have a
|
||
# higher false-positive surface (CGAL's expression-template trickery).
|
||
# Use the fast suite as the sanitizer canary; full coverage of the CGAL
|
||
# layer is covered by coverage.sh + the regular Release build.
|
||
nice -n 19 cmake --build "$BUILD_DIR" --target conformallab_tests \
|
||
-j"$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 2)"
|
||
|
||
# ── Run ──────────────────────────────────────────────────────────────────────
|
||
cd "$BUILD_DIR"
|
||
if ctest -E "^cgal\." --output-on-failure --output-junit san-results.xml; then
|
||
cd "$ROOT"
|
||
echo
|
||
echo "OK: all sanitizer-instrumented tests passed."
|
||
exit 0
|
||
else
|
||
cd "$ROOT"
|
||
echo
|
||
echo "FAIL: sanitizer-instrumented tests reported issues."
|
||
echo " See: $BUILD_DIR/Testing/Temporary/LastTest.log"
|
||
exit 1
|
||
fi
|