github.com/yukk001/go1.10.8@v0.0.0-20190813125351-6df2d3982e20/misc/cgo/errors/errors_test.go (about) 1 // Copyright 2017 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 package errorstest 6 7 import ( 8 "bytes" 9 "fmt" 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "regexp" 15 "strconv" 16 "strings" 17 "testing" 18 ) 19 20 func path(file string) string { 21 return filepath.Join("src", file) 22 } 23 24 func check(t *testing.T, file string) { 25 t.Run(file, func(t *testing.T) { 26 t.Parallel() 27 28 contents, err := ioutil.ReadFile(path(file)) 29 if err != nil { 30 t.Fatal(err) 31 } 32 var errors []*regexp.Regexp 33 for i, line := range bytes.Split(contents, []byte("\n")) { 34 if bytes.HasSuffix(line, []byte("ERROR HERE")) { 35 re := regexp.MustCompile(regexp.QuoteMeta(fmt.Sprintf("%s:%d:", file, i+1))) 36 errors = append(errors, re) 37 continue 38 } 39 40 frags := bytes.SplitAfterN(line, []byte("ERROR HERE: "), 2) 41 if len(frags) == 1 { 42 continue 43 } 44 re, err := regexp.Compile(string(frags[1])) 45 if err != nil { 46 t.Errorf("Invalid regexp after `ERROR HERE: `: %#q", frags[1]) 47 continue 48 } 49 errors = append(errors, re) 50 } 51 if len(errors) == 0 { 52 t.Fatalf("cannot find ERROR HERE") 53 } 54 expect(t, file, errors) 55 }) 56 } 57 58 func expect(t *testing.T, file string, errors []*regexp.Regexp) { 59 dir, err := ioutil.TempDir("", filepath.Base(t.Name())) 60 if err != nil { 61 t.Fatal(err) 62 } 63 defer os.RemoveAll(dir) 64 65 dst := filepath.Join(dir, strings.TrimSuffix(file, ".go")) 66 cmd := exec.Command("go", "build", "-gcflags=-L", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted 67 out, err := cmd.CombinedOutput() 68 if err == nil { 69 t.Errorf("expected cgo to fail but it succeeded") 70 } 71 72 lines := bytes.Split(out, []byte("\n")) 73 for _, re := range errors { 74 found := false 75 for _, line := range lines { 76 if re.Match(line) { 77 t.Logf("found match for %#q: %q", re, line) 78 found = true 79 break 80 } 81 } 82 if !found { 83 t.Errorf("expected error output to contain %#q", re) 84 } 85 } 86 87 if t.Failed() { 88 t.Logf("actual output:\n%s", out) 89 } 90 } 91 92 func sizeofLongDouble(t *testing.T) int { 93 cmd := exec.Command("go", "run", path("long_double_size.go")) 94 out, err := cmd.CombinedOutput() 95 if err != nil { 96 t.Fatalf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out) 97 } 98 99 i, err := strconv.Atoi(strings.TrimSpace(string(out))) 100 if err != nil { 101 t.Fatalf("long_double_size.go printed invalid size: %s", out) 102 } 103 return i 104 } 105 106 func TestReportsTypeErrors(t *testing.T) { 107 for _, file := range []string{ 108 "err1.go", 109 "err2.go", 110 "err3.go", 111 "issue7757.go", 112 "issue8442.go", 113 "issue11097a.go", 114 "issue11097b.go", 115 "issue13129.go", 116 "issue13423.go", 117 "issue13467.go", 118 "issue13635.go", 119 "issue13830.go", 120 "issue16116.go", 121 "issue16591.go", 122 "issue18452.go", 123 "issue18889.go", 124 } { 125 check(t, file) 126 } 127 128 if sizeofLongDouble(t) > 8 { 129 check(t, "err4.go") 130 } 131 } 132 133 func TestToleratesOptimizationFlag(t *testing.T) { 134 for _, cflags := range []string{ 135 "", 136 "-O", 137 } { 138 cflags := cflags 139 t.Run(cflags, func(t *testing.T) { 140 t.Parallel() 141 142 cmd := exec.Command("go", "build", path("issue14669.go")) 143 cmd.Env = append(os.Environ(), "CGO_CFLAGS="+cflags) 144 out, err := cmd.CombinedOutput() 145 if err != nil { 146 t.Errorf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out) 147 } 148 }) 149 } 150 } 151 152 func TestMallocCrashesOnNil(t *testing.T) { 153 t.Parallel() 154 155 cmd := exec.Command("go", "run", path("malloc.go")) 156 out, err := cmd.CombinedOutput() 157 if err == nil { 158 t.Logf("%#q:\n%s", strings.Join(cmd.Args, " "), out) 159 t.Fatalf("succeeded unexpectedly") 160 } 161 }