| # Copyright 2021 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/rust.gni") |
| import("//build/rust/rust_unit_tests_group.gni") |
| |
| # Defines a Rust unit test. |
| # |
| # This generates an executable + a script that can be run on Chromium bots. |
| # Future iterations of this template may do something smarter with the test |
| # code in order to automatically contribute it to test steps on the bots. |
| # |
| # Parameters |
| # |
| # sources |
| # edition (optional) |
| # allow_unsafe (optional) |
| # configs (optional) |
| # deps (optional) |
| # crate_root (optional) |
| # features (optional) |
| # rustflags (optional) |
| # inputs (optional) |
| # All as in rust_static_library. |
| # |
| # Example of usage: |
| # |
| # rust_unit_test("foo_tests") { |
| # deps = [ |
| # "//third_party/rust/test_utils/v1:lib", |
| # ] |
| # sources = [ "src/lib.rs" ] |
| # } |
| # |
| # Implementation note: you might assume it makes sense to implement this |
| # in terms of rust_target in order to avoid the duplication of logic around |
| # features and editions. We don't do that because rust_target actually |
| # depends on this template in order to build embedded unit tests |
| # (and therefore depending on rust_target here would lead to an infinite |
| # import loop). |
| |
| template("rust_unit_test") { |
| assert(can_build_rust_unit_tests) |
| if (defined(invoker.crate_name)) { |
| _crate_name = invoker.crate_name |
| } else { |
| _crate_name = target_name |
| } |
| if (defined(invoker.crate_root)) { |
| _crate_root = invoker.crate_root |
| } else { |
| _crate_root = "src/lib.rs" |
| } |
| _rustflags = invoker.rustflags |
| if (defined(invoker.features)) { |
| foreach(i, invoker.features) { |
| _rustflags += [ "--cfg=feature=\"${i}\"" ] |
| } |
| } |
| _configs = invoker.configs |
| _edition = "2021" |
| if (defined(invoker.edition)) { |
| _edition = invoker.edition |
| } |
| _configs += [ "//build/rust:edition_${_edition}" ] |
| |
| # We require that all source files are listed, even though this is |
| # not a requirement for rustc. The reason is to ensure that tools |
| # such as `gn deps` give the correct answer, and thus we trigger |
| # the right test suites etc. on code change. |
| # TODO(crbug.com/1256930) - verify this is correct |
| assert(defined(invoker.sources), "sources must be listed") |
| |
| _exe_target_name = target_name + "_exe" |
| rust_unit_tests_group(target_name) { |
| deps = [ ":$_exe_target_name" ] |
| } |
| |
| # The OUT_DIR for a crate's tests should point to the same OUT_DIR that the |
| # library it's testing used. The `env_out_dir` variable can be used to specify |
| # that directory. |
| if (defined(invoker.env_out_dir)) { |
| _env_out_dir = invoker.env_out_dir |
| } else { |
| _env_out_dir = target_gen_dir |
| } |
| |
| # TODO(crbug.com/1229320): Arrange to run test executables on try bots. |
| # TODO(crbug.com/gn/146): Allow Rust executables to depend on C/C++ source |
| # sets. |
| # This is important in cases where Rust tests may depend upon C/C++ |
| # dependencies. |
| executable(_exe_target_name) { |
| testonly = true |
| forward_variables_from(invoker, |
| "*", |
| [ |
| "allow_unsafe", |
| "edition", |
| "features", |
| "rustflags", |
| "configs", |
| "crate_name", |
| "crate_root", |
| "env_out_dir", |
| ]) |
| if (!defined(output_name) || output_name == "") { |
| output_name = _crate_name |
| } |
| |
| rustflags = [ |
| "--cfg", |
| "feature=\"test\"", |
| "--test", |
| ] |
| rustflags += _rustflags |
| configs = [] |
| configs = _configs |
| crate_name = _crate_name |
| crate_root = _crate_root |
| if (!defined(rustenv)) { |
| rustenv = [] |
| } |
| |
| rustenv += [ "OUT_DIR=" + rebase_path(_env_out_dir) ] |
| metadata = { |
| # Consumed by "rust_unit_tests_group" gni template. |
| rust_unit_test_executables = [ _crate_name ] |
| } |
| } |
| } |
| |
| set_defaults("rust_unit_test") { |
| configs = default_executable_configs |
| deps = [] |
| rustflags = [] |
| } |