Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 1 | /** |
| 2 | * |
Oleg Basov | 3d93f55 | 2019-03-27 01:01:20 +0100 | [diff] [blame] | 3 | * Launch validation of the cloud with Rally |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 4 | * |
| 5 | * Expected parameters: |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 6 | * |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 7 | * JOB_TIMEOUT Job timeout in hours |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 8 | * SALT_MASTER_URL URL of Salt master |
| 9 | * SALT_MASTER_CREDENTIALS Credentials to the Salt API |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 10 | * VALIDATE_PARAMS Validate job YAML params (see below) |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 11 | * |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 12 | * Rally - map with parameters for starting Rally tests |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 13 | * |
Dmitrii Kabanov | 9f3b7ed | 2017-09-29 10:47:36 -0700 | [diff] [blame] | 14 | * AVAILABILITY_ZONE The name of availability zone |
| 15 | * FLOATING_NETWORK The name of the external(floating) network |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 16 | * K8S_RALLY Use Kubernetes Rally plugin for testing K8S cluster |
| 17 | * STACKLIGHT_RALLY Use Stacklight Rally plugin for testing Stacklight |
Dmitrii Kabanov | 9f3b7ed | 2017-09-29 10:47:36 -0700 | [diff] [blame] | 18 | * RALLY_IMAGE The name of the image for Rally tests |
| 19 | * RALLY_FLAVOR The name of the flavor for Rally image |
Oleg Basov | 41c4fe7 | 2018-06-10 01:16:58 +0200 | [diff] [blame] | 20 | * RALLY_PLUGINS_REPO Git repository with Rally plugins |
| 21 | * RALLY_PLUGINS_BRANCH Git branch which will be used during the checkout |
Dmitrii Kabanov | b2f60ee | 2017-11-10 00:31:50 -0800 | [diff] [blame] | 22 | * RALLY_CONFIG_REPO Git repository with files for Rally |
| 23 | * RALLY_CONFIG_BRANCH Git branch which will be used during the checkout |
Sergey Galkin | 8991e82 | 2017-11-29 19:10:46 +0400 | [diff] [blame] | 24 | * RALLY_SCENARIOS Path to file or directory with rally scenarios |
Oleg Basov | bf86032 | 2018-09-04 20:54:36 +0200 | [diff] [blame] | 25 | * RALLY_SL_SCENARIOS Path to file or directory with stacklight rally scenarios |
Sergey Galkin | 8991e82 | 2017-11-29 19:10:46 +0400 | [diff] [blame] | 26 | * RALLY_TASK_ARGS_FILE Path to file with rally tests arguments |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 27 | * RALLY_DB_CONN_STRING Rally-compliant DB connection string for long-term storing |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 28 | * results to external DB |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 29 | * RALLY_TAGS List of tags for marking Rally tasks. Can be used when |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 30 | * generating Rally trends based on particular group of tasks |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 31 | * RALLY_TRENDS If enabled, generate Rally trends report. Requires external DB |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 32 | * connection string to be set. If RALLY_TAGS was set, trends will |
| 33 | * be generated based on finished tasks with these tags, otherwise |
| 34 | * on all the finished tasks available in DB |
mkraynov | da6b698 | 2018-08-06 17:48:24 +0400 | [diff] [blame] | 35 | * SKIP_LIST List of the Rally scenarios which should be skipped |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 36 | * |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 37 | * PARALLEL_PERFORMANCE If enabled, run Rally tests separately in parallel for each sub directory found |
| 38 | * inside RALLY_SCENARIOS and RALLY_SL_SCENARIOS (if STACKLIGHT_RALLY is enabled) |
Oleg Basov | 2d291f7 | 2019-05-28 11:44:15 +0200 | [diff] [blame] | 39 | * GENERATE_REPORT Set this to false if you are running longevity tests on a cicd node with less than |
| 40 | * 21GB memory. Rally consumes lots of memory when generating reports sourcing week |
| 41 | * amounts of data (BUG PROD-30433) |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 42 | */ |
| 43 | |
| 44 | common = new com.mirantis.mk.Common() |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 45 | validate = new com.mirantis.mcp.Validate() |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 46 | salt = new com.mirantis.mk.Salt() |
| 47 | salt_testing = new com.mirantis.mk.SaltModelTesting() |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 48 | |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 49 | def VALIDATE_PARAMS = readYaml(text: env.getProperty('VALIDATE_PARAMS')) ?: [:] |
| 50 | if (! VALIDATE_PARAMS) { |
| 51 | throw new Exception("VALIDATE_PARAMS yaml is empty.") |
| 52 | } |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 53 | def TEST_IMAGE = env.getProperty('TEST_IMAGE') ?: 'xrally-openstack:1.4.0' |
| 54 | def JOB_TIMEOUT = env.getProperty('JOB_TIMEOUT').toInteger() ?: 12 |
| 55 | def SLAVE_NODE = env.getProperty('SLAVE_NODE') ?: 'docker' |
| 56 | def rally = VALIDATE_PARAMS.get('rally') ?: [:] |
| 57 | def scenariosRepo = rally.get('RALLY_CONFIG_REPO') ?: 'https://review.gerrithub.io/Mirantis/scale-scenarios' |
| 58 | def scenariosBranch = rally.get('RALLY_CONFIG_BRANCH') ?: 'master' |
| 59 | def pluginsRepo = rally.get('RALLY_PLUGINS_REPO') ?: 'https://github.com/Mirantis/rally-plugins' |
| 60 | def pluginsBranch = rally.get('RALLY_PLUGINS_BRANCH') ?: 'master' |
| 61 | def tags = rally.get('RALLY_TAGS') ?: [] |
Oleg Basov | 2d291f7 | 2019-05-28 11:44:15 +0200 | [diff] [blame] | 62 | def generateReport = rally.get('GENERATE_REPORT', true).toBoolean() |
Oleg Basov | d4fa386 | 2019-03-05 21:49:12 +0100 | [diff] [blame] | 63 | |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 64 | // contrainer working dir vars |
| 65 | def rallyWorkdir = '/home/rally' |
| 66 | def rallyPluginsDir = "${rallyWorkdir}/rally-plugins" |
| 67 | def rallyScenariosDir = "${rallyWorkdir}/rally-scenarios" |
| 68 | def rallyResultsDir = "${rallyWorkdir}/test_results" |
| 69 | def rallySecrets = "${rallyWorkdir}/secrets" |
Oleg Basov | 3d93f55 | 2019-03-27 01:01:20 +0100 | [diff] [blame] | 70 | |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 71 | // env vars |
| 72 | def env_vars = [] |
| 73 | def platform = [ |
| 74 | type: 'unknown', |
| 75 | stacklight: [enabled: false, grafanaPass: ''], |
| 76 | ] |
| 77 | def cmp_count |
| 78 | |
| 79 | // test results vars |
| 80 | def testResult |
| 81 | def tasksParallel = [:] |
| 82 | def parallelResults = [:] |
| 83 | def configRun = [:] |
| 84 | |
| 85 | timeout(time: JOB_TIMEOUT, unit: 'HOURS') { |
| 86 | node (SLAVE_NODE) { |
| 87 | |
| 88 | // local dir vars |
| 89 | def workDir = "${env.WORKSPACE}/rally" |
| 90 | def pluginsDir = "${workDir}/rally-plugins" |
| 91 | def scenariosDir = "${workDir}/rally-scenarios" |
| 92 | def secrets = "${workDir}/secrets" |
| 93 | def artifacts = "${workDir}/validation_artifacts" |
| 94 | |
| 95 | stage('Configure env') { |
| 96 | |
| 97 | def master = salt.connection(SALT_MASTER_URL, SALT_MASTER_CREDENTIALS) |
| 98 | |
| 99 | // create local directories |
| 100 | sh "rm -rf ${workDir} || true" |
| 101 | sh "mkdir -p ${artifacts} ${secrets}" |
| 102 | writeFile file: "${workDir}/entrypoint.sh", text: '''#!/bin/bash |
| 103 | set -xe |
| 104 | exec "$@" |
| 105 | ''' |
| 106 | sh "chmod 755 ${workDir}/entrypoint.sh" |
| 107 | |
| 108 | // clone repo with Rally plugins and checkout refs/branch |
| 109 | checkout([ |
| 110 | $class : 'GitSCM', |
| 111 | branches : [[name: 'FETCH_HEAD']], |
| 112 | extensions : [[$class: 'RelativeTargetDirectory', relativeTargetDir: pluginsDir]], |
| 113 | userRemoteConfigs: [[url: pluginsRepo, refspec: pluginsBranch]], |
| 114 | ]) |
| 115 | |
| 116 | // clone scenarios repo and switch branch / fetch refspecs |
| 117 | checkout([ |
| 118 | $class : 'GitSCM', |
| 119 | branches : [[name: 'FETCH_HEAD']], |
| 120 | extensions : [[$class: 'RelativeTargetDirectory', relativeTargetDir: scenariosDir]], |
| 121 | userRemoteConfigs: [[url: scenariosRepo, refspec: scenariosBranch]], |
| 122 | ]) |
| 123 | |
| 124 | // get number of computes in the cluster |
| 125 | platform['cluster_name'] = salt.getPillar( |
| 126 | master, 'I@salt:master', '_param:cluster_name' |
| 127 | )['return'][0].values()[0] |
| 128 | def rcs_str_node = salt.getPillar( |
| 129 | master, 'I@salt:master', 'reclass:storage:node' |
| 130 | )['return'][0].values()[0] |
| 131 | |
| 132 | // set up Openstack env variables |
| 133 | if (rally.get('K8S_RALLY').toBoolean() == false) { |
| 134 | |
| 135 | platform['type'] = 'openstack' |
| 136 | platform['cmp_count'] = rcs_str_node.openstack_compute_rack01['repeat']['count'] |
| 137 | def rally_variables = [ |
| 138 | "floating_network=${rally.FLOATING_NETWORK}", |
| 139 | "rally_image=${rally.RALLY_IMAGE}", |
| 140 | "rally_flavor=${rally.RALLY_FLAVOR}", |
| 141 | "availability_zone=${rally.AVAILABILITY_ZONE}", |
| 142 | ] |
| 143 | |
| 144 | env_vars = validate._get_keystone_creds_v3(master) |
| 145 | if (!env_vars) { |
| 146 | env_vars = validate._get_keystone_creds_v2(master) |
| 147 | } |
| 148 | env_vars = env_vars + rally_variables |
| 149 | |
| 150 | } else { |
| 151 | // set up Kubernetes env variables get required secrets |
| 152 | platform['type'] = 'k8s' |
| 153 | platform['cmp_count'] = rcs_str_node.kubernetes_compute_rack01['repeat']['count'] |
| 154 | |
| 155 | def kubernetes = salt.getPillar( |
| 156 | master, 'I@kubernetes:master and *01*', 'kubernetes:master' |
| 157 | )['return'][0].values()[0] |
| 158 | |
| 159 | env_vars = [ |
| 160 | "KUBERNETES_HOST=http://${kubernetes.apiserver.vip_address}" + |
| 161 | ":${kubernetes.apiserver.insecure_port}", |
| 162 | "KUBERNETES_CERT_AUTH=${rallySecrets}/k8s-ca.crt", |
| 163 | "KUBERNETES_CLIENT_KEY=${rallySecrets}/k8s-client.key", |
| 164 | "KUBERNETES_CLIENT_CERT=${rallySecrets}/k8s-client.crt", |
| 165 | ] |
| 166 | |
| 167 | // get K8S certificates to manage cluster |
| 168 | def k8s_ca = salt.getFileContent( |
| 169 | master, 'I@kubernetes:master and *01*', '/etc/kubernetes/ssl/ca-kubernetes.crt' |
| 170 | ) |
| 171 | def k8s_client_key = salt.getFileContent( |
| 172 | master, 'I@kubernetes:master and *01*', '/etc/kubernetes/ssl/kubelet-client.key' |
| 173 | ) |
| 174 | def k8s_client_crt = salt.getFileContent( |
| 175 | master, 'I@kubernetes:master and *01*', '/etc/kubernetes/ssl/kubelet-client.crt' |
| 176 | ) |
| 177 | writeFile file: "${secrets}/k8s-ca.crt", text: k8s_ca |
| 178 | writeFile file: "${secrets}/k8s-client.key", text: k8s_client_key |
| 179 | writeFile file: "${secrets}/k8s-client.crt", text: k8s_client_crt |
| 180 | |
Tetiana Korchak | efa4f78 | 2017-08-25 10:22:29 -0700 | [diff] [blame] | 181 | } |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 182 | |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 183 | // get Stacklight data |
| 184 | if (rally.STACKLIGHT_RALLY.toBoolean() == true) { |
| 185 | platform['stacklight']['enabled'] = true |
| 186 | |
| 187 | def grafana = salt.getPillar( |
| 188 | master, 'I@grafana:client', 'grafana:client:server' |
| 189 | )['return'][0].values()[0] |
| 190 | |
| 191 | platform['stacklight']['grafanaPass'] = grafana['password'] |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 192 | } |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 193 | |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 194 | if (! rally.PARALLEL_PERFORMANCE.toBoolean()) { |
Dmitrii Kabanov | 6b9343e | 2017-08-30 15:30:21 -0700 | [diff] [blame] | 195 | |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 196 | // Define map with docker commands |
| 197 | def commands = validate.runRallyTests( |
| 198 | platform, rally.RALLY_SCENARIOS, |
Oleg Basov | 3d93f55 | 2019-03-27 01:01:20 +0100 | [diff] [blame] | 199 | rally.RALLY_SL_SCENARIOS, rally.RALLY_TASK_ARGS_FILE, |
| 200 | rally.RALLY_DB_CONN_STRING, tags, |
Oleg Basov | 2d291f7 | 2019-05-28 11:44:15 +0200 | [diff] [blame] | 201 | rally.RALLY_TRENDS.toBoolean(), rally.SKIP_LIST, generateReport |
Oleg Basov | 3d93f55 | 2019-03-27 01:01:20 +0100 | [diff] [blame] | 202 | ) |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 203 | def commands_list = commands.collectEntries{ [ (it.key) : { sh("${it.value}") } ] } |
Dmitrii Kabanov | a67e5a5 | 2017-08-14 16:31:11 -0700 | [diff] [blame] | 204 | |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 205 | configRun = [ |
| 206 | 'image': TEST_IMAGE, |
| 207 | 'baseRepoPreConfig': false, |
| 208 | 'dockerMaxCpus': 2, |
| 209 | 'dockerHostname': 'localhost', |
| 210 | 'dockerExtraOpts': [ |
| 211 | "--network=host", |
| 212 | "--entrypoint=/entrypoint.sh", |
| 213 | "-w ${rallyWorkdir}", |
| 214 | "-v ${workDir}/entrypoint.sh:/entrypoint.sh", |
| 215 | "-v ${pluginsDir}/:${rallyPluginsDir}", |
| 216 | "-v ${scenariosDir}/:${rallyScenariosDir}", |
| 217 | "-v ${artifacts}/:${rallyResultsDir}", |
| 218 | "-v ${secrets}/:${rallySecrets}", |
| 219 | ], |
| 220 | 'envOpts' : env_vars, |
| 221 | 'runCommands' : commands_list, |
| 222 | ] |
| 223 | common.infoMsg('Docker config:') |
| 224 | println configRun |
| 225 | common.infoMsg('Docker commands list:') |
| 226 | println commands |
Oleg Basov | 3d93f55 | 2019-03-27 01:01:20 +0100 | [diff] [blame] | 227 | |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 228 | } else { |
| 229 | |
| 230 | // Perform parallel testing of the components with Rally |
| 231 | def components = [ |
| 232 | Common: [], |
| 233 | Stacklight: [], |
| 234 | ] |
| 235 | |
| 236 | // get list of directories inside scenarios path |
| 237 | def scenPath = "${scenariosDir}/${rally.RALLY_SCENARIOS}" |
| 238 | def mainComponents = sh( |
| 239 | script: "find ${scenPath} -maxdepth 1 -mindepth 1 -type d -exec basename {} \\;", |
| 240 | returnStdout: true, |
| 241 | ).trim() |
| 242 | if (! mainComponents) { |
| 243 | error( |
| 244 | "No directories found inside RALLY_SCENARIOS ${rally.RALLY_SCENARIOS}\n" + |
| 245 | "Either set PARALLEL_PERFORMANCE=false or populate ${rally.RALLY_SCENARIOS} " + |
| 246 | "with component directories which include corresponding scenarios" |
| 247 | ) |
| 248 | } |
| 249 | components['Common'].addAll(mainComponents.split('\n')) |
| 250 | common.infoMsg( "Adding for parallel execution sub dirs found in " + |
| 251 | "RALLY_SCENARIOS (${rally.RALLY_SCENARIOS}):" |
| 252 | ) |
| 253 | print mainComponents |
| 254 | |
| 255 | if (rally.STACKLIGHT_RALLY.toBoolean() == true) { |
| 256 | def slScenPath = "${scenariosDir}/${rally.RALLY_SL_SCENARIOS}" |
| 257 | def slComponents = sh( |
| 258 | script: "find ${slScenPath} -maxdepth 1 -mindepth 1 -type d -exec basename {} \\;", |
| 259 | returnStdout: true, |
| 260 | ).trim() |
| 261 | if (! slComponents) { |
| 262 | error( |
| 263 | "No directories found inside RALLY_SCENARIOS ${rally.RALLY_SL_SCENARIOS}\n" + |
| 264 | "Either set PARALLEL_PERFORMANCE=false or populate ${rally.RALLY_SL_SCENARIOS} " + |
| 265 | "with component directories which include corresponding scenarios" |
| 266 | ) |
| 267 | } |
| 268 | components['Stacklight'].addAll(slComponents.split('\n')) |
| 269 | common.infoMsg( "Adding for parallel execution sub dirs found in " + |
| 270 | "RALLY_SL_SCENARIOS (${rally.RALLY_SL_SCENARIOS}):" |
| 271 | ) |
| 272 | print slComponents |
| 273 | } |
| 274 | |
| 275 | // build up a map with tasks for parallel execution |
| 276 | def allComponents = components.values().flatten() |
| 277 | for (int i=0; i < allComponents.size(); i++) { |
| 278 | // randomize run so we don't bump each other at the startup |
| 279 | // also we need to let first thread create rally deployment |
| 280 | // so all the rest rally threads can use it after |
| 281 | def sleepSeconds = 15 * i |
| 282 | |
| 283 | def task = allComponents[i] |
| 284 | def task_name = 'rally_' + task |
| 285 | def curComponent = components.find { task in it.value }.key |
| 286 | // inherit platform common data |
| 287 | def curPlatform = platform |
| 288 | |
| 289 | // setup scenarios and stacklight switch per component |
| 290 | def commonScens = "${rally.RALLY_SCENARIOS}/${task}" |
| 291 | def stacklightScens = "${rally.RALLY_SL_SCENARIOS}/${task}" |
| 292 | |
| 293 | switch (curComponent) { |
| 294 | case 'Common': |
| 295 | stacklightScens = '' |
| 296 | curPlatform['stacklight']['enabled'] = false |
| 297 | break |
| 298 | case 'Stacklight': |
| 299 | commonScens = '' |
| 300 | curPlatform['stacklight']['enabled'] = true |
| 301 | break |
| 302 | } |
| 303 | |
| 304 | def curCommands = validate.runRallyTests( |
| 305 | curPlatform, commonScens, |
| 306 | stacklightScens, rally.RALLY_TASK_ARGS_FILE, |
| 307 | rally.RALLY_DB_CONN_STRING, tags, |
Oleg Basov | 2d291f7 | 2019-05-28 11:44:15 +0200 | [diff] [blame] | 308 | rally.RALLY_TRENDS.toBoolean(), rally.SKIP_LIST, |
| 309 | generateReport |
Oleg Basov | 382613a | 2019-04-02 19:01:15 +0200 | [diff] [blame] | 310 | ) |
| 311 | |
| 312 | // copy required files for the current task |
| 313 | def taskWorkDir = "${env.WORKSPACE}/rally_" + task |
| 314 | def taskPluginsDir = "${taskWorkDir}/rally-plugins" |
| 315 | def taskScenariosDir = "${taskWorkDir}/rally-scenarios" |
| 316 | def taskArtifacts = "${taskWorkDir}/validation_artifacts" |
| 317 | def taskSecrets = "${taskWorkDir}/secrets" |
| 318 | sh "rm -rf ${taskWorkDir} || true" |
| 319 | sh "cp -ra ${workDir} ${taskWorkDir}" |
| 320 | |
| 321 | def curCommandsList = curCommands.collectEntries{ [ (it.key) : { sh("${it.value}") } ] } |
| 322 | def curConfigRun = [ |
| 323 | 'image': TEST_IMAGE, |
| 324 | 'baseRepoPreConfig': false, |
| 325 | 'dockerMaxCpus': 2, |
| 326 | 'dockerHostname': 'localhost', |
| 327 | 'dockerExtraOpts': [ |
| 328 | "--network=host", |
| 329 | "--entrypoint=/entrypoint.sh", |
| 330 | "-w ${rallyWorkdir}", |
| 331 | "-v ${taskWorkDir}/entrypoint.sh:/entrypoint.sh", |
| 332 | "-v ${taskPluginsDir}/:${rallyPluginsDir}", |
| 333 | "-v ${taskScenariosDir}/:${rallyScenariosDir}", |
| 334 | "-v ${taskArtifacts}/:${rallyResultsDir}", |
| 335 | "-v ${taskSecrets}/:${rallySecrets}", |
| 336 | ], |
| 337 | 'envOpts' : env_vars, |
| 338 | 'runCommands' : curCommandsList, |
| 339 | ] |
| 340 | |
| 341 | tasksParallel['rally_' + task] = { |
| 342 | sleep sleepSeconds |
| 343 | common.infoMsg("Docker config for task $task") |
| 344 | println curConfigRun |
| 345 | common.infoMsg("Docker commands list for task $task") |
| 346 | println curCommands |
| 347 | parallelResults[task_name] = salt_testing.setupDockerAndTest(curConfigRun) |
| 348 | } |
| 349 | } |
| 350 | } |
| 351 | } |
| 352 | |
| 353 | stage('Run Rally tests') { |
| 354 | |
| 355 | def dockerStatuses = [:] |
| 356 | |
| 357 | // start tests in Docker |
| 358 | if (! rally.PARALLEL_PERFORMANCE.toBoolean()) { |
| 359 | testResult = salt_testing.setupDockerAndTest(configRun) |
| 360 | dockerStatuses['rally'] = (testResult) ? 'OK' : 'FAILED' |
| 361 | } else { |
| 362 | common.infoMsg('Jobs to run in threads: ' + tasksParallel.keySet().join(' ')) |
| 363 | parallel tasksParallel |
| 364 | parallelResults.each { task -> |
| 365 | dockerStatuses[task.key] = (task.value) ? 'OK' : 'FAILED' |
| 366 | } |
| 367 | } |
| 368 | // safely archiving all possible results |
| 369 | dockerStatuses.each { task -> |
| 370 | print "Collecting results for ${task.key} (docker status = '${task.value}')" |
| 371 | try { |
| 372 | archiveArtifacts artifacts: "${task.key}/validation_artifacts/*" |
| 373 | } catch (Throwable e) { |
| 374 | print 'failed to get artifacts' |
| 375 | } |
| 376 | } |
| 377 | // setting final job status |
| 378 | def failed = dockerStatuses.findAll { it.value == 'FAILED' } |
| 379 | if (failed.size() == dockerStatuses.size()) { |
| 380 | currentBuild.result = 'FAILURE' |
| 381 | } else if (dockerStatuses.find { it.value != 'OK' }) { |
| 382 | currentBuild.result = 'UNSTABLE' |
| 383 | } |
| 384 | } |
| 385 | |
| 386 | stage('Clean env') { |
| 387 | // remove secrets |
| 388 | sh 'find ./ -type d -name secrets -exec rm -rf \\\"{}\\\" \\; || true' |
Tetiana Korchak | efa4f78 | 2017-08-25 10:22:29 -0700 | [diff] [blame] | 389 | } |
Petr Lomakin | e700ffd | 2017-08-01 10:53:15 -0700 | [diff] [blame] | 390 | } |
| 391 | } |