Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/usr/bin/env 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 itertools
15import json
16import signal
17import subprocess
18import os
19
20import kunit_config
21import kunit_parser
22import kunit_kernel
23import kunit_json
24import kunit
25
26test_tmpdir = ''
27abs_test_data_dir = ''
28
29def setUpModule():
30 global test_tmpdir, abs_test_data_dir
31 test_tmpdir = tempfile.mkdtemp()
32 abs_test_data_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'test_data'))
33
34def tearDownModule():
35 shutil.rmtree(test_tmpdir)
36
37def test_data_path(path):
38 return os.path.join(abs_test_data_dir, path)
39
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()
47 kconfig1.add_entry(kunit_config.KconfigEntry('TEST', 'y'))
48 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()
54 kconfig_path = test_data_path('test_read_from_file.kconfig')
55
56 kconfig.read_from_file(kconfig_path)
57
58 expected_kconfig = kunit_config.Kconfig()
59 expected_kconfig.add_entry(
60 kunit_config.KconfigEntry('UML', 'y'))
61 expected_kconfig.add_entry(
62 kunit_config.KconfigEntry('MMU', 'y'))
63 expected_kconfig.add_entry(
64 kunit_config.KconfigEntry('TEST', 'y'))
65 expected_kconfig.add_entry(
66 kunit_config.KconfigEntry('EXAMPLE_TEST', 'y'))
67 expected_kconfig.add_entry(
68 kunit_config.KconfigEntry('MK8', 'n'))
69
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(
77 kunit_config.KconfigEntry('UML', 'y'))
78 expected_kconfig.add_entry(
79 kunit_config.KconfigEntry('MMU', 'y'))
80 expected_kconfig.add_entry(
81 kunit_config.KconfigEntry('TEST', 'y'))
82 expected_kconfig.add_entry(
83 kunit_config.KconfigEntry('EXAMPLE_TEST', 'y'))
84 expected_kconfig.add_entry(
85 kunit_config.KconfigEntry('MK8', 'n'))
86
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
97 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:
101 if needle in line:
102 return
103 raise AssertionError(f'"{needle}" not found in {list(backup)}!')
104
105 def test_output_isolated_correctly(self):
106 log_path = test_data_path('test_output_isolated_correctly.log')
107 with open(log_path) as file:
108 result = kunit_parser.extract_tap_lines(file.readlines())
109 self.assertContains('TAP version 14', result)
110 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)
114 self.assertContains('ok 1 - example', result)
115
116 def test_output_with_prefix_isolated_correctly(self):
117 log_path = test_data_path('test_pound_sign.log')
118 with open(log_path) as file:
119 result = kunit_parser.extract_tap_lines(file.readlines())
120 self.assertContains('TAP version 14', result)
121 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)
129 self.assertContains('ok 1 - kunit-resource-test', result)
130 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',
134 result)
135 self.assertContains('ok 2 - kunit_test_try_catch_unsuccessful_try_does_catch',
136 result)
137 self.assertContains('ok 2 - kunit-try-catch-test', result)
138 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)
143 self.assertContains('ok 3 - string-stream-test', result)
144
145 def test_parse_successful_test_log(self):
146 all_passed_log = test_data_path('test_is_test_passed-all_passed.log')
147 with open(all_passed_log) as file:
148 result = kunit_parser.parse_run_tests(file.readlines())
149 self.assertEqual(
150 kunit_parser.TestStatus.SUCCESS,
151 result.status)
152
153 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
169 def test_parse_failed_test_log(self):
170 failed_log = test_data_path('test_is_test_passed-failure.log')
171 with open(failed_log) as file:
172 result = kunit_parser.parse_run_tests(file.readlines())
173 self.assertEqual(
174 kunit_parser.TestStatus.FAILURE,
175 result.status)
176
177 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()))
182 self.assertEqual(0, len(result.test.subtests))
183 self.assertEqual(
184 kunit_parser.TestStatus.FAILURE_TO_PARSE_TESTS,
185 result.status)
186
187 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
199 def test_no_tests(self):
200 header_log = test_data_path('test_is_test_passed-no_tests_run_with_header.log')
201 with open(header_log) as file:
202 result = kunit_parser.parse_run_tests(
203 kunit_parser.extract_tap_lines(file.readlines()))
204 self.assertEqual(0, len(result.test.subtests))
205 self.assertEqual(
206 kunit_parser.TestStatus.NO_TESTS,
207 result.status)
208
209 def test_no_kunit_output(self):
210 crash_log = test_data_path('test_insufficient_memory.log')
211 print_mock = mock.patch('builtins.print').start()
212 with open(crash_log) as file:
213 result = kunit_parser.parse_run_tests(
214 kunit_parser.extract_tap_lines(file.readlines()))
215 print_mock.assert_any_call(StrContains('invalid KTAP input!'))
216 print_mock.stop()
217 self.assertEqual(0, len(result.test.subtests))
218
219 def test_crashed_test(self):
220 crashed_log = test_data_path('test_is_test_passed-crash.log')
221 with open(crashed_log) as file:
222 result = kunit_parser.parse_run_tests(
223 file.readlines())
224 self.assertEqual(
225 kunit_parser.TestStatus.TEST_CRASHED,
226 result.status)
227
228 def test_skipped_test(self):
229 skipped_log = test_data_path('test_skip_tests.log')
230 with open(skipped_log) as file:
231 result = kunit_parser.parse_run_tests(file.readlines())
232
233 # A skipped test does not fail the whole suite.
234 self.assertEqual(
235 kunit_parser.TestStatus.SUCCESS,
236 result.status)
237
238 def test_skipped_all_tests(self):
239 skipped_log = test_data_path('test_skip_all_tests.log')
240 with open(skipped_log) as file:
241 result = kunit_parser.parse_run_tests(file.readlines())
242
243 self.assertEqual(
244 kunit_parser.TestStatus.SKIPPED,
245 result.status)
246
247 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
264
265 def test_ignores_prefix_printk_time(self):
266 prefix_log = test_data_path('test_config_printk_time.log')
267 with open(prefix_log) as file:
268 result = kunit_parser.parse_run_tests(file.readlines())
269 self.assertEqual(
270 kunit_parser.TestStatus.SUCCESS,
271 result.status)
272 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
273
274 def test_ignores_multiple_prefixes(self):
275 prefix_log = test_data_path('test_multiple_prefixes.log')
276 with open(prefix_log) as file:
277 result = kunit_parser.parse_run_tests(file.readlines())
278 self.assertEqual(
279 kunit_parser.TestStatus.SUCCESS,
280 result.status)
281 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
282
283 def test_prefix_mixed_kernel_output(self):
284 mixed_prefix_log = test_data_path('test_interrupted_tap_output.log')
285 with open(mixed_prefix_log) as file:
286 result = kunit_parser.parse_run_tests(file.readlines())
287 self.assertEqual(
288 kunit_parser.TestStatus.SUCCESS,
289 result.status)
290 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
291
292 def test_prefix_poundsign(self):
293 pound_log = test_data_path('test_pound_sign.log')
294 with open(pound_log) as file:
295 result = kunit_parser.parse_run_tests(file.readlines())
296 self.assertEqual(
297 kunit_parser.TestStatus.SUCCESS,
298 result.status)
299 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
300
301 def test_kernel_panic_end(self):
302 panic_log = test_data_path('test_kernel_panic_interrupt.log')
303 with open(panic_log) as file:
304 result = kunit_parser.parse_run_tests(file.readlines())
305 self.assertEqual(
306 kunit_parser.TestStatus.TEST_CRASHED,
307 result.status)
308 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
309
310 def test_pound_no_prefix(self):
311 pound_log = test_data_path('test_pound_no_prefix.log')
312 with open(pound_log) as file:
313 result = kunit_parser.parse_run_tests(file.readlines())
314 self.assertEqual(
315 kunit_parser.TestStatus.SUCCESS,
316 result.status)
317 self.assertEqual('kunit-resource-test', result.test.subtests[0].name)
318
319class 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:
331 kunit_kernel.LinuxSourceTree('', kunitconfig_path=kunitconfig.name)
332
333 def test_dir_kunitconfig(self):
334 with tempfile.TemporaryDirectory('') as dir:
335 with open(os.path.join(dir, '.kunitconfig'), 'w'):
336 pass
337 kunit_kernel.LinuxSourceTree('', kunitconfig_path=dir)
338
339 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
343 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
359 # TODO: add more test cases.
360
361
362class KUnitJsonTest(unittest.TestCase):
363
364 def _json_for(self, log_file):
365 with open(test_data_path(log_file)) as file:
366 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):
375 result = self._json_for('test_is_test_passed-failure.log')
376 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):
381 result = self._json_for('test_is_test_passed-crash.log')
382 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):
387 result = self._json_for('test_is_test_passed-no_tests_run_with_header.log')
388 self.assertEqual(0, len(result['sub_groups']))
389
390 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
396class StrContains(str):
397 def __eq__(self, other):
398 return self in other
399
400class KUnitMainTest(unittest.TestCase):
401 def setUp(self):
402 path = test_data_path('test_is_test_passed-all_passed.log')
403 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
409 self.linux_source_mock = mock.Mock()
410 self.linux_source_mock.build_reconfig = mock.Mock(return_value=True)
411 self.linux_source_mock.build_kernel = mock.Mock(return_value=True)
412 self.linux_source_mock.run_kernel = mock.Mock(return_value=all_passed_log)
413
414 def test_config_passes_args_pass(self):
415 kunit.main(['config', '--build_dir=.kunit'], self.linux_source_mock)
416 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
417 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 0)
418
419 def test_build_passes_args_pass(self):
420 kunit.main(['build'], self.linux_source_mock)
421 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 0)
422 self.linux_source_mock.build_kernel.assert_called_once_with(False, 8, '.kunit', None)
423 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 0)
424
425 def test_exec_passes_args_pass(self):
426 kunit.main(['exec'], self.linux_source_mock)
427 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 0)
428 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
429 self.linux_source_mock.run_kernel.assert_called_once_with(
430 args=None, build_dir='.kunit', filter_glob='', timeout=300)
431 self.print_mock.assert_any_call(StrContains('Testing complete.'))
432
433 def test_run_passes_args_pass(self):
434 kunit.main(['run'], self.linux_source_mock)
435 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
436 self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
437 self.linux_source_mock.run_kernel.assert_called_once_with(
438 args=None, build_dir='.kunit', filter_glob='', timeout=300)
439 self.print_mock.assert_any_call(StrContains('Testing complete.'))
440
441 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)
445 self.assertEqual(e.exception.code, 1)
446
447 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)
451 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)
454 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!'))
463
464 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)
467 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.')))
470 self.assertNotEqual(call, mock.call(StrContains(' 0 tests run!')))
471
472 def test_run_raw_output(self):
473 self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
474 kunit.main(['run', '--raw_output'], self.linux_source_mock)
475 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.')))
479 self.assertNotEqual(call, mock.call(StrContains(' 0 tests run!')))
480
481 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
490 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
498 def test_exec_timeout(self):
499 timeout = 3453
500 kunit.main(['exec', '--timeout', str(timeout)], self.linux_source_mock)
501 self.linux_source_mock.run_kernel.assert_called_once_with(
502 args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
503 self.print_mock.assert_any_call(StrContains('Testing complete.'))
504
505 def test_run_timeout(self):
506 timeout = 3453
507 kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock)
508 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
509 self.linux_source_mock.run_kernel.assert_called_once_with(
510 args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
511 self.print_mock.assert_any_call(StrContains('Testing complete.'))
512
513 def test_run_builddir(self):
514 build_dir = '.kunit'
515 kunit.main(['run', '--build_dir=.kunit'], self.linux_source_mock)
516 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
517 self.linux_source_mock.run_kernel.assert_called_once_with(
518 args=None, build_dir=build_dir, filter_glob='', timeout=300)
519 self.print_mock.assert_any_call(StrContains('Testing complete.'))
520
521 def test_config_builddir(self):
522 build_dir = '.kunit'
523 kunit.main(['config', '--build_dir', build_dir], self.linux_source_mock)
524 self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
525
526 def test_build_builddir(self):
527 build_dir = '.kunit'
528 kunit.main(['build', '--build_dir', build_dir], self.linux_source_mock)
529 self.linux_source_mock.build_kernel.assert_called_once_with(False, 8, build_dir, None)
530
531 def test_exec_builddir(self):
532 build_dir = '.kunit'
533 kunit.main(['exec', '--build_dir', build_dir], self.linux_source_mock)
534 self.linux_source_mock.run_kernel.assert_called_once_with(
535 args=None, build_dir=build_dir, filter_glob='', timeout=300)
536 self.print_mock.assert_any_call(StrContains('Testing complete.'))
537
538 @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.
543 mock_linux_init.assert_called_once_with('.kunit',
544 kunitconfig_path='mykunitconfig',
545 arch='um',
546 cross_compile=None,
547 qemu_config_path=None)
548
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.
554 mock_linux_init.assert_called_once_with('.kunit',
555 kunitconfig_path='mykunitconfig',
556 arch='um',
557 cross_compile=None,
558 qemu_config_path=None)
559
560 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
567 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
607
608if __name__ == '__main__':
609 unittest.main()