github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/go/ssa/interp/interp14_test.go (about) 1 // Copyright 2013 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 // +build !go1.5 6 7 // +build !android,!windows,!plan9 8 9 package interp_test 10 11 import ( 12 "bytes" 13 "fmt" 14 "go/build" 15 "os" 16 "path/filepath" 17 "strings" 18 "testing" 19 "time" 20 21 "golang.org/x/tools/go/loader" 22 "golang.org/x/tools/go/ssa" 23 "golang.org/x/tools/go/ssa/interp" 24 "golang.org/x/tools/go/ssa/ssautil" 25 "golang.org/x/tools/go/types" 26 ) 27 28 // Each line contains a space-separated list of $GOROOT/test/ 29 // filenames comprising the main package of a program. 30 // They are ordered quickest-first, roughly. 31 // 32 // TODO(adonovan): integrate into the $GOROOT/test driver scripts, 33 // golden file checking, etc. 34 var gorootTestTests = []string{ 35 "235.go", 36 "alias1.go", 37 "chancap.go", 38 "func5.go", 39 "func6.go", 40 "func7.go", 41 "func8.go", 42 "helloworld.go", 43 "varinit.go", 44 "escape3.go", 45 "initcomma.go", 46 "cmp.go", 47 "compos.go", 48 "turing.go", 49 "indirect.go", 50 // "complit.go", // tests go1.5 features 51 "for.go", 52 "struct0.go", 53 "intcvt.go", 54 "printbig.go", 55 "deferprint.go", 56 "escape.go", 57 "range.go", 58 "const4.go", 59 "float_lit.go", 60 "bigalg.go", 61 "decl.go", 62 "if.go", 63 "named.go", 64 "bigmap.go", 65 "func.go", 66 "reorder2.go", 67 "closure.go", 68 "gc.go", 69 "simassign.go", 70 "iota.go", 71 "nilptr2.go", 72 "goprint.go", // doesn't actually assert anything (cmpout) 73 "utf.go", 74 "method.go", 75 "char_lit.go", 76 "env.go", 77 "int_lit.go", 78 "string_lit.go", 79 "defer.go", 80 "typeswitch.go", 81 "stringrange.go", 82 "reorder.go", 83 "method3.go", 84 "literal.go", 85 "nul1.go", // doesn't actually assert anything (errorcheckoutput) 86 "zerodivide.go", 87 "convert.go", 88 "convT2X.go", 89 "switch.go", 90 "initialize.go", 91 "ddd.go", 92 "blank.go", // partly disabled 93 "map.go", 94 "closedchan.go", 95 "divide.go", 96 "rename.go", 97 "const3.go", 98 "nil.go", 99 "recover.go", // reflection parts disabled 100 "recover1.go", 101 "recover2.go", 102 "recover3.go", 103 "typeswitch1.go", 104 "floatcmp.go", 105 "crlf.go", // doesn't actually assert anything (runoutput) 106 // Slow tests follow. 107 "bom.go", // ~1.7s 108 "gc1.go", // ~1.7s 109 "cmplxdivide.go cmplxdivide1.go", // ~2.4s 110 111 // Working, but not worth enabling: 112 // "append.go", // works, but slow (15s). 113 // "gc2.go", // works, but slow, and cheats on the memory check. 114 // "sigchld.go", // works, but only on POSIX. 115 // "peano.go", // works only up to n=9, and slow even then. 116 // "stack.go", // works, but too slow (~30s) by default. 117 // "solitaire.go", // works, but too slow (~30s). 118 // "const.go", // works but for but one bug: constant folder doesn't consider representations. 119 // "init1.go", // too slow (80s) and not that interesting. Cheats on ReadMemStats check too. 120 // "rotate.go rotate0.go", // emits source for a test 121 // "rotate.go rotate1.go", // emits source for a test 122 // "rotate.go rotate2.go", // emits source for a test 123 // "rotate.go rotate3.go", // emits source for a test 124 // "64bit.go", // emits source for a test 125 // "run.go", // test driver, not a test. 126 127 // Broken. TODO(adonovan): fix. 128 // copy.go // very slow; but with N=4 quickly crashes, slice index out of range. 129 // nilptr.go // interp: V > uintptr not implemented. Slow test, lots of mem 130 // args.go // works, but requires specific os.Args from the driver. 131 // index.go // a template, not a real test. 132 // mallocfin.go // SetFinalizer not implemented. 133 134 // TODO(adonovan): add tests from $GOROOT/test/* subtrees: 135 // bench chan bugs fixedbugs interface ken. 136 } 137 138 // These are files in go.tools/go/ssa/interp/testdata/. 139 var testdataTests = []string{ 140 "boundmeth.go", 141 // "complit.go", // requires go1.5 142 "coverage.go", 143 "defer.go", 144 "fieldprom.go", 145 "ifaceconv.go", 146 "ifaceprom.go", 147 "initorder.go", 148 "methprom.go", 149 "mrvchain.go", 150 "range.go", 151 "recover.go", 152 "reflect.go", 153 "static.go", 154 "callstack.go", 155 } 156 157 // These are files and packages in $GOROOT/src/. 158 var gorootSrcTests = []string{ 159 "encoding/ascii85", 160 "encoding/hex", 161 // "encoding/pem", // TODO(adonovan): implement (reflect.Value).SetString 162 // "testing", // TODO(adonovan): implement runtime.Goexit correctly 163 // "hash/crc32", // TODO(adonovan): implement hash/crc32.haveCLMUL 164 // "log", // TODO(adonovan): implement runtime.Callers correctly 165 166 // Too slow: 167 // "container/ring", 168 // "hash/adler32", 169 170 "unicode/utf8", 171 "path", 172 "flag", 173 "encoding/csv", 174 "text/scanner", 175 "unicode", 176 } 177 178 type successPredicate func(exitcode int, output string) error 179 180 func run(t *testing.T, dir, input string, success successPredicate) bool { 181 fmt.Printf("Input: %s\n", input) 182 183 start := time.Now() 184 185 var inputs []string 186 for _, i := range strings.Split(input, " ") { 187 if strings.HasSuffix(i, ".go") { 188 i = dir + i 189 } 190 inputs = append(inputs, i) 191 } 192 193 var conf loader.Config 194 if _, err := conf.FromArgs(inputs, true); err != nil { 195 t.Errorf("FromArgs(%s) failed: %s", inputs, err) 196 return false 197 } 198 199 conf.Import("runtime") 200 201 // Print a helpful hint if we don't make it to the end. 202 var hint string 203 defer func() { 204 if hint != "" { 205 fmt.Println("FAIL") 206 fmt.Println(hint) 207 } else { 208 fmt.Println("PASS") 209 } 210 211 interp.CapturedOutput = nil 212 }() 213 214 hint = fmt.Sprintf("To dump SSA representation, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -test -build=CFP %s\n", input) 215 216 iprog, err := conf.Load() 217 if err != nil { 218 t.Errorf("conf.Load(%s) failed: %s", inputs, err) 219 return false 220 } 221 222 prog := ssautil.CreateProgram(iprog, ssa.SanityCheckFunctions) 223 prog.Build() 224 225 var mainPkg *ssa.Package 226 var initialPkgs []*ssa.Package 227 for _, info := range iprog.InitialPackages() { 228 if info.Pkg.Path() == "runtime" { 229 continue // not an initial package 230 } 231 p := prog.Package(info.Pkg) 232 initialPkgs = append(initialPkgs, p) 233 if mainPkg == nil && p.Func("main") != nil { 234 mainPkg = p 235 } 236 } 237 if mainPkg == nil { 238 testmainPkg := prog.CreateTestMainPackage(initialPkgs...) 239 if testmainPkg == nil { 240 t.Errorf("CreateTestMainPackage(%s) returned nil", mainPkg) 241 return false 242 } 243 if testmainPkg.Func("main") == nil { 244 t.Errorf("synthetic testmain package has no main") 245 return false 246 } 247 mainPkg = testmainPkg 248 } 249 250 var out bytes.Buffer 251 interp.CapturedOutput = &out 252 253 hint = fmt.Sprintf("To trace execution, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -build=C -run --interp=T %s\n", input) 254 exitCode := interp.Interpret(mainPkg, 0, &types.StdSizes{8, 8}, inputs[0], []string{}) 255 256 // The definition of success varies with each file. 257 if err := success(exitCode, out.String()); err != nil { 258 t.Errorf("interp.Interpret(%s) failed: %s", inputs, err) 259 return false 260 } 261 262 hint = "" // call off the hounds 263 264 if false { 265 fmt.Println(input, time.Since(start)) // test profiling 266 } 267 268 return true 269 } 270 271 const slash = string(os.PathSeparator) 272 273 func printFailures(failures []string) { 274 if failures != nil { 275 fmt.Println("The following tests failed:") 276 for _, f := range failures { 277 fmt.Printf("\t%s\n", f) 278 } 279 } 280 } 281 282 func success(exitcode int, output string) error { 283 if exitcode != 0 { 284 return fmt.Errorf("exit code was %d", exitcode) 285 } 286 if strings.Contains(output, "BUG") { 287 return fmt.Errorf("exited zero but output contained 'BUG'") 288 } 289 return nil 290 } 291 292 // TestTestdataFiles runs the interpreter on testdata/*.go. 293 func TestTestdataFiles(t *testing.T) { 294 var failures []string 295 start := time.Now() 296 for _, input := range testdataTests { 297 if testing.Short() && time.Since(start) > 30*time.Second { 298 printFailures(failures) 299 t.Skipf("timeout - aborting test") 300 } 301 if !run(t, "testdata"+slash, input, success) { 302 failures = append(failures, input) 303 } 304 } 305 printFailures(failures) 306 } 307 308 // TestGorootTest runs the interpreter on $GOROOT/test/*.go. 309 func TestGorootTest(t *testing.T) { 310 if testing.Short() { 311 t.Skip() // too slow (~30s) 312 } 313 314 var failures []string 315 316 for _, input := range gorootTestTests { 317 if !run(t, filepath.Join(build.Default.GOROOT, "test")+slash, input, success) { 318 failures = append(failures, input) 319 } 320 } 321 for _, input := range gorootSrcTests { 322 if !run(t, filepath.Join(build.Default.GOROOT, "src")+slash, input, success) { 323 failures = append(failures, input) 324 } 325 } 326 printFailures(failures) 327 } 328 329 // TestTestmainPackage runs the interpreter on a synthetic "testmain" package. 330 func TestTestmainPackage(t *testing.T) { 331 if testing.Short() { 332 t.Skip() // too slow on some platforms 333 } 334 335 success := func(exitcode int, output string) error { 336 if exitcode == 0 { 337 return fmt.Errorf("unexpected success") 338 } 339 if !strings.Contains(output, "FAIL: TestFoo") { 340 return fmt.Errorf("missing failure log for TestFoo") 341 } 342 if !strings.Contains(output, "FAIL: TestBar") { 343 return fmt.Errorf("missing failure log for TestBar") 344 } 345 // TODO(adonovan): test benchmarks too 346 return nil 347 } 348 run(t, "testdata"+slash, "a_test.go", success) 349 } 350 351 // CreateTestMainPackage should return nil if there were no tests. 352 func TestNullTestmainPackage(t *testing.T) { 353 var conf loader.Config 354 conf.CreateFromFilenames("", "testdata/b_test.go") 355 iprog, err := conf.Load() 356 if err != nil { 357 t.Fatalf("CreatePackages failed: %s", err) 358 } 359 prog := ssautil.CreateProgram(iprog, ssa.SanityCheckFunctions) 360 mainPkg := prog.Package(iprog.Created[0].Pkg) 361 if mainPkg.Func("main") != nil { 362 t.Fatalf("unexpected main function") 363 } 364 if prog.CreateTestMainPackage(mainPkg) != nil { 365 t.Fatalf("CreateTestMainPackage returned non-nil") 366 } 367 }