From 616dc264f02907d7b7887285d22307dfe6d097b6 Mon Sep 17 00:00:00 2001 From: Finn Ball Date: Wed, 7 Apr 2021 01:57:55 -0700 Subject: [PATCH] Fix Bazel Coverage with C++ to work with Remote Execution Adds missing coverage files: https://github.com/bazelbuild/bazel/issues/13193 Closes #13232. PiperOrigin-RevId: 367176195 --- .../lib/exec/StandaloneTestStrategy.java | 1 + .../bazel/remote/remote_execution_test.sh | 126 +++++++++++++++++- 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java b/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java index fd1214daf9cedb..0d45969cf43d91 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java +++ b/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java @@ -452,6 +452,7 @@ private static Spawn createCoveragePostProcessingSpawn( action.getLcovMergerRunfilesSupplier(), /* filesetMappings= */ ImmutableMap.of(), /* inputs= */ NestedSetBuilder.compileOrder() + .addAll(action.getInputs().toList()) .addAll(expandedCoverageDir) .add(action.getCollectCoverageScript()) .add(action.getCoverageDirectoryTreeArtifact()) diff --git a/src/test/shell/bazel/remote/remote_execution_test.sh b/src/test/shell/bazel/remote/remote_execution_test.sh index 51fc9261b4630b..67c514757fc6e7 100755 --- a/src/test/shell/bazel/remote/remote_execution_test.sh +++ b/src/test/shell/bazel/remote/remote_execution_test.sh @@ -2387,7 +2387,7 @@ EOF # because the coverage post-processing tool escaped the sandbox to find its own # runfiles. The error we would see here without the flag would be "Cannot find # runfiles". See #4685. -function test_rbe_coverage_produces_report() { +function test_java_rbe_coverage_produces_report() { mkdir -p java/factorial JAVA_TOOLCHAIN="@bazel_tools//tools/jdk:toolchain" @@ -2477,4 +2477,128 @@ end_of_record" assert_equals "$expected_result" "$(cat bazel-testlogs/java/factorial/fact-test/coverage.dat)" } +# Runs coverage with `cc_test` and RE then checks the coverage file is returned. +# Older versions of gcov are not supported with bazel coverage and so will be skipped. +# See the above `test_java_rbe_coverage_produces_report` for more information. +function test_cc_rbe_coverage_produces_report() { + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + + # Check to see if intermediate files are supported, otherwise skip. + gcov --help | grep "\-i," || return 0 + + local test_dir="a/cc/coverage_test" + mkdir -p $test_dir + + cat > "$test_dir"/BUILD <<'EOF' +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "hello-lib", + srcs = ["hello-lib.cc"], + hdrs = ["hello-lib.h"], +) + +cc_binary( + name = "hello-world", + srcs = ["hello-world.cc"], + deps = [":hello-lib"], +) + +cc_test( + name = "hello-test", + srcs = ["hello-world.cc"], + deps = [":hello-lib"], +) + +EOF + + cat > "$test_dir"/hello-lib.cc <<'EOF' +#include "hello-lib.h" + +#include + +using std::cout; +using std::endl; +using std::string; + +namespace hello { + +HelloLib::HelloLib(const string& greeting) : greeting_(new string(greeting)) { +} + +void HelloLib::greet(const string& thing) { + cout << *greeting_ << " " << thing << endl; +} + +} // namespace hello + +EOF + + cat > "$test_dir"/hello-lib.h <<'EOF' +#ifndef HELLO_LIB_H_ +#define HELLO_LIB_H_ + +#include +#include + +namespace hello { + +class HelloLib { + public: + explicit HelloLib(const std::string &greeting); + + void greet(const std::string &thing); + + private: + std::unique_ptr greeting_; +}; + +} // namespace hello + +#endif // HELLO_LIB_H_ + +EOF + + cat > "$test_dir"/hello-world.cc <<'EOF' +#include "hello-lib.h" + +#include + +using hello::HelloLib; +using std::string; + +int main(int argc, char** argv) { + HelloLib lib("Hello"); + string thing = "world"; + if (argc > 1) { + thing = argv[1]; + } + lib.greet(thing); + return 0; +} + +EOF + + bazel coverage \ + --test_output=all \ + --experimental_fetch_all_coverage_outputs \ + --experimental_split_coverage_postprocessing \ + --spawn_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + //"$test_dir":hello-test >& $TEST_log \ + || fail "Failed to run coverage for cc_test" + + # Different gcov versions generate different outputs. + # Simply check if this is empty or not. + if [[ ! -s bazel-testlogs/a/cc/coverage_test/hello-test/coverage.dat ]]; then + echo "Coverage is empty. Failing now." + return 1 + fi +} + run_suite "Remote execution and remote cache tests"