Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kunit: tool: add Python wrappers for running KUnit tests

The ultimate goal is to create minimal isolated test binaries; in the
meantime we are using UML to provide the infrastructure to run tests, so
define an abstract way to configure and run tests that allow us to
change the context in which tests are built without affecting the user.
This also makes pretty and dynamic error reporting, and a lot of other
nice features easier.

kunit_config.py:
- parse .config and Kconfig files.

kunit_kernel.py: provides helper functions to:
- configure the kernel using kunitconfig.
- build the kernel with the appropriate configuration.
- provide function to invoke the kernel and stream the output back.

kunit_parser.py: parses raw logs returned out by kunit_kernel and
displays them in a user friendly way.

test_data/*: samples of test data for testing kunit.py, kunit_config.py,
etc.

Signed-off-by: Felix Guo <felixguoxiuping@gmail.com>
Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

authored by

Felix Guo and committed by
Shuah Khan
6ebf5866 73ba5aaf

+1184
+3
tools/testing/kunit/.gitignore
··· 1 + # Byte-compiled / optimized / DLL files 2 + __pycache__/ 3 + *.py[cod]
+116
tools/testing/kunit/kunit.py
··· 1 + #!/usr/bin/python3 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # A thin wrapper on top of the KUnit Kernel 5 + # 6 + # Copyright (C) 2019, Google LLC. 7 + # Author: Felix Guo <felixguoxiuping@gmail.com> 8 + # Author: Brendan Higgins <brendanhiggins@google.com> 9 + 10 + import argparse 11 + import sys 12 + import os 13 + import time 14 + 15 + from collections import namedtuple 16 + from enum import Enum, auto 17 + 18 + import kunit_config 19 + import kunit_kernel 20 + import kunit_parser 21 + 22 + KunitResult = namedtuple('KunitResult', ['status','result']) 23 + 24 + KunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs', 'build_dir']) 25 + 26 + class KunitStatus(Enum): 27 + SUCCESS = auto() 28 + CONFIG_FAILURE = auto() 29 + BUILD_FAILURE = auto() 30 + TEST_FAILURE = auto() 31 + 32 + def run_tests(linux: kunit_kernel.LinuxSourceTree, 33 + request: KunitRequest) -> KunitResult: 34 + config_start = time.time() 35 + success = linux.build_reconfig(request.build_dir) 36 + config_end = time.time() 37 + if not success: 38 + return KunitResult(KunitStatus.CONFIG_FAILURE, 'could not configure kernel') 39 + 40 + kunit_parser.print_with_timestamp('Building KUnit Kernel ...') 41 + 42 + build_start = time.time() 43 + success = linux.build_um_kernel(request.jobs, request.build_dir) 44 + build_end = time.time() 45 + if not success: 46 + return KunitResult(KunitStatus.BUILD_FAILURE, 'could not build kernel') 47 + 48 + kunit_parser.print_with_timestamp('Starting KUnit Kernel ...') 49 + test_start = time.time() 50 + 51 + test_result = kunit_parser.TestResult(kunit_parser.TestStatus.SUCCESS, 52 + [], 53 + 'Tests not Parsed.') 54 + if request.raw_output: 55 + kunit_parser.raw_output( 56 + linux.run_kernel(timeout=request.timeout)) 57 + else: 58 + kunit_output = linux.run_kernel(timeout=request.timeout) 59 + test_result = kunit_parser.parse_run_tests(kunit_output) 60 + test_end = time.time() 61 + 62 + kunit_parser.print_with_timestamp(( 63 + 'Elapsed time: %.3fs total, %.3fs configuring, %.3fs ' + 64 + 'building, %.3fs running\n') % ( 65 + test_end - config_start, 66 + config_end - config_start, 67 + build_end - build_start, 68 + test_end - test_start)) 69 + 70 + if test_result.status != kunit_parser.TestStatus.SUCCESS: 71 + return KunitResult(KunitStatus.TEST_FAILURE, test_result) 72 + else: 73 + return KunitResult(KunitStatus.SUCCESS, test_result) 74 + 75 + def main(argv, linux): 76 + parser = argparse.ArgumentParser( 77 + description='Helps writing and running KUnit tests.') 78 + subparser = parser.add_subparsers(dest='subcommand') 79 + 80 + run_parser = subparser.add_parser('run', help='Runs KUnit tests.') 81 + run_parser.add_argument('--raw_output', help='don\'t format output from kernel', 82 + action='store_true') 83 + 84 + run_parser.add_argument('--timeout', 85 + help='maximum number of seconds to allow for all tests ' 86 + 'to run. This does not include time taken to build the ' 87 + 'tests.', 88 + type=int, 89 + default=300, 90 + metavar='timeout') 91 + 92 + run_parser.add_argument('--jobs', 93 + help='As in the make command, "Specifies the number of ' 94 + 'jobs (commands) to run simultaneously."', 95 + type=int, default=8, metavar='jobs') 96 + 97 + run_parser.add_argument('--build_dir', 98 + help='As in the make command, it specifies the build ' 99 + 'directory.', 100 + type=str, default=None, metavar='build_dir') 101 + 102 + cli_args = parser.parse_args(argv) 103 + 104 + if cli_args.subcommand == 'run': 105 + request = KunitRequest(cli_args.raw_output, 106 + cli_args.timeout, 107 + cli_args.jobs, 108 + cli_args.build_dir) 109 + result = run_tests(linux, request) 110 + if result.status != KunitStatus.SUCCESS: 111 + sys.exit(1) 112 + else: 113 + parser.print_help() 114 + 115 + if __name__ == '__main__': 116 + main(sys.argv[1:], kunit_kernel.LinuxSourceTree())
+66
tools/testing/kunit/kunit_config.py
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Builds a .config from a kunitconfig. 4 + # 5 + # Copyright (C) 2019, Google LLC. 6 + # Author: Felix Guo <felixguoxiuping@gmail.com> 7 + # Author: Brendan Higgins <brendanhiggins@google.com> 8 + 9 + import collections 10 + import re 11 + 12 + CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_\w+ is not set$' 13 + CONFIG_PATTERN = r'^CONFIG_\w+=\S+$' 14 + 15 + KconfigEntryBase = collections.namedtuple('KconfigEntry', ['raw_entry']) 16 + 17 + 18 + class KconfigEntry(KconfigEntryBase): 19 + 20 + def __str__(self) -> str: 21 + return self.raw_entry 22 + 23 + 24 + class KconfigParseError(Exception): 25 + """Error parsing Kconfig defconfig or .config.""" 26 + 27 + 28 + class Kconfig(object): 29 + """Represents defconfig or .config specified using the Kconfig language.""" 30 + 31 + def __init__(self): 32 + self._entries = [] 33 + 34 + def entries(self): 35 + return set(self._entries) 36 + 37 + def add_entry(self, entry: KconfigEntry) -> None: 38 + self._entries.append(entry) 39 + 40 + def is_subset_of(self, other: 'Kconfig') -> bool: 41 + return self.entries().issubset(other.entries()) 42 + 43 + def write_to_file(self, path: str) -> None: 44 + with open(path, 'w') as f: 45 + for entry in self.entries(): 46 + f.write(str(entry) + '\n') 47 + 48 + def parse_from_string(self, blob: str) -> None: 49 + """Parses a string containing KconfigEntrys and populates this Kconfig.""" 50 + self._entries = [] 51 + is_not_set_matcher = re.compile(CONFIG_IS_NOT_SET_PATTERN) 52 + config_matcher = re.compile(CONFIG_PATTERN) 53 + for line in blob.split('\n'): 54 + line = line.strip() 55 + if not line: 56 + continue 57 + elif config_matcher.match(line) or is_not_set_matcher.match(line): 58 + self._entries.append(KconfigEntry(line)) 59 + elif line[0] == '#': 60 + continue 61 + else: 62 + raise KconfigParseError('Failed to parse: ' + line) 63 + 64 + def read_from_file(self, path: str) -> None: 65 + with open(path, 'r') as f: 66 + self.parse_from_string(f.read())
+148
tools/testing/kunit/kunit_kernel.py
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Runs UML kernel, collects output, and handles errors. 4 + # 5 + # Copyright (C) 2019, Google LLC. 6 + # Author: Felix Guo <felixguoxiuping@gmail.com> 7 + # Author: Brendan Higgins <brendanhiggins@google.com> 8 + 9 + 10 + import logging 11 + import subprocess 12 + import os 13 + 14 + import kunit_config 15 + 16 + KCONFIG_PATH = '.config' 17 + 18 + class ConfigError(Exception): 19 + """Represents an error trying to configure the Linux kernel.""" 20 + 21 + 22 + class BuildError(Exception): 23 + """Represents an error trying to build the Linux kernel.""" 24 + 25 + 26 + class LinuxSourceTreeOperations(object): 27 + """An abstraction over command line operations performed on a source tree.""" 28 + 29 + def make_mrproper(self): 30 + try: 31 + subprocess.check_output(['make', 'mrproper']) 32 + except OSError as e: 33 + raise ConfigError('Could not call make command: ' + e) 34 + except subprocess.CalledProcessError as e: 35 + raise ConfigError(e.output) 36 + 37 + def make_olddefconfig(self, build_dir): 38 + command = ['make', 'ARCH=um', 'olddefconfig'] 39 + if build_dir: 40 + command += ['O=' + build_dir] 41 + try: 42 + subprocess.check_output(command) 43 + except OSError as e: 44 + raise ConfigError('Could not call make command: ' + e) 45 + except subprocess.CalledProcessError as e: 46 + raise ConfigError(e.output) 47 + 48 + def make(self, jobs, build_dir): 49 + command = ['make', 'ARCH=um', '--jobs=' + str(jobs)] 50 + if build_dir: 51 + command += ['O=' + build_dir] 52 + try: 53 + subprocess.check_output(command) 54 + except OSError as e: 55 + raise BuildError('Could not call execute make: ' + e) 56 + except subprocess.CalledProcessError as e: 57 + raise BuildError(e.output) 58 + 59 + def linux_bin(self, params, timeout, build_dir): 60 + """Runs the Linux UML binary. Must be named 'linux'.""" 61 + linux_bin = './linux' 62 + if build_dir: 63 + linux_bin = os.path.join(build_dir, 'linux') 64 + process = subprocess.Popen( 65 + [linux_bin] + params, 66 + stdin=subprocess.PIPE, 67 + stdout=subprocess.PIPE, 68 + stderr=subprocess.PIPE) 69 + process.wait(timeout=timeout) 70 + return process 71 + 72 + 73 + def get_kconfig_path(build_dir): 74 + kconfig_path = KCONFIG_PATH 75 + if build_dir: 76 + kconfig_path = os.path.join(build_dir, KCONFIG_PATH) 77 + return kconfig_path 78 + 79 + class LinuxSourceTree(object): 80 + """Represents a Linux kernel source tree with KUnit tests.""" 81 + 82 + def __init__(self): 83 + self._kconfig = kunit_config.Kconfig() 84 + self._kconfig.read_from_file('kunitconfig') 85 + self._ops = LinuxSourceTreeOperations() 86 + 87 + def clean(self): 88 + try: 89 + self._ops.make_mrproper() 90 + except ConfigError as e: 91 + logging.error(e) 92 + return False 93 + return True 94 + 95 + def build_config(self, build_dir): 96 + kconfig_path = get_kconfig_path(build_dir) 97 + if build_dir and not os.path.exists(build_dir): 98 + os.mkdir(build_dir) 99 + self._kconfig.write_to_file(kconfig_path) 100 + try: 101 + self._ops.make_olddefconfig(build_dir) 102 + except ConfigError as e: 103 + logging.error(e) 104 + return False 105 + validated_kconfig = kunit_config.Kconfig() 106 + validated_kconfig.read_from_file(kconfig_path) 107 + if not self._kconfig.is_subset_of(validated_kconfig): 108 + logging.error('Provided Kconfig is not contained in validated .config!') 109 + return False 110 + return True 111 + 112 + def build_reconfig(self, build_dir): 113 + """Creates a new .config if it is not a subset of the kunitconfig.""" 114 + kconfig_path = get_kconfig_path(build_dir) 115 + if os.path.exists(kconfig_path): 116 + existing_kconfig = kunit_config.Kconfig() 117 + existing_kconfig.read_from_file(kconfig_path) 118 + if not self._kconfig.is_subset_of(existing_kconfig): 119 + print('Regenerating .config ...') 120 + os.remove(kconfig_path) 121 + return self.build_config(build_dir) 122 + else: 123 + return True 124 + else: 125 + print('Generating .config ...') 126 + return self.build_config(build_dir) 127 + 128 + def build_um_kernel(self, jobs, build_dir): 129 + try: 130 + self._ops.make_olddefconfig(build_dir) 131 + self._ops.make(jobs, build_dir) 132 + except (ConfigError, BuildError) as e: 133 + logging.error(e) 134 + return False 135 + used_kconfig = kunit_config.Kconfig() 136 + used_kconfig.read_from_file(get_kconfig_path(build_dir)) 137 + if not self._kconfig.is_subset_of(used_kconfig): 138 + logging.error('Provided Kconfig is not contained in final config!') 139 + return False 140 + return True 141 + 142 + def run_kernel(self, args=[], timeout=None, build_dir=None): 143 + args.extend(['mem=256M']) 144 + process = self._ops.linux_bin(args, timeout, build_dir) 145 + with open('test.log', 'w') as f: 146 + for line in process.stdout: 147 + f.write(line.rstrip().decode('ascii') + '\n') 148 + yield line.rstrip().decode('ascii')
+310
tools/testing/kunit/kunit_parser.py
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Parses test results from a kernel dmesg log. 4 + # 5 + # Copyright (C) 2019, Google LLC. 6 + # Author: Felix Guo <felixguoxiuping@gmail.com> 7 + # Author: Brendan Higgins <brendanhiggins@google.com> 8 + 9 + import re 10 + 11 + from collections import namedtuple 12 + from datetime import datetime 13 + from enum import Enum, auto 14 + from functools import reduce 15 + from typing import List 16 + 17 + TestResult = namedtuple('TestResult', ['status','suites','log']) 18 + 19 + class TestSuite(object): 20 + def __init__(self): 21 + self.status = None 22 + self.name = None 23 + self.cases = [] 24 + 25 + def __str__(self): 26 + return 'TestSuite(' + self.status + ',' + self.name + ',' + str(self.cases) + ')' 27 + 28 + def __repr__(self): 29 + return str(self) 30 + 31 + class TestCase(object): 32 + def __init__(self): 33 + self.status = None 34 + self.name = '' 35 + self.log = [] 36 + 37 + def __str__(self): 38 + return 'TestCase(' + self.status + ',' + self.name + ',' + str(self.log) + ')' 39 + 40 + def __repr__(self): 41 + return str(self) 42 + 43 + class TestStatus(Enum): 44 + SUCCESS = auto() 45 + FAILURE = auto() 46 + TEST_CRASHED = auto() 47 + NO_TESTS = auto() 48 + 49 + kunit_start_re = re.compile(r'^TAP version [0-9]+$') 50 + kunit_end_re = re.compile('List of all partitions:') 51 + 52 + def isolate_kunit_output(kernel_output): 53 + started = False 54 + for line in kernel_output: 55 + if kunit_start_re.match(line): 56 + started = True 57 + yield line 58 + elif kunit_end_re.match(line): 59 + break 60 + elif started: 61 + yield line 62 + 63 + def raw_output(kernel_output): 64 + for line in kernel_output: 65 + print(line) 66 + 67 + DIVIDER = '=' * 60 68 + 69 + RESET = '\033[0;0m' 70 + 71 + def red(text): 72 + return '\033[1;31m' + text + RESET 73 + 74 + def yellow(text): 75 + return '\033[1;33m' + text + RESET 76 + 77 + def green(text): 78 + return '\033[1;32m' + text + RESET 79 + 80 + def print_with_timestamp(message): 81 + print('[%s] %s' % (datetime.now().strftime('%H:%M:%S'), message)) 82 + 83 + def format_suite_divider(message): 84 + return '======== ' + message + ' ========' 85 + 86 + def print_suite_divider(message): 87 + print_with_timestamp(DIVIDER) 88 + print_with_timestamp(format_suite_divider(message)) 89 + 90 + def print_log(log): 91 + for m in log: 92 + print_with_timestamp(m) 93 + 94 + TAP_ENTRIES = re.compile(r'^(TAP|\t?ok|\t?not ok|\t?[0-9]+\.\.[0-9]+|\t?#).*$') 95 + 96 + def consume_non_diagnositic(lines: List[str]) -> None: 97 + while lines and not TAP_ENTRIES.match(lines[0]): 98 + lines.pop(0) 99 + 100 + def save_non_diagnositic(lines: List[str], test_case: TestCase) -> None: 101 + while lines and not TAP_ENTRIES.match(lines[0]): 102 + test_case.log.append(lines[0]) 103 + lines.pop(0) 104 + 105 + OkNotOkResult = namedtuple('OkNotOkResult', ['is_ok','description', 'text']) 106 + 107 + OK_NOT_OK_SUBTEST = re.compile(r'^\t(ok|not ok) [0-9]+ - (.*)$') 108 + 109 + OK_NOT_OK_MODULE = re.compile(r'^(ok|not ok) [0-9]+ - (.*)$') 110 + 111 + def parse_ok_not_ok_test_case(lines: List[str], 112 + test_case: TestCase, 113 + expecting_test_case: bool) -> bool: 114 + save_non_diagnositic(lines, test_case) 115 + if not lines: 116 + if expecting_test_case: 117 + test_case.status = TestStatus.TEST_CRASHED 118 + return True 119 + else: 120 + return False 121 + line = lines[0] 122 + match = OK_NOT_OK_SUBTEST.match(line) 123 + if match: 124 + test_case.log.append(lines.pop(0)) 125 + test_case.name = match.group(2) 126 + if test_case.status == TestStatus.TEST_CRASHED: 127 + return True 128 + if match.group(1) == 'ok': 129 + test_case.status = TestStatus.SUCCESS 130 + else: 131 + test_case.status = TestStatus.FAILURE 132 + return True 133 + else: 134 + return False 135 + 136 + SUBTEST_DIAGNOSTIC = re.compile(r'^\t# .*?: (.*)$') 137 + DIAGNOSTIC_CRASH_MESSAGE = 'kunit test case crashed!' 138 + 139 + def parse_diagnostic(lines: List[str], test_case: TestCase) -> bool: 140 + save_non_diagnositic(lines, test_case) 141 + if not lines: 142 + return False 143 + line = lines[0] 144 + match = SUBTEST_DIAGNOSTIC.match(line) 145 + if match: 146 + test_case.log.append(lines.pop(0)) 147 + if match.group(1) == DIAGNOSTIC_CRASH_MESSAGE: 148 + test_case.status = TestStatus.TEST_CRASHED 149 + return True 150 + else: 151 + return False 152 + 153 + def parse_test_case(lines: List[str], expecting_test_case: bool) -> TestCase: 154 + test_case = TestCase() 155 + save_non_diagnositic(lines, test_case) 156 + while parse_diagnostic(lines, test_case): 157 + pass 158 + if parse_ok_not_ok_test_case(lines, test_case, expecting_test_case): 159 + return test_case 160 + else: 161 + return None 162 + 163 + SUBTEST_HEADER = re.compile(r'^\t# Subtest: (.*)$') 164 + 165 + def parse_subtest_header(lines: List[str]) -> str: 166 + consume_non_diagnositic(lines) 167 + if not lines: 168 + return None 169 + match = SUBTEST_HEADER.match(lines[0]) 170 + if match: 171 + lines.pop(0) 172 + return match.group(1) 173 + else: 174 + return None 175 + 176 + SUBTEST_PLAN = re.compile(r'\t[0-9]+\.\.([0-9]+)') 177 + 178 + def parse_subtest_plan(lines: List[str]) -> int: 179 + consume_non_diagnositic(lines) 180 + match = SUBTEST_PLAN.match(lines[0]) 181 + if match: 182 + lines.pop(0) 183 + return int(match.group(1)) 184 + else: 185 + return None 186 + 187 + def max_status(left: TestStatus, right: TestStatus) -> TestStatus: 188 + if left == TestStatus.TEST_CRASHED or right == TestStatus.TEST_CRASHED: 189 + return TestStatus.TEST_CRASHED 190 + elif left == TestStatus.FAILURE or right == TestStatus.FAILURE: 191 + return TestStatus.FAILURE 192 + elif left != TestStatus.SUCCESS: 193 + return left 194 + elif right != TestStatus.SUCCESS: 195 + return right 196 + else: 197 + return TestStatus.SUCCESS 198 + 199 + def parse_ok_not_ok_test_suite(lines: List[str], test_suite: TestSuite) -> bool: 200 + consume_non_diagnositic(lines) 201 + if not lines: 202 + test_suite.status = TestStatus.TEST_CRASHED 203 + return False 204 + line = lines[0] 205 + match = OK_NOT_OK_MODULE.match(line) 206 + if match: 207 + lines.pop(0) 208 + if match.group(1) == 'ok': 209 + test_suite.status = TestStatus.SUCCESS 210 + else: 211 + test_suite.status = TestStatus.FAILURE 212 + return True 213 + else: 214 + return False 215 + 216 + def bubble_up_errors(to_status, status_container_list) -> TestStatus: 217 + status_list = map(to_status, status_container_list) 218 + return reduce(max_status, status_list, TestStatus.SUCCESS) 219 + 220 + def bubble_up_test_case_errors(test_suite: TestSuite) -> TestStatus: 221 + max_test_case_status = bubble_up_errors(lambda x: x.status, test_suite.cases) 222 + return max_status(max_test_case_status, test_suite.status) 223 + 224 + def parse_test_suite(lines: List[str]) -> TestSuite: 225 + if not lines: 226 + return None 227 + consume_non_diagnositic(lines) 228 + test_suite = TestSuite() 229 + test_suite.status = TestStatus.SUCCESS 230 + name = parse_subtest_header(lines) 231 + if not name: 232 + return None 233 + test_suite.name = name 234 + expected_test_case_num = parse_subtest_plan(lines) 235 + if not expected_test_case_num: 236 + return None 237 + test_case = parse_test_case(lines, expected_test_case_num > 0) 238 + expected_test_case_num -= 1 239 + while test_case: 240 + test_suite.cases.append(test_case) 241 + test_case = parse_test_case(lines, expected_test_case_num > 0) 242 + expected_test_case_num -= 1 243 + if parse_ok_not_ok_test_suite(lines, test_suite): 244 + test_suite.status = bubble_up_test_case_errors(test_suite) 245 + return test_suite 246 + elif not lines: 247 + print_with_timestamp(red('[ERROR] ') + 'ran out of lines before end token') 248 + return test_suite 249 + else: 250 + print('failed to parse end of suite' + lines[0]) 251 + return None 252 + 253 + TAP_HEADER = re.compile(r'^TAP version 14$') 254 + 255 + def parse_tap_header(lines: List[str]) -> bool: 256 + consume_non_diagnositic(lines) 257 + if TAP_HEADER.match(lines[0]): 258 + lines.pop(0) 259 + return True 260 + else: 261 + return False 262 + 263 + def bubble_up_suite_errors(test_suite_list: List[TestSuite]) -> TestStatus: 264 + return bubble_up_errors(lambda x: x.status, test_suite_list) 265 + 266 + def parse_test_result(lines: List[str]) -> TestResult: 267 + if not lines: 268 + return TestResult(TestStatus.NO_TESTS, [], lines) 269 + consume_non_diagnositic(lines) 270 + if not parse_tap_header(lines): 271 + return None 272 + test_suites = [] 273 + test_suite = parse_test_suite(lines) 274 + while test_suite: 275 + test_suites.append(test_suite) 276 + test_suite = parse_test_suite(lines) 277 + return TestResult(bubble_up_suite_errors(test_suites), test_suites, lines) 278 + 279 + def parse_run_tests(kernel_output) -> TestResult: 280 + total_tests = 0 281 + failed_tests = 0 282 + crashed_tests = 0 283 + test_result = parse_test_result(list(isolate_kunit_output(kernel_output))) 284 + for test_suite in test_result.suites: 285 + if test_suite.status == TestStatus.SUCCESS: 286 + print_suite_divider(green('[PASSED] ') + test_suite.name) 287 + elif test_suite.status == TestStatus.TEST_CRASHED: 288 + print_suite_divider(red('[CRASHED] ' + test_suite.name)) 289 + else: 290 + print_suite_divider(red('[FAILED] ') + test_suite.name) 291 + for test_case in test_suite.cases: 292 + total_tests += 1 293 + if test_case.status == TestStatus.SUCCESS: 294 + print_with_timestamp(green('[PASSED] ') + test_case.name) 295 + elif test_case.status == TestStatus.TEST_CRASHED: 296 + crashed_tests += 1 297 + print_with_timestamp(red('[CRASHED] ' + test_case.name)) 298 + print_log(map(yellow, test_case.log)) 299 + print_with_timestamp('') 300 + else: 301 + failed_tests += 1 302 + print_with_timestamp(red('[FAILED] ') + test_case.name) 303 + print_log(map(yellow, test_case.log)) 304 + print_with_timestamp('') 305 + print_with_timestamp(DIVIDER) 306 + fmt = green if test_result.status == TestStatus.SUCCESS else red 307 + print_with_timestamp( 308 + fmt('Testing complete. %d tests run. %d failed. %d crashed.' % 309 + (total_tests, failed_tests, crashed_tests))) 310 + return test_result
+206
tools/testing/kunit/kunit_tool_test.py
··· 1 + #!/usr/bin/python3 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # A collection of tests for tools/testing/kunit/kunit.py 5 + # 6 + # Copyright (C) 2019, Google LLC. 7 + # Author: Brendan Higgins <brendanhiggins@google.com> 8 + 9 + import unittest 10 + from unittest import mock 11 + 12 + import tempfile, shutil # Handling test_tmpdir 13 + 14 + import os 15 + 16 + import kunit_config 17 + import kunit_parser 18 + import kunit_kernel 19 + import kunit 20 + 21 + test_tmpdir = '' 22 + 23 + def setUpModule(): 24 + global test_tmpdir 25 + test_tmpdir = tempfile.mkdtemp() 26 + 27 + def tearDownModule(): 28 + shutil.rmtree(test_tmpdir) 29 + 30 + def get_absolute_path(path): 31 + return os.path.join(os.path.dirname(__file__), path) 32 + 33 + class KconfigTest(unittest.TestCase): 34 + 35 + def test_is_subset_of(self): 36 + kconfig0 = kunit_config.Kconfig() 37 + self.assertTrue(kconfig0.is_subset_of(kconfig0)) 38 + 39 + kconfig1 = kunit_config.Kconfig() 40 + kconfig1.add_entry(kunit_config.KconfigEntry('CONFIG_TEST=y')) 41 + self.assertTrue(kconfig1.is_subset_of(kconfig1)) 42 + self.assertTrue(kconfig0.is_subset_of(kconfig1)) 43 + self.assertFalse(kconfig1.is_subset_of(kconfig0)) 44 + 45 + def test_read_from_file(self): 46 + kconfig = kunit_config.Kconfig() 47 + kconfig_path = get_absolute_path( 48 + 'test_data/test_read_from_file.kconfig') 49 + 50 + kconfig.read_from_file(kconfig_path) 51 + 52 + expected_kconfig = kunit_config.Kconfig() 53 + expected_kconfig.add_entry( 54 + kunit_config.KconfigEntry('CONFIG_UML=y')) 55 + expected_kconfig.add_entry( 56 + kunit_config.KconfigEntry('CONFIG_MMU=y')) 57 + expected_kconfig.add_entry( 58 + kunit_config.KconfigEntry('CONFIG_TEST=y')) 59 + expected_kconfig.add_entry( 60 + kunit_config.KconfigEntry('CONFIG_EXAMPLE_TEST=y')) 61 + expected_kconfig.add_entry( 62 + kunit_config.KconfigEntry('# CONFIG_MK8 is not set')) 63 + 64 + self.assertEqual(kconfig.entries(), expected_kconfig.entries()) 65 + 66 + def test_write_to_file(self): 67 + kconfig_path = os.path.join(test_tmpdir, '.config') 68 + 69 + expected_kconfig = kunit_config.Kconfig() 70 + expected_kconfig.add_entry( 71 + kunit_config.KconfigEntry('CONFIG_UML=y')) 72 + expected_kconfig.add_entry( 73 + kunit_config.KconfigEntry('CONFIG_MMU=y')) 74 + expected_kconfig.add_entry( 75 + kunit_config.KconfigEntry('CONFIG_TEST=y')) 76 + expected_kconfig.add_entry( 77 + kunit_config.KconfigEntry('CONFIG_EXAMPLE_TEST=y')) 78 + expected_kconfig.add_entry( 79 + kunit_config.KconfigEntry('# CONFIG_MK8 is not set')) 80 + 81 + expected_kconfig.write_to_file(kconfig_path) 82 + 83 + actual_kconfig = kunit_config.Kconfig() 84 + actual_kconfig.read_from_file(kconfig_path) 85 + 86 + self.assertEqual(actual_kconfig.entries(), 87 + expected_kconfig.entries()) 88 + 89 + class KUnitParserTest(unittest.TestCase): 90 + 91 + def assertContains(self, needle, haystack): 92 + for line in haystack: 93 + if needle in line: 94 + return 95 + raise AssertionError('"' + 96 + str(needle) + '" not found in "' + str(haystack) + '"!') 97 + 98 + def test_output_isolated_correctly(self): 99 + log_path = get_absolute_path( 100 + 'test_data/test_output_isolated_correctly.log') 101 + file = open(log_path) 102 + result = kunit_parser.isolate_kunit_output(file.readlines()) 103 + self.assertContains('TAP version 14\n', result) 104 + self.assertContains(' # Subtest: example', result) 105 + self.assertContains(' 1..2', result) 106 + self.assertContains(' ok 1 - example_simple_test', result) 107 + self.assertContains(' ok 2 - example_mock_test', result) 108 + self.assertContains('ok 1 - example', result) 109 + file.close() 110 + 111 + def test_parse_successful_test_log(self): 112 + all_passed_log = get_absolute_path( 113 + 'test_data/test_is_test_passed-all_passed.log') 114 + file = open(all_passed_log) 115 + result = kunit_parser.parse_run_tests(file.readlines()) 116 + self.assertEqual( 117 + kunit_parser.TestStatus.SUCCESS, 118 + result.status) 119 + file.close() 120 + 121 + def test_parse_failed_test_log(self): 122 + failed_log = get_absolute_path( 123 + 'test_data/test_is_test_passed-failure.log') 124 + file = open(failed_log) 125 + result = kunit_parser.parse_run_tests(file.readlines()) 126 + self.assertEqual( 127 + kunit_parser.TestStatus.FAILURE, 128 + result.status) 129 + file.close() 130 + 131 + def test_no_tests(self): 132 + empty_log = get_absolute_path( 133 + 'test_data/test_is_test_passed-no_tests_run.log') 134 + file = open(empty_log) 135 + result = kunit_parser.parse_run_tests( 136 + kunit_parser.isolate_kunit_output(file.readlines())) 137 + self.assertEqual(0, len(result.suites)) 138 + self.assertEqual( 139 + kunit_parser.TestStatus.NO_TESTS, 140 + result.status) 141 + file.close() 142 + 143 + def test_crashed_test(self): 144 + crashed_log = get_absolute_path( 145 + 'test_data/test_is_test_passed-crash.log') 146 + file = open(crashed_log) 147 + result = kunit_parser.parse_run_tests(file.readlines()) 148 + self.assertEqual( 149 + kunit_parser.TestStatus.TEST_CRASHED, 150 + result.status) 151 + file.close() 152 + 153 + class StrContains(str): 154 + def __eq__(self, other): 155 + return self in other 156 + 157 + class KUnitMainTest(unittest.TestCase): 158 + def setUp(self): 159 + path = get_absolute_path('test_data/test_is_test_passed-all_passed.log') 160 + file = open(path) 161 + all_passed_log = file.readlines() 162 + self.print_patch = mock.patch('builtins.print') 163 + self.print_mock = self.print_patch.start() 164 + self.linux_source_mock = mock.Mock() 165 + self.linux_source_mock.build_reconfig = mock.Mock(return_value=True) 166 + self.linux_source_mock.build_um_kernel = mock.Mock(return_value=True) 167 + self.linux_source_mock.run_kernel = mock.Mock(return_value=all_passed_log) 168 + 169 + def tearDown(self): 170 + self.print_patch.stop() 171 + pass 172 + 173 + def test_run_passes_args_pass(self): 174 + kunit.main(['run'], self.linux_source_mock) 175 + assert self.linux_source_mock.build_reconfig.call_count == 1 176 + assert self.linux_source_mock.run_kernel.call_count == 1 177 + self.print_mock.assert_any_call(StrContains('Testing complete.')) 178 + 179 + def test_run_passes_args_fail(self): 180 + self.linux_source_mock.run_kernel = mock.Mock(return_value=[]) 181 + with self.assertRaises(SystemExit) as e: 182 + kunit.main(['run'], self.linux_source_mock) 183 + assert type(e.exception) == SystemExit 184 + assert e.exception.code == 1 185 + assert self.linux_source_mock.build_reconfig.call_count == 1 186 + assert self.linux_source_mock.run_kernel.call_count == 1 187 + self.print_mock.assert_any_call(StrContains(' 0 tests run')) 188 + 189 + def test_run_raw_output(self): 190 + self.linux_source_mock.run_kernel = mock.Mock(return_value=[]) 191 + kunit.main(['run', '--raw_output'], self.linux_source_mock) 192 + assert self.linux_source_mock.build_reconfig.call_count == 1 193 + assert self.linux_source_mock.run_kernel.call_count == 1 194 + for kall in self.print_mock.call_args_list: 195 + assert kall != mock.call(StrContains('Testing complete.')) 196 + assert kall != mock.call(StrContains(' 0 tests run')) 197 + 198 + def test_run_timeout(self): 199 + timeout = 3453 200 + kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock) 201 + assert self.linux_source_mock.build_reconfig.call_count == 1 202 + self.linux_source_mock.run_kernel.assert_called_once_with(timeout=timeout) 203 + self.print_mock.assert_any_call(StrContains('Testing complete.')) 204 + 205 + if __name__ == '__main__': 206 + unittest.main()
+32
tools/testing/kunit/test_data/test_is_test_passed-all_passed.log
··· 1 + TAP version 14 2 + # Subtest: sysctl_test 3 + 1..8 4 + # sysctl_test_dointvec_null_tbl_data: sysctl_test_dointvec_null_tbl_data passed 5 + ok 1 - sysctl_test_dointvec_null_tbl_data 6 + # sysctl_test_dointvec_table_maxlen_unset: sysctl_test_dointvec_table_maxlen_unset passed 7 + ok 2 - sysctl_test_dointvec_table_maxlen_unset 8 + # sysctl_test_dointvec_table_len_is_zero: sysctl_test_dointvec_table_len_is_zero passed 9 + ok 3 - sysctl_test_dointvec_table_len_is_zero 10 + # sysctl_test_dointvec_table_read_but_position_set: sysctl_test_dointvec_table_read_but_position_set passed 11 + ok 4 - sysctl_test_dointvec_table_read_but_position_set 12 + # sysctl_test_dointvec_happy_single_positive: sysctl_test_dointvec_happy_single_positive passed 13 + ok 5 - sysctl_test_dointvec_happy_single_positive 14 + # sysctl_test_dointvec_happy_single_negative: sysctl_test_dointvec_happy_single_negative passed 15 + ok 6 - sysctl_test_dointvec_happy_single_negative 16 + # sysctl_test_dointvec_single_less_int_min: sysctl_test_dointvec_single_less_int_min passed 17 + ok 7 - sysctl_test_dointvec_single_less_int_min 18 + # sysctl_test_dointvec_single_greater_int_max: sysctl_test_dointvec_single_greater_int_max passed 19 + ok 8 - sysctl_test_dointvec_single_greater_int_max 20 + kunit sysctl_test: all tests passed 21 + ok 1 - sysctl_test 22 + # Subtest: example 23 + 1..2 24 + init_suite 25 + # example_simple_test: initializing 26 + # example_simple_test: example_simple_test passed 27 + ok 1 - example_simple_test 28 + # example_mock_test: initializing 29 + # example_mock_test: example_mock_test passed 30 + ok 2 - example_mock_test 31 + kunit example: all tests passed 32 + ok 2 - example
+69
tools/testing/kunit/test_data/test_is_test_passed-crash.log
··· 1 + printk: console [tty0] enabled 2 + printk: console [mc-1] enabled 3 + TAP version 14 4 + # Subtest: sysctl_test 5 + 1..8 6 + # sysctl_test_dointvec_null_tbl_data: sysctl_test_dointvec_null_tbl_data passed 7 + ok 1 - sysctl_test_dointvec_null_tbl_data 8 + # sysctl_test_dointvec_table_maxlen_unset: sysctl_test_dointvec_table_maxlen_unset passed 9 + ok 2 - sysctl_test_dointvec_table_maxlen_unset 10 + # sysctl_test_dointvec_table_len_is_zero: sysctl_test_dointvec_table_len_is_zero passed 11 + ok 3 - sysctl_test_dointvec_table_len_is_zero 12 + # sysctl_test_dointvec_table_read_but_position_set: sysctl_test_dointvec_table_read_but_position_set passed 13 + ok 4 - sysctl_test_dointvec_table_read_but_position_set 14 + # sysctl_test_dointvec_happy_single_positive: sysctl_test_dointvec_happy_single_positive passed 15 + ok 5 - sysctl_test_dointvec_happy_single_positive 16 + # sysctl_test_dointvec_happy_single_negative: sysctl_test_dointvec_happy_single_negative passed 17 + ok 6 - sysctl_test_dointvec_happy_single_negative 18 + # sysctl_test_dointvec_single_less_int_min: sysctl_test_dointvec_single_less_int_min passed 19 + ok 7 - sysctl_test_dointvec_single_less_int_min 20 + # sysctl_test_dointvec_single_greater_int_max: sysctl_test_dointvec_single_greater_int_max passed 21 + ok 8 - sysctl_test_dointvec_single_greater_int_max 22 + kunit sysctl_test: all tests passed 23 + ok 1 - sysctl_test 24 + # Subtest: example 25 + 1..2 26 + init_suite 27 + # example_simple_test: initializing 28 + Stack: 29 + 6016f7db 6f81bd30 6f81bdd0 60021450 30 + 6024b0e8 60021440 60018bbe 16f81bdc0 31 + 00000001 6f81bd30 6f81bd20 6f81bdd0 32 + Call Trace: 33 + [<6016f7db>] ? kunit_try_run_case+0xab/0xf0 34 + [<60021450>] ? set_signals+0x0/0x60 35 + [<60021440>] ? get_signals+0x0/0x10 36 + [<60018bbe>] ? kunit_um_run_try_catch+0x5e/0xc0 37 + [<60021450>] ? set_signals+0x0/0x60 38 + [<60021440>] ? get_signals+0x0/0x10 39 + [<60018bb3>] ? kunit_um_run_try_catch+0x53/0xc0 40 + [<6016f321>] ? kunit_run_case_catch_errors+0x121/0x1a0 41 + [<60018b60>] ? kunit_um_run_try_catch+0x0/0xc0 42 + [<600189e0>] ? kunit_um_throw+0x0/0x180 43 + [<6016f730>] ? kunit_try_run_case+0x0/0xf0 44 + [<6016f600>] ? kunit_catch_run_case+0x0/0x130 45 + [<6016edd0>] ? kunit_vprintk+0x0/0x30 46 + [<6016ece0>] ? kunit_fail+0x0/0x40 47 + [<6016eca0>] ? kunit_abort+0x0/0x40 48 + [<6016ed20>] ? kunit_printk_emit+0x0/0xb0 49 + [<6016f200>] ? kunit_run_case_catch_errors+0x0/0x1a0 50 + [<6016f46e>] ? kunit_run_tests+0xce/0x260 51 + [<6005b390>] ? unregister_console+0x0/0x190 52 + [<60175b70>] ? suite_kunit_initexample_test_suite+0x0/0x20 53 + [<60001cbb>] ? do_one_initcall+0x0/0x197 54 + [<60001d47>] ? do_one_initcall+0x8c/0x197 55 + [<6005cd20>] ? irq_to_desc+0x0/0x30 56 + [<60002005>] ? kernel_init_freeable+0x1b3/0x272 57 + [<6005c5ec>] ? printk+0x0/0x9b 58 + [<601c0086>] ? kernel_init+0x26/0x160 59 + [<60014442>] ? new_thread_handler+0x82/0xc0 60 + 61 + # example_simple_test: kunit test case crashed! 62 + # example_simple_test: example_simple_test failed 63 + not ok 1 - example_simple_test 64 + # example_mock_test: initializing 65 + # example_mock_test: example_mock_test passed 66 + ok 2 - example_mock_test 67 + kunit example: one or more tests failed 68 + not ok 2 - example 69 + List of all partitions:
+36
tools/testing/kunit/test_data/test_is_test_passed-failure.log
··· 1 + TAP version 14 2 + # Subtest: sysctl_test 3 + 1..8 4 + # sysctl_test_dointvec_null_tbl_data: sysctl_test_dointvec_null_tbl_data passed 5 + ok 1 - sysctl_test_dointvec_null_tbl_data 6 + # sysctl_test_dointvec_table_maxlen_unset: sysctl_test_dointvec_table_maxlen_unset passed 7 + ok 2 - sysctl_test_dointvec_table_maxlen_unset 8 + # sysctl_test_dointvec_table_len_is_zero: sysctl_test_dointvec_table_len_is_zero passed 9 + ok 3 - sysctl_test_dointvec_table_len_is_zero 10 + # sysctl_test_dointvec_table_read_but_position_set: sysctl_test_dointvec_table_read_but_position_set passed 11 + ok 4 - sysctl_test_dointvec_table_read_but_position_set 12 + # sysctl_test_dointvec_happy_single_positive: sysctl_test_dointvec_happy_single_positive passed 13 + ok 5 - sysctl_test_dointvec_happy_single_positive 14 + # sysctl_test_dointvec_happy_single_negative: sysctl_test_dointvec_happy_single_negative passed 15 + ok 6 - sysctl_test_dointvec_happy_single_negative 16 + # sysctl_test_dointvec_single_less_int_min: sysctl_test_dointvec_single_less_int_min passed 17 + ok 7 - sysctl_test_dointvec_single_less_int_min 18 + # sysctl_test_dointvec_single_greater_int_max: sysctl_test_dointvec_single_greater_int_max passed 19 + ok 8 - sysctl_test_dointvec_single_greater_int_max 20 + kunit sysctl_test: all tests passed 21 + ok 1 - sysctl_test 22 + # Subtest: example 23 + 1..2 24 + init_suite 25 + # example_simple_test: initializing 26 + # example_simple_test: EXPECTATION FAILED at lib/kunit/example-test.c:30 27 + Expected 1 + 1 == 3, but 28 + 1 + 1 == 2 29 + 3 == 3 30 + # example_simple_test: example_simple_test failed 31 + not ok 1 - example_simple_test 32 + # example_mock_test: initializing 33 + # example_mock_test: example_mock_test passed 34 + ok 2 - example_mock_test 35 + kunit example: one or more tests failed 36 + not ok 2 - example
+75
tools/testing/kunit/test_data/test_is_test_passed-no_tests_run.log
··· 1 + Core dump limits : 2 + soft - 0 3 + hard - NONE 4 + Checking environment variables for a tempdir...none found 5 + Checking if /dev/shm is on tmpfs...OK 6 + Checking PROT_EXEC mmap in /dev/shm...OK 7 + Adding 24743936 bytes to physical memory to account for exec-shield gap 8 + Linux version 4.12.0-rc3-00010-g7319eb35f493-dirty (brendanhiggins@mactruck.svl.corp.google.com) (gcc version 7.3.0 (Debian 7.3.0-5) ) #29 Thu Mar 15 14:57:19 PDT 2018 9 + Built 1 zonelists in Zone order, mobility grouping on. Total pages: 14038 10 + Kernel command line: root=98:0 11 + PID hash table entries: 256 (order: -1, 2048 bytes) 12 + Dentry cache hash table entries: 8192 (order: 4, 65536 bytes) 13 + Inode-cache hash table entries: 4096 (order: 3, 32768 bytes) 14 + Memory: 27868K/56932K available (1681K kernel code, 480K rwdata, 400K rodata, 89K init, 205K bss, 29064K reserved, 0K cma-reserved) 15 + SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 16 + NR_IRQS:15 17 + clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns 18 + Calibrating delay loop... 7384.26 BogoMIPS (lpj=36921344) 19 + pid_max: default: 32768 minimum: 301 20 + Mount-cache hash table entries: 512 (order: 0, 4096 bytes) 21 + Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes) 22 + Checking that host ptys support output SIGIO...Yes 23 + Checking that host ptys support SIGIO on close...No, enabling workaround 24 + Using 2.6 host AIO 25 + clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns 26 + futex hash table entries: 256 (order: 0, 6144 bytes) 27 + clocksource: Switched to clocksource timer 28 + console [stderr0] disabled 29 + mconsole (version 2) initialized on /usr/local/google/home/brendanhiggins/.uml/6Ijecl/mconsole 30 + Checking host MADV_REMOVE support...OK 31 + workingset: timestamp_bits=62 max_order=13 bucket_order=0 32 + Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254) 33 + io scheduler noop registered 34 + io scheduler deadline registered 35 + io scheduler cfq registered (default) 36 + io scheduler mq-deadline registered 37 + io scheduler kyber registered 38 + Initialized stdio console driver 39 + Using a channel type which is configured out of UML 40 + setup_one_line failed for device 1 : Configuration failed 41 + Using a channel type which is configured out of UML 42 + setup_one_line failed for device 2 : Configuration failed 43 + Using a channel type which is configured out of UML 44 + setup_one_line failed for device 3 : Configuration failed 45 + Using a channel type which is configured out of UML 46 + setup_one_line failed for device 4 : Configuration failed 47 + Using a channel type which is configured out of UML 48 + setup_one_line failed for device 5 : Configuration failed 49 + Using a channel type which is configured out of UML 50 + setup_one_line failed for device 6 : Configuration failed 51 + Using a channel type which is configured out of UML 52 + setup_one_line failed for device 7 : Configuration failed 53 + Using a channel type which is configured out of UML 54 + setup_one_line failed for device 8 : Configuration failed 55 + Using a channel type which is configured out of UML 56 + setup_one_line failed for device 9 : Configuration failed 57 + Using a channel type which is configured out of UML 58 + setup_one_line failed for device 10 : Configuration failed 59 + Using a channel type which is configured out of UML 60 + setup_one_line failed for device 11 : Configuration failed 61 + Using a channel type which is configured out of UML 62 + setup_one_line failed for device 12 : Configuration failed 63 + Using a channel type which is configured out of UML 64 + setup_one_line failed for device 13 : Configuration failed 65 + Using a channel type which is configured out of UML 66 + setup_one_line failed for device 14 : Configuration failed 67 + Using a channel type which is configured out of UML 68 + setup_one_line failed for device 15 : Configuration failed 69 + Console initialized on /dev/tty0 70 + console [tty0] enabled 71 + console [mc-1] enabled 72 + List of all partitions: 73 + No filesystem could mount root, tried: 74 + 75 + Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(98,0)
+106
tools/testing/kunit/test_data/test_output_isolated_correctly.log
··· 1 + Linux version 5.1.0-rc7-00061-g04652f1cb4aa0 (brendanhiggins@mactruck.svl.corp.google.com) (gcc version 7.3.0 (Debian 7.3.0-18)) #163 Wed May 8 16:18:20 PDT 2019 2 + Built 1 zonelists, mobility grouping on. Total pages: 69906 3 + Kernel command line: mem=256M root=98:0 4 + Dentry cache hash table entries: 65536 (order: 7, 524288 bytes) 5 + Inode-cache hash table entries: 32768 (order: 6, 262144 bytes) 6 + Memory: 254468K/283500K available (1734K kernel code, 489K rwdata, 396K rodata, 85K init, 216K bss, 29032K reserved, 0K cma-reserved) 7 + SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 8 + NR_IRQS: 15 9 + clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns 10 + ------------[ cut here ]------------ 11 + WARNING: CPU: 0 PID: 0 at kernel/time/clockevents.c:458 clockevents_register_device+0x143/0x160 12 + posix-timer cpumask == cpu_all_mask, using cpu_possible_mask instead 13 + CPU: 0 PID: 0 Comm: swapper Not tainted 5.1.0-rc7-00061-g04652f1cb4aa0 #163 14 + Stack: 15 + 6005cc00 60233e18 60233e60 60233e18 16 + 60233e60 00000009 00000000 6002a1b4 17 + 1ca00000000 60071c23 60233e78 100000000000062 18 + Call Trace: 19 + [<600214c5>] ? os_is_signal_stack+0x15/0x30 20 + [<6005c5ec>] ? printk+0x0/0x9b 21 + [<6001597e>] ? show_stack+0xbe/0x1c0 22 + [<6005cc00>] ? __printk_safe_exit+0x0/0x40 23 + [<6002a1b4>] ? __warn+0x144/0x170 24 + [<60071c23>] ? clockevents_register_device+0x143/0x160 25 + [<60021440>] ? get_signals+0x0/0x10 26 + [<6005c5ec>] ? printk+0x0/0x9b 27 + [<6002a27b>] ? warn_slowpath_fmt+0x9b/0xb0 28 + [<6005c5ec>] ? printk+0x0/0x9b 29 + [<6002a1e0>] ? warn_slowpath_fmt+0x0/0xb0 30 + [<6005c5ec>] ? printk+0x0/0x9b 31 + [<60021440>] ? get_signals+0x0/0x10 32 + [<600213f0>] ? block_signals+0x0/0x20 33 + [<60071c23>] ? clockevents_register_device+0x143/0x160 34 + [<60021440>] ? get_signals+0x0/0x10 35 + [<600213f0>] ? block_signals+0x0/0x20 36 + [<6005c5ec>] ? printk+0x0/0x9b 37 + [<60001bc8>] ? start_kernel+0x477/0x56a 38 + [<600036f1>] ? start_kernel_proc+0x46/0x4d 39 + [<60014442>] ? new_thread_handler+0x82/0xc0 40 + 41 + random: get_random_bytes called from print_oops_end_marker+0x4c/0x60 with crng_init=0 42 + ---[ end trace c83434852b3702d3 ]--- 43 + Calibrating delay loop... 6958.28 BogoMIPS (lpj=34791424) 44 + pid_max: default: 32768 minimum: 301 45 + Mount-cache hash table entries: 1024 (order: 1, 8192 bytes) 46 + Mountpoint-cache hash table entries: 1024 (order: 1, 8192 bytes) 47 + *** VALIDATE proc *** 48 + Checking that host ptys support output SIGIO...Yes 49 + Checking that host ptys support SIGIO on close...No, enabling workaround 50 + clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns 51 + futex hash table entries: 256 (order: 0, 6144 bytes) 52 + clocksource: Switched to clocksource timer 53 + printk: console [stderr0] disabled 54 + mconsole (version 2) initialized on /usr/local/google/home/brendanhiggins/.uml/VZ2qMm/mconsole 55 + Checking host MADV_REMOVE support...OK 56 + workingset: timestamp_bits=62 max_order=16 bucket_order=0 57 + Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254) 58 + io scheduler mq-deadline registered 59 + io scheduler kyber registered 60 + Initialized stdio console driver 61 + Using a channel type which is configured out of UML 62 + setup_one_line failed for device 1 : Configuration failed 63 + Using a channel type which is configured out of UML 64 + setup_one_line failed for device 2 : Configuration failed 65 + Using a channel type which is configured out of UML 66 + setup_one_line failed for device 3 : Configuration failed 67 + Using a channel type which is configured out of UML 68 + setup_one_line failed for device 4 : Configuration failed 69 + Using a channel type which is configured out of UML 70 + setup_one_line failed for device 5 : Configuration failed 71 + Using a channel type which is configured out of UML 72 + setup_one_line failed for device 6 : Configuration failed 73 + Using a channel type which is configured out of UML 74 + setup_one_line failed for device 7 : Configuration failed 75 + Using a channel type which is configured out of UML 76 + setup_one_line failed for device 8 : Configuration failed 77 + Using a channel type which is configured out of UML 78 + setup_one_line failed for device 9 : Configuration failed 79 + Using a channel type which is configured out of UML 80 + setup_one_line failed for device 10 : Configuration failed 81 + Using a channel type which is configured out of UML 82 + setup_one_line failed for device 11 : Configuration failed 83 + Using a channel type which is configured out of UML 84 + setup_one_line failed for device 12 : Configuration failed 85 + Using a channel type which is configured out of UML 86 + setup_one_line failed for device 13 : Configuration failed 87 + Using a channel type which is configured out of UML 88 + setup_one_line failed for device 14 : Configuration failed 89 + Using a channel type which is configured out of UML 90 + setup_one_line failed for device 15 : Configuration failed 91 + Console initialized on /dev/tty0 92 + printk: console [tty0] enabled 93 + printk: console [mc-1] enabled 94 + TAP version 14 95 + # Subtest: example 96 + 1..2 97 + init_suite 98 + # example_simple_test: initializing 99 + # example_simple_test: example_simple_test passed 100 + ok 1 - example_simple_test 101 + # example_mock_test: initializing 102 + # example_mock_test: example_mock_test passed 103 + ok 2 - example_mock_test 104 + kunit example: all tests passed 105 + ok 1 - example 106 + List of all partitions:
+17
tools/testing/kunit/test_data/test_read_from_file.kconfig
··· 1 + # 2 + # Automatically generated file; DO NOT EDIT. 3 + # User Mode Linux/x86 4.12.0-rc3 Kernel Configuration 4 + # 5 + CONFIG_UML=y 6 + CONFIG_MMU=y 7 + 8 + # 9 + # UML-specific options 10 + # 11 + 12 + # 13 + # Host processor type and features 14 + # 15 + # CONFIG_MK8 is not set 16 + CONFIG_TEST=y 17 + CONFIG_EXAMPLE_TEST=y