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

TOMOYO Linux Cross Reference
Linux/tools/testing/kunit/kunit_tool_test.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_tool_test.py (Version linux-6.12-rc7) and /tools/testing/kunit/kunit_tool_test.py (Version linux-6.2.16)


  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 collection of tests for tools/testing/kuni      4 # A collection of tests for tools/testing/kunit/kunit.py
  5 #                                                   5 #
  6 # Copyright (C) 2019, Google LLC.                   6 # Copyright (C) 2019, Google LLC.
  7 # Author: Brendan Higgins <brendanhiggins@googl      7 # Author: Brendan Higgins <brendanhiggins@google.com>
  8                                                     8 
  9 import unittest                                     9 import unittest
 10 from unittest import mock                          10 from unittest import mock
 11                                                    11 
 12 import tempfile, shutil # Handling test_tmpdir     12 import tempfile, shutil # Handling test_tmpdir
 13                                                    13 
 14 import itertools                                   14 import itertools
 15 import json                                        15 import json
 16 import os                                          16 import os
 17 import signal                                      17 import signal
 18 import subprocess                                  18 import subprocess
 19 from typing import Iterable                        19 from typing import Iterable
 20                                                    20 
 21 import kunit_config                                21 import kunit_config
 22 import kunit_parser                                22 import kunit_parser
 23 import kunit_kernel                                23 import kunit_kernel
 24 import kunit_json                                  24 import kunit_json
 25 import kunit                                       25 import kunit
 26                                                    26 
 27 test_tmpdir = ''                                   27 test_tmpdir = ''
 28 abs_test_data_dir = ''                             28 abs_test_data_dir = ''
 29                                                    29 
 30 def setUpModule():                                 30 def setUpModule():
 31         global test_tmpdir, abs_test_data_dir      31         global test_tmpdir, abs_test_data_dir
 32         test_tmpdir = tempfile.mkdtemp()           32         test_tmpdir = tempfile.mkdtemp()
 33         abs_test_data_dir = os.path.abspath(os     33         abs_test_data_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'test_data'))
 34                                                    34 
 35 def tearDownModule():                              35 def tearDownModule():
 36         shutil.rmtree(test_tmpdir)                 36         shutil.rmtree(test_tmpdir)
 37                                                    37 
 38 def test_data_path(path):                          38 def test_data_path(path):
 39         return os.path.join(abs_test_data_dir,     39         return os.path.join(abs_test_data_dir, path)
 40                                                    40 
 41 class KconfigTest(unittest.TestCase):              41 class KconfigTest(unittest.TestCase):
 42                                                    42 
 43         def test_is_subset_of(self):               43         def test_is_subset_of(self):
 44                 kconfig0 = kunit_config.Kconfi     44                 kconfig0 = kunit_config.Kconfig()
 45                 self.assertTrue(kconfig0.is_su     45                 self.assertTrue(kconfig0.is_subset_of(kconfig0))
 46                                                    46 
 47                 kconfig1 = kunit_config.Kconfi     47                 kconfig1 = kunit_config.Kconfig()
 48                 kconfig1.add_entry('TEST', 'y'     48                 kconfig1.add_entry('TEST', 'y')
 49                 self.assertTrue(kconfig1.is_su     49                 self.assertTrue(kconfig1.is_subset_of(kconfig1))
 50                 self.assertTrue(kconfig0.is_su     50                 self.assertTrue(kconfig0.is_subset_of(kconfig1))
 51                 self.assertFalse(kconfig1.is_s     51                 self.assertFalse(kconfig1.is_subset_of(kconfig0))
 52                                                    52 
 53         def test_read_from_file(self):             53         def test_read_from_file(self):
 54                 kconfig_path = test_data_path(     54                 kconfig_path = test_data_path('test_read_from_file.kconfig')
 55                                                    55 
 56                 kconfig = kunit_config.parse_f     56                 kconfig = kunit_config.parse_file(kconfig_path)
 57                                                    57 
 58                 expected_kconfig = kunit_confi     58                 expected_kconfig = kunit_config.Kconfig()
 59                 expected_kconfig.add_entry('UM     59                 expected_kconfig.add_entry('UML', 'y')
 60                 expected_kconfig.add_entry('MM     60                 expected_kconfig.add_entry('MMU', 'y')
 61                 expected_kconfig.add_entry('TE     61                 expected_kconfig.add_entry('TEST', 'y')
 62                 expected_kconfig.add_entry('EX     62                 expected_kconfig.add_entry('EXAMPLE_TEST', 'y')
 63                 expected_kconfig.add_entry('MK     63                 expected_kconfig.add_entry('MK8', 'n')
 64                                                    64 
 65                 self.assertEqual(kconfig, expe     65                 self.assertEqual(kconfig, expected_kconfig)
 66                                                    66 
 67         def test_write_to_file(self):              67         def test_write_to_file(self):
 68                 kconfig_path = os.path.join(te     68                 kconfig_path = os.path.join(test_tmpdir, '.config')
 69                                                    69 
 70                 expected_kconfig = kunit_confi     70                 expected_kconfig = kunit_config.Kconfig()
 71                 expected_kconfig.add_entry('UM     71                 expected_kconfig.add_entry('UML', 'y')
 72                 expected_kconfig.add_entry('MM     72                 expected_kconfig.add_entry('MMU', 'y')
 73                 expected_kconfig.add_entry('TE     73                 expected_kconfig.add_entry('TEST', 'y')
 74                 expected_kconfig.add_entry('EX     74                 expected_kconfig.add_entry('EXAMPLE_TEST', 'y')
 75                 expected_kconfig.add_entry('MK     75                 expected_kconfig.add_entry('MK8', 'n')
 76                                                    76 
 77                 expected_kconfig.write_to_file     77                 expected_kconfig.write_to_file(kconfig_path)
 78                                                    78 
 79                 actual_kconfig = kunit_config.     79                 actual_kconfig = kunit_config.parse_file(kconfig_path)
 80                 self.assertEqual(actual_kconfi     80                 self.assertEqual(actual_kconfig, expected_kconfig)
 81                                                    81 
 82 class KUnitParserTest(unittest.TestCase):          82 class KUnitParserTest(unittest.TestCase):
 83         def setUp(self):                           83         def setUp(self):
 84                 self.print_mock = mock.patch('     84                 self.print_mock = mock.patch('kunit_printer.Printer.print').start()
 85                 self.addCleanup(mock.patch.sto     85                 self.addCleanup(mock.patch.stopall)
 86                                                    86 
 87         def noPrintCallContains(self, substr:      87         def noPrintCallContains(self, substr: str):
 88                 for call in self.print_mock.mo     88                 for call in self.print_mock.mock_calls:
 89                         self.assertNotIn(subst     89                         self.assertNotIn(substr, call.args[0])
 90                                                    90 
 91         def assertContains(self, needle: str,      91         def assertContains(self, needle: str, haystack: kunit_parser.LineStream):
 92                 # Clone the iterator so we can     92                 # Clone the iterator so we can print the contents on failure.
 93                 copy, backup = itertools.tee(h     93                 copy, backup = itertools.tee(haystack)
 94                 for line in copy:                  94                 for line in copy:
 95                         if needle in line:         95                         if needle in line:
 96                                 return             96                                 return
 97                 raise AssertionError(f'"{needl     97                 raise AssertionError(f'"{needle}" not found in {list(backup)}!')
 98                                                    98 
 99         def test_output_isolated_correctly(sel     99         def test_output_isolated_correctly(self):
100                 log_path = test_data_path('tes    100                 log_path = test_data_path('test_output_isolated_correctly.log')
101                 with open(log_path) as file:      101                 with open(log_path) as file:
102                         result = kunit_parser.    102                         result = kunit_parser.extract_tap_lines(file.readlines())
103                 self.assertContains('TAP versi    103                 self.assertContains('TAP version 14', result)
104                 self.assertContains('# Subtest    104                 self.assertContains('# Subtest: example', result)
105                 self.assertContains('1..2', re    105                 self.assertContains('1..2', result)
106                 self.assertContains('ok 1 - ex    106                 self.assertContains('ok 1 - example_simple_test', result)
107                 self.assertContains('ok 2 - ex    107                 self.assertContains('ok 2 - example_mock_test', result)
108                 self.assertContains('ok 1 - ex    108                 self.assertContains('ok 1 - example', result)
109                                                   109 
110         def test_output_with_prefix_isolated_c    110         def test_output_with_prefix_isolated_correctly(self):
111                 log_path = test_data_path('tes    111                 log_path = test_data_path('test_pound_sign.log')
112                 with open(log_path) as file:      112                 with open(log_path) as file:
113                         result = kunit_parser.    113                         result = kunit_parser.extract_tap_lines(file.readlines())
114                 self.assertContains('TAP versi    114                 self.assertContains('TAP version 14', result)
115                 self.assertContains('# Subtest    115                 self.assertContains('# Subtest: kunit-resource-test', result)
116                 self.assertContains('1..5', re    116                 self.assertContains('1..5', result)
117                 self.assertContains('ok 1 - ku    117                 self.assertContains('ok 1 - kunit_resource_test_init_resources', result)
118                 self.assertContains('ok 2 - ku    118                 self.assertContains('ok 2 - kunit_resource_test_alloc_resource', result)
119                 self.assertContains('ok 3 - ku    119                 self.assertContains('ok 3 - kunit_resource_test_destroy_resource', result)
120                 self.assertContains('foo bar      120                 self.assertContains('foo bar    #', result)
121                 self.assertContains('ok 4 - ku    121                 self.assertContains('ok 4 - kunit_resource_test_cleanup_resources', result)
122                 self.assertContains('ok 5 - ku    122                 self.assertContains('ok 5 - kunit_resource_test_proper_free_ordering', result)
123                 self.assertContains('ok 1 - ku    123                 self.assertContains('ok 1 - kunit-resource-test', result)
124                 self.assertContains('foo bar      124                 self.assertContains('foo bar    # non-kunit output', result)
125                 self.assertContains('# Subtest    125                 self.assertContains('# Subtest: kunit-try-catch-test', result)
126                 self.assertContains('1..2', re    126                 self.assertContains('1..2', result)
127                 self.assertContains('ok 1 - ku    127                 self.assertContains('ok 1 - kunit_test_try_catch_successful_try_no_catch',
128                                     result)       128                                     result)
129                 self.assertContains('ok 2 - ku    129                 self.assertContains('ok 2 - kunit_test_try_catch_unsuccessful_try_does_catch',
130                                     result)       130                                     result)
131                 self.assertContains('ok 2 - ku    131                 self.assertContains('ok 2 - kunit-try-catch-test', result)
132                 self.assertContains('# Subtest    132                 self.assertContains('# Subtest: string-stream-test', result)
133                 self.assertContains('1..3', re    133                 self.assertContains('1..3', result)
134                 self.assertContains('ok 1 - st    134                 self.assertContains('ok 1 - string_stream_test_empty_on_creation', result)
135                 self.assertContains('ok 2 - st    135                 self.assertContains('ok 2 - string_stream_test_not_empty_after_add', result)
136                 self.assertContains('ok 3 - st    136                 self.assertContains('ok 3 - string_stream_test_get_string', result)
137                 self.assertContains('ok 3 - st    137                 self.assertContains('ok 3 - string-stream-test', result)
138                                                   138 
139         def test_parse_successful_test_log(sel    139         def test_parse_successful_test_log(self):
140                 all_passed_log = test_data_pat    140                 all_passed_log = test_data_path('test_is_test_passed-all_passed.log')
141                 with open(all_passed_log) as f    141                 with open(all_passed_log) as file:
142                         result = kunit_parser.    142                         result = kunit_parser.parse_run_tests(file.readlines())
143                 self.assertEqual(kunit_parser.    143                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
144                 self.assertEqual(result.counts    144                 self.assertEqual(result.counts.errors, 0)
145                                                   145 
146         def test_parse_successful_nested_tests    146         def test_parse_successful_nested_tests_log(self):
147                 all_passed_log = test_data_pat    147                 all_passed_log = test_data_path('test_is_test_passed-all_passed_nested.log')
148                 with open(all_passed_log) as f    148                 with open(all_passed_log) as file:
149                         result = kunit_parser.    149                         result = kunit_parser.parse_run_tests(file.readlines())
150                 self.assertEqual(kunit_parser.    150                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
151                 self.assertEqual(result.counts    151                 self.assertEqual(result.counts.errors, 0)
152                                                   152 
153         def test_kselftest_nested(self):          153         def test_kselftest_nested(self):
154                 kselftest_log = test_data_path    154                 kselftest_log = test_data_path('test_is_test_passed-kselftest.log')
155                 with open(kselftest_log) as fi    155                 with open(kselftest_log) as file:
156                         result = kunit_parser.    156                         result = kunit_parser.parse_run_tests(file.readlines())
157                 self.assertEqual(kunit_parser.    157                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
158                 self.assertEqual(result.counts    158                 self.assertEqual(result.counts.errors, 0)
159                                                   159 
160         def test_parse_failed_test_log(self):     160         def test_parse_failed_test_log(self):
161                 failed_log = test_data_path('t    161                 failed_log = test_data_path('test_is_test_passed-failure.log')
162                 with open(failed_log) as file:    162                 with open(failed_log) as file:
163                         result = kunit_parser.    163                         result = kunit_parser.parse_run_tests(file.readlines())
164                 self.assertEqual(kunit_parser.    164                 self.assertEqual(kunit_parser.TestStatus.FAILURE, result.status)
165                 self.assertEqual(result.counts    165                 self.assertEqual(result.counts.errors, 0)
166                                                   166 
167         def test_no_header(self):                 167         def test_no_header(self):
168                 empty_log = test_data_path('te    168                 empty_log = test_data_path('test_is_test_passed-no_tests_run_no_header.log')
169                 with open(empty_log) as file:     169                 with open(empty_log) as file:
170                         result = kunit_parser.    170                         result = kunit_parser.parse_run_tests(
171                                 kunit_parser.e    171                                 kunit_parser.extract_tap_lines(file.readlines()))
172                 self.assertEqual(0, len(result    172                 self.assertEqual(0, len(result.subtests))
173                 self.assertEqual(kunit_parser.    173                 self.assertEqual(kunit_parser.TestStatus.FAILURE_TO_PARSE_TESTS, result.status)
174                 self.assertEqual(result.counts    174                 self.assertEqual(result.counts.errors, 1)
175                                                   175 
176         def test_missing_test_plan(self):         176         def test_missing_test_plan(self):
177                 missing_plan_log = test_data_p    177                 missing_plan_log = test_data_path('test_is_test_passed-'
178                         'missing_plan.log')       178                         'missing_plan.log')
179                 with open(missing_plan_log) as    179                 with open(missing_plan_log) as file:
180                         result = kunit_parser.    180                         result = kunit_parser.parse_run_tests(
181                                 kunit_parser.e    181                                 kunit_parser.extract_tap_lines(
182                                 file.readlines    182                                 file.readlines()))
183                 # A missing test plan is not a    183                 # A missing test plan is not an error.
184                 self.assertEqual(result.counts    184                 self.assertEqual(result.counts, kunit_parser.TestCounts(passed=10, errors=0))
185                 self.assertEqual(kunit_parser.    185                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
186                                                   186 
187         def test_no_tests(self):                  187         def test_no_tests(self):
188                 header_log = test_data_path('t    188                 header_log = test_data_path('test_is_test_passed-no_tests_run_with_header.log')
189                 with open(header_log) as file:    189                 with open(header_log) as file:
190                         result = kunit_parser.    190                         result = kunit_parser.parse_run_tests(
191                                 kunit_parser.e    191                                 kunit_parser.extract_tap_lines(file.readlines()))
192                 self.assertEqual(0, len(result    192                 self.assertEqual(0, len(result.subtests))
193                 self.assertEqual(kunit_parser.    193                 self.assertEqual(kunit_parser.TestStatus.NO_TESTS, result.status)
194                 self.assertEqual(result.counts    194                 self.assertEqual(result.counts.errors, 1)
195                                                   195 
196         def test_no_tests_no_plan(self):          196         def test_no_tests_no_plan(self):
197                 no_plan_log = test_data_path('    197                 no_plan_log = test_data_path('test_is_test_passed-no_tests_no_plan.log')
198                 with open(no_plan_log) as file    198                 with open(no_plan_log) as file:
199                         result = kunit_parser.    199                         result = kunit_parser.parse_run_tests(
200                                 kunit_parser.e    200                                 kunit_parser.extract_tap_lines(file.readlines()))
201                 self.assertEqual(0, len(result    201                 self.assertEqual(0, len(result.subtests[0].subtests[0].subtests))
202                 self.assertEqual(                 202                 self.assertEqual(
203                         kunit_parser.TestStatu    203                         kunit_parser.TestStatus.NO_TESTS,
204                         result.subtests[0].sub    204                         result.subtests[0].subtests[0].status)
205                 self.assertEqual(result.counts    205                 self.assertEqual(result.counts, kunit_parser.TestCounts(passed=1, errors=1))
206                                                   206 
207                                                   207 
208         def test_no_kunit_output(self):           208         def test_no_kunit_output(self):
209                 crash_log = test_data_path('te    209                 crash_log = test_data_path('test_insufficient_memory.log')
210                 print_mock = mock.patch('kunit    210                 print_mock = mock.patch('kunit_printer.Printer.print').start()
211                 with open(crash_log) as file:     211                 with open(crash_log) as file:
212                         result = kunit_parser.    212                         result = kunit_parser.parse_run_tests(
213                                 kunit_parser.e    213                                 kunit_parser.extract_tap_lines(file.readlines()))
214                 print_mock.assert_any_call(Str    214                 print_mock.assert_any_call(StrContains('Could not find any KTAP output.'))
215                 print_mock.stop()                 215                 print_mock.stop()
216                 self.assertEqual(0, len(result    216                 self.assertEqual(0, len(result.subtests))
217                 self.assertEqual(result.counts    217                 self.assertEqual(result.counts.errors, 1)
218                                                   218 
219         def test_skipped_test(self):              219         def test_skipped_test(self):
220                 skipped_log = test_data_path('    220                 skipped_log = test_data_path('test_skip_tests.log')
221                 with open(skipped_log) as file    221                 with open(skipped_log) as file:
222                         result = kunit_parser.    222                         result = kunit_parser.parse_run_tests(file.readlines())
223                                                   223 
224                 # A skipped test does not fail    224                 # A skipped test does not fail the whole suite.
225                 self.assertEqual(kunit_parser.    225                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
226                 self.assertEqual(result.counts    226                 self.assertEqual(result.counts, kunit_parser.TestCounts(passed=4, skipped=1))
227                                                   227 
228         def test_skipped_all_tests(self):         228         def test_skipped_all_tests(self):
229                 skipped_log = test_data_path('    229                 skipped_log = test_data_path('test_skip_all_tests.log')
230                 with open(skipped_log) as file    230                 with open(skipped_log) as file:
231                         result = kunit_parser.    231                         result = kunit_parser.parse_run_tests(file.readlines())
232                                                   232 
233                 self.assertEqual(kunit_parser.    233                 self.assertEqual(kunit_parser.TestStatus.SKIPPED, result.status)
234                 self.assertEqual(result.counts    234                 self.assertEqual(result.counts, kunit_parser.TestCounts(skipped=5))
235                                                   235 
236         def test_ignores_hyphen(self):            236         def test_ignores_hyphen(self):
237                 hyphen_log = test_data_path('t    237                 hyphen_log = test_data_path('test_strip_hyphen.log')
238                 with open(hyphen_log) as file:    238                 with open(hyphen_log) as file:
239                         result = kunit_parser.    239                         result = kunit_parser.parse_run_tests(file.readlines())
240                                                   240 
241                 # A skipped test does not fail    241                 # A skipped test does not fail the whole suite.
242                 self.assertEqual(kunit_parser.    242                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
243                 self.assertEqual(                 243                 self.assertEqual(
244                         "sysctl_test",            244                         "sysctl_test",
245                         result.subtests[0].nam    245                         result.subtests[0].name)
246                 self.assertEqual(                 246                 self.assertEqual(
247                         "example",                247                         "example",
248                         result.subtests[1].nam    248                         result.subtests[1].name)
249                                                   249 
250         def test_ignores_prefix_printk_time(se    250         def test_ignores_prefix_printk_time(self):
251                 prefix_log = test_data_path('t    251                 prefix_log = test_data_path('test_config_printk_time.log')
252                 with open(prefix_log) as file:    252                 with open(prefix_log) as file:
253                         result = kunit_parser.    253                         result = kunit_parser.parse_run_tests(file.readlines())
254                 self.assertEqual(kunit_parser.    254                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
255                 self.assertEqual('kunit-resour    255                 self.assertEqual('kunit-resource-test', result.subtests[0].name)
256                 self.assertEqual(result.counts    256                 self.assertEqual(result.counts.errors, 0)
257                                                   257 
258         def test_ignores_multiple_prefixes(sel    258         def test_ignores_multiple_prefixes(self):
259                 prefix_log = test_data_path('t    259                 prefix_log = test_data_path('test_multiple_prefixes.log')
260                 with open(prefix_log) as file:    260                 with open(prefix_log) as file:
261                         result = kunit_parser.    261                         result = kunit_parser.parse_run_tests(file.readlines())
262                 self.assertEqual(kunit_parser.    262                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
263                 self.assertEqual('kunit-resour    263                 self.assertEqual('kunit-resource-test', result.subtests[0].name)
264                 self.assertEqual(result.counts    264                 self.assertEqual(result.counts.errors, 0)
265                                                   265 
266         def test_prefix_mixed_kernel_output(se    266         def test_prefix_mixed_kernel_output(self):
267                 mixed_prefix_log = test_data_p    267                 mixed_prefix_log = test_data_path('test_interrupted_tap_output.log')
268                 with open(mixed_prefix_log) as    268                 with open(mixed_prefix_log) as file:
269                         result = kunit_parser.    269                         result = kunit_parser.parse_run_tests(file.readlines())
270                 self.assertEqual(kunit_parser.    270                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
271                 self.assertEqual('kunit-resour    271                 self.assertEqual('kunit-resource-test', result.subtests[0].name)
272                 self.assertEqual(result.counts    272                 self.assertEqual(result.counts.errors, 0)
273                                                   273 
274         def test_prefix_poundsign(self):          274         def test_prefix_poundsign(self):
275                 pound_log = test_data_path('te    275                 pound_log = test_data_path('test_pound_sign.log')
276                 with open(pound_log) as file:     276                 with open(pound_log) as file:
277                         result = kunit_parser.    277                         result = kunit_parser.parse_run_tests(file.readlines())
278                 self.assertEqual(kunit_parser.    278                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
279                 self.assertEqual('kunit-resour    279                 self.assertEqual('kunit-resource-test', result.subtests[0].name)
280                 self.assertEqual(result.counts    280                 self.assertEqual(result.counts.errors, 0)
281                                                   281 
282         def test_kernel_panic_end(self):          282         def test_kernel_panic_end(self):
283                 panic_log = test_data_path('te    283                 panic_log = test_data_path('test_kernel_panic_interrupt.log')
284                 with open(panic_log) as file:     284                 with open(panic_log) as file:
285                         result = kunit_parser.    285                         result = kunit_parser.parse_run_tests(file.readlines())
286                 self.assertEqual(kunit_parser.    286                 self.assertEqual(kunit_parser.TestStatus.TEST_CRASHED, result.status)
287                 self.assertEqual('kunit-resour    287                 self.assertEqual('kunit-resource-test', result.subtests[0].name)
288                 self.assertGreaterEqual(result    288                 self.assertGreaterEqual(result.counts.errors, 1)
289                                                   289 
290         def test_pound_no_prefix(self):           290         def test_pound_no_prefix(self):
291                 pound_log = test_data_path('te    291                 pound_log = test_data_path('test_pound_no_prefix.log')
292                 with open(pound_log) as file:     292                 with open(pound_log) as file:
293                         result = kunit_parser.    293                         result = kunit_parser.parse_run_tests(file.readlines())
294                 self.assertEqual(kunit_parser.    294                 self.assertEqual(kunit_parser.TestStatus.SUCCESS, result.status)
295                 self.assertEqual('kunit-resour    295                 self.assertEqual('kunit-resource-test', result.subtests[0].name)
296                 self.assertEqual(result.counts    296                 self.assertEqual(result.counts.errors, 0)
297                                                   297 
298         def test_summarize_failures(self):        298         def test_summarize_failures(self):
299                 output = """                      299                 output = """
300                 KTAP version 1                    300                 KTAP version 1
301                 1..2                              301                 1..2
302                         # Subtest: all_failed_    302                         # Subtest: all_failed_suite
303                         1..2                      303                         1..2
304                         not ok 1 - test1          304                         not ok 1 - test1
305                         not ok 2 - test2          305                         not ok 2 - test2
306                 not ok 1 - all_failed_suite       306                 not ok 1 - all_failed_suite
307                         # Subtest: some_failed    307                         # Subtest: some_failed_suite
308                         1..2                      308                         1..2
309                         ok 1 - test1              309                         ok 1 - test1
310                         not ok 2 - test2          310                         not ok 2 - test2
311                 not ok 1 - some_failed_suite      311                 not ok 1 - some_failed_suite
312                 """                               312                 """
313                 result = kunit_parser.parse_ru    313                 result = kunit_parser.parse_run_tests(output.splitlines())
314                 self.assertEqual(kunit_parser.    314                 self.assertEqual(kunit_parser.TestStatus.FAILURE, result.status)
315                                                   315 
316                 self.assertEqual(kunit_parser.    316                 self.assertEqual(kunit_parser._summarize_failed_tests(result),
317                         'Failures: all_failed_    317                         'Failures: all_failed_suite, some_failed_suite.test2')
318                                                   318 
319         def test_ktap_format(self):               319         def test_ktap_format(self):
320                 ktap_log = test_data_path('tes    320                 ktap_log = test_data_path('test_parse_ktap_output.log')
321                 with open(ktap_log) as file:      321                 with open(ktap_log) as file:
322                         result = kunit_parser.    322                         result = kunit_parser.parse_run_tests(file.readlines())
323                 self.assertEqual(result.counts    323                 self.assertEqual(result.counts, kunit_parser.TestCounts(passed=3))
324                 self.assertEqual('suite', resu    324                 self.assertEqual('suite', result.subtests[0].name)
325                 self.assertEqual('case_1', res    325                 self.assertEqual('case_1', result.subtests[0].subtests[0].name)
326                 self.assertEqual('case_2', res    326                 self.assertEqual('case_2', result.subtests[0].subtests[1].name)
327                                                   327 
328         def test_parse_subtest_header(self):      328         def test_parse_subtest_header(self):
329                 ktap_log = test_data_path('tes    329                 ktap_log = test_data_path('test_parse_subtest_header.log')
330                 with open(ktap_log) as file:      330                 with open(ktap_log) as file:
331                         kunit_parser.parse_run << 
332                 self.print_mock.assert_any_cal << 
333                                                << 
334         def test_parse_attributes(self):       << 
335                 ktap_log = test_data_path('tes << 
336                 with open(ktap_log) as file:   << 
337                         result = kunit_parser.    331                         result = kunit_parser.parse_run_tests(file.readlines())
338                                                << 
339                 # Test should pass with no err << 
340                 self.assertEqual(result.counts << 
341                 self.assertEqual(kunit_parser. << 
342                                                << 
343                 # Ensure suite header is parse << 
344                 self.print_mock.assert_any_cal    332                 self.print_mock.assert_any_call(StrContains('suite (1 subtest)'))
345                                                   333 
346                 # Ensure attributes in correct << 
347                 self.assertContains('# module: << 
348                 self.assertContains('# test.sp << 
349                                                << 
350         def test_show_test_output_on_failure(s    334         def test_show_test_output_on_failure(self):
351                 output = """                      335                 output = """
352                 KTAP version 1                    336                 KTAP version 1
353                 1..1                              337                 1..1
354                   Test output.                    338                   Test output.
355                     Indented more.                339                     Indented more.
356                 not ok 1 test1                    340                 not ok 1 test1
357                 """                               341                 """
358                 result = kunit_parser.parse_ru    342                 result = kunit_parser.parse_run_tests(output.splitlines())
359                 self.assertEqual(kunit_parser.    343                 self.assertEqual(kunit_parser.TestStatus.FAILURE, result.status)
360                                                   344 
361                 self.print_mock.assert_any_cal    345                 self.print_mock.assert_any_call(StrContains('Test output.'))
362                 self.print_mock.assert_any_cal    346                 self.print_mock.assert_any_call(StrContains('  Indented more.'))
363                 self.noPrintCallContains('not     347                 self.noPrintCallContains('not ok 1 test1')
364                                                   348 
365 def line_stream_from_strs(strs: Iterable[str])    349 def line_stream_from_strs(strs: Iterable[str]) -> kunit_parser.LineStream:
366         return kunit_parser.LineStream(enumera    350         return kunit_parser.LineStream(enumerate(strs, start=1))
367                                                   351 
368 class LineStreamTest(unittest.TestCase):          352 class LineStreamTest(unittest.TestCase):
369                                                   353 
370         def test_basic(self):                     354         def test_basic(self):
371                 stream = line_stream_from_strs    355                 stream = line_stream_from_strs(['hello', 'world'])
372                                                   356 
373                 self.assertTrue(stream, msg='S    357                 self.assertTrue(stream, msg='Should be more input')
374                 self.assertEqual(stream.line_n    358                 self.assertEqual(stream.line_number(), 1)
375                 self.assertEqual(stream.peek()    359                 self.assertEqual(stream.peek(), 'hello')
376                 self.assertEqual(stream.pop(),    360                 self.assertEqual(stream.pop(), 'hello')
377                                                   361 
378                 self.assertTrue(stream, msg='S    362                 self.assertTrue(stream, msg='Should be more input')
379                 self.assertEqual(stream.line_n    363                 self.assertEqual(stream.line_number(), 2)
380                 self.assertEqual(stream.peek()    364                 self.assertEqual(stream.peek(), 'world')
381                 self.assertEqual(stream.pop(),    365                 self.assertEqual(stream.pop(), 'world')
382                                                   366 
383                 self.assertFalse(stream, msg='    367                 self.assertFalse(stream, msg='Should be no more input')
384                 with self.assertRaisesRegex(Va    368                 with self.assertRaisesRegex(ValueError, 'LineStream: going past EOF'):
385                         stream.pop()              369                         stream.pop()
386                                                   370 
387         def test_is_lazy(self):                   371         def test_is_lazy(self):
388                 called_times = 0                  372                 called_times = 0
389                 def generator():                  373                 def generator():
390                         nonlocal called_times     374                         nonlocal called_times
391                         for _ in range(1,5):      375                         for _ in range(1,5):
392                                 called_times +    376                                 called_times += 1
393                                 yield called_t    377                                 yield called_times, str(called_times)
394                                                   378 
395                 stream = kunit_parser.LineStre    379                 stream = kunit_parser.LineStream(generator())
396                 self.assertEqual(called_times,    380                 self.assertEqual(called_times, 0)
397                                                   381 
398                 self.assertEqual(stream.pop(),    382                 self.assertEqual(stream.pop(), '1')
399                 self.assertEqual(called_times,    383                 self.assertEqual(called_times, 1)
400                                                   384 
401                 self.assertEqual(stream.pop(),    385                 self.assertEqual(stream.pop(), '2')
402                 self.assertEqual(called_times,    386                 self.assertEqual(called_times, 2)
403                                                   387 
404 class LinuxSourceTreeTest(unittest.TestCase):     388 class LinuxSourceTreeTest(unittest.TestCase):
405                                                   389 
406         def setUp(self):                          390         def setUp(self):
407                 mock.patch.object(signal, 'sig    391                 mock.patch.object(signal, 'signal').start()
408                 self.addCleanup(mock.patch.sto    392                 self.addCleanup(mock.patch.stopall)
409                                                   393 
410         def test_invalid_kunitconfig(self):       394         def test_invalid_kunitconfig(self):
411                 with self.assertRaisesRegex(ku    395                 with self.assertRaisesRegex(kunit_kernel.ConfigError, 'nonexistent.* does not exist'):
412                         kunit_kernel.LinuxSour    396                         kunit_kernel.LinuxSourceTree('', kunitconfig_paths=['/nonexistent_file'])
413                                                   397 
414         def test_valid_kunitconfig(self):         398         def test_valid_kunitconfig(self):
415                 with tempfile.NamedTemporaryFi    399                 with tempfile.NamedTemporaryFile('wt') as kunitconfig:
416                         kunit_kernel.LinuxSour    400                         kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[kunitconfig.name])
417                                                   401 
418         def test_dir_kunitconfig(self):           402         def test_dir_kunitconfig(self):
419                 with tempfile.TemporaryDirecto    403                 with tempfile.TemporaryDirectory('') as dir:
420                         with open(os.path.join    404                         with open(os.path.join(dir, '.kunitconfig'), 'w'):
421                                 pass              405                                 pass
422                         kunit_kernel.LinuxSour    406                         kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[dir])
423                                                   407 
424         def test_multiple_kunitconfig(self):      408         def test_multiple_kunitconfig(self):
425                 want_kconfig = kunit_config.Kc    409                 want_kconfig = kunit_config.Kconfig()
426                 want_kconfig.add_entry('KUNIT'    410                 want_kconfig.add_entry('KUNIT', 'y')
427                 want_kconfig.add_entry('KUNIT_    411                 want_kconfig.add_entry('KUNIT_TEST', 'm')
428                                                   412 
429                 with tempfile.TemporaryDirecto    413                 with tempfile.TemporaryDirectory('') as dir:
430                         other = os.path.join(d    414                         other = os.path.join(dir, 'otherkunitconfig')
431                         with open(os.path.join    415                         with open(os.path.join(dir, '.kunitconfig'), 'w') as f:
432                                 f.write('CONFI    416                                 f.write('CONFIG_KUNIT=y')
433                         with open(other, 'w')     417                         with open(other, 'w') as f:
434                                 f.write('CONFI    418                                 f.write('CONFIG_KUNIT_TEST=m')
435                                 pass              419                                 pass
436                                                   420 
437                         tree = kunit_kernel.Li    421                         tree = kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[dir, other])
438                         self.assertTrue(want_k    422                         self.assertTrue(want_kconfig.is_subset_of(tree._kconfig), msg=tree._kconfig)
439                                                   423 
440                                                   424 
441         def test_multiple_kunitconfig_invalid(    425         def test_multiple_kunitconfig_invalid(self):
442                 with tempfile.TemporaryDirecto    426                 with tempfile.TemporaryDirectory('') as dir:
443                         other = os.path.join(d    427                         other = os.path.join(dir, 'otherkunitconfig')
444                         with open(os.path.join    428                         with open(os.path.join(dir, '.kunitconfig'), 'w') as f:
445                                 f.write('CONFI    429                                 f.write('CONFIG_KUNIT=y')
446                         with open(other, 'w')     430                         with open(other, 'w') as f:
447                                 f.write('CONFI    431                                 f.write('CONFIG_KUNIT=m')
448                                                   432 
449                         with self.assertRaises    433                         with self.assertRaisesRegex(kunit_kernel.ConfigError, '(?s)Multiple values.*CONFIG_KUNIT'):
450                                 kunit_kernel.L    434                                 kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[dir, other])
451                                                   435 
452                                                   436 
453         def test_kconfig_add(self):               437         def test_kconfig_add(self):
454                 want_kconfig = kunit_config.Kc    438                 want_kconfig = kunit_config.Kconfig()
455                 want_kconfig.add_entry('NOT_RE    439                 want_kconfig.add_entry('NOT_REAL', 'y')
456                                                   440 
457                 tree = kunit_kernel.LinuxSourc    441                 tree = kunit_kernel.LinuxSourceTree('', kconfig_add=['CONFIG_NOT_REAL=y'])
458                 self.assertTrue(want_kconfig.i    442                 self.assertTrue(want_kconfig.is_subset_of(tree._kconfig), msg=tree._kconfig)
459                                                   443 
460         def test_invalid_arch(self):              444         def test_invalid_arch(self):
461                 with self.assertRaisesRegex(ku    445                 with self.assertRaisesRegex(kunit_kernel.ConfigError, 'not a valid arch, options are.*x86_64'):
462                         kunit_kernel.LinuxSour    446                         kunit_kernel.LinuxSourceTree('', arch='invalid')
463                                                   447 
464         def test_run_kernel_hits_exception(sel    448         def test_run_kernel_hits_exception(self):
465                 def fake_start(unused_args, un    449                 def fake_start(unused_args, unused_build_dir):
466                         return subprocess.Pope    450                         return subprocess.Popen(['echo "hi\nbye"'], shell=True, text=True, stdout=subprocess.PIPE)
467                                                   451 
468                 with tempfile.TemporaryDirecto    452                 with tempfile.TemporaryDirectory('') as build_dir:
469                         tree = kunit_kernel.Li    453                         tree = kunit_kernel.LinuxSourceTree(build_dir)
470                         mock.patch.object(tree    454                         mock.patch.object(tree._ops, 'start', side_effect=fake_start).start()
471                                                   455 
472                         with self.assertRaises    456                         with self.assertRaises(ValueError):
473                                 for line in tr    457                                 for line in tree.run_kernel(build_dir=build_dir):
474                                         self.a    458                                         self.assertEqual(line, 'hi\n')
475                                         raise     459                                         raise ValueError('uh oh, did not read all output')
476                                                   460 
477                         with open(kunit_kernel    461                         with open(kunit_kernel.get_outfile_path(build_dir), 'rt') as outfile:
478                                 self.assertEqu    462                                 self.assertEqual(outfile.read(), 'hi\nbye\n', msg='Missing some output')
479                                                   463 
480         def test_build_reconfig_no_config(self    464         def test_build_reconfig_no_config(self):
481                 with tempfile.TemporaryDirecto    465                 with tempfile.TemporaryDirectory('') as build_dir:
482                         with open(kunit_kernel    466                         with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
483                                 f.write('CONFI    467                                 f.write('CONFIG_KUNIT=y')
484                                                   468 
485                         tree = kunit_kernel.Li    469                         tree = kunit_kernel.LinuxSourceTree(build_dir)
486                         # Stub out the source     470                         # Stub out the source tree operations, so we don't have
487                         # the defaults for any    471                         # the defaults for any given architecture get in the
488                         # way.                    472                         # way.
489                         tree._ops = kunit_kern    473                         tree._ops = kunit_kernel.LinuxSourceTreeOperations('none', None)
490                         mock_build_config = mo    474                         mock_build_config = mock.patch.object(tree, 'build_config').start()
491                                                   475 
492                         # Should generate the     476                         # Should generate the .config
493                         self.assertTrue(tree.b    477                         self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
494                         mock_build_config.asse    478                         mock_build_config.assert_called_once_with(build_dir, [])
495                                                   479 
496         def test_build_reconfig_existing_confi    480         def test_build_reconfig_existing_config(self):
497                 with tempfile.TemporaryDirecto    481                 with tempfile.TemporaryDirectory('') as build_dir:
498                         # Existing .config is     482                         # Existing .config is a superset, should not touch it
499                         with open(kunit_kernel    483                         with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
500                                 f.write('CONFI    484                                 f.write('CONFIG_KUNIT=y')
501                         with open(kunit_kernel    485                         with open(kunit_kernel.get_old_kunitconfig_path(build_dir), 'w') as f:
502                                 f.write('CONFI    486                                 f.write('CONFIG_KUNIT=y')
503                         with open(kunit_kernel    487                         with open(kunit_kernel.get_kconfig_path(build_dir), 'w') as f:
504                                 f.write('CONFI    488                                 f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')
505                                                   489 
506                         tree = kunit_kernel.Li    490                         tree = kunit_kernel.LinuxSourceTree(build_dir)
507                         # Stub out the source     491                         # Stub out the source tree operations, so we don't have
508                         # the defaults for any    492                         # the defaults for any given architecture get in the
509                         # way.                    493                         # way.
510                         tree._ops = kunit_kern    494                         tree._ops = kunit_kernel.LinuxSourceTreeOperations('none', None)
511                         mock_build_config = mo    495                         mock_build_config = mock.patch.object(tree, 'build_config').start()
512                                                   496 
513                         self.assertTrue(tree.b    497                         self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
514                         self.assertEqual(mock_    498                         self.assertEqual(mock_build_config.call_count, 0)
515                                                   499 
516         def test_build_reconfig_remove_option(    500         def test_build_reconfig_remove_option(self):
517                 with tempfile.TemporaryDirecto    501                 with tempfile.TemporaryDirectory('') as build_dir:
518                         # We removed CONFIG_KU    502                         # We removed CONFIG_KUNIT_TEST=y from our .kunitconfig...
519                         with open(kunit_kernel    503                         with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
520                                 f.write('CONFI    504                                 f.write('CONFIG_KUNIT=y')
521                         with open(kunit_kernel    505                         with open(kunit_kernel.get_old_kunitconfig_path(build_dir), 'w') as f:
522                                 f.write('CONFI    506                                 f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')
523                         with open(kunit_kernel    507                         with open(kunit_kernel.get_kconfig_path(build_dir), 'w') as f:
524                                 f.write('CONFI    508                                 f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')
525                                                   509 
526                         tree = kunit_kernel.Li    510                         tree = kunit_kernel.LinuxSourceTree(build_dir)
527                         # Stub out the source     511                         # Stub out the source tree operations, so we don't have
528                         # the defaults for any    512                         # the defaults for any given architecture get in the
529                         # way.                    513                         # way.
530                         tree._ops = kunit_kern    514                         tree._ops = kunit_kernel.LinuxSourceTreeOperations('none', None)
531                         mock_build_config = mo    515                         mock_build_config = mock.patch.object(tree, 'build_config').start()
532                                                   516 
533                         # ... so we should tri    517                         # ... so we should trigger a call to build_config()
534                         self.assertTrue(tree.b    518                         self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
535                         mock_build_config.asse    519                         mock_build_config.assert_called_once_with(build_dir, [])
536                                                   520 
537         # TODO: add more test cases.              521         # TODO: add more test cases.
538                                                   522 
539                                                   523 
540 class KUnitJsonTest(unittest.TestCase):           524 class KUnitJsonTest(unittest.TestCase):
541         def setUp(self):                          525         def setUp(self):
542                 self.print_mock = mock.patch('    526                 self.print_mock = mock.patch('kunit_printer.Printer.print').start()
543                 self.addCleanup(mock.patch.sto    527                 self.addCleanup(mock.patch.stopall)
544                                                   528 
545         def _json_for(self, log_file):            529         def _json_for(self, log_file):
546                 with open(test_data_path(log_f    530                 with open(test_data_path(log_file)) as file:
547                         test_result = kunit_pa    531                         test_result = kunit_parser.parse_run_tests(file)
548                         json_obj = kunit_json.    532                         json_obj = kunit_json.get_json_result(
549                                 test=test_resu    533                                 test=test_result,
550                                 metadata=kunit    534                                 metadata=kunit_json.Metadata())
551                 return json.loads(json_obj)       535                 return json.loads(json_obj)
552                                                   536 
553         def test_failed_test_json(self):          537         def test_failed_test_json(self):
554                 result = self._json_for('test_    538                 result = self._json_for('test_is_test_passed-failure.log')
555                 self.assertEqual(                 539                 self.assertEqual(
556                         {'name': 'example_simp    540                         {'name': 'example_simple_test', 'status': 'FAIL'},
557                         result["sub_groups"][1    541                         result["sub_groups"][1]["test_cases"][0])
558                                                   542 
559         def test_crashed_test_json(self):         543         def test_crashed_test_json(self):
560                 result = self._json_for('test_    544                 result = self._json_for('test_kernel_panic_interrupt.log')
561                 self.assertEqual(                 545                 self.assertEqual(
562                         {'name': '', 'status':    546                         {'name': '', 'status': 'ERROR'},
563                         result["sub_groups"][2    547                         result["sub_groups"][2]["test_cases"][1])
564                                                   548 
565         def test_skipped_test_json(self):         549         def test_skipped_test_json(self):
566                 result = self._json_for('test_    550                 result = self._json_for('test_skip_tests.log')
567                 self.assertEqual(                 551                 self.assertEqual(
568                         {'name': 'example_skip    552                         {'name': 'example_skip_test', 'status': 'SKIP'},
569                         result["sub_groups"][1    553                         result["sub_groups"][1]["test_cases"][1])
570                                                   554 
571         def test_no_tests_json(self):             555         def test_no_tests_json(self):
572                 result = self._json_for('test_    556                 result = self._json_for('test_is_test_passed-no_tests_run_with_header.log')
573                 self.assertEqual(0, len(result    557                 self.assertEqual(0, len(result['sub_groups']))
574                                                   558 
575         def test_nested_json(self):               559         def test_nested_json(self):
576                 result = self._json_for('test_    560                 result = self._json_for('test_is_test_passed-all_passed_nested.log')
577                 self.assertEqual(                 561                 self.assertEqual(
578                         {'name': 'example_simp    562                         {'name': 'example_simple_test', 'status': 'PASS'},
579                         result["sub_groups"][0    563                         result["sub_groups"][0]["sub_groups"][0]["test_cases"][0])
580                                                   564 
581 class StrContains(str):                           565 class StrContains(str):
582         def __eq__(self, other):                  566         def __eq__(self, other):
583                 return self in other              567                 return self in other
584                                                   568 
585 class KUnitMainTest(unittest.TestCase):           569 class KUnitMainTest(unittest.TestCase):
586         def setUp(self):                          570         def setUp(self):
587                 path = test_data_path('test_is    571                 path = test_data_path('test_is_test_passed-all_passed.log')
588                 with open(path) as file:          572                 with open(path) as file:
589                         all_passed_log = file.    573                         all_passed_log = file.readlines()
590                                                   574 
591                 self.print_mock = mock.patch('    575                 self.print_mock = mock.patch('kunit_printer.Printer.print').start()
592                 self.addCleanup(mock.patch.sto    576                 self.addCleanup(mock.patch.stopall)
593                                                   577 
594                 self.mock_linux_init = mock.pa    578                 self.mock_linux_init = mock.patch.object(kunit_kernel, 'LinuxSourceTree').start()
595                 self.linux_source_mock = self.    579                 self.linux_source_mock = self.mock_linux_init.return_value
596                 self.linux_source_mock.build_r    580                 self.linux_source_mock.build_reconfig.return_value = True
597                 self.linux_source_mock.build_k    581                 self.linux_source_mock.build_kernel.return_value = True
598                 self.linux_source_mock.run_ker    582                 self.linux_source_mock.run_kernel.return_value = all_passed_log
599                                                   583 
600         def test_config_passes_args_pass(self)    584         def test_config_passes_args_pass(self):
601                 kunit.main(['config', '--build    585                 kunit.main(['config', '--build_dir=.kunit'])
602                 self.assertEqual(self.linux_so    586                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
603                 self.assertEqual(self.linux_so    587                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 0)
604                                                   588 
605         def test_build_passes_args_pass(self):    589         def test_build_passes_args_pass(self):
606                 kunit.main(['build'])             590                 kunit.main(['build'])
607                 self.assertEqual(self.linux_so    591                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
608                 self.linux_source_mock.build_k    592                 self.linux_source_mock.build_kernel.assert_called_once_with(kunit.get_default_jobs(), '.kunit', None)
609                 self.assertEqual(self.linux_so    593                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 0)
610                                                   594 
611         def test_exec_passes_args_pass(self):     595         def test_exec_passes_args_pass(self):
612                 kunit.main(['exec'])              596                 kunit.main(['exec'])
613                 self.assertEqual(self.linux_so    597                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 0)
614                 self.assertEqual(self.linux_so    598                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
615                 self.linux_source_mock.run_ker    599                 self.linux_source_mock.run_kernel.assert_called_once_with(
616                         args=None, build_dir=' !! 600                         args=None, build_dir='.kunit', filter_glob='', timeout=300)
617                 self.print_mock.assert_any_cal    601                 self.print_mock.assert_any_call(StrContains('Testing complete.'))
618                                                   602 
619         def test_run_passes_args_pass(self):      603         def test_run_passes_args_pass(self):
620                 kunit.main(['run'])               604                 kunit.main(['run'])
621                 self.assertEqual(self.linux_so    605                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
622                 self.assertEqual(self.linux_so    606                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
623                 self.linux_source_mock.run_ker    607                 self.linux_source_mock.run_kernel.assert_called_once_with(
624                         args=None, build_dir=' !! 608                         args=None, build_dir='.kunit', filter_glob='', timeout=300)
625                 self.print_mock.assert_any_cal    609                 self.print_mock.assert_any_call(StrContains('Testing complete.'))
626                                                   610 
627         def test_exec_passes_args_fail(self):     611         def test_exec_passes_args_fail(self):
628                 self.linux_source_mock.run_ker    612                 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
629                 with self.assertRaises(SystemE    613                 with self.assertRaises(SystemExit) as e:
630                         kunit.main(['exec'])      614                         kunit.main(['exec'])
631                 self.assertEqual(e.exception.c    615                 self.assertEqual(e.exception.code, 1)
632                                                   616 
633         def test_run_passes_args_fail(self):      617         def test_run_passes_args_fail(self):
634                 self.linux_source_mock.run_ker    618                 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
635                 with self.assertRaises(SystemE    619                 with self.assertRaises(SystemExit) as e:
636                         kunit.main(['run'])       620                         kunit.main(['run'])
637                 self.assertEqual(e.exception.c    621                 self.assertEqual(e.exception.code, 1)
638                 self.assertEqual(self.linux_so    622                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
639                 self.assertEqual(self.linux_so    623                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
640                 self.print_mock.assert_any_cal    624                 self.print_mock.assert_any_call(StrContains('Could not find any KTAP output.'))
641                                                   625 
642         def test_exec_no_tests(self):             626         def test_exec_no_tests(self):
643                 self.linux_source_mock.run_ker    627                 self.linux_source_mock.run_kernel = mock.Mock(return_value=['TAP version 14', '1..0'])
644                 with self.assertRaises(SystemE    628                 with self.assertRaises(SystemExit) as e:
645                         kunit.main(['run'])       629                         kunit.main(['run'])
646                 self.assertEqual(e.exception.c    630                 self.assertEqual(e.exception.code, 1)
647                 self.linux_source_mock.run_ker    631                 self.linux_source_mock.run_kernel.assert_called_once_with(
648                         args=None, build_dir=' !! 632                         args=None, build_dir='.kunit', filter_glob='', timeout=300)
649                 self.print_mock.assert_any_cal    633                 self.print_mock.assert_any_call(StrContains(' 0 tests run!'))
650                                                   634 
651         def test_exec_raw_output(self):           635         def test_exec_raw_output(self):
652                 self.linux_source_mock.run_ker    636                 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
653                 kunit.main(['exec', '--raw_out    637                 kunit.main(['exec', '--raw_output'])
654                 self.assertEqual(self.linux_so    638                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
655                 for call in self.print_mock.ca    639                 for call in self.print_mock.call_args_list:
656                         self.assertNotEqual(ca    640                         self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
657                         self.assertNotEqual(ca    641                         self.assertNotEqual(call, mock.call(StrContains(' 0 tests run!')))
658                                                   642 
659         def test_run_raw_output(self):            643         def test_run_raw_output(self):
660                 self.linux_source_mock.run_ker    644                 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
661                 kunit.main(['run', '--raw_outp    645                 kunit.main(['run', '--raw_output'])
662                 self.assertEqual(self.linux_so    646                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
663                 self.assertEqual(self.linux_so    647                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
664                 for call in self.print_mock.ca    648                 for call in self.print_mock.call_args_list:
665                         self.assertNotEqual(ca    649                         self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
666                         self.assertNotEqual(ca    650                         self.assertNotEqual(call, mock.call(StrContains(' 0 tests run!')))
667                                                   651 
668         def test_run_raw_output_kunit(self):      652         def test_run_raw_output_kunit(self):
669                 self.linux_source_mock.run_ker    653                 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
670                 kunit.main(['run', '--raw_outp    654                 kunit.main(['run', '--raw_output=kunit'])
671                 self.assertEqual(self.linux_so    655                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
672                 self.assertEqual(self.linux_so    656                 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
673                 for call in self.print_mock.ca    657                 for call in self.print_mock.call_args_list:
674                         self.assertNotEqual(ca    658                         self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
675                         self.assertNotEqual(ca    659                         self.assertNotEqual(call, mock.call(StrContains(' 0 tests run')))
676                                                   660 
677         def test_run_raw_output_invalid(self):    661         def test_run_raw_output_invalid(self):
678                 self.linux_source_mock.run_ker    662                 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
679                 with self.assertRaises(SystemE    663                 with self.assertRaises(SystemExit) as e:
680                         kunit.main(['run', '--    664                         kunit.main(['run', '--raw_output=invalid'])
681                 self.assertNotEqual(e.exceptio    665                 self.assertNotEqual(e.exception.code, 0)
682                                                   666 
683         def test_run_raw_output_does_not_take_    667         def test_run_raw_output_does_not_take_positional_args(self):
684                 # --raw_output is a string fla    668                 # --raw_output is a string flag, but we don't want it to consume
685                 # any positional arguments, on    669                 # any positional arguments, only ones after an '='
686                 self.linux_source_mock.run_ker    670                 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
687                 kunit.main(['run', '--raw_outp    671                 kunit.main(['run', '--raw_output', 'filter_glob'])
688                 self.linux_source_mock.run_ker    672                 self.linux_source_mock.run_kernel.assert_called_once_with(
689                         args=None, build_dir=' !! 673                         args=None, build_dir='.kunit', filter_glob='filter_glob', timeout=300)
690                                                   674 
691         def test_exec_timeout(self):              675         def test_exec_timeout(self):
692                 timeout = 3453                    676                 timeout = 3453
693                 kunit.main(['exec', '--timeout    677                 kunit.main(['exec', '--timeout', str(timeout)])
694                 self.linux_source_mock.run_ker    678                 self.linux_source_mock.run_kernel.assert_called_once_with(
695                         args=None, build_dir=' !! 679                         args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
696                 self.print_mock.assert_any_cal    680                 self.print_mock.assert_any_call(StrContains('Testing complete.'))
697                                                   681 
698         def test_run_timeout(self):               682         def test_run_timeout(self):
699                 timeout = 3453                    683                 timeout = 3453
700                 kunit.main(['run', '--timeout'    684                 kunit.main(['run', '--timeout', str(timeout)])
701                 self.assertEqual(self.linux_so    685                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
702                 self.linux_source_mock.run_ker    686                 self.linux_source_mock.run_kernel.assert_called_once_with(
703                         args=None, build_dir=' !! 687                         args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
704                 self.print_mock.assert_any_cal    688                 self.print_mock.assert_any_call(StrContains('Testing complete.'))
705                                                   689 
706         def test_run_builddir(self):              690         def test_run_builddir(self):
707                 build_dir = '.kunit'              691                 build_dir = '.kunit'
708                 kunit.main(['run', '--build_di    692                 kunit.main(['run', '--build_dir=.kunit'])
709                 self.assertEqual(self.linux_so    693                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
710                 self.linux_source_mock.run_ker    694                 self.linux_source_mock.run_kernel.assert_called_once_with(
711                         args=None, build_dir=b !! 695                         args=None, build_dir=build_dir, filter_glob='', timeout=300)
712                 self.print_mock.assert_any_cal    696                 self.print_mock.assert_any_call(StrContains('Testing complete.'))
713                                                   697 
714         def test_config_builddir(self):           698         def test_config_builddir(self):
715                 build_dir = '.kunit'              699                 build_dir = '.kunit'
716                 kunit.main(['config', '--build    700                 kunit.main(['config', '--build_dir', build_dir])
717                 self.assertEqual(self.linux_so    701                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
718                                                   702 
719         def test_build_builddir(self):            703         def test_build_builddir(self):
720                 build_dir = '.kunit'              704                 build_dir = '.kunit'
721                 jobs = kunit.get_default_jobs(    705                 jobs = kunit.get_default_jobs()
722                 kunit.main(['build', '--build_    706                 kunit.main(['build', '--build_dir', build_dir])
723                 self.linux_source_mock.build_k    707                 self.linux_source_mock.build_kernel.assert_called_once_with(jobs, build_dir, None)
724                                                   708 
725         def test_exec_builddir(self):             709         def test_exec_builddir(self):
726                 build_dir = '.kunit'              710                 build_dir = '.kunit'
727                 kunit.main(['exec', '--build_d    711                 kunit.main(['exec', '--build_dir', build_dir])
728                 self.linux_source_mock.run_ker    712                 self.linux_source_mock.run_kernel.assert_called_once_with(
729                         args=None, build_dir=b !! 713                         args=None, build_dir=build_dir, filter_glob='', timeout=300)
730                 self.print_mock.assert_any_cal    714                 self.print_mock.assert_any_call(StrContains('Testing complete.'))
731                                                   715 
732         def test_run_kunitconfig(self):           716         def test_run_kunitconfig(self):
733                 kunit.main(['run', '--kunitcon    717                 kunit.main(['run', '--kunitconfig=mykunitconfig'])
734                 # Just verify that we parsed a    718                 # Just verify that we parsed and initialized it correctly here.
735                 self.mock_linux_init.assert_ca    719                 self.mock_linux_init.assert_called_once_with('.kunit',
736                                                   720                                                 kunitconfig_paths=['mykunitconfig'],
737                                                   721                                                 kconfig_add=None,
738                                                   722                                                 arch='um',
739                                                   723                                                 cross_compile=None,
740                                                   724                                                 qemu_config_path=None,
741                                                   725                                                 extra_qemu_args=[])
742                                                   726 
743         def test_config_kunitconfig(self):        727         def test_config_kunitconfig(self):
744                 kunit.main(['config', '--kunit    728                 kunit.main(['config', '--kunitconfig=mykunitconfig'])
745                 # Just verify that we parsed a    729                 # Just verify that we parsed and initialized it correctly here.
746                 self.mock_linux_init.assert_ca    730                 self.mock_linux_init.assert_called_once_with('.kunit',
747                                                   731                                                 kunitconfig_paths=['mykunitconfig'],
748                                                   732                                                 kconfig_add=None,
749                                                   733                                                 arch='um',
750                                                   734                                                 cross_compile=None,
751                                                   735                                                 qemu_config_path=None,
752                                                   736                                                 extra_qemu_args=[])
753                                                   737 
754         def test_config_alltests(self):           738         def test_config_alltests(self):
755                 kunit.main(['config', '--kunit    739                 kunit.main(['config', '--kunitconfig=mykunitconfig', '--alltests'])
756                 # Just verify that we parsed a    740                 # Just verify that we parsed and initialized it correctly here.
757                 self.mock_linux_init.assert_ca    741                 self.mock_linux_init.assert_called_once_with('.kunit',
758                                                   742                                                 kunitconfig_paths=[kunit_kernel.ALL_TESTS_CONFIG_PATH, 'mykunitconfig'],
759                                                   743                                                 kconfig_add=None,
760                                                   744                                                 arch='um',
761                                                   745                                                 cross_compile=None,
762                                                   746                                                 qemu_config_path=None,
763                                                   747                                                 extra_qemu_args=[])
764                                                   748 
765                                                   749 
766         @mock.patch.object(kunit_kernel, 'Linu    750         @mock.patch.object(kunit_kernel, 'LinuxSourceTree')
767         def test_run_multiple_kunitconfig(self    751         def test_run_multiple_kunitconfig(self, mock_linux_init):
768                 mock_linux_init.return_value =    752                 mock_linux_init.return_value = self.linux_source_mock
769                 kunit.main(['run', '--kunitcon    753                 kunit.main(['run', '--kunitconfig=mykunitconfig', '--kunitconfig=other'])
770                 # Just verify that we parsed a    754                 # Just verify that we parsed and initialized it correctly here.
771                 mock_linux_init.assert_called_    755                 mock_linux_init.assert_called_once_with('.kunit',
772                                                   756                                                         kunitconfig_paths=['mykunitconfig', 'other'],
773                                                   757                                                         kconfig_add=None,
774                                                   758                                                         arch='um',
775                                                   759                                                         cross_compile=None,
776                                                   760                                                         qemu_config_path=None,
777                                                   761                                                         extra_qemu_args=[])
778                                                   762 
779         def test_run_kconfig_add(self):           763         def test_run_kconfig_add(self):
780                 kunit.main(['run', '--kconfig_    764                 kunit.main(['run', '--kconfig_add=CONFIG_KASAN=y', '--kconfig_add=CONFIG_KCSAN=y'])
781                 # Just verify that we parsed a    765                 # Just verify that we parsed and initialized it correctly here.
782                 self.mock_linux_init.assert_ca    766                 self.mock_linux_init.assert_called_once_with('.kunit',
783                                                   767                                                 kunitconfig_paths=[],
784                                                   768                                                 kconfig_add=['CONFIG_KASAN=y', 'CONFIG_KCSAN=y'],
785                                                   769                                                 arch='um',
786                                                   770                                                 cross_compile=None,
787                                                   771                                                 qemu_config_path=None,
788                                                   772                                                 extra_qemu_args=[])
789                                                   773 
790         def test_run_qemu_args(self):             774         def test_run_qemu_args(self):
791                 kunit.main(['run', '--arch=x86    775                 kunit.main(['run', '--arch=x86_64', '--qemu_args', '-m 2048'])
792                 # Just verify that we parsed a    776                 # Just verify that we parsed and initialized it correctly here.
793                 self.mock_linux_init.assert_ca    777                 self.mock_linux_init.assert_called_once_with('.kunit',
794                                                   778                                                 kunitconfig_paths=[],
795                                                   779                                                 kconfig_add=None,
796                                                   780                                                 arch='x86_64',
797                                                   781                                                 cross_compile=None,
798                                                   782                                                 qemu_config_path=None,
799                                                   783                                                 extra_qemu_args=['-m', '2048'])
800                                                   784 
801         def test_run_kernel_args(self):           785         def test_run_kernel_args(self):
802                 kunit.main(['run', '--kernel_a    786                 kunit.main(['run', '--kernel_args=a=1', '--kernel_args=b=2'])
803                 self.assertEqual(self.linux_so    787                 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
804                 self.linux_source_mock.run_ker    788                 self.linux_source_mock.run_kernel.assert_called_once_with(
805                       args=['a=1','b=2'], buil !! 789                       args=['a=1','b=2'], build_dir='.kunit', filter_glob='', timeout=300)
806                 self.print_mock.assert_any_cal    790                 self.print_mock.assert_any_call(StrContains('Testing complete.'))
807                                                   791 
808         def test_list_tests(self):                792         def test_list_tests(self):
809                 want = ['suite.test1', 'suite.    793                 want = ['suite.test1', 'suite.test2', 'suite2.test1']
810                 self.linux_source_mock.run_ker    794                 self.linux_source_mock.run_kernel.return_value = ['TAP version 14', 'init: random output'] + want
811                                                   795 
812                 got = kunit._list_tests(self.l    796                 got = kunit._list_tests(self.linux_source_mock,
813                                      kunit.Kun !! 797                                      kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', None, 'suite'))
                                                   >> 798 
814                 self.assertEqual(got, want)       799                 self.assertEqual(got, want)
815                 # Should respect the user's fi    800                 # Should respect the user's filter glob when listing tests.
816                 self.linux_source_mock.run_ker    801                 self.linux_source_mock.run_kernel.assert_called_once_with(
817                         args=['kunit.action=li !! 802                         args=['kunit.action=list'], build_dir='.kunit', filter_glob='suite*', timeout=300)
                                                   >> 803 
818                                                   804 
819         @mock.patch.object(kunit, '_list_tests    805         @mock.patch.object(kunit, '_list_tests')
820         def test_run_isolated_by_suite(self, m    806         def test_run_isolated_by_suite(self, mock_tests):
821                 mock_tests.return_value = ['su    807                 mock_tests.return_value = ['suite.test1', 'suite.test2', 'suite2.test1']
822                 kunit.main(['exec', '--run_iso    808                 kunit.main(['exec', '--run_isolated=suite', 'suite*.test*'])
823                                                   809 
824                 # Should respect the user's fi    810                 # Should respect the user's filter glob when listing tests.
825                 mock_tests.assert_called_once_    811                 mock_tests.assert_called_once_with(mock.ANY,
826                                      kunit.Kun !! 812                                      kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*.test*', None, 'suite'))
827                 self.linux_source_mock.run_ker    813                 self.linux_source_mock.run_kernel.assert_has_calls([
828                         mock.call(args=None, b !! 814                         mock.call(args=None, build_dir='.kunit', filter_glob='suite.test*', timeout=300),
829                         mock.call(args=None, b !! 815                         mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test*', timeout=300),
830                 ])                                816                 ])
831                                                   817 
832         @mock.patch.object(kunit, '_list_tests    818         @mock.patch.object(kunit, '_list_tests')
833         def test_run_isolated_by_test(self, mo    819         def test_run_isolated_by_test(self, mock_tests):
834                 mock_tests.return_value = ['su    820                 mock_tests.return_value = ['suite.test1', 'suite.test2', 'suite2.test1']
835                 kunit.main(['exec', '--run_iso    821                 kunit.main(['exec', '--run_isolated=test', 'suite*'])
836                                                   822 
837                 # Should respect the user's fi    823                 # Should respect the user's filter glob when listing tests.
838                 mock_tests.assert_called_once_    824                 mock_tests.assert_called_once_with(mock.ANY,
839                                      kunit.Kun !! 825                                      kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', None, 'test'))
840                 self.linux_source_mock.run_ker    826                 self.linux_source_mock.run_kernel.assert_has_calls([
841                         mock.call(args=None, b !! 827                         mock.call(args=None, build_dir='.kunit', filter_glob='suite.test1', timeout=300),
842                         mock.call(args=None, b !! 828                         mock.call(args=None, build_dir='.kunit', filter_glob='suite.test2', timeout=300),
843                         mock.call(args=None, b !! 829                         mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test1', timeout=300),
844                 ])                                830                 ])
                                                   >> 831 
845                                                   832 
846 if __name__ == '__main__':                        833 if __name__ == '__main__':
847         unittest.main()                           834         unittest.main()
                                                      

~ [ 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