aboutsummaryrefslogtreecommitdiff
path: root/tests/core/coverage/coverage_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/core/coverage/coverage_test.go')
-rw-r--r--tests/core/coverage/coverage_test.go265
1 files changed, 265 insertions, 0 deletions
diff --git a/tests/core/coverage/coverage_test.go b/tests/core/coverage/coverage_test.go
new file mode 100644
index 00000000..52bda780
--- /dev/null
+++ b/tests/core/coverage/coverage_test.go
@@ -0,0 +1,265 @@
+// Copyright 2019 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package coverage_test
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "path/filepath"
+ "testing"
+
+ "github.com/bazelbuild/rules_go/go/tools/bazel_testing"
+)
+
+func TestMain(m *testing.M) {
+ bazel_testing.TestMain(m, bazel_testing.Args{
+ Main: `
+-- BUILD.bazel --
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_test(
+ name = "a_test",
+ srcs = ["a_test.go"],
+ embed = [":a"],
+)
+
+go_test(
+ name = "a_test_cross",
+ srcs = ["a_test.go"],
+ embed = [":a"],
+ goarch = "386",
+ goos = "linux",
+ pure = "on",
+ tags = ["manual"],
+)
+
+go_library(
+ name = "a",
+ srcs = ["a.go"],
+ importpath = "example.com/coverage/a",
+ deps = [":b"],
+)
+
+go_library(
+ name = "b",
+ srcs = ["b.go"],
+ importpath = "example.com/coverage/b",
+ deps = [":c"],
+)
+
+go_library(
+ name = "c",
+ srcs = ["c.go"],
+ importpath = "example.com/coverage/c",
+)
+
+go_library(
+ name = "d",
+ srcs = ["d.go"],
+ importpath = "example.com/coverage/d",
+)
+
+go_test(
+ name = "d_test",
+ embed = [":d"],
+)
+
+go_library(
+ name = "panicking",
+ srcs = ["panicking.go"],
+ importpath = "example.com/coverage/panicking",
+)
+
+go_test(
+ name = "panicking_test",
+ srcs = ["panicking_test.go"],
+ embed = [":panicking"],
+)
+-- a_test.go --
+package a
+
+import "testing"
+
+func TestA(t *testing.T) {
+ ALive()
+}
+-- a.go --
+package a
+
+import "example.com/coverage/b"
+
+func ALive() int {
+ return b.BLive()
+}
+
+func ADead() int {
+ return b.BDead()
+}
+
+-- b.go --
+package b
+
+import "example.com/coverage/c"
+
+func BLive() int {
+ return c.CLive()
+}
+
+func BDead() int {
+ return c.CDead()
+}
+
+-- c.go --
+package c
+
+func CLive() int {
+ return 12
+}
+
+func CDead() int {
+ return 34
+}
+
+-- d.go --
+package lzma
+
+/* Naming conventions follows the CodeReviewComments in the Go Wiki. */
+
+// ntz32Const is used by the functions NTZ and NLZ.
+const ntz32Const = 0x04d7651f
+-- panicking.go --
+package panicking
+
+func Panic() {
+ panic("from line 4")
+}
+-- panicking_test.go --
+package panicking
+
+import (
+ "regexp"
+ "runtime/debug"
+ "testing"
+)
+
+func TestPanic(t *testing.T) {
+ defer func() {
+ if err := recover(); err != nil {
+ got := regexp.MustCompile("panicking.go:[0-9]+").
+ FindString(string(debug.Stack()))
+ if want := "panicking.go:4"; want != got {
+ t.Errorf("want %q; got %q", want, got)
+ }
+ }
+ }()
+ Panic()
+}
+`,
+ })
+}
+
+func TestCoverage(t *testing.T) {
+ t.Run("without-race", func(t *testing.T) {
+ testCoverage(t, "set")
+ })
+
+ t.Run("with-race", func(t *testing.T) {
+ testCoverage(t, "atomic", "--@io_bazel_rules_go//go/config:race")
+ })
+}
+
+func testCoverage(t *testing.T, expectedCoverMode string, extraArgs ...string) {
+ args := append([]string{"coverage"}, append(
+ extraArgs,
+ "--instrumentation_filter=-//:b",
+ "--@io_bazel_rules_go//go/config:cover_format=go_cover",
+ ":a_test",
+ )...)
+
+ if err := bazel_testing.RunBazel(args...); err != nil {
+ t.Fatal(err)
+ }
+
+ coveragePath := filepath.FromSlash("bazel-testlogs/a_test/coverage.dat")
+ coverageData, err := ioutil.ReadFile(coveragePath)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, include := range []string{
+ fmt.Sprintf("mode: %s", expectedCoverMode),
+ "example.com/coverage/a/a.go:",
+ "example.com/coverage/c/c.go:",
+ } {
+ if !bytes.Contains(coverageData, []byte(include)) {
+ t.Errorf("%s: does not contain %q\n", coveragePath, include)
+ }
+ }
+ for _, exclude := range []string{
+ "example.com/coverage/b/b.go:",
+ } {
+ if bytes.Contains(coverageData, []byte(exclude)) {
+ t.Errorf("%s: contains %q\n", coveragePath, exclude)
+ }
+ }
+}
+
+func TestCrossBuild(t *testing.T) {
+ t.Run("lcov", func(t *testing.T) {
+ testCrossBuild(t)
+ })
+ t.Run("cover", func(t *testing.T) {
+ testCrossBuild(t, "--@io_bazel_rules_go//go/config:cover_format=go_cover")
+ })
+}
+
+func testCrossBuild(t *testing.T, extraArgs ...string) {
+ if err := bazel_testing.RunBazel(append(
+ []string{"build", "--collect_code_coverage", "--instrumentation_filter=-//:b", "//:a_test_cross"},
+ extraArgs...,
+ )...); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestCoverageWithComments(t *testing.T) {
+ t.Run("lcov", func(t *testing.T) {
+ testCoverageWithComments(t)
+ })
+ t.Run("go_cover", func(t *testing.T) {
+ testCoverageWithComments(t, "--@io_bazel_rules_go//go/config:cover_format=go_cover")
+ })
+}
+
+func testCoverageWithComments(t *testing.T, extraArgs ...string) {
+ if err := bazel_testing.RunBazel(append([]string{"coverage", ":d_test"}, extraArgs...)...); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestCoverageWithCorrectLineNumbers(t *testing.T) {
+ t.Run("lcov", func(t *testing.T) {
+ testCoverageWithCorrectLineNumbers(t)
+ })
+ t.Run("go_cover", func(t *testing.T) {
+ testCoverageWithCorrectLineNumbers(t, "--@io_bazel_rules_go//go/config:cover_format=go_cover")
+ })
+}
+
+func testCoverageWithCorrectLineNumbers(t *testing.T, extraArgs ...string) {
+ if err := bazel_testing.RunBazel(append([]string{"coverage", ":panicking_test"}, extraArgs...)...); err != nil {
+ t.Fatal(err)
+ }
+}