ci: refactor uitests to use multiple stages
Please do not run 20 different things in a single stage. It makes debugging much harder than it needs to be, since now you can see at a glance the startup of which container fails easily. Changes: - Starting of Ganache and Nim-Waku containers extracted to separate stages - Cleanup of containers moved to `cleanup` step after tests are executed - Many variables moved to `enrivonment` section for job and some stages - The `throttle` effect narrowed down just to the `Tests` stage and not whole job - RPC API is used to get the Multiaddress of Nim-Waku node instead of hardcoding key - Removed no longer necessary `status-go` history node related files - `Jenkinsfile.uitests` was renamed to `Jenkinsfile.e2e` to match CI job names Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
parent
f3ccc2422c
commit
9f076ed70c
|
@ -0,0 +1,181 @@
|
||||||
|
library 'status-jenkins-lib@v1.6.1'
|
||||||
|
|
||||||
|
/* Options section can't access functions in objects. */
|
||||||
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent { label 'linux' }
|
||||||
|
|
||||||
|
parameters {
|
||||||
|
booleanParam(
|
||||||
|
name: 'RELEASE',
|
||||||
|
description: 'Decides whether binaries are built with debug symbols.',
|
||||||
|
defaultValue: params.RELEASE ?: false
|
||||||
|
)
|
||||||
|
choice(
|
||||||
|
name: 'VERBOSE',
|
||||||
|
description: 'Level of verbosity based on nimbus-build-system setup.',
|
||||||
|
choices: ['0', '1', '2']
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
options {
|
||||||
|
timestamps()
|
||||||
|
/* Prevent Jenkins jobs from running forever */
|
||||||
|
timeout(time: 120, unit: 'MINUTES')
|
||||||
|
/* manage how many builds we keep */
|
||||||
|
buildDiscarder(logRotator(
|
||||||
|
numToKeepStr: '10',
|
||||||
|
daysToKeepStr: '30',
|
||||||
|
artifactNumToKeepStr: '3',
|
||||||
|
))
|
||||||
|
/* Throttle number of concurrent builds. */
|
||||||
|
throttleJobProperty(
|
||||||
|
throttleEnabled: true,
|
||||||
|
throttleOption: 'category',
|
||||||
|
maxConcurrentPerNode: 1,
|
||||||
|
maxConcurrentTotal: 1
|
||||||
|
)
|
||||||
|
/* Abort old PR builds. */
|
||||||
|
disableConcurrentBuilds(
|
||||||
|
abortPrevious: isPRBuild
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
environment {
|
||||||
|
TARGET = 'e2e'
|
||||||
|
/* Improve make performance */
|
||||||
|
MAKEFLAGS = "-j4 V=${params.VERBOSE}"
|
||||||
|
/* Disable colors in Nim compiler logs */
|
||||||
|
NIMFLAGS = '--colors:off'
|
||||||
|
/* Makefile assumes the compiler folder is included */
|
||||||
|
QTDIR = '/opt/qt/5.14.2/gcc_64'
|
||||||
|
/* Include library in order to compile the project */
|
||||||
|
LD_LIBRARY_PATH = "$QTDIR/lib:$WORKSPACE/vendor/status-go/build/bin:$WORKSPACE/vendor/status-keycard-go/build/libkeycard/"
|
||||||
|
/* Container ports */
|
||||||
|
RPC_PORT = "${8545 + env.EXECUTOR_NUMBER.toInteger()}"
|
||||||
|
P2P_PORT = "${6010 + env.EXECUTOR_NUMBER.toInteger()}"
|
||||||
|
/* Ganache config */
|
||||||
|
GANACHE_RPC_PORT = "${9545 + env.EXECUTOR_NUMBER.toInteger()}"
|
||||||
|
GANACHE_MNEMONIC = 'pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial'
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Deps') {
|
||||||
|
steps {
|
||||||
|
sh 'make update'
|
||||||
|
sh 'make deps'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('status-go') {
|
||||||
|
steps {
|
||||||
|
sh 'make status-go'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('build') {
|
||||||
|
environment {
|
||||||
|
GANACHE_NETWORK_RPC_URL = "http://localhost:${env.GANACHE_RPC_PORT}"
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
sh 'make'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Containers') {
|
||||||
|
parallel {
|
||||||
|
stage('Ganache') { steps { script {
|
||||||
|
ganache = docker.image(
|
||||||
|
'trufflesuite/ganache:v7.4.1'
|
||||||
|
).run(
|
||||||
|
["-p 127.0.0.1:${env.GANACHE_RPC_PORT}:8545",
|
||||||
|
"-v ${env.WORKSPACE}/test/ui-test/fixtures/ganache-dbs/goerli:/goerli-db"].join(' '),
|
||||||
|
["-m='${GANACHE_MNEMONIC}'", "-e=10",
|
||||||
|
'--chain.chainId=5',
|
||||||
|
'--database.dbPath=/goerli-db'].join(' ')
|
||||||
|
)
|
||||||
|
} } }
|
||||||
|
|
||||||
|
stage('Nim-Waku') { steps { script {
|
||||||
|
nimwaku = docker.image(
|
||||||
|
'statusteam/nim-waku:v0.13.0'
|
||||||
|
).run(
|
||||||
|
["-p 127.0.0.1:${env.RPC_PORT}:8545",
|
||||||
|
"-p 127.0.0.1:${env.P2P_PORT}:30303/tcp",
|
||||||
|
"-p 127.0.0.1:${env.P2P_PORT}:30303/udp",
|
||||||
|
"-v ${env.WORKSPACE}/ci/mailserver/config.json:/config.json"].join(' '),
|
||||||
|
['--store=true',
|
||||||
|
'--keep-alive=true',
|
||||||
|
'--rpc-address=0.0.0.0',
|
||||||
|
'--nat=none'].join(' ')
|
||||||
|
)
|
||||||
|
env.TEST_PEER_ENR = getPeerAddress()
|
||||||
|
} } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Tests') {
|
||||||
|
options {
|
||||||
|
throttle(categories: ['status-desktop-e2e-tests'])
|
||||||
|
}
|
||||||
|
steps { script {
|
||||||
|
wrap([
|
||||||
|
$class: 'Xvfb',
|
||||||
|
autoDisplayName: true,
|
||||||
|
parallelBuild: true,
|
||||||
|
screen: '2560x1440x24',
|
||||||
|
]) { script {
|
||||||
|
def result = squish([
|
||||||
|
extraOptions: [
|
||||||
|
'--retry', '2',
|
||||||
|
'--tags', '~mayfail',
|
||||||
|
'--tags', '~merge',
|
||||||
|
'--tags', '~relyon-mailserver',
|
||||||
|
'--config', 'addAUT', 'nim_status_client',
|
||||||
|
"${WORKSPACE}/bin",
|
||||||
|
].join('\n'),
|
||||||
|
squishPackageName: 'squish-6.7.2-qt514x-linux64',
|
||||||
|
testSuite: "${WORKSPACE}/test/ui-test/testSuites/*",
|
||||||
|
])
|
||||||
|
print("Squish run result: ${result}")
|
||||||
|
if (!['SUCCESS', 'UNSTABLE'].contains(result)) {
|
||||||
|
throw new Exception('Squish run failed!')
|
||||||
|
}
|
||||||
|
} }
|
||||||
|
} }
|
||||||
|
post {
|
||||||
|
failure { script {
|
||||||
|
sh("docker logs ${nimwaku.id}")
|
||||||
|
sh("docker logs ${ganache.id}")
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
success { script {
|
||||||
|
github.notifyPR(true)
|
||||||
|
} }
|
||||||
|
failure { script {
|
||||||
|
github.notifyPR(false)
|
||||||
|
} }
|
||||||
|
always { script { /* No artifact but a PKG_URL is necessary. */
|
||||||
|
env.PKG_URL = "${currentBuild.absoluteUrl}/consoleText"
|
||||||
|
} }
|
||||||
|
cleanup { script {
|
||||||
|
sh './scripts/clean-git.sh'
|
||||||
|
if (binding.hasVariable('ganache')) { ganache.stop() }
|
||||||
|
if (binding.hasVariable('nimwaku')) { nimwaku.stop() }
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getPeerAddress() {
|
||||||
|
def rpcResp = sh(
|
||||||
|
script: "${env.WORKSPACE}/scripts/rpc.sh get_waku_v2_debug_v1_info",
|
||||||
|
returnStdout: true
|
||||||
|
).trim()
|
||||||
|
assert rpcResp : 'Could not get node address from RPC API!'
|
||||||
|
return readJSON(text: rpcResp)['result']['listenAddresses'][0]
|
||||||
|
}
|
|
@ -1,149 +0,0 @@
|
||||||
library 'status-jenkins-lib@v1.6.2'
|
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
|
||||||
def isPRBuild = utils.isPRBuild()
|
|
||||||
|
|
||||||
pipeline {
|
|
||||||
agent { label 'linux' }
|
|
||||||
|
|
||||||
parameters {
|
|
||||||
booleanParam(
|
|
||||||
name: 'RELEASE',
|
|
||||||
description: 'Decides whether binaries are built with debug symbols.',
|
|
||||||
defaultValue: params.RELEASE ?: false
|
|
||||||
)
|
|
||||||
choice(
|
|
||||||
name: 'VERBOSE',
|
|
||||||
description: 'Level of verbosity based on nimbus-build-system setup.',
|
|
||||||
choices: ['0', '1', '2']
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
options {
|
|
||||||
timestamps()
|
|
||||||
/* Prevent Jenkins jobs from running forever */
|
|
||||||
timeout(time: 120, unit: 'MINUTES')
|
|
||||||
/* manage how many builds we keep */
|
|
||||||
buildDiscarder(logRotator(
|
|
||||||
numToKeepStr: '10',
|
|
||||||
daysToKeepStr: '30',
|
|
||||||
artifactNumToKeepStr: '3',
|
|
||||||
))
|
|
||||||
/* Throttle number of concurrent builds. */
|
|
||||||
throttleJobProperty(
|
|
||||||
throttleEnabled: true,
|
|
||||||
throttleOption: 'category',
|
|
||||||
categories: ['status-desktop-e2e-tests'],
|
|
||||||
maxConcurrentPerNode: 1,
|
|
||||||
maxConcurrentTotal: 1
|
|
||||||
)
|
|
||||||
/* Abort old PR builds. */
|
|
||||||
disableConcurrentBuilds(
|
|
||||||
abortPrevious: isPRBuild
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
environment {
|
|
||||||
TARGET = 'e2e'
|
|
||||||
/* Improve make performance */
|
|
||||||
MAKEFLAGS = "-j4 V=${params.VERBOSE}"
|
|
||||||
/* Disable colors in Nim compiler logs */
|
|
||||||
NIMFLAGS = '--colors:off'
|
|
||||||
/* Makefile assumes the compiler folder is included */
|
|
||||||
QTDIR = "/opt/qt/5.14.2/gcc_64"
|
|
||||||
/* Control output the filename */
|
|
||||||
STATUS_CLIENT_APPIMAGE = "pkg/${utils.pkgFilename(ext: 'AppImage')}"
|
|
||||||
STATUS_CLIENT_TARBALL = "pkg/${utils.pkgFilename(ext: 'tar.gz')}"
|
|
||||||
/* Include library in order to compile the project */
|
|
||||||
LD_LIBRARY_PATH = "$QTDIR/lib:$WORKSPACE/vendor/status-go/build/bin:$WORKSPACE/vendor/status-keycard-go/build/libkeycard/"
|
|
||||||
INFURA_TOKEN = "cd313fedd0dd4699b194d72b5184be06"
|
|
||||||
GANACHE_NETWORK_RPC_URL = "http://0.0.0.0:${855 + env.EXECUTOR_NUMBER}"
|
|
||||||
}
|
|
||||||
|
|
||||||
stages {
|
|
||||||
stage('Deps') {
|
|
||||||
steps {
|
|
||||||
/* trigger fetching of git submodules */
|
|
||||||
sh 'make check-pkg-target-linux'
|
|
||||||
/* TODO: Re-add caching of Nim compiler. */
|
|
||||||
sh 'make deps'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('status-go') {
|
|
||||||
steps { sh 'make status-go' }
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('build') {
|
|
||||||
steps { sh 'make' }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Tests') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
def goerli_rpc_port = 855 + env.EXECUTOR_NUMBER
|
|
||||||
def mnemonic = "pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial"
|
|
||||||
def goerli_db_path = "$WORKSPACE/test/ui-test/fixtures/ganache-dbs/goerli"
|
|
||||||
def tcp_port = 6010 + env.EXECUTOR_NUMBER
|
|
||||||
docker.image('trufflesuite/ganache:v7.4.1').withRun(
|
|
||||||
"-p 127.0.0.1:${goerli_rpc_port}:8545 -v ${goerli_db_path}:/goerli-db",
|
|
||||||
"-e 10 -m='${mnemonic}' --chain.chainId 5 --database.dbPath /goerli-db"
|
|
||||||
) { c ->
|
|
||||||
docker.image('statusteam/nim-waku').withRun(
|
|
||||||
"-p 127.0.0.1:${tcp_port}:60000/tcp",
|
|
||||||
"--use-db=true --persist-messages=true --nat=none --nodekey=1122334455667788990011223344556677889900112233445566778899001122"
|
|
||||||
) { c2 ->
|
|
||||||
env.PEER_ENR = "/ip4/127.0.0.1/tcp/" + tcp_port + "/p2p/16Uiu2HAmMGhfSTUzKbsjMWxc6T1X4wiTWSF1bEWSLjAukCm7KiHV"
|
|
||||||
withEnv(["TEST_PEER_ENR=${env.PEER_ENR}"]){
|
|
||||||
wrap([
|
|
||||||
$class: 'Xvfb',
|
|
||||||
autoDisplayName: true,
|
|
||||||
parallelBuild: true,
|
|
||||||
screen: '2560x1440x24',
|
|
||||||
]) {
|
|
||||||
script {
|
|
||||||
def res = squish([
|
|
||||||
extraOptions: '''
|
|
||||||
--retry
|
|
||||||
2
|
|
||||||
|
|
||||||
--tags
|
|
||||||
~mayfail
|
|
||||||
|
|
||||||
--tags
|
|
||||||
~merge
|
|
||||||
|
|
||||||
--tags
|
|
||||||
~relyon-mailserver
|
|
||||||
|
|
||||||
--config
|
|
||||||
addAUT
|
|
||||||
nim_status_client
|
|
||||||
${WORKSPACE}/bin
|
|
||||||
''',
|
|
||||||
squishPackageName: 'squish-6.7.2-qt514x-linux64',
|
|
||||||
testSuite: '${WORKSPACE}/test/ui-test/testSuites/*',
|
|
||||||
])
|
|
||||||
echo res
|
|
||||||
if ( res == "SUCCESS" || res == "UNSTABLE" ) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
throw new Exception("squish test didn't end with success")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sh "docker logs ${c.id}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
post {
|
|
||||||
success { script { github.notifyPR(true) } }
|
|
||||||
failure { script { github.notifyPR(false) } }
|
|
||||||
cleanup { sh './scripts/clean-git.sh' }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"Rendezvous": false,
|
|
||||||
"NoDiscovery": true,
|
|
||||||
"ClusterConfig": {
|
|
||||||
"Enabled": true,
|
|
||||||
"Fleet": "eth.prod",
|
|
||||||
"BootNodes": [],
|
|
||||||
"TrustedMailServers": [],
|
|
||||||
"PushNotificationsServers": [],
|
|
||||||
"StaticNodes": []
|
|
||||||
},
|
|
||||||
"ListenAddr": "0.0.0.0:30303",
|
|
||||||
"HTTPEnabled": true,
|
|
||||||
"HTTPHost": "0.0.0.0",
|
|
||||||
"HTTPPort": 8545,
|
|
||||||
"MaxPeers": 50,
|
|
||||||
"DataDir": "/var/tmp/status-go-mailserver",
|
|
||||||
"APIModules": "eth,web3,admin,waku,wakuext",
|
|
||||||
"RegisterTopics": [
|
|
||||||
"whispermail"
|
|
||||||
],
|
|
||||||
"WakuConfig": {
|
|
||||||
"Enabled": true,
|
|
||||||
"EnableMailServer": true,
|
|
||||||
"DataDir": "/var/tmp/status-go-mailserver/waku",
|
|
||||||
"MailServerPassword": "status-offline-inbox",
|
|
||||||
"MailServerDataRetention": 30
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
RPC_ADDR="${RPC_ADDR:-localhost}"
|
|
||||||
RPC_PORT="${RPC_PORT:-8545}"
|
|
||||||
MAILSERVER_PORT="${MAILSERVER_PORT:-30303}"
|
|
||||||
# might be provided by parent
|
|
||||||
if [[ -z "${PUBLIC_IP}" ]]; then
|
|
||||||
PUBLIC_IP=$(curl -s https://ipecho.net/plain)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# query local
|
|
||||||
RESP_JSON=$(
|
|
||||||
curl -sS --retry 3 --retry-connrefused \
|
|
||||||
-X POST http://${RPC_ADDR}:${RPC_PORT}/ \
|
|
||||||
-H 'Content-type: application/json' \
|
|
||||||
-d '{"jsonrpc":"2.0","method":"admin_nodeInfo","params":[],"id":1}'
|
|
||||||
)
|
|
||||||
if [[ "$?" -ne 0 ]]; then
|
|
||||||
echo "RPC port not up, unable to query enode address!" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# extract enode from JSON response
|
|
||||||
ENODE_RAW=$(echo "${RESP_JSON}" | jq -r '.result.enode')
|
|
||||||
# drop arguments at the end of enode address
|
|
||||||
ENODE_CLEAN=$(echo "${ENODE_RAW}" | grep -oP '\Kenode://[^?]+')
|
|
||||||
|
|
||||||
ENODE=$(echo "${ENODE_CLEAN}" | sed \
|
|
||||||
-e "s/:30303/:${MAILSERVER_PORT}/")
|
|
||||||
|
|
||||||
echo "${ENODE}"
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# vim: set ft=sh:
|
||||||
|
|
||||||
|
RPC_PORT="${RPC_PORT:-8545}"
|
||||||
|
RPC_HOST="${RPC_HOST:-127.0.0.1}"
|
||||||
|
|
||||||
|
METHOD="$1"
|
||||||
|
shift
|
||||||
|
PARAMS=("$@")
|
||||||
|
|
||||||
|
if [[ -z "${METHOD}" ]]; then
|
||||||
|
echo "No method specified!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -n "${PARAMS}" ]]; then
|
||||||
|
PARAMS_STR=$(printf '%s\",\"' "${PARAMS[@]}")
|
||||||
|
# Params are a nested array because of a bug in nim-json-rpc.
|
||||||
|
# https://github.com/status-im/nim-json-rpc/issues/90
|
||||||
|
PARAMS_STR="[\"${PARAMS_STR%%\",\"}\"]"
|
||||||
|
else
|
||||||
|
PARAMS_STR=''
|
||||||
|
fi
|
||||||
|
|
||||||
|
PAYLOAD="{
|
||||||
|
\"id\": 1,
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"${METHOD}\",
|
||||||
|
\"params\": [${PARAMS_STR}]
|
||||||
|
}"
|
||||||
|
|
||||||
|
# The jq script checks if error exists and adjusts exit code.
|
||||||
|
curl --request POST \
|
||||||
|
--silent \
|
||||||
|
--show-error \
|
||||||
|
--fail-with-body \
|
||||||
|
--header 'Content-type:application/json' \
|
||||||
|
--data "${PAYLOAD}" \
|
||||||
|
"${RPC_HOST}:${RPC_PORT}" | \
|
||||||
|
jq -e '., if .error != null then null|halt_error(2) else halt end'
|
Loading…
Reference in New Issue