Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collect coverage from cc_binary data deps of java_test #15216

Merged
merged 1 commit into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
attr(":lcov_merger", LABEL)
.cfg(ExecutionTransitionFactory.create())
.value(BaseRuleClasses.getCoverageOutputGeneratorLabel()))
// Add the script as an attribute in order for java_test to output code coverage results for
// code covered by CC binaries invocations.
.add(
attr("$collect_cc_coverage", LABEL)
.cfg(ExecutionTransitionFactory.create())
.singleArtifact()
.value(env.getToolsLabel("//tools/test:collect_cc_coverage")))
/* <!-- #BLAZE_RULE(java_test).ATTRIBUTE(test_class) -->
The Java class to be loaded by the test runner.<br/>
<p>
Expand Down
153 changes: 153 additions & 0 deletions src/test/shell/bazel/bazel_coverage_java_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,25 @@ EOF
cat $(rlocation io_bazel/src/test/shell/bazel/testdata/jdk_http_archives) >> WORKSPACE
}

# Returns 0 if gcov is not installed or if a version before 7.0 was found.
# Returns 1 otherwise.
function is_gcov_missing_or_wrong_version() {
local -r gcov_location=$(which gcov)
if [[ ! -x ${gcov_location:-/usr/bin/gcov} ]]; then
echo "gcov not installed."
return 0
fi

"$gcov_location" -version | grep "LLVM" && \
echo "gcov LLVM version not supported." && return 0
# gcov -v | grep "gcov" outputs a line that looks like this:
# gcov (Debian 7.3.0-5) 7.3.0
local gcov_version="$(gcov -v | grep "gcov" | cut -d " " -f 4 | cut -d "." -f 1)"
[ "$gcov_version" -lt 7 ] \
&& echo "gcov versions before 7.0 is not supported." && return 0
return 1
}

# Asserts if the given expected coverage result is included in the given output
# file.
#
Expand Down Expand Up @@ -990,4 +1009,138 @@ BRH:5"
assert_coverage_result "$expected_result" "$coverage_file_path"
}

function test_java_test_coverage_cc_binary() {
if is_gcov_missing_or_wrong_version; then
echo "Skipping test." && return
fi

########### Setup source files and BUILD file ###########
cat <<EOF > BUILD
java_test(
name = "NumJava",
srcs = ["NumJava.java"],
data = ["//examples/cpp:num-world"],
main_class = "main.NumJava",
use_testrunner = False,
)
EOF
cat <<EOF > NumJava.java
package main;

public class NumJava {
public static void main(String[] args) throws java.io.IOException {
Runtime.getRuntime().exec("examples/cpp/num-world");
}
}
EOF

mkdir -p examples/cpp

cat <<EOF > examples/cpp/BUILD
package(default_visibility = ["//visibility:public"])

cc_binary(
name = "num-world",
srcs = ["num-world.cc"],
deps = [":num-lib"],
)

cc_library(
name = "num-lib",
srcs = ["num-lib.cc"],
hdrs = ["num-lib.h"]
)
EOF

cat <<EOF > examples/cpp/num-world.cc
#include "examples/cpp/num-lib.h"

using num::NumLib;

int main(int argc, char** argv) {
NumLib lib(30);
int value = 42;
if (argc > 1) {
value = 43;
}
lib.add_number(value);
return 0;
}
EOF

cat <<EOF > examples/cpp/num-lib.h
#ifndef EXAMPLES_CPP_NUM_LIB_H_
#define EXAMPLES_CPP_NUM_LIB_H_

namespace num {

class NumLib {
public:
explicit NumLib(int number);

int add_number(int value);

private:
int number_;
};

} // namespace num

#endif // EXAMPLES_CPP_NUM_LIB_H_
EOF

cat <<EOF > examples/cpp/num-lib.cc
#include "examples/cpp/num-lib.h"

namespace num {

NumLib::NumLib(int number) : number_(number) {
}

int NumLib::add_number(int value) {
return number_ + value;
}

} // namespace num
EOF

########### Run bazel coverage ###########
bazel coverage --test_output=all \
//:NumJava &>$TEST_log || fail "Coverage for //:NumJava failed"

########### Assert coverage results. ###########
local coverage_file_path="$( get_coverage_file_path_from_test_log )"
local expected_result_num_lib="SF:examples/cpp/num-lib.cc
FN:8,_ZN3num6NumLib10add_numberEi
FN:5,_ZN3num6NumLibC2Ei
FNDA:1,_ZN3num6NumLib10add_numberEi
FNDA:1,_ZN3num6NumLibC2Ei
FNF:2
FNH:2
DA:5,1
DA:6,1
DA:8,1
DA:9,1
LH:4
LF:4
end_of_record"
assert_coverage_result "$expected_result_num_lib" "$coverage_file_path"
local coverage_result_num_lib_header="SF:examples/cpp/num-world.cc
FN:5,main
FNDA:1,main
FNF:1
FNH:1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,0
DA:11,1
DA:12,1
LH:6
LF:7
end_of_record"
assert_coverage_result "$coverage_result_num_lib_header" "$coverage_file_path"
}

run_suite "test tests"