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