1
2
3
4
5 package test
6
7 import (
8 "bytes"
9 "fmt"
10 "go/ast"
11 "go/parser"
12 "go/token"
13 "internal/testenv"
14 "os"
15 "path/filepath"
16 "runtime"
17 "strings"
18 "testing"
19 )
20
21
22
23
24
25 func runGenTest(t *testing.T, filename, tmpname string, ev ...string) {
26 testenv.MustHaveGoRun(t)
27 gotool := testenv.GoToolPath(t)
28 var stdout, stderr bytes.Buffer
29 cmd := testenv.Command(t, gotool, "run", filepath.Join("testdata", filename))
30 cmd.Stdout = &stdout
31 cmd.Stderr = &stderr
32 if err := cmd.Run(); err != nil {
33 t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
34 }
35
36 rungo := filepath.Join(t.TempDir(), "run.go")
37 ok := os.WriteFile(rungo, stdout.Bytes(), 0600)
38 if ok != nil {
39 t.Fatalf("Failed to create temporary file %s", rungo)
40 }
41
42 stdout.Reset()
43 stderr.Reset()
44 cmd = testenv.Command(t, gotool, "run", "-gcflags=-d=ssa/check/on", rungo)
45 cmd.Stdout = &stdout
46 cmd.Stderr = &stderr
47 cmd.Env = append(cmd.Env, ev...)
48 err := cmd.Run()
49 if err != nil {
50 t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
51 }
52 if s := stderr.String(); s != "" {
53 t.Errorf("Stderr = %s\nWant empty", s)
54 }
55 if s := stdout.String(); s != "" {
56 t.Errorf("Stdout = %s\nWant empty", s)
57 }
58 }
59
60 func TestGenFlowGraph(t *testing.T) {
61 if testing.Short() {
62 t.Skip("not run in short mode.")
63 }
64 runGenTest(t, "flowgraph_generator1.go", "ssa_fg_tmp1")
65 }
66
67
68
69
70
71 func TestCode(t *testing.T) {
72 testenv.MustHaveGoBuild(t)
73 gotool := testenv.GoToolPath(t)
74
75
76 tmpdir := t.TempDir()
77
78
79 var srcs []string
80 type test struct {
81 name string
82 usesFloat bool
83 }
84 var tests []test
85 files, err := os.ReadDir("testdata")
86 if err != nil {
87 t.Fatalf("can't read testdata directory: %v", err)
88 }
89 for _, f := range files {
90 if !strings.HasSuffix(f.Name(), "_test.go") {
91 continue
92 }
93 text, err := os.ReadFile(filepath.Join("testdata", f.Name()))
94 if err != nil {
95 t.Fatalf("can't read testdata/%s: %v", f.Name(), err)
96 }
97 fset := token.NewFileSet()
98 code, err := parser.ParseFile(fset, f.Name(), text, 0)
99 if err != nil {
100 t.Fatalf("can't parse testdata/%s: %v", f.Name(), err)
101 }
102 srcs = append(srcs, filepath.Join("testdata", f.Name()))
103 foundTest := false
104 for _, d := range code.Decls {
105 fd, ok := d.(*ast.FuncDecl)
106 if !ok {
107 continue
108 }
109 if !strings.HasPrefix(fd.Name.Name, "Test") {
110 continue
111 }
112 if fd.Recv != nil {
113 continue
114 }
115 if fd.Type.Results != nil {
116 continue
117 }
118 if len(fd.Type.Params.List) != 1 {
119 continue
120 }
121 p := fd.Type.Params.List[0]
122 if len(p.Names) != 1 {
123 continue
124 }
125 s, ok := p.Type.(*ast.StarExpr)
126 if !ok {
127 continue
128 }
129 sel, ok := s.X.(*ast.SelectorExpr)
130 if !ok {
131 continue
132 }
133 base, ok := sel.X.(*ast.Ident)
134 if !ok {
135 continue
136 }
137 if base.Name != "testing" {
138 continue
139 }
140 if sel.Sel.Name != "T" {
141 continue
142 }
143
144 tests = append(tests, test{name: fd.Name.Name, usesFloat: bytes.Contains(text, []byte("float"))})
145 foundTest = true
146 }
147 if !foundTest {
148 t.Fatalf("test file testdata/%s has no tests in it", f.Name())
149 }
150 }
151
152 flags := []string{""}
153 if runtime.GOARCH == "arm" || runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" || runtime.GOARCH == "386" {
154 flags = append(flags, ",softfloat")
155 }
156 for _, flag := range flags {
157 args := []string{"test", "-c", "-gcflags=-d=ssa/check/on" + flag, "-o", filepath.Join(tmpdir, "code.test")}
158 args = append(args, srcs...)
159 out, err := testenv.Command(t, gotool, args...).CombinedOutput()
160 if err != nil || len(out) != 0 {
161 t.Fatalf("Build failed: %v\n%s\n", err, out)
162 }
163
164
165 for _, test := range tests {
166 test := test
167 if flag == ",softfloat" && !test.usesFloat {
168
169 continue
170 }
171 t.Run(fmt.Sprintf("%s%s", test.name[4:], flag), func(t *testing.T) {
172 out, err := testenv.Command(t, filepath.Join(tmpdir, "code.test"), "-test.run=^"+test.name+"$").CombinedOutput()
173 if err != nil || string(out) != "PASS\n" {
174 t.Errorf("Failed:\n%s\n", out)
175 }
176 })
177 }
178 }
179 }
180
View as plain text