Remove extra '/' in upload path
[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))
c2f8bcb9 75 testcases = yaml.unsafe_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 116 job_finished, log = server.scheduler.jobs.logs(str(job))
be7f51b6 117 logs = yaml.unsafe_load(log.data.decode('ascii'))
0425e1dd
JR
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 -----')
d132001f
FD
128 print_line = False
129 continue
0425e1dd
JR
130 if print_line:
131 print("{} {}".format(line['dt'], line['msg']))
878b4840 132
f5f36c68
FD
133
134def get_vlttng_cmd(
135 lttng_tools_url, lttng_tools_commit, lttng_ust_url=None, lttng_ust_commit=None
136):
21fec189
JR
137 """
138 Return vlttng cmd to be used in the job template for setup.
139 """
878b4840 140
f5f36c68
FD
141 vlttng_cmd = (
142 'vlttng --jobs=$(nproc) --profile urcu-master'
143 ' --override projects.babeltrace.build-env.PYTHON=python3'
144 ' --override projects.babeltrace.build-env.PYTHON_CONFIG=python3-config'
145 ' --profile babeltrace-stable-1.4'
146 ' --profile babeltrace-python'
147 ' --profile lttng-tools-master'
148 ' --override projects.lttng-tools.source='
149 + lttng_tools_url
150 + ' --override projects.lttng-tools.checkout='
151 + lttng_tools_commit
152 + ' --profile lttng-tools-no-man-pages'
153 )
878b4840
JR
154
155 if lttng_ust_commit is not None:
f5f36c68
FD
156 vlttng_cmd += (
157 ' --profile lttng-ust-master '
158 ' --override projects.lttng-ust.source='
159 + lttng_ust_url
160 + ' --override projects.lttng-ust.checkout='
161 + lttng_ust_commit
162 + ' --profile lttng-ust-no-man-pages'
163 )
878b4840 164
888b31de 165 vlttng_path = '/tmp/virtenv'
c11ec858 166
4cb5cc4f 167 vlttng_cmd += ' ' + vlttng_path
878b4840 168
4cb5cc4f 169 return vlttng_cmd
878b4840 170
f5f36c68 171
878b4840 172def main():
9a49d69d 173 nfsrootfs = "https://obj.internal.efficios.com/lava/rootfs/rootfs_amd64_xenial_2018-12-05.tar.gz"
878b4840
JR
174 test_type = None
175 parser = argparse.ArgumentParser(description='Launch baremetal test using Lava')
176 parser.add_argument('-t', '--type', required=True)
177 parser.add_argument('-j', '--jobname', required=True)
178 parser.add_argument('-k', '--kernel', required=True)
878b4840 179 parser.add_argument('-lm', '--lmodule', required=True)
eb5bdbeb 180 parser.add_argument('-tu', '--tools-url', required=True)
878b4840 181 parser.add_argument('-tc', '--tools-commit', required=True)
6b35e57c 182 parser.add_argument('-id', '--build-id', required=True)
eb5bdbeb 183 parser.add_argument('-uu', '--ust-url', required=False)
878b4840 184 parser.add_argument('-uc', '--ust-commit', required=False)
f23dc688 185 parser.add_argument('-d', '--debug', required=False, action='store_true')
878b4840
JR
186 args = parser.parse_args()
187
188 if args.type not in TestType.values:
189 print('argument -t/--type {} unrecognized.'.format(args.type))
190 print('Possible values are:')
191 for k in TestType.values:
192 print('\t {}'.format(k))
193 return -1
878b4840
JR
194
195 lava_api_key = None
f23dc688
JR
196 if not args.debug:
197 try:
ef84c6ec 198 lava_api_key = os.environ['LAVA2_JENKINS_TOKEN']
21fec189 199 except Exception as error:
f5f36c68
FD
200 print(
201 'LAVA2_JENKINS_TOKEN not found in the environment variable. Exiting...',
202 error,
203 )
f23dc688 204 return -1
878b4840 205
4cb5cc4f 206 jinja_loader = FileSystemLoader(os.path.dirname(os.path.realpath(__file__)))
f5f36c68 207 jinja_env = Environment(loader=jinja_loader, trim_blocks=True, lstrip_blocks=True)
4cb5cc4f 208 jinja_template = jinja_env.get_template('template_lava_job.jinja2')
4cb5cc4f
JR
209
210 test_type = TestType.values[args.type]
211
212 if test_type in [TestType.baremetal_benchmarks, TestType.baremetal_tests]:
213 device_type = DeviceType.x86
878b4840 214 else:
4cb5cc4f 215 device_type = DeviceType.kvm
e640b6d8
JR
216
217 vlttng_path = '/tmp/virtenv'
4cb5cc4f 218
f5f36c68
FD
219 vlttng_cmd = get_vlttng_cmd(
220 args.tools_url, args.tools_commit, args.ust_url, args.ust_commit
221 )
4cb5cc4f
JR
222
223 context = dict()
224 context['DeviceType'] = DeviceType
225 context['TestType'] = TestType
226
227 context['job_name'] = args.jobname
228 context['test_type'] = test_type
4cb5cc4f
JR
229 context['random_seed'] = random.randint(0, 1000000)
230 context['device_type'] = device_type
231
232 context['vlttng_cmd'] = vlttng_cmd
233 context['vlttng_path'] = vlttng_path
234
235 context['kernel_url'] = args.kernel
236 context['nfsrootfs_url'] = nfsrootfs
237 context['lttng_modules_url'] = args.lmodule
6b35e57c 238 context['jenkins_build_id'] = args.build_id
4cb5cc4f
JR
239
240 context['kprobe_round_nb'] = 10
241
ef84c6ec
JR
242 render = jinja_template.render(context)
243
ef84c6ec
JR
244 print('Job to be submitted:')
245
246 print(render)
878b4840 247
f23dc688 248 if args.debug:
f23dc688
JR
249 return 0
250
f5f36c68
FD
251 server = xmlrpc.client.ServerProxy(
252 'http://%s:%s@%s/RPC2' % (USERNAME, lava_api_key, HOSTNAME)
253 )
878b4840 254
21fec189
JR
255 for attempt in range(10):
256 try:
257 jobid = server.scheduler.submit_job(render)
258 except xmlrpc.client.ProtocolError as error:
f5f36c68
FD
259 print(
260 'Protocol error on submit, sleeping and retrying. Attempt #{}'.format(
261 attempt
262 )
263 )
21fec189
JR
264 time.sleep(5)
265 continue
266 else:
267 break
878b4840
JR
268
269 print('Lava jobid:{}'.format(jobid))
f5f36c68
FD
270 print(
271 'Lava job URL: http://lava-master-02.internal.efficios.com/scheduler/job/{}'.format(
272 jobid
273 )
274 )
878b4840 275
f5f36c68 276 # Check the status of the job every 30 seconds
0425e1dd
JR
277 jobstatus = server.scheduler.job_state(jobid)['job_state']
278 running = False
21fec189 279 while jobstatus in ['Submitted', 'Scheduling', 'Scheduled', 'Running']:
0425e1dd 280 if not running and jobstatus == 'Running':
878b4840 281 print('Job started running')
0425e1dd 282 running = True
878b4840 283 time.sleep(30)
26cbe60b
JR
284 try:
285 jobstatus = server.scheduler.job_state(jobid)['job_state']
21fec189
JR
286 except xmlrpc.client.ProtocolError as error:
287 print('Protocol error, retrying')
288 continue
878b4840 289 print('Job ended with {} status.'.format(jobstatus))
0425e1dd
JR
290
291 if jobstatus != 'Finished':
878b4840 292 return -1
878b4840 293
0425e1dd
JR
294 if test_type is TestType.kvm_tests or test_type is TestType.baremetal_tests:
295 print_test_output(server, jobid)
296 elif test_type is TestType.baremetal_benchmarks:
297 fetch_benchmark_results(args.build_id)
298
21fec189 299 passed, failed = check_job_all_test_cases_state_count(server, jobid)
0425e1dd
JR
300 print('With {} passed and {} failed Lava test cases.'.format(passed, failed))
301
21fec189 302 if failed != 0:
0425e1dd 303 return -1
878b4840 304
21fec189
JR
305 return 0
306
f5f36c68 307
878b4840
JR
308if __name__ == "__main__":
309 sys.exit(main())
This page took 0.043081 seconds and 4 git commands to generate.