# 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") # This directory must be the same for every cast_test_group instance. _shared_dir = "$root_gen_dir/chromecast/tests" # 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: " --gtest_filter=" # The 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. # template("cast_test_group") { assert(defined(invoker.tests), "$target_name needs 'tests' listing the test() targets") # 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. # 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" # 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 } } }