blob: e079f8d980c7eeebb43862679a086163f8e0a55f [file] [log] [blame]
# Copyright 2026 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Utility functions for working with Bazel test targets."""
import json
import os
import sys
import typing as T
from pathlib import Path
_SCRIPT_DIR = Path(__file__).parent
sys.path.append(str(_SCRIPT_DIR))
import build_utils
from build_utils import BazelLauncher, BazelPaths
def generate_tests_json(
bazel_paths: BazelPaths,
command_runner: T.Optional[build_utils.CommandRunner] = None,
) -> tuple[dict[str, T.Any], set[Path]]:
"""Generate a tests.json file corresponding to all Bazel host test targets
Args:
bazel_paths: The BazelPaths object to use for path resolution.
command_runner: An optional CommandRunner instance.
Returns:
A pair of two values which are:
- A list of dictionaries, describing each Bazel host_test() reachable
from the root_host_targets, according to the tests.json schema.
- A set of input paths, whose changes would require a regeneration of
the tests.json file.
"""
if not command_runner:
command_runner = build_utils.CommandRunner()
bazel_launcher = BazelLauncher(bazel_paths.launcher, runner=command_runner)
starlark_input = _SCRIPT_DIR / "../starlark/FuchsiaHostTestInfo.cquery"
ret = bazel_launcher.run_query(
"cquery",
[
"--config=host",
"--output=starlark",
f"--starlark:file={starlark_input}",
"deps(//build/bazel/host_tests)",
],
False,
)
if ret.returncode != 0:
raise RuntimeError(f"Failed to run bazel query: {ret.stderr}")
def make_execroot_path_relative_to_ninja_build_dir(path: str) -> str:
"""Convert a path relative to the Bazel execroot to a path relative to the Ninja build directory."""
return os.path.relpath(
bazel_paths.execroot / path, bazel_paths.ninja_build_dir
)
tests_json: list[dict[str, T.Any]] = []
for line in ret.stdout.splitlines():
line = line.strip()
if not line:
continue
# The line if a JSON-encoded object that follows the tests.json schema with
# the following exceptions:
# - The 'bazel_execroot_path' and 'bazel_execroot_runtime_deps_path' fields
# are present instead of 'path' and 'runtime_deps_path', and they contain
# paths relative to the Bazel execroot instead of the Ninja build directory.
cquery_test = json.loads(line)
# LINT.IfChange(cquery_output_schema)
tests_json.append(
{
"environments": [],
"expects_ssh": False,
"test": {
"name": cquery_test["name"],
"label": cquery_test["label"],
"source_label": cquery_test["source_label"],
"path": make_execroot_path_relative_to_ninja_build_dir(
cquery_test["launcher_execroot_path"]
),
"runtime_deps": make_execroot_path_relative_to_ninja_build_dir(
cquery_test["runtime_deps_json_execroot_path"]
),
"os": cquery_test["os"],
"cpu": cquery_test["cpu"],
},
}
)
# LINT.ThenChange(//build/bazel/starlark/FuchsiaHostTestInfo.cquery:cquery_output_schema)
return tests_json, {starlark_input}