diff options
Diffstat (limited to 'tests/core/coverage/coverage_test.go')
-rw-r--r-- | tests/core/coverage/coverage_test.go | 265 |
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) + } +} |