# # Copyright (C) 2021 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # """Tests for Soong APIs.""" import contextlib import os from pathlib import Path import tempfile import unittest import unittest.mock from .soong import Soong if "ANDROID_BUILD_TOP" not in os.environ: raise RuntimeError( "Cannot run Soong tests without ANDROID_BUILD_TOP defined. Run lunch." ) ANDROID_BUILD_TOP = Path(os.environ["ANDROID_BUILD_TOP"]).resolve() class SoongTest(unittest.TestCase): """Tests for the Soong executor.""" out_dir: Path def setUp(self) -> None: with contextlib.ExitStack() as stack: self.out_dir = Path(stack.enter_context(tempfile.TemporaryDirectory())) self.addCleanup(stack.pop_all().close) def test_finds_soong_ui(self) -> None: """Tests that soong_ui.bash is found correctly.""" soong = Soong(ANDROID_BUILD_TOP, self.out_dir) self.assertTrue(soong.soong_ui_path.exists()) self.assertEqual("soong_ui.bash", soong.soong_ui_path.name) def test_get_build_var(self) -> None: """Tests that we can read build variables from Soong.""" soong = Soong(ANDROID_BUILD_TOP, self.out_dir) old_product = os.environ["TARGET_PRODUCT"] try: # Clear the lunched target out of the test environment for a # consistent result. del os.environ["TARGET_PRODUCT"] self.assertEqual("generic", soong.get_make_var("TARGET_DEVICE")) finally: os.environ["TARGET_PRODUCT"] = old_product def test_clean(self) -> None: """Tests that clean works.""" soong = Soong(ANDROID_BUILD_TOP, self.out_dir) self.assertTrue(self.out_dir.exists()) soong.clean() self.assertFalse(self.out_dir.exists()) soong.clean() self.assertFalse(self.out_dir.exists()) def test_build(self) -> None: """Tests that build invokes the correct command. Does not actually test a build, as there aren't any good options for short builds in the tree, so instead tests that soong_ui is called the way we expect it to be. """ soong = Soong(ANDROID_BUILD_TOP, self.out_dir) with unittest.mock.patch.object(soong, "soong_ui") as soong_ui: soong.build(["foo"]) soong_ui.assert_called_with( ["--make-mode", "--soong-only", "foo"], env=None ) def test_build_creates_out_dir(self) -> None: """Tests that build creates the out directory if necessary.""" soong = Soong(ANDROID_BUILD_TOP, self.out_dir) soong.clean() with unittest.mock.patch.object(soong, "soong_ui"): soong.build([]) self.assertTrue(self.out_dir.exists())