blob: 465dc6399e70e10ba00d1b60fa152bf52f3225a6 [file] [log] [blame]
# Copyright 2020 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.
import("//build/compiled_action.gni")
import("//build/testing/test_spec.gni")
import("fuchsia_package.gni")
import("fuchsia_test_component.gni")
import("fuchsia_test_component_manifest.gni")
_log_severity_allowed_val = [
"FATAL",
"ERROR",
"WARN",
"INFO",
"DEBUG",
"TRACE",
]
# Defines a Fuchsia package that contains one or more components, some of which
# implement one or more tests, and specifies how to run tests.
# See: https://fuchsia.dev/fuchsia-src/development/components/build
#
# Example:
# ```
# fuchsia_component("fonts-service") { ... }
# fuchsia_component("fonts-service-test") {
# testonly = true
# ...
# }
#
# fuchsia_test_package("fonts-service-test-package") {
# test_components = [ ":fonts-service-test" ]
# deps = [ ":fonts-service" ],
# }
#
# fuchsia_component("fonts-ui") { ... }
# fuchsia_component("fonts-ui-test") {
# testonly = true
# ...
# }
#
# fuchsia_test_package("fonts-ui-test-package") {
# test_components = [ ":fonts-ui-test" ]
# deps = [ ":fonts-ui" ],
# test_specs = {
# environments = [
# astro_env,
# sherlock_env,
# ]
# }
# }
#
# fuchsia_package("fonts-ui-package") {
# deps = [ ":fonts-ui" ],
# }
#
# # Defining dependencies via subpackages:
# fuchsia_test_package("fonts-ui-test-with-subpackage") {
# test_components = [ ":fonts-ui-test" ]
# subpackages = [ ":fonts-ui-package" ],
# test_specs = {
# environments = [
# astro_env,
# sherlock_env,
# ]
# }
# }
# ```
#
# Parameters
#
# test_components (required)
# `fuchsia_component()` targets to include in the package and also register
# as entry points for tests.
# Additional non-test components can be included via `deps`.
# Type: list(labels)
#
# test_specs (optional)
# Additional test specifications to apply to tests defined above.
# See `test_spec.gni`.
# Type: scope
#
# package_name (optional)
# The name of the package.
# Type: string
# Default: target_name
#
# renameable_subpackages (optional)
# A list of subpackages defined by scoped variables `package` (a
# `fuchsia_package()` target) and an optional `name`. See
# `fuchsia_package()` for more details.
# Type: list of scopes
#
# subpackages (optional)
# A list of `fuchsia_package` targets. See `fuchsia_package()` for more
# details.
# Type: list of targets
#
# package_deps (optional)
# A list of `fuchsia_package` targets that are not subpackages but needed
# by the test at runtime. This will get forwarded to the test_spec. See
# //build/testing/test_spec.gni for more details. If using this instead of
# `subpackages`, please add a comment explaining why.
# Type: list of targets
#
# is_bootfs (optional)
# ONLY to be used by |fuchsia_bootfs_test_package| to indicate a bootfs based package.
#
# data_deps
# deps
# visibility
template("fuchsia_test_package") {
if (current_toolchain == default_toolchain) {
assert(
defined(invoker.test_components) && invoker.test_components != [],
"`test_components` must be specified when calling fuchsia_test_package($target_name)")
package_name = target_name
package_label = get_label_info(":$target_name", "label_with_toolchain")
package_manifest =
rebase_path("$target_out_dir/$target_name/package_manifest.json",
root_build_dir)
if (defined(invoker.package_name)) {
package_name = invoker.package_name
}
test_specs = {
}
if (defined(invoker.test_specs)) {
test_specs = invoker.test_specs
}
if (defined(invoker.is_bootfs) && invoker.is_bootfs) {
test_specs.build_rule = "fuchsia_bootfs_test_package"
test_specs.expects_ssh = false
}
# test packages won't be configured by assembly tools, so we can check their config earlier
_validate_structured_config = true
if (defined(invoker.validate_structured_config)) {
_validate_structured_config = invoker.validate_structured_config
}
# While ffx is not listed as a dependency here, it is required for running this target
# test. It is not included as a dependency, because doing so would push the the scheduling
# of the test target creation steps to after the compilation of ffx, which would slow the
# build significantly. ffx is ambiently available when these tests are run and is listed
# as a dependency in //bundles/infra/test:host_tools.
host_test_component_target =
"//src/developer/ffx:suite_test_data($host_toolchain)"
host_tool_dir = get_label_info(host_test_component_target, "root_out_dir")
host_executable = "$host_tool_dir/ffx"
host_executable_rebased = rebase_path(host_executable, root_build_dir)
test_pilot_target = "//tools/test_pilot:test_deps($host_toolchain)"
test_pilot_dir = get_label_info(test_pilot_target, "root_out_dir")
test_pilot_executable = "$test_pilot_dir/test-pilot"
test_pilot_executable_rebased =
"./" + rebase_path(test_pilot_executable, root_build_dir)
test_deps = []
foreach(test, invoker.test_components) {
test_target_name = get_label_info(test, "name")
component_label = get_label_info(test, "label_with_toolchain")
test_target = "${target_name}_test_" + test_target_name
manifest_path = []
manifest_path = get_target_outputs(test)
manifest_name = get_path_info(manifest_path[0], "file")
if (defined(invoker.is_bootfs) && invoker.is_bootfs) {
test_url = "fuchsia-boot:///$package_name#meta/$manifest_name"
} else {
test_url = "fuchsia-pkg://fuchsia.com/$package_name#meta/$manifest_name"
}
_max_severity_logs = "WARN"
if (defined(test_specs.log_settings)) {
_log_settings = {
}
_log_settings = test_specs.log_settings
if (defined(_log_settings.max_severity)) {
assert(
_log_severity_allowed_val + [ _log_settings.max_severity ] -
[ _log_settings.max_severity ] != _log_severity_allowed_val,
"Invalid 'log_settings.max_severity': ${_log_settings.max_severity}, valid values are ${_log_severity_allowed_val}")
_max_severity_logs = _log_settings.max_severity
}
if (defined(_log_settings.min_severity)) {
assert(
_log_severity_allowed_val + [ _log_settings.min_severity ] -
[ _log_settings.min_severity ] != _log_severity_allowed_val,
"Invalid 'log_settings.min_severity': ${_log_settings.min_severity}, valid values are ${_log_severity_allowed_val}")
_min_severity_logs = _log_settings.min_severity
}
}
_test_config = {
}
_test_config = {
host_test_binary = host_executable_rebased
host_test_args = [
"--log-output",
"{output_directory}/test/ffx.log",
"--strict",
"--config",
"ffx.subtool-search-paths=host_${host_cpu}",
"--config",
"log.dir={output_directory}/test/ffx_logs",
"--config",
"ssh.priv={ssh_private_key_path}",
"--config",
"{ffx_config}",
"--machine",
"raw",
"--target",
"{target}",
"test",
"run",
"--pilot",
"{test_config_file}",
"--filter-ansi",
]
require = [
"target",
"ssh_private_key_path",
]
# TODO(https://fxbug.dev/327640651): Add common tags for the test.
target_test_url = test_url
if (defined(test_specs.parallel)) {
parallel = test_specs.parallel
}
max_severity_logs = _max_severity_logs
if (defined(_min_severity_logs)) {
min_severity_logs = _min_severity_logs
}
ffx_config = "{}"
}
test_component_output_label =
"$package_name.$manifest_name.test_component_config"
test_component_output =
"$root_out_dir/test_configs_partial/$test_component_output_label.json"
generated_file(test_component_output_label) {
testonly = true
data_keys = [ "test_components" ]
walk_keys = [ "test_components_barrier" ]
outputs = [ test_component_output ]
output_conversion = "json"
deps = [ test ]
visibility = [ ":*" ]
}
config_file_label = "$package_name.$manifest_name.test_config_partial"
output_config =
"$root_out_dir/test_configs_partial/$config_file_label.json"
generated_file(config_file_label) {
outputs = [ output_config ]
contents = _test_config
output_conversion = "json"
}
final_test_config_name = "$package_name.$manifest_name.test_config"
final_output_config_path =
"$root_out_dir/test_configs/$final_test_config_name.json"
script_output_path =
"${root_out_dir}/${package_name}_${manifest_name}_test.sh"
script_output_path_rebased =
rebase_path(script_output_path, root_build_dir)
final_output_config_path_rebased =
rebase_path(final_output_config_path, root_build_dir)
compiled_action("${test_target}_script_gen") {
testonly = true
tool = "//build/components:test_component_host_helper"
outputs = [
script_output_path,
final_output_config_path,
]
args = [
"--test-pilot",
test_pilot_executable_rebased,
"--component-manifest-path",
rebase_path(manifest_path[0], root_build_dir),
"--partial-test-config",
rebase_path(output_config, root_build_dir),
"--test-component-config",
rebase_path(test_component_output, root_build_dir),
"--script-output-filename",
script_output_path_rebased,
"--test-config-output-filename",
final_output_config_path_rebased,
]
inputs = [
test_component_output,
output_config,
manifest_path[0],
]
deps = [
":$config_file_label",
":$test_component_output_label",
test,
]
}
script_outputs = []
script_outputs = get_target_outputs(":${test_target}_script_gen")
group("${test_target}_runtime_deps_group") {
testonly = true
data_deps = [
":${test_target}_script_gen",
test_pilot_target,
]
metadata = {
test_runtime_deps = script_outputs
# avoid adding unintended entries to the test package due to
# dependency on ffx.
distribution_entries_barrier = []
}
}
test_spec(test_target) {
forward_variables_from(test_specs, "*")
forward_variables_from(invoker, [ "package_deps" ])
if (!defined(build_rule)) {
build_rule = "fuchsia_test_package"
}
target = get_label_info(package_label, "label_with_toolchain")
package_label = package_label
component_label = component_label
package_manifests = [ package_manifest ]
package_url = test_url
# Adding new_path for transition period. We will later replace this with path.
new_path = script_outputs[0]
if (!defined(data_deps)) {
data_deps = []
}
data_deps += [ ":${test_target}_runtime_deps_group" ]
}
test_deps += [ ":$test_target" ]
}
fuchsia_package(target_name) {
forward_variables_from(invoker,
[
"data_deps",
"deps",
"disable_elf_binaries_checks",
"metadata",
"package_deps",
"visibility",
])
package_name = package_name
if (!defined(deps)) {
deps = []
}
deps += invoker.test_components
deps += test_deps
testonly = true
if (!defined(invoker.metadata)) {
metadata = {
}
}
metadata.test_components_barrier = invoker.test_components
# Pass subpackages through a different parameter than the documented one,
# so that the fuchsia_package() can identify these as from a test package.
# This is only for allow-list enforcement
if (defined(invoker.subpackages)) {
test_pkg__subpackages = invoker.subpackages
}
if (defined(invoker.renameable_subpackages)) {
test_pkg__renameable_subpackages = invoker.renameable_subpackages
}
validate_structured_config = _validate_structured_config
}
} else {
group(target_name) {
testonly = true
forward_variables_from(invoker, [ "visibility" ])
deps = [ ":$target_name($default_toolchain)" ]
}
not_needed(invoker, "*")
}
}
# Identical to |fuchsia_test_package| with the exceptions that:
# - The generated url will be a bootfs "fuchsia-boot:///" url.
# - The 'build_rule' in the test specs metadata will be "fuchsia_bootfs_test_package".
# - The 'expects_ssh' field in the test specs metadata is set to false.
template("fuchsia_bootfs_test_package") {
fuchsia_test_package(target_name) {
forward_variables_from(invoker, "*")
is_bootfs = true
}
}