github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/cmd/vet/vet_test.go (about)

     1  // Copyright 2013 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // No testdata on Android.
     6  
     7  // +build !android
     8  
     9  package main_test
    10  
    11  import (
    12  	"bytes"
    13  	"flag"
    14  	"fmt"
    15  	"os"
    16  	"os/exec"
    17  	"path/filepath"
    18  	"runtime"
    19  	"testing"
    20  )
    21  
    22  const (
    23  	dataDir = "testdata"
    24  	binary  = "testvet.exe"
    25  )
    26  
    27  // We implement TestMain so remove the test binary when all is done.
    28  func TestMain(m *testing.M) {
    29  	flag.Parse()
    30  	result := m.Run()
    31  	os.Remove(binary)
    32  	os.Exit(result)
    33  }
    34  
    35  func CanRun() bool {
    36  	switch runtime.GOOS {
    37  	case "plan9", "windows":
    38  		// No Perl installed, can't run errcheck.
    39  		return false
    40  	case "nacl":
    41  		// Minimal and problematic file system.
    42  		return false
    43  	}
    44  	return true
    45  }
    46  
    47  var (
    48  	built  = false // We have built the binary.
    49  	failed = false // We have failed to build the binary, don't try again.
    50  )
    51  
    52  func Build(t *testing.T) {
    53  	if built {
    54  		return
    55  	}
    56  	if !CanRun() || failed {
    57  		t.Skip("cannot run on this environment")
    58  		return
    59  	}
    60  	cmd := exec.Command("go", "build", "-o", binary)
    61  	output, err := cmd.CombinedOutput()
    62  	if err != nil {
    63  		failed = true
    64  		fmt.Fprintf(os.Stderr, "%s\n", output)
    65  		t.Fatal(err)
    66  	}
    67  	built = true
    68  }
    69  
    70  func Vet(t *testing.T, files []string) {
    71  	errchk := filepath.Join(runtime.GOROOT(), "test", "errchk")
    72  	flags := []string{
    73  		"./" + binary,
    74  		"-printfuncs=Warn:1,Warnf:1",
    75  		"-test", // TODO: Delete once -shadow is part of -all.
    76  	}
    77  	cmd := exec.Command(errchk, append(flags, files...)...)
    78  	if !run(cmd, t) {
    79  		t.Fatal("vet command failed")
    80  	}
    81  }
    82  
    83  // Run this shell script, but do it in Go so it can be run by "go test".
    84  // 	go build -o testvet
    85  // 	$(GOROOT)/test/errchk ./testvet -shadow -printfuncs='Warn:1,Warnf:1' testdata/*.go testdata/*.s
    86  // 	rm testvet
    87  //
    88  
    89  func TestVet(t *testing.T) {
    90  	Build(t)
    91  
    92  	// errchk ./testvet
    93  	gos, err := filepath.Glob(filepath.Join(dataDir, "*.go"))
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  	asms, err := filepath.Glob(filepath.Join(dataDir, "*.s"))
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  	files := append(gos, asms...)
   102  	Vet(t, files)
   103  }
   104  
   105  func TestDivergentPackagesExamples(t *testing.T) {
   106  	Build(t)
   107  	// errchk ./testvet
   108  	Vet(t, []string{"testdata/divergent/buf.go", "testdata/divergent/buf_test.go"})
   109  }
   110  
   111  func TestIncompleteExamples(t *testing.T) {
   112  	Build(t)
   113  	// errchk ./testvet
   114  	Vet(t, []string{"testdata/incomplete/examples_test.go"})
   115  }
   116  
   117  func run(c *exec.Cmd, t *testing.T) bool {
   118  	output, err := c.CombinedOutput()
   119  	os.Stderr.Write(output)
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	// Errchk delights by not returning non-zero status if it finds errors, so we look at the output.
   124  	// It prints "BUG" if there is a failure.
   125  	if !c.ProcessState.Success() {
   126  		return false
   127  	}
   128  	return !bytes.Contains(output, []byte("BUG"))
   129  }
   130  
   131  // TestTags verifies that the -tags argument controls which files to check.
   132  func TestTags(t *testing.T) {
   133  	Build(t)
   134  	args := []string{
   135  		"-tags=testtag",
   136  		"-v", // We're going to look at the files it examines.
   137  		"testdata/tagtest",
   138  	}
   139  	cmd := exec.Command("./"+binary, args...)
   140  	output, err := cmd.CombinedOutput()
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	// file1 has testtag and file2 has !testtag.
   145  	if !bytes.Contains(output, []byte(filepath.Join("tagtest", "file1.go"))) {
   146  		t.Error("file1 was excluded, should be included")
   147  	}
   148  	if bytes.Contains(output, []byte(filepath.Join("tagtest", "file2.go"))) {
   149  		t.Error("file2 was included, should be excluded")
   150  	}
   151  }