Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] ci(jenkins): use APM e2e in the CI (#61803) #67359

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
"