声明式 Jenkins 管道;并行批量运行测试用例

问题描述 投票:0回答:1

在工作中,我们只能在一个特别锁定的 jenkins 实例上运行无人值守的测试,我无法控制该实例。

该作业从多个存储库获取测试集合,因此集合的数量非常动态,并且只会不断增长。

测试集合通常需要 30 秒来执行,因此并行运行它们很好,直到实例开始耗尽资源,并开始终止进程。

下面的代码运行良好,直到我们达到大约 30 个测试集合

 script {
    echo " * *  find all postman collections, and create separate steps"
    def TMP_FILENAME = ".pm_files_list"
    sh "basename -s .postman_collection.json ./pm_collections/* > ${TMP_FILENAME}"
    def filenames = readFile(TMP_FILENAME).split( "\\r?\\n" );
    sh "rm -f ${TMP_FILENAME}"

    parallelStagesMap = filenames.collectEntries {
        ["${it}" : generateStage(it)]
    }
    parallel parallelStagesMap
}

generateStage 看起来像这样

def generateStage(collection) {
    return {
        stage("${collection}") {
            echo "running: ${collection}"
            sh  script: "npm run newman-run-collection --collection=\"${collection}\" "
        }
    }
}

我想实现像https://stackoverflow.com/a/67116586/10505992这样的目标,所以我想出了这个:(我的用户没有创建作业的权限,所以我无法使用其他答案直接)

        stage('batch')
        {
            steps {
                script {
                    echo " * *  find all postman collections, and create seperate steps"
                    def TMP_FILENAME = ".pm_files_list"
                    sh "basename -s .postman_collection.json ./pm_collections/* > ${TMP_FILENAME}"
                    def collectionfiles = readFile(TMP_FILENAME).split( "\\r?\\n" ) as List;
                    //echo "collectionfiles: ${collectionfiles}"
                    collectionfiles.collate(10).each { List batch ->
                        echo "batch: ${batch}"

                        parallelStagesMap = batch.collectEntries {
                            ["${it}" : generateStage(it)]
                        }
                        parallel parallelStagesMap
                    }
                    parallelStagesMap["failFast"] = false
                }
            }
        }

但问题是只执行了第一批。 如果我将上面的内容减少到仅回显列表,我会看到

collectionfiles
batch
包含我期望的文件名。

我想最终以每批 10 到 20 个的批次运行测试集合,但并行运行这些批次,就像上面链接的答案一样。

非常感谢任何帮助!

jenkins groovy parallel-processing jenkins-pipeline jenkins-groovy
1个回答
0
投票

我在工作中也遇到过同样的问题。好吧,我们总是达到资源限制。 无论如何,您只需要用顺序运行器包装并行运行器,并为其提供正确的数据结构,该数据结构应该是列表的列表:

["f1", "f2", "f3", "f4", "f5", "f6"] -> 应转换为 -> [["f1", "f2"], ["f3", “f4”],[“f5”,“f6”]]

因此,顺序运行程序正在获取列表列表(LoL),并为子列表中的每个项目顺序启动并行运行程序。因此,您可以实现特定数量项目的并行执行。 技术上整理功能来实现转变:

                list.collate(parallelSize)

因此,您可以调整系统中可以承受的并行度:

pipeline
    {
        agent { label 'master' }
        parameters {
            string(name: 'Parallel_items', defaultValue: '2', description: '')
        }
        
        stages
        {
            stage('sandbox')
            {
                steps
                {
                    script
                    {
                        echo "start"
                        def fileNames = ["f1", "f2", "f3", "f4", "f5", "f6"]
                        runSequential(fileNames.collate(params.Parallel_items.toInteger()))
                    }
                }
            }
        }
    }
   
    
    def runSequential(parallelQueue){
        parallelQueue.each{
            runParallel(it)
        }
    }
    
    def runParallel(fileNames){
        parallelStagesMap = fileNames.collectEntries {
            ["${it}" : generateStage(it)]
        }
        parallel parallelStagesMap
    }
    
    def generateStage(collection) {
        return {
            stage("${collection}") {
                echo "running: ${collection}"
                sleep 5
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.