forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcast_test.gni
458 lines (407 loc) · 15.1 KB
/
cast_test.gni
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file contains templates which are meant to simplify building and
# running test binaries with the Chromecast build infrastructure. See
# documentation above each template for specific use.
#
# Example Usage
#
# # This is a standard test() template from //testing/test.gni. This generates
# # a binary called foo_unittests.
# test("foo_unittests") {
# sources = [ "foo_unittest.cc" ]
#
# deps = [
# ":foo",
# "//testing/gtest",
# "//testing/gmock",
# ]
# }
#
# # And another standard test() target, which generates bar_unittests
# test("bar_unittests") {
# sources = [ "bar_unittest.cc" ]
#
# deps = [ ... ]
# }
#
# # This is an organizational target. This cannot be built directly.
# cast_test_group("cast_tests") {
# tests = [
# ":bar_unittests",
# "//path/to:foo_unittests",
# ]
# }
#
# # Here is another cast_test_group target which builds a bunch of other
# # test binaries, and wants to apply some filters.
# cast_test_group("external_tests") {
# filters = []
# tests = [
# "//path/to/widget:widget_unittests",
# "//even/more/foo:foo_unittests",
# ]
#
# widget_unittests_filter = {
# test_name = "widgets_unittests"
# gtest_includes = [ "WidgetTest.*" ]
# gtest_excludes = [ "WidgetTest.TestToBeFilteredOut",
# "WidgetTest.MoreTestsToFilterOut" ]
# args = [ "--extra_arg",
# "--another_arg", ]
# }
# filters += [ widget_unittests_filter ]
# }
#
# # Build this to create build and run lists for bar and foo tests.
# cast_test_group_list("cast_test_lists") {
# test_groups = [
# ":cast_tests",
# ":external_tests",
# ]
#
# build_list_paths = "$root_out_dir/path/to/test/build_list.txt"
# run_list_path = "$root_out_dir/path/to/list/run_list.txt"
# runtime_deps_path = "$root_out_dir/path/to/list/runtime_deps.json"
# }
import("//chromecast/chromecast.gni")
import("//testing/test.gni")
declare_args() {
# Set this true to build all tests in a cast_test_group_list by default. This
# can be overriden in each cast_test_group_list instance by setting
# |build_tests|.
build_cast_tests_by_default = true
}
# Do not allow mixing of gtests and junit tests. All gtests must go into one
# directory, while all junit tests must go into another directory.
_gtest_gen_dir = "$root_gen_dir/chromecast/tests"
_junit_gen_dir = "$root_gen_dir/chromecast/junit"
# A group of test executables. Including test targets in this group makes it
# possible for Chromecast build infrastructure to build and run them with
# filters. To accomplish this, it defines two actions, one which generates a
# build list of all |tests|, and one which generates a run list of all |tests|.
# It also creates a group with dependencies on each test, to ensure that they
# are valid targets. Do not build these targets. Build cast_test_group_list
# instead.
#
# Parameters
# tests (required)
# A list of test targets included in the assembly. Do not include any
# other type of target. Each target's name must match the name of the
# executable it builds.
#
# filters (optional)
# A list of scopes, where each scope has the has the follow variables:
# test_name (required): The name of the test executable. This must
# correspond to a test in |tests|.
# gtest_includes (optional): A list of gtest filter pattern strings.
# Only tests that match one of the positive patterns (if provided)\
# will be run.
# Example: gtest_includes = [ "Foo.*", "Bar.Test1", "Bar.Test2" ]
# will get translated to "--gtest_filter=Foo.*:Bar.Test1:Bar.Test2"
# gtest_excludes (optional): A list of gtest filter pattern strings.
# Only tests that do not match any of the negative patterns
# (if provided) will be run.
# Example: gtest_excludes = [ "Baz.*", "Biz.Test" ]
# will get translated to "--gtest_filter=-Baz.*:Biz.Test1"
# args (optional): A list of additional args to pass to the test.
# Please see //chromecast/tools/build/generate_test_lists.py for more
# information.
# If |filters| is not defined, no filters are applied.
#
# priority (optional)
# A string which takes any single-digit integer bewtween "1" and "9",
# inclusive. Assign this to prioritize filters applied by other
# cast_test_groups, where a higher number trumps a lower number.
# If not assigned, priority defaults to "1", the lowest priority.
#
# test_type (optional)
# A string, which must be either "junit" or "gtest". If not defined,
# defaults to "gtest".
#
template("cast_test_group") {
assert(defined(invoker.tests),
"$target_name needs 'tests' listing the test() targets")
_test_type = "gtest"
if (defined(invoker.test_type)) {
assert(invoker.test_type == "gtest" || invoker.test_type == "junit")
_test_type = invoker.test_type
}
if (_test_type == "gtest") {
_shared_dir = _gtest_gen_dir
} else if (_test_type == "junit") {
_shared_dir = _junit_gen_dir
}
# If a set of filters has not been defined, use the empty list.
_filters = []
if (defined(invoker.filters)) {
foreach(filter, invoker.filters) {
assert(defined(filter.test_name), "A filter must have a test_name.")
_test_name = filter.test_name
_gtest_include_filter = ""
if (defined(filter.gtest_includes)) {
foreach(include, filter.gtest_includes) {
_gtest_include_filter = "${_gtest_include_filter}:${include}"
}
}
_gtest_exclude_filter = ""
if (defined(filter.gtest_excludes)) {
foreach(exclude, filter.gtest_excludes) {
_gtest_exclude_filter = "${_gtest_exclude_filter}:${exclude}"
}
}
_gtest_filter = ""
if (_gtest_include_filter != "" || _gtest_exclude_filter != "") {
_gtest_filter += "--gtest_filter="
if (_gtest_include_filter != "") {
_gtest_filter += _gtest_include_filter
}
if (_gtest_exclude_filter != "") {
_gtest_filter += "-" + _gtest_exclude_filter
}
}
_args = ""
if (defined(filter.args)) {
foreach(arg, filter.args) {
_args = "${_args} ${arg}"
}
}
# Only add filters that actually do something, otherwise the
# generate script will get confused.
if (_args != "" || _gtest_filter != "") {
_filters += [ "${_test_name} ${_args} ${_gtest_filter}" ]
}
}
}
# If priority has not been set, set the priority to "1", the lowest priority.
_priority = "1"
if (defined(invoker.priority)) {
_priority = invoker.priority
}
# Assert that |_priority| is an integer between "1" and "9", inclusive.
assert(_priority == "1" || _priority == "2" || _priority == "3" ||
_priority == "4" || _priority == "5" || _priority == "6" ||
_priority == "7" || _priority == "8" || _priority == "9")
# This will be the prefix of each output file.
_output_prefix = "$_shared_dir/$_priority-$target_name"
# Create a list of all the target names. These must correspond to the name of
# the test binary.
_test_names = []
foreach(_test, invoker.tests) {
_test_names += [ get_label_info(_test, "name") ]
}
# Create a dummy target so that we can get the runtime deps for each test
# and output them into a file. The runtime deps include all of the data files,
# data directories, and shared libraries that a test needs in order to run.
foreach(_test, invoker.tests) {
_test_name = get_label_info(_test, "name")
group(_test_name + "_cast_runtime_deps") {
testonly = true
data_deps = [
_test,
]
write_runtime_deps =
"${_shared_dir}/runtime_deps/${_test_name}_runtime_deps.txt"
}
}
# This action generates a list of target names to build and run. It will be
# depended upon by the "pack_build" action of the cast_test_group_list
# instance which depends on this cast_test_group.
action(target_name + "_create_list") {
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
"$_output_prefix.tests",
]
args = [
"-o",
rebase_path("$_output_prefix.tests", root_build_dir),
"create_list",
]
args += _test_names
deps = []
if (defined(invoker.deps)) {
foreach(_dep, invoker.deps) {
deps += [ _dep + "_create_list" ]
}
}
}
# This action generates a list of test filters, which will have a priority
# [1-9]. This will be depended upon by the "pack_run" action of the
# cast_test_group_list which depends on this group.
action(target_name + "_filters") {
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
"$_output_prefix.filters",
]
args = [
"-o",
rebase_path("$_output_prefix.filters", root_build_dir),
"create_list",
]
args += _filters
deps = []
if (defined(invoker.deps)) {
foreach(_dep, invoker.deps) {
deps += [ _dep + "_filters" ]
}
}
}
# This target allows us to reference each test as a fully-qualified GN path,
# to ensure that each path is correct. If a test does not exist, gives a
# helpful error message at the line it is included. Do not build this target
# directly.
group(target_name + "_build_tests") {
testonly = true
deps = invoker.tests
if (defined(invoker.deps)) {
foreach(_dep, invoker.deps) {
deps += [ _dep + "_build_tests" ]
}
}
}
}
# This template runs a script which generates lists of test to be built and run.
#
# Parameters
# test_groups (required)
# The cast_test_group() targets for which this binary is to be created.
# The targets referenced here must be cast_test_group targets, or buiding
# this target will fail.
#
# build_list_path (required)
# The absolute filepath of the output file which will hold the list of
# tests to be built.
#
# run_list_path (required)
# The absolute filepath of the output file which will hold the list of
# tests to be run, each with filters assigned by cast_groups.
#
# runtime_deps_path (required)
# The absolute filepath of the output file which will hold the json dict
# of runtime dependencies for each test to be run.
#
# additional_options (optional)
# Options which are passed to the python script, and applied to every test
#
# build_tests (optional)
# If true, all of the tests included in |test_groups| will be built as
# dependencies of this target. If false, only the lists will be generated.
# If not explicitly set, this defaults to the value of
# |build_cast_tests_by_default|. Note that if this is set to true,
# the test targets will be built after all the lists are generated.
#
# test_type (optional)
# A string, which must be either "junit" or "gtest". If not defined,
# defaults to "gtest".
#
template("cast_test_group_list") {
assert(defined(invoker.test_groups), "$target_name needs 'test_groups'")
assert(defined(invoker.run_list_path), "$target_name needs 'run_list_path'")
assert(defined(invoker.build_list_path),
"$target_name needs 'build_list_path'")
assert(defined(invoker.runtime_deps_path),
"$target_name needs 'runtime_deps_path'")
_pack_build_action = target_name + "_pack_build"
_test_type = "gtest"
if (defined(invoker.test_type)) {
assert(invoker.test_type == "gtest" || invoker.test_type == "junit")
_test_type = invoker.test_type
}
if (_test_type == "gtest") {
_shared_dir = _gtest_gen_dir
} else if (_test_type == "junit") {
_shared_dir = _junit_gen_dir
}
# Add the run list to runtime data dependencies
data = [
invoker.run_list_path,
invoker.runtime_deps_path,
]
# Generate a list of the "create_list" actions for each group. These will be
# depended upon to ensure they're run before the "pack_build" step.
_build_actions = []
foreach(_test_group, invoker.test_groups) {
_build_actions += [ _test_group + "_create_list" ]
}
# Generate a list of the "filter" actions for each group. These will be
# depended upon to ensure they're run before the "pack_run" step.
_filter_actions = []
foreach(_test_group, invoker.test_groups) {
_filter_actions += [ _test_group + "_filters" ]
}
# Decide whether tests are built as dependencies.
_build_cast_tests = build_cast_tests_by_default
if (defined(invoker.build_tests)) {
_build_cast_tests = invoker.build_tests
}
# Generate a list of the groups of targets, so that they can be depended upon
# by the "pack_run" step and built when this target is invoked.
if (_build_cast_tests) {
_build_test_targets = []
foreach(_test_group, invoker.test_groups) {
_build_test_targets += [ _test_group + "_build_tests" ]
}
}
# The "pack_build" step. This step looks in the common folder for files with
# the ".tests" extenstion, collecting these and packing them into an output
# file. The steps which create these files are depeneded upon, to ensure
# they're run before this step. Do not invoke this target directly.
action(_pack_build_action) {
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
invoker.build_list_path,
]
args = [
"-o",
rebase_path(invoker.build_list_path, root_build_dir),
"-t",
rebase_path(_shared_dir, root_build_dir),
"pack_build",
]
deps = _build_actions
}
# The "pack_run" step. This step looks in the common folder for files with
# the ".tests" and ".filters" extensions, creating a script of tests to run,
# with filters and priorities. See
# //chromecast/tools/build/generate_test_lists.py for more information.
# Note that this target takes the name of the invoker, such that invoking the
# target runs this step.
action(target_name) {
testonly = true
script = "//chromecast/tools/build/generate_test_lists.py"
outputs = [
invoker.run_list_path,
invoker.runtime_deps_path,
]
args = [
"-o",
rebase_path(invoker.run_list_path, root_build_dir),
"-d",
rebase_path(invoker.runtime_deps_path, root_build_dir),
"-t",
rebase_path(_shared_dir, root_build_dir),
"pack_run",
]
# Add addtional options if they have been set.
if (defined(invoker.additional_options)) {
args += [ "-a" ]
args += invoker.additional_options
}
# Depend first on the "pack_build" step, so that the build lists are created.
deps = [
":$_pack_build_action",
]
# Next, depend on the filter steps, such that they are created before this
# script executes.
deps += _filter_actions
# If |_build_cast_tests| has been set to true, depend on the testing targets
# so that the tests are built.
if (_build_cast_tests) {
deps += _build_test_targets
}
if (chromecast_branding != "public") {
deps += [ "//chromecast/internal:cast_test_checker" ]
}
}
}