在工作中,我们只能在一个特别锁定的 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 个的批次运行测试集合,但并行运行这些批次,就像上面链接的答案一样。
非常感谢任何帮助!
我在工作中也遇到过同样的问题。好吧,我们总是达到资源限制。 无论如何,您只需要用顺序运行器包装并行运行器,并为其提供正确的数据结构,该数据结构应该是列表的列表:
["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
}
}
}