Cleanup: system-tests: format lava2-submit.py according to `black`
[lttng-ci.git] / scripts / system-tests / lava2-submit.py
CommitLineData
21fec189 1#!/usr/bin/python3
878b4840
JR
2# Copyright (C) 2016 - Francis Deslauriers <francis.deslauriers@efficios.com>
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import argparse
878b4840
JR
18import json
19import os
20import random
21import sys
22import time
23import xmlrpc.client
6d3950a9
JR
24from urllib.parse import urljoin
25from urllib.request import urlretrieve
21fec189
JR
26import yaml
27from jinja2 import Environment, FileSystemLoader
878b4840 28
ef84c6ec
JR
29USERNAME = 'lava-jenkins'
30HOSTNAME = 'lava-master-02.internal.efficios.com'
0425e1dd 31OBJSTORE_URL = "https://obj.internal.efficios.com/lava/results/"
878b4840 32
f5f36c68
FD
33
34class TestType:
21fec189 35 """ Enum like for test type """
f5f36c68 36
21fec189
JR
37 baremetal_benchmarks = 1
38 baremetal_tests = 2
39 kvm_tests = 3
40 kvm_fuzzing_tests = 4
878b4840 41 values = {
f5f36c68
FD
42 'baremetal-benchmarks': baremetal_benchmarks,
43 'baremetal-tests': baremetal_tests,
44 'kvm-tests': kvm_tests,
45 'kvm-fuzzing-tests': kvm_fuzzing_tests,
878b4840
JR
46 }
47
f5f36c68
FD
48
49class DeviceType:
21fec189 50 """ Enum like for device type """
f5f36c68 51
4cb5cc4f 52 x86 = 'x86'
f9a184a9 53 kvm = 'qemu'
f5f36c68
FD
54 values = {'kvm': kvm, 'x86': x86}
55
4cb5cc4f 56
878b4840
JR
57def get_job_bundle_content(server, job):
58 try:
59 bundle_sha = server.scheduler.job_status(str(job))['bundle_sha1']
60 bundle = server.dashboard.get(bundle_sha)
21fec189
JR
61 except xmlrpc.client.Fault as error:
62 print('Error while fetching results bundle', error.faultString)
63 raise error
878b4840
JR
64
65 return json.loads(bundle['content'])
66
f5f36c68 67
878b4840 68def check_job_all_test_cases_state_count(server, job):
21fec189
JR
69 """
70 Parse the results bundle to see the run-tests testcase
71 of the lttng-kernel-tests passed successfully
72 """
0425e1dd
JR
73 print("Testcase result:")
74 content = server.results.get_testjob_results_yaml(str(job))
75 testcases = yaml.load(content)
878b4840 76
21fec189
JR
77 passed_tests = 0
78 failed_tests = 0
0425e1dd
JR
79 for testcase in testcases:
80 if testcase['result'] != 'pass':
f5f36c68
FD
81 print(
82 "\tFAILED {}\n\t\t See http://{}{}".format(
83 testcase['name'], HOSTNAME, testcase['url']
84 )
85 )
21fec189 86 failed_tests += 1
0425e1dd 87 else:
21fec189 88 passed_tests += 1
878b4840
JR
89 return (passed_tests, failed_tests)
90
f5f36c68 91
0425e1dd 92def fetch_benchmark_results(build_id):
21fec189
JR
93 """
94 Get the benchmark results from the objstore
95 save them as CSV files localy
96 """
f5f36c68
FD
97 testcases = [
98 'processed_results_close.csv',
99 'processed_results_ioctl.csv',
100 'processed_results_open_efault.csv',
101 'processed_results_open_enoent.csv',
102 'processed_results_dup_close.csv',
103 'processed_results_raw_syscall_getpid.csv',
104 'processed_results_lttng_test_filter.csv',
105 ]
0425e1dd
JR
106 for testcase in testcases:
107 url = urljoin(OBJSTORE_URL, "{:s}/{:s}".format(build_id, testcase))
935bfecd 108 print('Fetching {}'.format(url))
0425e1dd 109 urlretrieve(url, testcase)
878b4840 110
f5f36c68 111
878b4840 112def print_test_output(server, job):
21fec189
JR
113 """
114 Parse the attachment of the testcase to fetch the stdout of the test suite
115 """
0425e1dd
JR
116 job_finished, log = server.scheduler.jobs.logs(str(job))
117 logs = yaml.load(log.data.decode('ascii'))
118 print_line = False
119 for line in logs:
120 if line['lvl'] != 'target':
121 continue
122 if line['msg'] == '<LAVA_SIGNAL_STARTTC run-tests>':
123 print('---- TEST SUITE OUTPUT BEGIN ----')
124 print_line = True
125 continue
126 if line['msg'] == '<LAVA_SIGNAL_ENDTC run-tests>':
127 print('----- TEST SUITE OUTPUT END -----')
128 break
129 if print_line:
130 print("{} {}".format(line['dt'], line['msg']))
878b4840 131
f5f36c68
FD
132
133def get_vlttng_cmd(
134 lttng_tools_url, lttng_tools_commit, lttng_ust_url=None, lttng_ust_commit=None
135):
21fec189
JR
136 """
137 Return vlttng cmd to be used in the job template for setup.
138 """
878b4840 139
f5f36c68
FD
140 vlttng_cmd = (
141 'vlttng --jobs=$(nproc) --profile urcu-master'
142 ' --override projects.babeltrace.build-env.PYTHON=python3'
143 ' --override projects.babeltrace.build-env.PYTHON_CONFIG=python3-config'
144 ' --profile babeltrace-stable-1.4'
145 ' --profile babeltrace-python'
146 ' --profile lttng-tools-master'
147 ' --override projects.lttng-tools.source='
148 + lttng_tools_url
149 + ' --override projects.lttng-tools.checkout='
150 + lttng_tools_commit
151 + ' --profile lttng-tools-no-man-pages'
152 )
878b4840
JR
153
154 if lttng_ust_commit is not None:
f5f36c68
FD
155 vlttng_cmd += (
156 ' --profile lttng-ust-master '
157 ' --override projects.lttng-ust.source='
158 + lttng_ust_url
159 + ' --override projects.lttng-ust.checkout='
160 + lttng_ust_commit
161 + ' --profile lttng-ust-no-man-pages'
162 )
878b4840 163
888b31de 164 vlttng_path = '/tmp/virtenv'
c11ec858 165
4cb5cc4f 166 vlttng_cmd += ' ' + vlttng_path
878b4840 167
4cb5cc4f 168 return vlttng_cmd
878b4840 169
f5f36c68 170
878b4840 171def main():
9a49d69d 172 nfsrootfs = "https://obj.internal.efficios.com/lava/rootfs/rootfs_amd64_xenial_2018-12-05.tar.gz"
878b4840
JR
173 test_type = None
174 parser = argparse.ArgumentParser(description='Launch baremetal test using Lava')
175 parser.add_argument('-t', '--type', required=True)
176 parser.add_argument('-j', '--jobname', required=True)
177 parser.add_argument('-k', '--kernel', required=True)
878b4840 178 parser.add_argument('-lm', '--lmodule', required=True)
eb5bdbeb 179 parser.add_argument('-tu', '--tools-url', required=True)
878b4840 180 parser.add_argument('-tc', '--tools-commit', required=True)
6b35e57c 181 parser.add_argument('-id', '--build-id', required=True)
eb5bdbeb 182 parser.add_argument('-uu', '--ust-url', required=False)
878b4840 183 parser.add_argument('-uc', '--ust-commit', required=False)
f23dc688 184 parser.add_argument('-d', '--debug', required=False, action='store_true')
878b4840
JR
185 args = parser.parse_args()
186
187 if args.type not in TestType.values:
188 print('argument -t/--type {} unrecognized.'.format(args.type))
189 print('Possible values are:')
190 for k in TestType.values:
191 print('\t {}'.format(k))
192 return -1
878b4840
JR
193
194 lava_api_key = None
f23dc688
JR
195 if not args.debug:
196 try:
ef84c6ec 197 lava_api_key = os.environ['LAVA2_JENKINS_TOKEN']
21fec189 198 except Exception as error:
f5f36c68
FD
199 print(
200 'LAVA2_JENKINS_TOKEN not found in the environment variable. Exiting...',
201 error,
202 )
f23dc688 203 return -1
878b4840 204
4cb5cc4f 205 jinja_loader = FileSystemLoader(os.path.dirname(os.path.realpath(__file__)))
f5f36c68 206 jinja_env = Environment(loader=jinja_loader, trim_blocks=True, lstrip_blocks=True)
4cb5cc4f 207 jinja_template = jinja_env.get_template('template_lava_job.jinja2')
4cb5cc4f
JR
208
209 test_type = TestType.values[args.type]
210
211 if test_type in [TestType.baremetal_benchmarks, TestType.baremetal_tests]:
212 device_type = DeviceType.x86
878b4840 213 else:
4cb5cc4f 214 device_type = DeviceType.kvm
e640b6d8
JR
215
216 vlttng_path = '/tmp/virtenv'
4cb5cc4f 217
f5f36c68
FD
218 vlttng_cmd = get_vlttng_cmd(
219 args.tools_url, args.tools_commit, args.ust_url, args.ust_commit
220 )
4cb5cc4f
JR
221
222 context = dict()
223 context['DeviceType'] = DeviceType
224 context['TestType'] = TestType
225
226 context['job_name'] = args.jobname
227 context['test_type'] = test_type
4cb5cc4f
JR
228 context['random_seed'] = random.randint(0, 1000000)
229 context['device_type'] = device_type
230
231 context['vlttng_cmd'] = vlttng_cmd
232 context['vlttng_path'] = vlttng_path
233
234 context['kernel_url'] = args.kernel
235 context['nfsrootfs_url'] = nfsrootfs
236 context['lttng_modules_url'] = args.lmodule
6b35e57c 237 context['jenkins_build_id'] = args.build_id
4cb5cc4f
JR
238
239 context['kprobe_round_nb'] = 10
240
ef84c6ec
JR
241 render = jinja_template.render(context)
242
ef84c6ec
JR
243 print('Job to be submitted:')
244
245 print(render)
878b4840 246
f23dc688 247 if args.debug:
f23dc688
JR
248 return 0
249
f5f36c68
FD
250 server = xmlrpc.client.ServerProxy(
251 'http://%s:%s@%s/RPC2' % (USERNAME, lava_api_key, HOSTNAME)
252 )
878b4840 253
21fec189
JR
254 for attempt in range(10):
255 try:
256 jobid = server.scheduler.submit_job(render)
257 except xmlrpc.client.ProtocolError as error:
f5f36c68
FD
258 print(
259 'Protocol error on submit, sleeping and retrying. Attempt #{}'.format(
260 attempt
261 )
262 )
21fec189
JR
263 time.sleep(5)
264 continue
265 else:
266 break
878b4840
JR
267
268 print('Lava jobid:{}'.format(jobid))
f5f36c68
FD
269 print(
270 'Lava job URL: http://lava-master-02.internal.efficios.com/scheduler/job/{}'.format(
271 jobid
272 )
273 )
878b4840 274
f5f36c68 275 # Check the status of the job every 30 seconds
0425e1dd
JR
276 jobstatus = server.scheduler.job_state(jobid)['job_state']
277 running = False
21fec189 278 while jobstatus in ['Submitted', 'Scheduling', 'Scheduled', 'Running']:
0425e1dd 279 if not running and jobstatus == 'Running':
878b4840 280 print('Job started running')
0425e1dd 281 running = True
878b4840 282 time.sleep(30)
26cbe60b
JR
283 try:
284 jobstatus = server.scheduler.job_state(jobid)['job_state']
21fec189
JR
285 except xmlrpc.client.ProtocolError as error:
286 print('Protocol error, retrying')
287 continue
878b4840 288 print('Job ended with {} status.'.format(jobstatus))
0425e1dd
JR
289
290 if jobstatus != 'Finished':
878b4840 291 return -1
878b4840 292
0425e1dd
JR
293 if test_type is TestType.kvm_tests or test_type is TestType.baremetal_tests:
294 print_test_output(server, jobid)
295 elif test_type is TestType.baremetal_benchmarks:
296 fetch_benchmark_results(args.build_id)
297
21fec189 298 passed, failed = check_job_all_test_cases_state_count(server, jobid)
0425e1dd
JR
299 print('With {} passed and {} failed Lava test cases.'.format(passed, failed))
300
21fec189 301 if failed != 0:
0425e1dd 302 return -1
878b4840 303
21fec189
JR
304 return 0
305
f5f36c68 306
878b4840
JR
307if __name__ == "__main__":
308 sys.exit(main())
This page took 0.037814 seconds and 4 git commands to generate.