name: BCC Build and tests

on:
  push:
    branches:
      - master
  pull_request:

env:
  # Use docker.io for Docker Hub if empty
  REGISTRY: ghcr.io
  # github.repository as <account>/<repo>
  IMAGE_NAME: ${{ github.repository }}

permissions:
  contents: read # to fetch code (actions/checkout)
  pull-requests: read # to read pull requests (dorny/paths-filter)

jobs:
  test_bcc:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        os: [{distro: "ubuntu", version: "20.04", nick: focal}]
        llvm_version: [12, 15, 17]
        env:
        - TYPE: Debug
          PYTHON_TEST_LOGFILE: critical.log
          RW_ENGINE_ENABLED: ON
        - TYPE: Debug
          PYTHON_TEST_LOGFILE: critical.log
          RW_ENGINE_ENABLED: OFF
        - TYPE: Release
          PYTHON_TEST_LOGFILE: critical.log
          RW_ENGINE_ENABLED: ON
    steps:
    - uses: actions/checkout@v4
    - uses: dorny/paths-filter@v3
      id: changes
      with:
        filters: |
          docker:
            - 'docker/build/**'
    - name: System info
      run: |
        uname -a
        ip addr
    - name: Pull docker container
      if: steps.changes.outputs.docker == 'false'
      run: |
        docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.os.distro }}-${{ matrix.os.version }}
    - name: Build docker container
      if: steps.changes.outputs.docker == 'true'
      uses: ./.github/actions/build-container
      with:
        os_distro: ${{ matrix.os.distro }}
        os_version: ${{ matrix.os.version }}
        os_nick: ${{ matrix.os.nick }}
        llvm_versions: ${{ matrix.llvm_version }}
    - name: Tag docker container
      run: |
        docker tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.os.distro }}-${{ matrix.os.version }} bcc-docker
    - name: Run bcc build - llvm-${{ matrix.llvm_version }}
      env: ${{ matrix.env }}
      run: |
        /bin/bash -c \
                   "docker run --privileged \
                   --pid=host \
                   -v $(pwd):/bcc \
                   -v /sys/kernel/debug:/sys/kernel/debug:rw \
                   -v /lib/modules:/lib/modules:ro \
                   -v /usr/src:/usr/src:ro \
                   -v /usr/include/linux:/usr/include/linux:ro \
                   bcc-docker \
                   /bin/bash -c \
                   'mkdir -p /bcc/build && cd /bcc/build && \
                    LLVM_ROOT=/usr/lib/llvm-${{ matrix.llvm_version }} cmake -DCMAKE_BUILD_TYPE=${TYPE} -DENABLE_LLVM_NATIVECODEGEN=${RW_ENGINE_ENABLED} .. && make -j9'"
    - name: Run bcc's cc tests
      env: ${{ matrix.env }}
      # tests are wrapped with `script` as a hack to get a TTY as github actions doesn't provide this
      # see https://github.com/actions/runner/issues/241
      run: |
        script -e -c /bin/bash -c \
        "docker run -ti \
                    --privileged \
                    --network=host \
                    --pid=host \
                    -v $(pwd):/bcc \
                    -v /sys/kernel/debug:/sys/kernel/debug:rw \
                    -v /lib/modules:/lib/modules:ro \
                    -v /usr/src:/usr/src:ro \
                    -e CTEST_OUTPUT_ON_FAILURE=1 \
                    bcc-docker \
                    /bin/bash -c \
                    '/bcc/build/tests/wrapper.sh \
                        c_test_all sudo /bcc/build/tests/cc/test_libbcc'"

    - name: Run all tests
      env: ${{ matrix.env }}
      run: |
        script -e -c /bin/bash -c \
        "docker run -ti \
                    --privileged \
                    --network=host \
                    --pid=host \
                    -v $(pwd):/bcc \
                    -v /sys/kernel/debug:/sys/kernel/debug:rw \
                    -v /lib/modules:/lib/modules:ro \
                    -v /usr/src:/usr/src:ro \
                    -e CTEST_OUTPUT_ON_FAILURE=1 \
                    bcc-docker \
                    /bin/bash -c \
                    'cd /bcc/build && \
                     make test PYTHON_TEST_LOGFILE=$PYTHON_TEST_LOGFILE ARGS=-V'"

    - name: Check critical tests
      env: ${{ matrix.env }}
      run: |
        critical_count=$(grep @mayFail tests/python/critical.log | wc -l)
        echo "There were $critical_count critical tests skipped with @mayFail:"
        grep -A2 @mayFail tests/python/critical.log

    - uses: actions/upload-artifact@v4
      with:
        name: critical-tests-${{ matrix.env['TYPE'] }}-${{ matrix.os.version }}
        path: tests/python/critical.log
        overwrite: true

  test_bcc_fedora:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        os: [{distro: "fedora", version: "38", nick: "f38"}]
        env:
        - TYPE: Debug
          PYTHON_TEST_LOGFILE: critical.log
        - TYPE: Release
          PYTHON_TEST_LOGFILE: critical.log
    steps:
    - uses: actions/checkout@v4
    - uses: dorny/paths-filter@v3
      id: changes
      with:
        filters: |
          docker:
            - 'docker/build/**'
    - name: System info
      run: |
        uname -a
        ip addr
    - name: Pull docker container
      if: steps.changes.outputs.docker == 'false'
      run: |
        docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.os.distro }}-${{ matrix.os.version }}
    - name: Build docker container
      if: steps.changes.outputs.docker == 'true'
      uses: ./.github/actions/build-container
      with:
        os_distro: ${{ matrix.os.distro }}
        os_version: ${{ matrix.os.version }}
        os_nick: ${{ matrix.os.nick }}
    - name: Tag docker container
      run: |
        docker tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.os.distro }}-${{ matrix.os.version }} bcc-docker
    - name: Run bcc build
      env: ${{ matrix.env }}
      run: |
        /bin/bash -c \
                   "docker run --privileged \
                   --pid=host \
                   -v $(pwd):/bcc \
                   -v /sys/kernel/debug:/sys/kernel/debug:rw \
                   -v /lib/modules:/lib/modules:ro \
                   -v /usr/src:/usr/src:ro \
                   -v /usr/include/linux:/usr/include/linux:ro \
                   bcc-docker \
                   /bin/bash -c \
                   'mkdir -p /bcc/build && cd /bcc/build && \
                    cmake -DCMAKE_BUILD_TYPE=${TYPE} -DENABLE_LLVM_SHARED=ON -DRUN_LUA_TESTS=OFF .. && make -j9'"
    - name: Run libbpf-tools build
      env: ${{ matrix.env }}
      run: |
        /bin/bash -c \
                   "docker run --privileged \
                   --pid=host \
                   -v $(pwd):/bcc \
                   -v /sys/kernel/debug:/sys/kernel/debug:rw \
                   -v /lib/modules:/lib/modules:ro \
                   -v /usr/src:/usr/src:ro \
                   -v /usr/include/linux:/usr/include/linux:ro \
                   bcc-docker \
                   /bin/bash -c \
                   'cd /bcc/libbpf-tools && make -j9'"

    - name: Run bcc's cc tests
      env: ${{ matrix.env }}
      # tests are wrapped with `script` as a hack to get a TTY as github actions doesn't provide this
      # see https://github.com/actions/runner/issues/241
      run: |
        script -e -c /bin/bash -c \
        "docker run -ti \
                    --privileged \
                    --network=host \
                    --pid=host \
                    -v $(pwd):/bcc \
                    -v /sys/kernel/debug:/sys/kernel/debug:rw \
                    -v /lib/modules:/lib/modules:ro \
                    -v /usr/src:/usr/src:ro \
                    -e CTEST_OUTPUT_ON_FAILURE=1 \
                    bcc-docker \
                    /bin/bash -c \
                    '/bcc/build/tests/wrapper.sh \
                        c_test_all sudo /bcc/build/tests/cc/test_libbcc'"

    - name: Run all tests
      env: ${{ matrix.env }}
      run: |
        script -e -c /bin/bash -c \
        "docker run -ti \
                    --privileged \
                    --network=host \
                    --pid=host \
                    -v $(pwd):/bcc \
                    -v /sys/kernel/debug:/sys/kernel/debug:rw \
                    -v /lib/modules:/lib/modules:ro \
                    -v /usr/src:/usr/src:ro \
                    -e CTEST_OUTPUT_ON_FAILURE=1 \
                    bcc-docker \
                    /bin/bash -c \
                    'cd /bcc/build && \
                     make test PYTHON_TEST_LOGFILE=$PYTHON_TEST_LOGFILE ARGS=-V'"

    - name: Check critical tests
      env: ${{ matrix.env }}
      run: |
        critical_count=$(grep @mayFail tests/python/critical.log | wc -l)
        echo "There were $critical_count critical tests skipped with @mayFail:"
        grep -A2 @mayFail tests/python/critical.log


# To debug weird issues, you can add this step to be able to SSH to the test environment
#     https://github.com/marketplace/actions/debugging-with-tmate
#    - name: Setup tmate session
#      uses: mxschmitt/action-tmate@v1
