|  | # Copyright 2018 The Fuchsia Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | import("//build/testing/host_test.gni") | 
|  |  | 
|  | # Defines a Rust unit test, without also compiling a separate binary or library | 
|  | # target. | 
|  | # | 
|  | # Parameters | 
|  | # | 
|  | #   output_name (optional) | 
|  | #   name (optional, deprecated) | 
|  | #     Name of the test binary, also used as the crate name as defined in its | 
|  | #     manifest file. If not specified, it is assumed to be the same as the | 
|  | #     target name. | 
|  | # | 
|  | #   version | 
|  | #     Semver version of the crate as seen on crates.io. | 
|  | # | 
|  | #   edition (optional) | 
|  | #     Edition of the Rust language to be used. | 
|  | #     Options are "2015" and "2018". Defaults to "2018". | 
|  | # | 
|  | #   configs (optional) | 
|  | #     A list of config labels applying to this target. | 
|  | # | 
|  | #   enforce_source_listing (optional) | 
|  | #     When true, enforces that any source files used by the Rust compiler are | 
|  | #     listed in `sources`. Defaults to true. | 
|  | # | 
|  | #   sources (optional) | 
|  | #     List of source files which this crate is allowed to compile. Only | 
|  | #     allowed when `enforce_source_listing = true`. | 
|  | #     The Rust compiler discovers source files by following `mod` declarations | 
|  | #     starting at the `source_root`. The discovered source files must match this | 
|  | #     list. | 
|  | # | 
|  | #   inputs (optional) | 
|  | #     List of additional non-source files read by the compiler. These are typically | 
|  | #     configuration or test-data files included in the build with the `include_str!` | 
|  | #     macro. Only allowed when `enforce_source_listing = true`. | 
|  | # | 
|  | #   deps (optional) | 
|  | #     List of rust_library GN targets on which this crate depends. | 
|  | #     Third party crates can be included through paths like | 
|  | #     "//third_party/rust_crates:<cratename>", | 
|  | # | 
|  | #   non_rust_deps (optional) | 
|  | #     List of non-rust_library GN targets on which this crate depends. | 
|  | # | 
|  | #   test_environments (optional) | 
|  | #     What environments the unit test should target. Only used here | 
|  | #     for linux and mac tests, with a default value of a general linux/mac | 
|  | #     environment (as a function of $current_os). | 
|  | #     See environments parameter on //build/testing/test_spec.gni for more | 
|  | #     details. | 
|  |  | 
|  | #   args (optional) | 
|  | #     List of flags to pass directly to the test binary, e.g. | 
|  | #     ["--nocapture"]. | 
|  | # | 
|  | #   source_root (optional) | 
|  | #     Location of the crate root (e.g. `src/main.rs` or `src/lib.rs`). | 
|  | #     This should usually be 'src/lib.rs/ for libraries (the default) | 
|  | #     and `src/main.rs` for binaries. | 
|  | # | 
|  | #   features (optional) | 
|  | #     A list of conditional compilation flags to enable. This can be used to set features for crates | 
|  | #     built in-tree which are also published to crates.io. This would be passed to rustc as | 
|  | #     '--cfg feature=XXX' | 
|  | # | 
|  | #   output_dir (optional) | 
|  | #     Directory that the resulting test should be placed in. | 
|  | #     See: `gn help output_dir` | 
|  | # | 
|  | # Example of usage: | 
|  | # | 
|  | #   rustc_test("foo_test") { | 
|  | #     source_root = "src/foo_test.rs", | 
|  | #     deps = [ | 
|  | #       "//garnet/public/rust/bar", | 
|  | #       "//third_party/rust_crates:clap", | 
|  | #       "//third_party/rust_crates:serde", | 
|  | #       "//third_party/rust_crates:slab", | 
|  | #     ] | 
|  | #     sources = [ "src/lib.rs" ] | 
|  | #   } | 
|  | template("rustc_test") { | 
|  | not_needed(invoker, | 
|  | [ | 
|  | "version", | 
|  | "edition", | 
|  | "force_opt", | 
|  | "testonly", | 
|  | ]) | 
|  |  | 
|  | # default location for rust libraries | 
|  | source_root = "src/lib.rs" | 
|  | if (defined(invoker.source_root)) { | 
|  | source_root = invoker.source_root | 
|  | } | 
|  |  | 
|  | # use the target name unless another name is specified | 
|  | assert(!(defined(invoker.output_name) && defined(invoker.name)), | 
|  | "Only one of output_name and name may be specified.") | 
|  | package_name = target_name | 
|  | if (defined(invoker.output_name)) { | 
|  | package_name = invoker.output_name | 
|  | } else if (defined(invoker.name)) { | 
|  | package_name = invoker.name | 
|  | } | 
|  |  | 
|  | # built-in gn rules do not support dashes | 
|  | crate_name = string_replace(package_name, "-", "_") | 
|  |  | 
|  | exe_target_name = target_name | 
|  |  | 
|  | if (is_host) { | 
|  | exe_target_name = "${target_name}_executable" | 
|  | all_deps = [ ":${exe_target_name}" ] | 
|  | if (defined(invoker.deps)) { | 
|  | all_deps += invoker.deps | 
|  | } | 
|  | if (defined(invoker.non_rust_deps)) { | 
|  | all_deps += invoker.non_rust_deps | 
|  | } | 
|  |  | 
|  | host_test(target_name) { | 
|  | binary_path = "${root_out_dir}/${crate_name}" | 
|  | deps = all_deps | 
|  | if (defined(invoker.test_environments)) { | 
|  | environments = invoker.test_environments | 
|  | } | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "args", | 
|  | "visibility", | 
|  | ]) | 
|  | } | 
|  | } else { | 
|  | # if not a host-side target, we don't need this since it doesn't | 
|  | # propogate to package.gni | 
|  | not_needed(invoker, [ "test_environments" ]) | 
|  | } | 
|  |  | 
|  | # enable these features for the target | 
|  | features = [] | 
|  | if (defined(invoker.features)) { | 
|  | foreach(i, invoker.features) { | 
|  | features += [ "--cfg=feature=\"${i}\"" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | _sources = [] | 
|  | _deps = [] | 
|  |  | 
|  | if (!defined(invoker.enforce_source_listing) || | 
|  | invoker.enforce_source_listing == true) { | 
|  | # fail early when the user forgets to list sources | 
|  | assert(defined(invoker.sources), "sources must be listed") | 
|  | _sources = invoker.sources | 
|  | } else { | 
|  | not_needed(invoker, [ "sources" ]) | 
|  |  | 
|  | # This is a hack to workaround the fact that a GN `tool` invocation can't receive arbitrary input. | 
|  | # Add a sentinel value so that enforcement is skipped. | 
|  | _sources = [ "//build/rust/__SKIP_ENFORCEMENT__.rs" ] | 
|  |  | 
|  | # Opting out of strict sources check requires that the package is present | 
|  | # in a global allow-list. | 
|  | _deps += [ "//build/rust:disable_strict_sources_check_allowlist" ] | 
|  | } | 
|  |  | 
|  | executable(exe_target_name) { | 
|  | # anything defined with rustc_test MUST be a test target | 
|  | testonly = true | 
|  |  | 
|  | configs = [] | 
|  | configs = invoker.configs | 
|  |  | 
|  | crate_root = source_root | 
|  | output_name = crate_name | 
|  | crate_name = crate_name | 
|  |  | 
|  | # tell rustc to compile in the test harness | 
|  | rustflags = features + [ "--test" ] | 
|  |  | 
|  | deps = _deps | 
|  | if (defined(invoker.deps)) { | 
|  | deps += invoker.deps | 
|  | } | 
|  | if (defined(invoker.non_rust_deps)) { | 
|  | deps += invoker.non_rust_deps | 
|  | } | 
|  |  | 
|  | # test_deps specified in the parent template (if not used directly) | 
|  | # should also be treated as normal dependencies | 
|  | if (defined(invoker.test_deps)) { | 
|  | deps += invoker.test_deps | 
|  | } | 
|  |  | 
|  | data_deps = [] | 
|  | if (defined(invoker.data_deps)) { | 
|  | data_deps = invoker.data_deps | 
|  | } | 
|  | if (is_fuchsia) { | 
|  | # Dynamic linking applies to not only to libstd but to libtest as well, | 
|  | # which means we must depend on it as a data_dep to get it in our | 
|  | # package. | 
|  | _dynamic_rust_config = | 
|  | [ "//build/config/fuchsia:dynamic_rust_standard_library" ] | 
|  | if (configs + _dynamic_rust_config - _dynamic_rust_config != configs) { | 
|  | data_deps += [ "//build/toolchain/runtime:shared-rust-libtest-deps" ] | 
|  | } else { | 
|  | data_deps += [ "//build/toolchain/runtime:static-rust-libtest-deps" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | if (is_fuchsia) { | 
|  | deps += [ "//build/test:rust_test_metadata" ] | 
|  | metadata = { | 
|  | cmx_patches_walk = [ "//build/test:rust_test_metadata" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | sources = _sources | 
|  |  | 
|  | # in-tree default in 2018 edition | 
|  | if (defined(invoker.edition) && invoker.edition == "2015") { | 
|  | configs -= [ "//build/config:rust_edition_2018" ] | 
|  | configs += [ "//build/config:rust_edition_2015" ] | 
|  | } | 
|  |  | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "inputs", | 
|  | "output_dir", | 
|  | "visibility", | 
|  | ]) | 
|  | } | 
|  | } |