blob: ecb084302b0a5365f9f7653c07c14bcbf1736a0a [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file contains templates which are meant to simplify building and
# running test binaries with the Chromecast build infrastructure. See
# documentation above each template for specific use.
#
# Example Usage
#
# # This is a standard test() template from //testing/test.gni. This generates
# # a binary called foo_unittests.
# test("foo_unittests") {
# sources = [ "foo_unittest.cc" ]
#
# deps = [
# ":foo",
# "//testing/gtest",
# "//testing/gmock",
# ]
# }
#
# # And another standard test() target, which generates bar_unittests
# test("bar_unittests") {
# sources = [ "bar_unittest.cc" ]
#
# deps = [ ... ]
# }
#
# # This is an organizational target. This cannot be built directly.
# cast_test_group("cast_tests") {
# tests = [
# ":bar_unittests",
# "//path/to:foo_unittests",
# ]
# }
#
# # Here is another cast_test_group target which builds a bunch of other
# # test binaries, and wants to apply some filters.
# cast_test_group("external_tests") {
# tests = [
# "//path/to/widget:widget_unittests",
# "//even/more/foo:foo_unittests",
# ]
#
# filters = [
# "widget_unittests --gtest_filter=-WidgetTest.TestToBeFiltered",
# ]
# }
#
# # Build this to create build and run lists for bar and foo tests.
# cast_test_group_list("cast_test_lists") {
# test_groups = [
# ":cast_tests",
# ":external_tests",
# ]
#
# build_list_paths = "$root_out_dir/path/to/test/build_list.txt"
#
# run_list_path = "$root_out_dir/path/to/list/run_list.txt"
# }
import("//testing/test.gni")
# Do not allow mixing of gtests and junit tests. All gtests must go into one
# directory, while all junit tests must go into another directory.
_gtest_gen_dir = "$root_gen_dir/chromecast/tests"
_junit_gen_dir = "$root_gen_dir/chromecast/junit"
# A group of test executables. Including test targets in this group makes it
# possible for Chromecast build infrastructure to build and run them with
# filters. To accomplish this, it defines two actions, one which generates a
# build list of all |tests|, and one which generates a run list of all |tests|.
# It also creates a group with dependencies on each test, to ensure that they
# are valid targets. Do not build these targets. Build cast_test_group_list
# instead.
#
# Parameters
# tests (required)
# A list of test targets included in the assembly. Do not include any
# other type of target. Each target's name must match the name of the
# executable it builds.
#
# filters (optional)
# A list of strings of format: "<test_name> --gtest_filter=<filter_logic>"
# The <test_name> used must correspond to a test in |tests|. Please see
# //chromecast/tools/build/generate_test_lists.py for more information.
# If this is not defined, no filters are applied.
#
# priority (optional)
# A string which takes any single-digit integer bewtween "1" and "9",
# inclusive. Assign this to prioritize filters applied by other
# cast_test_groups, where a higher number trumps a lower number.
# If not assigned, priority defaults to "1", the lowest priority.
#
# test_type (optional)
# A string, which must be either "junit" or "gtest". If not defined,
# defaults to "gtest".
#
template("cast_test_group") {
assert(defined(invoker.tests),
"$target_name needs 'tests' listing the test() targets")
_test_type = "gtest"
if (defined(invoker.test_type)) {
assert(invoker.test_type == "gtest" || invoker.test_type == "junit")
_test_type = invoker.test_type
}
if (_test_type == "gtest") {
_shared_dir = _gtest_gen_dir
} else if (_test_type == "junit") {
_shared_dir = _junit_gen_dir
}
# If a set of filters has not been defined, use the empty list.
_filters = []
if (defined(invoker.filters)) {
_filters = invoker.filters
}
# If priority has not been set, set the priority to "1", the lowest priority.
_priority = "1"
if (defined(invoker.priority)) {
_priority = invoker.priority
}
# Assert that |_priority| is an integer between "1" and "9", inclusive.
assert(_priority == "1" || _priority == "2" || _priority == "3" ||
_priority == "4" || _priority == "5" || _priority == "6" ||
_priority == "7" || _priority == "8" || _priority == "9")
# This will be the prefix of each output file.
_output_prefix = "$_shared_dir/$_priority-$target_name"
# Create a list of all the target names. These must correspond to the name of
# the test binary.
_test_names = []
foreach(_test, invoker.tests) {
_test_names += [ get_label_info(_test, "name") ]
}
# This action generates a list of target names to build and run. It will be
# depended upon by the "pack_build" action of the cast_test_group_list
# instance which depends on this cast_test_group.
action(target_name + "_create_list") {
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
"$_output_prefix.tests",
]
args = [
"-o",
rebase_path("$_output_prefix.tests"),
"create_list",
]
args += _test_names
deps = []
if (defined(invoker.deps)) {
foreach(_dep, invoker.deps) {
deps += [ _dep + "_create_list" ]
}
}
}
# This action generates a list of test filters, which will have a priority
# [1-9]. This will be depended upon by the "pack_run" action of the
# cast_test_group_list which depends on this group.
action(target_name + "_filters") {
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
"$_output_prefix.filters",
]
args = [
"-o",
rebase_path("$_output_prefix.filters"),
"create_list",
]
args += _filters
deps = []
if (defined(invoker.deps)) {
foreach(_dep, invoker.deps) {
deps += [ _dep + "_filters" ]
}
}
}
# This target allows us to reference each test as a fully-qualified GN path,
# to ensure that each path is correct. If a test does not exist, gives a
# helpful error message at the line it is included. Do not build this target
# directly.
group(target_name + "_build_tests") {
testonly = true
deps = invoker.tests
if (defined(invoker.deps)) {
foreach(_dep, invoker.deps) {
deps += [ _dep + "_build_tests" ]
}
}
}
}
# This template runs a script which generates lists of test to be built and run.
#
# Parameters
# test_groups (required)
# The cast_test_group() targets for which this binary is to be created.
# The targets referenced here must be cast_test_group targets, or buiding
# this target will fail.
#
# build_list_path (required)
# The absolute filepath of the output file which will hold the list of
# tests to be built.
#
# run_list_path (required)
# The absolute filepath of the output file which will hold the list of
# tests to be run, each with filters assigned by cast_groups.
#
# additional_options (optional)
# Options which are passed to the python script, and applied to every test
#
# build_tests (optional)
# Set this to true to build all of the tests included in |test_groups|.
# Defaults to false. Note that if this is set to true, the test targets
# will be built after all the lists are generated.
# test_type (optional)
# A string, which must be either "junit" or "gtest". If not defined,
# defaults to "gtest".
#
template("cast_test_group_list") {
assert(defined(invoker.test_groups), "$target_name needs 'test_groups'")
assert(defined(invoker.run_list_path), "$target_name needs 'run_list_path'")
assert(defined(invoker.build_list_path),
"$target_name needs 'build_list_path'")
_pack_build_action = target_name + "_pack_build"
_test_type = "gtest"
if (defined(invoker.test_type)) {
assert(invoker.test_type == "gtest" || invoker.test_type == "junit")
_test_type = invoker.test_type
}
if (_test_type == "gtest") {
_shared_dir = _gtest_gen_dir
} else if (_test_type == "junit") {
_shared_dir = _junit_gen_dir
}
# Add the run list to runtime data dependencies
data = [
invoker.run_list_path,
]
# Generate a list of the "create_list" actions for each group. These will be
# depended upon to ensure they're run before the "pack_build" step.
_build_actions = []
foreach(_test_group, invoker.test_groups) {
_build_actions += [ _test_group + "_create_list" ]
}
# Generate a list of the "filter" actions for each group. These will be
# depended upon to ensure they're run before the "pack_run" step.
_filter_actions = []
foreach(_test_group, invoker.test_groups) {
_filter_actions += [ _test_group + "_filters" ]
}
# Generate a list of the groups of targets, so that they can be depended upon
# by the "pack_run" step and built when this target is invoked.
if (defined(invoker.build_tests) && invoker.build_tests) {
_build_tests = []
foreach(_test_group, invoker.test_groups) {
_build_tests += [ _test_group + "_build_tests" ]
}
}
# The "pack_build" step. This step looks in the common folder for files with
# the ".tests" extenstion, collecting these and packing them into an output
# file. The steps which create these files are depeneded upon, to ensure
# they're run before this step. Do not invoke this target directly.
action(_pack_build_action) {
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
invoker.build_list_path,
]
args = [
"-o",
rebase_path(invoker.build_list_path),
"-t",
rebase_path(_shared_dir),
"pack_build",
]
deps = _build_actions
}
# The "pack_run" step. This step looks in the common folder for files with
# the ".tests" and ".filters" extensions, creating a script of tests to run,
# with filters and priorities. See
# //chromecast/tools/build/generate_test_lists.py for more information.
# Note that this target takes the name of the invoker, such that invoking the
# target runs this step.
action(target_name) {
testonly = true
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
invoker.run_list_path,
]
args = [
"-o",
rebase_path(invoker.run_list_path),
"-t",
rebase_path(_shared_dir),
"pack_run",
]
# Add addtional options if they have been set.
if (defined(invoker.additional_options)) {
args += [ "-a" ]
args += invoker.additional_options
}
# Depend first on the "pack_build" step, so that the build lists are created.
deps = [
":$_pack_build_action",
]
# Next, depend on the filter steps, such that they are created before this
# script executes.
deps += _filter_actions
# If |build_tests| has been set to true, depend on the testing targets so
# that the tests are built.
if (defined(_build_tests)) {
deps += _build_tests
}
}
}