aboutsummaryrefslogtreecommitdiff
path: root/tests/core/nogo/vet/vet_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/core/nogo/vet/vet_test.go')
-rw-r--r--tests/core/nogo/vet/vet_test.go179
1 files changed, 179 insertions, 0 deletions
diff --git a/tests/core/nogo/vet/vet_test.go b/tests/core/nogo/vet/vet_test.go
new file mode 100644
index 00000000..4bc2163f
--- /dev/null
+++ b/tests/core/nogo/vet/vet_test.go
@@ -0,0 +1,179 @@
+// 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 vet_test
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "regexp"
+ "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_tool_library", "nogo")
+
+nogo(
+ name = "nogo",
+ vet = True,
+ visibility = ["//visibility:public"],
+)
+
+go_library(
+ name = "has_errors",
+ srcs = ["has_errors.go"],
+ importpath = "haserrors",
+ deps = [":fmtwrap"],
+)
+
+go_library(
+ name = "no_errors",
+ srcs = ["no_errors.go"],
+ cgo = True,
+ importpath = "noerrors",
+)
+
+go_library(
+ name = "fmtwrap",
+ srcs = ["fmtwrap.go"],
+ importpath = "fmtwrap",
+)
+
+-- has_errors.go --
+package haserrors
+
+// +build build_tags_error
+
+import (
+ "fmtwrap"
+ "sync/atomic"
+)
+
+func F() {}
+
+func Foo() bool {
+ x := uint64(1)
+ _ = atomic.AddUint64(&x, 1)
+ if F == nil { // nilfunc error.
+ return false
+ }
+ fmtwrap.Printf("%b", "hi") // printf error.
+ return true || true // redundant boolean error.
+}
+
+-- no_errors.go --
+package noerrors
+
+// const int x = 1;
+import "C"
+
+func Foo() bool {
+ return bool(C.x == 1)
+}
+
+-- fmtwrap.go --
+package fmtwrap
+
+import "fmt"
+
+func Printf(format string, args ...interface{}) {
+ fmt.Printf(format, args...)
+}
+`,
+ })
+}
+
+func Test(t *testing.T) {
+ for _, test := range []struct {
+ desc, nogo, target string
+ wantSuccess bool
+ includes, excludes []string
+ }{
+ {
+ desc: "default",
+ target: "//:has_errors",
+ wantSuccess: true,
+ excludes: []string{
+ "\\+build comment must appear before package clause and be followed by a blank line",
+ "comparison of function F == nil is always false",
+ "Printf format %b has arg \"hi\" of wrong type string",
+ "redundant or: true \\|\\| true",
+ },
+ }, {
+ desc: "enabled_no_errors",
+ target: "//:no_errors",
+ wantSuccess: true,
+ }, {
+ desc: "enabled_has_errors",
+ nogo: "@//:nogo",
+ target: "//:has_errors",
+ includes: []string{
+ "misplaced \\+build comment",
+ "comparison of function F == nil is always false",
+ "Printf format %b has arg \"hi\" of wrong type string",
+ "redundant or: true \\|\\| true",
+ },
+ },
+ } {
+ t.Run(test.desc, func(t *testing.T) {
+ if test.nogo != "" {
+ origRegister := "go_register_toolchains()"
+ customRegister := fmt.Sprintf("go_register_toolchains(nogo = %q)", test.nogo)
+ if err := replaceInFile("WORKSPACE", origRegister, customRegister); err != nil {
+ t.Fatal(err)
+ }
+ defer replaceInFile("WORKSPACE", customRegister, origRegister)
+ }
+
+ cmd := bazel_testing.BazelCmd("build", test.target)
+ stderr := &bytes.Buffer{}
+ cmd.Stderr = stderr
+ if err := cmd.Run(); err == nil && !test.wantSuccess {
+ t.Fatal("unexpected success")
+ } else if err != nil && test.wantSuccess {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ for _, pattern := range test.includes {
+ if matched, err := regexp.Match(pattern, stderr.Bytes()); err != nil {
+ t.Fatal(err)
+ } else if !matched {
+ t.Errorf("output did not contain pattern: %s", pattern)
+ }
+ }
+ for _, pattern := range test.excludes {
+ if matched, err := regexp.Match(pattern, stderr.Bytes()); err != nil {
+ t.Fatal(err)
+ } else if matched {
+ t.Errorf("output contained pattern: %s", pattern)
+ }
+ }
+ })
+ }
+}
+
+func replaceInFile(path, old, new string) error {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ data = bytes.ReplaceAll(data, []byte(old), []byte(new))
+ return ioutil.WriteFile(path, data, 0666)
+}