blob: 1147970edf59a4a43c5f25519f1aa2c4b482430e [file] [log] [blame]
Petr Lomakin47fee0a2017-08-01 10:46:05 -07001package com.mirantis.mcp
2
3/**
4 *
5 * Tests providing functions
6 *
7 */
8
9/**
10 * Configure docker image with tests
11 *
12 * @param dockerImageLink Docker image link with rally and tempest
13 * @param target Host to run tests
14 * @param output_dir Directory for results
Dmitrii Kabanov65fdc282017-09-29 10:53:08 -070015 * @param ext_variables The set of external variables
Petr Lomakin47fee0a2017-08-01 10:46:05 -070016 */
Dmitrii Kabanov65fdc282017-09-29 10:53:08 -070017def runContainerConfiguration(master, dockerImageLink, target, output_dir, ext_variables){
Petr Lomakin47fee0a2017-08-01 10:46:05 -070018 def salt = new com.mirantis.mk.Salt()
19 def common = new com.mirantis.mk.Common()
20 def output_file = 'docker.log'
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -070021 def nodes = getNodeList(master)
22 def nodes_hw = getNodeList(master, 'G@virtual:physical')
Sam Stoelinga28bdb722017-09-25 18:29:59 -070023 def _pillar = salt.getPillar(master, 'I@keystone:server', 'keystone:server')
24 def keystone = _pillar['return'][0].values()[0]
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -070025 def ssh_key = getFileContent(master, 'I@salt:master', '/root/.ssh/id_rsa')
Petr Lomakin47fee0a2017-08-01 10:46:05 -070026 salt.cmdRun(master, target, "docker run -tid --net=host --name=qa_tools " +
Dmitrii Kabanov65fdc282017-09-29 10:53:08 -070027 " ${ext_variables} " +
Petr Lomakin47fee0a2017-08-01 10:46:05 -070028 "-e tempest_version=15.0.0 -e OS_USERNAME=${keystone.admin_name} " +
29 "-e OS_PASSWORD=${keystone.admin_password} -e OS_TENANT_NAME=${keystone.admin_tenant} " +
30 "-e OS_AUTH_URL=http://${keystone.bind.private_address}:${keystone.bind.private_port}/v2.0 " +
31 "-e OS_REGION_NAME=${keystone.region} -e OS_ENDPOINT_TYPE=admin ${dockerImageLink} /bin/bash")
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -070032 salt.cmdRun(master, target, "docker exec qa_tools bash -c \"sudo mkdir -p /root/.ssh; " +
33 "echo \'${ssh_key}\' | sudo tee /root/.ssh/id_rsa > /dev/null; " +
34 "sudo chmod 700 /root/.ssh; sudo chmod 600 /root/.ssh/id_rsa; " +
35 "echo -e '${nodes}' > nodes.json; echo -e '${nodes_hw}' > nodes_hw.json\"")
Petr Lomakin47fee0a2017-08-01 10:46:05 -070036 salt.cmdRun(master, target, "docker exec qa_tools bash -c /opt/devops-qa-tools/deployment/configure.sh > ${output_file}")
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -070037 def file_content = getFileContent(master, target, output_file)
Petr Lomakin47fee0a2017-08-01 10:46:05 -070038 writeFile file: "${output_dir}${output_file}", text: file_content
39}
40
41/**
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -070042 * Get file content. Extended version
43 *
44 * @param target Compound target (should target only one host)
45 * @param file File path to read
46 * @return The content of the file
47 */
48def getFileContent(master, target, file) {
49 def salt = new com.mirantis.mk.Salt()
50 def _result = null
51 def file_content = null
52 def result = salt.cmdRun(master, target, "if [ \$(wc -c <${file}) -gt 1048575 ]; then echo 1; fi", false, null, false)
53 def large_file = result['return'][0].values()[0]
54 if ( large_file ) {
55 salt.cmdRun(master, target, "split -b 1MB -d ${file} ${file}__", false, null, false)
56 def list_files = salt.cmdRun(master, target, "ls ${file}__*", false, null, false)
57 for ( item in list_files['return'][0].values()[0].tokenize() ) {
58 _result = salt.cmdRun(master, target, "cat ${item}", false, null, false)
59 file_content = file_content + _result['return'][0].values()[0].replaceAll('Salt command execution success','')
60 }
61 salt.cmdRun(master, target, "rm ${file}__*", false, null, false)
62 return file_content
63 } else {
64 _result = salt.cmdRun(master, target, "cat ${file}", false, null, false)
65 return _result['return'][0].values()[0].replaceAll('Salt command execution success','')
66 }
67}
68
69/**
70 * Get reclass value
71 *
72 * @param target The host for which the values will be provided
73 * @param filter Parameters divided by dots
74 * @return The pillar data
75 */
76def getReclassValue(master, target, filter) {
77 def common = new com.mirantis.mk.Common()
78 def salt = new com.mirantis.mk.Salt()
79 def items = filter.tokenize('.')
80 def _result = salt.cmdRun(master, 'I@salt:master', "reclass-salt -o json -p ${target} | " +
81 "python -c 'import json,sys; print(json.dumps(json.loads(sys.stdin.read()).get(\"${items[0]}\")))'", false, null, false)
82 _result = common.parseJSON(_result['return'][0].values()[0])
83 for ( item in items.tail()) {
84 if ( _result ) {
85 _result = _result["${item}"]
86 }
87 }
88 return _result
89}
90
91/**
92 * Create list of nodes in JSON format.
93 *
94 * @param filter The Salt's matcher
95 * @return JSON list of nodes
96 */
97def getNodeList(master, filter = null) {
98 def salt = new com.mirantis.mk.Salt()
99 def common = new com.mirantis.mk.Common()
100 def builder = new groovy.json.JsonBuilder()
101 def nodes = []
102 def n_counter = 0
103 def filtered_list = null
104 def controllers = salt.getMinions(master, 'I@nova:controller')
105 def hw_nodes = salt.getMinions(master, 'G@virtual:physical')
106 def json = builder (ip: '', roles: '', id: '', network_data: [ builder (name: 'management', ip: '')])
107 if ( filter ) {
108 filtered_list = salt.getMinions(master, filter)
109 filtered_list.addAll(controllers)
110 }
111 def _result = salt.cmdRun(master, 'I@salt:master', "reclass-salt -o json -t", false, null, false)
112 def reclass_top = common.parseJSON(_result['return'][0].values()[0])
113 for (item in reclass_top.base) {
114 if ( filtered_list ) {
115 if ( ! filtered_list.contains(item.getKey()) ) {
116 continue
117 }
118 }
119 n_counter += 1
120 json.id = n_counter.toString()
121 json.ip = getReclassValue(master, item.getKey(), '_param.linux_single_interface.address')
122 json.network_data[0].ip = json.ip
123 json.roles = item.getKey().tokenize('.')[0]
124 if ( controllers.contains(item.getKey()) ) {
125 json.roles = "${json.roles}, controller"
126 }
127 if ( hw_nodes.contains(item.getKey()) ) {
128 json.roles = "${json.roles}, hw_node"
129 }
130 def node = builder.toPrettyString().replace('"', '\\"')
131 nodes.add(node)
132 }
133 return nodes
134}
135
136
137/**
Petr Lomakin47fee0a2017-08-01 10:46:05 -0700138 * Execute tempest tests
139 *
140 * @param target Host to run tests
141 * @param pattern If not false, will run only tests matched the pattern
142 * @param output_dir Directory for results
143 */
144def runTempestTests(master, target, output_dir, pattern = "false") {
145 def salt = new com.mirantis.mk.Salt()
146 def output_file = 'docker-tempest.log'
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700147 def path = '/opt/devops-qa-tools/generate_test_report/test_results'
148 def jsonfile = 'tempest_results.json'
149 def htmlfile = 'tempest_results.html'
Petr Lomakin47fee0a2017-08-01 10:46:05 -0700150 if (pattern == "false") {
151 salt.cmdRun(master, target, "docker exec qa_tools rally verify start --pattern set=full " +
152 "--detailed > ${output_file}")
153 }
154 else {
155 salt.cmdRun(master, target, "docker exec qa_tools rally verify start --pattern ${pattern} " +
156 "--detailed > ${output_file}")
157 }
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700158 salt.cmdRun(master, target, "docker exec qa_tools rally verify report --type json " +
159 "--to ${path}/report-tempest.json")
160 salt.cmdRun(master, target, "docker exec qa_tools rally verify report --type html " +
161 "--to ${path}/report-tempest.html")
162
163 salt.cmdRun(master, target, "docker cp qa_tools:${path}/report-tempest.json ${jsonfile}")
164 salt.cmdRun(master, target, "docker cp qa_tools:${path}/report-tempest.html ${htmlfile}")
165 def file_content = getFileContent(master, target, jsonfile)
166 writeFile file: "${output_dir}/report-tempest.json", text: file_content
167 file_content = getFileContent(master, target, htmlfile)
168 writeFile file: "${output_dir}/report-tempest.html", text: file_content
169 file_content = getFileContent(master, target, output_file)
Petr Lomakin47fee0a2017-08-01 10:46:05 -0700170 writeFile file: "${output_dir}${output_file}", text: file_content
171}
172
173/**
174 * Execute rally tests
175 *
176 * @param target Host to run tests
177 * @param pattern If not false, will run only tests matched the pattern
178 * @param output_dir Directory for results
179 */
180def runRallyTests(master, target, output_dir, pattern = "false") {
181 def salt = new com.mirantis.mk.Salt()
182 def output_file = 'docker-rally.log'
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700183 def path = '/opt/devops-qa-tools/generate_test_report/test_results'
184 def xmlfile = 'rally_results.xml'
185 def htmlfile = 'rally_results.html'
Petr Lomakin47fee0a2017-08-01 10:46:05 -0700186 salt.cmdRun(master, target, "docker exec qa_tools rally task start combined_scenario.yaml --task-args-file " +
187 "/opt/devops-qa-tools/rally-scenarios/task_arguments.yaml | tee ${output_file}")
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700188
189 salt.cmdRun(master, target, "docker exec qa_tools rally task export --type junit-xml " +
190 "--to ${path}/report-rally.xml")
191 salt.cmdRun(master, target, "docker exec qa_tools rally task report --out ${path}/report-rally.html")
192 salt.cmdRun(master, target, "docker cp qa_tools:${path}/report-rally.xml ${xmlfile}")
193 salt.cmdRun(master, target, "docker cp qa_tools:${path}/report-rally.html ${htmlfile}")
194
195 def file_content = getFileContent(master, target, xmlfile)
196 writeFile file: "${output_dir}/report-rally.xml", text: file_content
197 file_content = getFileContent(master, target, htmlfile)
198 writeFile file: "${output_dir}/report-rally.html", text: file_content
199 file_content = getFileContent(master, target, output_file)
Petr Lomakin47fee0a2017-08-01 10:46:05 -0700200 writeFile file: "${output_dir}${output_file}", text: file_content
201}
202
203/**
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700204 * Generate test report
205 *
206 * @param target Host to run script from
207 * @param output_dir Directory for results
208 */
209def generateTestReport(master, target, output_dir) {
210 def report_file = 'jenkins_test_report.html'
211 def path = '/opt/devops-qa-tools/generate_test_report/'
212 def res_path = '/opt/devops-qa-tools/generate_test_report/test_results/'
213 def salt = new com.mirantis.mk.Salt()
214 def common = new com.mirantis.mk.Common()
215
216 // Create 'test_results' directory in case it doesn't exist in container
217 def test_results = salt.cmdRun(master, target, "docker exec qa_tools bash -c \"if [ ! -d ${res_path} ]; " +
218 "then echo Creating directory ${res_path}; mkdir ${res_path}; fi\"")
219
220 def reports = ['report-tempest.json', 'report-rally.xml', 'report-k8s-e2e-tests.txt', 'report-ha.json', 'report-spt.txt']
221
222 for (report in reports) {
223 def _result = salt.cmdRun(master, target, "docker exec qa_tools bash -c \"if [ -f ${res_path}${report} ]; then echo 1; fi\"", checkResponse=false)
224 res = _result['return'][0].values()[0]
225 if ( res ) {
226 common.infoMsg("File ${report} already exists in docker container")
227 continue
228 }
229 if ( fileExists("${output_dir}${report}") ) {
230 common.infoMsg("Copying ${report} to docker container")
231 if ("${report}" == "report-tempest.json") {
232 def temp_file = readJSON file: "${output_dir}/${report}"
233 def tempest_cont = temp_file['verifications']
234 def json = common.prettify(["verifications":tempest_cont])
235 json = sh(script: "echo '${json}' | base64 -w 0", returnStdout: true)
236 salt.cmdRun(master, target, "docker exec qa_tools bash -c \"echo \"${json}\" | base64 -d | tee ${res_path}${report}\"", false, null, true)
237 }
238 else if ( "${report}" == "report-k8s-e2e-tests.txt" ) {
239 def k8s_content = sh(script: "cat ${output_dir}${report}| tail -20 | base64 -w 0", returnStdout: true)
240 salt.cmdRun(master, target, "docker exec qa_tools bash -c \"echo ${k8s_content} | base64 -d | tee ${res_path}${report}\"", false, null, true)
241 }
242 else {
243 def rep_content = sh(script: "cat ${output_dir}${report} | base64 -w 0", returnStdout: true)
244 salt.cmdRun(master, target, "docker exec qa_tools bash -c \"echo \"${rep_content}\" | base64 -d | tee ${res_path}${report}\"", false, null, true)
245 }
246 }
247 }
248 salt.cmdRun(master, target, "docker exec qa_tools jenkins_report.py --path ${path}")
249 salt.cmdRun(master, target, "docker cp qa_tools:/home/rally/${report_file} ${report_file}")
250
251 def report_content = salt.getFileContent(master, target, report_file)
252 writeFile file: "${output_dir}${report_file}", text: report_content
253}
254
255/**
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -0700256 * Execute SPT tests
257 *
258 * @param target Host to run tests
259 * @param output_dir Directory for results
260 */
261def runSptTests(master, target, output_dir) {
262 def salt = new com.mirantis.mk.Salt()
263 def output_file = 'docker-spt.log'
264 def report_file = 'report-spt.txt'
265 def report_file_hw = 'report-spt-hw.txt'
266 def archive_file = 'results-spt.tar.gz'
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700267 def path = '/opt/devops-qa-tools/generate_test_report/test_results'
268
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -0700269 salt.cmdRun(master, target, "docker exec qa_tools sudo timmy -c simplified-performance-testing/config.yaml " +
270 "--nodes-json nodes.json --log-file ${output_file}")
271 salt.cmdRun(master, target, "docker exec qa_tools ./simplified-performance-testing/SPT_parser.sh > ${report_file}")
272 salt.cmdRun(master, target, "docker exec qa_tools custom_spt_parser.sh > ${report_file_hw}")
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700273
274 salt.cmdRun(master, target, "docker cp ${report_file} qa_tools:${path}/report-spt.txt")
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -0700275 salt.cmdRun(master, target, "docker cp qa_tools:/home/rally/${output_file} ${output_file}")
276 salt.cmdRun(master, target, "docker cp qa_tools:/tmp/timmy/archives/general.tar.gz ${archive_file}")
Tetiana Korchak3383cc92017-08-25 09:36:19 -0700277
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -0700278 def file_content = getFileContent(master, target, output_file)
279 writeFile file: "${output_dir}${output_file}", text: file_content
280 file_content = getFileContent(master, target, report_file)
281 writeFile file: "${output_dir}${report_file}", text: file_content
282 file_content = getFileContent(master, target, report_file_hw)
283 writeFile file: "${output_dir}${report_file_hw}", text: file_content
284}
285
Dmitrii Kabanovd5f1c5f2017-08-30 14:51:41 -0700286/**
Petr Lomakin47fee0a2017-08-01 10:46:05 -0700287 * Cleanup
288 *
289 * @param target Host to run commands
290 * @param output_dir Directory for results
291 */
292def runCleanup(master, target, output_dir) {
293 def salt = new com.mirantis.mk.Salt()
Dmitrii Kabanov321405a2017-08-16 16:38:51 -0700294 if ( salt.cmdRun(master, target, "docker ps -f name=qa_tools -q", false, null, false)['return'][0].values()[0] ) {
295 salt.cmdRun(master, target, "docker rm -f qa_tools")
296 }
Petr Lomakin47fee0a2017-08-01 10:46:05 -0700297}
298
299/** Install docker if needed
300 *
301 * @param target Target node to install docker pkg
302 */
303def installDocker(master, target) {
304 def salt = new com.mirantis.mk.Salt()
305 if ( ! salt.runSaltProcessStep(master, target, 'pkg.version', ["docker-engine"]) ) {
306 salt.runSaltProcessStep(master, target, 'pkg.install', ["docker.io"])
307 }
308}