xref: /aosp_15_r20/external/angle/build/rust/rust_unit_test.gni (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1# Copyright 2021 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/rust.gni")
6import("//build/rust/rust_unit_tests_group.gni")
7
8# Defines a Rust unit test.
9#
10# This generates an executable + a script that can be run on Chromium bots.
11# Future iterations of this template may do something smarter with the test
12# code in order to automatically contribute it to test steps on the bots.
13#
14# Parameters
15#
16#   sources
17#   edition (optional)
18#   allow_unsafe (optional)
19#   configs (optional)
20#   deps (optional)
21#   crate_root (optional)
22#   features (optional)
23#   rustflags (optional)
24#   inputs (optional)
25#     All as in rust_static_library.
26#
27# Example of usage:
28#
29#   rust_unit_test("foo_tests") {
30#     deps = [
31#       "//third_party/rust/test_utils/v1:lib",
32#     ]
33#     sources = [ "src/lib.rs" ]
34#   }
35#
36# Implementation note: you might assume it makes sense to implement this
37# in terms of rust_target in order to avoid the duplication of logic around
38# features and editions. We don't do that because rust_target actually
39# depends on this template in order to build embedded unit tests
40# (and therefore depending on rust_target here would lead to an infinite
41# import loop).
42
43template("rust_unit_test") {
44  assert(can_build_rust_unit_tests)
45  if (defined(invoker.crate_name)) {
46    _crate_name = invoker.crate_name
47  } else {
48    _crate_name = target_name
49  }
50  if (defined(invoker.crate_root)) {
51    _crate_root = invoker.crate_root
52  } else {
53    _crate_root = "src/lib.rs"
54  }
55  _rustflags = invoker.rustflags
56  if (defined(invoker.features)) {
57    foreach(i, invoker.features) {
58      _rustflags += [ "--cfg=feature=\"${i}\"" ]
59    }
60  }
61  _configs = invoker.configs
62  _edition = "2021"
63  if (defined(invoker.edition)) {
64    _edition = invoker.edition
65  }
66  _configs += [ "//build/rust:edition_${_edition}" ]
67
68  # We require that all source files are listed, even though this is
69  # not a requirement for rustc. The reason is to ensure that tools
70  # such as `gn deps` give the correct answer, and thus we trigger
71  # the right test suites etc. on code change.
72  # TODO(crbug.com/40200431) - verify this is correct
73  assert(defined(invoker.sources), "sources must be listed")
74
75  _exe_target_name = target_name + "_exe"
76  rust_unit_tests_group(target_name) {
77    deps = [ ":$_exe_target_name" ]
78  }
79
80  # The OUT_DIR for a crate's tests should point to the same OUT_DIR that the
81  # library it's testing used. The `env_out_dir` variable can be used to specify
82  # that directory.
83  if (defined(invoker.env_out_dir)) {
84    _env_out_dir = invoker.env_out_dir
85  } else {
86    _env_out_dir = target_gen_dir
87  }
88
89  executable(_exe_target_name) {
90    testonly = true
91    forward_variables_from(invoker,
92                           "*",
93                           [
94                             "allow_unsafe",
95                             "edition",
96                             "features",
97                             "rustflags",
98                             "configs",
99                             "crate_name",
100                             "crate_root",
101                             "env_out_dir",
102                           ])
103    if (!defined(output_name) || output_name == "") {
104      output_name = _crate_name
105    }
106
107    rustflags = [
108      "--cfg",
109      "feature=\"test\"",
110      "--test",
111    ]
112    rustflags += _rustflags
113    configs = []
114    configs = _configs
115    crate_name = _crate_name
116    crate_root = _crate_root
117    if (!defined(rustenv)) {
118      rustenv = []
119    }
120
121    rustenv += [ "OUT_DIR=" +
122                 rebase_path(_env_out_dir, get_path_info(_crate_root, "dir")) ]
123    metadata = {
124      # Consumed by "rust_unit_tests_group" gni template.
125      rust_unit_test_executables = [ _crate_name ]
126    }
127
128    # Duplicated from rust_target since we didn't use the rust_executable
129    # template as it causes a GN cycle.
130    if (!defined(deps)) {
131      deps = []
132    }
133    if (!defined(invoker.no_chromium_prelude) || !invoker.no_chromium_prelude) {
134      if (enable_chromium_prelude) {
135        deps += [ "//build/rust/chromium_prelude" ]
136      }
137    }
138  }
139}
140
141set_defaults("rust_unit_test") {
142  configs = default_executable_configs
143  deps = []
144  rustflags = []
145}
146