@@ -6,11 +6,16 @@ package gc
6
6
7
7
import (
8
8
"bytes"
9
+ "fmt"
10
+ "go/ast"
11
+ "go/parser"
12
+ "go/token"
9
13
"internal/testenv"
10
14
"io/ioutil"
11
15
"os"
12
16
"os/exec"
13
17
"path/filepath"
18
+ "runtime"
14
19
"strings"
15
20
"testing"
16
21
)
@@ -104,11 +109,123 @@ func TestGenFlowGraph(t *testing.T) {
104
109
runGenTest (t , "flowgraph_generator1.go" , "ssa_fg_tmp1" )
105
110
}
106
111
107
- // TestShortCircuit tests OANDAND and OOROR expressions and short circuiting.
108
- func TestShortCircuit (t * testing.T ) { runTest (t , "short.go" ) }
112
+ // TestCode runs all the tests in the testdata directory as subtests.
113
+ // These tests are special because we want to run them with different
114
+ // compiler flags set (and thus they can't just be _test.go files in
115
+ // this directory).
116
+ func TestCode (t * testing.T ) {
117
+ testenv .MustHaveGoBuild (t )
118
+ gotool := testenv .GoToolPath (t )
119
+
120
+ // Make a temporary directory to work in.
121
+ tmpdir , err := ioutil .TempDir ("" , "TestCode" )
122
+ if err != nil {
123
+ t .Fatalf ("Failed to create temporary directory: %v" , err )
124
+ }
125
+ defer os .RemoveAll (tmpdir )
126
+
127
+ // Find all the test functions (and the files containing them).
128
+ var srcs []string // files containing Test functions
129
+ type test struct {
130
+ name string // TestFoo
131
+ usesFloat bool // might use float operations
132
+ }
133
+ var tests []test
134
+ files , err := ioutil .ReadDir ("testdata" )
135
+ if err != nil {
136
+ t .Fatalf ("can't read testdata directory: %v" , err )
137
+ }
138
+ for _ , f := range files {
139
+ if ! strings .HasSuffix (f .Name (), "_test.go" ) {
140
+ continue
141
+ }
142
+ text , err := ioutil .ReadFile (filepath .Join ("testdata" , f .Name ()))
143
+ if err != nil {
144
+ t .Fatalf ("can't read testdata/%s: %v" , f .Name (), err )
145
+ }
146
+ fset := token .NewFileSet ()
147
+ code , err := parser .ParseFile (fset , f .Name (), text , 0 )
148
+ if err != nil {
149
+ t .Fatalf ("can't parse testdata/%s: %v" , f .Name (), err )
150
+ }
151
+ srcs = append (srcs , filepath .Join ("testdata" , f .Name ()))
152
+ foundTest := false
153
+ for _ , d := range code .Decls {
154
+ fd , ok := d .(* ast.FuncDecl )
155
+ if ! ok {
156
+ continue
157
+ }
158
+ if ! strings .HasPrefix (fd .Name .Name , "Test" ) {
159
+ continue
160
+ }
161
+ if fd .Recv != nil {
162
+ continue
163
+ }
164
+ if fd .Type .Results != nil {
165
+ continue
166
+ }
167
+ if len (fd .Type .Params .List ) != 1 {
168
+ continue
169
+ }
170
+ p := fd .Type .Params .List [0 ]
171
+ if len (p .Names ) != 1 {
172
+ continue
173
+ }
174
+ s , ok := p .Type .(* ast.StarExpr )
175
+ if ! ok {
176
+ continue
177
+ }
178
+ sel , ok := s .X .(* ast.SelectorExpr )
179
+ if ! ok {
180
+ continue
181
+ }
182
+ base , ok := sel .X .(* ast.Ident )
183
+ if ! ok {
184
+ continue
185
+ }
186
+ if base .Name != "testing" {
187
+ continue
188
+ }
189
+ if sel .Sel .Name != "T" {
190
+ continue
191
+ }
192
+ // Found a testing function.
193
+ tests = append (tests , test {name : fd .Name .Name , usesFloat : bytes .Contains (text , []byte ("float" ))})
194
+ foundTest = true
195
+ }
196
+ if ! foundTest {
197
+ t .Fatalf ("test file testdata/%s has no tests in it" , f .Name ())
198
+ }
199
+ }
109
200
110
- // TestBreakContinue tests that continue and break statements do what they say.
111
- func TestBreakContinue (t * testing.T ) { runTest (t , "break.go" ) }
201
+ flags := []string {"" }
202
+ if runtime .GOARCH == "arm" || runtime .GOARCH == "mips" || runtime .GOARCH == "mips64" {
203
+ flags = append (flags , ",softfloat" )
204
+ }
205
+ for _ , flag := range flags {
206
+ args := []string {"test" , "-c" , "-gcflags=-d=ssa/check/on" + flag , "-o" , filepath .Join (tmpdir , "code.test" )}
207
+ args = append (args , srcs ... )
208
+ out , err := exec .Command (gotool , args ... ).CombinedOutput ()
209
+ if err != nil || len (out ) != 0 {
210
+ t .Fatalf ("Build failed: %v\n %s\n " , err , out )
211
+ }
212
+
213
+ // Now we have a test binary. Run it with all the tests as subtests of this one.
214
+ for _ , test := range tests {
215
+ test := test
216
+ if flag == ",softfloat" && ! test .usesFloat {
217
+ // No point in running the soft float version if the test doesn't use floats.
218
+ continue
219
+ }
220
+ t .Run (fmt .Sprintf ("%s%s" , test .name [4 :], flag ), func (t * testing.T ) {
221
+ out , err := exec .Command (filepath .Join (tmpdir , "code.test" ), "-test.run=" + test .name ).CombinedOutput ()
222
+ if err != nil || string (out ) != "PASS\n " {
223
+ t .Errorf ("Failed:\n %s\n " , out )
224
+ }
225
+ })
226
+ }
227
+ }
228
+ }
112
229
113
230
// TestTypeAssertion tests type assertions.
114
231
func TestTypeAssertion (t * testing.T ) { runTest (t , "assert.go" ) }
0 commit comments