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