name: Regression Tests
description: "Run regression tests"

inputs:
  dfly-executable:
    required: true
    type: string
  gspace-secret:
    required: false
    type: string
  run-only-on-ubuntu-latest:
    # 'true' or 'false' cause boolean
    # is not supported in composite actions
    required: true
    type: string
  build-folder-name:
    required: true
    type: string
  filter:
    required: false
    type: string

runs:
  using: "composite"
  # bring back timeouts once composite actions start supporting them
  # timeout-minutes: 20
  steps:
    - name: Run PyTests
      id: first
      shell: bash
      run: |
        ls -l ${GITHUB_WORKSPACE}/
        cd ${GITHUB_WORKSPACE}/tests
        echo "Current commit is ${{github.sha}}"
        pip3 install -r dragonfly/requirements.txt
        # used by PyTests
        export DRAGONFLY_PATH="${GITHUB_WORKSPACE}/${{inputs.build-folder-name}}/${{inputs.dfly-executable}}"
        export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 # to crash on errors

        timeout 20m pytest -m "${{inputs.filter}}" --color=yes --json-report --json-report-file=report.json dragonfly --ignore=dragonfly/replication_test.py --log-cli-level=INFO || code=$?
        if [[ $code -ne 0 ]]; then
          echo "TIMEDOUT=1">> "$GITHUB_OUTPUT";
          exit 1
        fi

    - name: Run PyTests replication test
      id: second
      if: ${{ inputs.run-only-on-ubuntu-latest == 'true' || (inputs.run-only-on-ubuntu-latest == 'false' && matrix.runner == 'ubuntu-latest') }}
      shell: bash
      run: |
        echo "Running PyTests replication test"
        cd ${GITHUB_WORKSPACE}/tests
        # used by PyTests
        export DRAGONFLY_PATH="${GITHUB_WORKSPACE}/${{inputs.build-folder-name}}/${{inputs.dfly-executable}}"

        run_pytest_with_args() {
          timeout 20m pytest -m "${{inputs.filter}}" --color=yes --json-report \
            --json-report-file=rep1_report.json dragonfly/replication_test.py --log-cli-level=INFO \
            --df alsologtostderr $1 $2 || code=$?
          if [[ $code -ne 0 ]]; then
            echo "TIMEDOUT=1">> "$GITHUB_OUTPUT"
            exit 1
          fi
        }

        (run_pytest_with_args --df enable_multi_shard_sync=true)
        (run_pytest_with_args --df enable_multi_shard_sync=false)

    - name: Print last log on timeout
      if: failure()
      shell: bash
      env:
        TIMEDOUT_STEP_1: ${{ steps.first.outputs.TIMEDOUT }}
        TIMEDOUT_STEP_2: ${{ steps.second.outputs.TIMEDOUT }}
      run: |
        if [[ "${{ env.TIMEDOUT_STEP_1 }}" -eq 1 ]] || [[ "${{ env.TIMEDOUT_STEP_2 }}" -eq 1 ]]; then
          echo "🪵🪵🪵🪵🪵🪵 Latest log before timeout 🪵🪵🪵🪵🪵🪵\n\n"
          ls -t /tmp/dragonfly*log*INFO* | head -n 1 | xargs cat
          echo "🪵🪵🪵🪵🪵🪵 Latest log before timeout end 🪵🪵🪵🪵🪵🪵\n\n"
        fi

    - name: Send notification on failure
      if: failure() && github.ref == 'refs/heads/main'
      shell: bash
      run: |
        get_failed_tests() {
          local report_file=$1
          echo $(jq -r '.tests[] | select(.outcome == "failed") | .nodeid' "$report_file")
        }
        cd ${GITHUB_WORKSPACE}/tests
        failed_tests=""
        # The order in of if is important, and expected to be the oposite order of the pytest run.
        # As github runner will not run the next step if the pytest failed, we start from the last
        # report file and if exist we get the failed test from the pytest run, if there are any.
        if [ -f rep2_report.json ]; then
          failed_tests=$(get_failed_tests rep2_report.json)
        elif [ -f rep1_report.json ]; then
          failed_tests=$(get_failed_tests rep1_report.json)
        elif [ -f report.json ]; then
          failed_tests=$(get_failed_tests report.json)
        fi

        job_link="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
        message="Regression tests failed.\\n The commit is: ${{github.sha}}.\\n $failed_tests \\n Job Link: ${job_link}\\n"

        curl -s \
          -X POST \
          -H 'Content-Type: application/json' \
          '${{ inputs.gspace-secret }}' \
          -d '{"text": "'"${message}"'"}'
