| # 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") { |
| # filters = [] |
| # tests = [ |
| # "//path/to/widget:widget_unittests", |
| # "//even/more/foo:foo_unittests", |
| # ] |
| # |
| # widget_unittests_filter = { |
| # test_name = "widgets_unittests" |
| # gtest_includes = [ "WidgetTest.*" ] |
| # gtest_excludes = [ "WidgetTest.TestToBeFilteredOut", |
| # "WidgetTest.MoreTestsToFilterOut" ] |
| # args = [ "--extra_arg", |
| # "--another_arg", ] |
| # } |
| # filters += [ widget_unittests_filter ] |
| # } |
| # |
| # # 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" |
| # runtime_deps_path = "$root_out_dir/path/to/list/runtime_deps.json" |
| # } |
| |
| import("//chromecast/chromecast.gni") |
| import("//testing/test.gni") |
| |
| declare_args() { |
| # Set this true to build all tests in a cast_test_group_list by default. This |
| # can be overriden in each cast_test_group_list instance by setting |
| # |build_tests|. |
| build_cast_tests_by_default = true |
| } |
| |
| # 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 scopes, where each scope has the has the follow variables: |
| # test_name (required): The name of the test executable. This must |
| # correspond to a test in |tests|. |
| # gtest_includes (optional): A list of gtest filter pattern strings. |
| # Only tests that match one of the positive patterns (if provided)\ |
| # will be run. |
| # Example: gtest_includes = [ "Foo.*", "Bar.Test1", "Bar.Test2" ] |
| # will get translated to "--gtest_filter=Foo.*:Bar.Test1:Bar.Test2" |
| # gtest_excludes (optional): A list of gtest filter pattern strings. |
| # Only tests that do not match any of the negative patterns |
| # (if provided) will be run. |
| # Example: gtest_excludes = [ "Baz.*", "Biz.Test" ] |
| # will get translated to "--gtest_filter=-Baz.*:Biz.Test1" |
| # args (optional): A list of additional args to pass to the test. |
| # Please see //chromecast/tools/build/generate_test_lists.py for more |
| # information. |
| # If |filters| 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)) { |
| foreach(filter, invoker.filters) { |
| assert(defined(filter.test_name), "A filter must have a test_name.") |
| _test_name = filter.test_name |
| |
| _gtest_include_filter = "" |
| if (defined(filter.gtest_includes)) { |
| foreach(include, filter.gtest_includes) { |
| _gtest_include_filter = "${_gtest_include_filter}:${include}" |
| } |
| } |
| |
| _gtest_exclude_filter = "" |
| if (defined(filter.gtest_excludes)) { |
| foreach(exclude, filter.gtest_excludes) { |
| _gtest_exclude_filter = "${_gtest_exclude_filter}:${exclude}" |
| } |
| } |
| |
| _gtest_filter = "" |
| if (_gtest_include_filter != "" || _gtest_exclude_filter != "") { |
| _gtest_filter += "--gtest_filter=" |
| if (_gtest_include_filter != "") { |
| _gtest_filter += _gtest_include_filter |
| } |
| if (_gtest_exclude_filter != "") { |
| _gtest_filter += "-" + _gtest_exclude_filter |
| } |
| } |
| |
| _args = "" |
| if (defined(filter.args)) { |
| foreach(arg, filter.args) { |
| _args = "${_args} ${arg}" |
| } |
| } |
| |
| # Only add filters that actually do something, otherwise the |
| # generate script will get confused. |
| if (_args != "" || _gtest_filter != "") { |
| _filters += [ "${_test_name} ${_args} ${_gtest_filter}" ] |
| } |
| } |
| } |
| |
| # 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") ] |
| } |
| |
| # Create a dummy target so that we can get the runtime deps for each test |
| # and output them into a file. The runtime deps include all of the data files, |
| # data directories, and shared libraries that a test needs in order to run. |
| foreach(_test, invoker.tests) { |
| _test_name = get_label_info(_test, "name") |
| group(_test_name + "_cast_runtime_deps") { |
| testonly = true |
| data_deps = [ |
| _test, |
| ] |
| write_runtime_deps = |
| "${_shared_dir}/runtime_deps/${_test_name}_runtime_deps.txt" |
| } |
| } |
| |
| # 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", root_build_dir), |
| "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", root_build_dir), |
| "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. |
| # |
| # runtime_deps_path (required) |
| # The absolute filepath of the output file which will hold the json dict |
| # of runtime dependencies for each test to be run. |
| # |
| # additional_options (optional) |
| # Options which are passed to the python script, and applied to every test |
| # |
| # build_tests (optional) |
| # If true, all of the tests included in |test_groups| will be built as |
| # dependencies of this target. If false, only the lists will be generated. |
| # If not explicitly set, this defaults to the value of |
| # |build_cast_tests_by_default|. 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'") |
| assert(defined(invoker.runtime_deps_path), |
| "$target_name needs 'runtime_deps_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, |
| invoker.runtime_deps_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" ] |
| } |
| |
| # Decide whether tests are built as dependencies. |
| _build_cast_tests = build_cast_tests_by_default |
| if (defined(invoker.build_tests)) { |
| _build_cast_tests = invoker.build_tests |
| } |
| |
| # 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 (_build_cast_tests) { |
| _build_test_targets = [] |
| foreach(_test_group, invoker.test_groups) { |
| _build_test_targets += [ _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, root_build_dir), |
| "-t", |
| rebase_path(_shared_dir, root_build_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, |
| invoker.runtime_deps_path, |
| ] |
| |
| args = [ |
| "-o", |
| rebase_path(invoker.run_list_path, root_build_dir), |
| "-d", |
| rebase_path(invoker.runtime_deps_path, root_build_dir), |
| "-t", |
| rebase_path(_shared_dir, root_build_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_cast_tests| has been set to true, depend on the testing targets |
| # so that the tests are built. |
| if (_build_cast_tests) { |
| deps += _build_test_targets |
| } |
| |
| if (chromecast_branding != "public") { |
| deps += [ "//chromecast/internal:cast_test_checker" ] |
| } |
| } |
| } |
| |
| # This template creates a tar.gz file with test dependencies. |
| # |
| # Parameters |
| # output (required) |
| # The absolute path to the tar.gz file to be created. |
| # |
| # deps_list_path (required) |
| # Absolute path to runtime dependencies file. This has to point to the |
| # same file runtime_deps_path of cast_test_group_list is pointing to. |
| # |
| # exclude_deps (optional) |
| # gn list of paths to filter out from the dependencies list. |
| # This is used to remove folders with huge files that are not needed. |
| # |
| # additional_deps (optional) |
| # gn list of paths to be added to the list of dependencies |
| # before creating the tar.gz file. |
| # |
| # This template has to be used in combination with cast_test_group_list |
| # that generates the runtime dependencies file. |
| # |
| # Example usage: |
| # |
| # cast_test_group_list("chromecast_test_lists") { |
| # build_list_path = "$root_out_dir/tests/build_test_list.txt" |
| # runtime_deps_path = "$root_out_dir/tests/runtime_deps.json" |
| # run_list_path = "$root_out_dir/tests/run_test_list.txt" |
| # test_groups = [ ":chromecast_test_group" ] |
| # } |
| # |
| # cast_test_deps_archive("chromecast_test_deps_archive") { |
| # output = "$root_out_dir/test_deps.tar.gz" |
| # deps_list_path = "$root_out_dir/tests/runtime_deps.json" |
| # exclude_deps = [ |
| # "exe.unstripped", |
| # "lib.unstripped" |
| # ] |
| # additional_deps = [ |
| # "tests", |
| # ] |
| # deps = [ |
| # ":chromecast_test_lists" |
| # ] |
| # } |
| # |
| template("cast_test_deps_archive") { |
| assert(defined(invoker.output), "$target_name needs 'output'") |
| assert(defined(invoker.deps_list_path), |
| "$target_name needs 'deps_list_path'") |
| |
| deps = invoker.deps |
| |
| action(target_name) { |
| testonly = true |
| |
| script = "//chromecast/tools/build/package_test_deps.py" |
| outputs = [ |
| invoker.output |
| ] |
| |
| # Generate a comma separated list of filters. |
| _exclude_deps = "" |
| foreach(_exclude_dep, invoker.exclude_deps) { |
| _exclude_deps += "," + _exclude_dep |
| } |
| |
| # Generate a comma separated list of includes. |
| _additional_deps = "" |
| foreach(_additional_dep, invoker.additional_deps) { |
| _additional_deps += "," + _additional_dep |
| } |
| |
| args = [ |
| "--output", |
| rebase_path(invoker.output, root_build_dir), |
| "--deps_list_path", |
| rebase_path(invoker.deps_list_path, root_build_dir), |
| "--exclude_deps", |
| _exclude_deps, |
| "--additional_deps", |
| _additional_deps, |
| ] |
| } |
| } |