# Runs fuzzing nightly.
name: fuzz-nightly
on:
  workflow_dispatch: # allow running workflow manually
  schedule:
    - cron: '0 3 * * *'
  pull_request:
    branches: [master]
    paths:
      - "test/fuzz/**/*.go"

jobs:
  fuzz-nightly-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-go@v2
        with:
          go-version: '1.16'

      - uses: actions/checkout@v2.3.4

      - name: Install go-fuzz
        working-directory: test/fuzz
        run: go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-build

      - name: Fuzz mempool
        working-directory: test/fuzz
        run: timeout -s SIGINT --preserve-status 10m make fuzz-mempool
        continue-on-error: true

      - name: Fuzz p2p-addrbook
        working-directory: test/fuzz
        run: timeout -s SIGINT --preserve-status 10m make fuzz-p2p-addrbook
        continue-on-error: true

      - name: Fuzz p2p-pex
        working-directory: test/fuzz
        run: timeout -s SIGINT --preserve-status 10m make fuzz-p2p-pex
        continue-on-error: true

      - name: Fuzz p2p-sc
        working-directory: test/fuzz
        run: timeout -s SIGINT --preserve-status 10m make fuzz-p2p-sc
        continue-on-error: true

      - name: Fuzz p2p-rpc-server
        working-directory: test/fuzz
        run: timeout -s SIGINT --preserve-status 10m make fuzz-rpc-server
        continue-on-error: true

      - name: Archive crashers
        uses: actions/upload-artifact@v2
        with:
          name: crashers
          path: test/fuzz/**/crashers
          retention-days: 3

      - name: Archive suppressions
        uses: actions/upload-artifact@v2
        with:
          name: suppressions
          path: test/fuzz/**/suppressions
          retention-days: 3

      - name: Set crashers count
        working-directory: test/fuzz
        run: echo "::set-output name=count::$(find . -type d -name 'crashers' | xargs -I % sh -c 'ls % | wc -l' | awk '{total += $1} END {print total}')"
        id: set-crashers-count

    outputs:
      crashers-count: ${{ steps.set-crashers-count.outputs.count }}

  fuzz-nightly-fail:
    needs: fuzz-nightly-test
    if: ${{ needs.fuzz-nightly-test.outputs.crashers-count != 0 }}
    runs-on: ubuntu-latest
    steps:
      - name: Notify Slack if any crashers
        uses: rtCamp/action-slack-notify@f565a63638bd3615e76249bffab00fcb9dab90f7
        env:
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
          SLACK_CHANNEL: tendermint-internal
          SLACK_USERNAME: Nightly Fuzz Tests
          SLACK_ICON_EMOJI: ':firecracker:'
          SLACK_COLOR: danger
          SLACK_MESSAGE: Crashers found in Nightly Fuzz tests
          SLACK_FOOTER: ''
