Source file
misc/cgo/errors/errors_test.go
1
2
3
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))
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 }
158
View as plain text