# 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("fuchsia_component.gni")
import("fuchsia_test_component_manifest.gni")

# Defines a component that launches a test.
# See: https://fuchsia.dev/fuchsia-src/development/components/build
#
# This template is a useful shortcut for defining classic unit tests for target
# devices, but (unlike fuchsia_unittest_package) where you have multiple test
# targets and want to bundle them in a single test package.
# Pure unit tests don't require any special capabilities, so their component
# manifest can be generated by the template if a manifest is not specified.
#
# Example:
# ```
# executable("rot13_encoder_test") {
#   sources = [ "rot13_encoder_test.cc" ]
#   testonly = true
# }
#
# fuchsia_unittest_component("rot13-encoder-test") {
#   deps = [ ":rot13_encoder_decoder_test" ]
# }
#
# executable("rot13_decoder_test") {
#   sources = [ "rot13_decoder_test.cc" ]
#   testonly = true
# }
#
# fuchsia_unittest_component("rot13-decoder-test") {
#   deps = [ ":rot13_decoder_test" ]
# }
#
# fuchsia_test_package("rot13-tests") {
#   test_components = [
#     ":rot13-encoder-test",
#     ":rot13-decoder-test",
#   ]
# }
# ```
#
# The above will generate a manifest for each test and include both components in a single package,
# which can be run with the launch URLs:
# fuchsia-pkg://fuchsia.com/rot13-tests#meta/rot13-encoder-test.cmx
# fuchsia-pkg://fuchsia.com/rot13-tests#meta/rot13-decoder-test.cmx
#
# Parameters
#
#   manifest (optional)
#     Specify a component manifest for the test.
#     If a manifest is not specified, a trivial manifest will be generated.
#     The generated manifest requests no special capabilities, which is good
#     enough for "pure" unit tests.
#     To view the generated manifest, see:
#     `fx gn outputs out/default path/to/your:<target_name>_generated_manifest`
#     Type: path
#
#   component_name (optional)
#     The name of the component.
#     Type: string
#     Default: target_name
#
#   v2 (optional)
#     If specified and set to false, will generate a CFv1 (.cmx) manifest.
#     If `manifest` is specified then this is ignored.
#     Type: boolean
#
#   restricted_features (optional)
#     The set of restricted CML features to allow. Only applicable to v2 components.
#     The set of features is allowlisted here: //tools/cmc/build/restricted_features/BUILD.gn
#     where each feature name is represented by a group of the same name.
#     Type: list of strings
#     Default: []
#
#   deprecated_legacy_test_execution (optional)
#     If set for a v2 test, the test will be forced to use ELF runner,
#     which sacrifices isolation for higher performance.
#     Type: boolean
#
#   deps
#   visibility
template("fuchsia_unittest_component") {
  if (current_toolchain == default_toolchain) {
    assert(
        !(defined(invoker.deprecated_legacy_test_execution) &&
              invoker.deprecated_legacy_test_execution &&
              (defined(invoker.manifest) ||
                   (defined(invoker.v2) && !invoker.v2))),
        "cannot specify both deprecated_legacy_test_execution with either v2 = false or an explicit manifest")
    if (!defined(invoker.manifest)) {
      generated_target = "${target_name}_generated_manifest"
      fuchsia_test_component_manifest(generated_target) {
        forward_variables_from(invoker,
                               [
                                 "deps",
                                 "v2",
                               ])
        visibility = [ ":*" ]
      }
      manifest = get_target_outputs(":$generated_target")
      manifest = manifest[0]
    }

    fuchsia_component(target_name) {
      forward_variables_from(invoker,
                             [
                               "deps",
                               "manifest",
                               "restricted_features",
                               "visibility",
                             ])
      if (defined(invoker.deprecated_legacy_test_execution) &&
          invoker.deprecated_legacy_test_execution) {
        experimental_force_runner = "elf_test_runner"
      }
      component_name = target_name
      if (defined(invoker.component_name)) {
        component_name = invoker.component_name
      }
      testonly = true

      if (defined(generated_target)) {
        if (!defined(deps)) {
          deps = []
        }
        deps += [ ":$generated_target" ]
      }
    }
  } else {
    group(target_name) {
      testonly = true
      deps = [ ":$target_name($default_toolchain)" ]
    }
    not_needed(invoker, "*")
  }
}
