16ebf5866SFelix Guo#!/usr/bin/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 14ff7b437fSBrendan Higginsimport shutil 156ebf5866SFelix Guo 166ebf5866SFelix Guofrom collections import namedtuple 176ebf5866SFelix Guofrom enum import Enum, auto 186ebf5866SFelix Guo 196ebf5866SFelix Guoimport kunit_config 206ebf5866SFelix Guoimport kunit_kernel 216ebf5866SFelix Guoimport kunit_parser 226ebf5866SFelix Guo 236ebf5866SFelix GuoKunitResult = namedtuple('KunitResult', ['status','result']) 246ebf5866SFelix Guo 25ff7b437fSBrendan HigginsKunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs', 'build_dir', 'defconfig']) 266ebf5866SFelix Guo 276ebf5866SFelix Guoclass KunitStatus(Enum): 286ebf5866SFelix Guo SUCCESS = auto() 296ebf5866SFelix Guo CONFIG_FAILURE = auto() 306ebf5866SFelix Guo BUILD_FAILURE = auto() 316ebf5866SFelix Guo TEST_FAILURE = auto() 326ebf5866SFelix Guo 33ff7b437fSBrendan Higginsdef create_default_kunitconfig(): 34ff7b437fSBrendan Higgins if not os.path.exists(kunit_kernel.KUNITCONFIG_PATH): 35ff7b437fSBrendan Higgins shutil.copyfile('arch/um/configs/kunit_defconfig', 36ff7b437fSBrendan Higgins kunit_kernel.KUNITCONFIG_PATH) 37ff7b437fSBrendan Higgins 386ebf5866SFelix Guodef run_tests(linux: kunit_kernel.LinuxSourceTree, 396ebf5866SFelix Guo request: KunitRequest) -> KunitResult: 40ff7b437fSBrendan Higgins if request.defconfig: 41ff7b437fSBrendan Higgins create_default_kunitconfig() 42ff7b437fSBrendan Higgins 436ebf5866SFelix Guo config_start = time.time() 446ebf5866SFelix Guo success = linux.build_reconfig(request.build_dir) 456ebf5866SFelix Guo config_end = time.time() 466ebf5866SFelix Guo if not success: 476ebf5866SFelix Guo return KunitResult(KunitStatus.CONFIG_FAILURE, 'could not configure kernel') 486ebf5866SFelix Guo 496ebf5866SFelix Guo kunit_parser.print_with_timestamp('Building KUnit Kernel ...') 506ebf5866SFelix Guo 516ebf5866SFelix Guo build_start = time.time() 526ebf5866SFelix Guo success = linux.build_um_kernel(request.jobs, request.build_dir) 536ebf5866SFelix Guo build_end = time.time() 546ebf5866SFelix Guo if not success: 556ebf5866SFelix Guo return KunitResult(KunitStatus.BUILD_FAILURE, 'could not build kernel') 566ebf5866SFelix Guo 576ebf5866SFelix Guo kunit_parser.print_with_timestamp('Starting KUnit Kernel ...') 586ebf5866SFelix Guo test_start = time.time() 596ebf5866SFelix Guo 606ebf5866SFelix Guo test_result = kunit_parser.TestResult(kunit_parser.TestStatus.SUCCESS, 616ebf5866SFelix Guo [], 626ebf5866SFelix Guo 'Tests not Parsed.') 636ebf5866SFelix Guo if request.raw_output: 646ebf5866SFelix Guo kunit_parser.raw_output( 65*6ec1b81dSSeongJae Park linux.run_kernel(timeout=request.timeout, 66*6ec1b81dSSeongJae Park build_dir=request.build_dir)) 676ebf5866SFelix Guo else: 68*6ec1b81dSSeongJae Park kunit_output = linux.run_kernel(timeout=request.timeout, 69*6ec1b81dSSeongJae Park build_dir=request.build_dir) 706ebf5866SFelix Guo test_result = kunit_parser.parse_run_tests(kunit_output) 716ebf5866SFelix Guo test_end = time.time() 726ebf5866SFelix Guo 736ebf5866SFelix Guo kunit_parser.print_with_timestamp(( 746ebf5866SFelix Guo 'Elapsed time: %.3fs total, %.3fs configuring, %.3fs ' + 756ebf5866SFelix Guo 'building, %.3fs running\n') % ( 766ebf5866SFelix Guo test_end - config_start, 776ebf5866SFelix Guo config_end - config_start, 786ebf5866SFelix Guo build_end - build_start, 796ebf5866SFelix Guo test_end - test_start)) 806ebf5866SFelix Guo 816ebf5866SFelix Guo if test_result.status != kunit_parser.TestStatus.SUCCESS: 826ebf5866SFelix Guo return KunitResult(KunitStatus.TEST_FAILURE, test_result) 836ebf5866SFelix Guo else: 846ebf5866SFelix Guo return KunitResult(KunitStatus.SUCCESS, test_result) 856ebf5866SFelix Guo 86ff7b437fSBrendan Higginsdef main(argv, linux=None): 876ebf5866SFelix Guo parser = argparse.ArgumentParser( 886ebf5866SFelix Guo description='Helps writing and running KUnit tests.') 896ebf5866SFelix Guo subparser = parser.add_subparsers(dest='subcommand') 906ebf5866SFelix Guo 916ebf5866SFelix Guo run_parser = subparser.add_parser('run', help='Runs KUnit tests.') 926ebf5866SFelix Guo run_parser.add_argument('--raw_output', help='don\'t format output from kernel', 936ebf5866SFelix Guo action='store_true') 946ebf5866SFelix Guo 956ebf5866SFelix Guo run_parser.add_argument('--timeout', 966ebf5866SFelix Guo help='maximum number of seconds to allow for all tests ' 976ebf5866SFelix Guo 'to run. This does not include time taken to build the ' 986ebf5866SFelix Guo 'tests.', 996ebf5866SFelix Guo type=int, 1006ebf5866SFelix Guo default=300, 1016ebf5866SFelix Guo metavar='timeout') 1026ebf5866SFelix Guo 1036ebf5866SFelix Guo run_parser.add_argument('--jobs', 1046ebf5866SFelix Guo help='As in the make command, "Specifies the number of ' 1056ebf5866SFelix Guo 'jobs (commands) to run simultaneously."', 1066ebf5866SFelix Guo type=int, default=8, metavar='jobs') 1076ebf5866SFelix Guo 1086ebf5866SFelix Guo run_parser.add_argument('--build_dir', 1096ebf5866SFelix Guo help='As in the make command, it specifies the build ' 1106ebf5866SFelix Guo 'directory.', 1116ebf5866SFelix Guo type=str, default=None, metavar='build_dir') 1126ebf5866SFelix Guo 113ff7b437fSBrendan Higgins run_parser.add_argument('--defconfig', 114ff7b437fSBrendan Higgins help='Uses a default kunitconfig.', 115ff7b437fSBrendan Higgins action='store_true') 116ff7b437fSBrendan Higgins 1176ebf5866SFelix Guo cli_args = parser.parse_args(argv) 1186ebf5866SFelix Guo 1196ebf5866SFelix Guo if cli_args.subcommand == 'run': 120ff7b437fSBrendan Higgins if cli_args.defconfig: 121ff7b437fSBrendan Higgins create_default_kunitconfig() 122ff7b437fSBrendan Higgins 123ff7b437fSBrendan Higgins if not linux: 124ff7b437fSBrendan Higgins linux = kunit_kernel.LinuxSourceTree() 125ff7b437fSBrendan Higgins 1266ebf5866SFelix Guo request = KunitRequest(cli_args.raw_output, 1276ebf5866SFelix Guo cli_args.timeout, 1286ebf5866SFelix Guo cli_args.jobs, 129ff7b437fSBrendan Higgins cli_args.build_dir, 130ff7b437fSBrendan Higgins cli_args.defconfig) 1316ebf5866SFelix Guo result = run_tests(linux, request) 1326ebf5866SFelix Guo if result.status != KunitStatus.SUCCESS: 1336ebf5866SFelix Guo sys.exit(1) 1346ebf5866SFelix Guo else: 1356ebf5866SFelix Guo parser.print_help() 1366ebf5866SFelix Guo 1376ebf5866SFelix Guoif __name__ == '__main__': 138ff7b437fSBrendan Higgins main(sys.argv[1:]) 139