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 331 kunit_parser.parse_run_tests(file.readlines()) 332 self.print_mock.assert_any_cal 332 self.print_mock.assert_any_call(StrContains('suite (1 subtest)')) 333 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. << 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 << 345 << 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()
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.