Files
pw/config/jobs/scripts/qa-runner.groovy
T

269 lines
13 KiB
Groovy

pipeline {
agent { label 'jjb' }
options {
timestamps()
ansiColor('xterm')
}
stages {
stage('Prepare Metadata') {
steps {
script {
def bddRefsRaw = (params.BDD_REFS ?: '').trim()
def bddRefs = bddRefsRaw
? bddRefsRaw.split(',').collect { it.trim() }.findAll { it }.unique()
: []
if (bddRefs.isEmpty() && (params.BDD_REPO_REF ?: '').trim()) {
bddRefs = [params.BDD_REPO_REF.trim()]
}
if (bddRefs.isEmpty()) {
bddRefs = ['main', 'homework_2']
}
env.BDD_REFS_EFFECTIVE = bddRefs.join(',')
wrap([$class: 'BuildUser']) {
env.RUN_TRIGGER_USER = env.BUILD_USER_ID ?: env.BUILD_USER ?: 'system'
env.RUN_TRIGGER_NAME = env.BUILD_USER ?: env.BUILD_USER_ID ?: 'system'
}
currentBuild.displayName = "#${env.BUILD_NUMBER} runner"
currentBuild.description = "by=${env.RUN_TRIGGER_NAME}; bddRefs=${env.BDD_REFS_EFFECTIVE}; qaRef=${params.QA_REPO_REF}; mobileRef=${params.MOBILE_REPO_REF}"
}
}
}
stage('Run Jobs In Parallel') {
steps {
script {
def fanout = [:]
def bddRefs = env.BDD_REFS_EFFECTIVE
.split(',')
.collect { it.trim() }
.findAll { it }
if (bddRefs.isEmpty()) {
bddRefs = ['main', 'homework_2']
}
bddRefs.each { ref ->
def refValue = ref
def refKey = ref.replaceAll(/[^A-Za-z0-9_.-]/, '_')
def runFile = "downstream-web-bdd-${refKey}.txt"
fanout["web-bdd-${refKey}"] = {
def run = build job: 'qa-web-bdd-tests',
wait: true,
propagate: false,
parameters: [
string(name: 'BDD_REPO_URL', value: params.BDD_REPO_URL),
string(name: 'BDD_REPO_REF', value: refValue),
string(name: 'BROWSER', value: params.BROWSER),
string(name: 'BASE_URL', value: params.BASE_URL),
string(name: 'SELENOID_URL', value: params.SELENOID_URL),
string(name: 'HEADLESS', value: params.HEADLESS)
]
writeFile file: runFile, text: "${run.number}|${run.result}\n"
}
}
fanout['selenium'] = {
def run = build job: 'qa-selenium-tests',
wait: true,
propagate: false,
parameters: [
string(name: 'QA_REPO_URL', value: params.QA_REPO_URL),
string(name: 'QA_REPO_REF', value: params.QA_REPO_REF),
string(name: 'BROWSER', value: params.BROWSER),
string(name: 'BASE_URL', value: params.BASE_URL),
string(name: 'EXECUTION_MODE', value: params.EXECUTION_MODE),
string(name: 'SELENOID_URL', value: params.SELENOID_URL),
string(name: 'HEADLESS', value: params.HEADLESS)
]
writeFile file: 'downstream-selenium.txt', text: "${run.number}|${run.result}\n"
}
fanout['mobile'] = {
def run = build job: 'qa-mobile-appium-tests',
wait: true,
propagate: false,
parameters: [
string(name: 'MOBILE_REPO_URL', value: params.MOBILE_REPO_URL),
string(name: 'MOBILE_REPO_REF', value: params.MOBILE_REPO_REF),
string(name: 'MOBILE_MAX_EMULATORS', value: params.MOBILE_MAX_EMULATORS),
string(name: 'JUNIT_PARALLELISM', value: params.JUNIT_PARALLELISM),
string(name: 'APP_URL', value: params.APP_URL),
string(name: 'DB_URL', value: params.DB_URL),
string(name: 'DB_USER', value: params.DB_USER),
string(name: 'DB_PASSWORD', value: params.DB_PASSWORD),
string(name: 'WISHLISTS_USERNAME', value: params.WISHLISTS_USERNAME),
string(name: 'WISHLISTS_PASSWORD', value: params.WISHLISTS_PASSWORD),
string(name: 'GIFTS_USERNAME', value: params.GIFTS_USERNAME),
string(name: 'GIFTS_PASSWORD', value: params.GIFTS_PASSWORD),
string(name: 'RESERVATION_USERNAME', value: params.RESERVATION_USERNAME),
string(name: 'RESERVATION_PASSWORD', value: params.RESERVATION_PASSWORD),
string(name: 'RESERVATION_OWNER', value: params.RESERVATION_OWNER)
]
writeFile file: 'downstream-mobile.txt', text: "${run.number}|${run.result}\n"
}
fanout['api'] = {
def run = build job: 'qa-api-citrus-tests',
wait: true,
propagate: false,
parameters: [
string(name: 'QA_REPO_URL', value: params.QA_REPO_URL),
string(name: 'QA_REPO_REF', value: params.QA_REPO_REF)
]
writeFile file: 'downstream-api.txt', text: "${run.number}|${run.result}\n"
}
fanout['api-contract'] = {
def run = build job: 'qa-api-contract-tests',
wait: true,
propagate: false
writeFile file: 'downstream-api-contract.txt', text: "${run.number}|${run.result}\n"
}
fanout['api-rest'] = {
def run = build job: 'qa-api-rest-tests',
wait: true,
propagate: false,
parameters: [
string(name: 'API_REST_REPO_URL', value: params.API_REST_REPO_URL),
string(name: 'API_REST_REPO_REF', value: params.API_REST_REPO_REF)
]
writeFile file: 'downstream-api-rest.txt', text: "${run.number}|${run.result}\n"
}
fanout['extra'] = {
def run = build job: 'qa-maven-extra-tests',
wait: true,
propagate: false,
parameters: [
string(name: 'EXTRA_REPO_URL', value: params.EXTRA_REPO_URL),
string(name: 'EXTRA_REPO_REF', value: params.EXTRA_REPO_REF)
]
writeFile file: 'downstream-extra.txt', text: "${run.number}|${run.result}\n"
}
fanout['playwright'] = {
def run = build job: 'qa-playwright-tests',
wait: true,
propagate: false,
parameters: [
string(name: 'PLAYWRIGHT_REPO_URL', value: params.PLAYWRIGHT_REPO_URL),
string(name: 'PLAYWRIGHT_REPO_REF', value: params.PLAYWRIGHT_REPO_REF),
string(name: 'PLAYWRIGHT_BROWSER', value: params.PLAYWRIGHT_BROWSER),
string(name: 'PLAYWRIGHT_HEADLESS', value: params.PLAYWRIGHT_HEADLESS),
string(name: 'PLAYWRIGHT_BASE_URL', value: params.BASE_URL),
string(name: 'PLAYWRIGHT_DOCKER_IMAGE', value: params.PLAYWRIGHT_DOCKER_IMAGE)
]
writeFile file: 'downstream-playwright.txt', text: "${run.number}|${run.result}\n"
}
parallel fanout
def parseRun = { String fileName ->
if (!fileExists(fileName)) {
return [number: 'n/a', result: 'NOT_BUILT']
}
def parts = readFile(fileName).trim().tokenize('|')
return [
number: parts ? parts[0] : 'n/a',
result: parts.size() > 1 ? parts[1] : 'UNKNOWN'
]
}
def bddRuns = [:]
bddRefs.each { ref ->
def refKey = ref.replaceAll(/[^A-Za-z0-9_.-]/, '_')
bddRuns[ref] = parseRun("downstream-web-bdd-${refKey}.txt")
}
def seleniumRun = parseRun('downstream-selenium.txt')
def mobileRun = parseRun('downstream-mobile.txt')
def apiRun = parseRun('downstream-api.txt')
def apiContractRun = parseRun('downstream-api-contract.txt')
def apiRestRun = parseRun('downstream-api-rest.txt')
def extraRun = parseRun('downstream-extra.txt')
def playwrightRun = parseRun('downstream-playwright.txt')
def lines = []
lines << "job=${env.JOB_NAME}"
lines << "build=${env.BUILD_NUMBER}"
lines << "trigger_user=${env.RUN_TRIGGER_USER}"
lines << "trigger_name=${env.RUN_TRIGGER_NAME}"
lines << "bdd_repo_url=${params.BDD_REPO_URL}"
lines << "bdd_refs=${bddRefs.join(',')}"
lines << "qa_repo_url=${params.QA_REPO_URL}"
lines << "qa_repo_ref=${params.QA_REPO_REF}"
lines << "mobile_repo_url=${params.MOBILE_REPO_URL}"
lines << "mobile_repo_ref=${params.MOBILE_REPO_REF}"
lines << "api_rest_repo_url=${params.API_REST_REPO_URL}"
lines << "api_rest_repo_ref=${params.API_REST_REPO_REF}"
lines << "extra_repo_url=${params.EXTRA_REPO_URL}"
lines << "extra_repo_ref=${params.EXTRA_REPO_REF}"
lines << "playwright_repo_url=${params.PLAYWRIGHT_REPO_URL}"
lines << "playwright_repo_ref=${params.PLAYWRIGHT_REPO_REF}"
lines << "playwright_docker_image=${params.PLAYWRIGHT_DOCKER_IMAGE}"
bddRefs.each { ref ->
def refKey = ref.replaceAll(/[^A-Za-z0-9_.-]/, '_')
def run = bddRuns[ref]
lines << "web_bdd_${refKey}_build=${run.number}"
lines << "web_bdd_${refKey}_result=${run.result}"
lines << "web_bdd_${refKey}_link=/job/qa-web-bdd-tests/${run.number}/"
lines << "web_bdd_${refKey}_link_abs=${env.JENKINS_URL}job/qa-web-bdd-tests/${run.number}/"
}
def primaryBddRef = bddRefs[0]
def primaryBddRun = bddRuns[primaryBddRef]
lines << "web_bdd_build=${primaryBddRun.number}"
lines << "web_bdd_result=${primaryBddRun.result}"
lines << "selenium_build=${seleniumRun.number}"
lines << "selenium_result=${seleniumRun.result}"
lines << "mobile_build=${mobileRun.number}"
lines << "mobile_result=${mobileRun.result}"
lines << "api_build=${apiRun.number}"
lines << "api_result=${apiRun.result}"
lines << "api_contract_build=${apiContractRun.number}"
lines << "api_contract_result=${apiContractRun.result}"
lines << "api_rest_build=${apiRestRun.number}"
lines << "api_rest_result=${apiRestRun.result}"
lines << "extra_build=${extraRun.number}"
lines << "extra_result=${extraRun.result}"
lines << "playwright_build=${playwrightRun.number}"
lines << "playwright_result=${playwrightRun.result}"
lines << "web_bdd_link=/job/qa-web-bdd-tests/${primaryBddRun.number}/"
lines << "selenium_link=/job/qa-selenium-tests/${seleniumRun.number}/"
lines << "mobile_link=/job/qa-mobile-appium-tests/${mobileRun.number}/"
lines << "api_link=/job/qa-api-citrus-tests/${apiRun.number}/"
lines << "api_contract_link=/job/qa-api-contract-tests/${apiContractRun.number}/"
lines << "api_rest_link=/job/qa-api-rest-tests/${apiRestRun.number}/"
lines << "extra_link=/job/qa-maven-extra-tests/${extraRun.number}/"
lines << "playwright_link=/job/qa-playwright-tests/${playwrightRun.number}/"
lines << "web_bdd_link_abs=${env.JENKINS_URL}job/qa-web-bdd-tests/${primaryBddRun.number}/"
lines << "selenium_link_abs=${env.JENKINS_URL}job/qa-selenium-tests/${seleniumRun.number}/"
lines << "mobile_link_abs=${env.JENKINS_URL}job/qa-mobile-appium-tests/${mobileRun.number}/"
lines << "api_link_abs=${env.JENKINS_URL}job/qa-api-citrus-tests/${apiRun.number}/"
lines << "api_contract_link_abs=${env.JENKINS_URL}job/qa-api-contract-tests/${apiContractRun.number}/"
lines << "api_rest_link_abs=${env.JENKINS_URL}job/qa-api-rest-tests/${apiRestRun.number}/"
lines << "extra_link_abs=${env.JENKINS_URL}job/qa-maven-extra-tests/${extraRun.number}/"
lines << "playwright_link_abs=${env.JENKINS_URL}job/qa-playwright-tests/${playwrightRun.number}/"
writeFile file: 'runner-summary.txt', text: lines.join('\n') + '\n'
archiveArtifacts allowEmptyArchive: false, artifacts: 'runner-summary.txt'
def criticalRuns = [mobileRun, apiRun, apiContractRun, apiRestRun, extraRun]
def optionalRuns = []
optionalRuns << seleniumRun
optionalRuns.addAll(bddRuns.values())
optionalRuns << playwrightRun
def criticalFailed = criticalRuns.any { it.result != 'SUCCESS' }
def optionalFailed = optionalRuns.any { it.result != 'SUCCESS' }
if (criticalFailed) {
error("One or more critical downstream QA jobs failed. See runner-summary.txt for build links and statuses.")
}
if (optionalFailed) {
currentBuild.result = 'UNSTABLE'
echo "Optional downstream jobs have failures (web-bdd refs/playwright). See runner-summary.txt for details."
}
}
}
}
}
}