blob: 9c41267314573308729b90a7eab2fc3977bdd931 [file] [log] [blame]
Finn Behrensc25ce582020-11-23 15:15:33 +01001#!/usr/bin/env python3
Felix Guo6ebf5862019-09-23 02:02:43 -07002# 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
Daniel Latypovb29b14f2021-05-26 01:22:17 -070014import itertools
Heidi Fahim21a6d172020-08-11 14:27:56 -070015import json
Daniel Latypov243180f2021-02-01 12:55:14 -080016import signal
Daniel Latypov7d7c48d2021-10-04 18:13:40 -070017import subprocess
Felix Guo6ebf5862019-09-23 02:02:43 -070018import os
19
20import kunit_config
21import kunit_parser
22import kunit_kernel
Heidi Fahim21a6d172020-08-11 14:27:56 -070023import kunit_json
Felix Guo6ebf5862019-09-23 02:02:43 -070024import kunit
25
26test_tmpdir = ''
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -080027abs_test_data_dir = ''
Felix Guo6ebf5862019-09-23 02:02:43 -070028
29def setUpModule():
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -080030 global test_tmpdir, abs_test_data_dir
Felix Guo6ebf5862019-09-23 02:02:43 -070031 test_tmpdir = tempfile.mkdtemp()
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -080032 abs_test_data_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'test_data'))
Felix Guo6ebf5862019-09-23 02:02:43 -070033
34def tearDownModule():
35 shutil.rmtree(test_tmpdir)
36
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -080037def test_data_path(path):
38 return os.path.join(abs_test_data_dir, path)
Felix Guo6ebf5862019-09-23 02:02:43 -070039
40class KconfigTest(unittest.TestCase):
41
42 def test_is_subset_of(self):
43 kconfig0 = kunit_config.Kconfig()
44 self.assertTrue(kconfig0.is_subset_of(kconfig0))
45
46 kconfig1 = kunit_config.Kconfig()
David Gow97752c32020-03-23 19:43:33 -070047 kconfig1.add_entry(kunit_config.KconfigEntry('TEST', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070048 self.assertTrue(kconfig1.is_subset_of(kconfig1))
49 self.assertTrue(kconfig0.is_subset_of(kconfig1))
50 self.assertFalse(kconfig1.is_subset_of(kconfig0))
51
52 def test_read_from_file(self):
53 kconfig = kunit_config.Kconfig()
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -080054 kconfig_path = test_data_path('test_read_from_file.kconfig')
Felix Guo6ebf5862019-09-23 02:02:43 -070055
56 kconfig.read_from_file(kconfig_path)
57
58 expected_kconfig = kunit_config.Kconfig()
59 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070060 kunit_config.KconfigEntry('UML', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070061 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070062 kunit_config.KconfigEntry('MMU', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070063 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070064 kunit_config.KconfigEntry('TEST', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070065 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070066 kunit_config.KconfigEntry('EXAMPLE_TEST', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070067 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070068 kunit_config.KconfigEntry('MK8', 'n'))
Felix Guo6ebf5862019-09-23 02:02:43 -070069
70 self.assertEqual(kconfig.entries(), expected_kconfig.entries())
71
72 def test_write_to_file(self):
73 kconfig_path = os.path.join(test_tmpdir, '.config')
74
75 expected_kconfig = kunit_config.Kconfig()
76 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070077 kunit_config.KconfigEntry('UML', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070078 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070079 kunit_config.KconfigEntry('MMU', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070080 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070081 kunit_config.KconfigEntry('TEST', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070082 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070083 kunit_config.KconfigEntry('EXAMPLE_TEST', 'y'))
Felix Guo6ebf5862019-09-23 02:02:43 -070084 expected_kconfig.add_entry(
David Gow97752c32020-03-23 19:43:33 -070085 kunit_config.KconfigEntry('MK8', 'n'))
Felix Guo6ebf5862019-09-23 02:02:43 -070086
87 expected_kconfig.write_to_file(kconfig_path)
88
89 actual_kconfig = kunit_config.Kconfig()
90 actual_kconfig.read_from_file(kconfig_path)
91
92 self.assertEqual(actual_kconfig.entries(),
93 expected_kconfig.entries())
94
95class KUnitParserTest(unittest.TestCase):
96
Daniel Latypovb29b14f2021-05-26 01:22:17 -070097 def assertContains(self, needle: str, haystack: kunit_parser.LineStream):
98 # Clone the iterator so we can print the contents on failure.
99 copy, backup = itertools.tee(haystack)
100 for line in copy:
Felix Guo6ebf5862019-09-23 02:02:43 -0700101 if needle in line:
102 return
Daniel Latypovb29b14f2021-05-26 01:22:17 -0700103 raise AssertionError(f'"{needle}" not found in {list(backup)}!')
Felix Guo6ebf5862019-09-23 02:02:43 -0700104
105 def test_output_isolated_correctly(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800106 log_path = test_data_path('test_output_isolated_correctly.log')
Daniel Latypova3ece072020-12-02 11:08:23 -0800107 with open(log_path) as file:
Daniel Latypovb29b14f2021-05-26 01:22:17 -0700108 result = kunit_parser.extract_tap_lines(file.readlines())
Daniel Latypov060352e2020-10-30 15:38:53 -0700109 self.assertContains('TAP version 14', result)
Rae Moard65d07c2021-10-11 14:50:37 -0700110 self.assertContains('# Subtest: example', result)
111 self.assertContains('1..2', result)
112 self.assertContains('ok 1 - example_simple_test', result)
113 self.assertContains('ok 2 - example_mock_test', result)
Felix Guo6ebf5862019-09-23 02:02:43 -0700114 self.assertContains('ok 1 - example', result)
Felix Guo6ebf5862019-09-23 02:02:43 -0700115
Heidi Fahimafc63da2020-03-16 13:21:24 -0700116 def test_output_with_prefix_isolated_correctly(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800117 log_path = test_data_path('test_pound_sign.log')
Heidi Fahimafc63da2020-03-16 13:21:24 -0700118 with open(log_path) as file:
Daniel Latypovb29b14f2021-05-26 01:22:17 -0700119 result = kunit_parser.extract_tap_lines(file.readlines())
Daniel Latypov060352e2020-10-30 15:38:53 -0700120 self.assertContains('TAP version 14', result)
Rae Moard65d07c2021-10-11 14:50:37 -0700121 self.assertContains('# Subtest: kunit-resource-test', result)
122 self.assertContains('1..5', result)
123 self.assertContains('ok 1 - kunit_resource_test_init_resources', result)
124 self.assertContains('ok 2 - kunit_resource_test_alloc_resource', result)
125 self.assertContains('ok 3 - kunit_resource_test_destroy_resource', result)
126 self.assertContains('foo bar #', result)
127 self.assertContains('ok 4 - kunit_resource_test_cleanup_resources', result)
128 self.assertContains('ok 5 - kunit_resource_test_proper_free_ordering', result)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700129 self.assertContains('ok 1 - kunit-resource-test', result)
Rae Moard65d07c2021-10-11 14:50:37 -0700130 self.assertContains('foo bar # non-kunit output', result)
131 self.assertContains('# Subtest: kunit-try-catch-test', result)
132 self.assertContains('1..2', result)
133 self.assertContains('ok 1 - kunit_test_try_catch_successful_try_no_catch',
Heidi Fahimafc63da2020-03-16 13:21:24 -0700134 result)
Rae Moard65d07c2021-10-11 14:50:37 -0700135 self.assertContains('ok 2 - kunit_test_try_catch_unsuccessful_try_does_catch',
Heidi Fahimafc63da2020-03-16 13:21:24 -0700136 result)
137 self.assertContains('ok 2 - kunit-try-catch-test', result)
Rae Moard65d07c2021-10-11 14:50:37 -0700138 self.assertContains('# Subtest: string-stream-test', result)
139 self.assertContains('1..3', result)
140 self.assertContains('ok 1 - string_stream_test_empty_on_creation', result)
141 self.assertContains('ok 2 - string_stream_test_not_empty_after_add', result)
142 self.assertContains('ok 3 - string_stream_test_get_string', result)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700143 self.assertContains('ok 3 - string-stream-test', result)
144
Felix Guo6ebf5862019-09-23 02:02:43 -0700145 def test_parse_successful_test_log(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800146 all_passed_log = test_data_path('test_is_test_passed-all_passed.log')
Daniel Latypova3ece072020-12-02 11:08:23 -0800147 with open(all_passed_log) as file:
148 result = kunit_parser.parse_run_tests(file.readlines())
Felix Guo6ebf5862019-09-23 02:02:43 -0700149 self.assertEqual(
150 kunit_parser.TestStatus.SUCCESS,
151 result.status)
Felix Guo6ebf5862019-09-23 02:02:43 -0700152
Rae Moard65d07c2021-10-11 14:50:37 -0700153 def test_parse_successful_nested_tests_log(self):
154 all_passed_log = test_data_path('test_is_test_passed-all_passed_nested.log')
155 with open(all_passed_log) as file:
156 result = kunit_parser.parse_run_tests(file.readlines())
157 self.assertEqual(
158 kunit_parser.TestStatus.SUCCESS,
159 result.status)
160
161 def test_kselftest_nested(self):
162 kselftest_log = test_data_path('test_is_test_passed-kselftest.log')
163 with open(kselftest_log) as file:
164 result = kunit_parser.parse_run_tests(file.readlines())
165 self.assertEqual(
166 kunit_parser.TestStatus.SUCCESS,
167 result.status)
168
Felix Guo6ebf5862019-09-23 02:02:43 -0700169 def test_parse_failed_test_log(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800170 failed_log = test_data_path('test_is_test_passed-failure.log')
Daniel Latypova3ece072020-12-02 11:08:23 -0800171 with open(failed_log) as file:
172 result = kunit_parser.parse_run_tests(file.readlines())
Felix Guo6ebf5862019-09-23 02:02:43 -0700173 self.assertEqual(
174 kunit_parser.TestStatus.FAILURE,
175 result.status)
Felix Guo6ebf5862019-09-23 02:02:43 -0700176
Rae Moared01ad32021-07-01 17:52:31 +0000177 def test_no_header(self):
178 empty_log = test_data_path('test_is_test_passed-no_tests_run_no_header.log')
179 with open(empty_log) as file:
180 result = kunit_parser.parse_run_tests(
181 kunit_parser.extract_tap_lines(file.readlines()))
Rae Moard65d07c2021-10-11 14:50:37 -0700182 self.assertEqual(0, len(result.test.subtests))
Rae Moared01ad32021-07-01 17:52:31 +0000183 self.assertEqual(
184 kunit_parser.TestStatus.FAILURE_TO_PARSE_TESTS,
185 result.status)
186
Rae Moard65d07c2021-10-11 14:50:37 -0700187 def test_missing_test_plan(self):
188 missing_plan_log = test_data_path('test_is_test_passed-'
189 'missing_plan.log')
190 with open(missing_plan_log) as file:
191 result = kunit_parser.parse_run_tests(
192 kunit_parser.extract_tap_lines(
193 file.readlines()))
194 self.assertEqual(2, result.test.counts.errors)
195 self.assertEqual(
196 kunit_parser.TestStatus.SUCCESS,
197 result.status)
198
Felix Guo6ebf5862019-09-23 02:02:43 -0700199 def test_no_tests(self):
Rae Moard65d07c2021-10-11 14:50:37 -0700200 header_log = test_data_path('test_is_test_passed-no_tests_run_with_header.log')
201 with open(header_log) as file:
Daniel Latypova3ece072020-12-02 11:08:23 -0800202 result = kunit_parser.parse_run_tests(
Daniel Latypovb29b14f2021-05-26 01:22:17 -0700203 kunit_parser.extract_tap_lines(file.readlines()))
Rae Moard65d07c2021-10-11 14:50:37 -0700204 self.assertEqual(0, len(result.test.subtests))
Felix Guo6ebf5862019-09-23 02:02:43 -0700205 self.assertEqual(
206 kunit_parser.TestStatus.NO_TESTS,
207 result.status)
Felix Guo6ebf5862019-09-23 02:02:43 -0700208
Uriel Guajardoe173b8b2020-06-11 21:05:45 +0000209 def test_no_kunit_output(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800210 crash_log = test_data_path('test_insufficient_memory.log')
Uriel Guajardoe173b8b2020-06-11 21:05:45 +0000211 print_mock = mock.patch('builtins.print').start()
Daniel Latypova3ece072020-12-02 11:08:23 -0800212 with open(crash_log) as file:
213 result = kunit_parser.parse_run_tests(
Daniel Latypovb29b14f2021-05-26 01:22:17 -0700214 kunit_parser.extract_tap_lines(file.readlines()))
Rae Moard65d07c2021-10-11 14:50:37 -0700215 print_mock.assert_any_call(StrContains('invalid KTAP input!'))
Uriel Guajardoe173b8b2020-06-11 21:05:45 +0000216 print_mock.stop()
Rae Moard65d07c2021-10-11 14:50:37 -0700217 self.assertEqual(0, len(result.test.subtests))
Uriel Guajardoe173b8b2020-06-11 21:05:45 +0000218
Felix Guo6ebf5862019-09-23 02:02:43 -0700219 def test_crashed_test(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800220 crashed_log = test_data_path('test_is_test_passed-crash.log')
Daniel Latypova3ece072020-12-02 11:08:23 -0800221 with open(crashed_log) as file:
Rae Moard65d07c2021-10-11 14:50:37 -0700222 result = kunit_parser.parse_run_tests(
223 file.readlines())
Felix Guo6ebf5862019-09-23 02:02:43 -0700224 self.assertEqual(
225 kunit_parser.TestStatus.TEST_CRASHED,
226 result.status)
Felix Guo6ebf5862019-09-23 02:02:43 -0700227
David Gow5acaf602021-06-24 23:58:13 -0700228 def test_skipped_test(self):
229 skipped_log = test_data_path('test_skip_tests.log')
Daniel Latypova54ea2e2021-09-28 15:11:11 -0700230 with open(skipped_log) as file:
231 result = kunit_parser.parse_run_tests(file.readlines())
David Gow5acaf602021-06-24 23:58:13 -0700232
233 # A skipped test does not fail the whole suite.
234 self.assertEqual(
235 kunit_parser.TestStatus.SUCCESS,
236 result.status)
David Gow5acaf602021-06-24 23:58:13 -0700237
238 def test_skipped_all_tests(self):
239 skipped_log = test_data_path('test_skip_all_tests.log')
Daniel Latypova54ea2e2021-09-28 15:11:11 -0700240 with open(skipped_log) as file:
241 result = kunit_parser.parse_run_tests(file.readlines())
David Gow5acaf602021-06-24 23:58:13 -0700242
243 self.assertEqual(
244 kunit_parser.TestStatus.SKIPPED,
245 result.status)
David Gow5acaf602021-06-24 23:58:13 -0700246
Rae Moard65d07c2021-10-11 14:50:37 -0700247 def test_ignores_hyphen(self):
248 hyphen_log = test_data_path('test_strip_hyphen.log')
249 file = open(hyphen_log)
250 result = kunit_parser.parse_run_tests(file.readlines())
251
252 # A skipped test does not fail the whole suite.
253 self.assertEqual(
254 kunit_parser.TestStatus.SUCCESS,
255 result.status)
256 self.assertEqual(
257 "sysctl_test",
258 result.test.subtests[0].name)
259 self.assertEqual(
260 "example",
261 result.test.subtests[1].name)
262 file.close()
263
David Gow5acaf602021-06-24 23:58:13 -0700264
Heidi Fahimafc63da2020-03-16 13:21:24 -0700265 def test_ignores_prefix_printk_time(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800266 prefix_log = test_data_path('test_config_printk_time.log')
Heidi Fahimafc63da2020-03-16 13:21:24 -0700267 with open(prefix_log) as file:
268 result = kunit_parser.parse_run_tests(file.readlines())
Brendan Higgins0d0d2452020-10-21 13:39:14 -0700269 self.assertEqual(
270 kunit_parser.TestStatus.SUCCESS,
271 result.status)
Rae Moard65d07c2021-10-11 14:50:37 -0700272 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700273
274 def test_ignores_multiple_prefixes(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800275 prefix_log = test_data_path('test_multiple_prefixes.log')
Heidi Fahimafc63da2020-03-16 13:21:24 -0700276 with open(prefix_log) as file:
277 result = kunit_parser.parse_run_tests(file.readlines())
Brendan Higgins0d0d2452020-10-21 13:39:14 -0700278 self.assertEqual(
279 kunit_parser.TestStatus.SUCCESS,
280 result.status)
Rae Moard65d07c2021-10-11 14:50:37 -0700281 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700282
283 def test_prefix_mixed_kernel_output(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800284 mixed_prefix_log = test_data_path('test_interrupted_tap_output.log')
Heidi Fahimafc63da2020-03-16 13:21:24 -0700285 with open(mixed_prefix_log) as file:
286 result = kunit_parser.parse_run_tests(file.readlines())
Brendan Higgins0d0d2452020-10-21 13:39:14 -0700287 self.assertEqual(
288 kunit_parser.TestStatus.SUCCESS,
289 result.status)
Rae Moard65d07c2021-10-11 14:50:37 -0700290 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700291
292 def test_prefix_poundsign(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800293 pound_log = test_data_path('test_pound_sign.log')
Heidi Fahimafc63da2020-03-16 13:21:24 -0700294 with open(pound_log) as file:
295 result = kunit_parser.parse_run_tests(file.readlines())
Brendan Higgins0d0d2452020-10-21 13:39:14 -0700296 self.assertEqual(
297 kunit_parser.TestStatus.SUCCESS,
298 result.status)
Rae Moard65d07c2021-10-11 14:50:37 -0700299 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700300
301 def test_kernel_panic_end(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800302 panic_log = test_data_path('test_kernel_panic_interrupt.log')
Heidi Fahimafc63da2020-03-16 13:21:24 -0700303 with open(panic_log) as file:
304 result = kunit_parser.parse_run_tests(file.readlines())
Brendan Higgins0d0d2452020-10-21 13:39:14 -0700305 self.assertEqual(
306 kunit_parser.TestStatus.TEST_CRASHED,
307 result.status)
Rae Moard65d07c2021-10-11 14:50:37 -0700308 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700309
310 def test_pound_no_prefix(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800311 pound_log = test_data_path('test_pound_no_prefix.log')
Heidi Fahimafc63da2020-03-16 13:21:24 -0700312 with open(pound_log) as file:
313 result = kunit_parser.parse_run_tests(file.readlines())
Brendan Higgins0d0d2452020-10-21 13:39:14 -0700314 self.assertEqual(
315 kunit_parser.TestStatus.SUCCESS,
316 result.status)
Rae Moard65d07c2021-10-11 14:50:37 -0700317 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
Heidi Fahimafc63da2020-03-16 13:21:24 -0700318
Daniel Latypov243180f2021-02-01 12:55:14 -0800319class LinuxSourceTreeTest(unittest.TestCase):
320
321 def setUp(self):
322 mock.patch.object(signal, 'signal').start()
323 self.addCleanup(mock.patch.stopall)
324
325 def test_invalid_kunitconfig(self):
326 with self.assertRaisesRegex(kunit_kernel.ConfigError, 'nonexistent.* does not exist'):
327 kunit_kernel.LinuxSourceTree('', kunitconfig_path='/nonexistent_file')
328
329 def test_valid_kunitconfig(self):
330 with tempfile.NamedTemporaryFile('wt') as kunitconfig:
Daniel Latypova54ea2e2021-09-28 15:11:11 -0700331 kunit_kernel.LinuxSourceTree('', kunitconfig_path=kunitconfig.name)
Daniel Latypov243180f2021-02-01 12:55:14 -0800332
Daniel Latypov98547812021-02-22 14:52:41 -0800333 def test_dir_kunitconfig(self):
334 with tempfile.TemporaryDirectory('') as dir:
Daniel Latypova54ea2e2021-09-28 15:11:11 -0700335 with open(os.path.join(dir, '.kunitconfig'), 'w'):
Daniel Latypov98547812021-02-22 14:52:41 -0800336 pass
Daniel Latypova54ea2e2021-09-28 15:11:11 -0700337 kunit_kernel.LinuxSourceTree('', kunitconfig_path=dir)
Daniel Latypov98547812021-02-22 14:52:41 -0800338
Daniel Latypovfe678fe2021-09-29 16:25:34 -0700339 def test_invalid_arch(self):
340 with self.assertRaisesRegex(kunit_kernel.ConfigError, 'not a valid arch, options are.*x86_64'):
341 kunit_kernel.LinuxSourceTree('', arch='invalid')
342
Daniel Latypov7d7c48d2021-10-04 18:13:40 -0700343 def test_run_kernel_hits_exception(self):
344 def fake_start(unused_args, unused_build_dir):
345 return subprocess.Popen(['echo "hi\nbye"'], shell=True, text=True, stdout=subprocess.PIPE)
346
347 with tempfile.TemporaryDirectory('') as build_dir:
348 tree = kunit_kernel.LinuxSourceTree(build_dir, load_config=False)
349 mock.patch.object(tree._ops, 'start', side_effect=fake_start).start()
350
351 with self.assertRaises(ValueError):
352 for line in tree.run_kernel(build_dir=build_dir):
353 self.assertEqual(line, 'hi\n')
354 raise ValueError('uh oh, did not read all output')
355
356 with open(kunit_kernel.get_outfile_path(build_dir), 'rt') as outfile:
357 self.assertEqual(outfile.read(), 'hi\nbye\n', msg='Missing some output')
358
Daniel Latypov243180f2021-02-01 12:55:14 -0800359 # TODO: add more test cases.
360
361
Heidi Fahim21a6d172020-08-11 14:27:56 -0700362class KUnitJsonTest(unittest.TestCase):
363
364 def _json_for(self, log_file):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800365 with open(test_data_path(log_file)) as file:
Heidi Fahim21a6d172020-08-11 14:27:56 -0700366 test_result = kunit_parser.parse_run_tests(file)
367 json_obj = kunit_json.get_json_result(
368 test_result=test_result,
369 def_config='kunit_defconfig',
370 build_dir=None,
371 json_path='stdout')
372 return json.loads(json_obj)
373
374 def test_failed_test_json(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800375 result = self._json_for('test_is_test_passed-failure.log')
Heidi Fahim21a6d172020-08-11 14:27:56 -0700376 self.assertEqual(
377 {'name': 'example_simple_test', 'status': 'FAIL'},
378 result["sub_groups"][1]["test_cases"][0])
379
380 def test_crashed_test_json(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800381 result = self._json_for('test_is_test_passed-crash.log')
Heidi Fahim21a6d172020-08-11 14:27:56 -0700382 self.assertEqual(
383 {'name': 'example_simple_test', 'status': 'ERROR'},
384 result["sub_groups"][1]["test_cases"][0])
385
386 def test_no_tests_json(self):
Rae Moared01ad32021-07-01 17:52:31 +0000387 result = self._json_for('test_is_test_passed-no_tests_run_with_header.log')
Heidi Fahim21a6d172020-08-11 14:27:56 -0700388 self.assertEqual(0, len(result['sub_groups']))
389
Rae Moard65d07c2021-10-11 14:50:37 -0700390 def test_nested_json(self):
391 result = self._json_for('test_is_test_passed-all_passed_nested.log')
392 self.assertEqual(
393 {'name': 'example_simple_test', 'status': 'PASS'},
394 result["sub_groups"][0]["sub_groups"][0]["test_cases"][0])
395
Felix Guo6ebf5862019-09-23 02:02:43 -0700396class StrContains(str):
397 def __eq__(self, other):
398 return self in other
399
400class KUnitMainTest(unittest.TestCase):
401 def setUp(self):
Daniel Latypovcd4a9bc2020-12-02 11:08:24 -0800402 path = test_data_path('test_is_test_passed-all_passed.log')
Daniel Latypovcfd607e2020-12-02 11:08:21 -0800403 with open(path) as file:
404 all_passed_log = file.readlines()
405
406 self.print_mock = mock.patch('builtins.print').start()
407 self.addCleanup(mock.patch.stopall)
408
Felix Guo6ebf5862019-09-23 02:02:43 -0700409 self.linux_source_mock = mock.Mock()
410 self.linux_source_mock.build_reconfig = mock.Mock(return_value=True)
Brendan Higgins87c9c162021-05-26 14:24:06 -0700411 self.linux_source_mock.build_kernel = mock.Mock(return_value=True)
Felix Guo6ebf5862019-09-23 02:02:43 -0700412 self.linux_source_mock.run_kernel = mock.Mock(return_value=all_passed_log)
413
David Gow45ba7a82020-04-30 21:27:01 -0700414 def test_config_passes_args_pass(self):
Brendan Higginsd43c7fb2020-07-14 13:41:30 -0700415 kunit.main(['config', '--build_dir=.kunit'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800416 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
417 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 0)
David Gow45ba7a82020-04-30 21:27:01 -0700418
419 def test_build_passes_args_pass(self):
420 kunit.main(['build'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800421 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 0)
Brendan Higgins87c9c162021-05-26 14:24:06 -0700422 self.linux_source_mock.build_kernel.assert_called_once_with(False, 8, '.kunit', None)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800423 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 0)
David Gow45ba7a82020-04-30 21:27:01 -0700424
425 def test_exec_passes_args_pass(self):
426 kunit.main(['exec'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800427 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 0)
428 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
Daniel Latypovd992880b2021-02-05 16:08:53 -0800429 self.linux_source_mock.run_kernel.assert_called_once_with(
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700430 args=None, build_dir='.kunit', filter_glob='', timeout=300)
David Gow45ba7a82020-04-30 21:27:01 -0700431 self.print_mock.assert_any_call(StrContains('Testing complete.'))
432
Felix Guo6ebf5862019-09-23 02:02:43 -0700433 def test_run_passes_args_pass(self):
434 kunit.main(['run'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800435 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
436 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
Heidi Fahim021ed9f2020-03-16 13:21:25 -0700437 self.linux_source_mock.run_kernel.assert_called_once_with(
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700438 args=None, build_dir='.kunit', filter_glob='', timeout=300)
Felix Guo6ebf5862019-09-23 02:02:43 -0700439 self.print_mock.assert_any_call(StrContains('Testing complete.'))
440
David Gow45ba7a82020-04-30 21:27:01 -0700441 def test_exec_passes_args_fail(self):
442 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
443 with self.assertRaises(SystemExit) as e:
444 kunit.main(['exec'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800445 self.assertEqual(e.exception.code, 1)
David Gow45ba7a82020-04-30 21:27:01 -0700446
Felix Guo6ebf5862019-09-23 02:02:43 -0700447 def test_run_passes_args_fail(self):
448 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
449 with self.assertRaises(SystemExit) as e:
450 kunit.main(['run'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800451 self.assertEqual(e.exception.code, 1)
452 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
453 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
Rae Moard65d07c2021-10-11 14:50:37 -0700454 self.print_mock.assert_any_call(StrContains('invalid KTAP input!'))
455
456 def test_exec_no_tests(self):
457 self.linux_source_mock.run_kernel = mock.Mock(return_value=['TAP version 14', '1..0'])
458 with self.assertRaises(SystemExit) as e:
459 kunit.main(['run'], self.linux_source_mock)
460 self.linux_source_mock.run_kernel.assert_called_once_with(
461 args=None, build_dir='.kunit', filter_glob='', timeout=300)
462 self.print_mock.assert_any_call(StrContains(' 0 tests run!'))
Felix Guo6ebf5862019-09-23 02:02:43 -0700463
David Gow45ba7a82020-04-30 21:27:01 -0700464 def test_exec_raw_output(self):
465 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
466 kunit.main(['exec', '--raw_output'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800467 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
468 for call in self.print_mock.call_args_list:
469 self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
Rae Moard65d07c2021-10-11 14:50:37 -0700470 self.assertNotEqual(call, mock.call(StrContains(' 0 tests run!')))
David Gow45ba7a82020-04-30 21:27:01 -0700471
Felix Guo6ebf5862019-09-23 02:02:43 -0700472 def test_run_raw_output(self):
473 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
David Gow45ba7a82020-04-30 21:27:01 -0700474 kunit.main(['run', '--raw_output'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800475 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
476 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
477 for call in self.print_mock.call_args_list:
478 self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
Rae Moard65d07c2021-10-11 14:50:37 -0700479 self.assertNotEqual(call, mock.call(StrContains(' 0 tests run!')))
David Gow45ba7a82020-04-30 21:27:01 -0700480
Daniel Latypov6a499c92021-08-05 16:51:44 -0700481 def test_run_raw_output_kunit(self):
482 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
483 kunit.main(['run', '--raw_output=kunit'], self.linux_source_mock)
484 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
485 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
486 for call in self.print_mock.call_args_list:
487 self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
488 self.assertNotEqual(call, mock.call(StrContains(' 0 tests run')))
489
Daniel Latypovd8c23ea2021-09-22 09:39:21 -0700490 def test_run_raw_output_does_not_take_positional_args(self):
491 # --raw_output is a string flag, but we don't want it to consume
492 # any positional arguments, only ones after an '='
493 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
494 kunit.main(['run', '--raw_output', 'filter_glob'], self.linux_source_mock)
495 self.linux_source_mock.run_kernel.assert_called_once_with(
496 args=None, build_dir='.kunit', filter_glob='filter_glob', timeout=300)
497
David Gow45ba7a82020-04-30 21:27:01 -0700498 def test_exec_timeout(self):
499 timeout = 3453
500 kunit.main(['exec', '--timeout', str(timeout)], self.linux_source_mock)
Daniel Latypovd992880b2021-02-05 16:08:53 -0800501 self.linux_source_mock.run_kernel.assert_called_once_with(
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700502 args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
David Gow45ba7a82020-04-30 21:27:01 -0700503 self.print_mock.assert_any_call(StrContains('Testing complete.'))
Felix Guo6ebf5862019-09-23 02:02:43 -0700504
505 def test_run_timeout(self):
506 timeout = 3453
507 kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800508 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
Heidi Fahim021ed9f2020-03-16 13:21:25 -0700509 self.linux_source_mock.run_kernel.assert_called_once_with(
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700510 args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
Felix Guo6ebf5862019-09-23 02:02:43 -0700511 self.print_mock.assert_any_call(StrContains('Testing complete.'))
512
SeongJae Parkb1b35202019-12-20 05:14:08 +0000513 def test_run_builddir(self):
514 build_dir = '.kunit'
Brendan Higginsd43c7fb2020-07-14 13:41:30 -0700515 kunit.main(['run', '--build_dir=.kunit'], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800516 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
Heidi Fahim021ed9f2020-03-16 13:21:25 -0700517 self.linux_source_mock.run_kernel.assert_called_once_with(
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700518 args=None, build_dir=build_dir, filter_glob='', timeout=300)
SeongJae Parkb1b35202019-12-20 05:14:08 +0000519 self.print_mock.assert_any_call(StrContains('Testing complete.'))
520
David Gow45ba7a82020-04-30 21:27:01 -0700521 def test_config_builddir(self):
522 build_dir = '.kunit'
523 kunit.main(['config', '--build_dir', build_dir], self.linux_source_mock)
Daniel Latypov0b3e6802020-12-02 11:08:22 -0800524 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
David Gow45ba7a82020-04-30 21:27:01 -0700525
526 def test_build_builddir(self):
527 build_dir = '.kunit'
528 kunit.main(['build', '--build_dir', build_dir], self.linux_source_mock)
Brendan Higgins87c9c162021-05-26 14:24:06 -0700529 self.linux_source_mock.build_kernel.assert_called_once_with(False, 8, build_dir, None)
David Gow45ba7a82020-04-30 21:27:01 -0700530
531 def test_exec_builddir(self):
532 build_dir = '.kunit'
533 kunit.main(['exec', '--build_dir', build_dir], self.linux_source_mock)
Daniel Latypovd992880b2021-02-05 16:08:53 -0800534 self.linux_source_mock.run_kernel.assert_called_once_with(
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700535 args=None, build_dir=build_dir, filter_glob='', timeout=300)
David Gow45ba7a82020-04-30 21:27:01 -0700536 self.print_mock.assert_any_call(StrContains('Testing complete.'))
537
Daniel Latypov243180f2021-02-01 12:55:14 -0800538 @mock.patch.object(kunit_kernel, 'LinuxSourceTree')
539 def test_run_kunitconfig(self, mock_linux_init):
540 mock_linux_init.return_value = self.linux_source_mock
541 kunit.main(['run', '--kunitconfig=mykunitconfig'])
542 # Just verify that we parsed and initialized it correctly here.
Brendan Higgins87c9c162021-05-26 14:24:06 -0700543 mock_linux_init.assert_called_once_with('.kunit',
544 kunitconfig_path='mykunitconfig',
545 arch='um',
546 cross_compile=None,
547 qemu_config_path=None)
Daniel Latypov243180f2021-02-01 12:55:14 -0800548
549 @mock.patch.object(kunit_kernel, 'LinuxSourceTree')
550 def test_config_kunitconfig(self, mock_linux_init):
551 mock_linux_init.return_value = self.linux_source_mock
552 kunit.main(['config', '--kunitconfig=mykunitconfig'])
553 # Just verify that we parsed and initialized it correctly here.
Brendan Higgins87c9c162021-05-26 14:24:06 -0700554 mock_linux_init.assert_called_once_with('.kunit',
555 kunitconfig_path='mykunitconfig',
556 arch='um',
557 cross_compile=None,
558 qemu_config_path=None)
Daniel Latypov243180f2021-02-01 12:55:14 -0800559
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700560 def test_run_kernel_args(self):
561 kunit.main(['run', '--kernel_args=a=1', '--kernel_args=b=2'], self.linux_source_mock)
562 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
563 self.linux_source_mock.run_kernel.assert_called_once_with(
564 args=['a=1','b=2'], build_dir='.kunit', filter_glob='', timeout=300)
565 self.print_mock.assert_any_call(StrContains('Testing complete.'))
566
Daniel Latypovff9e09a2021-09-30 15:20:48 -0700567 def test_list_tests(self):
568 want = ['suite.test1', 'suite.test2', 'suite2.test1']
569 self.linux_source_mock.run_kernel.return_value = ['TAP version 14', 'init: random output'] + want
570
571 got = kunit._list_tests(self.linux_source_mock,
572 kunit.KunitExecRequest(300, '.kunit', False, 'suite*', None, 'suite'))
573
574 self.assertEqual(got, want)
575 # Should respect the user's filter glob when listing tests.
576 self.linux_source_mock.run_kernel.assert_called_once_with(
577 args=['kunit.action=list'], build_dir='.kunit', filter_glob='suite*', timeout=300)
578
579
580 @mock.patch.object(kunit, '_list_tests')
581 def test_run_isolated_by_suite(self, mock_tests):
582 mock_tests.return_value = ['suite.test1', 'suite.test2', 'suite2.test1']
583 kunit.main(['exec', '--run_isolated=suite', 'suite*.test*'], self.linux_source_mock)
584
585 # Should respect the user's filter glob when listing tests.
586 mock_tests.assert_called_once_with(mock.ANY,
587 kunit.KunitExecRequest(300, '.kunit', False, 'suite*.test*', None, 'suite'))
588 self.linux_source_mock.run_kernel.assert_has_calls([
589 mock.call(args=None, build_dir='.kunit', filter_glob='suite.test*', timeout=300),
590 mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test*', timeout=300),
591 ])
592
593 @mock.patch.object(kunit, '_list_tests')
594 def test_run_isolated_by_test(self, mock_tests):
595 mock_tests.return_value = ['suite.test1', 'suite.test2', 'suite2.test1']
596 kunit.main(['exec', '--run_isolated=test', 'suite*'], self.linux_source_mock)
597
598 # Should respect the user's filter glob when listing tests.
599 mock_tests.assert_called_once_with(mock.ANY,
600 kunit.KunitExecRequest(300, '.kunit', False, 'suite*', None, 'test'))
601 self.linux_source_mock.run_kernel.assert_has_calls([
602 mock.call(args=None, build_dir='.kunit', filter_glob='suite.test1', timeout=300),
603 mock.call(args=None, build_dir='.kunit', filter_glob='suite.test2', timeout=300),
604 mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test1', timeout=300),
605 ])
606
Daniel Latypov6cb51a12021-07-15 09:08:19 -0700607
Felix Guo6ebf5862019-09-23 02:02:43 -0700608if __name__ == '__main__':
609 unittest.main()