| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 1 | package com.mirantis.system_qa | 
|  | 2 |  | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 3 | import groovy.xml.XmlUtil | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 4 |  | 
| Dennis Dmitriev | 70cefed | 2018-09-17 15:41:35 +0300 | [diff] [blame^] | 5 | def run_sh(String cmd) { | 
|  | 6 | // run shell script without catching any output | 
|  | 7 | def common = new com.mirantis.mk.Common() | 
|  | 8 | common.printMsg("Run shell command:\n" + cmd, "blue") | 
|  | 9 | def VENV_PATH='/home/jenkins/fuel-devops30' | 
|  | 10 | script = """\ | 
|  | 11 | set -ex; | 
|  | 12 | . ${VENV_PATH}/bin/activate; | 
|  | 13 | bash -c '${cmd.stripIndent()}' | 
|  | 14 | """ | 
|  | 15 | return sh(script: script) | 
|  | 16 | } | 
|  | 17 |  | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 18 | def run_cmd(String cmd, Boolean returnStdout=false) { | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 19 | def common = new com.mirantis.mk.Common() | 
|  | 20 | common.printMsg("Run shell command:\n" + cmd, "blue") | 
|  | 21 | def VENV_PATH='/home/jenkins/fuel-devops30' | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 22 | def stderr_path = "/tmp/${JOB_NAME}_${BUILD_NUMBER}_stderr.log" | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 23 | script = """\ | 
|  | 24 | set +x; | 
|  | 25 | echo 'activate python virtualenv ${VENV_PATH}'; | 
|  | 26 | . ${VENV_PATH}/bin/activate; | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 27 | bash -c 'set -ex; set -ex; ${cmd.stripIndent()}' 2>${stderr_path} | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 28 | """ | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 29 | def result | 
|  | 30 | try { | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 31 | return sh(script: script, returnStdout: returnStdout) | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 32 | } catch (e) { | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 33 | def stderr = readFile("${stderr_path}") | 
|  | 34 | def error_message = e.message + "\n<<<<<< STDERR: >>>>>>\n" + stderr | 
|  | 35 | throw new Exception(error_message) | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 36 | } finally { | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 37 | sh(script: "rm ${stderr_path} || true") | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 38 | } | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 39 | } | 
|  | 40 |  | 
|  | 41 | def run_cmd_stdout(cmd) { | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 42 | return run_cmd(cmd, true) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 43 | } | 
|  | 44 |  | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 45 | def build_pipeline_job(job_name, parameters) { | 
|  | 46 | //Build a job, grab the results if failed and use the results in exception | 
|  | 47 | def common = new com.mirantis.mk.Common() | 
|  | 48 | common.printMsg("Start building job '${job_name}' with parameters:", "purple") | 
|  | 49 | common.prettyPrint(parameters) | 
|  | 50 |  | 
|  | 51 | def job_info = build job: "${job_name}", | 
|  | 52 | parameters: parameters, | 
|  | 53 | propagate: false | 
|  | 54 |  | 
|  | 55 | if (job_info.getResult() != "SUCCESS") { | 
|  | 56 | currentBuild.result = job_info.getResult() | 
|  | 57 | def build_number = job_info.getNumber() | 
|  | 58 | common.printMsg("Job '${job_name}' failed, getting details", "red") | 
|  | 59 | def workflow_details=run_cmd_stdout("""\ | 
|  | 60 | export JOB_NAME=${job_name} | 
|  | 61 | export BUILD_NUMBER=${build_number} | 
|  | 62 | python ./tcp_tests/utils/get_jenkins_job_stages.py | 
|  | 63 | """) | 
|  | 64 | throw new Exception(workflow_details) | 
|  | 65 | } | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | def build_shell_job(job_name, parameters, junit_report_filename=null, junit_report_source_dir='**/') { | 
|  | 69 | //Build a job, grab the results if failed and use the results in exception | 
|  | 70 | //junit_report_filename: if not null, try to copy this JUnit report first from remote job | 
|  | 71 | def common = new com.mirantis.mk.Common() | 
|  | 72 | common.printMsg("Start building job '${job_name}' with parameters:", "purple") | 
|  | 73 | common.prettyPrint(parameters) | 
|  | 74 |  | 
|  | 75 | def job_info = build job: "${job_name}", | 
|  | 76 | parameters: parameters, | 
|  | 77 | propagate: false | 
|  | 78 |  | 
|  | 79 | if (job_info.getResult() != "SUCCESS") { | 
|  | 80 | def build_status = job_info.getResult() | 
|  | 81 | def build_number = job_info.getNumber() | 
|  | 82 | def build_url = job_info.getAbsoluteUrl() | 
|  | 83 | def job_url = "${build_url}" | 
|  | 84 | currentBuild.result = build_status | 
|  | 85 | if (junit_report_filename) { | 
|  | 86 | common.printMsg("Job '${job_url}' failed with status ${build_status}, getting details", "red") | 
|  | 87 | step($class: 'hudson.plugins.copyartifact.CopyArtifact', | 
|  | 88 | projectName: job_name, | 
|  | 89 | selector: specific("${build_number}"), | 
|  | 90 | filter: "${junit_report_source_dir}/${junit_report_filename}", | 
|  | 91 | target: '.', | 
|  | 92 | flatten: true, | 
|  | 93 | fingerprintArtifacts: true) | 
|  | 94 |  | 
|  | 95 | def String junit_report_xml = readFile("${junit_report_filename}") | 
|  | 96 | def String junit_report_xml_pretty = new XmlUtil().serialize(junit_report_xml) | 
| Dennis Dmitriev | 3f9329c | 2018-08-30 18:17:49 +0300 | [diff] [blame] | 97 | // Replace '<' and '>' to '<' and '>' to avoid conflicts between xml tags in the message and JUnit report | 
|  | 98 | def String junit_report_xml_filtered = junit_report_xml_pretty.replaceAll("<","<").replaceAll(">", ">") | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 99 | def String msg = "Job '${job_url}' failed with status ${build_status}, JUnit report:\n" | 
| Dennis Dmitriev | 3966608 | 2018-08-29 15:30:45 +0300 | [diff] [blame] | 100 | throw new Exception(msg + junit_report_xml_filtered) | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 101 | } else { | 
|  | 102 | throw new Exception("Job '${job_url}' failed with status ${build_status}, please check the console output.") | 
|  | 103 | } | 
|  | 104 | } | 
|  | 105 | } | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 106 |  | 
|  | 107 | def prepare_working_dir() { | 
|  | 108 | println "Clean the working directory ${env.WORKSPACE}" | 
|  | 109 | deleteDir() | 
|  | 110 |  | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 111 | // do not fail if environment doesn't exists | 
|  | 112 | println "Remove environment ${ENV_NAME}" | 
|  | 113 | run_cmd("""\ | 
|  | 114 | dos.py erase ${ENV_NAME} || true | 
|  | 115 | """) | 
|  | 116 | println "Remove config drive ISO" | 
|  | 117 | run_cmd("""\ | 
|  | 118 | rm /home/jenkins/images/${CFG01_CONFIG_IMAGE_NAME} || true | 
|  | 119 | """) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 120 |  | 
|  | 121 | run_cmd("""\ | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 122 | git clone https://github.com/Mirantis/tcp-qa.git ${env.WORKSPACE} | 
|  | 123 | if [ -n "$TCP_QA_REFS" ]; then | 
|  | 124 | set -e | 
|  | 125 | git fetch https://review.gerrithub.io/Mirantis/tcp-qa $TCP_QA_REFS && git checkout FETCH_HEAD || exit \$? | 
|  | 126 | fi | 
|  | 127 | pip install --upgrade --upgrade-strategy=only-if-needed -r tcp_tests/requirements.txt | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 128 | """) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 129 | } | 
|  | 130 |  | 
| Dennis Dmitriev | 70cefed | 2018-09-17 15:41:35 +0300 | [diff] [blame^] | 131 | def update_working_dir() { | 
|  | 132 | // Use to fetch a patchset from gerrit to the working dir | 
|  | 133 | run_cmd("""\ | 
|  | 134 | if [ -n "$TCP_QA_REFS" ]; then | 
|  | 135 | set -e | 
|  | 136 | git fetch https://review.gerrithub.io/Mirantis/tcp-qa $TCP_QA_REFS && git checkout FETCH_HEAD || exit \$? | 
|  | 137 | fi | 
|  | 138 | pip install -r tcp_tests/requirements.txt | 
|  | 139 | """) | 
|  | 140 | } | 
|  | 141 |  | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 142 | def swarm_bootstrap_salt_cluster_devops() { | 
|  | 143 | def common = new com.mirantis.mk.Common() | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 144 | def cookiecutter_template_commit = env.COOKIECUTTER_TEMPLATE_COMMIT ?: env.MCP_VERSION | 
|  | 145 | def salt_models_system_commit = env.SALT_MODELS_SYSTEM_COMMIT ?: env.MCP_VERSION | 
|  | 146 | def tcp_qa_refs = env.TCP_QA_REFS ?: '' | 
|  | 147 | def mk_pipelines_ref = env.MK_PIPELINES_REF ?: '' | 
|  | 148 | def pipeline_library_ref = env.PIPELINE_LIBRARY_REF ?: '' | 
|  | 149 | def cookiecutter_ref_change = env.COOKIECUTTER_REF_CHANGE ?: '' | 
|  | 150 | def environment_template_ref_change = env.ENVIRONMENT_TEMPLATE_REF_CHANGE ?: '' | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 151 | def parameters = [ | 
|  | 152 | string(name: 'PARENT_NODE_NAME', value: "${NODE_NAME}"), | 
|  | 153 | string(name: 'PARENT_WORKSPACE', value: pwd()), | 
|  | 154 | string(name: 'LAB_CONFIG_NAME', value: "${LAB_CONFIG_NAME}"), | 
|  | 155 | string(name: 'ENV_NAME', value: "${ENV_NAME}"), | 
|  | 156 | string(name: 'MCP_VERSION', value: "${MCP_VERSION}"), | 
|  | 157 | string(name: 'MCP_IMAGE_PATH1604', value: "${MCP_IMAGE_PATH1604}"), | 
|  | 158 | string(name: 'IMAGE_PATH_CFG01_DAY01', value: "${IMAGE_PATH_CFG01_DAY01}"), | 
|  | 159 | string(name: 'CFG01_CONFIG_IMAGE_NAME', value: "${CFG01_CONFIG_IMAGE_NAME}"), | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 160 | string(name: 'TCP_QA_REFS', value: "${tcp_qa_refs}"), | 
|  | 161 | string(name: 'PIPELINE_LIBRARY_REF', value: "${pipeline_library_ref}"), | 
|  | 162 | string(name: 'MK_PIPELINES_REF', value: "${mk_pipelines_ref}"), | 
|  | 163 | string(name: 'COOKIECUTTER_TEMPLATE_COMMIT', value: "${cookiecutter_template_commit}"), | 
|  | 164 | string(name: 'SALT_MODELS_SYSTEM_COMMIT', value: "${salt_models_system_commit}"), | 
|  | 165 | string(name: 'COOKIECUTTER_REF_CHANGE', value: "${cookiecutter_ref_change}"), | 
|  | 166 | string(name: 'ENVIRONMENT_TEMPLATE_REF_CHANGE', value: "${environment_template_ref_change}"), | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 167 | booleanParam(name: 'SHUTDOWN_ENV_ON_TEARDOWN', value: false), | 
|  | 168 | ] | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 169 |  | 
|  | 170 | build_pipeline_job('swarm-bootstrap-salt-cluster-devops', parameters) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 171 | } | 
|  | 172 |  | 
|  | 173 | def swarm_deploy_cicd(String stack_to_install='core,cicd') { | 
|  | 174 | // Run openstack_deploy job on cfg01 Jenkins for specified stacks | 
|  | 175 | def common = new com.mirantis.mk.Common() | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 176 | def tcp_qa_refs = env.TCP_QA_REFS ?: '' | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 177 | def parameters = [ | 
|  | 178 | string(name: 'PARENT_NODE_NAME', value: "${NODE_NAME}"), | 
|  | 179 | string(name: 'PARENT_WORKSPACE', value: pwd()), | 
|  | 180 | string(name: 'ENV_NAME', value: "${ENV_NAME}"), | 
|  | 181 | string(name: 'STACK_INSTALL', value: stack_to_install), | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 182 | string(name: 'TCP_QA_REFS', value: "${tcp_qa_refs}"), | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 183 | booleanParam(name: 'SHUTDOWN_ENV_ON_TEARDOWN', value: false), | 
|  | 184 | ] | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 185 | build_pipeline_job('swarm-deploy-cicd', parameters) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 186 | } | 
|  | 187 |  | 
|  | 188 | def swarm_deploy_platform(String stack_to_install) { | 
|  | 189 | // Run openstack_deploy job on CICD Jenkins for specified stacks | 
|  | 190 | def common = new com.mirantis.mk.Common() | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 191 | def tcp_qa_refs = env.TCP_QA_REFS ?: '' | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 192 | def parameters = [ | 
|  | 193 | string(name: 'PARENT_NODE_NAME', value: "${NODE_NAME}"), | 
|  | 194 | string(name: 'PARENT_WORKSPACE', value: pwd()), | 
|  | 195 | string(name: 'ENV_NAME', value: "${ENV_NAME}"), | 
|  | 196 | string(name: 'STACK_INSTALL', value: stack_to_install), | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 197 | string(name: 'TCP_QA_REFS', value: "${tcp_qa_refs}"), | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 198 | booleanParam(name: 'SHUTDOWN_ENV_ON_TEARDOWN', value: false), | 
|  | 199 | ] | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 200 | build_pipeline_job('swarm-deploy-platform', parameters) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 201 | } | 
|  | 202 |  | 
| Dennis Dmitriev | fde667f | 2018-07-23 16:26:50 +0300 | [diff] [blame] | 203 | def swarm_run_pytest(String passed_steps) { | 
|  | 204 | // Run pytest tests | 
|  | 205 | def common = new com.mirantis.mk.Common() | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 206 | def tcp_qa_refs = env.TCP_QA_REFS ?: '' | 
| Dennis Dmitriev | fde667f | 2018-07-23 16:26:50 +0300 | [diff] [blame] | 207 | def parameters = [ | 
|  | 208 | string(name: 'ENV_NAME', value: "${ENV_NAME}"), | 
|  | 209 | string(name: 'PASSED_STEPS', value: passed_steps), | 
|  | 210 | string(name: 'RUN_TEST_OPTS', value: "${RUN_TEST_OPTS}"), | 
|  | 211 | string(name: 'PARENT_NODE_NAME', value: "${NODE_NAME}"), | 
|  | 212 | string(name: 'PARENT_WORKSPACE', value: pwd()), | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 213 | string(name: 'TCP_QA_REFS', value: "${tcp_qa_refs}"), | 
| Dennis Dmitriev | fde667f | 2018-07-23 16:26:50 +0300 | [diff] [blame] | 214 | booleanParam(name: 'SHUTDOWN_ENV_ON_TEARDOWN', value: false), | 
|  | 215 | string(name: 'LAB_CONFIG_NAME', value: "${LAB_CONFIG_NAME}"), | 
|  | 216 | string(name: 'REPOSITORY_SUITE', value: "${MCP_VERSION}"), | 
|  | 217 | string(name: 'MCP_IMAGE_PATH1604', value: "${MCP_IMAGE_PATH1604}"), | 
|  | 218 | string(name: 'IMAGE_PATH_CFG01_DAY01', value: "${IMAGE_PATH_CFG01_DAY01}"), | 
|  | 219 | ] | 
|  | 220 | common.printMsg("Start building job 'swarm-run-pytest' with parameters:", "purple") | 
|  | 221 | common.prettyPrint(parameters) | 
|  | 222 | build job: 'swarm-run-pytest', | 
|  | 223 | parameters: parameters | 
|  | 224 | } | 
|  | 225 |  | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 226 | def swarm_testrail_report(String passed_steps) { | 
|  | 227 | // Run pytest tests | 
|  | 228 | def common = new com.mirantis.mk.Common() | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 229 | def tcp_qa_refs = env.TCP_QA_REFS ?: '' | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 230 | def parameters = [ | 
|  | 231 | string(name: 'ENV_NAME', value: "${ENV_NAME}"), | 
|  | 232 | string(name: 'MCP_VERSION', value: "${MCP_VERSION}"), | 
|  | 233 | string(name: 'PASSED_STEPS', value: passed_steps), | 
|  | 234 | string(name: 'PARENT_NODE_NAME', value: "${NODE_NAME}"), | 
|  | 235 | string(name: 'PARENT_WORKSPACE', value: pwd()), | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 236 | string(name: 'TCP_QA_REFS', value: "${tcp_qa_refs}"), | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 237 | ] | 
|  | 238 | common.printMsg("Start building job 'swarm-testrail-report' with parameters:", "purple") | 
|  | 239 | common.prettyPrint(parameters) | 
|  | 240 | build job: 'swarm-testrail-report', | 
|  | 241 | parameters: parameters | 
|  | 242 | } | 
|  | 243 |  | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 244 | def generate_cookied_model() { | 
|  | 245 | def common = new com.mirantis.mk.Common() | 
|  | 246 | // do not fail if environment doesn't exists | 
|  | 247 | def IPV4_NET_ADMIN=run_cmd_stdout("dos.py net-list ${ENV_NAME} | grep admin-pool01").trim().split().last() | 
|  | 248 | def IPV4_NET_CONTROL=run_cmd_stdout("dos.py net-list ${ENV_NAME} | grep private-pool01").trim().split().last() | 
|  | 249 | def IPV4_NET_TENANT=run_cmd_stdout("dos.py net-list ${ENV_NAME} | grep tenant-pool01").trim().split().last() | 
|  | 250 | def IPV4_NET_EXTERNAL=run_cmd_stdout("dos.py net-list ${ENV_NAME} | grep external-pool01").trim().split().last() | 
|  | 251 | println("IPV4_NET_ADMIN=" + IPV4_NET_ADMIN) | 
|  | 252 | println("IPV4_NET_CONTROL=" + IPV4_NET_CONTROL) | 
|  | 253 | println("IPV4_NET_TENANT=" + IPV4_NET_TENANT) | 
|  | 254 | println("IPV4_NET_EXTERNAL=" + IPV4_NET_EXTERNAL) | 
|  | 255 |  | 
|  | 256 | def cookiecuttertemplate_commit = env.COOKIECUTTER_TEMPLATE_COMMIT ?: env.MCP_VERSION | 
|  | 257 | def saltmodels_system_commit = env.SALT_MODELS_SYSTEM_COMMIT ?: env.MCP_VERSION | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 258 | def tcp_qa_refs = env.TCP_QA_REFS ?: '' | 
|  | 259 | def environment_template_ref_change = env.ENVIRONMENT_TEMPLATE_REF_CHANGE ?: '' | 
|  | 260 | def cookiecutter_ref_change = env.COOKIECUTTER_REF_CHANGE ?: '' | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 261 |  | 
|  | 262 | def parameters = [ | 
|  | 263 | string(name: 'LAB_CONTEXT_NAME', value: "${LAB_CONFIG_NAME}"), | 
|  | 264 | string(name: 'CLUSTER_NAME', value: "${LAB_CONFIG_NAME}"), | 
|  | 265 | string(name: 'DOMAIN_NAME', value: "${LAB_CONFIG_NAME}.local"), | 
|  | 266 | string(name: 'REPOSITORY_SUITE', value: "${env.MCP_VERSION}"), | 
|  | 267 | string(name: 'SALT_MODELS_SYSTEM_COMMIT', value: "${saltmodels_system_commit}"), | 
|  | 268 | string(name: 'COOKIECUTTER_TEMPLATE_COMMIT', value: "${cookiecuttertemplate_commit}"), | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 269 | string(name: 'COOKIECUTTER_REF_CHANGE', value: "${cookiecutter_ref_change}"), | 
|  | 270 | string(name: 'ENVIRONMENT_TEMPLATE_REF_CHANGE', value: "${environment_template_ref_change}"), | 
|  | 271 | string(name: 'TCP_QA_REVIEW', value: "${tcp_qa_refs}"), | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 272 | string(name: 'IPV4_NET_ADMIN', value: IPV4_NET_ADMIN), | 
|  | 273 | string(name: 'IPV4_NET_CONTROL', value: IPV4_NET_CONTROL), | 
|  | 274 | string(name: 'IPV4_NET_TENANT', value: IPV4_NET_TENANT), | 
|  | 275 | string(name: 'IPV4_NET_EXTERNAL', value: IPV4_NET_EXTERNAL), | 
|  | 276 | ] | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 277 |  | 
|  | 278 | build_shell_job('swarm-cookied-model-generator', parameters, "deploy_generate_model.xml") | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 279 | } | 
|  | 280 |  | 
|  | 281 | def generate_configdrive_iso() { | 
|  | 282 | def common = new com.mirantis.mk.Common() | 
|  | 283 | def SALT_MASTER_IP=run_cmd_stdout("""\ | 
|  | 284 | export ENV_NAME=${ENV_NAME} | 
|  | 285 | . ./tcp_tests/utils/env_salt | 
|  | 286 | echo \$SALT_MASTER_IP | 
|  | 287 | """).trim().split().last() | 
|  | 288 | println("SALT_MASTER_IP=" + SALT_MASTER_IP) | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 289 |  | 
|  | 290 | def mk_pipelines_ref = env.MK_PIPELINES_REF ?: '' | 
|  | 291 | def pipeline_library_ref = env.PIPELINE_LIBRARY_REF ?: '' | 
|  | 292 |  | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 293 | def parameters = [ | 
|  | 294 | string(name: 'CLUSTER_NAME', value: "${LAB_CONFIG_NAME}"), | 
|  | 295 | string(name: 'MODEL_URL', value: "http://cz8133.bud.mirantis.net:8098/${LAB_CONFIG_NAME}.git"), | 
|  | 296 | string(name: 'MODEL_URL_OBJECT_TYPE', value: "git"), | 
|  | 297 | booleanParam(name: 'DOWNLOAD_CONFIG_DRIVE', value: true), | 
|  | 298 | string(name: 'MCP_VERSION', value: "${MCP_VERSION}"), | 
|  | 299 | string(name: 'COMMON_SCRIPTS_COMMIT', value: "${MCP_VERSION}"), | 
|  | 300 | string(name: 'NODE_NAME', value: "${NODE_NAME}"), | 
|  | 301 | string(name: 'CONFIG_DRIVE_ISO_NAME', value: "${CFG01_CONFIG_IMAGE_NAME}"), | 
|  | 302 | string(name: 'SALT_MASTER_DEPLOY_IP', value: SALT_MASTER_IP), | 
|  | 303 | string(name: 'PIPELINE_REPO_URL', value: "https://github.com/Mirantis"), | 
|  | 304 | booleanParam(name: 'PIPELINES_FROM_ISO', value: true), | 
|  | 305 | string(name: 'MCP_SALT_REPO_URL', value: "http://apt.mirantis.com/xenial"), | 
|  | 306 | string(name: 'MCP_SALT_REPO_KEY', value: "http://apt.mirantis.com/public.gpg"), | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 307 | string(name: 'PIPELINE_LIBRARY_REF', value: "${pipeline_library_ref}"), | 
|  | 308 | string(name: 'MK_PIPELINES_REF', value: "${mk_pipelines_ref}"), | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 309 | ] | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 310 | build_pipeline_job('create-cfg-config-drive', parameters) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 311 | } | 
|  | 312 |  | 
|  | 313 | def run_job_on_day01_node(stack_to_install, timeout=1800) { | 
|  | 314 | // stack_to_install="core,cicd" | 
|  | 315 | def stack = "${stack_to_install}" | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 316 | try { | 
|  | 317 | run_cmd("""\ | 
|  | 318 | export ENV_NAME=${ENV_NAME} | 
|  | 319 | . ./tcp_tests/utils/env_salt | 
|  | 320 | . ./tcp_tests/utils/env_jenkins_day01 | 
|  | 321 | export JENKINS_BUILD_TIMEOUT=${timeout} | 
|  | 322 | JOB_PARAMETERS=\"{ | 
|  | 323 | \\\"SALT_MASTER_URL\\\": \\\"\${SALTAPI_URL}\\\", | 
|  | 324 | \\\"STACK_INSTALL\\\": \\\"${stack}\\\" | 
|  | 325 | }\" | 
|  | 326 | JOB_PREFIX="[ ${ENV_NAME}/{build_number}:${stack} {time} ] " | 
|  | 327 | python ./tcp_tests/utils/run_jenkins_job.py --verbose --job-name=deploy_openstack --job-parameters="\$JOB_PARAMETERS" --job-output-prefix="\$JOB_PREFIX" | 
|  | 328 | """) | 
|  | 329 | } catch (e) { | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 330 | def common = new com.mirantis.mk.Common() | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 331 | common.printMsg("Product job 'deploy_openstack' failed, getting details", "red") | 
|  | 332 | def workflow_details=run_cmd_stdout("""\ | 
|  | 333 | . ./tcp_tests/utils/env_salt | 
|  | 334 | . ./tcp_tests/utils/env_jenkins_day01 | 
|  | 335 | export JOB_NAME=deploy_openstack | 
|  | 336 | export BUILD_NUMBER=lastBuild | 
|  | 337 | python ./tcp_tests/utils/get_jenkins_job_stages.py | 
|  | 338 | """) | 
|  | 339 | throw new Exception(workflow_details) | 
|  | 340 | } | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 341 | } | 
|  | 342 |  | 
|  | 343 | def run_job_on_cicd_nodes(stack_to_install, timeout=1800) { | 
|  | 344 | // stack_to_install="k8s,calico,stacklight" | 
|  | 345 | def stack = "${stack_to_install}" | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 346 | try { | 
|  | 347 | run_cmd("""\ | 
|  | 348 | export ENV_NAME=${ENV_NAME} | 
|  | 349 | . ./tcp_tests/utils/env_salt | 
|  | 350 | . ./tcp_tests/utils/env_jenkins_cicd | 
|  | 351 | export JENKINS_BUILD_TIMEOUT=${timeout} | 
|  | 352 | JOB_PARAMETERS=\"{ | 
|  | 353 | \\\"SALT_MASTER_URL\\\": \\\"\${SALTAPI_URL}\\\", | 
|  | 354 | \\\"STACK_INSTALL\\\": \\\"${stack}\\\" | 
|  | 355 | }\" | 
|  | 356 | JOB_PREFIX="[ ${ENV_NAME}/{build_number}:${stack} {time} ] " | 
|  | 357 | python ./tcp_tests/utils/run_jenkins_job.py --verbose --job-name=deploy_openstack --job-parameters="\$JOB_PARAMETERS" --job-output-prefix="\$JOB_PREFIX" | 
|  | 358 | sleep 60  # Wait for IO calm down on cluster nodes | 
|  | 359 | """) | 
|  | 360 | } catch (e) { | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 361 | def common = new com.mirantis.mk.Common() | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 362 | common.printMsg("Product job 'deploy_openstack' failed, getting details", "red") | 
|  | 363 | def workflow_details=run_cmd_stdout("""\ | 
|  | 364 | . ./tcp_tests/utils/env_salt | 
|  | 365 | . ./tcp_tests/utils/env_jenkins_cicd | 
|  | 366 | export JOB_NAME=deploy_openstack | 
|  | 367 | export BUILD_NUMBER=lastBuild | 
|  | 368 | python ./tcp_tests/utils/get_jenkins_job_stages.py | 
|  | 369 | """) | 
|  | 370 | throw new Exception(workflow_details) | 
|  | 371 | } | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 372 | } | 
|  | 373 |  | 
|  | 374 | def sanity_check_component(stack) { | 
|  | 375 | // Run sanity check for the component ${stack}. | 
|  | 376 | // Result will be stored in JUnit XML file deploy_${stack}.xml | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 377 | try { | 
|  | 378 | run_cmd("""\ | 
|  | 379 | py.test --junit-xml=deploy_${stack}.xml -m check_${stack} | 
|  | 380 | """) | 
|  | 381 | } catch (e) { | 
|  | 382 | def String junit_report_xml = readFile("deploy_${stack}.xml") | 
|  | 383 | def String junit_report_xml_pretty = new XmlUtil().serialize(junit_report_xml) | 
|  | 384 | def String msg = "Sanity check for '${stack}' failed, JUnit report:\n" | 
|  | 385 | throw new Exception(msg + junit_report_xml_pretty) | 
|  | 386 | } | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 387 | } | 
|  | 388 |  | 
|  | 389 | def devops_snapshot(stack) { | 
|  | 390 | // Make the snapshot with name "${stack}_deployed" | 
|  | 391 | // for all VMs in the environment. | 
|  | 392 | // If oslo_config INI file ${ENV_NAME}_salt_deployed.ini exists, | 
|  | 393 | // then make a copy for the created snapshot to allow the system | 
|  | 394 | // tests to revert this snapshot along with the metadata from the INI file. | 
|  | 395 | run_cmd("""\ | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 396 | set -ex | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 397 | dos.py suspend ${ENV_NAME} | 
|  | 398 | dos.py snapshot ${ENV_NAME} ${stack}_deployed | 
|  | 399 | dos.py resume ${ENV_NAME} | 
| Dennis Dmitriev | 1fed666 | 2018-07-27 18:22:13 +0300 | [diff] [blame] | 400 | sleep 20    # Wait for I/O on the host calms down | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 401 |  | 
|  | 402 | CFG01_NAME=\$(dos.py show-resources ${ENV_NAME} | grep ^cfg01 | cut -d" " -f1) | 
|  | 403 | dos.py time-sync ${ENV_NAME} --skip-sync \${CFG01_NAME} | 
|  | 404 |  | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 405 | if [ -f \$(pwd)/${ENV_NAME}_salt_deployed.ini ]; then | 
|  | 406 | cp \$(pwd)/${ENV_NAME}_salt_deployed.ini \$(pwd)/${ENV_NAME}_${stack}_deployed.ini | 
|  | 407 | fi | 
| Dennis Dmitriev | 8df3544 | 2018-07-31 08:40:20 +0300 | [diff] [blame] | 408 | """) | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 409 | } | 
|  | 410 |  | 
| Dennis Dmitriev | fde667f | 2018-07-23 16:26:50 +0300 | [diff] [blame] | 411 | def get_steps_list(steps) { | 
|  | 412 | // Make a list from comma separated string | 
|  | 413 | return steps.split(',').collect { it.split(':')[0] } | 
|  | 414 | } | 
|  | 415 |  | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 416 | def create_xml_report(String filename, String classname, String name, String status='success', String status_message='', String text='', String stdout='', String stderr='') { | 
|  | 417 | // <filename> is name of the XML report file that will be created | 
|  | 418 | // <status> is one of the 'success', 'skipped', 'failure' or 'error' | 
|  | 419 | // 'error' status is assumed as 'Blocker' in TestRail reporter | 
| Dennis Dmitriev | 3966608 | 2018-08-29 15:30:45 +0300 | [diff] [blame] | 420 | def script = """\ | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 421 | <?xml version=\"1.0\" encoding=\"utf-8\"?> | 
|  | 422 | <testsuite> | 
|  | 423 | <testcase classname=\"${classname}\" name=\"${name}\" time=\"0\"> | 
|  | 424 | <${status} message=\"${status_message}\">${text}</${status}> | 
|  | 425 | <system-out>${stdout}</system-out> | 
|  | 426 | <system-err>${stderr}</system-err> | 
|  | 427 | </testcase> | 
|  | 428 | </testsuite> | 
| Dennis Dmitriev | 3966608 | 2018-08-29 15:30:45 +0300 | [diff] [blame] | 429 | """ | 
|  | 430 | writeFile(file: filename, text: script, encoding: "UTF-8") | 
| Dennis Dmitriev | b3b3749 | 2018-07-08 21:23:00 +0300 | [diff] [blame] | 431 | } | 
|  | 432 |  | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 433 | def upload_results_to_testrail(report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options=[]) { | 
|  | 434 | def venvPath = '/home/jenkins/venv_testrail_reporter' | 
|  | 435 | def testPlanDesc = env.ENV_NAME | 
|  | 436 | def testrailURL = "https://mirantis.testrail.com" | 
|  | 437 | def testrailProject = "Mirantis Cloud Platform" | 
|  | 438 | def testPlanName = "[MCP-Q2]System-${MCP_VERSION}-${new Date().format('yyyy-MM-dd')}" | 
|  | 439 | def testrailMilestone = "MCP1.1" | 
|  | 440 | def jobURL = env.BUILD_URL | 
|  | 441 |  | 
|  | 442 | def reporterOptions = [ | 
|  | 443 | "--verbose", | 
|  | 444 | "--env-description \"${testPlanDesc}\"", | 
|  | 445 | "--testrail-run-update", | 
|  | 446 | "--testrail-url \"${testrailURL}\"", | 
|  | 447 | "--testrail-user \"\${TESTRAIL_USER}\"", | 
|  | 448 | "--testrail-password \"\${TESTRAIL_PASSWORD}\"", | 
|  | 449 | "--testrail-project \"${testrailProject}\"", | 
|  | 450 | "--testrail-plan-name \"${testPlanName}\"", | 
|  | 451 | "--testrail-milestone \"${testrailMilestone}\"", | 
|  | 452 | "--testrail-suite \"${testSuiteName}\"", | 
|  | 453 | "--xunit-name-template \"${methodname}\"", | 
|  | 454 | "--testrail-name-template \"${testrail_name_template}\"", | 
|  | 455 | "--test-results-link \"${jobURL}\"", | 
|  | 456 | ] + reporter_extra_options | 
|  | 457 |  | 
|  | 458 | def script = """ | 
|  | 459 | . ${venvPath}/bin/activate | 
|  | 460 | set -ex | 
| Dennis Dmitriev | ee5ef23 | 2018-08-31 13:53:18 +0300 | [diff] [blame] | 461 | report ${reporterOptions.join(' ')} ${report_name} | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 462 | """ | 
|  | 463 |  | 
|  | 464 | def testrail_cred_id = params.TESTRAIL_CRED ?: 'testrail_system_tests' | 
|  | 465 |  | 
|  | 466 | withCredentials([ | 
|  | 467 | [$class          : 'UsernamePasswordMultiBinding', | 
|  | 468 | credentialsId   : testrail_cred_id, | 
|  | 469 | passwordVariable: 'TESTRAIL_PASSWORD', | 
|  | 470 | usernameVariable: 'TESTRAIL_USER'] | 
|  | 471 | ]) { | 
|  | 472 | return run_cmd(script) | 
|  | 473 | } | 
|  | 474 | } | 
|  | 475 |  | 
|  | 476 |  | 
|  | 477 | def create_deploy_result_report(deploy_expected_stacks, result, text) { | 
|  | 478 | def STATUS_MAP = ['SUCCESS': 'success', 'FAILURE': 'failure', 'UNSTABLE': 'failure', 'ABORTED': 'error'] | 
|  | 479 | def classname = "Deploy" | 
|  | 480 | def name = "deployment_${ENV_NAME}" | 
| Dennis Dmitriev | 3966608 | 2018-08-29 15:30:45 +0300 | [diff] [blame] | 481 | def filename = "${name}.xml" | 
| Dennis Dmitriev | e4b831b | 2018-08-15 17:16:10 +0300 | [diff] [blame] | 482 | def status = STATUS_MAP[result ?: 'FAILURE']   // currentBuild.result *must* be set at the finish of the try/catch | 
|  | 483 | create_xml_report(filename, classname, name, status, "Deploy components: ${deploy_expected_stacks}", text, '', '') | 
| Dennis Dmitriev | 27a9679 | 2018-07-30 07:52:03 +0300 | [diff] [blame] | 484 | } |