• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright 2022 The Pigweed Authors
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may not
5# use this file except in compliance with the License. You may obtain a copy of
6# the License at
7#
8#     https://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations under
14# the License.
15"""Tests for ninja_parser."""
16
17from pathlib import Path
18import unittest
19from unittest.mock import MagicMock, mock_open, patch
20
21from pw_presubmit import ninja_parser
22
23_STOP = 'ninja: build stopped:\n'
24
25_REAL_TEST_INPUT = """
26[1168/1797] cp ../../pw_software_update/py/dev_sign_test.py python/gen/pw_software_update/py/py.generated_python_package/dev_sign_test.py
27[1169/1797] ACTION //pw_presubmit/py:py.lint.mypy(//pw_build/python_toolchain:python)
28FAILED: python/gen/pw_presubmit/py/py.lint.mypy.pw_pystamp
29python ../../pw_build/py/pw_build/python_runner.py --gn-root ../../ --current-path ../../pw_presubmit/py --default-toolchain=//pw_toolchain/default:default --current-toolchain=//pw_build/python_toolchain:python --env=MYPY_FORCE_COLOR=1 --touch python/gen/pw_presubmit/py/py.lint.mypy.pw_pystamp --capture-output --module mypy --python-virtualenv-config python/gen/pw_env_setup/pigweed_build_venv/venv_metadata.json --python-dep-list-files python/gen/pw_presubmit/py/py.lint.mypy_metadata_path_list.txt -- --pretty --show-error-codes ../../pw_presubmit/py/pw_presubmit/__init__.py ../../pw_presubmit/py/pw_presubmit/build.py ../../pw_presubmit/py/pw_presubmit/cli.py ../../pw_presubmit/py/pw_presubmit/cpp_checks.py ../../pw_presubmit/py/pw_presubmit/format_code.py ../../pw_presubmit/py/pw_presubmit/git_repo.py ../../pw_presubmit/py/pw_presubmit/inclusive_language.py ../../pw_presubmit/py/pw_presubmit/install_hook.py ../../pw_presubmit/py/pw_presubmit/keep_sorted.py ../../pw_presubmit/py/pw_presubmit/ninja_parser.py ../../pw_presubmit/py/pw_presubmit/npm_presubmit.py ../../pw_presubmit/py/pw_presubmit/pigweed_presubmit.py ../../pw_presubmit/py/pw_presubmit/presubmit.py ../../pw_presubmit/py/pw_presubmit/python_checks.py ../../pw_presubmit/py/pw_presubmit/shell_checks.py ../../pw_presubmit/py/pw_presubmit/todo_check.py ../../pw_presubmit/py/pw_presubmit/tools.py ../../pw_presubmit/py/git_repo_test.py ../../pw_presubmit/py/keep_sorted_test.py ../../pw_presubmit/py/ninja_parser_test.py ../../pw_presubmit/py/presubmit_test.py ../../pw_presubmit/py/tools_test.py ../../pw_presubmit/py/setup.py
30  Requirement already satisfied: pyserial in c:\\b\\s\\w\\ir\\x\\w\\co\\environment\\pigweed-venv\\lib\\site-packages (from pigweed==0.0.13+20230126212203) (3.5)
31../../pw_presubmit/py/presubmit_test.py:63: error: Module has no attribute
32"Filter"  [attr-defined]
33            TestData(presubmit.Filter(suffix=('.a', '.b')), 'foo.c', False...
34                     ^
35Found 1 error in 1 file (checked 23 source files)
36[1170/1797] stamp python/obj/pw_snapshot/metadata_proto.python._mirror_sources_to_out_dir.stamp
37[1171/1797] stamp python/obj/pw_software_update/py/py._mirror_sources_to_out_dir_dev_sign_test.py.stamp
38[1172/1797] ACTION //pw_log:protos.python(//pw_build/python_toolchain:python)
39[1173/1797] ACTION //pw_thread_freertos/py:py.lint.pylint(//pw_build/python_toolchain:python)
40[1174/1797] ACTION //pw_symbolizer/py:py.lint.pylint(//pw_build/python_toolchain:python)
41[1175/1797] ACTION //pw_symbolizer/py:py.lint.pylint(//pw_build/python_toolchain:python)
42[1176/1797] ACTION //pw_thread_freertos/py:py.lint.pylint(//pw_build/python_toolchain:python)
43[1177/1797] ACTION //pw_tls_client/py:py.lint.pylint(//pw_build/python_toolchain:python)
44[1178/1797] ACTION //pw_symbolizer/py:py.lint.pylint(//pw_build/python_toolchain:python)
45[1179/1797] ACTION //pw_console/py:py.lint.pylint(//pw_build/python_toolchain:python)
46[1180/1797] ACTION //pw_tls_client/py:py.lint.pylint(//pw_build/python_toolchain:python)
47[1181/1797] ACTION //pw_console/py:py.lint.pylint(//pw_build/python_toolchain:python)
48[1182/1797] ACTION //pw_console/py:py.lint.pylint(//pw_build/python_toolchain:python)
49[1183/1797] ACTION //pw_tls_client/py:py.lint.mypy(//pw_build/python_toolchain:python)
50[1184/1797] ACTION //pw_symbolizer/py:py.lint.pylint(//pw_build/python_toolchain:python)
51[1185/1797] ACTION //pw_thread_freertos/py:py.lint.pylint(//pw_build/python_toolchain:python)
52[1186/1797] ACTION //pw_tls_client/py:py.lint.pylint(//pw_build/python_toolchain:python)
53ninja: build stopped: subcommand failed.
54[FINISHED]
55"""
56
57_REAL_TEST_SUMMARY = """
58[1169/1797] ACTION //pw_presubmit/py:py.lint.mypy(//pw_build/python_toolchain:python)
59FAILED: python/gen/pw_presubmit/py/py.lint.mypy.pw_pystamp
60python ../../pw_build/py/pw_build/python_runner.py --gn-root ../../ --current-path ../../pw_presubmit/py --default-toolchain=//pw_toolchain/default:default --current-toolchain=//pw_build/python_toolchain:python --env=MYPY_FORCE_COLOR=1 --touch python/gen/pw_presubmit/py/py.lint.mypy.pw_pystamp --capture-output --module mypy --python-virtualenv-config python/gen/pw_env_setup/pigweed_build_venv/venv_metadata.json --python-dep-list-files python/gen/pw_presubmit/py/py.lint.mypy_metadata_path_list.txt -- --pretty --show-error-codes ../../pw_presubmit/py/pw_presubmit/__init__.py ../../pw_presubmit/py/pw_presubmit/build.py ../../pw_presubmit/py/pw_presubmit/cli.py ../../pw_presubmit/py/pw_presubmit/cpp_checks.py ../../pw_presubmit/py/pw_presubmit/format_code.py ../../pw_presubmit/py/pw_presubmit/git_repo.py ../../pw_presubmit/py/pw_presubmit/inclusive_language.py ../../pw_presubmit/py/pw_presubmit/install_hook.py ../../pw_presubmit/py/pw_presubmit/keep_sorted.py ../../pw_presubmit/py/pw_presubmit/ninja_parser.py ../../pw_presubmit/py/pw_presubmit/npm_presubmit.py ../../pw_presubmit/py/pw_presubmit/pigweed_presubmit.py ../../pw_presubmit/py/pw_presubmit/presubmit.py ../../pw_presubmit/py/pw_presubmit/python_checks.py ../../pw_presubmit/py/pw_presubmit/shell_checks.py ../../pw_presubmit/py/pw_presubmit/todo_check.py ../../pw_presubmit/py/pw_presubmit/tools.py ../../pw_presubmit/py/git_repo_test.py ../../pw_presubmit/py/keep_sorted_test.py ../../pw_presubmit/py/ninja_parser_test.py ../../pw_presubmit/py/presubmit_test.py ../../pw_presubmit/py/tools_test.py ../../pw_presubmit/py/setup.py
61../../pw_presubmit/py/presubmit_test.py:63: error: Module has no attribute
62"Filter"  [attr-defined]
63            TestData(presubmit.Filter(suffix=('.a', '.b')), 'foo.c', False...
64                     ^
65Found 1 error in 1 file (checked 23 source files)
66"""
67
68
69class TestNinjaParser(unittest.TestCase):
70    """Test ninja_parser."""
71
72    def _run(self, contents: str) -> str:  # pylint: disable=no-self-use
73        path = MagicMock(spec=Path('foo/bar'))
74
75        def mocked_open_read(*args, **kwargs):
76            return mock_open(read_data=contents)(*args, **kwargs)
77
78        with patch.object(path, 'open', mocked_open_read):
79            return ninja_parser.parse_ninja_stdout(path)
80
81    def test_simple(self) -> None:
82        error = '[2/10] baz\nFAILED: something\nerror 1\nerror 2\n'
83        result = self._run('[0/10] foo\n[1/10] bar\n' + error + _STOP)
84        self.assertEqual(error.strip(), result.strip())
85
86    def test_short(self) -> None:
87        error = '[2/10] baz\nFAILED: something\n'
88        result = self._run('[0/10] foo\n[1/10] bar\n' + error + _STOP)
89        self.assertEqual(error.strip(), result.strip())
90
91    def test_unexpected(self) -> None:
92        error = '[2/10] baz\nERROR: something\nerror 1\n'
93        result = self._run('[0/10] foo\n[1/10] bar\n' + error)
94        self.assertEqual('', result.strip())
95
96    def test_real(self) -> None:
97        result = self._run(_REAL_TEST_INPUT)
98        self.assertEqual(_REAL_TEST_SUMMARY.strip(), result.strip())
99
100
101if __name__ == '__main__':
102    unittest.main()
103