Skip to content

Commit 2f834a3

Browse files
authored
coverage: force test's data executable to disable coverage (#10793)
Some of our tests depend on go_binary clis. Under coverage mode, these clis are mistakenly treated as test binaries and refused to run without specific environment variables. Apply a transition on these go_binary to disable coverage, force opt mode and exec configuration.
1 parent e3db241 commit 2f834a3

File tree

4 files changed

+74
-4
lines changed

4 files changed

+74
-4
lines changed

cli/testutil/testcli/BUILD

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
load("@io_bazel_rules_go//go:def.bzl", "go_library")
2+
load("//rules:coverage_transitions.bzl", "coverage_free_tool")
23

34
package(default_visibility = ["//cli:__subpackages__"])
45

56
go_library(
67
name = "testcli",
78
testonly = 1,
89
srcs = ["testcli.go"],
9-
data = ["//cli/cmd/bb"],
10+
data = [":bb_no_cov"],
1011
importpath = "github.com/buildbuddy-io/buildbuddy/cli/testutil/testcli",
1112
visibility = ["//visibility:public"],
1213
x_defs = {
13-
"bbRunfilePath": "$(rlocationpath //cli/cmd/bb)",
14+
"bbRunfilePath": "$(rlocationpath :bb_no_cov)",
1415
},
1516
deps = [
1617
"//cli/storage",
@@ -24,3 +25,9 @@ go_library(
2425
"@com_github_stretchr_testify//require",
2526
],
2627
)
28+
29+
coverage_free_tool(
30+
name = "bb_no_cov",
31+
tags = ["manual"],
32+
target = "//cli/cmd/bb",
33+
)

enterprise/server/remote_execution/commandutil/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ go_test(
3737
],
3838
data = select({
3939
"@io_bazel_rules_go//go/platform:windows": [],
40-
"//conditions:default": ["//enterprise/server/remote_execution/commandutil/test_binary"],
40+
"//conditions:default": ["//enterprise/server/remote_execution/commandutil/test_binary:test_binary_no_cov"],
4141
}),
4242
tags = ["cpu:4"],
4343
x_defs = select({
4444
"@io_bazel_rules_go//go/platform:windows": {},
4545
"//conditions:default": {
46-
"testBinaryRunfilePath": "$(rlocationpath //enterprise/server/remote_execution/commandutil/test_binary)",
46+
"testBinaryRunfilePath": "$(rlocationpath //enterprise/server/remote_execution/commandutil/test_binary:test_binary_no_cov)",
4747
},
4848
}),
4949
deps = [

enterprise/server/remote_execution/commandutil/test_binary/BUILD

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
2+
load("//rules:coverage_transitions.bzl", "coverage_free_tool")
23

34
package(
45
default_testonly = 1,
@@ -15,3 +16,9 @@ go_binary(
1516
name = "test_binary",
1617
embed = [":lib"],
1718
)
19+
20+
coverage_free_tool(
21+
name = "test_binary_no_cov",
22+
tags = ["manual"],
23+
target = ":test_binary",
24+
)

rules/coverage_transitions.bzl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""Transition helpers used to build tools without coverage instrumentation.
2+
3+
The coverage runner builds every target with coverage enabled, which breaks
4+
Go binaries that are used as helper tools inside tests (they print coverage
5+
warnings and behave like test binaries). The transition below disables coverage
6+
and forces an opt build for those binaries so they behave like normal tools.
7+
"""
8+
9+
def _coverage_free_exec_transition_impl(settings, attr):
10+
return {
11+
"//command_line_option:collect_code_coverage": "false",
12+
"//command_line_option:compilation_mode": "opt",
13+
}
14+
15+
# Transition that turns off coverage and forces opt in the transitioned config.
16+
coverage_free_exec_transition = transition(
17+
implementation = _coverage_free_exec_transition_impl,
18+
inputs = [],
19+
outputs = [
20+
"//command_line_option:collect_code_coverage",
21+
"//command_line_option:compilation_mode",
22+
],
23+
)
24+
25+
def _coverage_free_tool_impl(ctx):
26+
target = ctx.attr.target
27+
if type(target) == type([]):
28+
target = target[0]
29+
default = target[DefaultInfo]
30+
31+
runfiles = default.default_runfiles.merge(default.data_runfiles)
32+
33+
return [
34+
DefaultInfo(
35+
files = default.files,
36+
data_runfiles = runfiles,
37+
default_runfiles = runfiles,
38+
),
39+
]
40+
41+
# Wrapper rule that rebuilds the given executable with the coverage-free
42+
# transition, exposing identical runfiles for use in data attributes. The rule
43+
# itself transitions to disable coverage/opt builds, and the wrapped target is
44+
# built in the execution configuration so the resulting binary matches the
45+
# executor platform.
46+
coverage_free_tool = rule(
47+
implementation = _coverage_free_tool_impl,
48+
attrs = {
49+
"target": attr.label(
50+
cfg = coverage_free_exec_transition,
51+
executable = True,
52+
mandatory = True,
53+
providers = [DefaultInfo],
54+
),
55+
},
56+
)

0 commit comments

Comments
 (0)