1*90c8c64dSAndroid Build Coastguard Worker# 2*90c8c64dSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project 3*90c8c64dSAndroid Build Coastguard Worker# 4*90c8c64dSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*90c8c64dSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*90c8c64dSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*90c8c64dSAndroid Build Coastguard Worker# 8*90c8c64dSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*90c8c64dSAndroid Build Coastguard Worker# 10*90c8c64dSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*90c8c64dSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*90c8c64dSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*90c8c64dSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*90c8c64dSAndroid Build Coastguard Worker# limitations under the License. 15*90c8c64dSAndroid Build Coastguard Worker# 16*90c8c64dSAndroid Build Coastguard Worker"""Tests for Soong APIs.""" 17*90c8c64dSAndroid Build Coastguard Workerimport contextlib 18*90c8c64dSAndroid Build Coastguard Workerimport os 19*90c8c64dSAndroid Build Coastguard Workerfrom pathlib import Path 20*90c8c64dSAndroid Build Coastguard Workerimport tempfile 21*90c8c64dSAndroid Build Coastguard Workerimport unittest 22*90c8c64dSAndroid Build Coastguard Workerimport unittest.mock 23*90c8c64dSAndroid Build Coastguard Worker 24*90c8c64dSAndroid Build Coastguard Workerfrom .soong import Soong 25*90c8c64dSAndroid Build Coastguard Worker 26*90c8c64dSAndroid Build Coastguard Worker 27*90c8c64dSAndroid Build Coastguard Workerif "ANDROID_BUILD_TOP" not in os.environ: 28*90c8c64dSAndroid Build Coastguard Worker raise RuntimeError( 29*90c8c64dSAndroid Build Coastguard Worker "Cannot run Soong tests without ANDROID_BUILD_TOP defined. Run lunch." 30*90c8c64dSAndroid Build Coastguard Worker ) 31*90c8c64dSAndroid Build Coastguard Worker 32*90c8c64dSAndroid Build Coastguard Worker 33*90c8c64dSAndroid Build Coastguard WorkerANDROID_BUILD_TOP = Path(os.environ["ANDROID_BUILD_TOP"]).resolve() 34*90c8c64dSAndroid Build Coastguard Worker 35*90c8c64dSAndroid Build Coastguard Worker 36*90c8c64dSAndroid Build Coastguard Workerclass SoongTest(unittest.TestCase): 37*90c8c64dSAndroid Build Coastguard Worker """Tests for the Soong executor.""" 38*90c8c64dSAndroid Build Coastguard Worker 39*90c8c64dSAndroid Build Coastguard Worker out_dir: Path 40*90c8c64dSAndroid Build Coastguard Worker 41*90c8c64dSAndroid Build Coastguard Worker def setUp(self) -> None: 42*90c8c64dSAndroid Build Coastguard Worker with contextlib.ExitStack() as stack: 43*90c8c64dSAndroid Build Coastguard Worker self.out_dir = Path(stack.enter_context(tempfile.TemporaryDirectory())) 44*90c8c64dSAndroid Build Coastguard Worker self.addCleanup(stack.pop_all().close) 45*90c8c64dSAndroid Build Coastguard Worker 46*90c8c64dSAndroid Build Coastguard Worker def test_finds_soong_ui(self) -> None: 47*90c8c64dSAndroid Build Coastguard Worker """Tests that soong_ui.bash is found correctly.""" 48*90c8c64dSAndroid Build Coastguard Worker soong = Soong(ANDROID_BUILD_TOP, self.out_dir) 49*90c8c64dSAndroid Build Coastguard Worker self.assertTrue(soong.soong_ui_path.exists()) 50*90c8c64dSAndroid Build Coastguard Worker self.assertEqual("soong_ui.bash", soong.soong_ui_path.name) 51*90c8c64dSAndroid Build Coastguard Worker 52*90c8c64dSAndroid Build Coastguard Worker def test_get_build_var(self) -> None: 53*90c8c64dSAndroid Build Coastguard Worker """Tests that we can read build variables from Soong.""" 54*90c8c64dSAndroid Build Coastguard Worker soong = Soong(ANDROID_BUILD_TOP, self.out_dir) 55*90c8c64dSAndroid Build Coastguard Worker old_product = os.environ["TARGET_PRODUCT"] 56*90c8c64dSAndroid Build Coastguard Worker try: 57*90c8c64dSAndroid Build Coastguard Worker # Clear the lunched target out of the test environment for a 58*90c8c64dSAndroid Build Coastguard Worker # consistent result. 59*90c8c64dSAndroid Build Coastguard Worker del os.environ["TARGET_PRODUCT"] 60*90c8c64dSAndroid Build Coastguard Worker self.assertEqual("generic", soong.get_make_var("TARGET_DEVICE")) 61*90c8c64dSAndroid Build Coastguard Worker finally: 62*90c8c64dSAndroid Build Coastguard Worker os.environ["TARGET_PRODUCT"] = old_product 63*90c8c64dSAndroid Build Coastguard Worker 64*90c8c64dSAndroid Build Coastguard Worker def test_clean(self) -> None: 65*90c8c64dSAndroid Build Coastguard Worker """Tests that clean works.""" 66*90c8c64dSAndroid Build Coastguard Worker soong = Soong(ANDROID_BUILD_TOP, self.out_dir) 67*90c8c64dSAndroid Build Coastguard Worker self.assertTrue(self.out_dir.exists()) 68*90c8c64dSAndroid Build Coastguard Worker soong.clean() 69*90c8c64dSAndroid Build Coastguard Worker self.assertFalse(self.out_dir.exists()) 70*90c8c64dSAndroid Build Coastguard Worker soong.clean() 71*90c8c64dSAndroid Build Coastguard Worker self.assertFalse(self.out_dir.exists()) 72*90c8c64dSAndroid Build Coastguard Worker 73*90c8c64dSAndroid Build Coastguard Worker def test_build(self) -> None: 74*90c8c64dSAndroid Build Coastguard Worker """Tests that build invokes the correct command. 75*90c8c64dSAndroid Build Coastguard Worker 76*90c8c64dSAndroid Build Coastguard Worker Does not actually test a build, as there aren't any good options for short 77*90c8c64dSAndroid Build Coastguard Worker builds in the tree, so instead tests that soong_ui is called the way we expect 78*90c8c64dSAndroid Build Coastguard Worker it to be. 79*90c8c64dSAndroid Build Coastguard Worker """ 80*90c8c64dSAndroid Build Coastguard Worker soong = Soong(ANDROID_BUILD_TOP, self.out_dir) 81*90c8c64dSAndroid Build Coastguard Worker with unittest.mock.patch.object(soong, "soong_ui") as soong_ui: 82*90c8c64dSAndroid Build Coastguard Worker soong.build(["foo"]) 83*90c8c64dSAndroid Build Coastguard Worker soong_ui.assert_called_with( 84*90c8c64dSAndroid Build Coastguard Worker ["--make-mode", "--soong-only", "foo"], env=None 85*90c8c64dSAndroid Build Coastguard Worker ) 86*90c8c64dSAndroid Build Coastguard Worker 87*90c8c64dSAndroid Build Coastguard Worker def test_build_creates_out_dir(self) -> None: 88*90c8c64dSAndroid Build Coastguard Worker """Tests that build creates the out directory if necessary.""" 89*90c8c64dSAndroid Build Coastguard Worker soong = Soong(ANDROID_BUILD_TOP, self.out_dir) 90*90c8c64dSAndroid Build Coastguard Worker soong.clean() 91*90c8c64dSAndroid Build Coastguard Worker with unittest.mock.patch.object(soong, "soong_ui"): 92*90c8c64dSAndroid Build Coastguard Worker soong.build([]) 93*90c8c64dSAndroid Build Coastguard Worker self.assertTrue(self.out_dir.exists()) 94