#!/bin/groovy library 'kibana-pipeline-library' kibanaLibrary.load() def TASK_PARAM = params.TASK ?: params.CI_GROUP // Looks like 'oss:ciGroup:1', 'oss:firefoxSmoke' def JOB_PARTS = TASK_PARAM.split(':') def IS_XPACK = JOB_PARTS[0] == 'xpack' def JOB = JOB_PARTS.size() > 1 ? JOB_PARTS[1] : JOB_PARTS[0] def CI_GROUP = JOB_PARTS.size() > 2 ? JOB_PARTS[2] : '' def EXECUTIONS = params.NUMBER_EXECUTIONS.toInteger() def AGENT_COUNT = getAgentCount(EXECUTIONS) def NEED_BUILD = JOB != 'jestIntegration' && JOB != 'apiIntegration' currentBuild.displayName += trunc(" ${params.GITHUB_OWNER}:${params.branch_specifier}", 24) currentBuild.description = "${params.CI_GROUP}
Agents: ${AGENT_COUNT}
Executions: ${params.NUMBER_EXECUTIONS}" kibanaPipeline(timeoutMinutes: 180) { def agents = [:] def workerFailures = [] def worker = getWorkerFromParams(IS_XPACK, JOB, CI_GROUP) for(def agentNumber = 1; agentNumber <= AGENT_COUNT; agentNumber++) { def agentExecutions = floor(EXECUTIONS/AGENT_COUNT) + (agentNumber <= EXECUTIONS%AGENT_COUNT ? 1 : 0) agents["agent-${agentNumber}"] = { agentProcess( agentNumber: agentNumber, agentExecutions: agentExecutions, worker: worker, workerFailures: workerFailures, needBuild: NEED_BUILD, isXpack: IS_XPACK, ciGroup: CI_GROUP ) } } parallel(agents) currentBuild.description += ", Failures: ${workerFailures.size()}" if (workerFailures.size() > 0) { print "There were ${workerFailures.size()} test suite failures." print "The executions that failed were:" print workerFailures.join("\n") print "Please check 'Test Result' and 'Pipeline Steps' pages for more info" } } def agentProcess(Map params = [:]) { def config = [ agentNumber: 1, agentExecutions: 0, worker: {}, workerFailures: [], needBuild: false, isXpack: false, ciGroup: null, ] + params catchErrors { print "Agent ${config.agentNumber} - ${config.agentExecutions} executions" withEnv([ 'IGNORE_SHIP_CI_STATS_ERROR=true', ]) { kibanaPipeline.withTasks([ parallel: 20, ]) { task { if (config.needBuild) { kibanaPipeline.buildKibana() } for(def i = 0; i < config.agentExecutions; i++) { def taskNumber = i task({ withEnv([ "REMOVE_KIBANA_INSTALL_DIR=1", ]) { catchErrors { try { config.worker() } catch (ex) { config.workerFailures << "agent-${config.agentNumber}-${taskNumber}" throw ex } } } }) } } } } } } def getWorkerFromParams(isXpack, job, ciGroup) { if (!isXpack) { if (job == 'accessibility') { return kibanaPipeline.functionalTestProcess('kibana-accessibility', './test/scripts/jenkins_accessibility.sh') } else if (job == 'firefoxSmoke') { return kibanaPipeline.functionalTestProcess('firefoxSmoke', './test/scripts/jenkins_firefox_smoke.sh') } else if (job == 'visualRegression') { return kibanaPipeline.functionalTestProcess('visualRegression', './test/scripts/jenkins_visual_regression.sh') } else if (job == 'jestIntegration') { return kibanaPipeline.scriptTaskDocker('Jest Integration Tests', 'test/scripts/test/jest_integration.sh') } else if (job == 'apiIntegration') { return kibanaPipeline.scriptTask('API Integration Tests', 'test/scripts/test/api_integration.sh') } else if (job == 'pluginFunctional') { return kibanaPipeline.functionalTestProcess('oss-pluginFunctional', './test/scripts/jenkins_plugin_functional.sh') } else { return kibanaPipeline.ossCiGroupProcess(ciGroup) } } if (job == 'accessibility') { return kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh') } else if (job == 'firefoxSmoke') { return kibanaPipeline.functionalTestProcess('xpack-firefoxSmoke', './test/scripts/jenkins_xpack_firefox_smoke.sh') } else if (job == 'visualRegression') { return kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh') } else { return kibanaPipeline.xpackCiGroupProcess(ciGroup) } } def getAgentCount(executions) { // Increase agent count every 20 worker processess, up to 3 agents maximum return Math.min(3, 1 + floor(executions/20)) } def trunc(str, length) { if (str.size() >= length) { return str.take(length) + "..." } return str; } // All of the real rounding/truncating methods are sandboxed def floor(num) { return num .toString() .split('\\.')[0] .toInteger() }