Why doesn't stash / unstash work in this Jenkins file?

I have a Jenkins server running in place and it uses a Jenkins pipeline control file that uses a parallel testing plugin to run all of my JUnit tests for multiple agents to speed up testing. We have a blade server that we made (itโ€™s cheaper than buying!), And this accelerated our tests in about 2 hours to 22 minutes. The JUnit plugin works great with parallel tests.

The Jacoco plugin, however, does not. Therefore, I am trying to combine coverage files into one file so that the Jacoco plugin can publish coverage results. Stash / unstash works in the source store, but it does not work when I try to hide various Javaoco output files to unlock them on the main server.

Any ideas why?

Here is my Jenkins file:

#!/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}" } } 

output i get:

 [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 

[edit] cabinet for cover0

 [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 

note the line

 [split0] name: coverage0, include jacoco0 

- this is just my echo instruction, in which I repeat the name from this part of the script:

  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" 

Note that the actual erasure is not performed on the node, it is indicated as a pipeline, even if it is performed on the remote node device. I saw things that indicated that the cover was being done on the main computer, but not really where this directory was located.

[[FURTHER EDITION]] - thanks to the recommendations of eis.

In the directory jobs / jdesigner / builds / 1639 / stashes / on the main server there are files with the extension # .tar.gz that contain the corresponding jacoco # .exec files. When I set an attempt to catch the instability:

 try { unstash name: "coverage${it}" } catch (error) { echo "error unstashing: ${error}" } 

output i get:

 collecting exec files [Pipeline] echo unstash coverage0 [Pipeline] unstash [Pipeline] echo error unstashing: java.io.NotSerializableException: groovy.lang.IntRange [Pipeline] echo make file name 
+5
source share
1 answer

Since in your example this works:

 node('remote') { ### - this stash works fine -### stash name: 'sources', includes: '**', excludes: '**/.git,**/.git/**' } node('remote') { ### - this unstash works fine - ### unstash 'sources' } 

But this is not so:

 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}" } 

I think that the worker will be hidden and deleted on your remote node device, while the idle one will be hidden on your remote node device, but you will try to unlock it on your host node (where it naturally will not be found).

Edit: this is not the case. According to this ,

When you attach a file to the slave, the files are sent to the wizard. Files will be saved in the Work folder, in the associated assembly, a folder under the folder. Each cache will be stored as a tar file. These files are deleted at the end of the assembly.

Thus, remote sharing of skill should not matter. In addition, if it werenโ€™t for stash not to be found, you can see from sources that it would fail with "No such saved stash '" + name + "' , since according to AbortException javadoc " When this exception is caught, the specified message will be reported. "This is clearly not happening.

Instead, you should debug the use of the try-catch block to find out what is the real exception that breaks the assembly.

As for why by default it is not properly reported, for example, this problem : "The serialization error at the end of the stream is not reported correctly in the build log, only the Jenkins log." The bug report claims to be โ€œfixedโ€, but apparently only because some new tests of this behavior did not cause a problem in newer versions, so it may still exist.

+5
source

Source: https://habr.com/ru/post/1273738/


All Articles