2017-11-29 20 views
5

Tôi có một máy chủ Jenkins đang chạy tại chỗ, và nó sử dụng một Jenkinsfile để quản lý một đường ống sử dụng plugin thi hành song song để chạy tất cả các bài kiểm tra JUnit của tôi trên một số tác nhân để tăng tốc độ kiểm tra. Chúng tôi có một máy chủ phiến chúng tôi đã thực hiện (cách rẻ hơn so với mua một cái!) Và nó tăng tốc các thử nghiệm của chúng tôi từ gần 2 giờ đến 22 phút. Plugin JUnit hoạt động tốt với các bài kiểm tra song song.Tại sao stash/unstash không hoạt động trong Jenkinsfile này?

Tuy nhiên, Plugin Jacoco thì không. Vì vậy, tôi đang cố gắng để có được các tập tin bảo hiểm sáp nhập vào một tập tin để các plugin Jacoco có thể công bố kết quả bảo hiểm. Stash/unstash đang làm việc trong việc lưu trữ các nguồn nhưng nó không hoạt động khi tôi cố gắng để stash các tập tin đầu ra Jacoco khác nhau để unstash chúng trên tổng thể.

Mọi ý tưởng tại sao?

Đây là Jenkinsfile tôi:

#!/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: '[email protected]: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}" 

    } 
} 

đầu ra tôi nhận được là:

[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 

[sửa] các stash cho coverage0 là

[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 

lưu ý dòng

[split0] name: coverage0, include jacoco0 

chỉ là echo tuyên bố của tôi, nơi tôi vang tên từ phần này của kịch bản:

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" 

Lưu ý stashing thực tế không được thực hiện trên các nút, nó được liệt kê như đường ống mặc dù nó được thực hiện trên một nút từ xa. Tôi đã nhìn thấy những thứ chỉ ra stash được thực hiện trên tổng thể nhưng không thực sự là nơi mà thư mục đó cư trú.

[[FURTHER EDIT]] - nhờ eis cho các đề xuất.

Công việc/jdesigner/builds/1639/stashes/directory trên trang chủ có các tệp # .tar.gz bảo hiểm bao gồm tệp jacoco # .exec thích hợp. Khi tôi đặt một catch xung quanh unstash:

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

đầu ra tôi nhận được là:

collecting exec files 
[Pipeline] echo 
unstash coverage0 
[Pipeline] unstash 
[Pipeline] echo 
error unstashing: java.io.NotSerializableException: groovy.lang.IntRange 
[Pipeline] echo 
make file name 
+0

Trích xuất đầu ra cho thấy sự băm của 'vùng phủ sóng7' và việc bỏ liên kết' vùng phủ sóng0'. Thú vị hơn sẽ là một phần của nhật ký stashing 'coverage0'. –

+0

Tôi đã thêm bit đó @GeroldBroser – vextorspace

Trả lời

5

Vì trong ví dụ của bạn hoạt động này:

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

Nhưng điều này không:

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

Tôi nghĩ người đang làm việc ashed và unstashed trên nút từ xa của bạn, trong khi không làm việc một trong stashed trên nút từ xa của bạn nhưng bạn cố gắng unstash nó trên nút chủ của bạn (nơi nó tự nhiên sẽ không được tìm thấy).

Chỉnh sửa: do đó không phải như vậy. Theo số this,

When you stash a file on a slave, the files are send to the master. The files will be stored in the Job folder, in the associated build folder under the stash folder. Each stash will be stored as a tar file. These files are deleted at the end of the build.

Vì vậy, tách từ xa chính không nên tạo sự khác biệt.Ngoài ra, nếu không tìm thấy stash, bạn có thể see from the sources rằng nó sẽ bị lỗi với "No such saved stash ‘" + name + "’, vì theo số AbortException javadoc "Khi ngoại lệ này bị bắt, thông báo được chỉ định sẽ được báo cáo." Điều đó rõ ràng là không xảy ra.

Thay vào đó, bạn nên gỡ lỗi bằng cách sử dụng khối try-catch để tìm hiểu ngoại lệ thực sự đang phá vỡ bản dựng là gì.

Vì sao nó không được báo cáo đúng theo mặc định, có ví dụ this issue: "Lỗi tuần tự hóa ở cuối luồng không được báo cáo đúng trong nhật ký xây dựng, chỉ nhật ký Jenkins". Báo cáo lỗi tuyên bố "cố định" của nó nhưng dường như chỉ vì trên các phiên bản mới, một số thử nghiệm hành vi này không kích hoạt sự cố, do đó, nó vẫn có thể tồn tại.

+0

Nó được lưu trữ trên một nút từ xa và chưa được lưu trên 8 nút từ xa khác. Đó là những gì tôi nghĩ stash và unstash đã cho. – vextorspace

+0

từ tài liệu Jenkins: Lưu một tập hợp các tệp để sử dụng sau này trong cùng một bản dựng, thường là trên một nút/không gian làm việc khác. https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#stash-stash-some-files-to-be-used-later-in-the-build – vextorspace

+1

@vextorspace ... và cả , nếu không có stash như vậy, nó sẽ thất bại với [thông báo này] (https://github.com/jenkinsci/workflow-api-plugin/blob/master/src/main/java/org/jenkinsci/plugins /workflow/flow/StashManager.java#L127) vì [AbortException javadoc] (http://javadoc.jenkins-ci.org/hudson/AbortException.html) nói "Khi ngoại lệ này bị bắt, thông điệp được chỉ định sẽ được báo cáo. " vì vậy tôi đoán nó phải là một cái gì đó khác. Tuy nhiên, có vấn đề được repoted với master-remote stash sync: https://stackoverflow.com/questions/42508119/file-not-unstash-in-slave-machine-of-jenkins-server – eis

Các vấn đề liên quan