Jenkins在Jenkins中的不同节点上并行运行测试,没有这样的DSL方法';代理人';在台阶间找到的
我让以下脚本在一个Jenkins上正常运行:Jenkins在Jenkins中的不同节点上并行运行测试,没有这样的DSL方法';代理人';在台阶间找到的,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,我让以下脚本在一个Jenkins上正常运行: def serenityBatches = [:] pipeline { agent any parameters { string(defaultValue: '6', description: 'Number of test batches that should runindividually, either parallel or batch after batch', name: 'batchCo
def serenityBatches = [:]
pipeline {
agent any
parameters {
string(defaultValue: '6', description: 'Number of test batches that should runindividually, either parallel or batch after batch', name: 'batchCount')
string(defaultValue: '1', description: 'Number of tests/browsers that can run simultaniously on one node', name: 'forkCount')
}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
disableConcurrentBuilds()
}
stages {
stage('Clean workspace') {
steps {
withMaven(){ sh "mvn clean" }
}
}
stage('Create batches') {
steps {
script {
def batchCount = params.batchCount.toInteger()
def forkCount = params.forkCount.toInteger()
setJobDescription( batchCount, forkCount )
for (int i = 1; i <= batchCount; i++) {
def batchNumber = i
def batchName = "batch${batchNumber}"
serenityBatches[batchName] = {
node {
stage("batch${batchNumber} checkout") {
cleanWs()
checkoutFromSvn()
}
stage("batch${batchNumber} testing") {
runTests(batchNumber, batchCount, forkCount)
}
}
}
}
}
}
}
stage('Execute tests') {
steps {
script {
parallel serenityBatches
}
}
}
stage('Generate Report') {
steps {
collectReportsFromAllBatches()
aggregateReports()
publishReport()
zulipNotification stream: 'xxy', topic: 'AutoTests'
}
}
}
post {
changed {
script {
// report back to normal after failure
if(hudson.model.Result.FAILURE.equals(currentBuild.getPreviousBuild().result)) {
zulipNotification stream: 'xxy', topic: 'AutoTests'
}
}
}
}
}
void checkoutFromSvn() {
checkout changelog: false,
scm: [ $class: 'SubversionSCM',
locations: [[ cancelProcessOnExternalsFail: true,
credentialsId: 'someID',
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
remote: 'https://whatever',
clearWorkspace: true
]],
quietOperation: true,
workspaceUpdater: [$class: 'UpdateUpdater']
]
}
void runTests(batchNumber, batchCount, forkCount) {
try {
withMaven(){
sh "mvn clean"
sh "rm -rf target/site/serenity"
sh "mvn -U verify -Dparallel.tests=${forkCount} -Dserenity.batch.count=${batchCount} -Dserenity.batch.number=${batchNumber}"
}
} catch (Throwable e) {
throw e
} finally {
stash name: getStashId(batchNumber), excludes: "**", allowEmpty: true
stash name: getStashId(batchNumber), includes: "target/site/serenity/**/*", allowEmpty: true
}
}
String getStashId(int batchNumber) {
return "$JOB_NAME".replace('/','_')+"-$BUILD_NUMBER-batch-${batchNumber}"
}
/** unstash each of the batches **/
void collectReportsFromAllBatches() {
script {
def batchCount = params.batchCount.toInteger()
for (int batchNumber = 1; batchNumber <= batchCount; batchNumber++) {
def stashName = getStashId(batchNumber)
unstash stashName
}
}
}
void aggregateReports() {
withMaven(){ sh "mvn serenity:aggregate" }
}
/** publish the Serenity report **/
void publishReport() {
publishHTML(target: [
reportName : 'Serenity Report',
reportDir: 'target/site/serenity',
reportFiles: 'index.html',
keepAll: true,
alwaysLinkToLastBuild: true,
allowMissing: false
])
}
void setJobDescription(int batchCount, int forkCount) {
currentBuild.description = "batches:$batchCount forks:$forkCount"
}
def serenityBatches=[:]
管道{
任何代理人
参数{
字符串(defaultValue:'6',description:'应单独运行的测试批数,并行或批后运行',name:'batchCount')
字符串(defaultValue:'1',description:'可以在一个节点上同时运行的测试/浏览器的数量',name:'forkCount')
}
选择权{
构建丢弃器(logRotator(numtokepstr:'10'))
disableConcurrentBuilds()
}
舞台{
阶段(“清洁工作区”){
台阶{
withMaven(){sh“mvn clean”}
}
}
阶段('创建批'){
台阶{
剧本{
def batchCount=params.batchCount.toInteger()
def forkCount=params.forkCount.toInteger()
setJobDescription(batchCount、forkCount)
对于(inti=1;i尝试使用包含阶段的块的节点(标签){…}块定义代理
例如:
serenityBatches[batchName] = {
node('chrome') {
stage("batch${batchNumber} checkout") {
steps {
cleanWs()
checkoutFromSvn()
runTests(batchNumber, batchCount, forkCount)
}
}
}
}
似乎您在脚本
中嵌套了阶段
,这意味着代理
嵌套在脚本
块中。这在语法上是不明确的,可能是不允许的,这可能是您看到该错误的原因。请尝试在阶段
之前关闭脚本
块d以后打开一个新的。我不确定你打算在哪里这样做。我需要脚本块来向集合中添加批。如果你能提供一个示例作为答案,我将试一试。好的,我刚想到你可能使用的是脚本管道,而不是声明性的。我被使用代理
而抛弃了您使用的是脚本语法而不是声明性的,对吗?我理解这是声明性的。虽然我经常对什么是什么感到困惑…实际上我不介意哪一个…它应该可以工作。:)好球。我已经试过了。这就是为什么在那个位置上有空行。;-)但给我同样的错误:java.lang.NoSuchMethodError:在步骤中找不到这样的DSL方法“agent”
您得到了一条空行,并且在步骤{}中定义了一个agent{label'chrome'}block。确保在没有代理{label'chrome}的情况下测试我的解决方案。你应该知道这一点。现在我得到了一个java.lang.NoSuchMethodError:在步骤中找不到这样的DSL方法“步骤”
。谢谢。从这里开始尝试。``serentitybatches[batchName]={node('chrome'){stage(“batch${batchNumber}checkout”){steps{cleanWs()checkoutFromSvn()runTests(batchNumber,batchCount,forkCount)}}}}}``所以现在这是一个“脚本化管道”对吗?因为对于声明性管道,示例清楚地说明了“代理”而不是“节点”
serenityBatches[batchName] = {
node('chrome') {
stage("batch${batchNumber} checkout") {
steps {
cleanWs()
checkoutFromSvn()
runTests(batchNumber, batchCount, forkCount)
}
}
}
}