| # Copyright 2018 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/chrome_build.gni") |
| import("//build/config/chromeos/args.gni") |
| import("//build/config/chromeos/ui_mode.gni") |
| import("//build/config/dcheck_always_on.gni") |
| import("//build/config/gclient_args.gni") |
| import("//build/config/python.gni") |
| import("//build/util/generate_wrapper.gni") |
| |
| assert(is_chromeos && is_chromeos_device) |
| |
| # Determine the real paths for various items in the SDK, which may be used |
| # in the 'generate_runner_script' template below. We do so outside the template |
| # to confine exec_script to a single invocation. |
| if (cros_sdk_version != "") { |
| # Ideally these should be maps, however, gn doesn't support map, so using a |
| # list of list to simulate a map: |
| # [key1, [value1, value2, ...]], [key2, [value1, value2, ...]], where |
| # the keys are boards and values are symlinks or symlink targets, and the |
| # mapping shouldn't be used for anything else. |
| # |
| # A sample usage is: |
| # foreach(m, _symlink_targets_map) { |
| # if(m[0] == target_key) { |
| # target_value = m[1] |
| # } |
| # } |
| # |
| _symlink_map = [] |
| _symlink_targets_map = [] |
| |
| if (is_chromeos_ash) { |
| _potential_test_boards = [ cros_board ] |
| } else { |
| _potential_test_boards = [] |
| if (cros_boards != "") { |
| _potential_test_boards += string_split(cros_boards, ":") |
| } |
| if (cros_boards_with_qemu_images != "") { |
| _potential_test_boards += string_split(cros_boards_with_qemu_images, ":") |
| } |
| } |
| |
| foreach(b, _potential_test_boards) { |
| _cache_path_prefix = |
| "//build/cros_cache/chrome-sdk/symlinks/${b}+${cros_sdk_version}" |
| |
| _cros_is_vm = false |
| foreach(b1, string_split(cros_boards_with_qemu_images, ":")) { |
| if (b == b1) { |
| _cros_is_vm = true |
| } |
| } |
| |
| _symlinks = [] |
| _symlinks = [ |
| # Tast harness & test data. |
| rebase_path("${_cache_path_prefix}+autotest_server_package.tar.bz2"), |
| |
| # Binutils (and other toolchain tools) used to deploy Chrome to the device. |
| rebase_path( |
| "${_cache_path_prefix}+environment_chromeos-base_chromeos-chrome.tar.xz"), |
| rebase_path("${_cache_path_prefix}+target_toolchain"), |
| ] |
| if (_cros_is_vm) { |
| # VM-related tools. |
| _symlinks += [ |
| rebase_path("${_cache_path_prefix}+sys-firmware/seabios"), |
| rebase_path("${_cache_path_prefix}+chromiumos_test_image.tar.xz"), |
| rebase_path("${_cache_path_prefix}+app-emulation/qemu"), |
| ] |
| } |
| _symlink_map += [ [ |
| b, |
| _symlinks, |
| ] ] |
| } |
| |
| _all_symlinks = [] |
| foreach(m, _symlink_map) { |
| _all_symlinks += m[1] |
| } |
| _all_symlink_targets = |
| exec_script("//build/get_symlink_targets.py", _all_symlinks, "list lines") |
| _index = 0 |
| foreach(m, _symlink_map) { |
| _symlink_targets = [] |
| foreach(_, m[1]) { |
| _symlink_targets += [ _all_symlink_targets[_index] ] |
| _index += 1 |
| } |
| |
| _symlink_targets_map += [ [ |
| m[0], |
| _symlink_targets, |
| ] ] |
| } |
| } |
| |
| # Creates dependencies required by skylab testing. If passed the |
| # generated_script and test_exe this will generate the skylab runner script. |
| # If passed tast_attr_expr, tast_tests or tast_disabled_tests this will |
| # generate a filter file containing the expression for running tests in skylab. |
| # Args: |
| # generated_script: Name of the generated runner script created for test_exe |
| # test_exe: Name of the executable to run with the generated script. |
| # tast_attr_expr: Tast expression to determine tests to run. This creates the |
| # initial set of tests that can be further filtered.. |
| # tast_tests: Names of tests to enable in tast. All other tests will be |
| # disabled that are not listed. |
| # tast_disabled_tests: Names of tests to disable in tast. All other tests that |
| # match the tast expression will still run. |
| # tast_control: gni file with collections of tests to be used for specific |
| # filters (e.g. "//chromeos/tast_control.gni"). Any lists of strings in |
| # this file will be used to generate additional tast expressions with |
| # those strings expanded into tests to disable (i.e. as && !"name:test"). |
| # The name of those lists are then intended to be used to specify in |
| # test_suites.pyl which collection to be used on specific test suites. |
| template("generate_skylab_deps") { |
| forward_variables_from(invoker, |
| [ |
| "generated_script", |
| "test_exe", |
| "tast_attr_expr", |
| "tast_tests", |
| "tast_disabled_tests", |
| "tast_control", |
| ]) |
| if (defined(test_exe) || defined(generated_script)) { |
| assert(defined(test_exe) && defined(generated_script), |
| "The test_exe and generated_script must both be defined when " + |
| "generating the skylab runner script") |
| action(target_name) { |
| script = "//build/chromeos/generate_skylab_deps.py" |
| outputs = [ generated_script ] |
| args = [ |
| "generate-runner", |
| "--test-exe", |
| test_exe, |
| "--output", |
| rebase_path(generated_script, root_build_dir), |
| ] |
| |
| deps = [ "//testing/buildbot/filters:chromeos_filters" ] |
| if (defined(invoker.deps)) { |
| deps += invoker.deps |
| } |
| |
| data = [ generated_script ] |
| if (defined(invoker.data)) { |
| data += invoker.data |
| } |
| |
| data_deps = [ "//testing:test_scripts_shared" ] |
| if (defined(invoker.data_deps)) { |
| data_deps += invoker.data_deps |
| } |
| } |
| } |
| if (defined(tast_attr_expr) || defined(tast_tests) || |
| defined(tast_disabled_tests)) { |
| if (defined(tast_disabled_tests)) { |
| assert(defined(tast_attr_expr), |
| "tast_attr_expr must be used when specifying tast_disabled_tests.") |
| } |
| _generated_filter = "$root_build_dir/bin/${target_name}.filter" |
| _skylab_args = [ |
| "generate-filter", |
| "--output", |
| rebase_path(_generated_filter), |
| ] |
| if (defined(tast_control)) { |
| _skylab_args += [ |
| "--tast-control", |
| rebase_path(tast_control), |
| ] |
| } |
| if (defined(tast_attr_expr)) { |
| _skylab_args += [ |
| "--tast-expr", |
| tast_attr_expr, |
| ] |
| } |
| if (defined(tast_tests)) { |
| foreach(_test, tast_tests) { |
| _skylab_args += [ |
| "--enabled-tests", |
| _test, |
| ] |
| } |
| } |
| if (defined(tast_disabled_tests)) { |
| foreach(_test, tast_disabled_tests) { |
| _excluded_test_name_and_board = [] |
| _excluded_test_name_and_board = string_split(_test, "@") + [ "" ] |
| _excluded_test_name = _excluded_test_name_and_board[0] |
| _excluded_board = _excluded_test_name_and_board[1] |
| if (_excluded_board == "" || _excluded_board == cros_board) { |
| _skylab_args += [ |
| "--disabled-tests", |
| _excluded_test_name, |
| ] |
| } |
| } |
| } |
| action(target_name) { |
| script = "//build/chromeos/generate_skylab_deps.py" |
| if (defined(tast_control)) { |
| sources = [ tast_control ] |
| } |
| outputs = [ _generated_filter ] |
| args = _skylab_args |
| if (defined(invoker.data_deps)) { |
| data_deps = invoker.data_deps |
| } |
| data = [ _generated_filter ] |
| if (defined(invoker.data)) { |
| data += invoker.data |
| } |
| if (defined(invoker.deps)) { |
| deps = invoker.deps |
| } |
| } |
| } |
| } |
| |
| # Creates a script at $generated_script that can be used to launch a cros VM |
| # and optionally run a test within it. |
| # Args: |
| # test_exe: Name of test binary located in the out dir. This will get copied |
| # to the VM and executed there. |
| # tast_attr_expr: Tast expression to pass to local_test_runner on the VM. |
| # tast_tests: List of Tast tests to run on the VM. Note that when this is |
| # specified, the target name used to invoke this template will be |
| # designated as the "name" of this test and will primarly used for test |
| # results tracking and displaying (eg: flakiness dashboard). |
| # generated_script: Path to place the generated script. |
| # deploy_chrome: If true, deploys a locally built chrome located in the root |
| # build dir to the VM or DUT after launching it. |
| # deploy_lacros: If true, deploys a locally built Lacros located in the root |
| # build dir to the VM or DUT after launching it. |
| # runtime_deps_file: Path to file listing runtime deps for the test. If set, |
| # all files listed will be copied to the VM before testing. |
| # skip_generating_board_args: By default, this template generates an '--board' |
| # arg with corresponding '--flash' or '--use-vm' args for device and vm |
| # respectively. This argument instructs the template to skip generating |
| # them, and it's designed for use cases where one builds for one board |
| # (e.g. amd64-generic), but tests on a different board (e.g. eve). |
| # tast_vars: A list of "key=value" runtime variable pairs to pass to invoke |
| # strip_chrome: If true, strips Chrome before deploying it for non-Tast tests. |
| # the Tast tests. For more details, please see: |
| # https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/writing_tests.md#Runtime-variables |
| template("generate_runner_script") { |
| forward_variables_from(invoker, |
| [ |
| "deploy_chrome", |
| "deploy_lacros", |
| "generated_script", |
| "runtime_deps_file", |
| "skip_generating_board_args", |
| "strip_chrome", |
| "tast_attr_expr", |
| "tast_tests", |
| "tast_vars", |
| "testonly", |
| "test_exe", |
| ]) |
| |
| if (!defined(skip_generating_board_args)) { |
| skip_generating_board_args = false |
| } |
| |
| if (skip_generating_board_args) { |
| # cros_board is not needed, so setting it to empty to avoid being used |
| # accidentally below. |
| cros_board = "" |
| not_needed([ cros_board ]) |
| } |
| |
| if (!defined(deploy_chrome)) { |
| deploy_chrome = false |
| } |
| if (!defined(deploy_lacros)) { |
| deploy_lacros = false |
| } |
| if (!defined(strip_chrome)) { |
| strip_chrome = false |
| } |
| is_tast = defined(tast_attr_expr) || defined(tast_tests) |
| assert(!(is_tast && defined(test_exe)), |
| "Tast tests are invoked from binaries shipped with the VM image. " + |
| "There should be no locally built binary needed.") |
| assert(is_tast || !defined(tast_vars), |
| "tast_vars is only support for Tast tests") |
| |
| if (is_tast) { |
| not_needed([ "strip_chrome" ]) |
| } |
| |
| # If we're in the cros chrome-sdk (and not the raw ebuild), the test will |
| # need some additional runtime data located in the SDK cache. |
| _sdk_data = [] |
| if (cros_sdk_version != "") { |
| assert(defined(generated_script), |
| "Must specify where to place generated test launcher script via " + |
| "'generated_script'") |
| |
| foreach(b, _potential_test_boards) { |
| _cros_is_vm = false |
| foreach(b1, string_split(cros_boards_with_qemu_images, ":")) { |
| if (b == b1) { |
| _cros_is_vm = true |
| } |
| } |
| |
| # Determine the real paths for various items in the SDK, which may be used |
| # in the 'generate_runner_script' template below. |
| if (is_tast || _cros_is_vm || deploy_chrome) { |
| _symlink_targets = [] |
| foreach(m, _symlink_targets_map) { |
| if (b == m[0]) { |
| _symlink_targets = [] |
| _symlink_targets = m[1] |
| } |
| } |
| |
| if (is_tast) { |
| # Add tast sdk items. |
| _sdk_data += [ _symlink_targets[0] ] |
| } |
| if (deploy_chrome) { |
| # To deploy chrome to the VM, it needs to be stripped down to fit into |
| # the VM. This is done by using binutils in the toolchain. So add the |
| # toolchain to the data. |
| _sdk_data += [ |
| _symlink_targets[1], |
| _symlink_targets[2], |
| ] |
| } |
| if (_cros_is_vm) { |
| # Add vm sdk items. |
| _sdk_data += [ |
| _symlink_targets[3], |
| _symlink_targets[4], |
| _symlink_targets[5], |
| ] |
| } |
| } |
| } |
| } |
| |
| generate_wrapper(target_name) { |
| executable = "//build/chromeos/test_runner.py" |
| wrapper_script = generated_script |
| executable_args = [] |
| |
| if (defined(runtime_deps_file)) { |
| write_runtime_deps = runtime_deps_file |
| } |
| |
| # Build executable_args for the three different test types: GTest, Tast, |
| # and host-side commands (eg telemetry). |
| if (defined(test_exe)) { |
| executable_args += [ |
| "gtest", |
| "--test-exe", |
| test_exe, |
| ] |
| if (defined(runtime_deps_file)) { |
| executable_args += [ |
| "--runtime-deps-path", |
| rebase_path(runtime_deps_file, root_build_dir), |
| ] |
| } |
| } else if (is_tast) { |
| # When --tast-tests is specified, test_runner.py will call |
| # local_test_runner on the VM to run the set of tests. |
| executable_args += [ |
| "tast", |
| "--suite-name", |
| target_name, |
| ] |
| if (defined(tast_attr_expr)) { |
| executable_args += [ |
| "--attr-expr", |
| tast_attr_expr, |
| ] |
| } else { |
| foreach(test, tast_tests) { |
| executable_args += [ |
| "-t", |
| test, |
| ] |
| } |
| } |
| if (defined(tast_vars)) { |
| foreach(var, tast_vars) { |
| executable_args += [ |
| "--tast-var", |
| var, |
| ] |
| } |
| } |
| if (dcheck_always_on) { |
| executable_args += [ |
| "--tast-extra-use-flags", |
| "chrome_dcheck", |
| ] |
| } |
| } else { |
| executable_args += [ "host-cmd" ] |
| } |
| executable_args += [ |
| "--cros-cache", |
| "build/cros_cache/", |
| "--path-to-outdir", |
| rebase_path(root_out_dir, "//"), |
| "-v", |
| ] |
| |
| if (!is_tast && strip_chrome) { |
| executable_args += [ "--strip-chrome" ] |
| } |
| |
| if (!skip_generating_board_args) { |
| executable_args += [ |
| "--board", |
| cros_board, |
| ] |
| |
| _cros_is_vm = false |
| foreach(b, string_split(cros_boards_with_qemu_images, ":")) { |
| if (cros_board == b) { |
| _cros_is_vm = true |
| } |
| } |
| if (_cros_is_vm) { |
| executable_args += [ "--use-vm" ] |
| } else { |
| executable_args += [ "--flash" ] |
| } |
| } |
| |
| # If we have public Chromium builds, use public Chromium OS images when |
| # flashing the test device. |
| if (!is_chrome_branded) { |
| executable_args += [ "--public-image" ] |
| } |
| |
| if (deploy_lacros) { |
| executable_args += [ "--deploy-lacros" ] |
| } |
| |
| if (deploy_chrome && !defined(test_exe)) { |
| executable_args += [ "--deploy-chrome" ] |
| } |
| |
| # executable_args should be finished, now build the data and deps lists. |
| deps = [ "//testing/buildbot/filters:chromeos_filters" ] |
| if (defined(invoker.deps)) { |
| deps += invoker.deps |
| } |
| data = [ |
| "//.vpython3", |
| |
| # We use android test-runner's results libs to construct gtest output |
| # json. |
| "//build/android/pylib/__init__.py", |
| "//build/android/pylib/base/", |
| "//build/android/pylib/results/", |
| "//build/chromeos/", |
| "//build/util/", |
| |
| # Needed for various SDK components used below. |
| "//build/cros_cache/chrome-sdk/misc/", |
| "//build/cros_cache/chrome-sdk/symlinks/", |
| "//chrome/VERSION", |
| |
| # The LKGM file controls what version of the VM image to download. Add it |
| # as data here so that changes to it will trigger analyze. |
| "//chromeos/CHROMEOS_LKGM", |
| "//third_party/chromite/", |
| ] |
| |
| data += _sdk_data |
| |
| if (defined(invoker.data)) { |
| data += invoker.data |
| } |
| |
| data_deps = [ "//testing:test_scripts_shared" ] |
| if (defined(invoker.data_deps)) { |
| data_deps += invoker.data_deps |
| } |
| } |
| } |
| |
| template("tast_test") { |
| forward_variables_from(invoker, "*") |
| |
| if (!defined(deploy_lacros_chrome)) { |
| deploy_lacros_chrome = false |
| } |
| |
| # Default the expression to match any chrome-related test. |
| if (!defined(tast_attr_expr) && !defined(tast_tests)) { |
| # The following expression filters out all non-critical tests. See the link |
| # below for more details: |
| # https://chromium.googlesource.com/chromiumos/platform/tast/+/main/docs/test_attributes.md |
| tast_attr_expr = "\"group:mainline\" && \"dep:chrome\"" |
| |
| if (defined(enable_tast_informational_tests) && |
| enable_tast_informational_tests) { |
| tast_attr_expr += " && informational" |
| } else { |
| tast_attr_expr += " && !informational" |
| } |
| if (!is_chrome_branded) { |
| tast_attr_expr += " && !\"dep:chrome_internal\"" |
| } |
| } else { |
| assert(defined(tast_attr_expr) != defined(tast_tests), |
| "Specify one of tast_tests or tast_attr_expr.") |
| } |
| |
| # Append any disabled tests to the expression. |
| if (defined(tast_disabled_tests)) { |
| assert(defined(tast_attr_expr), |
| "tast_attr_expr must be used when specifying tast_disabled_tests.") |
| foreach(_test, tast_disabled_tests) { |
| _excluded_test_name_and_board = [] |
| _excluded_test_name_and_board = string_split(_test, "@") + [ "" ] |
| _excluded_test_name = _excluded_test_name_and_board[0] |
| _excluded_board = _excluded_test_name_and_board[1] |
| if (_excluded_board == "" || _excluded_board == cros_board) { |
| tast_attr_expr += " && !\"name:${_excluded_test_name}\"" |
| } |
| } |
| } |
| if (defined(tast_attr_expr)) { |
| tast_attr_expr = "( " + tast_attr_expr + " )" |
| } |
| generate_runner_script(target_name) { |
| testonly = true |
| generated_script = "$root_build_dir/bin/run_${target_name}" |
| runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps" |
| deploy_chrome = true |
| deploy_lacros = deploy_lacros_chrome |
| data_deps = [ |
| "//:chromiumos_preflight", # Builds the browser. |
| "//chromeos:cros_chrome_deploy", # Adds additional browser run-time deps. |
| |
| # Tools used to symbolize Chrome crash dumps. |
| # TODO(crbug.com/1156772): Remove these if/when all tests pick them up by |
| # default. |
| "//third_party/breakpad:dump_syms", |
| "//third_party/breakpad:minidump_dump", |
| "//third_party/breakpad:minidump_stackwalk", |
| ] |
| |
| data = [ "//components/crash/content/tools/generate_breakpad_symbols.py" ] |
| if (deploy_lacros_chrome) { |
| data += [ |
| # A script needed to launch Lacros in Lacros Tast tests. |
| "//build/lacros/mojo_connection_lacros_launcher.py", |
| ] |
| } |
| } |
| } |
| |
| template("lacros_tast_tests") { |
| forward_variables_from(invoker, |
| [ |
| "tast_attr_expr", |
| "tast_disabled_tests", |
| "tast_tests", |
| "tast_control", |
| ]) |
| assert(defined(tast_attr_expr) != defined(tast_tests), |
| "Specify one of tast_tests or tast_attr_expr.") |
| |
| _lacros_data_deps = [ |
| "//chrome", # Builds the browser. |
| |
| # Tools used to symbolize Chrome crash dumps. |
| # TODO(crbug.com/1156772): Remove these if/when all tests pick them up by |
| # default. |
| "//third_party/breakpad:dump_syms", |
| "//third_party/breakpad:minidump_dump", |
| "//third_party/breakpad:minidump_stackwalk", |
| ] |
| |
| _lacros_data = [ |
| "//components/crash/content/tools/generate_breakpad_symbols.py", |
| |
| # A script needed to launch Lacros in Lacros Tast tests. |
| "//build/lacros/mojo_connection_lacros_launcher.py", |
| ] |
| |
| if (is_skylab) { |
| generate_skylab_deps(target_name) { |
| data = _lacros_data |
| data_deps = _lacros_data_deps |
| |
| # To disable a test on specific milestones, add it to the appropriate |
| # collection in the following file |
| tast_control = "//chromeos/tast_control.gni" |
| } |
| } else { |
| # Append any disabled tests to the expression. |
| if (defined(tast_disabled_tests)) { |
| assert(defined(tast_attr_expr), |
| "tast_attr_expr must be used when specifying tast_disabled_tests.") |
| foreach(_test, tast_disabled_tests) { |
| _excluded_test_name_and_board = [] |
| _excluded_test_name_and_board = string_split(_test, "@") + [ "" ] |
| _excluded_test_name = _excluded_test_name_and_board[0] |
| _excluded_board = _excluded_test_name_and_board[1] |
| if (_excluded_board == "" || _excluded_board == cros_board) { |
| tast_attr_expr += " && !\"name:${_excluded_test_name}\"" |
| } |
| } |
| } |
| if (defined(tast_attr_expr)) { |
| tast_attr_expr = "( " + tast_attr_expr + " )" |
| } |
| generate_runner_script(target_name) { |
| testonly = true |
| deploy_lacros = true |
| generated_script = "$root_build_dir/bin/run_${target_name}" |
| runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps" |
| |
| # At build time, Lacros tests don't know whether they'll run on VM or HW, |
| # and instead, these flags are specified at runtime when invoking the |
| # generated runner script. |
| skip_generating_board_args = true |
| |
| # By default, tast tests download a lacros-chrome from a gcs location and |
| # use it for testing. To support running lacros tast tests from Chromium CI, |
| # a Var is added to support pointing the tast tests to use a specified |
| # pre-deployed lacros-chrome. The location is decided by: |
| # https://source.chromium.org/chromium/chromium/src/+/main:third_party/chromite/scripts/deploy_chrome.py;l=80;drc=86f1234a4be8e9574442e076cdc835897f7bea61 |
| tast_vars = [ "lacros.DeployedBinary=/usr/local/lacros-chrome" ] |
| |
| data_deps = _lacros_data_deps |
| |
| data = _lacros_data |
| } |
| } |
| } |