# # Copyright (C) 2023 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. # """Common tools for end-to-end tests.""" import subprocess from pathlib import Path import pytest from .treebuilder import TreeBuilder THIS_DIR = Path(__file__).parent.resolve() EXTERNAL_UPDATER_DIR = THIS_DIR.parent.parent ANDROID_DIR = EXTERNAL_UPDATER_DIR.parent.parent def pytest_addoption(parser: pytest.Parser) -> None: """Add custom options to pytest.""" parser.addoption( "--build-updater", action="store_true", default=True, help=( "Build external_updater before running tests. This is the default behavior." ), ) parser.addoption( "--no-build-updater", action="store_false", dest="build_updater", help=( "Do not build external_updater before running tests. Only use this option " "if you've manually built external_updater. It will make test startup " "faster." ), ) @pytest.fixture(name="should_build_updater", scope="session") def should_build_updater_fixture(request: pytest.FixtureRequest) -> bool: """True if external_updater should be built before running tests.""" return request.config.getoption("--build-updater") # Session scope means that this fixture will only run the first time it's used. We don't # want to re-run soong for every test because it's horrendously slow to do so. @pytest.fixture(scope="session") def updater_cmd(should_build_updater: bool) -> list[str]: """The command to run for external_updater. The result is the prefix of the command that should be used with subprocess.run or similar. """ # Running updater.sh should be a more accurate test, but doing so isn't really # feasible with a no-op `m external_updater` taking ~10 seconds. Doing that would # add 10 seconds to every test. Build the updater once for the first thing that # requires it (that's the "session" scope above) and run the PAR directly. if should_build_updater: subprocess.run( [ ANDROID_DIR / "build/soong/soong_ui.bash", "--make-mode", "external_updater", ], check=True, ) return [str("external_updater")] @pytest.fixture(name="tree_builder") def tree_builder_fixture(tmp_path: Path) -> TreeBuilder: """Creates a TreeBuilder for making test repo trees.""" return TreeBuilder(tmp_path)