parent
2d22ab8881
commit
c16be20e8e
10 changed files with 156 additions and 97 deletions
117
.ci/end2end.groovy
Normal file
117
.ci/end2end.groovy
Normal file
|
@ -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())
|
||||
}
|
|
@ -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_
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
ARG NODE_VERSION
|
||||
FROM node:$NODE_VERSION
|
||||
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -y -qq install xvfb \
|
||||
libgtk-3-0 \
|
||||
libxtst6 \
|
||||
libnotify-dev \
|
||||
libgconf-2-4 \
|
||||
libnss3 \
|
||||
libxss1 \
|
||||
libasound2 \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
## Add host.docker.internal to localhost
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -y -qq install dnsutils \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
|
@ -1,36 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -xe
|
||||
|
||||
## host.docker.internal is not available in native docker installations
|
||||
kibana=$(dig +short host.docker.internal)
|
||||
if [ -z "${kibana}" ] ; then
|
||||
kibana=127.0.0.1
|
||||
fi
|
||||
|
||||
export CYPRESS_BASE_URL=http://${kibana}:5701
|
||||
|
||||
## To avoid issues with the home and caching artifacts
|
||||
export HOME=/tmp
|
||||
npm config set cache ${HOME}
|
||||
|
||||
## To avoid issues with volumes.
|
||||
#rsync -rv --exclude=.git --exclude=docs \
|
||||
# --exclude=.cache --exclude=node_modules \
|
||||
# --exclude=test/ \
|
||||
# --exclude=src/ \
|
||||
# --exclude=packages/ \
|
||||
# --exclude=built_assets --exclude=target \
|
||||
# --exclude=data /app ${HOME}/
|
||||
#cd ${HOME}/app/x-pack/plugins/apm/e2e/cypress
|
||||
|
||||
cd /app/x-pack/plugins/apm/e2e
|
||||
## Install dependencies for cypress
|
||||
CI=true npm install
|
||||
yarn install
|
||||
|
||||
# Wait for the kibana to be up and running
|
||||
npm install wait-on
|
||||
./node_modules/.bin/wait-on ${CYPRESS_BASE_URL}/status && echo 'Kibana is up and running'
|
||||
|
||||
# Run cypress
|
||||
npm run cypress:run
|
|
@ -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
|
||||
yarn kbn clean && 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
|
||||
|
||||
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
x-pack/plugins/apm/e2e/ci/run-e2e.sh
Executable file
11
x-pack/plugins/apm/e2e/ci/run-e2e.sh
Executable file
|
@ -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
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"nodeVersion": "system",
|
||||
"baseUrl": "http://localhost:5701",
|
||||
"video": false,
|
||||
"trashAssetsBeforeRuns": false,
|
||||
"fileServerFolder": "../",
|
||||
"fixturesFolder": "./cypress/fixtures",
|
||||
|
@ -9,6 +8,8 @@
|
|||
"pluginsFile": "./cypress/plugins/index.js",
|
||||
"screenshotsFolder": "./cypress/screenshots",
|
||||
"supportFile": "./cypress/support/index.ts",
|
||||
"video": true,
|
||||
"videoCompression": false,
|
||||
"videosFolder": "./cypress/videos",
|
||||
"useRelativeSnapshots": true,
|
||||
"reporter": "junit",
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
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`);
|
||||
|
@ -14,7 +17,9 @@ Given(`a user browses the APM UI application`, () => {
|
|||
|
||||
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`, () => {
|
||||
|
|
BIN
x-pack/plugins/apm/e2e/cypress/videos/apm.feature.mp4
Normal file
BIN
x-pack/plugins/apm/e2e/cypress/videos/apm.feature.mp4
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# variables
|
||||
KIBANA_PORT=5701
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
#
|
||||
|
@ -129,4 +140,3 @@ ${bold}If you want to run the test interactively, run:${normal}
|
|||
|
||||
yarn cypress open --config pageLoadTimeout=100000,watchForFileChanges=true
|
||||
"
|
||||
|
||||
|
|
Loading…
Reference in a new issue