xref: /aosp_15_r20/external/cronet/build/clobber_unittest.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1#!/usr/bin/env python3
2# Copyright 2023 The Chromium Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import os
7import pathlib
8import shutil
9import sys
10import tempfile
11import textwrap
12import unittest
13from unittest import mock
14
15import clobber
16
17
18class TestExtractBuildCommand(unittest.TestCase):
19  def setUp(self):
20    self.build_ninja_file, self.build_ninja_path = tempfile.mkstemp(text=True)
21
22  def tearDown(self):
23    os.close(self.build_ninja_file)
24    os.remove(self.build_ninja_path)
25
26  def test_normal_extraction(self):
27    build_ninja_file_contents = textwrap.dedent("""
28        ninja_required_version = 1.7.2
29
30        rule gn
31          command = ../../buildtools/gn --root=../.. -q --regeneration gen .
32          pool = console
33          description = Regenerating ninja files
34
35        build build.ninja.stamp: gn
36          generator = 1
37          depfile = build.ninja.d
38
39        build build.ninja: phony build.ninja.stamp
40          generator = 1
41
42        pool build_toolchain_action_pool
43          depth = 72
44
45        pool build_toolchain_link_pool
46          depth = 23
47
48        subninja toolchain.ninja
49        subninja clang_newlib_x64/toolchain.ninja
50        subninja glibc_x64/toolchain.ninja
51        subninja irt_x64/toolchain.ninja
52        subninja nacl_bootstrap_x64/toolchain.ninja
53        subninja newlib_pnacl/toolchain.ninja
54
55        build blink_python_tests: phony obj/blink_python_tests.stamp
56        build blink_tests: phony obj/blink_tests.stamp
57
58        default all
59    """)  # Based off of a standard linux build dir.
60    with open(self.build_ninja_path, 'w') as f:
61      f.write(build_ninja_file_contents)
62
63    expected_build_ninja_file_contents = textwrap.dedent("""
64        ninja_required_version = 1.7.2
65
66        rule gn
67          command = ../../buildtools/gn --root=../.. -q --regeneration gen .
68          pool = console
69          description = Regenerating ninja files
70
71        build build.ninja.stamp: gn
72          generator = 1
73          depfile = build.ninja.d
74
75        build build.ninja: phony build.ninja.stamp
76          generator = 1
77
78    """)
79
80    self.assertEqual(clobber.extract_gn_build_commands(self.build_ninja_path),
81                     expected_build_ninja_file_contents)
82
83  def test_unexpected_format(self):
84    # No "build build.ninja:" line should make it return an empty string.
85    build_ninja_file_contents = textwrap.dedent("""
86        ninja_required_version = 1.7.2
87
88        rule gn
89          command = ../../buildtools/gn --root=../.. -q --regeneration gen .
90          pool = console
91          description = Regenerating ninja files
92
93        subninja toolchain.ninja
94
95        build blink_python_tests: phony obj/blink_python_tests.stamp
96        build blink_tests: phony obj/blink_tests.stamp
97
98    """)
99    with open(self.build_ninja_path, 'w') as f:
100      f.write(build_ninja_file_contents)
101
102    self.assertEqual(clobber.extract_gn_build_commands(self.build_ninja_path),
103                     '')
104
105
106class TestDelete(unittest.TestCase):
107  def setUp(self):
108    self.build_dir = tempfile.mkdtemp()
109
110    pathlib.Path(os.path.join(self.build_dir, 'build.ninja')).touch()
111    pathlib.Path(os.path.join(self.build_dir, 'build.ninja.d')).touch()
112
113  def tearDown(self):
114    shutil.rmtree(self.build_dir)
115
116  def test_delete_build_dir_full(self):
117    # Create a dummy file in the build dir and ensure it gets removed.
118    dummy_file = os.path.join(self.build_dir, 'dummy')
119    pathlib.Path(dummy_file).touch()
120
121    clobber.delete_build_dir(self.build_dir)
122
123    self.assertFalse(os.path.exists(dummy_file))
124
125  def test_delete_build_dir_fail(self):
126    # Make delete_dir() throw to ensure it's handled gracefully.
127
128    with mock.patch('clobber._clean_dir', side_effect=OSError):
129      with self.assertRaises(OSError):
130        clobber.delete_build_dir(self.build_dir)
131
132  @unittest.skipIf(sys.platform == 'win32', 'Symlinks are not allowed on Windows by default')
133  def test_delete_build_dir_link(self):
134    with tempfile.TemporaryDirectory() as tmpdir:
135      # create a symlink.
136      build_dir = os.path.join(tmpdir, 'link')
137      os.symlink(self.build_dir, build_dir)
138
139      # create a dummy file.
140      dummy_file = os.path.join(build_dir, 'dummy')
141      pathlib.Path(dummy_file).touch()
142      clobber.delete_build_dir(build_dir)
143
144      self.assertFalse(os.path.exists(dummy_file))
145
146
147if __name__ == '__main__':
148  unittest.main()
149