# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   https://apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

name: TR Ultimate Test Harness

env:
  DOCKER_BUILDKIT: '1'
  COMPOSE_DOCKER_CLI_BUILD: '1'

on:
  push:
    paths:
      - .github/actions/tr-ultimate-test-harness/**
      - .github/workflows/tr-ultimate-test-harness.yml
      - dev/traffic_router/**
      - traffic_router/**
  create:
  pull_request:
    paths:
      - .github/actions/tr-ultimate-test-harness/**
      - .github/workflows/tr-ultimate-test-harness.yml
      - dev/traffic_router/**
      - traffic_router/**
    types: [ opened, reopened, ready_for_review, synchronize ]

jobs:
  tests:
    if: github.event.pull_request.draft == false
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@master
      - name: Fetch environment variables
        run: |
          source dev/atc.dev.sh &&
          env | grep -e^TO_ -e^UID= >> .env
      - name: Load environment
        run: |
          set -o pipefail &&
          cat infrastructure/cdn-in-a-box/variables.env .env |
            sed /^#/d |
            tee --append "${{ github.env }}"
      - name: Install Go
        uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_VERSION }}
      - name: Vendor dependencies
        run: go mod vendor
      - name: Build docker-compose services
        run: |
          docker-compose build --parallel &&
          docker-compose pull db
      - name: Cache local Maven repository
        uses: actions/cache@v2
        with:
          path: ${{ github.workspace }}/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-maven-
      - name: Cache node modules
        uses: actions/cache@v2
        with:
          path: ${{ github.workspace }}/.npm
          key: ${{ runner.os }}-node-modules-${{ hashFiles('traffic_portal/**/package*.json') }}-
          restore-keys: |
            ${{ runner.os }}-node-modules-
      - name: Start the Dev CDN in a Box
        run: docker-compose up -d
      - name: Wait until Traffic Ops is ready to accept requests
        run: |
          trap 'echo "Error on line ${LINENO} of setting interface IP addresses"; exit 1' ERR
          set -o errexit -o nounset -o pipefail

          # Get atc-ready function
          source dev/atc.dev.sh
          export -f atc-ready

          echo 'Waiting until Traffic Ops is ready to accept requests...'
          if ! timeout 10m bash -c 'atc-ready -w'; then
            echo 'Traffic Ops was not available within 10 minutes!'
            trap - ERR
            echo 'Exiting...'
            exit 1
          fi

      - name: Set interface IP addresses
        run: |2
          trap 'echo "Error on line ${LINENO} of setting interface IP addresses"; exit 1' ERR
          # set -o xtrace
          # uncomment this line ^ to check interface data
          set -o errexit -o nounset -o pipefail

          source infrastructure/cdn-in-a-box/traffic_ops/to-access.sh

          declare -A service_by_hostname
          service_by_hostname[trafficrouter]=trafficrouter
          service_by_hostname[edge]=t3c

          for hostname in trafficrouter edge; do
            container_id="$(docker-compose ps -q "${service_by_hostname[$hostname]}")"
            interface="$(<<'JSON' jq
            {
              "mtu": 1500,
              "monitor": true,
              "ipAddresses": [],
              "name": "eth0"
            }
          JSON
            )"
            docker_network="$(docker network inspect dev.ciab.test)"
            for ip_address_field in IPv4Address IPv6Address; do
              ip_address="$(<<<"$docker_network" jq -r --arg CONTAINER_ID "$container_id" --arg IP_ADDRESS_FIELD "$ip_address_field" '.[0].Containers[$CONTAINER_ID][$IP_ADDRESS_FIELD]')"
              if [[ "$ip_address" == null ]]; then
                echo "Could not find ${ip_address_field} for ${hostname} service!"
                exit 1
              fi
              interface="$(<<<"$interface" jq --arg IP_ADDRESS "$ip_address" '.ipAddresses += [{} | .address = $IP_ADDRESS | .serviceAddress = true]')"
            done

            # Get server JSON
            server="$(to-get "api/$TO_API_VERSION/servers?hostName=${hostname}" | jq '.response[0]')"
            if [[ -z "$server" ]]; then
              echo "Could not get JSON for server ${hostname}"
              exit 1
            fi

            # Update server's interface with its IP addresses
            server="$(<<<"$server" jq ".interfaces = [${interface}]")"
            server_id="$(<<<"$server" jq .id)"
            if ! to-put "api/$TO_API_VERSION/servers/${server_id}" "$server"; then
              echo "Could not update server ${hostname} with ${server}"
              exit 1
            fi
          done

          # Snapshot
          cdn_id="$(<<<"$server" jq .cdnId)"
          to-put "api/$TO_API_VERSION/snapshot?cdnID=${cdn_id}"

      - name: Wait for Traffic Monitor to serve a snapshot
        run: |
          echo "Waiting for Traffic Monitor to serve a snapshot..."
          if ! timeout 10m curl \
            --retry 99999 \
            --retry-delay 5 \
            --show-error \
            -fIso/dev/null \
            http://localhost/publish/CrConfig
          then
            echo "CrConfig was not available from Traffic Monitor within 10 minutes!"
            trap - ERR
            echo 'Exiting...'
            exit 1
          fi

      - name: Compile the tests
        run: go test -c ./traffic_router/ultimate-test-harness

      - name: Wait for Delivery Service to become available
        id: wait-for-ds
        run: |
          trap 'echo "Error on line ${LINENO} of waiting for the Delivery Service to become available"; exit 1' ERR
          set -o errexit -o nounset -o pipefail

          # Get atc-ready function
          source dev/atc.dev.sh
          export -f atc-ready

          deliveryservice=cdn.dev-ds.ciab.test
          echo "Waiting for Delivery Service ${deliveryservice} to become available..."
          if ! timeout 10m bash -c 'atc-ready -d'; then
              echo "Delivery Service ${deliveryservice} was not available within 10 minutes!"
              trap - ERR
              echo 'Exiting...'
              exit 1
          fi

      - name: Run Traffic Router Ultimate Test Harness HTTP tests
        run: ./ultimate-test-harness.test -test.v -test.run=^TestHTTPLoad$ -http_requests_threshold=1200

      - name: Run Traffic Router Ultimate Test Harness DNS tests
        run: ./ultimate-test-harness.test -test.v -test.run=^TestDNSLoad$ -dns_requests_threshold=2500
        if: ${{ steps.wait-for-ds.outcome == 'success' && always() }}

      - name: Write Dev CDN-in-a-Box logs to files
        run: |
          set -o errexit -o nounset
          mkdir -p dev/logs
          for service in $(docker-compose ps --services); do
            docker-compose logs --no-color --timestamps "$service" >"dev/logs/${service}.log"
          done
        if: ${{ failure() }}
      - name: Upload Dev CDN-in-a-Box logs
        uses: actions/upload-artifact@v2
        with:
          name: dev-ciab-logs
          path: dev/logs/*.log
        if: ${{ failure() }}
