Proof of concept for test selection via GN
This CL implements gn based unittest filtering. The files in the rts_exclude_file are manually selected for this example, but will later be populated using the smart logic in rts-chromium. These two cases (source_set and test template) cover most of the test files. I haven't seen any other templates with unittests, but even if there are some this would be a great start. This also doesn't cover webtests, but I think there's enough exclusion power here to save a lot of compute. This also adds a linux-rts builder to the mb config to prepare the experimental builder. Bug: 1145216 Change-Id: I7343249f3df0739e39cfe351e5714d7978059d86 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2551276 Commit-Queue: Gregory Guterman <guterman@google.com> Reviewed-by: Dirk Pranke <dpranke@google.com> Reviewed-by: Nodir Turakulov <nodir@chromium.org> Cr-Commit-Position: refs/heads/master@{#841248}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
927b1789db
commit
8da79b7118
build/config
docs/testing
testing
tools/mb
@ -162,6 +162,17 @@ declare_args() {
|
||||
is_component_build = is_debug && current_os != "ios"
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
# Regression Test Selection (RTS).
|
||||
# https://chromium.googlesource.com/chromium/src/+/master/docs/testing/regression-test-selection.md
|
||||
#
|
||||
# Exclude unittest/browsertest files listed in this file.
|
||||
#
|
||||
# Entries should be newline separated.
|
||||
# Each entry much be an source-absolute path starting with //.
|
||||
rts_exclude_file = ""
|
||||
}
|
||||
|
||||
assert(!(is_debug && is_official_build), "Can't do official debug builds")
|
||||
|
||||
# ==============================================================================
|
||||
@ -575,3 +586,32 @@ set_defaults("component") {
|
||||
configs = default_compiler_configs
|
||||
}
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# Regression Test Selection (RTS)
|
||||
# https://chromium.googlesource.com/chromium/src/+/master/docs/testing/regression-test-selection.md
|
||||
# ==============================================================================
|
||||
if (rts_exclude_file != "") {
|
||||
rts_exclusions = read_file(rts_exclude_file, "list lines")
|
||||
|
||||
# Many tests are included in source_sets
|
||||
template("source_set") {
|
||||
_target_name = target_name
|
||||
target("source_set", _target_name) {
|
||||
forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
|
||||
forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
|
||||
|
||||
if (defined(sources) && sources != []) {
|
||||
# Normalize paths
|
||||
abs_paths = get_path_info(sources, "abspath")
|
||||
|
||||
# Filter
|
||||
filtered_sources = filter_exclude(abs_paths, rts_exclusions)
|
||||
|
||||
# Do the replacement
|
||||
sources = []
|
||||
sources = filtered_sources
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
38
docs/testing/regression-test-selection.md
Normal file
38
docs/testing/regression-test-selection.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Regression test selection (RTS)
|
||||
|
||||
Regression Test Selection (RTS) is a technique to intellegently select tests to
|
||||
run, without spending too many resources on testing, but still detecting bad
|
||||
code changes.
|
||||
|
||||
[TOC]
|
||||
|
||||
## Current strategy
|
||||
|
||||
The current strategy is to skip files which we deem unaffected by the CL's
|
||||
changelist. Affectedness is estimated using the heuristic that dependent files
|
||||
are committed together. We look at git history and measure how often each file
|
||||
A appears together each file B in the same commit. If A affects B,
|
||||
and B affects C, we assume A also affects C. We represent these transitive
|
||||
relationships in a graph where files are the nodes and the probability that the
|
||||
two files affect each other are the weighted edges. The distance between two
|
||||
nodes represents the (inverse) probability that these two files affect
|
||||
each other. Finally, we skip tests in files that are farther than a
|
||||
certain distance from the files in the CL.
|
||||
|
||||
## Skipping mechanism
|
||||
|
||||
Test skipping happens at the GN level in
|
||||
[source_set](/build/config/BUILDCONFIG.gn) and [test](/testing/test.gni)
|
||||
GN targets.
|
||||
|
||||
## Known failure mode
|
||||
|
||||
Consider a test file A that contains unit tests, as well as some variables
|
||||
used in another file B. When our RTS strategy excludes A, but not B, a
|
||||
compilation error will occur.
|
||||
|
||||
## Design Docs
|
||||
|
||||
- [File-level RTS](http://doc/1KWG82gNpkaRAchlp3jtENFdlefGvJxMHkAszlu9fo1c)
|
||||
- [Chrome RTS](http://doc/10RP1XRw8ZSrvgVky1flH7ykAaIaG15RymM4gW7bFURQ)
|
||||
|
@ -41,6 +41,20 @@ if (is_android) {
|
||||
# Similar to the GN arg 'enable_run_ios_unittests_with_xctest' but
|
||||
# for build targets.
|
||||
template("test") {
|
||||
# RTS
|
||||
if (rts_exclude_file != "" && defined(invoker.sources) &&
|
||||
invoker.sources != []) {
|
||||
# Normalize paths
|
||||
abs_paths = get_path_info(invoker.sources, "abspath")
|
||||
|
||||
# Filter
|
||||
filtered_sources = filter_exclude(abs_paths, rts_exclusions)
|
||||
|
||||
# Do the replacement
|
||||
invoker.sources = []
|
||||
invoker.sources = filtered_sources
|
||||
}
|
||||
|
||||
testonly = true
|
||||
if (!is_ios) {
|
||||
assert(!defined(invoker.is_xctest) || !invoker.is_xctest,
|
||||
|
@ -994,6 +994,7 @@
|
||||
'linux-perfetto-rel': 'perfetto_release_trybot',
|
||||
'linux-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage',
|
||||
'linux-rel-builderful': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage',
|
||||
'linux-rts': 'release_trybot_rts',
|
||||
'linux-trusty-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange',
|
||||
'linux-viz-rel': 'release_trybot',
|
||||
'linux-warmed': 'release_trybot_no_symbols_use_dummy_lastchange_code_coverage',
|
||||
@ -2592,6 +2593,10 @@
|
||||
'no_goma',
|
||||
],
|
||||
|
||||
'release_trybot_rts': [
|
||||
'release_bot', 'rts_bot',
|
||||
],
|
||||
|
||||
'tsan_disable_nacl_debug_bot': [
|
||||
'tsan', 'disable_nacl', 'debug_bot',
|
||||
],
|
||||
@ -3238,6 +3243,10 @@
|
||||
'gn_args': 'enable_resource_allowlist_generation=true',
|
||||
},
|
||||
|
||||
'rts_bot': {
|
||||
'gn_args': 'rts_exclude_file="//testing/rts_exclude_file.txt"',
|
||||
},
|
||||
|
||||
'shared': {
|
||||
'gn_args': 'is_component_build=true',
|
||||
},
|
||||
|
@ -554,6 +554,14 @@
|
||||
"use_goma": true
|
||||
}
|
||||
},
|
||||
"linux-rts": {
|
||||
"gn_args": {
|
||||
"is_component_build": false,
|
||||
"is_debug": false,
|
||||
"rts_exclude_file": "//testing/rts_exclude_file.txt",
|
||||
"use_goma": true
|
||||
}
|
||||
},
|
||||
"linux-trusty-rel": {
|
||||
"gn_args": {
|
||||
"dcheck_always_on": true,
|
||||
|
Reference in New Issue
Block a user