summaryrefslogtreecommitdiff
path: root/chromium/build/rust/rust_unit_test.gni
blob: 879cb84a9294b85da4e3f0fba1ac8b66a33f543c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# 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)
#   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 += [ string_join("",
                            [
                              "//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" ]
  }

  # 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,
                           "*",
                           [
                             "edition",
                             "features",
                             "rustflags",
                             "configs",
                             "output_name",
                             "crate_name",
                             "crate_root",
                           ])

    if (defined(output_dir) && output_dir != "") {
      _out_dir = output_dir
    } else {
      _out_dir = target_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(_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 = []
}