1#!/usr/bin/python3 2# SPDX-License-Identifier: GPL-2.0 3# 4# A collection of tests for tools/testing/kunit/kunit.py 5# 6# Copyright (C) 2019, Google LLC. 7# Author: Brendan Higgins <brendanhiggins@google.com> 8 9import unittest 10from unittest import mock 11 12import tempfile, shutil # Handling test_tmpdir 13 14import os 15 16import kunit_config 17import kunit_parser 18import kunit_kernel 19import kunit 20 21test_tmpdir = '' 22 23def setUpModule(): 24 global test_tmpdir 25 test_tmpdir = tempfile.mkdtemp() 26 27def tearDownModule(): 28 shutil.rmtree(test_tmpdir) 29 30def get_absolute_path(path): 31 return os.path.join(os.path.dirname(__file__), path) 32 33class KconfigTest(unittest.TestCase): 34 35 def test_is_subset_of(self): 36 kconfig0 = kunit_config.Kconfig() 37 self.assertTrue(kconfig0.is_subset_of(kconfig0)) 38 39 kconfig1 = kunit_config.Kconfig() 40 kconfig1.add_entry(kunit_config.KconfigEntry('CONFIG_TEST=y')) 41 self.assertTrue(kconfig1.is_subset_of(kconfig1)) 42 self.assertTrue(kconfig0.is_subset_of(kconfig1)) 43 self.assertFalse(kconfig1.is_subset_of(kconfig0)) 44 45 def test_read_from_file(self): 46 kconfig = kunit_config.Kconfig() 47 kconfig_path = get_absolute_path( 48 'test_data/test_read_from_file.kconfig') 49 50 kconfig.read_from_file(kconfig_path) 51 52 expected_kconfig = kunit_config.Kconfig() 53 expected_kconfig.add_entry( 54 kunit_config.KconfigEntry('CONFIG_UML=y')) 55 expected_kconfig.add_entry( 56 kunit_config.KconfigEntry('CONFIG_MMU=y')) 57 expected_kconfig.add_entry( 58 kunit_config.KconfigEntry('CONFIG_TEST=y')) 59 expected_kconfig.add_entry( 60 kunit_config.KconfigEntry('CONFIG_EXAMPLE_TEST=y')) 61 expected_kconfig.add_entry( 62 kunit_config.KconfigEntry('# CONFIG_MK8 is not set')) 63 64 self.assertEqual(kconfig.entries(), expected_kconfig.entries()) 65 66 def test_write_to_file(self): 67 kconfig_path = os.path.join(test_tmpdir, '.config') 68 69 expected_kconfig = kunit_config.Kconfig() 70 expected_kconfig.add_entry( 71 kunit_config.KconfigEntry('CONFIG_UML=y')) 72 expected_kconfig.add_entry( 73 kunit_config.KconfigEntry('CONFIG_MMU=y')) 74 expected_kconfig.add_entry( 75 kunit_config.KconfigEntry('CONFIG_TEST=y')) 76 expected_kconfig.add_entry( 77 kunit_config.KconfigEntry('CONFIG_EXAMPLE_TEST=y')) 78 expected_kconfig.add_entry( 79 kunit_config.KconfigEntry('# CONFIG_MK8 is not set')) 80 81 expected_kconfig.write_to_file(kconfig_path) 82 83 actual_kconfig = kunit_config.Kconfig() 84 actual_kconfig.read_from_file(kconfig_path) 85 86 self.assertEqual(actual_kconfig.entries(), 87 expected_kconfig.entries()) 88 89class KUnitParserTest(unittest.TestCase): 90 91 def assertContains(self, needle, haystack): 92 for line in haystack: 93 if needle in line: 94 return 95 raise AssertionError('"' + 96 str(needle) + '" not found in "' + str(haystack) + '"!') 97 98 def test_output_isolated_correctly(self): 99 log_path = get_absolute_path( 100 'test_data/test_output_isolated_correctly.log') 101 file = open(log_path) 102 result = kunit_parser.isolate_kunit_output(file.readlines()) 103 self.assertContains('TAP version 14\n', result) 104 self.assertContains(' # Subtest: example', result) 105 self.assertContains(' 1..2', result) 106 self.assertContains(' ok 1 - example_simple_test', result) 107 self.assertContains(' ok 2 - example_mock_test', result) 108 self.assertContains('ok 1 - example', result) 109 file.close() 110 111 def test_parse_successful_test_log(self): 112 all_passed_log = get_absolute_path( 113 'test_data/test_is_test_passed-all_passed.log') 114 file = open(all_passed_log) 115 result = kunit_parser.parse_run_tests(file.readlines()) 116 self.assertEqual( 117 kunit_parser.TestStatus.SUCCESS, 118 result.status) 119 file.close() 120 121 def test_parse_failed_test_log(self): 122 failed_log = get_absolute_path( 123 'test_data/test_is_test_passed-failure.log') 124 file = open(failed_log) 125 result = kunit_parser.parse_run_tests(file.readlines()) 126 self.assertEqual( 127 kunit_parser.TestStatus.FAILURE, 128 result.status) 129 file.close() 130 131 def test_no_tests(self): 132 empty_log = get_absolute_path( 133 'test_data/test_is_test_passed-no_tests_run.log') 134 file = open(empty_log) 135 result = kunit_parser.parse_run_tests( 136 kunit_parser.isolate_kunit_output(file.readlines())) 137 self.assertEqual(0, len(result.suites)) 138 self.assertEqual( 139 kunit_parser.TestStatus.NO_TESTS, 140 result.status) 141 file.close() 142 143 def test_crashed_test(self): 144 crashed_log = get_absolute_path( 145 'test_data/test_is_test_passed-crash.log') 146 file = open(crashed_log) 147 result = kunit_parser.parse_run_tests(file.readlines()) 148 self.assertEqual( 149 kunit_parser.TestStatus.TEST_CRASHED, 150 result.status) 151 file.close() 152 153class StrContains(str): 154 def __eq__(self, other): 155 return self in other 156 157class KUnitMainTest(unittest.TestCase): 158 def setUp(self): 159 path = get_absolute_path('test_data/test_is_test_passed-all_passed.log') 160 file = open(path) 161 all_passed_log = file.readlines() 162 self.print_patch = mock.patch('builtins.print') 163 self.print_mock = self.print_patch.start() 164 self.linux_source_mock = mock.Mock() 165 self.linux_source_mock.build_reconfig = mock.Mock(return_value=True) 166 self.linux_source_mock.build_um_kernel = mock.Mock(return_value=True) 167 self.linux_source_mock.run_kernel = mock.Mock(return_value=all_passed_log) 168 169 def tearDown(self): 170 self.print_patch.stop() 171 pass 172 173 def test_run_passes_args_pass(self): 174 kunit.main(['run'], self.linux_source_mock) 175 assert self.linux_source_mock.build_reconfig.call_count == 1 176 assert self.linux_source_mock.run_kernel.call_count == 1 177 self.linux_source_mock.run_kernel.assert_called_once_with(build_dir='', timeout=300) 178 self.print_mock.assert_any_call(StrContains('Testing complete.')) 179 180 def test_run_passes_args_fail(self): 181 self.linux_source_mock.run_kernel = mock.Mock(return_value=[]) 182 with self.assertRaises(SystemExit) as e: 183 kunit.main(['run'], self.linux_source_mock) 184 assert type(e.exception) == SystemExit 185 assert e.exception.code == 1 186 assert self.linux_source_mock.build_reconfig.call_count == 1 187 assert self.linux_source_mock.run_kernel.call_count == 1 188 self.print_mock.assert_any_call(StrContains(' 0 tests run')) 189 190 def test_run_raw_output(self): 191 self.linux_source_mock.run_kernel = mock.Mock(return_value=[]) 192 kunit.main(['run', '--raw_output'], self.linux_source_mock) 193 assert self.linux_source_mock.build_reconfig.call_count == 1 194 assert self.linux_source_mock.run_kernel.call_count == 1 195 for kall in self.print_mock.call_args_list: 196 assert kall != mock.call(StrContains('Testing complete.')) 197 assert kall != mock.call(StrContains(' 0 tests run')) 198 199 def test_run_timeout(self): 200 timeout = 3453 201 kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock) 202 assert self.linux_source_mock.build_reconfig.call_count == 1 203 self.linux_source_mock.run_kernel.assert_called_once_with(build_dir='', timeout=timeout) 204 self.print_mock.assert_any_call(StrContains('Testing complete.')) 205 206 def test_run_builddir(self): 207 build_dir = '.kunit' 208 kunit.main(['run', '--build_dir', build_dir], self.linux_source_mock) 209 assert self.linux_source_mock.build_reconfig.call_count == 1 210 self.linux_source_mock.run_kernel.assert_called_once_with(build_dir=build_dir, timeout=300) 211 self.print_mock.assert_any_call(StrContains('Testing complete.')) 212 213if __name__ == '__main__': 214 unittest.main() 215