#!/usr/bin/env python3 # Copyright 2023 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 pathlib import shutil import sys import tempfile import textwrap import unittest from unittest import mock import clobber class TestExtractBuildCommand(unittest.TestCase): def setUp(self): self.build_ninja_file, self.build_ninja_path = tempfile.mkstemp(text=True) def tearDown(self): os.close(self.build_ninja_file) os.remove(self.build_ninja_path) def test_normal_extraction(self): build_ninja_file_contents = textwrap.dedent(""" ninja_required_version = 1.7.2 rule gn command = ../../buildtools/gn --root=../.. -q --regeneration gen . pool = console description = Regenerating ninja files build build.ninja.stamp: gn generator = 1 depfile = build.ninja.d build build.ninja: phony build.ninja.stamp generator = 1 pool build_toolchain_action_pool depth = 72 pool build_toolchain_link_pool depth = 23 subninja toolchain.ninja subninja clang_newlib_x64/toolchain.ninja subninja glibc_x64/toolchain.ninja subninja irt_x64/toolchain.ninja subninja nacl_bootstrap_x64/toolchain.ninja subninja newlib_pnacl/toolchain.ninja build blink_python_tests: phony obj/blink_python_tests.stamp build blink_tests: phony obj/blink_tests.stamp default all """) # Based off of a standard linux build dir. with open(self.build_ninja_path, 'w') as f: f.write(build_ninja_file_contents) expected_build_ninja_file_contents = textwrap.dedent(""" ninja_required_version = 1.7.2 rule gn command = ../../buildtools/gn --root=../.. -q --regeneration gen . pool = console description = Regenerating ninja files build build.ninja.stamp: gn generator = 1 depfile = build.ninja.d build build.ninja: phony build.ninja.stamp generator = 1 """) self.assertEqual(clobber.extract_gn_build_commands(self.build_ninja_path), expected_build_ninja_file_contents) def test_unexpected_format(self): # No "build build.ninja:" line should make it return an empty string. build_ninja_file_contents = textwrap.dedent(""" ninja_required_version = 1.7.2 rule gn command = ../../buildtools/gn --root=../.. -q --regeneration gen . pool = console description = Regenerating ninja files subninja toolchain.ninja build blink_python_tests: phony obj/blink_python_tests.stamp build blink_tests: phony obj/blink_tests.stamp """) with open(self.build_ninja_path, 'w') as f: f.write(build_ninja_file_contents) self.assertEqual(clobber.extract_gn_build_commands(self.build_ninja_path), '') class TestDelete(unittest.TestCase): def setUp(self): self.build_dir = tempfile.mkdtemp() pathlib.Path(os.path.join(self.build_dir, 'build.ninja')).touch() pathlib.Path(os.path.join(self.build_dir, 'build.ninja.d')).touch() def tearDown(self): shutil.rmtree(self.build_dir) def test_delete_build_dir_full(self): # Create a dummy file in the build dir and ensure it gets removed. dummy_file = os.path.join(self.build_dir, 'dummy') pathlib.Path(dummy_file).touch() clobber.delete_build_dir(self.build_dir) self.assertFalse(os.path.exists(dummy_file)) def test_delete_build_dir_fail(self): # Make delete_dir() throw to ensure it's handled gracefully. with mock.patch('clobber._clean_dir', side_effect=OSError): with self.assertRaises(OSError): clobber.delete_build_dir(self.build_dir) @unittest.skipIf(sys.platform == 'win32', 'Symlinks are not allowed on Windows by default') def test_delete_build_dir_link(self): with tempfile.TemporaryDirectory() as tmpdir: # create a symlink. build_dir = os.path.join(tmpdir, 'link') os.symlink(self.build_dir, build_dir) # create a dummy file. dummy_file = os.path.join(build_dir, 'dummy') pathlib.Path(dummy_file).touch() clobber.delete_build_dir(build_dir) self.assertFalse(os.path.exists(dummy_file)) if __name__ == '__main__': unittest.main()