Repository navigation
fix some issues on the PR #224
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Memory-hardening CI: builds the C++ core + bindings with instrumentation | |
| # that the release wheels do not carry, and runs the test modules most likely | |
| # to surface memory issues (out-of-bounds, use-after-free, UB, silenced | |
| # assertions). Complements the functional suites on CircleCI, which run | |
| # against plain optimized builds. | |
| # | |
| # Two axes are covered here: | |
| # - WHAT is instrumented: the python extension (asan_ubsan / debug_asserts, | |
| # which need LD_PRELOAD to get the ASan runtime into an uninstrumented | |
| # interpreter) and the standalone Catch2 binary of src/tests (the *_cpp | |
| # jobs, natively linked against the sanitizer runtime -- no LD_PRELOAD, no | |
| # CPython suppressions, and no python/grid2op install at all). | |
| # - HOW it is instrumented: ASan+UBSan catches accesses OUTSIDE an allocation; | |
| # the assertion builds catch accesses that are logically wrong but still | |
| # INSIDE one (a wrong Eigen index into a large enough vector) -- invisible | |
| # to both ASan and the valgrind run of the C++ unit tests workflow. Neither | |
| # subsumes the other, hence four jobs. | |
| name: Sanitizers | |
| on: | |
| push: | |
| branches: | |
| # '**' and not '*': a single '*' does not match '/' in GitHub Actions | |
| # globs, so topic branches like 'foo/bar' would silently never run | |
| - '**' | |
| tags: | |
| - 'v*.*.*' | |
| jobs: | |
| asan_ubsan: | |
| # AddressSanitizer + UndefinedBehaviorSanitizer over the untrusted-input | |
| # path (binary serialization) and the heaviest C++ compute paths (solver | |
| # control, time series, contingency analysis). | |
| name: ASan + UBSan tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| submodules: true | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.12' | |
| - name: Install python dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -r requirements_compile_ci.txt | |
| python -m pip install grid2op scipy pandapower | |
| - name: Build lightsim2grid with ASan + UBSan | |
| # __SANITIZE=1 is picked up by src/core/CMakeLists.txt and | |
| # src/bindings/python/CMakeLists.txt: -fsanitize=address,undefined | |
| # on both lightsim2grid_core and lightsim2grid_cpp | |
| run: __SANITIZE=1 python -m pip install -v . --no-build-isolation | |
| - name: Run tests under ASan + UBSan | |
| # The sanitized code lives in a python extension, so the ASan runtime | |
| # must be the first thing loaded into the (uninstrumented) python | |
| # process: hence LD_PRELOAD. libstdc++ must be preloaded along with | |
| # it: python itself does not link it, and without it ASan's | |
| # __cxa_throw interceptor cannot resolve the real function and every | |
| # C++ exception aborts the process. Leak detection stays off: | |
| # CPython's allocator keeps interned objects alive by design and | |
| # would drown real reports in noise. | |
| env: | |
| ASAN_OPTIONS: detect_leaks=0 | |
| UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1 | |
| run: | | |
| export LD_PRELOAD="$(gcc -print-file-name=libasan.so) $(gcc -print-file-name=libstdc++.so.6)" | |
| cd lightsim2grid/tests | |
| python -W ignore -m unittest -v \ | |
| test_binary_serialization \ | |
| test_solver_control \ | |
| test_TimeSerie \ | |
| test_time_series_dc \ | |
| test_SecurityAnlysis \ | |
| test_DCSecurityAnlysis \ | |
| test_SecurityAnlysis_cpp \ | |
| test_ContingencyAnalysis_limit_violations \ | |
| test_ContingencyAnalysis_split \ | |
| test_check_grid \ | |
| test_LSGrid_out_of_bounds | |
| debug_asserts: | |
| # Release wheels are compiled with NDEBUG, which silences every Eigen | |
| # bounds assertion: logically-wrong-but-in-bounds indexing is invisible | |
| # to ASan. This build re-enables them (plus the ABI-safe libstdc++ | |
| # container checks) and runs the solver-heavy modules. | |
| name: Eigen/libstdc++ assertions tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| submodules: true | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.12' | |
| - name: Install python dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -r requirements_compile_ci.txt | |
| python -m pip install grid2op scipy pandapower | |
| - name: Build lightsim2grid with assertions re-enabled | |
| # __DEBUG_ASSERTS=1 -> -UNDEBUG -D_GLIBCXX_ASSERTIONS on both targets | |
| run: __DEBUG_ASSERTS=1 python -m pip install -v . --no-build-isolation | |
| - name: Run solver tests with assertions active | |
| run: | | |
| cd lightsim2grid/tests | |
| python -W ignore -m unittest -v \ | |
| test_ACPF \ | |
| test_DCPF \ | |
| test_solver_control | |
| asan_ubsan_cpp: | |
| # The Catch2 suite of src/tests under ASan + UBSan. The python jobs above | |
| # exercise the same core through the extension module; this one adds the | |
| # C++-only tests (the binary archive layer, the LSGrid / NRSystem tests) | |
| # and, being a plain binary linked against the sanitizer runtime, needs | |
| # neither LD_PRELOAD nor CPython suppressions. | |
| name: ASan + UBSan C++ tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| # eigen (transitive include of the core headers) and Catch2 | |
| submodules: true | |
| - name: Configure | |
| # standalone test project: no python, pybind11 or KLU involved. | |
| # __SANITIZE=1 is picked up by src/core/CMakeLists.txt (for | |
| # lightsim2grid_core) and by src/tests/CMakeLists.txt (for the test | |
| # binary itself, which must be compiled AND linked with | |
| # -fsanitize=address,undefined: ASan only instruments the translation | |
| # units it compiles, and linking the executable with it is what puts | |
| # the runtime first in the process). | |
| run: __SANITIZE=1 cmake -S src/tests -B build_tests -DCMAKE_BUILD_TYPE=RelWithDebInfo | |
| - name: Build | |
| # catch_discover_tests runs the freshly built binary post-build to | |
| # enumerate the TEST_CASEs, so the ASan options apply here too | |
| env: | |
| ASAN_OPTIONS: detect_leaks=0 | |
| run: __SANITIZE=1 cmake --build build_tests -j$(nproc) | |
| - name: Run tests under ASan + UBSan | |
| # Leak detection stays off, as in the python jobs: the Catch2 runner | |
| # and the solver registry keep process-lifetime singletons alive by | |
| # design. Real leaks in the tested code are covered by the valgrind | |
| # run of the C++ unit tests workflow (--leak-check=full). | |
| env: | |
| ASAN_OPTIONS: detect_leaks=0 | |
| UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1 | |
| run: ./build_tests/lightsim2grid_unit_tests | |
| debug_asserts_cpp: | |
| # The Catch2 suite of src/tests with the assertions an optimized build | |
| # silences. An index that is wrong but still inside its allocation is | |
| # invisible to BOTH valgrind (cpp_unit_tests.yml) and ASan (the job | |
| # above): only Eigen's own bounds checks catch it, and NDEBUG turns them | |
| # off. Release (not Debug) on purpose -- that is the configuration | |
| # NDEBUG applies to, and the one -UNDEBUG then has to undo. | |
| name: Eigen/libstdc++ assertions C++ tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| submodules: true | |
| - name: Configure | |
| # __DEBUG_ASSERTS=1 -> -UNDEBUG -D_GLIBCXX_ASSERTIONS on both | |
| # lightsim2grid_core and the test binary (see src/tests/CMakeLists.txt) | |
| run: __DEBUG_ASSERTS=1 cmake -S src/tests -B build_tests -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| run: __DEBUG_ASSERTS=1 cmake --build build_tests -j$(nproc) | |
| - name: Run tests with assertions active | |
| run: ctest --test-dir build_tests --output-on-failure |