#
# 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
#
#      http://www.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.
#
{% from 'shared_jinja.yml' import github_access with context %}
---

resources:
- name: once-a-day
  type: time
  source:
    interval: 24h
- name: geode-ci
  type: git
  source:
    depth: 1
    uri: https://github.com/apache/geode.git
    branch: ((geode-build-branch))
    paths:
    - ci/*
    {{ github_access() | indent(4) }}
- name: docker-geode-build-image
  type: docker-image
  source:
    username: ((docker-username))
    password: ((docker-password))
    repository: gcr.io/((gcp-project))/((pipeline-prefix))metric-tools
    tag: latest


{%- macro metrics_job(job_name) %}
- name: Geode{{job_name}}Metrics
  serial: true
  public: true
  plan:
  - aggregate:
    - get: docker-geode-build-image
    - get: geode-ci
    - get: once-a-day
      trigger: true
  - task: get_metrics
    image: docker-geode-build-image
    config:
      inputs:
      - name: geode-ci
      outputs:
      - name: workspace
      platform: linux
      params:
        CONCOURSE_URL: ((concourse-url))
{%- if repository.upstream_fork!="apache" %}
        CONCOURSE_USERNAME: ((concourse-username))
        CONCOURSE_PASSWORD: ((concourse-password))
{%- endif %}
        MAIN_PIPELINE_NAME: ((pipeline-prefix))main
        JOB_NAME: {{job_name}}
        JOB_COUNT: 50
        CONCOURSE_TEAM: ((concourse-team))
        PUBLIC_PIPELINE: ((public-pipelines))
        UPSTREAM_FORK: ((upstream-fork))
      run:
        path: bash
        args:
        - -ecx
        - |-
          apk add jq &> /dev/null
          pip install yq &> /dev/null
          apk add curl &> /dev/null
          curl "${CONCOURSE_URL}/api/v1/cli?arch=amd64&platform=linux" --output fly
          chmod +x fly
          TARGET_NAME=concourse

          set +x
          ./fly -t ${TARGET_NAME} login -c "${CONCOURSE_URL}" -n "${CONCOURSE_TEAM}" -u "${CONCOURSE_USERNAME}" -p "${CONCOURSE_PASSWORD}"
          API_TOKEN=$(yq -r .targets.${TARGET_NAME}.token.value ~/.flyrc)
          PYTHON_ARGUMENTS="--number-of-builds ${JOB_COUNT} --team ${CONCOURSE_TEAM} --cookie-token {API_TOKEN} ${CONCOURSE_URL} ${MAIN_PIPELINE_NAME} ${JOB_NAME}"
          set -x

          python3 geode-ci/ci/bin/concourse_job_performance.py ${PYTHON_ARGUMENTS}

{%- endmacro %}

jobs:
{{- metrics_job('Build') }}
  {%- for test in (tests) if not test.name=="StressNew" -%}
    {%- for java_test_version in (java_test_versions) %}
{{ metrics_job(test.name+'Test'+java_test_version.name) }}
    {%- endfor -%}
  {%- endfor -%}
