github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/gc/ssa_test.go (about) 1 // Copyright 2015 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 gc 6 7 import ( 8 "bytes" 9 "fmt" 10 "go/ast" 11 "go/parser" 12 "go/token" 13 "github.com/gagliardetto/golang-go/not-internal/testenv" 14 "io/ioutil" 15 "os" 16 "os/exec" 17 "path/filepath" 18 "runtime" 19 "strings" 20 "testing" 21 ) 22 23 // runGenTest runs a test-generator, then runs the generated test. 24 // Generated test can either fail in compilation or execution. 25 // The environment variable parameter(s) is passed to the run 26 // of the generated test. 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 // Write stdout into a temporary file 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 // TestCode runs all the tests in the testdata directory as subtests. 76 // These tests are special because we want to run them with different 77 // compiler flags set (and thus they can't just be _test.go files in 78 // this directory). 79 func TestCode(t *testing.T) { 80 testenv.MustHaveGoBuild(t) 81 gotool := testenv.GoToolPath(t) 82 83 // Make a temporary directory to work in. 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 // Find all the test functions (and the files containing them). 91 var srcs []string // files containing Test functions 92 type test struct { 93 name string // TestFoo 94 usesFloat bool // might use float operations 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 // Found a testing function. 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" { 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 // Now we have a test binary. Run it with all the tests as subtests of this one. 177 for _, test := range tests { 178 test := test 179 if flag == ",softfloat" && !test.usesFloat { 180 // No point in running the soft float version if the test doesn't use floats. 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 }