# Run all tests, with or without flaky tests.

name: Tests

on:
  workflow_call:
    inputs:
      rust-version:
        description: 'The version of the rust compiler to run'
        type: string
        default: 'stable'
      flaky:
        description: 'Whether to also run flaky tests'
        type: boolean
        default: false
      git-ref:
        description: 'Which git ref to checkout'
        type: string
        default: ${{ github.ref }}

env:
  RUST_BACKTRACE: 1
  RUSTFLAGS: -Dwarnings
  RUSTDOCFLAGS: -Dwarnings
  SCCACHE_CACHE_SIZE: "50G"
  CRATES_LIST: "iroh-gossip"
  IROH_FORCE_STAGING_RELAYS: "1"

jobs:
  build_and_test_nix:
    timeout-minutes: 30
    name: "Tests"
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix:
        name: [ubuntu-latest, macOS-arm-latest]
        rust: [ '${{ inputs.rust-version }}' ]
        features: [all, none, default]
        include:
          - name: ubuntu-latest
            os: ubuntu-latest
            release-os: linux
            release-arch: amd64
            runner: [self-hosted, linux, X64]
          - name: macOS-arm-latest
            os: macOS-latest
            release-os: darwin
            release-arch: aarch64
            runner: [self-hosted, macOS, ARM64]
    env:
      # Using self-hosted runners so use local cache for sccache and
      # not SCCACHE_GHA_ENABLED.
      RUSTC_WRAPPER: "sccache"
    steps:
    - name: Checkout
      uses: actions/checkout@v5
      with:
        ref: ${{ inputs.git-ref }}

    - name: Install ${{ matrix.rust }} rust
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: ${{ matrix.rust }}

    - name: Install cargo-nextest
      uses: taiki-e/install-action@v2
      with:
        tool: nextest@0.9.80

    - name: Install sccache
      uses: mozilla-actions/sccache-action@v0.0.9

    - name: Select features
      run: |
        case "${{ matrix.features }}" in
            all)
                echo "FEATURES=--all-features" >> "$GITHUB_ENV"
                ;;
            none)
                echo "FEATURES=--no-default-features" >> "$GITHUB_ENV"
                ;;
            default)
                echo "FEATURES=" >> "$GITHUB_ENV"
                ;;
            *)
                exit 1
        esac

    - name: check features
      if: ${{ ! inputs.flaky }}
      run: |
        for i in ${CRATES_LIST//,/ }
        do
          echo "Checking $i $FEATURES"
          if [ $i = "iroh-cli" ]; then
            targets="--bins"
          else
            targets="--lib --bins"
          fi
          echo cargo check -p $i $FEATURES $targets
          cargo check -p $i $FEATURES $targets
        done
      env:
        RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}

    - name: build tests
      run: |
        cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --no-run

    - name: list ignored tests
      run: |
        cargo nextest list --workspace ${{ env.FEATURES }} --lib --bins --tests --run-ignored ignored-only

    - name: run tests
      run: |
        mkdir -p output
        cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --profile ci --run-ignored ${{ inputs.flaky && 'all' || 'default' }} --no-fail-fast --message-format ${{ inputs.flaky && 'libtest-json' || 'human' }} > output/${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
      env:
        RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}
        NEXTEST_EXPERIMENTAL_LIBTEST_JSON: 1

    - name: upload results
      if: ${{ failure() && inputs.flaky }}
      uses: actions/upload-artifact@v4
      with:
        name: libtest_run_${{ github.run_number }}-${{ github.run_attempt }}-${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
        path: output
        retention-days: 45
        compression-level: 0

    - name: doctests
      if: ${{ (! inputs.flaky) &&  matrix.features == 'all' }}
      run: |
        if [ -n "${{ runner.debug }}" ]; then
            export RUST_LOG=TRACE
        else
            export RUST_LOG=DEBUG
        fi
        cargo test --workspace --all-features --doc

  build_and_test_windows:
    timeout-minutes: 30
    name: "Tests"
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix:
        name: [windows-latest]
        rust: [ '${{ inputs.rust-version}}' ]
        features: [all, none, default]
        target:
          - x86_64-pc-windows-msvc
        include:
          - name: windows-latest
            os: windows
            runner: [self-hosted, windows, x64]
    env:
      # Using self-hosted runners so use local cache for sccache and
      # not SCCACHE_GHA_ENABLED.
      RUSTC_WRAPPER: "sccache"
    steps:
    - name: Checkout
      uses: actions/checkout@v5
      with:
        ref: ${{ inputs.git-ref }}

    - name: Install ${{ matrix.rust }}
      run: |
        rustup toolchain install ${{ matrix.rust }}
        rustup toolchain default ${{ matrix.rust }}
        rustup target add ${{ matrix.target }}
        rustup set default-host ${{ matrix.target }}

    - name: Install cargo-nextest
      shell: powershell
      run: |
        $tmp = New-TemporaryFile | Rename-Item -NewName { $_ -replace 'tmp$', 'zip' } -PassThru
        Invoke-WebRequest -OutFile $tmp https://get.nexte.st/latest/windows
        $outputDir = if ($Env:CARGO_HOME) { Join-Path $Env:CARGO_HOME "bin" } else { "~/.cargo/bin" }
        $tmp | Expand-Archive -DestinationPath $outputDir -Force
        $tmp | Remove-Item

    - name: Select features
      run: |
        switch ("${{ matrix.features }}") {
            "all" {
                echo "FEATURES=--all-features" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
            }
            "none" {
                echo "FEATURES=--no-default-features" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
            }
            "default" {
                echo "FEATURES=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
            }
            default {
                Exit 1
            }
        }

    - name: Install sccache
      uses: mozilla-actions/sccache-action@v0.0.9

    - uses: msys2/setup-msys2@v2

    - name: build tests
      run: |
        cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --target ${{ matrix.target }} --no-run

    - name: list ignored tests
      run: |
        cargo nextest list --workspace ${{ env.FEATURES }} --lib --bins --tests --target ${{ matrix.target }} --run-ignored ignored-only

    - name: tests
      run: |
        mkdir -p output
        cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --profile ci --target ${{ matrix.target }} --run-ignored ${{ inputs.flaky && 'all' || 'default' }} --no-fail-fast --message-format ${{ inputs.flaky && 'libtest-json' || 'human' }} > output/${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
      env:
        RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}
        NEXTEST_EXPERIMENTAL_LIBTEST_JSON: 1
  
    - name: upload results
      if: ${{ failure() && inputs.flaky }}
      uses: actions/upload-artifact@v4
      with:
        name: libtest_run_${{ github.run_number }}-${{ github.run_attempt }}-${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
        path: output
        retention-days: 1
        compression-level: 0
