Commit ccbb22b9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux-kselftest-kunit-fixes-5.14-rc2' of...

Merge tag 'linux-kselftest-kunit-fixes-5.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kunit fixes from Shuah Khan:
 "Fixes to kunit tool and documentation:

   - fix asserts on older python versions

   - fixes to misleading error messages when TAP header format is
     incorrect or when file is missing

   - documentation fix: drop obsolete information about uml_abort
     coverage

   - remove unnecessary annotations"

* tag 'linux-kselftest-kunit-fixes-5.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  kunit: tool: Assert the version requirement
  kunit: tool: remove unnecessary "annotations" import
  Documentation: kunit: drop obsolete note about uml_abort for coverage
  kunit: tool: Fix error messages for cases of no tests and wrong TAP header
parents 00397e74 df4b0807
...@@ -86,19 +86,7 @@ Generating code coverage reports under UML ...@@ -86,19 +86,7 @@ Generating code coverage reports under UML
.. note:: .. note::
TODO(brendanhiggins@google.com): There are various issues with UML and TODO(brendanhiggins@google.com): There are various issues with UML and
versions of gcc 7 and up. You're likely to run into missing ``.gcda`` versions of gcc 7 and up. You're likely to run into missing ``.gcda``
files or compile errors. We know one `faulty GCC commit files or compile errors.
<https://github.com/gcc-mirror/gcc/commit/8c9434c2f9358b8b8bad2c1990edf10a21645f9d>`_
but not how we'd go about getting this fixed. The compile errors still
need some investigation.
.. note::
TODO(brendanhiggins@google.com): for recent versions of Linux
(5.10-5.12, maybe earlier), there's a bug with gcov counters not being
flushed in UML. This translates to very low (<1%) reported coverage. This is
related to the above issue and can be worked around by replacing the
one call to ``uml_abort()`` (it's in ``os_dump_core()``) with a plain
``exit()``.
This is different from the "normal" way of getting coverage information that is This is different from the "normal" way of getting coverage information that is
documented in Documentation/dev-tools/gcov.rst. documented in Documentation/dev-tools/gcov.rst.
......
...@@ -12,6 +12,8 @@ import sys ...@@ -12,6 +12,8 @@ import sys
import os import os
import time import time
assert sys.version_info >= (3, 7), "Python version is too old"
from collections import namedtuple from collections import namedtuple
from enum import Enum, auto from enum import Enum, auto
......
...@@ -6,15 +6,13 @@ ...@@ -6,15 +6,13 @@
# Author: Felix Guo <felixguoxiuping@gmail.com> # Author: Felix Guo <felixguoxiuping@gmail.com>
# Author: Brendan Higgins <brendanhiggins@google.com> # Author: Brendan Higgins <brendanhiggins@google.com>
from __future__ import annotations
import importlib.util import importlib.util
import logging import logging
import subprocess import subprocess
import os import os
import shutil import shutil
import signal import signal
from typing import Iterator from typing import Iterator, Optional, Tuple
from typing import Optional
from contextlib import ExitStack from contextlib import ExitStack
...@@ -208,7 +206,7 @@ def get_source_tree_ops(arch: str, cross_compile: Optional[str]) -> LinuxSourceT ...@@ -208,7 +206,7 @@ def get_source_tree_ops(arch: str, cross_compile: Optional[str]) -> LinuxSourceT
raise ConfigError(arch + ' is not a valid arch') raise ConfigError(arch + ' is not a valid arch')
def get_source_tree_ops_from_qemu_config(config_path: str, def get_source_tree_ops_from_qemu_config(config_path: str,
cross_compile: Optional[str]) -> tuple[ cross_compile: Optional[str]) -> Tuple[
str, LinuxSourceTreeOperations]: str, LinuxSourceTreeOperations]:
# The module name/path has very little to do with where the actual file # The module name/path has very little to do with where the actual file
# exists (I learned this through experimentation and could not find it # exists (I learned this through experimentation and could not find it
......
...@@ -338,9 +338,11 @@ def bubble_up_suite_errors(test_suites: Iterable[TestSuite]) -> TestStatus: ...@@ -338,9 +338,11 @@ def bubble_up_suite_errors(test_suites: Iterable[TestSuite]) -> TestStatus:
def parse_test_result(lines: LineStream) -> TestResult: def parse_test_result(lines: LineStream) -> TestResult:
consume_non_diagnostic(lines) consume_non_diagnostic(lines)
if not lines or not parse_tap_header(lines): if not lines or not parse_tap_header(lines):
return TestResult(TestStatus.NO_TESTS, [], lines) return TestResult(TestStatus.FAILURE_TO_PARSE_TESTS, [], lines)
expected_test_suite_num = parse_test_plan(lines) expected_test_suite_num = parse_test_plan(lines)
if not expected_test_suite_num: if expected_test_suite_num == 0:
return TestResult(TestStatus.NO_TESTS, [], lines)
elif expected_test_suite_num is None:
return TestResult(TestStatus.FAILURE_TO_PARSE_TESTS, [], lines) return TestResult(TestStatus.FAILURE_TO_PARSE_TESTS, [], lines)
test_suites = [] test_suites = []
for i in range(1, expected_test_suite_num + 1): for i in range(1, expected_test_suite_num + 1):
......
...@@ -157,8 +157,18 @@ class KUnitParserTest(unittest.TestCase): ...@@ -157,8 +157,18 @@ class KUnitParserTest(unittest.TestCase):
kunit_parser.TestStatus.FAILURE, kunit_parser.TestStatus.FAILURE,
result.status) result.status)
def test_no_header(self):
empty_log = test_data_path('test_is_test_passed-no_tests_run_no_header.log')
with open(empty_log) as file:
result = kunit_parser.parse_run_tests(
kunit_parser.extract_tap_lines(file.readlines()))
self.assertEqual(0, len(result.suites))
self.assertEqual(
kunit_parser.TestStatus.FAILURE_TO_PARSE_TESTS,
result.status)
def test_no_tests(self): def test_no_tests(self):
empty_log = test_data_path('test_is_test_passed-no_tests_run.log') empty_log = test_data_path('test_is_test_passed-no_tests_run_with_header.log')
with open(empty_log) as file: with open(empty_log) as file:
result = kunit_parser.parse_run_tests( result = kunit_parser.parse_run_tests(
kunit_parser.extract_tap_lines(file.readlines())) kunit_parser.extract_tap_lines(file.readlines()))
...@@ -173,7 +183,7 @@ class KUnitParserTest(unittest.TestCase): ...@@ -173,7 +183,7 @@ class KUnitParserTest(unittest.TestCase):
with open(crash_log) as file: with open(crash_log) as file:
result = kunit_parser.parse_run_tests( result = kunit_parser.parse_run_tests(
kunit_parser.extract_tap_lines(file.readlines())) kunit_parser.extract_tap_lines(file.readlines()))
print_mock.assert_any_call(StrContains('no tests run!')) print_mock.assert_any_call(StrContains('could not parse test results!'))
print_mock.stop() print_mock.stop()
file.close() file.close()
...@@ -309,7 +319,7 @@ class KUnitJsonTest(unittest.TestCase): ...@@ -309,7 +319,7 @@ class KUnitJsonTest(unittest.TestCase):
result["sub_groups"][1]["test_cases"][0]) result["sub_groups"][1]["test_cases"][0])
def test_no_tests_json(self): def test_no_tests_json(self):
result = self._json_for('test_is_test_passed-no_tests_run.log') result = self._json_for('test_is_test_passed-no_tests_run_with_header.log')
self.assertEqual(0, len(result['sub_groups'])) self.assertEqual(0, len(result['sub_groups']))
class StrContains(str): class StrContains(str):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment