diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-11-25 15:01:30 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-11-25 15:01:30 -0800 |
commit | e25645b181ae67753f9a48e11bb5b34dcf41187d (patch) | |
tree | bbcaf23c38d83faa48a52433625b9f2851cbf990 /tools/testing/kunit/kunit.py | |
parent | db7d275415d774de3d2151d6885bf61c33243419 (diff) | |
parent | ea2dd7c0875ed31955cda7b1b20612c8337192e5 (diff) |
Merge tag 'linux-kselftest-5.5-rc1-kunit' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kselftest KUnit support gtom Shuah Khan:
"This adds KUnit, a lightweight unit testing and mocking framework for
the Linux kernel from Brendan Higgins.
KUnit is not an end-to-end testing framework. It is currently
supported on UML and sub-systems can write unit tests and run them in
UML env. KUnit documentation is included in this update.
In addition, this Kunit update adds 3 new kunit tests:
- proc sysctl test from Iurii Zaikin
- the 'list' doubly linked list test from David Gow
- ext4 tests for decoding extended timestamps from Iurii Zaikin
In the future KUnit will be linked to Kselftest framework to provide a
way to trigger KUnit tests from user-space"
* tag 'linux-kselftest-5.5-rc1-kunit' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (23 commits)
lib/list-test: add a test for the 'list' doubly linked list
ext4: add kunit test for decoding extended timestamps
Documentation: kunit: Fix verification command
kunit: Fix '--build_dir' option
kunit: fix failure to build without printk
MAINTAINERS: add proc sysctl KUnit test to PROC SYSCTL section
kernel/sysctl-test: Add null pointer test for sysctl.c:proc_dointvec()
MAINTAINERS: add entry for KUnit the unit testing framework
Documentation: kunit: add documentation for KUnit
kunit: defconfig: add defconfigs for building KUnit tests
kunit: tool: add Python wrappers for running KUnit tests
kunit: test: add tests for KUnit managed resources
kunit: test: add the concept of assertions
kunit: test: add tests for kunit test abort
kunit: test: add support for test abort
objtool: add kunit_try_catch_throw to the noreturn list
kunit: test: add initial tests
lib: enable building KUnit in lib/
kunit: test: add the concept of expectations
kunit: test: add assertion printing library
...
Diffstat (limited to 'tools/testing/kunit/kunit.py')
-rwxr-xr-x | tools/testing/kunit/kunit.py | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py new file mode 100755 index 000000000000..efe06d621983 --- /dev/null +++ b/tools/testing/kunit/kunit.py @@ -0,0 +1,138 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0 +# +# A thin wrapper on top of the KUnit Kernel +# +# Copyright (C) 2019, Google LLC. +# Author: Felix Guo <felixguoxiuping@gmail.com> +# Author: Brendan Higgins <brendanhiggins@google.com> + +import argparse +import sys +import os +import time +import shutil + +from collections import namedtuple +from enum import Enum, auto + +import kunit_config +import kunit_kernel +import kunit_parser + +KunitResult = namedtuple('KunitResult', ['status','result']) + +KunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs', 'build_dir', 'defconfig']) + +class KunitStatus(Enum): + SUCCESS = auto() + CONFIG_FAILURE = auto() + BUILD_FAILURE = auto() + TEST_FAILURE = auto() + +def create_default_kunitconfig(): + if not os.path.exists(kunit_kernel.KUNITCONFIG_PATH): + shutil.copyfile('arch/um/configs/kunit_defconfig', + kunit_kernel.KUNITCONFIG_PATH) + +def run_tests(linux: kunit_kernel.LinuxSourceTree, + request: KunitRequest) -> KunitResult: + if request.defconfig: + create_default_kunitconfig() + + config_start = time.time() + success = linux.build_reconfig(request.build_dir) + config_end = time.time() + if not success: + return KunitResult(KunitStatus.CONFIG_FAILURE, 'could not configure kernel') + + kunit_parser.print_with_timestamp('Building KUnit Kernel ...') + + build_start = time.time() + success = linux.build_um_kernel(request.jobs, request.build_dir) + build_end = time.time() + if not success: + return KunitResult(KunitStatus.BUILD_FAILURE, 'could not build kernel') + + kunit_parser.print_with_timestamp('Starting KUnit Kernel ...') + test_start = time.time() + + test_result = kunit_parser.TestResult(kunit_parser.TestStatus.SUCCESS, + [], + 'Tests not Parsed.') + if request.raw_output: + kunit_parser.raw_output( + linux.run_kernel(timeout=request.timeout, + build_dir=request.build_dir)) + else: + kunit_output = linux.run_kernel(timeout=request.timeout, + build_dir=request.build_dir) + test_result = kunit_parser.parse_run_tests(kunit_output) + test_end = time.time() + + kunit_parser.print_with_timestamp(( + 'Elapsed time: %.3fs total, %.3fs configuring, %.3fs ' + + 'building, %.3fs running\n') % ( + test_end - config_start, + config_end - config_start, + build_end - build_start, + test_end - test_start)) + + if test_result.status != kunit_parser.TestStatus.SUCCESS: + return KunitResult(KunitStatus.TEST_FAILURE, test_result) + else: + return KunitResult(KunitStatus.SUCCESS, test_result) + +def main(argv, linux=None): + parser = argparse.ArgumentParser( + description='Helps writing and running KUnit tests.') + subparser = parser.add_subparsers(dest='subcommand') + + run_parser = subparser.add_parser('run', help='Runs KUnit tests.') + run_parser.add_argument('--raw_output', help='don\'t format output from kernel', + action='store_true') + + run_parser.add_argument('--timeout', + help='maximum number of seconds to allow for all tests ' + 'to run. This does not include time taken to build the ' + 'tests.', + type=int, + default=300, + metavar='timeout') + + run_parser.add_argument('--jobs', + help='As in the make command, "Specifies the number of ' + 'jobs (commands) to run simultaneously."', + type=int, default=8, metavar='jobs') + + run_parser.add_argument('--build_dir', + help='As in the make command, it specifies the build ' + 'directory.', + type=str, default=None, metavar='build_dir') + + run_parser.add_argument('--defconfig', + help='Uses a default kunitconfig.', + action='store_true') + + cli_args = parser.parse_args(argv) + + if cli_args.subcommand == 'run': + if cli_args.defconfig: + create_default_kunitconfig() + + if not linux: + linux = kunit_kernel.LinuxSourceTree() + + request = KunitRequest(cli_args.raw_output, + cli_args.timeout, + cli_args.jobs, + cli_args.build_dir, + cli_args.defconfig) + result = run_tests(linux, request) + if result.status != KunitStatus.SUCCESS: + sys.exit(1) + else: + parser.print_help() + +if __name__ == '__main__': + main(sys.argv[1:]) |