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