Commit 4a38e3ec authored by Olivier Cédric's avatar Olivier Cédric Committed by Pierre Smeyers
Browse files

feat: initialisation of k6 template

parent a74e8054
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
include:
  - project: 'Orange-OpenSource/tbc/tools/gitlab-ci'
    ref: 'master'
    file: '/templates/validation.yml'
  - project: 'Orange-OpenSource/tbc/kicker'
    ref: 'master'
    file: '/templates/validation.yml'
  - project: 'Orange-OpenSource/tbc/bash'
    ref: '1.0.0'
    file: 'templates/gitlab-ci-bash.yml'
  - project: "to-be-continuous/tools/gitlab-ci"
    ref: "master"
    file: "/templates/validation.yml"
  - project: "to-be-continuous/kicker"
    ref: "master"
    file: "/templates/validation.yml"
  - project: "to-be-continuous/bash"
    ref: "1.0.0"
    file: "templates/gitlab-ci-bash.yml"

stages:
  - build
  - publish

variables:
  GITLAB_CI_FILES: "templates/gitlab-ci-xxx.yml"
  GITLAB_CI_FILES: "templates/gitlab-ci-k6.yml"
  BASH_SHELLCHECK_FILES: "*.sh"

# extract the Bash script from template (for ShellCheck job)
+40 −21
Original line number Diff line number Diff line
# GitLab CI template for XXX
# GitLab CI template for k6 loading test

This project implements a generic GitLab CI template for running [XXX](https://link.to.tool.com/)  automated tests.
This project implements a generic GitLab CI template for loading test using [k6 loading test](https://k6.io/).

It provides several features, usable in different modes (by configuration).

@@ -10,43 +10,62 @@ In order to include this template in your project, add the following to your `gi

```yaml
include:
  - project: 'Orange-OpenSource/tbc/xxx'
  - project: 'to-be-continuous/k6'
    ref: '1.0.0'
    file: '/templates/gitlab-ci-xxx.yml'
    file: '/templates/gitlab-ci-k6.yml'

# Pipeline steps
stages:
  - acceptance # required by Cypress template
  # TODO: add all other required stages

```

:warning: depending on your needs and environment, you might have to use [one of the template variants](#variants).

## `xxx` job
## `k6` job

This job starts [XXX](https://link.to.tool.com/) tests.
This job starts [k6](https://k6.io/) tests.

It uses the following variable:
It uses the following variables:

| Name                | description                                                                                               | default value          |
| --------------------- | ----------------------------------------- | ----------------- |
| `XXX_IMAGE`           | The Docker image used to run XXX          | `xxx:latest`      |
| `XXX_ROOT_DIR`        | The root XXX project directory            | `.`               |
| `XXX_EXTRA_ARGS`      | XXX extra [options](link-to-ref-doc-here) | _none_            |
| `REVIEW_ENABLED`      | Set to enable XXX tests on review environments (dynamic environments instantiated on development branches) | _none_ (disabled) |
| ------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------- |
| `K6_IMAGE`          | The Docker image used to run k6                                                                           | `loadimpact/k6:latest` |
| `K6_TESTS_DIR`     | The k6 tests directory                                                                             | `k6`                    |
| `K6_EXTRA_ARGS`     | k6 extra  [command-line](https://k6.io/docs/getting-started/running-k6)                                   | _none_                 |
| `REVIEW_ENABLED` | Set to enable k6 tests on review environments (dynamic environments instantiated on development branches) | _none_ (disabled)      |

### Unit tests report integration
### Load performance report integration

XXX test reports are [integrated to GitLab by generating JUnit reports](https://docs.gitlab.com/ee/ci/junit_test_reports.html).
k6 test reports are [integrated to GitLab by generating load performance reports](https://docs.gitlab.com/ee/user/project/merge_requests/load_performance_testing.html).

This is done using the following CLI options: `--junit --output=reports/`  
This is done using the following CLI options: `--out json=reports/`  

### Base URL auto evaluation

By default, the XXX template tries to auto-evaluate the base URL (i.e. the variable pointing at server under test) by
By default, the k6 template tries to auto-evaluate the base URL (i.e. the variable pointing at server under test) by
looking either for a `$environment_url` variable or for an `environment_url.txt` file.

Therefore if an upstream job in the pipeline deployed your code to a server and propagated the deployed server url,
either through a [dotenv](https://docs.gitlab.com/ee/ci/pipelines/job_artifacts.html#artifactsreportsdotenv) variable `$environment_url`
or through a basic `environment_url.txt` file, then the XXX test will automatically be run on this server.
or through a basic `environment_url.txt` file, then the k6 test will automatically be run on this server.

:warning: all our deployment templates implement this design. Therefore even purely dynamic environments (such as review
environments) will automatically be propagated to your XXX tests.
environments) will automatically be propagated to your k6 tests.

In order to use the auto-evaluated base URL, you shall use the `base_url` environment variable from your k6 scripts.

If you're not using a smart deployment job, you may still explicitly declare the `XXX_BASE_URL` variable (but that
will be unfortunately hardcoded to a single server).
Example:

```javascript
import http from 'k6/http';
import {check, sleep} from 'k6';

export default function() {
  const data = {username: 'username', password: 'password'};
  let res = http.post(__ENV.base_url, data);
    check(res, { 'success login': (r) => r.status === 200 });
    sleep(0.3);
}
```
+13 −13
Original line number Diff line number Diff line
{
  "name": "XXX",
  "description": "GitLab CI template for running [XXX](https://link.to.tool.com/)  automated tests.",
  "template_path": "templates/gitlab-ci-xxx.yml",
  "name": "k6",
  "description": "GitLab CI template for running [k6](https://k6.io/)  automated tests.",
  "template_path": "templates/gitlab-ci-k6.yml",
  "kind": "acceptance",
  "variables": [
    {
      "name": "XXX_IMAGE",
      "description": "The Docker image used to run XXX CLI.",
      "default": "xxx:latest"
      "name": "K6_IMAGE",
      "description": "The Docker image used to run k6 CLI.",
      "default": "loadimpact/k6:latest"
    },
    {
      "name": "XXX_ROOT_DIR",
      "description": "The root XXX project directory",
      "default": "."
      "name": "K6_TESTS_DIR",
      "description": "The k6 tests directory",
      "default": "k6"
    },
    {
      "name": "XXX_EXTRA_ARGS",
      "description": "XXX extra [options](link-to-ref-doc-here)",
      "name": "K6_EXTRA_ARGS",
      "description": "k6 extra [command-line](https://k6.io/docs/getting-started/running-k6)",
      "advanced": true
    },
    {
      "name": "REVIEW_ENABLED",
      "description": "Set to enable XXX tests on review environments (dynamic environments instantiated on development branches)",
      "description": "Set to enable k6 tests on review environments (dynamic environments instantiated on development branches)",
      "type": "boolean"
    }
  ]
−8.84 KiB (2.13 KiB)
Loading image diff...
+33 −73
Original line number Diff line number Diff line
# =========================================================================================
# Copyright (C) 2021 Orange
# Copyright (C) 2021 Orange & contributors
#
# This program is free software; you can redistribute it and/or modify it under the terms 
# of the GNU Lesser General Public License as published by the Free Software Foundation; 
@@ -15,21 +15,21 @@
# =========================================================================================
variables:
  # Default Docker image (can be overriden)
  XXX_IMAGE: "xxx:latest"
  K6_IMAGE: "loadimpact/k6:latest"

  # Directory where XXX tests are implemented
  XXX_ROOT_DIR: "."
  # Directory where K6 tests are implemented
  K6_TESTS_DIR: "k6"

  # default production ref name (pattern)
  PROD_REF: '/^master$/'
  # default integration ref name (pattern)
  INTEG_REF: '/^develop$/'

# allowed stages depend on your template type (see: orange-opensource.gitlab.io/tbc/doc/dev-guidelines/#stages)
# allowed stages depend on your template type (see: https://to-be-continuous.gitlab.io/doc/understand/#generic-pipeline-stages)
stages:
  - acceptance

.xxx-scripts: &xxx-scripts |
.k6-scripts: &k6-scripts |
  # BEGSCRIPT
  set -e

@@ -58,42 +58,6 @@ stages:
    fi
  }

  function install_ca_certs() {
    certs=$1
    if [[ -z "$certs" ]]
    then
      return
    fi

    # List of typical bundles
    bundles="/etc/ssl/certs/ca-certificates.crt"                            # Debian/Ubuntu/Gentoo etc.
    bundles="${bundles} /etc/ssl/cert.pem"                                  # Alpine Linux
    bundles="${bundles} /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"  # CentOS/RHEL 7
    bundles="${bundles} /etc/pki/tls/certs/ca-bundle.crt"                   # Fedora/RHEL 6
    bundles="${bundles} /etc/ssl/ca-bundle.pem"                             # OpenSUSE
    bundles="${bundles} /etc/pki/tls/cacert.pem"                            # OpenELEC

    # Try to find the right bundle to update it with custom CA certificates
    for bundle in ${bundles}
    do
      # import if bundle exists
      if [[ -f "${bundle}" ]]
      then
        # Import certificates in bundle
        echo "${certs}" | tr -d '\r' >> "${bundle}"

        log_info "Custom CA certificates imported in \\e[33;1m${bundle}\\e[0m"
        ca_imported=1
        break
      fi
    done

    if [[ -z "$ca_imported" ]]
    then
      log_warn "Could not import custom CA certificates !"
    fi
  }

  function unscope_variables() {
    _scoped_vars=$(env | awk -F '=' "/^scoped__[a-zA-Z0-9_]+=/ {print \$1}" | sort)
    if [[ -z "$_scoped_vars" ]]; then return; fi
@@ -252,21 +216,21 @@ stages:
    # shellcheck disable=SC2154
    if [[ -n "$environment_url" ]]
    then
      XXX_BASE_URL="$environment_url"
      export XXX_BASE_URL
      log_info "Upstream \$environment_url variable set: use base url \\e[33;1m$XXX_BASE_URL\\e[0m"
      base_url="$environment_url"
      export base_url
      log_info "Upstream \$environment_url variable set: use base url \\e[33;1m$base_url\\e[0m"
    elif [[ -f environment_url.txt ]]
    then
      XXX_BASE_URL=$(cat environment_url.txt)
      export XXX_BASE_URL
      log_info "Upstream environment_url.txt file found: use base url \\e[33;1m$XXX_BASE_URL\\e[0m"
      base_url=$(cat environment_url.txt)
      export base_url
      log_info "Upstream environment_url.txt file found: use base url \\e[33;1m$base_url\\e[0m"
    else
      log_info "No upstream environment url found: leave default"
    fi
  }

  function get_latest_template_version() {
    tag_json=$(wget -T 5 -q -O - "$CI_API_V4_URL/projects/Orange-OpenSource%2Ftbc%2F$1/repository/tags?per_page=1" 2> /dev/null || curl -s --connect-timeout 5 "$CI_API_V4_URL/projects/Orange-OpenSource%2Ftbc%2F$1/repository/tags?per_page=1" 2> /dev/null || echo "")
    tag_json=$(wget -T 5 -q -O - "$CI_API_V4_URL/projects/to-be-continuous%2F$1/repository/tags?per_page=1" 2> /dev/null || curl -s --connect-timeout 5 "$CI_API_V4_URL/projects/to-be-continuous%2F$1/repository/tags?per_page=1" 2> /dev/null || echo "")
    echo "$tag_json" | sed -rn 's/^.*"name":"([^"]*)".*$/\1/p'
  }

@@ -283,7 +247,7 @@ stages:
    fi
  }

  if [[ -z "$TEMPLATE_CHECK_UPDATE_DISABLED" ]]; then check_for_update xxx "1.0.0"; fi
  if [[ -z "$TEMPLATE_CHECK_UPDATE_DISABLED" ]]; then check_for_update k6 "1.0.0"; fi
  unscope_variables
  eval_all_secrets

@@ -292,38 +256,34 @@ stages:
# The main job that starts acceptance tests tool
# on master branch: automatically started after staging deployment
# on non-master branch: manually started after review env deployment (requires $REVIEW_ENABLED to be set)
xxx:
  image: $XXX_IMAGE
k6:
  image:
    name: $K6_IMAGE
    entrypoint: [""]
  services:
    - name: "$CI_REGISTRY/orange-opensource/tbc/tools/tracking:master"
      command: ["--service", "xxx", "1.0.0"]
    - name: "$CI_REGISTRY/to-be-continuous/tools/tracking:master"
      command: ["--service", "k6", "1.0.0"]
  stage: acceptance
  # TODO (if necessary): define cache policy here
  cache:
    # cache shall be per branch per template
    key: "${CI_COMMIT_REF_SLUG}-xxx"
    paths:
      - .cache/
  before_script:
    - *xxx-scripts
    - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
    - *k6-scripts
    - eval_env_url
    - cd "$XXX_ROOT_DIR"
    # TODO (if necessary): do setup stuff here
    - mkdir -p reports/k6
  script:
    # TODO: run xxx tests
    # TODO (if possible): $TRACE set enables debug logs on the tool
    - mkdir reports
    - xxx run ${TRACE+--verbose} --env BASE_URL=$XXX_BASE_URL --junit --output=reports/ $XXX_EXTRA_ARGS
    - |
      for tests_file in $K6_TESTS_DIR/test_*.js
      do
        log_info "Running test \\e[33;1m$test\\e[0m..."
        namenoext=$(basename $tests_file | sed 's/\..*//')
        k6 run ${TRACE+--verbose} --out json=reports/k6/$namenoext.json $K6_EXTRA_ARGS $tests_file
      done
  artifacts:
    name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
    when: always
    paths:
      - $XXX_ROOT_DIR/reports/
      - reports/k6
    reports:
      # TODO (if possible): Acceptance tests use JUnit format and GitLab integration (see: https://docs.gitlab.com/ee/ci/yaml/#artifactsreports)
      junit:
        - $XXX_ROOT_DIR/reports/tests-report.xml
      load_performance:
        - reports/k6/*.json
    expire_in: 1 day
  rules:
    # exclude merge requests