blob: eab540f31b6933b45a5a613018389aea2cb2005e [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2025 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import unittest
from unittest import mock
import collect_warnings
################################################################################
# This file contains tests for the collect_warnings.py script.
# These are primarily regression tests, comparing the result of running on
# sample build logs to known outputs. The sample logs were generated by building
# chromium with some extra warnings enabled, then arbitrarily choosing some
# examples of each warning and splitting them into multiple test files.
################################################################################
class TestCollectWarnings(unittest.TestCase):
@property
def _input_dir(self):
base = os.path.dirname(os.path.abspath(__file__))
return os.path.join(base, "test_files")
@property
def _output_dir(self):
base = os.path.dirname(os.path.abspath(__file__))
return os.path.join(base, "expected_output")
def RunTestForWarning(self, warning_str, expected_file, other_args):
"""
Run the script on the files in test_files/, searching for the designated
warning. Ensure the output is identical to the contents of
`expected_file`.
"""
# Always write to stdout so we can capture the output easily via mock
args = ["-w", warning_str, "-o", "stdout", "-l", self._input_dir]
args += other_args
with mock.patch("sys.stdout", write=mock.Mock()) as mock_stdout:
collect_warnings.main(args)
output = mock_stdout.write.call_args_list
# Reconstruct the written output from the call_args
# Calling with more than one arg should be impossible
self.assertFalse(any(len(call.args) > 1 for call in output))
call_strs = [call.args[0] for call in output]
written_text = "".join(call_strs)
with open(os.path.join(self._output_dir, expected_file)) as expected:
self.assertEqual(written_text, expected.read())
## Tests for specific warning, to ensure we filter out warnings we don't
## want, and don't generate duplicates
def testMissingInitializers(self):
self.RunTestForWarning("[-Wmissing-field-initializers]",
"missing_initializers.txt", ["-s"])
def testUnusedParameter(self):
self.RunTestForWarning("[-Wunused-parameter]", "unused_parameter.txt",
["-s"])
# This warning only appears in the Windows output
def testNontrivialMemcall(self):
self.RunTestForWarning("[-Wnontrivial-memcall]",
"nontrivial_memcall.txt", ["-s"])
## Tests for the various output formats (json/text, links/no links)
def testEverything(self):
# Passing "]" as the warning string will grab all clang warnings
self.RunTestForWarning("]", "everything.json", [])
self.RunTestForWarning("]", "everything_links.json", ["-k"])
self.RunTestForWarning("]", "everything.txt", ["-s"])
self.RunTestForWarning("]", "everything_links.txt", ["-s", "-k"])
if __name__ == '__main__':
unittest.main()