| #!/usr/bin/env vpython3 | |
| # Copyright 2026 The Chromium Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """Unit tests for code_coverage_installer.py.""" | |
| import contextlib | |
| import io | |
| import pathlib | |
| import unittest | |
| from unittest.mock import patch | |
| from pyfakefs import fake_filesystem_unittest | |
| import code_coverage_installer | |
| class CodeCoverageInstallerTest(fake_filesystem_unittest.TestCase): | |
| """Tests individual filesystem verification and setup helper functions.""" | |
| def setUp(self) -> None: | |
| """Sets up virtual filesystem, stream redirection, and command mock.""" | |
| self.setUpPyfakefs() | |
| self.src_root = pathlib.Path('/src') | |
| self.fs.create_dir('/src') | |
| self.enterContext(contextlib.redirect_stdout(io.StringIO())) | |
| self.enterContext(contextlib.redirect_stderr(io.StringIO())) | |
| self.run_command_patcher = patch('code_coverage_installer.run_command') | |
| self.mock_run_command = self.run_command_patcher.start() | |
| self.addCleanup(self.run_command_patcher.stop) | |
| def test_verify_chromium_checkout_success(self) -> None: | |
| """Verifies checkout succeeds when DEPS file exists.""" | |
| self.fs.create_file('/src/DEPS') | |
| result = code_coverage_installer.verify_chromium_checkout(self.src_root) | |
| self.assertTrue(result) | |
| def test_verify_chromium_checkout_missing_deps(self) -> None: | |
| """Verifies checkout fails when DEPS file is missing.""" | |
| result = code_coverage_installer.verify_chromium_checkout(self.src_root) | |
| self.assertFalse(result) | |
| def test_verify_llvm_tools_success(self) -> None: | |
| """Verifies LLVM tools check succeeds when both binaries exist.""" | |
| self.fs.create_file( | |
| '/src/third_party/llvm-build/Release+Asserts/bin/llvm-cov' | |
| ) | |
| self.fs.create_file( | |
| '/src/third_party/llvm-build/Release+Asserts/bin/llvm-profdata' | |
| ) | |
| result = code_coverage_installer.verify_llvm_tools(self.src_root) | |
| self.assertTrue(result) | |
| def test_verify_llvm_tools_missing(self) -> None: | |
| """Verifies LLVM tools check fails when binaries are missing.""" | |
| result = code_coverage_installer.verify_llvm_tools(self.src_root) | |
| self.assertFalse(result) | |
| def test_verify_recipes_success(self) -> None: | |
| """Verifies recipes check succeeds when recipe module folder exists.""" | |
| self.fs.create_dir('/infra_dir/build/recipes/recipe_modules/code_coverage') | |
| infra_dir = pathlib.Path('/infra_dir') | |
| result = code_coverage_installer.verify_recipes(infra_dir) | |
| self.assertTrue(result) | |
| def test_verify_recipes_missing(self) -> None: | |
| """Verifies recipes check fails when recipe module folder is missing.""" | |
| infra_dir = pathlib.Path('/infra_dir') | |
| result = code_coverage_installer.verify_recipes(infra_dir) | |
| self.assertFalse(result) | |
| def test_verify_service_success(self) -> None: | |
| """Verifies FindIt service check succeeds when service directory exists.""" | |
| self.fs.create_dir('/infra_dir/infra/appengine/findit') | |
| infra_dir = pathlib.Path('/infra_dir') | |
| result = code_coverage_installer.verify_service(infra_dir) | |
| self.assertTrue(result) | |
| def test_verify_service_missing(self) -> None: | |
| """Verifies FindIt service check fails when service directory is missing.""" | |
| infra_dir = pathlib.Path('/infra_dir') | |
| result = code_coverage_installer.verify_service(infra_dir) | |
| self.assertFalse(result) | |
| def test_setup_infra_gclient_exists_sync_success(self) -> None: | |
| """Verifies running gclient sync when .gclient already exists.""" | |
| infra_dir = pathlib.Path('/infra_dir') | |
| self.fs.create_file('/infra_dir/.gclient') | |
| self.mock_run_command.return_value = 0 | |
| result = code_coverage_installer.setup_infra(infra_dir) | |
| self.assertTrue(result) | |
| self.mock_run_command.assert_called_once_with( | |
| ['gclient', 'sync'], cwd=infra_dir | |
| ) | |
| def test_setup_infra_gclient_exists_sync_failure(self) -> None: | |
| """Verifies setup fails when gclient sync returns non-zero code.""" | |
| infra_dir = pathlib.Path('/infra_dir') | |
| self.fs.create_file('/infra_dir/.gclient') | |
| self.mock_run_command.return_value = 1 | |
| result = code_coverage_installer.setup_infra(infra_dir) | |
| self.assertFalse(result) | |
| def test_setup_infra_no_gclient_fetch_success(self) -> None: | |
| """Verifies fetch infra_superproject runs when .gclient is missing.""" | |
| infra_dir = pathlib.Path('/infra_dir') | |
| self.mock_run_command.return_value = 0 | |
| result = code_coverage_installer.setup_infra(infra_dir) | |
| self.assertTrue(result) | |
| self.mock_run_command.assert_called_once_with( | |
| ['fetch', 'infra_superproject'], cwd=infra_dir | |
| ) | |
| def test_setup_infra_no_gclient_fetch_failure(self) -> None: | |
| """Verifies setup fails when fetch infra_superproject returns non-zero.""" | |
| infra_dir = pathlib.Path('/infra_dir') | |
| self.mock_run_command.return_value = 1 | |
| result = code_coverage_installer.setup_infra(infra_dir) | |
| self.assertFalse(result) | |
| def test_fs_permission_error_handled(self) -> None: | |
| """Verifies filesystem permission errors are caught gracefully.""" | |
| with patch( | |
| 'pathlib.Path.exists', side_effect=PermissionError('Access Denied') | |
| ): | |
| result = code_coverage_installer.verify_chromium_checkout(self.src_root) | |
| self.assertFalse(result) | |
| def test_verify_gemini_md_creates_new(self) -> None: | |
| """Verifies creating GEMINI.md with template import when file missing.""" | |
| result = code_coverage_installer.verify_gemini_md(self.src_root) | |
| self.assertTrue(result) | |
| content = (self.src_root / 'GEMINI.md').read_text(encoding='utf-8') | |
| self.assertIn('@agents/prompts/templates/code_coverage.md', content) | |
| def test_verify_gemini_md_appends_existing(self) -> None: | |
| """Verifies appending template import when GEMINI.md already exists.""" | |
| gemini_path = self.src_root / 'GEMINI.md' | |
| gemini_path.write_text('# Existing prompt\n', encoding='utf-8') | |
| result = code_coverage_installer.verify_gemini_md(self.src_root) | |
| self.assertTrue(result) | |
| content = gemini_path.read_text(encoding='utf-8') | |
| self.assertIn('# Existing prompt', content) | |
| self.assertIn('@agents/prompts/templates/code_coverage.md', content) | |
| def test_verify_gemini_md_already_present(self) -> None: | |
| """Verifies no duplicate entry added when import is already present.""" | |
| gemini_path = self.src_root / 'GEMINI.md' | |
| gemini_path.write_text( | |
| '@agents/prompts/templates/code_coverage.md\n', encoding='utf-8' | |
| ) | |
| result = code_coverage_installer.verify_gemini_md(self.src_root) | |
| self.assertTrue(result) | |
| class CodeCoverageInstallerMainTest(unittest.TestCase): | |
| """Tests full CLI main() workflow with mocked environment verification.""" | |
| def setUp(self) -> None: | |
| """Initializes all verification patchers to isolate main() CLI execution.""" | |
| self.enterContext(contextlib.redirect_stdout(io.StringIO())) | |
| self.enterContext(contextlib.redirect_stderr(io.StringIO())) | |
| self.patcher_argv = patch( | |
| 'sys.argv', ['code_coverage_installer.py', '--infra-dir', '/infra_dir'] | |
| ) | |
| self.patcher_exit = patch('sys.exit', side_effect=SystemExit) | |
| self.patcher_gemini = patch( | |
| 'code_coverage_installer.verify_gemini_md', return_value=True | |
| ) | |
| self.patcher_checkout = patch( | |
| 'code_coverage_installer.verify_chromium_checkout' | |
| ) | |
| self.patcher_llvm = patch('code_coverage_installer.verify_llvm_tools') | |
| self.patcher_recipes = patch('code_coverage_installer.verify_recipes') | |
| self.patcher_service = patch('code_coverage_installer.verify_service') | |
| self.patcher_setup = patch('code_coverage_installer.setup_infra') | |
| self.mock_checkout = self.patcher_checkout.start() | |
| self.mock_llvm = self.patcher_llvm.start() | |
| self.mock_recipes = self.patcher_recipes.start() | |
| self.mock_service = self.patcher_service.start() | |
| self.mock_gemini = self.patcher_gemini.start() | |
| self.mock_setup = self.patcher_setup.start() | |
| self.mock_exit = self.patcher_exit.start() | |
| self.patcher_argv.start() | |
| self.addCleanup(patch.stopall) | |
| def test_main_checkout_failed(self) -> None: | |
| """Verifies main() exits with status 1 if Chromium checkout check fails.""" | |
| self.mock_checkout.return_value = False | |
| with self.assertRaises(SystemExit): | |
| code_coverage_installer.main() | |
| self.mock_exit.assert_called_once_with(1) | |
| def test_main_llvm_failed(self) -> None: | |
| """Verifies main() exits with status 1 if LLVM tools check fails.""" | |
| self.mock_checkout.return_value = True | |
| self.mock_llvm.return_value = False | |
| with self.assertRaises(SystemExit): | |
| code_coverage_installer.main() | |
| self.mock_exit.assert_called_once_with(1) | |
| def test_main_already_fully_set_up(self) -> None: | |
| """Verifies main() succeeds immediately without setup when checks pass.""" | |
| self.mock_checkout.return_value = True | |
| self.mock_llvm.return_value = True | |
| self.mock_recipes.return_value = True | |
| self.mock_service.return_value = True | |
| code_coverage_installer.main() | |
| self.assertEqual(self.mock_exit.call_count, 0) | |
| def test_main_setup_needed_and_succeeds(self) -> None: | |
| """Verifies main() runs setup_infra when recipes/service check fails.""" | |
| self.mock_checkout.return_value = True | |
| self.mock_llvm.return_value = True | |
| self.mock_recipes.side_effect = [False, True] | |
| self.mock_service.side_effect = [False, True] | |
| self.mock_setup.return_value = True | |
| code_coverage_installer.main() | |
| self.mock_setup.assert_called_once_with(pathlib.Path('/infra_dir')) | |
| self.assertEqual(self.mock_exit.call_count, 0) | |
| def test_main_setup_needed_but_setup_fails(self) -> None: | |
| """Verifies main() exits with status 1 when setup_infra fails.""" | |
| self.mock_checkout.return_value = True | |
| self.mock_llvm.return_value = True | |
| self.mock_recipes.return_value = False | |
| self.mock_service.return_value = False | |
| self.mock_setup.return_value = False | |
| with self.assertRaises(SystemExit): | |
| code_coverage_installer.main() | |
| self.mock_setup.assert_called_once_with(pathlib.Path('/infra_dir')) | |
| self.mock_exit.assert_called_once_with(1) | |
| def test_main_setup_succeeds_but_re_verification_fails(self) -> None: | |
| """Verifies main() exits with status 1 if re-verification fails.""" | |
| self.mock_checkout.return_value = True | |
| self.mock_llvm.return_value = True | |
| self.mock_recipes.side_effect = [False, False] | |
| self.mock_service.side_effect = [False, True] | |
| self.mock_setup.return_value = True | |
| with self.assertRaises(SystemExit): | |
| code_coverage_installer.main() | |
| self.mock_setup.assert_called_once_with(pathlib.Path('/infra_dir')) | |
| self.mock_exit.assert_called_once_with(1) | |
| if __name__ == '__main__': | |
| unittest.main() |