~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/kunit/kunit.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/testing/kunit/kunit.py (Version linux-6.12-rc7) and /tools/testing/kunit/kunit.py (Version linux-5.15.171)


  1 #!/usr/bin/env python3                              1 #!/usr/bin/env python3
  2 # SPDX-License-Identifier: GPL-2.0                  2 # SPDX-License-Identifier: GPL-2.0
  3 #                                                   3 #
  4 # A thin wrapper on top of the KUnit Kernel         4 # A thin wrapper on top of the KUnit Kernel
  5 #                                                   5 #
  6 # Copyright (C) 2019, Google LLC.                   6 # Copyright (C) 2019, Google LLC.
  7 # Author: Felix Guo <felixguoxiuping@gmail.com>      7 # Author: Felix Guo <felixguoxiuping@gmail.com>
  8 # Author: Brendan Higgins <brendanhiggins@googl      8 # Author: Brendan Higgins <brendanhiggins@google.com>
  9                                                     9 
 10 import argparse                                    10 import argparse
 11 import os                                      << 
 12 import re                                      << 
 13 import shlex                                   << 
 14 import sys                                         11 import sys
                                                   >>  12 import os
 15 import time                                        13 import time
 16                                                    14 
 17 assert sys.version_info >= (3, 7), "Python ver     15 assert sys.version_info >= (3, 7), "Python version is too old"
 18                                                    16 
 19 from dataclasses import dataclass              !!  17 from collections import namedtuple
 20 from enum import Enum, auto                        18 from enum import Enum, auto
 21 from typing import Iterable, List, Optional, S !!  19 from typing import Iterable, Sequence
 22                                                    20 
                                                   >>  21 import kunit_config
 23 import kunit_json                                  22 import kunit_json
 24 import kunit_kernel                                23 import kunit_kernel
 25 import kunit_parser                                24 import kunit_parser
 26 from kunit_printer import stdout               !!  25 
                                                   >>  26 KunitResult = namedtuple('KunitResult', ['status','result','elapsed_time'])
                                                   >>  27 
                                                   >>  28 KunitConfigRequest = namedtuple('KunitConfigRequest',
                                                   >>  29                                 ['build_dir', 'make_options'])
                                                   >>  30 KunitBuildRequest = namedtuple('KunitBuildRequest',
                                                   >>  31                                ['jobs', 'build_dir', 'alltests',
                                                   >>  32                                 'make_options'])
                                                   >>  33 KunitExecRequest = namedtuple('KunitExecRequest',
                                                   >>  34                               ['timeout', 'build_dir', 'alltests',
                                                   >>  35                                'filter_glob', 'kernel_args'])
                                                   >>  36 KunitParseRequest = namedtuple('KunitParseRequest',
                                                   >>  37                                ['raw_output', 'input_data', 'build_dir', 'json'])
                                                   >>  38 KunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs',
                                                   >>  39                                            'build_dir', 'alltests', 'filter_glob',
                                                   >>  40                                            'kernel_args', 'json', 'make_options'])
                                                   >>  41 
                                                   >>  42 KernelDirectoryPath = sys.argv[0].split('tools/testing/kunit/')[0]
 27                                                    43 
 28 class KunitStatus(Enum):                           44 class KunitStatus(Enum):
 29         SUCCESS = auto()                           45         SUCCESS = auto()
 30         CONFIG_FAILURE = auto()                    46         CONFIG_FAILURE = auto()
 31         BUILD_FAILURE = auto()                     47         BUILD_FAILURE = auto()
 32         TEST_FAILURE = auto()                      48         TEST_FAILURE = auto()
 33                                                    49 
 34 @dataclass                                     << 
 35 class KunitResult:                             << 
 36         status: KunitStatus                    << 
 37         elapsed_time: float                    << 
 38                                                << 
 39 @dataclass                                     << 
 40 class KunitConfigRequest:                      << 
 41         build_dir: str                         << 
 42         make_options: Optional[List[str]]      << 
 43                                                << 
 44 @dataclass                                     << 
 45 class KunitBuildRequest(KunitConfigRequest):   << 
 46         jobs: int                              << 
 47                                                << 
 48 @dataclass                                     << 
 49 class KunitParseRequest:                       << 
 50         raw_output: Optional[str]              << 
 51         json: Optional[str]                    << 
 52                                                << 
 53 @dataclass                                     << 
 54 class KunitExecRequest(KunitParseRequest):     << 
 55         build_dir: str                         << 
 56         timeout: int                           << 
 57         filter_glob: str                       << 
 58         filter: str                            << 
 59         filter_action: Optional[str]           << 
 60         kernel_args: Optional[List[str]]       << 
 61         run_isolated: Optional[str]            << 
 62         list_tests: bool                       << 
 63         list_tests_attr: bool                  << 
 64                                                << 
 65 @dataclass                                     << 
 66 class KunitRequest(KunitExecRequest, KunitBuil << 
 67         pass                                   << 
 68                                                << 
 69                                                << 
 70 def get_kernel_root_path() -> str:                 50 def get_kernel_root_path() -> str:
 71         path = sys.argv[0] if not __file__ els     51         path = sys.argv[0] if not __file__ else __file__
 72         parts = os.path.realpath(path).split('     52         parts = os.path.realpath(path).split('tools/testing/kunit')
 73         if len(parts) != 2:                        53         if len(parts) != 2:
 74                 sys.exit(1)                        54                 sys.exit(1)
 75         return parts[0]                            55         return parts[0]
 76                                                    56 
 77 def config_tests(linux: kunit_kernel.LinuxSour     57 def config_tests(linux: kunit_kernel.LinuxSourceTree,
 78                  request: KunitConfigRequest)      58                  request: KunitConfigRequest) -> KunitResult:
 79         stdout.print_with_timestamp('Configuri !!  59         kunit_parser.print_with_timestamp('Configuring KUnit Kernel ...')
 80                                                    60 
 81         config_start = time.time()                 61         config_start = time.time()
 82         success = linux.build_reconfig(request     62         success = linux.build_reconfig(request.build_dir, request.make_options)
 83         config_end = time.time()                   63         config_end = time.time()
 84         status = KunitStatus.SUCCESS if succes !!  64         if not success:
 85         return KunitResult(status, config_end  !!  65                 return KunitResult(KunitStatus.CONFIG_FAILURE,
                                                   >>  66                                    'could not configure kernel',
                                                   >>  67                                    config_end - config_start)
                                                   >>  68         return KunitResult(KunitStatus.SUCCESS,
                                                   >>  69                            'configured kernel successfully',
                                                   >>  70                            config_end - config_start)
 86                                                    71 
 87 def build_tests(linux: kunit_kernel.LinuxSourc     72 def build_tests(linux: kunit_kernel.LinuxSourceTree,
 88                 request: KunitBuildRequest) ->     73                 request: KunitBuildRequest) -> KunitResult:
 89         stdout.print_with_timestamp('Building  !!  74         kunit_parser.print_with_timestamp('Building KUnit Kernel ...')
 90                                                    75 
 91         build_start = time.time()                  76         build_start = time.time()
 92         success = linux.build_kernel(request.j !!  77         success = linux.build_kernel(request.alltests,
                                                   >>  78                                      request.jobs,
 93                                      request.b     79                                      request.build_dir,
 94                                      request.m     80                                      request.make_options)
 95         build_end = time.time()                    81         build_end = time.time()
 96         status = KunitStatus.SUCCESS if succes !!  82         if not success:
 97         return KunitResult(status, build_end - !!  83                 return KunitResult(KunitStatus.BUILD_FAILURE,
                                                   >>  84                                    'could not build kernel',
                                                   >>  85                                    build_end - build_start)
                                                   >>  86         if not success:
                                                   >>  87                 return KunitResult(KunitStatus.BUILD_FAILURE,
                                                   >>  88                                    'could not build kernel',
                                                   >>  89                                    build_end - build_start)
                                                   >>  90         return KunitResult(KunitStatus.SUCCESS,
                                                   >>  91                            'built kernel successfully',
                                                   >>  92                            build_end - build_start)
                                                   >>  93 
                                                   >>  94 def exec_tests(linux: kunit_kernel.LinuxSourceTree,
                                                   >>  95                request: KunitExecRequest) -> KunitResult:
                                                   >>  96         kunit_parser.print_with_timestamp('Starting KUnit Kernel ...')
                                                   >>  97         test_start = time.time()
                                                   >>  98         result = linux.run_kernel(
                                                   >>  99                 args=request.kernel_args,
                                                   >> 100                 timeout=None if request.alltests else request.timeout,
                                                   >> 101                 filter_glob=request.filter_glob,
                                                   >> 102                 build_dir=request.build_dir)
                                                   >> 103 
                                                   >> 104         test_end = time.time()
                                                   >> 105 
                                                   >> 106         return KunitResult(KunitStatus.SUCCESS,
                                                   >> 107                            result,
                                                   >> 108                            test_end - test_start)
 98                                                   109 
 99 def config_and_build_tests(linux: kunit_kernel !! 110 def parse_tests(request: KunitParseRequest) -> KunitResult:
100                            request: KunitBuild << 
101         config_result = config_tests(linux, re << 
102         if config_result.status != KunitStatus << 
103                 return config_result           << 
104                                                << 
105         return build_tests(linux, request)     << 
106                                                << 
107 def _list_tests(linux: kunit_kernel.LinuxSourc << 
108         args = ['kunit.action=list']           << 
109                                                << 
110         if request.kernel_args:                << 
111                 args.extend(request.kernel_arg << 
112                                                << 
113         output = linux.run_kernel(args=args,   << 
114                            timeout=request.tim << 
115                            filter_glob=request << 
116                            filter=request.filt << 
117                            filter_action=reque << 
118                            build_dir=request.b << 
119         lines = kunit_parser.extract_tap_lines << 
120         # Hack! Drop the dummy TAP version hea << 
121         lines.pop()                            << 
122                                                << 
123         # Filter out any extraneous non-test o << 
124         return [l for l in output if re.match( << 
125                                                << 
126 def _list_tests_attr(linux: kunit_kernel.Linux << 
127         args = ['kunit.action=list_attr']      << 
128                                                << 
129         if request.kernel_args:                << 
130                 args.extend(request.kernel_arg << 
131                                                << 
132         output = linux.run_kernel(args=args,   << 
133                            timeout=request.tim << 
134                            filter_glob=request << 
135                            filter=request.filt << 
136                            filter_action=reque << 
137                            build_dir=request.b << 
138         lines = kunit_parser.extract_tap_lines << 
139         # Hack! Drop the dummy TAP version hea << 
140         lines.pop()                            << 
141                                                << 
142         # Filter out any extraneous non-test o << 
143         return lines                           << 
144                                                << 
145 def _suites_from_test_list(tests: List[str]) - << 
146         """Extracts all the suites from an ord << 
147         suites = []  # type: List[str]         << 
148         for t in tests:                        << 
149                 parts = t.split('.', maxsplit= << 
150                 if len(parts) != 2:            << 
151                         raise ValueError(f'int << 
152                 suite, _ = parts               << 
153                 if not suites or suites[-1] != << 
154                         suites.append(suite)   << 
155         return suites                          << 
156                                                << 
157 def exec_tests(linux: kunit_kernel.LinuxSource << 
158         filter_globs = [request.filter_glob]   << 
159         if request.list_tests:                 << 
160                 output = _list_tests(linux, re << 
161                 for line in output:            << 
162                         print(line.rstrip())   << 
163                 return KunitResult(status=Kuni << 
164         if request.list_tests_attr:            << 
165                 attr_output = _list_tests_attr << 
166                 for line in attr_output:       << 
167                         print(line.rstrip())   << 
168                 return KunitResult(status=Kuni << 
169         if request.run_isolated:               << 
170                 tests = _list_tests(linux, req << 
171                 if request.run_isolated == 'te << 
172                         filter_globs = tests   << 
173                 elif request.run_isolated == ' << 
174                         filter_globs = _suites << 
175                         # Apply the test-part  << 
176                         if '.' in request.filt << 
177                                 test_glob = re << 
178                                 filter_globs = << 
179                                                << 
180         metadata = kunit_json.Metadata(arch=li << 
181                                                << 
182         test_counts = kunit_parser.TestCounts( << 
183         exec_time = 0.0                        << 
184         for i, filter_glob in enumerate(filter << 
185                 stdout.print_with_timestamp('S << 
186                                                << 
187                 test_start = time.time()       << 
188                 run_result = linux.run_kernel( << 
189                         args=request.kernel_ar << 
190                         timeout=request.timeou << 
191                         filter_glob=filter_glo << 
192                         filter=request.filter, << 
193                         filter_action=request. << 
194                         build_dir=request.buil << 
195                                                << 
196                 _, test_result = parse_tests(r << 
197                 # run_kernel() doesn't block o << 
198                 # That only happens after we g << 
199                 # So exec_time here actually c << 
200                 test_end = time.time()         << 
201                 exec_time += test_end - test_s << 
202                                                << 
203                 test_counts.add_subtest_counts << 
204                                                << 
205         if len(filter_globs) == 1 and test_cou << 
206                 bd = request.build_dir         << 
207                 print('The kernel seems to hav << 
208                 print('$ scripts/decode_stackt << 
209                                 bd, bd, kunit_ << 
210                                                << 
211         kunit_status = _map_to_overall_status( << 
212         return KunitResult(status=kunit_status << 
213                                                << 
214 def _map_to_overall_status(test_status: kunit_ << 
215         if test_status in (kunit_parser.TestSt << 
216                 return KunitStatus.SUCCESS     << 
217         return KunitStatus.TEST_FAILURE        << 
218                                                << 
219 def parse_tests(request: KunitParseRequest, me << 
220         parse_start = time.time()                 111         parse_start = time.time()
221                                                   112 
222         if request.raw_output:                 !! 113         test_result = kunit_parser.TestResult(kunit_parser.TestStatus.SUCCESS,
223                 # Treat unparsed results as on !! 114                                               [],
224                 fake_test = kunit_parser.Test( !! 115                                               'Tests not Parsed.')
225                 fake_test.status = kunit_parse << 
226                 fake_test.counts.passed = 1    << 
227                                                   116 
228                 output: Iterable[str] = input_ !! 117         if request.raw_output:
                                                   >> 118                 output: Iterable[str] = request.input_data
229                 if request.raw_output == 'all'    119                 if request.raw_output == 'all':
230                         pass                      120                         pass
231                 elif request.raw_output == 'ku    121                 elif request.raw_output == 'kunit':
232                         output = kunit_parser.    122                         output = kunit_parser.extract_tap_lines(output)
                                                   >> 123                 else:
                                                   >> 124                         print(f'Unknown --raw_output option "{request.raw_output}"', file=sys.stderr)
233                 for line in output:               125                 for line in output:
234                         print(line.rstrip())      126                         print(line.rstrip())
235                 parse_time = time.time() - par << 
236                 return KunitResult(KunitStatus << 
237                                                << 
238                                                   127 
239         # Actually parse the test results.     !! 128         else:
240         test = kunit_parser.parse_run_tests(in !! 129                 test_result = kunit_parser.parse_run_tests(request.input_data)
241         parse_time = time.time() - parse_start !! 130         parse_end = time.time()
242                                                   131 
243         if request.json:                          132         if request.json:
244                 json_str = kunit_json.get_json !! 133                 json_obj = kunit_json.get_json_result(
245                                         test=t !! 134                                         test_result=test_result,
246                                         metada !! 135                                         def_config='kunit_defconfig',
                                                   >> 136                                         build_dir=request.build_dir,
                                                   >> 137                                         json_path=request.json)
247                 if request.json == 'stdout':      138                 if request.json == 'stdout':
248                         print(json_str)        !! 139                         print(json_obj)
249                 else:                          << 
250                         with open(request.json << 
251                                 f.write(json_s << 
252                         stdout.print_with_time << 
253                                 os.path.abspat << 
254                                                   140 
255         if test.status != kunit_parser.TestSta !! 141         if test_result.status != kunit_parser.TestStatus.SUCCESS:
256                 return KunitResult(KunitStatus !! 142                 return KunitResult(KunitStatus.TEST_FAILURE, test_result,
                                                   >> 143                                    parse_end - parse_start)
257                                                   144 
258         return KunitResult(KunitStatus.SUCCESS !! 145         return KunitResult(KunitStatus.SUCCESS, test_result,
                                                   >> 146                                 parse_end - parse_start)
259                                                   147 
260 def run_tests(linux: kunit_kernel.LinuxSourceT    148 def run_tests(linux: kunit_kernel.LinuxSourceTree,
261               request: KunitRequest) -> KunitR    149               request: KunitRequest) -> KunitResult:
262         run_start = time.time()                   150         run_start = time.time()
263                                                   151 
264         config_result = config_tests(linux, re !! 152         config_request = KunitConfigRequest(request.build_dir,
                                                   >> 153                                             request.make_options)
                                                   >> 154         config_result = config_tests(linux, config_request)
265         if config_result.status != KunitStatus    155         if config_result.status != KunitStatus.SUCCESS:
266                 return config_result              156                 return config_result
267                                                   157 
268         build_result = build_tests(linux, requ !! 158         build_request = KunitBuildRequest(request.jobs, request.build_dir,
                                                   >> 159                                           request.alltests,
                                                   >> 160                                           request.make_options)
                                                   >> 161         build_result = build_tests(linux, build_request)
269         if build_result.status != KunitStatus.    162         if build_result.status != KunitStatus.SUCCESS:
270                 return build_result               163                 return build_result
271                                                   164 
272         exec_result = exec_tests(linux, reques !! 165         exec_request = KunitExecRequest(request.timeout, request.build_dir,
                                                   >> 166                                  request.alltests, request.filter_glob,
                                                   >> 167                                  request.kernel_args)
                                                   >> 168         exec_result = exec_tests(linux, exec_request)
                                                   >> 169         if exec_result.status != KunitStatus.SUCCESS:
                                                   >> 170                 return exec_result
                                                   >> 171 
                                                   >> 172         parse_request = KunitParseRequest(request.raw_output,
                                                   >> 173                                           exec_result.result,
                                                   >> 174                                           request.build_dir,
                                                   >> 175                                           request.json)
                                                   >> 176         parse_result = parse_tests(parse_request)
273                                                   177 
274         run_end = time.time()                     178         run_end = time.time()
275                                                   179 
276         stdout.print_with_timestamp((          !! 180         kunit_parser.print_with_timestamp((
277                 'Elapsed time: %.3fs total, %.    181                 'Elapsed time: %.3fs total, %.3fs configuring, %.3fs ' +
278                 'building, %.3fs running\n') %    182                 'building, %.3fs running\n') % (
279                                 run_end - run_    183                                 run_end - run_start,
280                                 config_result.    184                                 config_result.elapsed_time,
281                                 build_result.e    185                                 build_result.elapsed_time,
282                                 exec_result.el    186                                 exec_result.elapsed_time))
283         return exec_result                     !! 187         return parse_result
284                                                   188 
285 # Problem:                                        189 # Problem:
286 # $ kunit.py run --json                           190 # $ kunit.py run --json
287 # works as one would expect and prints the par    191 # works as one would expect and prints the parsed test results as JSON.
288 # $ kunit.py run --json suite_name                192 # $ kunit.py run --json suite_name
289 # would *not* pass suite_name as the filter_gl    193 # would *not* pass suite_name as the filter_glob and print as json.
290 # argparse will consider it to be another way     194 # argparse will consider it to be another way of writing
291 # $ kunit.py run --json=suite_name                195 # $ kunit.py run --json=suite_name
292 # i.e. it would run all tests, and dump the js    196 # i.e. it would run all tests, and dump the json to a `suite_name` file.
293 # So we hackily automatically rewrite --json =    197 # So we hackily automatically rewrite --json => --json=stdout
294 pseudo_bool_flag_defaults = {                     198 pseudo_bool_flag_defaults = {
295                 '--json': 'stdout',               199                 '--json': 'stdout',
296                 '--raw_output': 'kunit',          200                 '--raw_output': 'kunit',
297 }                                                 201 }
298 def massage_argv(argv: Sequence[str]) -> Seque    202 def massage_argv(argv: Sequence[str]) -> Sequence[str]:
299         def massage_arg(arg: str) -> str:         203         def massage_arg(arg: str) -> str:
300                 if arg not in pseudo_bool_flag    204                 if arg not in pseudo_bool_flag_defaults:
301                         return arg                205                         return arg
302                 return  f'{arg}={pseudo_bool_f    206                 return  f'{arg}={pseudo_bool_flag_defaults[arg]}'
303         return list(map(massage_arg, argv))       207         return list(map(massage_arg, argv))
304                                                   208 
305 def get_default_jobs() -> int:                 !! 209 def add_common_opts(parser) -> None:
306         return len(os.sched_getaffinity(0))    << 
307                                                << 
308 def add_common_opts(parser: argparse.ArgumentP << 
309         parser.add_argument('--build_dir',        210         parser.add_argument('--build_dir',
310                             help='As in the ma    211                             help='As in the make command, it specifies the build '
311                             'directory.',         212                             'directory.',
312                             type=str, default= !! 213                             type=str, default='.kunit', metavar='build_dir')
313         parser.add_argument('--make_options',     214         parser.add_argument('--make_options',
314                             help='X=Y make opt    215                             help='X=Y make option, can be repeated.',
315                             action='append', m !! 216                             action='append')
316         parser.add_argument('--alltests',         217         parser.add_argument('--alltests',
317                             help='Run all KUni !! 218                             help='Run all KUnit tests through allyesconfig',
318                             action='store_true    219                             action='store_true')
319         parser.add_argument('--kunitconfig',      220         parser.add_argument('--kunitconfig',
320                              help='Path to Kco    221                              help='Path to Kconfig fragment that enables KUnit tests.'
321                              ' If given a dire    222                              ' If given a directory, (e.g. lib/kunit), "/.kunitconfig" '
322                              'will get  automa !! 223                              'will get  automatically appended.',
323                              'blindly concaten !! 224                              metavar='kunitconfig')
324                              action='append',  << 
325         parser.add_argument('--kconfig_add',   << 
326                              help='Additional  << 
327                              '.kunitconfig, e. << 
328                             action='append', m << 
329                                                   225 
330         parser.add_argument('--arch',             226         parser.add_argument('--arch',
331                             help=('Specifies t    227                             help=('Specifies the architecture to run tests under. '
332                                   'The archite    228                                   'The architecture specified here must match the '
333                                   'string pass    229                                   'string passed to the ARCH make param, '
334                                   'e.g. i386,     230                                   'e.g. i386, x86_64, arm, um, etc. Non-UML '
335                                   'architectur    231                                   'architectures run on QEMU.'),
336                             type=str, default= !! 232                             type=str, default='um', metavar='arch')
337                                                   233 
338         parser.add_argument('--cross_compile',    234         parser.add_argument('--cross_compile',
339                             help=('Sets make\'    235                             help=('Sets make\'s CROSS_COMPILE variable; it should '
340                                   'be set to a    236                                   'be set to a toolchain path prefix (the prefix '
341                                   'of gcc and     237                                   'of gcc and other tools in your toolchain, for '
342                                   'example `sp    238                                   'example `sparc64-linux-gnu-` if you have the '
343                                   'sparc toolc    239                                   'sparc toolchain installed on your system, or '
344                                   '`$HOME/tool    240                                   '`$HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/microblaze-linux-` '
345                                   'if you have    241                                   'if you have downloaded the microblaze toolchain '
346                                   'from the 0-    242                                   'from the 0-day website to a directory in your '
347                                   'home direct    243                                   'home directory called `toolchains`).'),
348                             metavar='PREFIX')  !! 244                             metavar='cross_compile')
349                                                   245 
350         parser.add_argument('--qemu_config',      246         parser.add_argument('--qemu_config',
351                             help=('Takes a pat    247                             help=('Takes a path to a path to a file containing '
352                                   'a QemuArchP    248                                   'a QemuArchParams object.'),
353                             type=str, metavar= !! 249                             type=str, metavar='qemu_config')
354                                                   250 
355         parser.add_argument('--qemu_args',     !! 251 def add_build_opts(parser) -> None:
356                             help='Additional Q << 
357                             action='append', m << 
358                                                << 
359 def add_build_opts(parser: argparse.ArgumentPa << 
360         parser.add_argument('--jobs',             252         parser.add_argument('--jobs',
361                             help='As in the ma    253                             help='As in the make command, "Specifies  the number of '
362                             'jobs (commands) t    254                             'jobs (commands) to run simultaneously."',
363                             type=int, default= !! 255                             type=int, default=8, metavar='jobs')
364                                                   256 
365 def add_exec_opts(parser: argparse.ArgumentPar !! 257 def add_exec_opts(parser) -> None:
366         parser.add_argument('--timeout',          258         parser.add_argument('--timeout',
367                             help='maximum numb    259                             help='maximum number of seconds to allow for all tests '
368                             'to run. This does    260                             'to run. This does not include time taken to build the '
369                             'tests.',             261                             'tests.',
370                             type=int,             262                             type=int,
371                             default=300,          263                             default=300,
372                             metavar='SECONDS') !! 264                             metavar='timeout')
373         parser.add_argument('filter_glob',        265         parser.add_argument('filter_glob',
374                             help='Filter which !! 266                             help='maximum number of seconds to allow for all tests '
375                             'boot-time, e.g. l !! 267                             'to run. This does not include time taken to build the '
                                                   >> 268                             'tests.',
376                             type=str,             269                             type=str,
377                             nargs='?',            270                             nargs='?',
378                             default='',           271                             default='',
379                             metavar='filter_gl    272                             metavar='filter_glob')
380         parser.add_argument('--filter',        << 
381                             help='Filter KUnit << 
382                             'e.g. module=examp << 
383                             type=str,          << 
384                                 default='')    << 
385         parser.add_argument('--filter_action', << 
386                             help='If set to sk << 
387                                 'e.g. --filter << 
388                             type=str,          << 
389                                 choices=['skip << 
390         parser.add_argument('--kernel_args',      273         parser.add_argument('--kernel_args',
391                             help='Kernel comma    274                             help='Kernel command-line parameters. Maybe be repeated',
392                              action='append',  !! 275                              action='append')
393         parser.add_argument('--run_isolated',  << 
394                             'individual suite/ << 
395                             'a non-hermetic te << 
396                             'what ran before i << 
397                             type=str,          << 
398                             choices=['suite',  << 
399         parser.add_argument('--list_tests', he << 
400                             'run.',            << 
401                             action='store_true << 
402         parser.add_argument('--list_tests_attr << 
403                             'attributes.',     << 
404                             action='store_true << 
405                                                   276 
406 def add_parse_opts(parser: argparse.ArgumentPa !! 277 def add_parse_opts(parser) -> None:
407         parser.add_argument('--raw_output', he !! 278         parser.add_argument('--raw_output', help='If set don\'t format output from kernel. '
408                             'By default, filte !! 279                             'If set to --raw_output=kunit, filters to just KUnit output.',
409                             '--raw_output=all  !! 280                             type=str, nargs='?', const='all', default=None)
410                              type=str, nargs=' << 
411         parser.add_argument('--json',             281         parser.add_argument('--json',
412                             nargs='?',            282                             nargs='?',
413                             help='Prints parse !! 283                             help='Stores test results in a JSON, and either '
414                             'a filename is spe !! 284                             'prints to stdout or saves to file if a '
415                             type=str, const='s !! 285                             'filename is specified',
416                                                !! 286                             type=str, const='stdout', default=None)
417                                                << 
418 def tree_from_args(cli_args: argparse.Namespac << 
419         """Returns a LinuxSourceTree based on  << 
420         # Allow users to specify multiple argu << 
421         qemu_args: List[str] = []              << 
422         if cli_args.qemu_args:                 << 
423                 for arg in cli_args.qemu_args: << 
424                         qemu_args.extend(shlex << 
425                                                << 
426         kunitconfigs = cli_args.kunitconfig if << 
427         if cli_args.alltests:                  << 
428                 # Prepend so user-specified op << 
429                 # --kunitconfig options to hav << 
430                 kunitconfigs = [kunit_kernel.A << 
431                                                << 
432         return kunit_kernel.LinuxSourceTree(cl << 
433                         kunitconfig_paths=kuni << 
434                         kconfig_add=cli_args.k << 
435                         arch=cli_args.arch,    << 
436                         cross_compile=cli_args << 
437                         qemu_config_path=cli_a << 
438                         extra_qemu_args=qemu_a << 
439                                                << 
440                                                << 
441 def run_handler(cli_args: argparse.Namespace)  << 
442         if not os.path.exists(cli_args.build_d << 
443                 os.mkdir(cli_args.build_dir)   << 
444                                                << 
445         linux = tree_from_args(cli_args)       << 
446         request = KunitRequest(build_dir=cli_a << 
447                                         make_o << 
448                                         jobs=c << 
449                                         raw_ou << 
450                                         json=c << 
451                                         timeou << 
452                                         filter << 
453                                         filter << 
454                                         filter << 
455                                         kernel << 
456                                         run_is << 
457                                         list_t << 
458                                         list_t << 
459         result = run_tests(linux, request)     << 
460         if result.status != KunitStatus.SUCCES << 
461                 sys.exit(1)                    << 
462                                                << 
463                                                << 
464 def config_handler(cli_args: argparse.Namespac << 
465         if cli_args.build_dir and (            << 
466                         not os.path.exists(cli << 
467                 os.mkdir(cli_args.build_dir)   << 
468                                                << 
469         linux = tree_from_args(cli_args)       << 
470         request = KunitConfigRequest(build_dir << 
471                                                << 
472         result = config_tests(linux, request)  << 
473         stdout.print_with_timestamp((          << 
474                 'Elapsed time: %.3fs\n') % (   << 
475                         result.elapsed_time))  << 
476         if result.status != KunitStatus.SUCCES << 
477                 sys.exit(1)                    << 
478                                                << 
479                                                << 
480 def build_handler(cli_args: argparse.Namespace << 
481         linux = tree_from_args(cli_args)       << 
482         request = KunitBuildRequest(build_dir= << 
483                                         make_o << 
484                                         jobs=c << 
485         result = config_and_build_tests(linux, << 
486         stdout.print_with_timestamp((          << 
487                 'Elapsed time: %.3fs\n') % (   << 
488                         result.elapsed_time))  << 
489         if result.status != KunitStatus.SUCCES << 
490                 sys.exit(1)                    << 
491                                                << 
492                                                << 
493 def exec_handler(cli_args: argparse.Namespace) << 
494         linux = tree_from_args(cli_args)       << 
495         exec_request = KunitExecRequest(raw_ou << 
496                                         build_ << 
497                                         json=c << 
498                                         timeou << 
499                                         filter << 
500                                         filter << 
501                                         filter << 
502                                         kernel << 
503                                         run_is << 
504                                         list_t << 
505                                         list_t << 
506         result = exec_tests(linux, exec_reques << 
507         stdout.print_with_timestamp((          << 
508                 'Elapsed time: %.3fs\n') % (re << 
509         if result.status != KunitStatus.SUCCES << 
510                 sys.exit(1)                    << 
511                                                   287 
512                                                !! 288 def main(argv, linux=None):
513 def parse_handler(cli_args: argparse.Namespace << 
514         if cli_args.file is None:              << 
515                 sys.stdin.reconfigure(errors=' << 
516                 kunit_output = sys.stdin  # ty << 
517         else:                                  << 
518                 with open(cli_args.file, 'r',  << 
519                         kunit_output = f.read( << 
520         # We know nothing about how the result << 
521         metadata = kunit_json.Metadata()       << 
522         request = KunitParseRequest(raw_output << 
523                                         json=c << 
524         result, _ = parse_tests(request, metad << 
525         if result.status != KunitStatus.SUCCES << 
526                 sys.exit(1)                    << 
527                                                << 
528                                                << 
529 subcommand_handlers_map = {                    << 
530         'run': run_handler,                    << 
531         'config': config_handler,              << 
532         'build': build_handler,                << 
533         'exec': exec_handler,                  << 
534         'parse': parse_handler                 << 
535 }                                              << 
536                                                << 
537                                                << 
538 def main(argv: Sequence[str]) -> None:         << 
539         parser = argparse.ArgumentParser(         289         parser = argparse.ArgumentParser(
540                         description='Helps wri    290                         description='Helps writing and running KUnit tests.')
541         subparser = parser.add_subparsers(dest    291         subparser = parser.add_subparsers(dest='subcommand')
542                                                   292 
543         # The 'run' command will config, build    293         # The 'run' command will config, build, exec, and parse in one go.
544         run_parser = subparser.add_parser('run    294         run_parser = subparser.add_parser('run', help='Runs KUnit tests.')
545         add_common_opts(run_parser)               295         add_common_opts(run_parser)
546         add_build_opts(run_parser)                296         add_build_opts(run_parser)
547         add_exec_opts(run_parser)                 297         add_exec_opts(run_parser)
548         add_parse_opts(run_parser)                298         add_parse_opts(run_parser)
549                                                   299 
550         config_parser = subparser.add_parser('    300         config_parser = subparser.add_parser('config',
551                                                   301                                                 help='Ensures that .config contains all of '
552                                                   302                                                 'the options in .kunitconfig')
553         add_common_opts(config_parser)            303         add_common_opts(config_parser)
554                                                   304 
555         build_parser = subparser.add_parser('b    305         build_parser = subparser.add_parser('build', help='Builds a kernel with KUnit tests')
556         add_common_opts(build_parser)             306         add_common_opts(build_parser)
557         add_build_opts(build_parser)              307         add_build_opts(build_parser)
558                                                   308 
559         exec_parser = subparser.add_parser('ex    309         exec_parser = subparser.add_parser('exec', help='Run a kernel with KUnit tests')
560         add_common_opts(exec_parser)              310         add_common_opts(exec_parser)
561         add_exec_opts(exec_parser)                311         add_exec_opts(exec_parser)
562         add_parse_opts(exec_parser)               312         add_parse_opts(exec_parser)
563                                                   313 
564         # The 'parse' option is special, as it    314         # The 'parse' option is special, as it doesn't need the kernel source
565         # (therefore there is no need for a bu    315         # (therefore there is no need for a build_dir, hence no add_common_opts)
566         # and the '--file' argument is not rel    316         # and the '--file' argument is not relevant to 'run', so isn't in
567         # add_parse_opts()                        317         # add_parse_opts()
568         parse_parser = subparser.add_parser('p    318         parse_parser = subparser.add_parser('parse',
569                                             he    319                                             help='Parses KUnit results from a file, '
570                                             'a    320                                             'and parses formatted results.')
571         add_parse_opts(parse_parser)              321         add_parse_opts(parse_parser)
572         parse_parser.add_argument('file',         322         parse_parser.add_argument('file',
573                                   help='Specif    323                                   help='Specifies the file to read results from.',
574                                   type=str, na    324                                   type=str, nargs='?', metavar='input_file')
575                                                   325 
576         cli_args = parser.parse_args(massage_a    326         cli_args = parser.parse_args(massage_argv(argv))
577                                                   327 
578         if get_kernel_root_path():                328         if get_kernel_root_path():
579                 os.chdir(get_kernel_root_path(    329                 os.chdir(get_kernel_root_path())
580                                                   330 
581         subcomand_handler = subcommand_handler !! 331         if cli_args.subcommand == 'run':
582                                                !! 332                 if not os.path.exists(cli_args.build_dir):
583         if subcomand_handler is None:          !! 333                         os.mkdir(cli_args.build_dir)
                                                   >> 334 
                                                   >> 335                 if not linux:
                                                   >> 336                         linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                                   >> 337                                         kunitconfig_path=cli_args.kunitconfig,
                                                   >> 338                                         arch=cli_args.arch,
                                                   >> 339                                         cross_compile=cli_args.cross_compile,
                                                   >> 340                                         qemu_config_path=cli_args.qemu_config)
                                                   >> 341 
                                                   >> 342                 request = KunitRequest(cli_args.raw_output,
                                                   >> 343                                        cli_args.timeout,
                                                   >> 344                                        cli_args.jobs,
                                                   >> 345                                        cli_args.build_dir,
                                                   >> 346                                        cli_args.alltests,
                                                   >> 347                                        cli_args.filter_glob,
                                                   >> 348                                        cli_args.kernel_args,
                                                   >> 349                                        cli_args.json,
                                                   >> 350                                        cli_args.make_options)
                                                   >> 351                 result = run_tests(linux, request)
                                                   >> 352                 if result.status != KunitStatus.SUCCESS:
                                                   >> 353                         sys.exit(1)
                                                   >> 354         elif cli_args.subcommand == 'config':
                                                   >> 355                 if cli_args.build_dir and (
                                                   >> 356                                 not os.path.exists(cli_args.build_dir)):
                                                   >> 357                         os.mkdir(cli_args.build_dir)
                                                   >> 358 
                                                   >> 359                 if not linux:
                                                   >> 360                         linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                                   >> 361                                         kunitconfig_path=cli_args.kunitconfig,
                                                   >> 362                                         arch=cli_args.arch,
                                                   >> 363                                         cross_compile=cli_args.cross_compile,
                                                   >> 364                                         qemu_config_path=cli_args.qemu_config)
                                                   >> 365 
                                                   >> 366                 request = KunitConfigRequest(cli_args.build_dir,
                                                   >> 367                                              cli_args.make_options)
                                                   >> 368                 result = config_tests(linux, request)
                                                   >> 369                 kunit_parser.print_with_timestamp((
                                                   >> 370                         'Elapsed time: %.3fs\n') % (
                                                   >> 371                                 result.elapsed_time))
                                                   >> 372                 if result.status != KunitStatus.SUCCESS:
                                                   >> 373                         sys.exit(1)
                                                   >> 374         elif cli_args.subcommand == 'build':
                                                   >> 375                 if not linux:
                                                   >> 376                         linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                                   >> 377                                         kunitconfig_path=cli_args.kunitconfig,
                                                   >> 378                                         arch=cli_args.arch,
                                                   >> 379                                         cross_compile=cli_args.cross_compile,
                                                   >> 380                                         qemu_config_path=cli_args.qemu_config)
                                                   >> 381 
                                                   >> 382                 request = KunitBuildRequest(cli_args.jobs,
                                                   >> 383                                             cli_args.build_dir,
                                                   >> 384                                             cli_args.alltests,
                                                   >> 385                                             cli_args.make_options)
                                                   >> 386                 result = build_tests(linux, request)
                                                   >> 387                 kunit_parser.print_with_timestamp((
                                                   >> 388                         'Elapsed time: %.3fs\n') % (
                                                   >> 389                                 result.elapsed_time))
                                                   >> 390                 if result.status != KunitStatus.SUCCESS:
                                                   >> 391                         sys.exit(1)
                                                   >> 392         elif cli_args.subcommand == 'exec':
                                                   >> 393                 if not linux:
                                                   >> 394                         linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                                   >> 395                                         kunitconfig_path=cli_args.kunitconfig,
                                                   >> 396                                         arch=cli_args.arch,
                                                   >> 397                                         cross_compile=cli_args.cross_compile,
                                                   >> 398                                         qemu_config_path=cli_args.qemu_config)
                                                   >> 399 
                                                   >> 400                 exec_request = KunitExecRequest(cli_args.timeout,
                                                   >> 401                                                 cli_args.build_dir,
                                                   >> 402                                                 cli_args.alltests,
                                                   >> 403                                                 cli_args.filter_glob,
                                                   >> 404                                                 cli_args.kernel_args)
                                                   >> 405                 exec_result = exec_tests(linux, exec_request)
                                                   >> 406                 parse_request = KunitParseRequest(cli_args.raw_output,
                                                   >> 407                                                   exec_result.result,
                                                   >> 408                                                   cli_args.build_dir,
                                                   >> 409                                                   cli_args.json)
                                                   >> 410                 result = parse_tests(parse_request)
                                                   >> 411                 kunit_parser.print_with_timestamp((
                                                   >> 412                         'Elapsed time: %.3fs\n') % (
                                                   >> 413                                 exec_result.elapsed_time))
                                                   >> 414                 if result.status != KunitStatus.SUCCESS:
                                                   >> 415                         sys.exit(1)
                                                   >> 416         elif cli_args.subcommand == 'parse':
                                                   >> 417                 if cli_args.file == None:
                                                   >> 418                         kunit_output = sys.stdin
                                                   >> 419                 else:
                                                   >> 420                         with open(cli_args.file, 'r') as f:
                                                   >> 421                                 kunit_output = f.read().splitlines()
                                                   >> 422                 request = KunitParseRequest(cli_args.raw_output,
                                                   >> 423                                             kunit_output,
                                                   >> 424                                             None,
                                                   >> 425                                             cli_args.json)
                                                   >> 426                 result = parse_tests(request)
                                                   >> 427                 if result.status != KunitStatus.SUCCESS:
                                                   >> 428                         sys.exit(1)
                                                   >> 429         else:
584                 parser.print_help()               430                 parser.print_help()
585                 return                         << 
586                                                << 
587         subcomand_handler(cli_args)            << 
588                                                << 
589                                                   431 
590 if __name__ == '__main__':                        432 if __name__ == '__main__':
591         main(sys.argv[1:])                        433         main(sys.argv[1:])
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php