1c25ce589SFinn Behrens#!/usr/bin/env python3 26ebf5866SFelix Guo# SPDX-License-Identifier: GPL-2.0 36ebf5866SFelix Guo# 46ebf5866SFelix Guo# A thin wrapper on top of the KUnit Kernel 56ebf5866SFelix Guo# 66ebf5866SFelix Guo# Copyright (C) 2019, Google LLC. 76ebf5866SFelix Guo# Author: Felix Guo <felixguoxiuping@gmail.com> 86ebf5866SFelix Guo# Author: Brendan Higgins <brendanhiggins@google.com> 96ebf5866SFelix Guo 106ebf5866SFelix Guoimport argparse 116ebf5866SFelix Guoimport sys 126ebf5866SFelix Guoimport os 136ebf5866SFelix Guoimport time 146ebf5866SFelix Guo 15df4b0807SSeongJae Parkassert sys.version_info >= (3, 7), "Python version is too old" 16df4b0807SSeongJae Park 176ebf5866SFelix Guofrom collections import namedtuple 186ebf5866SFelix Guofrom enum import Enum, auto 19d8c23eadSDaniel Latypovfrom typing import Iterable, Sequence 206ebf5866SFelix Guo 2121a6d178SHeidi Fahimimport kunit_json 226ebf5866SFelix Guoimport kunit_kernel 236ebf5866SFelix Guoimport kunit_parser 246ebf5866SFelix Guo 2545ba7a89SDavid GowKunitResult = namedtuple('KunitResult', ['status','result','elapsed_time']) 266ebf5866SFelix Guo 2745ba7a89SDavid GowKunitConfigRequest = namedtuple('KunitConfigRequest', 2801397e82SVitor Massaru Iha ['build_dir', 'make_options']) 2945ba7a89SDavid GowKunitBuildRequest = namedtuple('KunitBuildRequest', 3045ba7a89SDavid Gow ['jobs', 'build_dir', 'alltests', 3145ba7a89SDavid Gow 'make_options']) 3245ba7a89SDavid GowKunitExecRequest = namedtuple('KunitExecRequest', 336cb51a18SDaniel Latypov ['timeout', 'build_dir', 'alltests', 346cb51a18SDaniel Latypov 'filter_glob', 'kernel_args']) 3545ba7a89SDavid GowKunitParseRequest = namedtuple('KunitParseRequest', 36*7ef925eaSDaniel Latypov ['raw_output', 'build_dir', 'json']) 37021ed9f5SHeidi FahimKunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs', 38d992880bSDaniel Latypov 'build_dir', 'alltests', 'filter_glob', 396cb51a18SDaniel Latypov 'kernel_args', 'json', 'make_options']) 406ebf5866SFelix Guo 41be886ba9SHeidi FahimKernelDirectoryPath = sys.argv[0].split('tools/testing/kunit/')[0] 42be886ba9SHeidi Fahim 436ebf5866SFelix Guoclass KunitStatus(Enum): 446ebf5866SFelix Guo SUCCESS = auto() 456ebf5866SFelix Guo CONFIG_FAILURE = auto() 466ebf5866SFelix Guo BUILD_FAILURE = auto() 476ebf5866SFelix Guo TEST_FAILURE = auto() 486ebf5866SFelix Guo 4909641f7cSDaniel Latypovdef get_kernel_root_path() -> str: 5009641f7cSDaniel Latypov path = sys.argv[0] if not __file__ else __file__ 5109641f7cSDaniel Latypov parts = os.path.realpath(path).split('tools/testing/kunit') 52be886ba9SHeidi Fahim if len(parts) != 2: 53be886ba9SHeidi Fahim sys.exit(1) 54be886ba9SHeidi Fahim return parts[0] 55be886ba9SHeidi Fahim 5645ba7a89SDavid Gowdef config_tests(linux: kunit_kernel.LinuxSourceTree, 5745ba7a89SDavid Gow request: KunitConfigRequest) -> KunitResult: 5845ba7a89SDavid Gow kunit_parser.print_with_timestamp('Configuring KUnit Kernel ...') 5945ba7a89SDavid Gow 606ebf5866SFelix Guo config_start = time.time() 610476e69fSGreg Thelen success = linux.build_reconfig(request.build_dir, request.make_options) 626ebf5866SFelix Guo config_end = time.time() 636ebf5866SFelix Guo if not success: 6445ba7a89SDavid Gow return KunitResult(KunitStatus.CONFIG_FAILURE, 6545ba7a89SDavid Gow 'could not configure kernel', 6645ba7a89SDavid Gow config_end - config_start) 6745ba7a89SDavid Gow return KunitResult(KunitStatus.SUCCESS, 6845ba7a89SDavid Gow 'configured kernel successfully', 6945ba7a89SDavid Gow config_end - config_start) 706ebf5866SFelix Guo 7145ba7a89SDavid Gowdef build_tests(linux: kunit_kernel.LinuxSourceTree, 7245ba7a89SDavid Gow request: KunitBuildRequest) -> KunitResult: 736ebf5866SFelix Guo kunit_parser.print_with_timestamp('Building KUnit Kernel ...') 746ebf5866SFelix Guo 756ebf5866SFelix Guo build_start = time.time() 7687c9c163SBrendan Higgins success = linux.build_kernel(request.alltests, 77021ed9f5SHeidi Fahim request.jobs, 780476e69fSGreg Thelen request.build_dir, 790476e69fSGreg Thelen request.make_options) 806ebf5866SFelix Guo build_end = time.time() 816ebf5866SFelix Guo if not success: 82ee61492aSDavid Gow return KunitResult(KunitStatus.BUILD_FAILURE, 83ee61492aSDavid Gow 'could not build kernel', 84ee61492aSDavid Gow build_end - build_start) 8545ba7a89SDavid Gow if not success: 8645ba7a89SDavid Gow return KunitResult(KunitStatus.BUILD_FAILURE, 8745ba7a89SDavid Gow 'could not build kernel', 8845ba7a89SDavid Gow build_end - build_start) 8945ba7a89SDavid Gow return KunitResult(KunitStatus.SUCCESS, 9045ba7a89SDavid Gow 'built kernel successfully', 9145ba7a89SDavid Gow build_end - build_start) 926ebf5866SFelix Guo 93*7ef925eaSDaniel Latypovdef exec_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest, 94*7ef925eaSDaniel Latypov parse_request: KunitParseRequest) -> KunitResult: 956ebf5866SFelix Guo kunit_parser.print_with_timestamp('Starting KUnit Kernel ...') 966ebf5866SFelix Guo test_start = time.time() 97*7ef925eaSDaniel Latypov run_result = linux.run_kernel( 986cb51a18SDaniel Latypov args=request.kernel_args, 99021ed9f5SHeidi Fahim timeout=None if request.alltests else request.timeout, 100d992880bSDaniel Latypov filter_glob=request.filter_glob, 1016ec1b81dSSeongJae Park build_dir=request.build_dir) 10245ba7a89SDavid Gow 1036ebf5866SFelix Guo test_end = time.time() 104*7ef925eaSDaniel Latypov exec_time = test_end - test_start 1056ebf5866SFelix Guo 106*7ef925eaSDaniel Latypov # Named tuples are immutable, so we rebuild them here manually 107*7ef925eaSDaniel Latypov result = parse_tests(parse_request, run_result) 10845ba7a89SDavid Gow 109*7ef925eaSDaniel Latypov return KunitResult(status=result.status, result=result.result, elapsed_time=exec_time) 110*7ef925eaSDaniel Latypov 111*7ef925eaSDaniel Latypovdef parse_tests(request: KunitParseRequest, input_data: Iterable[str]) -> KunitResult: 11245ba7a89SDavid Gow parse_start = time.time() 11345ba7a89SDavid Gow 11445ba7a89SDavid Gow test_result = kunit_parser.TestResult(kunit_parser.TestStatus.SUCCESS, 11545ba7a89SDavid Gow [], 11645ba7a89SDavid Gow 'Tests not Parsed.') 11721a6d178SHeidi Fahim 11845ba7a89SDavid Gow if request.raw_output: 119*7ef925eaSDaniel Latypov output: Iterable[str] = input_data 1206a499c9cSDaniel Latypov if request.raw_output == 'all': 1216a499c9cSDaniel Latypov pass 1226a499c9cSDaniel Latypov elif request.raw_output == 'kunit': 1236a499c9cSDaniel Latypov output = kunit_parser.extract_tap_lines(output) 1246a499c9cSDaniel Latypov else: 1256a499c9cSDaniel Latypov print(f'Unknown --raw_output option "{request.raw_output}"', file=sys.stderr) 1266a499c9cSDaniel Latypov for line in output: 1276a499c9cSDaniel Latypov print(line.rstrip()) 1286a499c9cSDaniel Latypov 12945ba7a89SDavid Gow else: 130*7ef925eaSDaniel Latypov test_result = kunit_parser.parse_run_tests(input_data) 13145ba7a89SDavid Gow parse_end = time.time() 13245ba7a89SDavid Gow 13321a6d178SHeidi Fahim if request.json: 13421a6d178SHeidi Fahim json_obj = kunit_json.get_json_result( 13521a6d178SHeidi Fahim test_result=test_result, 13621a6d178SHeidi Fahim def_config='kunit_defconfig', 13721a6d178SHeidi Fahim build_dir=request.build_dir, 13821a6d178SHeidi Fahim json_path=request.json) 13921a6d178SHeidi Fahim if request.json == 'stdout': 14021a6d178SHeidi Fahim print(json_obj) 14121a6d178SHeidi Fahim 14245ba7a89SDavid Gow if test_result.status != kunit_parser.TestStatus.SUCCESS: 14345ba7a89SDavid Gow return KunitResult(KunitStatus.TEST_FAILURE, test_result, 14445ba7a89SDavid Gow parse_end - parse_start) 14545ba7a89SDavid Gow 14645ba7a89SDavid Gow return KunitResult(KunitStatus.SUCCESS, test_result, 14745ba7a89SDavid Gow parse_end - parse_start) 14845ba7a89SDavid Gow 14945ba7a89SDavid Gowdef run_tests(linux: kunit_kernel.LinuxSourceTree, 15045ba7a89SDavid Gow request: KunitRequest) -> KunitResult: 15145ba7a89SDavid Gow run_start = time.time() 15245ba7a89SDavid Gow 15345ba7a89SDavid Gow config_request = KunitConfigRequest(request.build_dir, 15445ba7a89SDavid Gow request.make_options) 15545ba7a89SDavid Gow config_result = config_tests(linux, config_request) 15645ba7a89SDavid Gow if config_result.status != KunitStatus.SUCCESS: 15745ba7a89SDavid Gow return config_result 15845ba7a89SDavid Gow 15945ba7a89SDavid Gow build_request = KunitBuildRequest(request.jobs, request.build_dir, 16045ba7a89SDavid Gow request.alltests, 16145ba7a89SDavid Gow request.make_options) 16245ba7a89SDavid Gow build_result = build_tests(linux, build_request) 16345ba7a89SDavid Gow if build_result.status != KunitStatus.SUCCESS: 16445ba7a89SDavid Gow return build_result 16545ba7a89SDavid Gow 16645ba7a89SDavid Gow exec_request = KunitExecRequest(request.timeout, request.build_dir, 1676cb51a18SDaniel Latypov request.alltests, request.filter_glob, 1686cb51a18SDaniel Latypov request.kernel_args) 16945ba7a89SDavid Gow parse_request = KunitParseRequest(request.raw_output, 17021a6d178SHeidi Fahim request.build_dir, 17121a6d178SHeidi Fahim request.json) 172*7ef925eaSDaniel Latypov 173*7ef925eaSDaniel Latypov exec_result = exec_tests(linux, exec_request, parse_request) 17445ba7a89SDavid Gow 17545ba7a89SDavid Gow run_end = time.time() 17645ba7a89SDavid Gow 1776ebf5866SFelix Guo kunit_parser.print_with_timestamp(( 1786ebf5866SFelix Guo 'Elapsed time: %.3fs total, %.3fs configuring, %.3fs ' + 1796ebf5866SFelix Guo 'building, %.3fs running\n') % ( 18045ba7a89SDavid Gow run_end - run_start, 18145ba7a89SDavid Gow config_result.elapsed_time, 18245ba7a89SDavid Gow build_result.elapsed_time, 18345ba7a89SDavid Gow exec_result.elapsed_time)) 184*7ef925eaSDaniel Latypov return exec_result 1856ebf5866SFelix Guo 186d8c23eadSDaniel Latypov# Problem: 187d8c23eadSDaniel Latypov# $ kunit.py run --json 188d8c23eadSDaniel Latypov# works as one would expect and prints the parsed test results as JSON. 189d8c23eadSDaniel Latypov# $ kunit.py run --json suite_name 190d8c23eadSDaniel Latypov# would *not* pass suite_name as the filter_glob and print as json. 191d8c23eadSDaniel Latypov# argparse will consider it to be another way of writing 192d8c23eadSDaniel Latypov# $ kunit.py run --json=suite_name 193d8c23eadSDaniel Latypov# i.e. it would run all tests, and dump the json to a `suite_name` file. 194d8c23eadSDaniel Latypov# So we hackily automatically rewrite --json => --json=stdout 195d8c23eadSDaniel Latypovpseudo_bool_flag_defaults = { 196d8c23eadSDaniel Latypov '--json': 'stdout', 197d8c23eadSDaniel Latypov '--raw_output': 'kunit', 198d8c23eadSDaniel Latypov} 199d8c23eadSDaniel Latypovdef massage_argv(argv: Sequence[str]) -> Sequence[str]: 200d8c23eadSDaniel Latypov def massage_arg(arg: str) -> str: 201d8c23eadSDaniel Latypov if arg not in pseudo_bool_flag_defaults: 202d8c23eadSDaniel Latypov return arg 203d8c23eadSDaniel Latypov return f'{arg}={pseudo_bool_flag_defaults[arg]}' 204d8c23eadSDaniel Latypov return list(map(massage_arg, argv)) 205d8c23eadSDaniel Latypov 20609641f7cSDaniel Latypovdef add_common_opts(parser) -> None: 20745ba7a89SDavid Gow parser.add_argument('--build_dir', 20845ba7a89SDavid Gow help='As in the make command, it specifies the build ' 20945ba7a89SDavid Gow 'directory.', 210ddbd60c7SVitor Massaru Iha type=str, default='.kunit', metavar='build_dir') 21145ba7a89SDavid Gow parser.add_argument('--make_options', 21245ba7a89SDavid Gow help='X=Y make option, can be repeated.', 21345ba7a89SDavid Gow action='append') 21445ba7a89SDavid Gow parser.add_argument('--alltests', 21545ba7a89SDavid Gow help='Run all KUnit tests through allyesconfig', 2166ebf5866SFelix Guo action='store_true') 217243180f5SDaniel Latypov parser.add_argument('--kunitconfig', 2189854781dSDaniel Latypov help='Path to Kconfig fragment that enables KUnit tests.' 2199854781dSDaniel Latypov ' If given a directory, (e.g. lib/kunit), "/.kunitconfig" ' 2209854781dSDaniel Latypov 'will get automatically appended.', 221243180f5SDaniel Latypov metavar='kunitconfig') 2226ebf5866SFelix Guo 22387c9c163SBrendan Higgins parser.add_argument('--arch', 22487c9c163SBrendan Higgins help=('Specifies the architecture to run tests under. ' 22587c9c163SBrendan Higgins 'The architecture specified here must match the ' 22687c9c163SBrendan Higgins 'string passed to the ARCH make param, ' 22787c9c163SBrendan Higgins 'e.g. i386, x86_64, arm, um, etc. Non-UML ' 22887c9c163SBrendan Higgins 'architectures run on QEMU.'), 22987c9c163SBrendan Higgins type=str, default='um', metavar='arch') 23087c9c163SBrendan Higgins 23187c9c163SBrendan Higgins parser.add_argument('--cross_compile', 23287c9c163SBrendan Higgins help=('Sets make\'s CROSS_COMPILE variable; it should ' 23387c9c163SBrendan Higgins 'be set to a toolchain path prefix (the prefix ' 23487c9c163SBrendan Higgins 'of gcc and other tools in your toolchain, for ' 23587c9c163SBrendan Higgins 'example `sparc64-linux-gnu-` if you have the ' 23687c9c163SBrendan Higgins 'sparc toolchain installed on your system, or ' 23787c9c163SBrendan Higgins '`$HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/microblaze-linux-` ' 23887c9c163SBrendan Higgins 'if you have downloaded the microblaze toolchain ' 23987c9c163SBrendan Higgins 'from the 0-day website to a directory in your ' 24087c9c163SBrendan Higgins 'home directory called `toolchains`).'), 24187c9c163SBrendan Higgins metavar='cross_compile') 24287c9c163SBrendan Higgins 24387c9c163SBrendan Higgins parser.add_argument('--qemu_config', 24487c9c163SBrendan Higgins help=('Takes a path to a path to a file containing ' 24587c9c163SBrendan Higgins 'a QemuArchParams object.'), 24687c9c163SBrendan Higgins type=str, metavar='qemu_config') 24787c9c163SBrendan Higgins 24809641f7cSDaniel Latypovdef add_build_opts(parser) -> None: 24945ba7a89SDavid Gow parser.add_argument('--jobs', 25045ba7a89SDavid Gow help='As in the make command, "Specifies the number of ' 25145ba7a89SDavid Gow 'jobs (commands) to run simultaneously."', 25245ba7a89SDavid Gow type=int, default=8, metavar='jobs') 25345ba7a89SDavid Gow 25409641f7cSDaniel Latypovdef add_exec_opts(parser) -> None: 25545ba7a89SDavid Gow parser.add_argument('--timeout', 2566ebf5866SFelix Guo help='maximum number of seconds to allow for all tests ' 2576ebf5866SFelix Guo 'to run. This does not include time taken to build the ' 2586ebf5866SFelix Guo 'tests.', 2596ebf5866SFelix Guo type=int, 2606ebf5866SFelix Guo default=300, 2616ebf5866SFelix Guo metavar='timeout') 262d992880bSDaniel Latypov parser.add_argument('filter_glob', 263a127b154SDaniel Latypov help='Filter which KUnit test suites/tests run at ' 264a127b154SDaniel Latypov 'boot-time, e.g. list* or list*.*del_test', 265d992880bSDaniel Latypov type=str, 266d992880bSDaniel Latypov nargs='?', 267d992880bSDaniel Latypov default='', 268d992880bSDaniel Latypov metavar='filter_glob') 2696cb51a18SDaniel Latypov parser.add_argument('--kernel_args', 2706cb51a18SDaniel Latypov help='Kernel command-line parameters. Maybe be repeated', 2716cb51a18SDaniel Latypov action='append') 2726ebf5866SFelix Guo 27309641f7cSDaniel Latypovdef add_parse_opts(parser) -> None: 2746a499c9cSDaniel Latypov parser.add_argument('--raw_output', help='If set don\'t format output from kernel. ' 2756a499c9cSDaniel Latypov 'If set to --raw_output=kunit, filters to just KUnit output.', 2766a499c9cSDaniel Latypov type=str, nargs='?', const='all', default=None) 27721a6d178SHeidi Fahim parser.add_argument('--json', 27821a6d178SHeidi Fahim nargs='?', 27921a6d178SHeidi Fahim help='Stores test results in a JSON, and either ' 28021a6d178SHeidi Fahim 'prints to stdout or saves to file if a ' 28121a6d178SHeidi Fahim 'filename is specified', 28221a6d178SHeidi Fahim type=str, const='stdout', default=None) 283021ed9f5SHeidi Fahim 28445ba7a89SDavid Gowdef main(argv, linux=None): 28545ba7a89SDavid Gow parser = argparse.ArgumentParser( 28645ba7a89SDavid Gow description='Helps writing and running KUnit tests.') 28745ba7a89SDavid Gow subparser = parser.add_subparsers(dest='subcommand') 28845ba7a89SDavid Gow 28945ba7a89SDavid Gow # The 'run' command will config, build, exec, and parse in one go. 29045ba7a89SDavid Gow run_parser = subparser.add_parser('run', help='Runs KUnit tests.') 29145ba7a89SDavid Gow add_common_opts(run_parser) 29245ba7a89SDavid Gow add_build_opts(run_parser) 29345ba7a89SDavid Gow add_exec_opts(run_parser) 29445ba7a89SDavid Gow add_parse_opts(run_parser) 29545ba7a89SDavid Gow 29645ba7a89SDavid Gow config_parser = subparser.add_parser('config', 29745ba7a89SDavid Gow help='Ensures that .config contains all of ' 29845ba7a89SDavid Gow 'the options in .kunitconfig') 29945ba7a89SDavid Gow add_common_opts(config_parser) 30045ba7a89SDavid Gow 30145ba7a89SDavid Gow build_parser = subparser.add_parser('build', help='Builds a kernel with KUnit tests') 30245ba7a89SDavid Gow add_common_opts(build_parser) 30345ba7a89SDavid Gow add_build_opts(build_parser) 30445ba7a89SDavid Gow 30545ba7a89SDavid Gow exec_parser = subparser.add_parser('exec', help='Run a kernel with KUnit tests') 30645ba7a89SDavid Gow add_common_opts(exec_parser) 30745ba7a89SDavid Gow add_exec_opts(exec_parser) 30845ba7a89SDavid Gow add_parse_opts(exec_parser) 30945ba7a89SDavid Gow 31045ba7a89SDavid Gow # The 'parse' option is special, as it doesn't need the kernel source 31145ba7a89SDavid Gow # (therefore there is no need for a build_dir, hence no add_common_opts) 31245ba7a89SDavid Gow # and the '--file' argument is not relevant to 'run', so isn't in 31345ba7a89SDavid Gow # add_parse_opts() 31445ba7a89SDavid Gow parse_parser = subparser.add_parser('parse', 31545ba7a89SDavid Gow help='Parses KUnit results from a file, ' 31645ba7a89SDavid Gow 'and parses formatted results.') 31745ba7a89SDavid Gow add_parse_opts(parse_parser) 31845ba7a89SDavid Gow parse_parser.add_argument('file', 31945ba7a89SDavid Gow help='Specifies the file to read results from.', 32045ba7a89SDavid Gow type=str, nargs='?', metavar='input_file') 3210476e69fSGreg Thelen 322d8c23eadSDaniel Latypov cli_args = parser.parse_args(massage_argv(argv)) 3236ebf5866SFelix Guo 3245578d008SBrendan Higgins if get_kernel_root_path(): 3255578d008SBrendan Higgins os.chdir(get_kernel_root_path()) 3265578d008SBrendan Higgins 3276ebf5866SFelix Guo if cli_args.subcommand == 'run': 328e3212513SSeongJae Park if not os.path.exists(cli_args.build_dir): 329e3212513SSeongJae Park os.mkdir(cli_args.build_dir) 33082206a0cSBrendan Higgins 331ff7b437fSBrendan Higgins if not linux: 33287c9c163SBrendan Higgins linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir, 33387c9c163SBrendan Higgins kunitconfig_path=cli_args.kunitconfig, 33487c9c163SBrendan Higgins arch=cli_args.arch, 33587c9c163SBrendan Higgins cross_compile=cli_args.cross_compile, 33687c9c163SBrendan Higgins qemu_config_path=cli_args.qemu_config) 337fcdb0bc0SAndy Shevchenko 3386ebf5866SFelix Guo request = KunitRequest(cli_args.raw_output, 3396ebf5866SFelix Guo cli_args.timeout, 3406ebf5866SFelix Guo cli_args.jobs, 341ff7b437fSBrendan Higgins cli_args.build_dir, 3420476e69fSGreg Thelen cli_args.alltests, 343d992880bSDaniel Latypov cli_args.filter_glob, 3446cb51a18SDaniel Latypov cli_args.kernel_args, 34521a6d178SHeidi Fahim cli_args.json, 3460476e69fSGreg Thelen cli_args.make_options) 3476ebf5866SFelix Guo result = run_tests(linux, request) 3486ebf5866SFelix Guo if result.status != KunitStatus.SUCCESS: 3496ebf5866SFelix Guo sys.exit(1) 35045ba7a89SDavid Gow elif cli_args.subcommand == 'config': 35182206a0cSBrendan Higgins if cli_args.build_dir and ( 35282206a0cSBrendan Higgins not os.path.exists(cli_args.build_dir)): 35345ba7a89SDavid Gow os.mkdir(cli_args.build_dir) 35482206a0cSBrendan Higgins 35545ba7a89SDavid Gow if not linux: 35687c9c163SBrendan Higgins linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir, 35787c9c163SBrendan Higgins kunitconfig_path=cli_args.kunitconfig, 35887c9c163SBrendan Higgins arch=cli_args.arch, 35987c9c163SBrendan Higgins cross_compile=cli_args.cross_compile, 36087c9c163SBrendan Higgins qemu_config_path=cli_args.qemu_config) 361fcdb0bc0SAndy Shevchenko 36245ba7a89SDavid Gow request = KunitConfigRequest(cli_args.build_dir, 36345ba7a89SDavid Gow cli_args.make_options) 36445ba7a89SDavid Gow result = config_tests(linux, request) 36545ba7a89SDavid Gow kunit_parser.print_with_timestamp(( 36645ba7a89SDavid Gow 'Elapsed time: %.3fs\n') % ( 36745ba7a89SDavid Gow result.elapsed_time)) 36845ba7a89SDavid Gow if result.status != KunitStatus.SUCCESS: 36945ba7a89SDavid Gow sys.exit(1) 37045ba7a89SDavid Gow elif cli_args.subcommand == 'build': 37145ba7a89SDavid Gow if not linux: 37287c9c163SBrendan Higgins linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir, 37387c9c163SBrendan Higgins kunitconfig_path=cli_args.kunitconfig, 37487c9c163SBrendan Higgins arch=cli_args.arch, 37587c9c163SBrendan Higgins cross_compile=cli_args.cross_compile, 37687c9c163SBrendan Higgins qemu_config_path=cli_args.qemu_config) 377fcdb0bc0SAndy Shevchenko 37845ba7a89SDavid Gow request = KunitBuildRequest(cli_args.jobs, 37945ba7a89SDavid Gow cli_args.build_dir, 38045ba7a89SDavid Gow cli_args.alltests, 38145ba7a89SDavid Gow cli_args.make_options) 38245ba7a89SDavid Gow result = build_tests(linux, request) 38345ba7a89SDavid Gow kunit_parser.print_with_timestamp(( 38445ba7a89SDavid Gow 'Elapsed time: %.3fs\n') % ( 38545ba7a89SDavid Gow result.elapsed_time)) 38645ba7a89SDavid Gow if result.status != KunitStatus.SUCCESS: 38745ba7a89SDavid Gow sys.exit(1) 38845ba7a89SDavid Gow elif cli_args.subcommand == 'exec': 38945ba7a89SDavid Gow if not linux: 39087c9c163SBrendan Higgins linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir, 39187c9c163SBrendan Higgins kunitconfig_path=cli_args.kunitconfig, 39287c9c163SBrendan Higgins arch=cli_args.arch, 39387c9c163SBrendan Higgins cross_compile=cli_args.cross_compile, 39487c9c163SBrendan Higgins qemu_config_path=cli_args.qemu_config) 395fcdb0bc0SAndy Shevchenko 39645ba7a89SDavid Gow exec_request = KunitExecRequest(cli_args.timeout, 39745ba7a89SDavid Gow cli_args.build_dir, 398d992880bSDaniel Latypov cli_args.alltests, 3996cb51a18SDaniel Latypov cli_args.filter_glob, 4006cb51a18SDaniel Latypov cli_args.kernel_args) 40145ba7a89SDavid Gow parse_request = KunitParseRequest(cli_args.raw_output, 40221a6d178SHeidi Fahim cli_args.build_dir, 40321a6d178SHeidi Fahim cli_args.json) 404*7ef925eaSDaniel Latypov result = exec_tests(linux, exec_request, parse_request) 40545ba7a89SDavid Gow kunit_parser.print_with_timestamp(( 406*7ef925eaSDaniel Latypov 'Elapsed time: %.3fs\n') % (result.elapsed_time)) 40745ba7a89SDavid Gow if result.status != KunitStatus.SUCCESS: 40845ba7a89SDavid Gow sys.exit(1) 40945ba7a89SDavid Gow elif cli_args.subcommand == 'parse': 41045ba7a89SDavid Gow if cli_args.file == None: 41145ba7a89SDavid Gow kunit_output = sys.stdin 41245ba7a89SDavid Gow else: 41345ba7a89SDavid Gow with open(cli_args.file, 'r') as f: 41445ba7a89SDavid Gow kunit_output = f.read().splitlines() 41545ba7a89SDavid Gow request = KunitParseRequest(cli_args.raw_output, 4163959d0a6SDavid Gow None, 41721a6d178SHeidi Fahim cli_args.json) 418*7ef925eaSDaniel Latypov result = parse_tests(request, kunit_output) 41945ba7a89SDavid Gow if result.status != KunitStatus.SUCCESS: 42045ba7a89SDavid Gow sys.exit(1) 4216ebf5866SFelix Guo else: 4226ebf5866SFelix Guo parser.print_help() 4236ebf5866SFelix Guo 4246ebf5866SFelix Guoif __name__ == '__main__': 425ff7b437fSBrendan Higgins main(sys.argv[1:]) 426