Skip to content

Commit a5c6178

Browse files
authored
fix kj-test & wd-test test coverage reporting (#5881)
1 parent 2752663 commit a5c6178

File tree

18 files changed

+91
-60
lines changed

18 files changed

+91
-60
lines changed

.bazelrc

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,15 @@ build:v8-codegen-opt --per_file_copt=external/abseil-cpp@-O2
6868
# zlib and tcmalloc (for Linux) are also CPU-intensive, optimize them too.
6969
build:v8-codegen-opt --per_file_copt=external/tcmalloc@-O2
7070
build:v8-codegen-opt --per_file_copt=external/zlib@-O2
71+
# BoringSSL is CPU-intensive for crypto tests, optimize it too.
72+
build:v8-codegen-opt --per_file_copt=external/boringssl@-O2
73+
# simdutf is used for fast string encoding/decoding
74+
build:v8-codegen-opt --per_file_copt=external/+http+simdutf@-O2
7175
build:v8-codegen-opt-windows --per_file_copt=v8/src@/O2
7276
build:v8-codegen-opt-windows --per_file_copt=external/abseil-cpp@/O2
7377
build:v8-codegen-opt-windows --per_file_copt=external/zlib@/O2
78+
build:v8-codegen-opt-windows --per_file_copt=external/boringssl@/O2
79+
build:v8-codegen-opt-windows --per_file_copt=external/+http+simdutf@/O2
7480

7581
# In Google projects, exceptions are not used as a rule. Disabling them is more consistent with the
7682
# canonical V8 build and improves code size. Paths are adjusted for bzlmod mangling – V8 and ICU use
@@ -415,29 +421,59 @@ build:coverage --test_env=BAZEL_USE_LLVM_NATIVE_COVERAGE=1
415421
# GCOV is used by rules_cc to merge raw profile data (.profraw) into indexed profile data (.profdata)
416422
build:coverage --action_env=GCOV=llvm-profdata
417423
build:coverage --test_env=GCOV=llvm-profdata
424+
# COVERAGE_GCOV_PATH is used by collect_cc_coverage.sh for merging .profraw files.
425+
build:coverage --action_env=COVERAGE_GCOV_PATH=/usr/bin/llvm-profdata
426+
build:coverage --test_env=COVERAGE_GCOV_PATH=/usr/bin/llvm-profdata
418427
# BAZEL_LLVM_COV is used by rules_cc to generate coverage reports from profile data
419428
build:coverage --action_env=BAZEL_LLVM_COV=llvm-cov
420429
build:coverage --test_env=BAZEL_LLVM_COV=llvm-cov
421-
# Enable optimizations to reduce coverage overhead while maintaining good coverage quality
422-
build:coverage --copt=-O2
423-
build:coverage --copt=-DNDEBUG
424-
build:coverage --combined_report=lcov
430+
# LLVM_COV is used by collect_cc_coverage.sh for generating LCOV output
431+
build:coverage --test_env=LLVM_COV=llvm-cov
432+
# GENERATE_LLVM_LCOV=1 tells collect_cc_coverage.sh to use llvm-cov export to generate LCOV format
433+
# instead of just outputting raw profdata. LLVM_COV specifies the llvm-cov binary to use.
434+
build:coverage --test_env=GENERATE_LLVM_LCOV=1
425435
build:coverage --experimental_use_llvm_covmap
426436
build:coverage --experimental_generate_llvm_lcov
437+
# Ensure that we fetch coverage data from remote cache
427438
build:coverage --experimental_fetch_all_coverage_outputs
439+
build:coverage --experimental_split_coverage_postprocessing
440+
# Allow coverage outputs to be writable for post-processing
441+
build:coverage --experimental_writable_outputs
428442
build:coverage --collect_code_coverage
429-
build:coverage --instrumentation_filter="^//,-//external"
443+
# Only instrument source code, not tests or tools - significantly speeds up coverage builds
444+
build:coverage --instrumentation_filter="^//src/workerd[/:],^//src/rust[/:]"
430445
build:coverage --instrument_test_targets
446+
# Disable coverage instrumentation for external dependencies to speed up compilation.
447+
# Coverage for V8/external code is not useful for our purposes.
448+
# These flags negate -fprofile-instr-generate and -fcoverage-mapping set by rules_cc.
449+
build:coverage --per_file_copt=external/.*@-fno-profile-instr-generate,-fno-coverage-mapping
431450
# KJ uses _exit() by default which bypasses atexit handlers and prevents LLVM profile runtime
432451
# from writing coverage data. KJ_CLEAN_SHUTDOWN forces use of normal exit() instead.
433452
build:coverage --test_env=KJ_CLEAN_SHUTDOWN=1
453+
# Use -O1 for faster compilation - coverage builds don't need heavy optimization
454+
build:coverage --copt=-O1
455+
# External dependencies can use -O2 since they're not instrumented anyway
456+
build:coverage --config=v8-codegen-opt
457+
# Run coverage-related actions locally with sandboxing - remote execution doesn't support LLVM coverage well
458+
build:coverage --strategy=TestRunner=worker,sandboxed,local
459+
build:coverage --strategy=CoverageReport=worker,sandboxed,local
460+
build:coverage --strategy=CoveragePostprocessing=worker,sandboxed,local
461+
# Reduce debug info for faster compilation and smaller binaries
462+
build:coverage --copt=-g1
463+
# Use limited coverage mode for smaller binaries and faster execution (used by Chromium)
464+
build:coverage --copt=-mllvm
465+
build:coverage --copt=-limited-coverage-experimental=true
434466
coverage --test_tag_filters=-off-by-default,-requires-fuzzilli,-requires-container-engine,-lint,-benchmark,-workerd-benchmark,-no-coverage
467+
# Let tests know they're running in CI (normally set by ci-test but we can't use that config
468+
# due to --remote_download_minimal which prevents coverage data from being fetched)
469+
coverage --test_env=CI=true
470+
coverage --config=wpt-test
435471
# Coverage instrumentation slows down test execution, so extend timeouts
436472
# We disable enormous tests due to the slowdown (CI jobs have a 6h max duration)
437473
coverage --test_size_filters=-enormous
438-
coverage --test_timeout=60,240,240,240
474+
coverage --test_timeout=240,240,240,240
439475
coverage --build_tests_only
440-
coverage --config=coverage
476+
coverage --combined_report=lcov
441477

442478
# This config is defined internally and enabled on many machines.
443479
# Defining it as empty just so these machines can run build commands from the workerd repo

.github/actions/setup-runner/action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ runs:
2323
libclang-rt-19-dev \
2424
llvm-19
2525
sudo ln -s /usr/bin/llvm-symbolizer-19 /usr/bin/llvm-symbolizer
26+
sudo ln -s /usr/bin/llvm-profdata-19 /usr/bin/llvm-profdata
27+
sudo ln -s /usr/bin/llvm-cov-19 /usr/bin/llvm-cov
2628
echo "build:linux --action_env=CC=/usr/lib/llvm-19/bin/clang" >> .bazelrc
2729
echo "build:linux --host_action_env=CC=/usr/lib/llvm-19/bin/clang" >> .bazelrc
2830
echo "build:linux --linkopt=--ld-path=/usr/lib/llvm-19/bin/ld.lld" >> .bazelrc

.github/workflows/_bazel.yml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ jobs:
125125
run: |
126126
bazel --nowindows_enable_symlinks build ${{ inputs.extra_bazel_args }} --config=ci --profile build-win-workaround.bazel-profile.gz --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev //src/wpt:wpt-all@tsproject //src/node:node@tsproject //src/pyodide:pyodide_static@tsproject
127127
- name: Bazel build
128-
# timestamps are no longer being added here, the GitHub logs include timestamps (Use
129-
# 'Show timestamps' on the web interface)
130128
run: |
131129
bazel build --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} //...
132130
- name: Build and load container images
@@ -142,23 +140,20 @@ jobs:
142140
if: inputs.run_tests
143141
run: |
144142
bazel test --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} ${{ inputs.test_target }}
145-
- name: Setup LLVM tools for coverage
146-
if: inputs.run_coverage
147-
run: |
148-
sudo apt-get update && sudo apt-get install -y llvm
149-
sudo ln -sf /usr/bin/llvm-profdata /usr/local/bin/llvm-profdata
150-
sudo ln -sf /usr/bin/llvm-cov /usr/local/bin/llvm-cov
151143
- name: Bazel coverage
152144
if: inputs.run_coverage
153145
run: |
154-
bazel coverage --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci --config=coverage ${{ inputs.extra_bazel_args }} ${{ inputs.test_target }}
146+
bazel coverage --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} ${{ inputs.test_target }}
155147
- name: Upload coverage to Codecov
156148
if: inputs.run_coverage
157149
uses: codecov/codecov-action@v5
158150
with:
159-
files: ./bazel-out/_coverage/_coverage_report.dat
151+
# Use bazel info to get the actual output path, avoiding symlink issues
152+
files: ${{ github.workspace }}/bazel-out/_coverage/_coverage_report.dat
160153
fail_ci_if_error: true
161154
verbose: true
155+
disable_search: true
156+
root_dir: ${{ github.workspace }}
162157
env:
163158
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
164159
- name: Parse headers

.github/workflows/test.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,12 @@ jobs:
104104
os_name: linux
105105
arch_name: 'X64'
106106
suffix: 'coverage'
107+
# Don't use ci-test here because it enables --remote_download_minimal which prevents
108+
# coverage data from being fetched from cache. The coverage config already sets
109+
# --test_env=CI=true and --config=wpt-test which are the relevant parts of ci-test.
107110
# Use ci-linux-common instead of ci-linux to avoid overriding coverage test_tag_filters
108111
# (ci-linux sets test_tag_filters that would include container tests which require docker)
109-
extra_bazel_args: '--config=ci-test --config=ci-linux-common --config=ci-limit-storage'
112+
extra_bazel_args: '--config=ci-linux-common --config=ci-limit-storage --config=coverage'
110113
upload_test_logs: true
111114
upload_binary: false
112115
build_container_images: false

build/fixtures/kj_test.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
#!/bin/bash
22
set -euo pipefail
3-
"$@"
3+
4+
if [ -n "${COVERAGE_DIR:-}" ]; then
5+
export LLVM_PROFILE_FILE="$COVERAGE_DIR/%p-%m.profraw"
6+
fi
7+
8+
exec "$@"

build/kj_test.bzl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,20 @@ def kj_test(
5050

5151
sh_test(
5252
name = test_name + "@",
53-
size = size,
5453
srcs = ["//build/fixtures:kj_test.sh"],
55-
data = [cross_alias] + data,
56-
args = ["$(location " + cross_alias + ")"],
54+
args = ["$(location {})".format(cross_alias)],
55+
data = data + [cross_alias],
5756
tags = tags,
57+
size = size,
5858
)
59+
5960
sh_test(
6061
name = test_name + "@all-autogates",
61-
size = size,
62-
env = {"WORKERD_ALL_AUTOGATES": "1"},
6362
srcs = ["//build/fixtures:kj_test.sh"],
64-
data = [cross_alias] + data,
65-
args = ["$(location " + cross_alias + ")"],
66-
tags = tags,
63+
args = ["$(location {})".format(cross_alias)],
64+
data = data + [cross_alias],
65+
env = {"WORKERD_ALL_AUTOGATES": "1"},
66+
# Tag with no-coverage to reduce coverage CI time
67+
tags = tags + ["no-coverage"],
68+
size = size,
6769
)

build/wd_cc_binary.bzl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,5 @@ def wd_cc_binary(
4747
"@//build/config:prebuilt_binaries_arm64": "@//:bin.arm64/tmp/{}/{}.aarch64-linux-gnu".format(pkg, prebuilt_binary_name),
4848
"//conditions:default": name,
4949
}),
50-
# Propagate InstrumentedFilesInfo through the alias for coverage support
5150
testonly = kwargs.get("testonly", False),
5251
)

build/wd_rust_binary.bzl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ def wd_rust_binary(
5454
visibility = visibility,
5555
data = data,
5656
proc_macro_deps = proc_macro_deps,
57-
experimental_use_cc_common_link = select({
58-
"@platforms//os:windows": 0,
59-
"//conditions:default": 1,
60-
}),
6157
target_compatible_with = select({
6258
"@//build/config:no_build": ["@platforms//:incompatible"],
6359
"//conditions:default": [],
@@ -74,10 +70,6 @@ def wd_rust_binary(
7470
# our tests are usually very heavy and do not support concurrent invocation
7571
"RUST_TEST_THREADS": "1",
7672
},
77-
experimental_use_cc_common_link = select({
78-
"@platforms//os:windows": 0,
79-
"//conditions:default": 1,
80-
}),
8173
target_compatible_with = select({
8274
"@//build/config:no_build": ["@platforms//:incompatible"],
8375
"//conditions:default": [],

build/wd_rust_crate.bzl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,6 @@ def wd_rust_crate(
148148
crate_features = crate_features,
149149
deps = test_deps,
150150
proc_macro_deps = test_proc_macro_deps,
151-
experimental_use_cc_common_link = select({
152-
"@platforms//os:windows": 0,
153-
"//conditions:default": 1,
154-
}),
155151
)
156152

157153
if len(proc_macro_deps) + len(cxx_bridge_srcs) > 0:

build/wd_rust_proc_macro.bzl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,4 @@ def wd_rust_proc_macro(
4747
} | test_env,
4848
tags = test_tags,
4949
deps = test_deps,
50-
experimental_use_cc_common_link = select({
51-
"@platforms//os:windows": 0,
52-
"//conditions:default": 1,
53-
}),
5450
)

0 commit comments

Comments
 (0)