Skip to content

Commit

Permalink
[7.x] ci(jenkins): use APM e2e in the CI (#61803) #67948
Browse files Browse the repository at this point in the history
  • Loading branch information
v1v authored Jun 2, 2020
1 parent 2d22ab8 commit c16be20
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 97 deletions.
117 changes: 117 additions & 0 deletions .ci/end2end.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env groovy

library identifier: 'apm@current',
retriever: modernSCM(
[$class: 'GitSCMSource',
credentialsId: 'f94e9298-83ae-417e-ba91-85c279771570',
id: '37cf2c00-2cc7-482e-8c62-7bbffef475e2',
remote: 'git@github.com:elastic/apm-pipeline-library.git'])

pipeline {
agent { label 'linux && immutable' }
environment {
BASE_DIR = 'src/github.com/elastic/kibana'
HOME = "${env.WORKSPACE}"
E2E_DIR = 'x-pack/plugins/apm/e2e'
PIPELINE_LOG_LEVEL = 'DEBUG'
}
options {
timeout(time: 1, unit: 'HOURS')
buildDiscarder(logRotator(numToKeepStr: '40', artifactNumToKeepStr: '20', daysToKeepStr: '30'))
timestamps()
ansiColor('xterm')
disableResume()
durabilityHint('PERFORMANCE_OPTIMIZED')
}
triggers {
issueCommentTrigger('(?i)(retest|.*jenkins\\W+run\\W+(?:the\\W+)?e2e?.*)')
}
parameters {
booleanParam(name: 'FORCE', defaultValue: false, description: 'Whether to force the run.')
}
stages {
stage('Checkout') {
options { skipDefaultCheckout() }
steps {
deleteDir()
gitCheckout(basedir: "${BASE_DIR}", githubNotifyFirstTimeContributor: false,
shallow: false, reference: "/var/lib/jenkins/.git-references/kibana.git")
script {
dir("${BASE_DIR}"){
def regexps =[ "^x-pack/plugins/apm/.*" ]
env.APM_UPDATED = isGitRegionMatch(patterns: regexps)
}
}
}
}
stage('Prepare Kibana') {
options { skipDefaultCheckout() }
when {
anyOf {
expression { return params.FORCE }
expression { return env.APM_UPDATED != "false" }
}
}
environment {
JENKINS_NODE_COOKIE = 'dontKillMe'
}
steps {
notifyStatus('Preparing kibana', 'PENDING')
dir("${BASE_DIR}"){
sh "${E2E_DIR}/ci/prepare-kibana.sh"
}
}
post {
unsuccessful {
notifyStatus('Kibana warm up failed', 'FAILURE')
}
}
}
stage('Smoke Tests'){
options { skipDefaultCheckout() }
when {
anyOf {
expression { return params.FORCE }
expression { return env.APM_UPDATED != "false" }
}
}
steps{
notifyStatus('Running smoke tests', 'PENDING')
dir("${BASE_DIR}"){
sh "${E2E_DIR}/ci/run-e2e.sh"
}
}
post {
always {
dir("${BASE_DIR}/${E2E_DIR}"){
archiveArtifacts(allowEmptyArchive: false, artifacts: 'cypress/screenshots/**,cypress/videos/**,cypress/test-results/*e2e-tests.xml')
junit(allowEmptyResults: true, testResults: 'cypress/test-results/*e2e-tests.xml')
dir('tmp/apm-integration-testing'){
sh 'docker-compose logs > apm-its-docker.log || true'
sh 'docker-compose down -v || true'
archiveArtifacts(allowEmptyArchive: true, artifacts: 'apm-its-docker.log')
}
archiveArtifacts(allowEmptyArchive: true, artifacts: 'tmp/*.log')
}
}
unsuccessful {
notifyStatus('Test failures', 'FAILURE')
}
success {
notifyStatus('Tests passed', 'SUCCESS')
}
}
}
}
post {
always {
dir("${BASE_DIR}"){
archiveArtifacts(allowEmptyArchive: true, artifacts: "${E2E_DIR}/kibana.log")
}
}
}
}

def notifyStatus(String description, String status) {
withGithubNotify.notify('end2end-for-apm-ui', description, status, getBlueoceanDisplayURL())
}
19 changes: 1 addition & 18 deletions x-pack/plugins/apm/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,4 @@
x-pack/plugins/apm/e2e/run-e2e.sh
```

_Starts Kibana, APM Server, Elasticsearch (with sample data) and runs the tests_

## Reproducing CI builds

> This process is very slow compared to the local development described above. Consider that the CI must install and configure the build tools and create a Docker image for the project to run tests in a consistent manner.
The Jenkins CI uses a shell script to prepare Kibana:

```shell
# Prepare and run Kibana locally
$ x-pack/plugins/apm/e2e/ci/prepare-kibana.sh
# Build Docker image for Kibana
$ docker build --tag cypress --build-arg NODE_VERSION=$(cat .node-version) x-pack/plugins/apm/e2e/ci
# Run Docker image
$ docker run --rm -t --user "$(id -u):$(id -g)" \
-v `pwd`:/app --network="host" \
--name cypress cypress
```
_Starts APM Server, Elasticsearch (with sample data) and runs the tests_
24 changes: 0 additions & 24 deletions x-pack/plugins/apm/e2e/ci/Dockerfile

This file was deleted.

36 changes: 0 additions & 36 deletions x-pack/plugins/apm/e2e/ci/entrypoint.sh

This file was deleted.

20 changes: 6 additions & 14 deletions x-pack/plugins/apm/e2e/ci/prepare-kibana.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
#!/usr/bin/env bash
set -e
set -ex

E2E_DIR="x-pack/plugins/apm/e2e"

echo "1/3 Install dependencies ..."
E2E_DIR=x-pack/plugins/apm/e2e
echo "1/2 Install dependencies ..."
# shellcheck disable=SC1091
source src/dev/ci_setup/setup_env.sh true
yarn kbn bootstrap

echo "2/3 Ingest test data ..."
pushd ${E2E_DIR}
yarn install
curl --silent https://storage.googleapis.com/apm-ui-e2e-static-data/events.json --output ingest-data/events.json
node ingest-data/replay.js --server-url http://localhost:8201 --secret-token abcd --events ./events.json > ingest-data.log
yarn kbn clean && yarn kbn bootstrap

echo "3/3 Start Kibana ..."
popd
echo "2/2 Start Kibana ..."
## Might help to avoid FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
export NODE_OPTIONS="--max-old-space-size=4096"
nohup node scripts/kibana --config "${E2E_DIR}/ci/kibana.e2e.yml" --no-base-path --optimize.watch=false> kibana.log 2>&1 &
nohup node ./scripts/kibana --no-base-path --no-watch --dev --no-dev-config --config ${E2E_DIR}/ci/kibana.e2e.yml > ${E2E_DIR}/kibana.log 2>&1 &
11 changes: 11 additions & 0 deletions x-pack/plugins/apm/e2e/ci/run-e2e.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
##
## This is a wrapper to configure the environment with the right tools in the CI
## and run the e2e steps.
##

E2E_DIR="${0%/*}/.."
# shellcheck disable=SC1091
source src/dev/ci_setup/setup_env.sh true
set -ex
"${E2E_DIR}"/run-e2e.sh
3 changes: 2 additions & 1 deletion x-pack/plugins/apm/e2e/cypress.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"nodeVersion": "system",
"baseUrl": "http://localhost:5701",
"video": false,
"trashAssetsBeforeRuns": false,
"fileServerFolder": "../",
"fixturesFolder": "./cypress/fixtures",
"integrationFolder": "./cypress/integration",
"pluginsFile": "./cypress/plugins/index.js",
"screenshotsFolder": "./cypress/screenshots",
"supportFile": "./cypress/support/index.ts",
"video": true,
"videoCompression": false,
"videosFolder": "./cypress/videos",
"useRelativeSnapshots": true,
"reporter": "junit",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@
import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps';
import { loginAndWaitForPage } from '../../integration/helpers';

/** The default time in ms to wait for a Cypress command to complete */
export const DEFAULT_TIMEOUT = 60 * 1000;

Given(`a user browses the APM UI application`, () => {
// open service overview page
loginAndWaitForPage(`/app/apm#/services`);
});

When(`the user inspects the opbeans-node service`, () => {
// click opbeans-node service
cy.get(':contains(opbeans-node)').last().click({ force: true });
cy.get(':contains(opbeans-node)', { timeout: DEFAULT_TIMEOUT })
.last()
.click({ force: true });
});

Then(`should redirect to correct path with correct params`, () => {
Expand Down
Binary file not shown.
16 changes: 13 additions & 3 deletions x-pack/plugins/apm/e2e/run-e2e.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env bash

# variables
KIBANA_PORT=5701
Expand Down Expand Up @@ -65,6 +65,8 @@ ${APM_IT_DIR}/scripts/compose.py start master \
--elasticsearch-port $ELASTICSEARCH_PORT \
--apm-server-port=$APM_SERVER_PORT \
--elasticsearch-heap 4g \
--apm-server-opt queue.mem.events=8192 \
--apm-server-opt output.elasticsearch.bulk_max_size=4096 \
&> ${TMP_DIR}/apm-it.log

# Stop if apm-integration-testing failed to start correctly
Expand Down Expand Up @@ -98,7 +100,7 @@ curl --silent --user admin:changeme -XDELETE "localhost:${ELASTICSEARCH_PORT}/.a
curl --silent --user admin:changeme -XDELETE "localhost:${ELASTICSEARCH_PORT}/apm*" > /dev/null

# Ingest data into APM Server
node ingest-data/replay.js --server-url http://localhost:$APM_SERVER_PORT --events ${TMP_DIR}/events.json 2> ${TMP_DIR}/ingest-data.log
node ingest-data/replay.js --server-url http://localhost:$APM_SERVER_PORT --events ${TMP_DIR}/events.json 2>> ${TMP_DIR}/ingest-data.log

# Stop if not all events were ingested correctly
if [ $? -ne 0 ]; then
Expand All @@ -113,6 +115,15 @@ echo "\n${bold}Waiting for Kibana to start...${normal}"
echo "Note: you need to start Kibana manually. Find the instructions at the top."
yarn wait-on -i 500 -w 500 http-get://admin:changeme@localhost:$KIBANA_PORT/api/status > /dev/null

## Workaround to wait for the http server running
## See: https://github.com/elastic/kibana/issues/66326
if [ -e kibana.log ] ; then
grep -m 1 "http server running" <(tail -f -n +1 kibana.log)
echo "\n✅ Kibana server running...\n"
grep -m 1 "bundles compiled successfully" <(tail -f -n +1 kibana.log)
echo "\n✅ Kibana bundles have been compiled...\n"
fi

echo "\n✅ Setup completed successfully. Running tests...\n"

#
Expand All @@ -129,4 +140,3 @@ ${bold}If you want to run the test interactively, run:${normal}
yarn cypress open --config pageLoadTimeout=100000,watchForFileChanges=true
"

0 comments on commit c16be20

Please sign in to comment.