blob: 7ca1e02c21b98da11729c77784a5547a059ba23b [file] [log] [blame]
# Copyright 2023 The Fuchsia Authors.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/components.gni")
import("//src/lib/testing/expectation/preprocess/preprocess.gni")
import("//tools/cmc/build/expect_includes.gni")
# Defines a fuchsia_test_component with an expectations file for this test.
#
# Parameters
# expectations (optional)
# Path to a JSON5 test expectations file. See
# //src/lib/testing/expectation/example_expectations.json5 for an example of
# the format. Either expectations or generated_expectations is required.
# Type: path
#
# generated_expectations (optional)
# Name of the generated_expectations_file target that generates expectation file. Either
# expectations or generated_expectations is required.
# Type: target name
#
# manifest (required)
# The component manifest.
# Type: path
#
# treatment_of_cases_with_error_logs (optional)
# Identifies how test cases that are expected to generate error logs
# should be run.
# Type: string
# Options:
# - "SKIP_CASES_WITH_ERROR_LOGS" indicates that tests expected to
# generate error logs should be skipped.
# - "RUN_ONLY_CASES_WITH_ERROR_LOGS" indicates that only those tests
# expected to generate error logs should be run.
# - By default, all test cases will be run.
#
# All others - same as fuchsia_test_component.
template("fuchsia_test_component_with_expectations") {
assert(defined(invoker.manifest), "Must define path to manifest file.")
_test_component_name = target_name
_skip_err_logs_cases = "SKIP_CASES_WITH_ERROR_LOGS"
_run_err_logs_cases = "RUN_ONLY_CASES_WITH_ERROR_LOGS"
not_needed([
_skip_err_logs_cases,
_run_err_logs_cases,
])
_expectations_target = "${target_name}_preprocessed_expectations"
preprocess_expectations(_expectations_target) {
if (defined(invoker.generated_expectations)) {
assert(!defined(invoker.expectations))
deps = [ invoker.generated_expectations ]
expectations =
get_label_info(invoker.generated_expectations, "target_gen_dir") +
"/" + get_label_info(invoker.generated_expectations, "name") +
".json5"
} else {
assert(defined(invoker.expectations),
"Must define path to expectations file.")
expectations = invoker.expectations
}
if (defined(invoker.treatment_of_cases_with_error_logs)) {
assert(
invoker.treatment_of_cases_with_error_logs == _skip_err_logs_cases ||
invoker.treatment_of_cases_with_error_logs == _run_err_logs_cases)
if (invoker.treatment_of_cases_with_error_logs == _skip_err_logs_cases) {
cases_to_run = "NoErrLogs"
} else {
cases_to_run = "WithErrLogs"
}
}
output_path =
"data/tests/expectations/${_test_component_name}/expectations.json5"
}
_expectations_offer_cml_shard_target = "${target_name}_offer_cml_shard"
_expectations_offer_cml_shard_file =
"${target_gen_dir}/${_test_component_name}_expectations_offer.shard.cml"
generated_file(_expectations_offer_cml_shard_target) {
contents = {
offer = [
{
directory = "pkg"
from = "framework"
as = "expectations"
to = "#expectation-comparer"
subdir = "data/tests/expectations/${_test_component_name}"
},
]
}
outputs = [ _expectations_offer_cml_shard_file ]
output_conversion = "json"
}
_merged_cml_target = "${target_name}_merged_cml"
_merged_cml_file_name = "${_test_component_name}_merged.cml"
cmc_merge(_merged_cml_target) {
testonly = true
deps = [ ":${_expectations_offer_cml_shard_target}" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
sources = [
_expectations_offer_cml_shard_file,
invoker.manifest,
]
output_name = _merged_cml_file_name
}
_cmc_merge_outputs = get_target_outputs(":${_merged_cml_target}")
_merged_cml_file = _cmc_merge_outputs[0]
# We want to ensure that the manifest of the component built by this
# `fuchsia_test_component_with_expectations` invocation includes the
# expectation-comparer client shard. In order to validate this at build-time,
# we'll wire up a `cmc_check_includes` invocation providing:
# (a) The manifest that needs to be checked (this component's manifest)
# (b) The shard expected to be included (the expectation client shard)
# Part (a): the manifest that needs to be checked. `cmc_check_includes`
# expects to receive this in the form of a JSON file consisting of an
# array with a single element, where that element is the path to the CML file
# to check.
#
# i.e. the JSON file's contents look like:
# ```
# ["src/foo/bar/meta/test_component.cml"]
# ```
#
# Thus, the following generates a JSON file of that format.
_manifest_json_singleton_target = "${target_name}_manifest_json_singleton"
generated_file(_manifest_json_singleton_target) {
testonly = true
outputs = [ "$target_out_dir/$_manifest_json_singleton_target.json" ]
output_conversion = "json"
contents = [ rebase_path(invoker.manifest, root_build_dir) ]
visibility = [ ":*" ]
deps = []
if (defined(invoker.deps)) {
deps += invoker.deps
}
}
_manifest_json_singleton_target = ":$_manifest_json_singleton_target"
# Part (b): the shard expected to be included. This is specified to
# `cmc_check_includes` by having the `cmc_check_includes` invocation dep on
# a target whose metadata specifies the `cmc_expected_includes_cml` like so:
_expected_includes_metadata_target = "${target_name}-expected-includes"
group(_expected_includes_metadata_target) {
metadata = {
cmc_expected_includes_cml =
[ "//src/lib/testing/expectation/meta/common.shard.cml" ]
}
}
_expected_includes_metadata_target = ":$_expected_includes_metadata_target"
# Finally, the actual `cmc_check_includes` invocation. Building this target
# will fail if `invoker.manifest` does not include the expectation client
# shard.
_include_check_target = "${target_name}-check-includes"
cmc_check_includes(_include_check_target) {
testonly = true
_json_singleton_outputs =
get_target_outputs(_manifest_json_singleton_target)
manifest = _json_singleton_outputs[0]
deps = [
_expected_includes_metadata_target,
_manifest_json_singleton_target,
]
visibility = [ ":*" ]
}
_include_check_target = ":$_include_check_target"
fuchsia_test_component(target_name) {
forward_variables_from(invoker,
"*",
[
"deps",
"manifest",
])
deps = [
":${_expectations_target}",
":${_merged_cml_target}",
"//src/lib/testing/expectation:expectation_comparer",
_include_check_target,
]
manifest = _merged_cml_file
if (defined(invoker.deps)) {
deps += invoker.deps
}
}
}