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