name: Run test suite

on: [push, pull_request]

concurrency:
  # cancel older, in-progress jobs from the same PR, same workflow.
  # use run_id if the job is triggered by a push to ensure
  # push-triggered jobs to not get canceled.
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:

  lint:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1

    - name: Set up Python 3.11
      uses: actions/setup-python@v4
      with:
        python-version: "3.11"
        cache: "pip"

    - name: Install Dependencies
      run: pip install .[lint]

    - name: Run Black
      run: black --check -C --force-exclude=vyper/version.py ./vyper ./tests ./setup.py

    - name: Run flake8
      run: flake8 ./vyper ./tests ./setup.py
      if: always()

    - name: Run isort
      run: isort --check-only --diff ./vyper ./tests ./setup.py
      if: always()

  docs:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v1

      - name: Set up Python 3.11
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"
          cache: "pip"

      - name: Install Tox
        run: pip install tox

      - name: Run Tox
        run: TOXENV=docs tox -r

  mypy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1

    - name: Set up Python 3.11
      uses: actions/setup-python@v4
      with:
        python-version: "3.11"
        cache: "pip"

    - name: Install Tox
      run: pip install tox

    - name: Run Tox
      run: TOXENV=mypy tox -r

  # "Regular"/core tests.
  tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [["3.10", "310"], ["3.11", "311"]]
        # run in modes: --optimize [gas, none, codesize]
        flag: ["core", "no-opt", "codesize"]

    name: py${{ matrix.python-version[1] }}-${{ matrix.flag }}

    steps:
    - uses: actions/checkout@v1

    - name: Set up Python ${{ matrix.python-version[0] }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version[0] }}
        cache: "pip"

    - name: Install Tox
      run: pip install tox

    - name: Run Tox
      run: TOXENV=py${{ matrix.python-version[1] }}-${{ matrix.flag }} tox -r -- --reruns 10 --reruns-delay 1 -r aR tests/

    - name: Upload Coverage
      uses: codecov/codecov-action@v1
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
        file: ./coverage.xml


  core-tests-success:
    if: always()
    # summary result from test matrix.
    # see https://github.community/t/status-check-for-a-matrix-jobs/127354/7
    runs-on: ubuntu-latest
    needs: tests
    steps:
      - name: Check tests tests all succeeded
        if: ${{ needs.tests.result != 'success' }}
        run: exit 1


  # fuzzing + slow/exhaustive tests (things that are too slow to run in
  # the regular test suite)
  fuzzing:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]

    steps:
    - uses: actions/checkout@v1

    - name: Set up Python 3.11
      uses: actions/setup-python@v4
      with:
        python-version: "3.11"
        cache: "pip"

    - name: Install Tox
      run: pip install tox

    # fetch test durations
    # NOTE: if the tests get poorly distributed, run this and commit the resulting `.test_durations` file to the `vyper-test-durations` repo.
    # `TOXENV=fuzzing tox -r -- --store-durations --reruns 10 --reruns-delay 1 -r aR tests/`
    - name: Fetch test-durations
      run: curl --location "https://raw.githubusercontent.com/vyperlang/vyper-test-durations/5982755ee8459f771f2e8622427c36494646e1dd/test_durations" -o .test_durations

    - name: Run Tox
      run: TOXENV=fuzzing tox -r -- --splits 60 --group ${{ matrix.group }} --splitting-algorithm least_duration --reruns 10 --reruns-delay 1 -r aR tests/

    - name: Upload Coverage
      uses: codecov/codecov-action@v1
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
        file: ./coverage.xml

  slow-tests-success:
    if: always()
    # summary result from test matrix.
    # see https://github.community/t/status-check-for-a-matrix-jobs/127354/7
    runs-on: ubuntu-latest
    needs: fuzzing

    steps:
      - name: Check slow tests all succeeded
        if: ${{ needs.fuzzing.result != 'success' }}
        run: exit 1

  memory:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1

    - name: Set up Python 3.11
      uses: actions/setup-python@v4
      with:
        python-version: "3.11"
        cache: "pip"

    - name: Install Tox
      run: pip install tox

    - name: Run Tox
      run: TOXENV=memory tox -r

    - name: Upload Coverage
      uses: codecov/codecov-action@v1
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
        file: ./coverage.xml
