From f029957835feeae320d5368be27b578912236a60 Mon Sep 17 00:00:00 2001 From: Logikoma Date: Wed, 5 Aug 2026 13:41:34 -0400 Subject: [PATCH 1/2] Add ASan and UBSan CI coverage --- .gitea/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index efdee35..4a0b639 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -64,6 +64,7 @@ jobs: -I tests \ tests/freestanding_fixture.c -o /tmp/freestanding_fixture.o - run: echo "🍏 This job's status is ${{ job.status }}." + sanitizer: runs-on: ubuntu-latest steps: From 6670837643d8319f4ad17d1c5f398c09c4ca7d9c Mon Sep 17 00:00:00 2001 From: Logikoma Date: Wed, 5 Aug 2026 13:42:12 -0400 Subject: [PATCH 2/2] Pass CMake arguments to mutation builds --- scripts/mutation_test.py | 12 +++++++++--- tests/MUTATION.md | 9 +++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/mutation_test.py b/scripts/mutation_test.py index 1b2828e..0cc4294 100755 --- a/scripts/mutation_test.py +++ b/scripts/mutation_test.py @@ -25,6 +25,8 @@ Usage: --work DIR scratch dir for the mutated copy (default: a temp dir) --timeout SECONDS per-suite ctest timeout (default: 120) --threshold PCT exit non-zero if mutation score < PCT (default: 0 = off) + --cmake-arg ARG pass an additional argument to the mutant CMake configure; + repeat for multiple arguments (e.g. -DAKERR_SANITIZE=thread) --list only list the mutants that would be run, then exit --keep keep the scratch working copy on exit (for debugging) -j N (reserved) currently runs sequentially @@ -199,10 +201,11 @@ def generate_mutants(root, rel_target): # --------------------------------------------------------------------------- # class Runner: - def __init__(self, work, timeout): + def __init__(self, work, timeout, cmake_args): self.work = work self.build = os.path.join(work, "build") self.timeout = timeout + self.cmake_args = cmake_args def _run(self, cmd, timeout=None): return subprocess.run( @@ -211,7 +214,8 @@ class Runner: ) def configure(self): - r = self._run(["cmake", "-S", ".", "-B", "build"], timeout=self.timeout) + r = self._run(["cmake", "-S", ".", "-B", "build", *self.cmake_args], + timeout=self.timeout) return r.returncode == 0, r.stdout def build_and_test(self): @@ -307,6 +311,8 @@ def main(): ap.add_argument("--work", default=None) ap.add_argument("--timeout", type=int, default=120) ap.add_argument("--threshold", type=float, default=0.0) + ap.add_argument("--cmake-arg", action="append", default=[], + help="pass an argument to the mutant CMake configure; repeatable") ap.add_argument("--junit", default=None, help="write a JUnit XML report to this path") ap.add_argument("--max-mutants", type=int, default=0, @@ -354,7 +360,7 @@ def main(): print(f"\nCopying sources to scratch dir: {work}") copy_tree(root, work) - runner = Runner(work, args.timeout) + runner = Runner(work, args.timeout, args.cmake_arg) print("Configuring baseline ...") ok, out = runner.configure() diff --git a/tests/MUTATION.md b/tests/MUTATION.md index a5cfcd7..1d993b6 100644 --- a/tests/MUTATION.md +++ b/tests/MUTATION.md @@ -32,6 +32,9 @@ scripts/mutation_test.py --target src/error.c --list # Gate CI: exit non-zero if the score drops below 90% scripts/mutation_test.py --threshold 90 + +# Check concurrency mutants under ThreadSanitizer +scripts/mutation_test.py --cmake-arg=-DAKERR_SANITIZE=thread ``` Via CMake (configures a build first if needed): @@ -40,8 +43,10 @@ Via CMake (configures a build first if needed): cmake --build build --target mutation ``` -Useful flags: `--timeout SECONDS` (per-suite build+test cap; a mutant that -hangs is counted as killed), `--keep` (retain the scratch copy for debugging), +Useful flags: `--cmake-arg ARG` (pass a CMake configure argument to every +mutant build; repeat it for multiple arguments), `--timeout SECONDS` (per-suite +build+test cap; a mutant that hangs is counted as killed), `--keep` (retain the +scratch copy for debugging), `--work DIR` (use a specific scratch directory), `--junit FILE` (write a JUnit XML report — surviving mutants appear as failing test cases).