name: Coverage

on:
  workflow_dispatch:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

jobs:

  coverage:
    name: Coverage (+nightly)
    # The large timeout is to accommodate:
    # - nightly builds (75 minutes, typically 30-50 minutes)
    # - parameter downloads (40 minutes, but only when the cache expires)
    timeout-minutes: 115
    runs-on: ubuntu-latest
    env:
      CARGO_INCREMENTAL: 0
      RUST_BACKTRACE: full

    steps:
      - uses: actions/checkout@v2.4.0
        with:
          persist-credentials: false

      - uses: actions-rs/toolchain@v1.0.7
        with:
          toolchain: nightly
          override: true
          profile: minimal
          components: llvm-tools-preview

      - name: Install cargo-llvm-cov cargo command
        run: cargo install cargo-llvm-cov

      - name: Skip network tests on Ubuntu
        # Ubuntu runners don't have reliable network or DNS during test steps.
        shell: bash
        run: echo "ZEBRA_SKIP_NETWORK_TESTS=1" >> $GITHUB_ENV

      - name: Minimise proptest cases in Coverage tests
        # We set cases to 1, because some tests already run 1 case by default.
        # We set maximum shrink iterations to 0, because we don't expect failures in these tests.
        #
        # Coverage tests are much slower than other tests, particularly in hot loops.
        shell: bash
        run: |
             echo "PROPTEST_CASES=1" >> $GITHUB_ENV
             echo "PROPTEST_MAX_SHRINK_ITERS=0" >> $GITHUB_ENV

      # Modified from:
      # https://github.com/zcash/librustzcash/blob/c48bb4def2e122289843ddb3cb2984c325c03ca0/.github/workflows/ci.yml#L20-L33
      - name: Fetch path to Zcash parameters
        working-directory: ./zebra-consensus
        shell: bash
        # cargo-llvm-cov doesn't have a silent mode, so we have to extract the path from stderr
        run: echo "ZCASH_PARAMS=$(cargo llvm-cov --lcov --no-report run --example get-params-path 2>&1 >/dev/null | tail -1)" >> $GITHUB_ENV
      - name: Cache Zcash parameters
        id: cache-params
        uses: actions/cache@v2
        with:
          path: ${{ env.ZCASH_PARAMS }}
          key: ${{ runner.os }}-sprout-and-sapling-params
      - name: Fetch Zcash parameters
        if: steps.cache-params.outputs.cache-hit != 'true'
        working-directory: ./zebra-consensus
        run: cargo llvm-cov --lcov --no-report run --example download-params

      - name: Show env vars
        run: |
            echo "Test env vars:"
            echo "ZEBRA_SKIP_NETWORK_TESTS=${{ env.ZEBRA_SKIP_NETWORK_TESTS }}"
            echo "ZCASH_PARAMS=${{ env.ZCASH_PARAMS }}"
            echo "PROPTEST_CASES=${{ env.PROPTEST_CASES }}"
            echo "PROPTEST_MAX_SHRINK_ITERS=${{ env.PROPTEST_MAX_SHRINK_ITERS }}"
            echo "Common env vars:"
            echo "RUST_BACKTRACE=${{ env.RUST_BACKTRACE }}"
            echo "Build env vars:"
            echo "CARGO_INCREMENTAL=${{ env.CARGO_INCREMENTAL }}"
            echo "CARGO_TARGET_DIR=${{ env.CARGO_TARGET_DIR }}"

      - name: Run Zebra tests
        run: cargo llvm-cov --lcov --no-report

      - name: Generate coverage report
        run: cargo llvm-cov --lcov --no-run --output-path lcov.info

      - name: Upload coverage report to Codecov
        uses: codecov/codecov-action@v2.1.0
