name: test-linux

on:
  push:
    branches: [master, stable-*]
  pull_request:
    branches: [master, stable-*]

jobs:
  cmake:
    name: CMake correctness checks
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Configure build
        run: cmake -DAUDIT_SOURCE_FILE_LIST=ON .

  gcc-tests:
    name: gcc ${{ matrix.build_type }} ${{ matrix.runs_on }}
    runs-on: ${{ matrix.runs_on }}
    env:
      CC: gcc

    strategy:
      matrix:
        build_type: ["Debug", "Release"]
        runs_on: ["ubuntu-latest", "ubuntu-22.04-arm"]

    steps:
      - uses: actions/checkout@v4

      - name: Install Doxygen
        run: |
          sudo apt update
          sudo apt-get install doxygen graphviz clang-format-14

      - name: Configure build
        run: cmake -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DWARNINGS_AS_ERRORS=ON .

      - name: Formatting check
        working-directory: build
        run: |
          clang-format-14 --version
          make format
          git diff --exit-code

      - name: Build
        working-directory: build
        run: make

      - name: binding-functions
        working-directory: build
        run: |
          make binding-functions
          test -s binding-functions

      - name: Tests
        working-directory: build
        run: |
          make test
          sudo make install

        # Note the packages aren't used to test the examples below
      - name: Test packaging
        working-directory: build
        run: cpack -D CPACK_PACKAGE_CONTACT="Test build in CI"

      - name: Examples
        run: |
          mkdir build/examples
          cd build/examples
          cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ../../examples
          make
          env CTEST_OUTPUT_ON_FAILURE=1 make test 

  clang-tests:
    name: clang ${{ matrix.build_type }} ${{ matrix.runs_on }} ${{ matrix.compile_opt }}
    runs-on: ${{ matrix.runs_on }}
    env:
      CC: clang

    strategy:
      matrix:
        # See Clang docs for more information on the sanitizers:
        # https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
        compile_opt: ["", "-fsanitize=undefined,float-divide-by-zero -fno-sanitize-recover=undefined,float-divide-by-zero", "-fsanitize=memory -fno-sanitize-recover=memory", "-fsanitize=address -fno-sanitize-recover=address"]
        build_type: ["Debug", "Release"]
        runs_on: ["ubuntu-latest", "ubuntu-22.04-arm"]
        exclude:
          # TODO: Include msan on arm
          - runs_on: ubuntu-22.04-arm
            compile_opt: "-fsanitize=memory -fno-sanitize-recover=memory"

    steps:
      - uses: actions/checkout@v4

      - name: Install Doxygen
        run: |
          sudo apt update
          sudo apt-get install doxygen graphviz clang-format-14

      - name: Configure build
        run: cmake -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DWARNINGS_AS_ERRORS=ON -DCMAKE_C_FLAGS="${{ matrix.compile_opt }}" .

      - name: Formatting check
        working-directory: build
        run: |
          clang-format-14 --version
          make format
          git diff --exit-code

      - name: Build
        working-directory: build
        run: make

      - name: binding-functions
        working-directory: build
        run: |
          make binding-functions
          test -s binding-functions

      - name: Tests
        working-directory: build
        run: |
          make CTEST_OUTPUT_ON_FAILURE=1 test
          sudo make install

        # Note the packages aren't used to test the examples below
      - name: Test packaging
        working-directory: build
        run: cpack -D CPACK_PACKAGE_CONTACT="Test build in CI"

      - name: Examples
        run: |
          mkdir build/examples
          cd build/examples
          cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_C_FLAGS="${{ matrix.compile_opt }}" ../../examples
          make
          env CTEST_OUTPUT_ON_FAILURE=1 make test 

  valgrind-tests:
    name: Valgrind
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install Valgrind
        run: |
          sudo apt update
          sudo apt-get install valgrind

      - name: Configure build
        run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Debug -DWRAP_VALGRIND=ON .

      - name: Build
        working-directory: build
        run: make

      - name: Tests
        working-directory: build
        env:
          CTEST_OUTPUT_ON_FAILURE: 1
        run: make test-fast

  coverage-tests:
    name: Coverage
    runs-on: ubuntu-latest
    env:
      CC: gcc

    steps:
      - uses: actions/checkout@v4

      - name: Install lcov
        run: |
          sudo apt update
          sudo apt-get install lcov

      - name: Configure build
        run: cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON -DWARNINGS_AS_ERRORS=ON -DH3_PREFIX=testprefix_ .

      - name: Build
        run: make

      - name: Tests
        run: make coverage

      - uses: coverallsapp/github-action@master
        with:
          path-to-lcov: ./coverage.cleaned.info
          github-token: ${{ secrets.GITHUB_TOKEN }}
