blob: 27ca86cf2e5daaa01f0d65680806b570044fc71b [file]
#!/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()