vex*_*ace 6 java git groovy jenkins jacoco
我有一个在现场运行的Jenkins服务器,它使用Jenkins文件管理一个管道,该管道使用并行测试执行器插件在几个代理上运行所有JUnit测试以加快测试速度.我们有一个刀片服务器(比买一个便宜!)并且我们的测试从接近2小时到22分钟加速.JUnit插件适用于并行测试.
然而,Jacoco Plugin却没有.所以我试图将覆盖文件合并到一个文件,以便Jacoco插件可以发布覆盖结果.Stash/unstash正在存储源代码,但是当我尝试存储不同的Jacoco输出文件以在master上取消它们时,它无法正常工作.
有什么想法吗?
这是我的Jenkinsfile:
#!/usr/bin/env groovy
def branch
def hash
node('remote') {
sh 'echo starting'
branch = env.gitlabBranch ?: '**'
echo "Branch: $branch"
checkout([$class: 'GitSCM',
branches: [[name: "$branch"]],
extensions: [
[$class: 'PruneStaleBranch'],
[$class: 'CheckoutOption', timeout: 120],
[$class: 'CloneOption', depth: 0, noTags: true, shallow: true, timeout: 180]
],
doGenerateSubmoduleConfigurations: false,
submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'gitlabLabptop', url: 'git@gitlab.com:protocase/my_project_url.git']]
]
)
hash = sh (script: 'git rev-parse HEAD', returnStdout: true).trim()
### - this stash works fine -###
stash name: 'sources', includes: '**', excludes: '**/.git,**/.git/**'
}
def numBranches = 9
def splits = splitTests count(numBranches)
def branches = [:]
for (int i = 0; i < splits.size(); i++) {
def index = i // fresh variable per iteration; i will be mutated
branches["split${i}"] = {
timeout(time: 125, unit: 'MINUTES') {
node('remote') {
sh 'echo starting a node'
deleteDir()
### - this unstash works fine - ###
unstash 'sources'
def exclusions = splits.get(index);
writeFile file: 'test/exclusions.txt', text: exclusions.join("\n")
sh 'ant clean'
sh 'rm -rf build'
sh 'ant jar'
sh 'ant -buildfile build-test.xml buildTests'
sh 'ant -buildfile build-test.xml jenkinsBatch'
junit 'build/test/results/*.xml'
sh "mv build/test/jacoco/jacoco.exec build/test/jacoco/jacoco${index}.exec"
echo "name: coverage$index, unclude jacoco${index}"
### - this stash appears to work - ###
stash name: "coverage$index", includes: "build/test/jacoco/jacoco${index}.exec"
echo "stashed"
}
}
}
}
parallel branches
def branchIndecis = 0..numBranches
node('master') {
if (currentBuild.result != "ABORTED") {
echo "collecting exec files"
branchIndecis.each {
echo "unstash coverage${it}"
### !!! this unstash causes an error !!! ###
unstash name: "coverage${it}"
echo "make file name"
def coverageFileName = "build/test/jacoco/jacoco${it}.exec"
echo "merge file"
sh "ant -buildfile build-test.xml -Dfile=${coverageFileName} coverageMerge"
}
echo "collected exec files"
step([$class: 'JacocoPublisher',
execPattern:'build/test/jacoco/jacoco.exec',
classPattern: 'build/classes',
sourcePattern: 'src'])
echo "finishing ${branch} - ${hash}"
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
[split7] [jdesigner] Running shell script
[split7] + mv build/test/jacoco/jacoco.exec build/test/jacoco/jacoco7.exec
[Pipeline] [split7] echo
[split7] name: coverage7, unclude jacoco7
[Pipeline] [split7] stash
[split7] Stashed 1 file(s)
[Pipeline] [split7] echo
[split7] stashed
[Pipeline] [split7] }
[Pipeline] [split7] // node
[Pipeline] [split7] }
[Pipeline] [split7] // timeout
[Pipeline] [split7] }
[Pipeline] // parallel
[Pipeline] node
Running on eightyeight in /var/jenkins/workspace/jdesigner
[Pipeline] {
[Pipeline] echo
collecting exec files
[Pipeline] echo
unstash coverage0
[Pipeline] unstash
[Pipeline] }
[Pipeline] End of Pipeline
Finished: FAILURE
Run Code Online (Sandbox Code Playgroud)
[编辑]覆盖0的存储是
[split0] Recording test results
[Pipeline] [split0] sh
[split0] [jdesigner] Running shell script
[split0] + mv build/test/jacoco/jacoco.exec build/test/jacoco/jacoco0.exec
[Pipeline] [split0] echo
[split0] name: coverage0, include jacoco0
[Pipeline] [split0] stash
[split0] Stashed 1 file(s)
[Pipeline] [split0] echo
[split0] stashed
[Pipeline] [split0] }
[Pipeline] [split0] // node
[Pipeline] [split0] }
[Pipeline] [split0] // timeout
[Pipeline] [split0] }
[split3] [junit] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 18.737 sec
[split3] [junit] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 18.737 sec
Run Code Online (Sandbox Code Playgroud)
注意这条线
[split0] name: coverage0, include jacoco0
Run Code Online (Sandbox Code Playgroud)
只是我的echo语句,我从脚本的这一部分回显名称:
sh "mv build/test/jacoco/jacoco.exec build/test/jacoco/jacoco${index}.exec"
echo "name: coverage$index, include jacoco${index}"
stash name: "coverage$index", includes: "build/test/jacoco/jacoco${index}.exec"
echo "stashed"
Run Code Online (Sandbox Code Playgroud)
请注意,实际的存储未在节点上完成,即使在远程节点上完成,也会将其列为管道.我看到的东西表明存储是在主服务器上完成的,但实际上并不是该目录所在的位置.
[[进一步编辑]] - 感谢eis的建议.
master上的jobs/jdesigner/builds/1639/stashes /目录包含#.tar.gz文件,其中包含相应的jacoco#.exec文件.当我试着抓住unstash:
try {
unstash name: "coverage${it}"
} catch (error) {
echo "error unstashing: ${error}"
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
collecting exec files
[Pipeline] echo
unstash coverage0
[Pipeline] unstash
[Pipeline] echo
error unstashing: java.io.NotSerializableException: groovy.lang.IntRange
[Pipeline] echo
make file name
Run Code Online (Sandbox Code Playgroud)
TLDR:这是一个问题,迭代样式引起了这个问题,因为it使用的密钥不是Serializable.
让这很难调试的是错误消息没有正确报告,可能是由于这个问题.在代码和"手动"报告中捕获异常修复了这一点.
使用Serializable密钥修复了实际问题.
更长的版本:
因为在你的例子中这是有效的:
node('remote') {
### - this stash works fine -###
stash name: 'sources', includes: '**', excludes: '**/.git,**/.git/**'
}
node('remote') {
### - this unstash works fine - ###
unstash 'sources'
}
Run Code Online (Sandbox Code Playgroud)
但这不是:
node('remote') {
### - this stash appears to work - ###
stash name: "coverage$index", includes: "build/test/jacoco/jacoco${index}.exec"
echo "stashed"
}
node('master') {
echo "unstash coverage${it}"
### !!! this unstash causes an error !!! ###
unstash name: "coverage${it}"
}
Run Code Online (Sandbox Code Playgroud)
我最初认为工作的是在远程节点上存储和取消,而非工作的存储在远程节点上,但是你试图在主节点上取消它(当然不会找到它).
但事实并非如此.根据此,
将文件存储在从站上时,文件将发送给主站.这些文件将存储在作业文件夹中,存储在存储文件夹下的相关构建文件夹中.每个存储将存储为tar文件.这些文件在构建结束时被删除.
所以主远程分离不应该有所作为.另外,如果它是关于stash not found,你可以从源代码中看到它会失败"No such saved stash ‘" + name + "’,因为根据AbortException javadoc "当捕获到这个异常时,将报告指定的消息.".这显然没有发生.
相反,应该使用try-catch块进行调试,以找出破坏构建的真正异常.
至于默认情况下没有正确报告的原因,有一个问题:"在构建日志中没有正确报告流程结束时的序列化错误,只有Jenkins日志".错误报告声称它"固定"但显然只是因为在新版本中,这种行为的一些测试没有触发问题,所以它可能仍然存在.
有了错误消息,我们可以看到问题是这样的 - 当我们传递它时,我们试图序列化一个不可序列化的键.
| 归档时间: |
|
| 查看次数: |
14318 次 |
| 最近记录: |