• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# Copyright (C) 2023 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16"""Common tools for end-to-end tests."""
17import subprocess
18from pathlib import Path
19
20import pytest
21
22from .treebuilder import TreeBuilder
23
24THIS_DIR = Path(__file__).parent.resolve()
25EXTERNAL_UPDATER_DIR = THIS_DIR.parent.parent
26ANDROID_DIR = EXTERNAL_UPDATER_DIR.parent.parent
27
28
29def pytest_addoption(parser: pytest.Parser) -> None:
30    """Add custom options to pytest."""
31    parser.addoption(
32        "--build-updater",
33        action="store_true",
34        default=True,
35        help=(
36            "Build external_updater before running tests. This is the default behavior."
37        ),
38    )
39    parser.addoption(
40        "--no-build-updater",
41        action="store_false",
42        dest="build_updater",
43        help=(
44            "Do not build external_updater before running tests. Only use this option "
45            "if you've manually built external_updater. It will make test startup "
46            "faster."
47        ),
48    )
49
50
51@pytest.fixture(name="should_build_updater", scope="session")
52def should_build_updater_fixture(request: pytest.FixtureRequest) -> bool:
53    """True if external_updater should be built before running tests."""
54    return request.config.getoption("--build-updater")
55
56
57# Session scope means that this fixture will only run the first time it's used. We don't
58# want to re-run soong for every test because it's horrendously slow to do so.
59@pytest.fixture(scope="session")
60def updater_cmd(should_build_updater: bool) -> list[str]:
61    """The command to run for external_updater.
62
63    The result is the prefix of the command that should be used with subprocess.run or
64    similar.
65    """
66    # Running updater.sh should be a more accurate test, but doing so isn't really
67    # feasible with a no-op `m external_updater` taking ~10 seconds. Doing that would
68    # add 10 seconds to every test. Build the updater once for the first thing that
69    # requires it (that's the "session" scope above) and run the PAR directly.
70    if should_build_updater:
71        subprocess.run(
72            [
73                ANDROID_DIR / "build/soong/soong_ui.bash",
74                "--make-mode",
75                "external_updater",
76            ],
77            check=True,
78        )
79    return [str("external_updater")]
80
81
82@pytest.fixture(name="tree_builder")
83def tree_builder_fixture(tmp_path: Path) -> TreeBuilder:
84    """Creates a TreeBuilder for making test repo trees."""
85    return TreeBuilder(tmp_path)
86