name: Run tests

on:
  workflow_dispatch:
  pull_request:
  push:
    branches:
      - master

jobs:
  Test-in-Qemu:
    #if: ${{ false }} # disable for now
    runs-on: ubuntu-latest
    name: Test in Qemu (${{ matrix.distro }})
    strategy:
      fail-fast: false
      matrix:
        include:
          - distro: Ubuntu-24.04
            image: https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
            untar: false
            format: qcow2

          - distro: Ubuntu-22.04
            image: https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
            untar: false
            format: qcow2

          - distro: Ubuntu-20.04
            image: https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
            untar: false
            format: qcow2

          - distro: Debian13
            image: https://cloud.debian.org/images/cloud/trixie/daily/latest/debian-13-generic-amd64-daily.tar.xz
            untar: true
            format: raw

          - distro: Debian12
            image: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.tar.xz
            untar: true
            format: raw

          - distro: Debian11
            image: https://cdimage.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.tar.xz
            untar: true
            format: raw

          - distro: Debian10
            image: https://cloud.debian.org/images/cloud/buster/latest/debian-10-generic-amd64.tar.xz
            untar: true
            format: raw

    steps:
      - name: Check out repository code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
          path: "accel-ppp"
      - name: Install qemu and required tools
        run: >
          sudo apt update && 
          sudo apt -y install qemu-system-x86 qemu-utils cloud-image-utils cpu-checker cloud-image-utils wget openssh-client screen
      - name: Check kvm support (fail is ok)
        run: sudo kvm-ok || exit 0
      - name: Prepare cloud-init image disk
        run: |
          ssh-keygen -t ed25519 -q -N "" -f ssh-key
          echo "instance-id: $(uuidgen || echo i-abcdefg)" > init-meta
          echo "#cloud-config" > init-data
          echo "package_update: true" >> init-data
          echo "package_upgrade: true" >> init-data
          echo "package_reboot_if_required: false" >> init-data
          echo "users:" >> init-data
          echo "  - default" >> init-data
          echo "  - name: user" >> init-data
          echo "    shell: /bin/bash" >> init-data
          echo "    sudo: ALL=(ALL) NOPASSWD:ALL" >> init-data
          echo "    ssh_authorized_keys:" >> init-data
          echo "      - "`cat ssh-key.pub` >> init-data
          echo "power_state:">> init-data
          echo "    mode: poweroff">> init-data
          cat init-data
          cloud-localds init.img init-data init-meta
      - name: Download, unpack and resize target OS cloud image
        if: ${{ matrix.untar }}
        run: |
          wget -nv ${{ matrix.image }}
          mkdir img
          tar -xf *.tar.xz -C img
          qemu-img resize -f ${{ matrix.format }} img/`ls -1 img` +2G
      - name: Download and resize target OS cloud image
        if: ${{ !matrix.untar }}
        run: |
          mkdir img
          wget -nv ${{ matrix.image }} -O img/image
          qemu-img resize -f ${{ matrix.format }} img/`ls -1 img` +2G
      - name: Run target OS first time (for cloud-init actions)
        run: sudo qemu-system-x86_64 -m 4096 -nographic -drive format=${{ matrix.format }},file=img/`ls -1 img` -drive format=raw,file=init.img
      - name: Run target OS
        run: sudo screen -dmS qemu qemu-system-x86_64 -net nic -net user,hostfwd=tcp::2222-:22 -m 4096 -nographic -drive format=${{ matrix.format }},file=img/`ls -1 img`
      - name: Check that target OS is running
        run: |
          sleep 1
          sudo screen -ls
      - name: Wait for ssh connection
        timeout-minutes: 30
        run: >
          while ! ssh -o StrictHostKeyChecking=accept-new -p2222 -o ConnectTimeout=5 -i ssh-key user@localhost "exit 0";
          do
          echo "Trying to establish ssh connection";
          sleep 5;
          done;
          cat ~/.ssh/known_hosts
      - name: Display free space, current dir, kernel version and test sudo
        run: |
          ssh -i ssh-key -p2222 user@localhost "df -h"
          ssh -i ssh-key -p2222 user@localhost "pwd"
          ssh -i ssh-key -p2222 user@localhost "uname -a"
          ssh -i ssh-key -p2222 user@localhost "sudo cat /etc/passwd"
      - name: Install build tools (on target OS)
        run: >
          ssh -i ssh-key -p2222 user@localhost "sudo apt -y install
          git build-essential cmake gcc linux-headers-\`uname -r\` 
          libpcre3-dev libssl-dev liblua5.1-0-dev kmod python3-pip 
          libxml2-dev libxslt1-dev zlib1g-dev 
          iproute2 ppp pppoe isc-dhcp-client timelimit && 
          (sudo pip3 install pytest pytest-dependency gcovr || sudo pip3 install --break-system-packages pytest pytest-dependency gcovr)"
      - name: Copy source code to target OS
        run: |
          tar -Jcf accel-ppp.tar.xz accel-ppp
          scp -i ssh-key -P2222 accel-ppp.tar.xz user@localhost:
          ssh -i ssh-key -p2222 user@localhost "tar -xf accel-ppp.tar.xz"
      - name: Build accel-ppp
        run: >
          ssh -i ssh-key -p2222 user@localhost "cd accel-ppp &&
          mkdir build && cd build &&
          cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr 
          -DKDIR=/usr/src/linux-headers-\`uname -r\` 
          -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE .. &&
          make && sudo make install"

      - name: Run tests (not related to ipoe and vlan_mon drivers)
        timeout-minutes: 5
        run: >
          ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && 
          sudo python3 -m pytest -Wall -v -m \"not ipoe_driver and not vlan_mon_driver\""
      - name: Display processes and dmesg after tests
        if: ${{ always() }}
        run: >
          ssh -i ssh-key -p2222 user@localhost "ps aux | grep accel- && 
          sudo dmesg"

      - name: Insert ipoe kernel module
        run: >
          ssh -i ssh-key -p2222 user@localhost "cd accel-ppp &&
          sudo insmod build/drivers/ipoe/driver/ipoe.ko &&
          lsmod | grep ipoe "

      - name: Run tests (not related to vlan_mon drivers)
        timeout-minutes: 5
        if: ${{ always() }}
        run: >
          ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && 
          sudo python3 -m pytest -Wall -v -m \"not vlan_mon_driver\""
      - name: Display processes and dmesg after tests
        if: ${{ always() }}
        run: >
          ssh -i ssh-key -p2222 user@localhost "ps aux | grep accel- && 
          sudo dmesg"

      - name: Insert vlan_mon kernel module
        run: >
          ssh -i ssh-key -p2222 user@localhost "cd accel-ppp &&
          sudo insmod build/drivers/vlan_mon/driver/vlan_mon.ko &&
          lsmod | grep vlan_mon"

      - name: Run tests (all)
        timeout-minutes: 5
        # vlan-mon tests fail on Debian10 due to Debian10 bug so don't run all tests on deb10
        if: ${{ matrix.distro != 'Debian10' }}
        run: >
          ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && 
          sudo python3 -m pytest -Wall -v"
      - name: Display processes and dmesg after tests
        if: ${{ always() }}
        run: >
          ssh -i ssh-key -p2222 user@localhost "ps aux | grep accel- && 
          sudo dmesg"

  Test-in-GH:
    #if: ${{ false }} # disable for now
    strategy:
      fail-fast: false
      matrix:
        distro: ["ubuntu-22.04", "ubuntu-20.04"]

    runs-on: ${{ matrix.distro }}
    steps:
      - name: Install build tools (using apt)
        run: >
          sudo apt update && 
          sudo apt -y install git build-essential cmake gcc linux-headers-`uname -r` 
          libpcre3-dev libssl-dev liblua5.1-0-dev kmod python3-pip 
          iproute2 ppp pppoe isc-dhcp-client

      - name: Install testing tools (using pip)
        run: >
          sudo pip3 install pytest pytest-dependency gcovr

      - name: Check out repository code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: mkdir build
        run: mkdir build

      - name: cmake (with coverage)
        working-directory: ./build
        run: >
          cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr 
          -DKDIR=/usr/src/linux-headers-`uname -r` 
          -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE ..

      - name: make && make install
        working-directory: ./build
        run: make && sudo make install

      - name: Insert and check kernel modules (ipoe and vlan-mon)
        # if: ${{ false }}
        run: |
          sudo insmod build/drivers/vlan_mon/driver/vlan_mon.ko
          sudo insmod build/drivers/ipoe/driver/ipoe.ko
          lsmod | grep ipoe
          lsmod | grep vlan_mon

      - name: Run tests
        timeout-minutes: 5
        working-directory: ./tests
        run: sudo python3 -m pytest -Wall -v

  Test-in-GH-Coverage:
    #if: ${{ false }} # disable for now
    strategy:
      fail-fast: false
      matrix:
        distro: ["ubuntu-22.04", "ubuntu-20.04"]

    runs-on: ${{ matrix.distro }}
    steps:
      - name: Install build tools (using apt)
        run: >
          sudo apt update && 
          sudo apt -y install git build-essential cmake gcc linux-headers-`uname -r` 
          libpcre3-dev libssl-dev liblua5.1-0-dev kmod python3-pip 
          iproute2 ppp pppoe isc-dhcp-client

      - name: Install testing tools (using pip)
        run: >
          sudo pip3 install pytest pytest-dependency gcovr

      - name: Check out repository code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: mkdir build
        run: mkdir build

      - name: cmake (with coverage)
        working-directory: ./build
        run: >
          cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr 
          -DKDIR=/usr/src/linux-headers-`uname -r` 
          -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE 
          -DCMAKE_C_FLAGS="--coverage -O0" ..

      - name: make && make install
        working-directory: ./build
        run: make && sudo make install

      - name: Insert and check kernel modules (ipoe and vlan-mon)
        # if: ${{ false }}
        run: |
          sudo insmod build/drivers/vlan_mon/driver/vlan_mon.ko
          sudo insmod build/drivers/ipoe/driver/ipoe.ko
          lsmod | grep ipoe
          lsmod | grep vlan_mon

      - name: Run tests (for coverage report) (fail is ok)
        timeout-minutes: 5
        working-directory: ./tests
        run: sudo python3 -m pytest -Wall -v || exit 0

      - name: Generate coverage reports (default(txt), csv, html)
        run: |
          mkdir -p tests/report
          gcovr --config=tests/gcovr.conf --output=tests/report/accel-ppp.txt
          gcovr --config=tests/gcovr.conf --csv --output=tests/report/accel-ppp.csv
          gcovr --config=tests/gcovr.conf --html --html-details --output=tests/report/accel-ppp.html

      - name: Show default coverage report
        run: cat tests/report/accel-ppp.txt

      - name: Upload coverage report
        # if: ${{ false }}
        uses: actions/upload-artifact@v3
        with:
          name: coverage-report-on-${{ matrix.distro }}
          path: tests/report/
          if-no-files-found: error