jjb: lava: kprobe-fuzzing: Add random seed param for generation script
[lttng-ci.git] / scripts / system-tests / lava-submit.py
CommitLineData
b3d73c46
FD
1#!/usr/bin/python
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
18import base64
19import json
20import os
78cb511c 21import random
b3d73c46
FD
22import sys
23import time
f42b2b7e 24import xmlrpc.client
b3d73c46
FD
25from collections import OrderedDict
26from enum import Enum
27
28USERNAME = 'frdeso'
29HOSTNAME = 'lava-master.internal.efficios.com'
30SCP_PATH = 'scp://jenkins-lava@storage.internal.efficios.com'
31
32class TestType(Enum):
1ac7fa2c
FD
33 baremetal_benchmarks=1
34 baremetal_tests=2
35 kvm_tests=3
a2243f89 36 kvm_fuzzing_tests=4
b3d73c46
FD
37
38def get_job_bundle_content(server, job):
534a243d
FD
39 try:
40 bundle_sha = server.scheduler.job_status(str(job))['bundle_sha1']
41 bundle = server.dashboard.get(bundle_sha)
f42b2b7e
FD
42 except xmlrpc.client.Fault as f:
43 print('Error while fetching results bundle', f.faultString)
5c0f342c 44 raise f
b3d73c46
FD
45
46 return json.loads(bundle['content'])
47
48# Parse the results bundle to see the run-tests testcase
49# of the lttng-kernel-tests passed successfully
50def check_job_all_test_cases_state_count(server, job):
51 content = get_job_bundle_content(server, job)
52
1d393f82
FD
53 # FIXME:Those tests are part of the boot actions and fail randomly but
54 # doesn't affect the behaviour of the tests. We should update our Lava
55 # installation and try to reproduce it. This error was encountered on
56 # Ubuntu 16.04.
57 tests_known_to_fail=['mount', 'df', 'ls', 'ip', 'wait_for_test_image_prompt']
58
b3d73c46
FD
59 passed_tests=0
60 failed_tests=0
61 for run in content['test_runs']:
62 for result in run['test_results']:
3e7245a4 63 if 'test_case_id' in result :
b3d73c46
FD
64 if result['result'] in 'pass':
65 passed_tests+=1
1d393f82 66 elif result['test_case_id'] in tests_known_to_fail:
3e7245a4 67 pass
b3d73c46
FD
68 else:
69 failed_tests+=1
70 return (passed_tests, failed_tests)
71
104ed94b
FD
72# Get the benchmark results from the lava bundle
73# save them as CSV files localy
74def fetch_benchmark_results(server, job):
75 content = get_job_bundle_content(server, job)
70e85c98 76 testcases = ['processed_results_close.csv',
c863d7ca 77 'processed_results_ioctl.csv',
70e85c98 78 'processed_results_open_efault.csv',
6ebb7306 79 'processed_results_open_enoent.csv',
dff1609b 80 'processed_results_dup_close.csv',
0ca122b6 81 'processed_results_raw_syscall_getpid.csv',
dff1609b 82 'processed_results_lttng_test_filter.csv']
104ed94b
FD
83
84 # The result bundle is a large JSON containing the results of every testcase
85 # of the LAVA job as well as the files that were attached during the run.
86 # We need to iterate over this JSON to get the base64 representation of the
87 # benchmark results produced during the run.
88 for run in content['test_runs']:
89 # We only care of the benchmark testcases
dff1609b 90 if 'benchmark-' in run['test_id']:
104ed94b
FD
91 if 'test_results' in run:
92 for res in run['test_results']:
93 if 'attachments' in res:
94 for a in res['attachments']:
95 # We only save the results file
96 if a['pathname'] in testcases:
f42b2b7e 97 with open(a['pathname'],'wb') as f:
104ed94b
FD
98 # Convert the b64 representation of the
99 # result file and write it to a file
100 # in the current working directory
101 f.write(base64.b64decode(a['content']))
102
b3d73c46
FD
103# Parse the attachment of the testcase to fetch the stdout of the test suite
104def print_test_output(server, job):
105 content = get_job_bundle_content(server, job)
106 found = False
107
108 for run in content['test_runs']:
109 if run['test_id'] in 'lttng-kernel-test':
110 for attachment in run['attachments']:
111 if attachment['pathname'] in 'stdout.log':
112
113 # Decode the base64 file and split on newlines to iterate
114 # on list
6d7f7c11
FD
115 testoutput = str(base64.b64decode(bytes(attachment['content'], encoding='UTF-8')))
116
117 testoutput = testoutput.replace('\\n', '\n')
b3d73c46
FD
118
119 # Create a generator to iterate on the lines and keeping
120 # the state of the iterator across the two loops.
6d7f7c11 121 testoutput_iter = iter(testoutput.split('\n'))
b3d73c46
FD
122 for line in testoutput_iter:
123
124 # Find the header of the test case and start printing
125 # from there
126 if 'LAVA_SIGNAL_STARTTC run-tests' in line:
b3d73c46
FD
127 print('---- TEST SUITE OUTPUT BEGIN ----')
128 for line in testoutput_iter:
129 if 'LAVA_SIGNAL_ENDTC run-tests' not in line:
130 print(line)
131 else:
132 # Print until we reach the end of the
133 # section
134 break
135
b3d73c46
FD
136 print('----- TEST SUITE OUTPUT END -----')
137 break
138
dc9700c9 139def create_new_job(name, build_device):
b3d73c46
FD
140 job = OrderedDict({
141 'health_check': False,
142 'job_name': name,
10ca6e3a 143 'device_type': build_device,
dc9700c9 144 'tags': [ ],
10ca6e3a 145 'timeout': 7200,
b3d73c46
FD
146 'actions': []
147 })
dc9700c9
FD
148 if build_device in 'x86':
149 job['tags'].append('dev-sda1')
150
b3d73c46
FD
151 return job
152
153def get_boot_cmd():
154 command = OrderedDict({
155 'command': 'boot_image'
156 })
157 return command
158
dc9700c9 159def get_config_cmd(build_device):
b3d73c46
FD
160 packages=['bsdtar', 'psmisc', 'wget', 'python3', 'python3-pip', \
161 'libglib2.0-dev', 'libffi-dev', 'elfutils', 'libdw-dev', \
e1504b01 162 'libelf-dev', 'libmount-dev', 'libxml2', 'libpfm4-dev', \
30b89c1f 163 'libnuma-dev', 'python3-dev', 'swig', 'stress']
b3d73c46
FD
164 command = OrderedDict({
165 'command': 'lava_command_run',
166 'parameters': {
167 'commands': [
b3d73c46
FD
168 'cat /etc/resolv.conf',
169 'echo nameserver 172.18.0.12 > /etc/resolv.conf',
dc9700c9 170 'groupadd tracing'
38cfd62c
FD
171 ],
172 'timeout':300
b3d73c46
FD
173 }
174 })
dc9700c9
FD
175 if build_device in 'x86':
176 command['parameters']['commands'].extend([
177 'mount /dev/sda1 /tmp',
178 'rm -rf /tmp/*'])
179
180 command['parameters']['commands'].extend([
181 'depmod -a',
182 'locale-gen en_US.UTF-8',
183 'apt-get update',
819f0b86 184 'apt-get upgrade',
dc9700c9
FD
185 'apt-get install -y {}'.format(' '.join(packages))
186 ])
b3d73c46
FD
187 return command
188
1ac7fa2c 189def get_baremetal_benchmarks_cmd():
b3d73c46
FD
190 command = OrderedDict({
191 'command': 'lava_test_shell',
192 'parameters': {
193 'testdef_repos': [
194 {
195 'git-repo': 'https://github.com/lttng/lttng-ci.git',
196 'revision': 'master',
3868791d 197 'testdef': 'lava/system-tests/failing-close.yml'
b3d73c46 198 },
c863d7ca
FD
199 {
200 'git-repo': 'https://github.com/lttng/lttng-ci.git',
201 'revision': 'master',
3868791d 202 'testdef': 'lava/system-tests/failing-ioctl.yml'
c863d7ca 203 },
b3d73c46
FD
204 {
205 'git-repo': 'https://github.com/lttng/lttng-ci.git',
206 'revision': 'master',
3868791d 207 'testdef': 'lava/system-tests/failing-open-efault.yml'
b3d73c46
FD
208 },
209 {
210 'git-repo': 'https://github.com/lttng/lttng-ci.git',
211 'revision': 'master',
3868791d 212 'testdef': 'lava/system-tests/success-dup-close.yml'
dff1609b 213 },
0ca122b6
FD
214 {
215 'git-repo': 'https://github.com/lttng/lttng-ci.git',
216 'revision': 'master',
3868791d 217 'testdef': 'lava/system-tests/raw-syscall-getpid.yml'
0ca122b6 218 },
6ebb7306
FD
219 {
220 'git-repo': 'https://github.com/lttng/lttng-ci.git',
221 'revision': 'master',
3868791d 222 'testdef': 'lava/system-tests/failing-open-enoent.yml'
6ebb7306 223 },
dff1609b
FD
224 {
225 'git-repo': 'https://github.com/lttng/lttng-ci.git',
226 'revision': 'master',
3868791d 227 'testdef': 'lava/system-tests/lttng-test-filter.yml'
1ac7fa2c
FD
228 }
229 ],
10ca6e3a 230 'timeout': 7200
1ac7fa2c
FD
231 }
232 })
233 return command
234
235def get_baremetal_tests_cmd():
236 command = OrderedDict({
237 'command': 'lava_test_shell',
238 'parameters': {
239 'testdef_repos': [
f3d4ee9f
FD
240 {
241 'git-repo': 'https://github.com/lttng/lttng-ci.git',
242 'revision': 'master',
3868791d 243 'testdef': 'lava/system-tests/perf-tests.yml'
b3d73c46
FD
244 }
245 ],
10ca6e3a 246 'timeout': 3600
b3d73c46
FD
247 }
248 })
249 return command
250
1ac7fa2c 251def get_kvm_tests_cmd():
b3d73c46
FD
252 command = OrderedDict({
253 'command': 'lava_test_shell',
254 'parameters': {
255 'testdef_repos': [
256 {
257 'git-repo': 'https://github.com/lttng/lttng-ci.git',
258 'revision': 'master',
3868791d 259 'testdef': 'lava/system-tests/kernel-tests.yml'
ee02050f
FD
260 },
261 {
262 'git-repo': 'https://github.com/lttng/lttng-ci.git',
263 'revision': 'master',
3868791d 264 'testdef': 'lava/system-tests/destructive-tests.yml'
9d9c173f
FD
265 }
266 ],
958065a8 267 'timeout': 7200
9d9c173f
FD
268 }
269 })
270 return command
6dffa64f
FD
271
272def get_kprobes_generate_data_cmd():
78cb511c 273 random_seed = random.randint(0, 1000000)
6dffa64f
FD
274 command = OrderedDict({
275 'command': 'lava_test_shell',
276 'parameters': {
277 'testdef_repos': [
278 {
279 'git-repo': 'https://github.com/lttng/lttng-ci.git',
280 'revision': 'master',
78cb511c
FD
281 'testdef': 'lava/system-tests/kprobe-fuzzing-generate-data.yml',
282 'parameters': { 'RANDOM_SEED': str(random_seed) }
6dffa64f
FD
283 }
284 ],
285 'timeout': 60
286 }
287 })
288 return command
289
c5b4a212 290def get_kprobes_test_cmd(round_nb):
9d9c173f
FD
291 command = OrderedDict({
292 'command': 'lava_test_shell',
293 'parameters': {
294 'testdef_repos': [
30b89c1f
FD
295 {
296 'git-repo': 'https://github.com/lttng/lttng-ci.git',
297 'revision': 'master',
c5b4a212
FD
298 'testdef': 'lava/system-tests/kprobe-fuzzing-tests.yml',
299 'parameters': { 'ROUND_NB': str(round_nb) }
b3d73c46 300 }
c5b4a212
FD
301 ],
302 'timeout': 1000
b3d73c46
FD
303 }
304 })
305 return command
306
307def get_results_cmd(stream_name):
308 command = OrderedDict({
309 'command': 'submit_results',
310 'parameters': {
311 'server': 'http://lava-master.internal.efficios.com/RPC2/'
312 }
313 })
314 command['parameters']['stream']='/anonymous/'+stream_name+'/'
315 return command
316
dc9700c9
FD
317def get_deploy_cmd_kvm(jenkins_job, kernel_path, linux_modules_path, lttng_modules_path):
318 command = OrderedDict({
319 'command': 'deploy_kernel',
320 'metadata': {},
321 'parameters': {
322 'customize': {},
323 'kernel': None,
819f0b86
FD
324 'target_type': 'ubuntu',
325 'rootfs': 'file:///var/lib/lava-server/default/media/images/xenial.img.gz',
326 'login_prompt': 'kvm02 login:',
327 'username': 'root'
dc9700c9
FD
328 }
329 })
330
331 command['parameters']['customize'][SCP_PATH+linux_modules_path]=['rootfs:/','archive']
332 command['parameters']['customize'][SCP_PATH+lttng_modules_path]=['rootfs:/','archive']
333 command['parameters']['kernel'] = str(SCP_PATH+kernel_path)
334 command['metadata']['jenkins_jobname'] = jenkins_job
335
336 return command
337
338def get_deploy_cmd_x86(jenkins_job, kernel_path, linux_modules_path, lttng_modules_path, nb_iter=None):
b3d73c46
FD
339 command = OrderedDict({
340 'command': 'deploy_kernel',
341 'metadata': {},
342 'parameters': {
343 'overlays': [],
344 'kernel': None,
345 'nfsrootfs': str(SCP_PATH+'/storage/jenkins-lava/rootfs/rootfs_amd64_trusty_2016-02-23-1134.tar.gz'),
346 'target_type': 'ubuntu'
347 }
348 })
349
350 command['parameters']['overlays'].append( str(SCP_PATH+linux_modules_path))
351 command['parameters']['overlays'].append( str(SCP_PATH+lttng_modules_path))
352 command['parameters']['kernel'] = str(SCP_PATH+kernel_path)
dc9700c9 353 command['metadata']['jenkins_jobname'] = jenkins_job
b3d73c46
FD
354 if nb_iter is not None:
355 command['metadata']['nb_iterations'] = nb_iter
356
357 return command
358
359
dc9700c9 360def get_env_setup_cmd(build_device, lttng_tools_commit, lttng_ust_commit=None):
b3d73c46
FD
361 command = OrderedDict({
362 'command': 'lava_command_run',
363 'parameters': {
364 'commands': [
819f0b86 365 'pip3 install --upgrade pip',
46fb8afa 366 'hash -r',
b3d73c46
FD
367 'pip3 install vlttng',
368 ],
10ca6e3a 369 'timeout': 3600
b3d73c46
FD
370 }
371 })
372
4418be37 373 vlttng_cmd = 'vlttng --jobs=$(nproc) --profile urcu-master' \
c6204172
FD
374 ' --override projects.babeltrace.build-env.PYTHON=python3' \
375 ' --override projects.babeltrace.build-env.PYTHON_CONFIG=python3-config' \
376 ' --profile babeltrace-stable-1.4' \
377 ' --profile babeltrace-python' \
b3d73c46
FD
378 ' --profile lttng-tools-master' \
379 ' --override projects.lttng-tools.checkout='+lttng_tools_commit + \
380 ' --profile lttng-tools-no-man-pages'
381
382 if lttng_ust_commit is not None:
383 vlttng_cmd += ' --profile lttng-ust-master ' \
384 ' --override projects.lttng-ust.checkout='+lttng_ust_commit+ \
385 ' --profile lttng-ust-no-man-pages'
386
dc9700c9
FD
387 virtenv_path = None
388 if build_device in 'kvm':
389 virtenv_path = '/root/virtenv'
390 else:
391 virtenv_path = '/tmp/virtenv'
392
393 vlttng_cmd += ' '+virtenv_path
b3d73c46
FD
394
395 command['parameters']['commands'].append(vlttng_cmd)
dc9700c9
FD
396 command['parameters']['commands'].append('ln -s '+virtenv_path+' /root/lttngvenv')
397 command['parameters']['commands'].append('sync')
398
b3d73c46
FD
399 return command
400
401def main():
402 test_type = None
403 parser = argparse.ArgumentParser(description='Launch baremetal test using Lava')
404 parser.add_argument('-t', '--type', required=True)
405 parser.add_argument('-j', '--jobname', required=True)
406 parser.add_argument('-k', '--kernel', required=True)
407 parser.add_argument('-km', '--kmodule', required=True)
408 parser.add_argument('-lm', '--lmodule', required=True)
b3d73c46
FD
409 parser.add_argument('-tc', '--tools-commit', required=True)
410 parser.add_argument('-uc', '--ust-commit', required=False)
411 args = parser.parse_args()
412
1ac7fa2c
FD
413 if args.type in 'baremetal-benchmarks':
414 test_type = TestType.baremetal_benchmarks
415 elif args.type in 'baremetal-tests':
416 test_type = TestType.baremetal_tests
417 elif args.type in 'kvm-tests':
418 test_type = TestType.kvm_tests
a2243f89
FD
419 elif args.type in 'kvm-fuzzing-tests':
420 test_type = TestType.kvm_fuzzing_tests
b3d73c46
FD
421 else:
422 print('argument -t/--type {} unrecognized. Exiting...'.format(args.type))
423 return -1
424
8cef2adf
FD
425 lava_api_key = None
426 try:
30003819 427 lava_api_key = os.environ['LAVA_JENKINS_TOKEN']
f42b2b7e 428 except Exception as e:
30003819 429 print('LAVA_JENKINS_TOKEN not found in the environment variable. Exiting...', e )
8cef2adf
FD
430 return -1
431
1ac7fa2c 432 if test_type is TestType.baremetal_benchmarks:
dc9700c9
FD
433 j = create_new_job(args.jobname, build_device='x86')
434 j['actions'].append(get_deploy_cmd_x86(args.jobname, args.kernel, args.kmodule, args.lmodule))
1ac7fa2c
FD
435 elif test_type is TestType.baremetal_tests:
436 j = create_new_job(args.jobname, build_device='x86')
437 j['actions'].append(get_deploy_cmd_x86(args.jobname, args.kernel, args.kmodule, args.lmodule))
a2243f89 438 elif test_type is TestType.kvm_tests or test_type is TestType.kvm_fuzzing_tests:
dc9700c9
FD
439 j = create_new_job(args.jobname, build_device='kvm')
440 j['actions'].append(get_deploy_cmd_kvm(args.jobname, args.kernel, args.kmodule, args.lmodule))
441
442 j['actions'].append(get_boot_cmd())
443
1ac7fa2c 444 if test_type is TestType.baremetal_benchmarks:
dc9700c9
FD
445 j['actions'].append(get_config_cmd('x86'))
446 j['actions'].append(get_env_setup_cmd('x86', args.tools_commit))
1ac7fa2c 447 j['actions'].append(get_baremetal_benchmarks_cmd())
b3d73c46 448 j['actions'].append(get_results_cmd(stream_name='benchmark-kernel'))
1ac7fa2c
FD
449 elif test_type is TestType.baremetal_tests:
450 if args.ust_commit is None:
451 print('Tests runs need -uc/--ust-commit options. Exiting...')
452 return -1
453 j['actions'].append(get_config_cmd('x86'))
454 j['actions'].append(get_env_setup_cmd('x86', args.tools_commit, args.ust_commit))
455 j['actions'].append(get_baremetal_tests_cmd())
456 j['actions'].append(get_results_cmd(stream_name='tests-kernel'))
457 elif test_type is TestType.kvm_tests:
b3d73c46
FD
458 if args.ust_commit is None:
459 print('Tests runs need -uc/--ust-commit options. Exiting...')
460 return -1
dc9700c9
FD
461 j['actions'].append(get_config_cmd('kvm'))
462 j['actions'].append(get_env_setup_cmd('kvm', args.tools_commit, args.ust_commit))
1ac7fa2c 463 j['actions'].append(get_kvm_tests_cmd())
a2243f89
FD
464 j['actions'].append(get_results_cmd(stream_name='tests-kernel'))
465 elif test_type is TestType.kvm_fuzzing_tests:
466 if args.ust_commit is None:
467 print('Tests runs need -uc/--ust-commit options. Exiting...')
468 return -1
469 j['actions'].append(get_config_cmd('kvm'))
6dffa64f 470 j['actions'].append(get_kprobes_generate_data_cmd())
c5b4a212
FD
471 for i in range(10):
472 j['actions'].append(get_kprobes_test_cmd(round_nb=i))
b3d73c46
FD
473 j['actions'].append(get_results_cmd(stream_name='tests-kernel'))
474 else:
475 assert False, 'Unknown test type'
476
f42b2b7e 477 server = xmlrpc.client.ServerProxy('http://%s:%s@%s/RPC2' % (USERNAME, lava_api_key, HOSTNAME))
b3d73c46
FD
478
479 jobid = server.scheduler.submit_job(json.dumps(j))
480
21e89f7e 481 print('Lava jobid:{}'.format(jobid))
0467dff8 482 print('Lava job URL: http://lava-master.internal.efficios.com/scheduler/job/{}/log_file'.format(jobid))
21e89f7e 483
b3d73c46
FD
484 #Check the status of the job every 30 seconds
485 jobstatus = server.scheduler.job_status(jobid)['job_status']
d9997fe4 486 not_running = False
b3d73c46 487 while jobstatus in 'Submitted' or jobstatus in 'Running':
d9997fe4
FD
488 if not_running is False and jobstatus in 'Running':
489 print('Job started running')
490 not_running = True
b3d73c46
FD
491 time.sleep(30)
492 jobstatus = server.scheduler.job_status(jobid)['job_status']
493
534a243d 494 if test_type is TestType.kvm_tests or test_type is TestType.baremetal_tests:
b3d73c46 495 print_test_output(server, jobid)
104ed94b
FD
496 elif test_type is TestType.baremetal_benchmarks:
497 fetch_benchmark_results(server, jobid)
b3d73c46 498
d1b69f4d
FD
499 print('Job ended with {} status.'.format(jobstatus))
500 if jobstatus not in 'Complete':
501 return -1
502 else:
73c1d4bc 503 passed, failed=check_job_all_test_cases_state_count(server, jobid)
d1b69f4d
FD
504 print('With {} passed and {} failed Lava test cases.'.format(passed, failed))
505
73c1d4bc
FD
506 if failed == 0:
507 return 0
508 else:
509 return -1
b3d73c46
FD
510
511if __name__ == "__main__":
512 sys.exit(main())
This page took 0.048057 seconds and 4 git commands to generate.