1*760c253cSXin Litest: add -target flag. 2*760c253cSXin Li 3*760c253cSXin Li--- test/run.go 4*760c253cSXin Li+++ test/run.go 5*760c253cSXin Li@@ -34,19 +34,19 @@ import ( 6*760c253cSXin Li 7*760c253cSXin Li var ( 8*760c253cSXin Li verbose = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.") 9*760c253cSXin Li keep = flag.Bool("k", false, "keep. keep temporary directory.") 10*760c253cSXin Li numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run") 11*760c253cSXin Li summary = flag.Bool("summary", false, "show summary of results") 12*760c253cSXin Li showSkips = flag.Bool("show_skips", false, "show skipped tests") 13*760c253cSXin Li runSkips = flag.Bool("run_skips", false, "run skipped tests (ignore skip and build tags)") 14*760c253cSXin Li- linkshared = flag.Bool("linkshared", false, "") 15*760c253cSXin Li updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output") 16*760c253cSXin Li runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run") 17*760c253cSXin Li+ target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries") 18*760c253cSXin Li 19*760c253cSXin Li shard = flag.Int("shard", 0, "shard index to run. Only applicable if -shards is non-zero.") 20*760c253cSXin Li shards = flag.Int("shards", 0, "number of shards. If 0, all tests are run. This is used by the continuous build.") 21*760c253cSXin Li ) 22*760c253cSXin Li 23*760c253cSXin Li var ( 24*760c253cSXin Li goos, goarch string 25*760c253cSXin Li 26*760c253cSXin Li@@ -189,48 +189,49 @@ func goFiles(dir string) []string { 27*760c253cSXin Li } 28*760c253cSXin Li sort.Strings(names) 29*760c253cSXin Li return names 30*760c253cSXin Li } 31*760c253cSXin Li 32*760c253cSXin Li type runCmd func(...string) ([]byte, error) 33*760c253cSXin Li 34*760c253cSXin Li func compileFile(runcmd runCmd, longname string, flags []string) (out []byte, err error) { 35*760c253cSXin Li- cmd := []string{"go", "tool", "compile", "-e"} 36*760c253cSXin Li+ cmd := []string{findGoCmd(), "tool", "compile", "-e"} 37*760c253cSXin Li cmd = append(cmd, flags...) 38*760c253cSXin Li- if *linkshared { 39*760c253cSXin Li- cmd = append(cmd, "-dynlink", "-installsuffix=dynlink") 40*760c253cSXin Li- } 41*760c253cSXin Li cmd = append(cmd, longname) 42*760c253cSXin Li return runcmd(cmd...) 43*760c253cSXin Li } 44*760c253cSXin Li 45*760c253cSXin Li func compileInDir(runcmd runCmd, dir string, flags []string, names ...string) (out []byte, err error) { 46*760c253cSXin Li- cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", "."} 47*760c253cSXin Li+ cmd := []string{findGoCmd(), "tool", "compile", "-e", "-D", ".", "-I", "."} 48*760c253cSXin Li cmd = append(cmd, flags...) 49*760c253cSXin Li- if *linkshared { 50*760c253cSXin Li- cmd = append(cmd, "-dynlink", "-installsuffix=dynlink") 51*760c253cSXin Li- } 52*760c253cSXin Li for _, name := range names { 53*760c253cSXin Li cmd = append(cmd, filepath.Join(dir, name)) 54*760c253cSXin Li } 55*760c253cSXin Li return runcmd(cmd...) 56*760c253cSXin Li } 57*760c253cSXin Li 58*760c253cSXin Li func linkFile(runcmd runCmd, goname string) (err error) { 59*760c253cSXin Li pfile := strings.Replace(goname, ".go", ".o", -1) 60*760c253cSXin Li- cmd := []string{"go", "tool", "link", "-w", "-o", "a.exe", "-L", "."} 61*760c253cSXin Li- if *linkshared { 62*760c253cSXin Li- cmd = append(cmd, "-linkshared", "-installsuffix=dynlink") 63*760c253cSXin Li- } 64*760c253cSXin Li- cmd = append(cmd, pfile) 65*760c253cSXin Li- _, err = runcmd(cmd...) 66*760c253cSXin Li+ _, err = runcmd(findGoCmd(), "tool", "link", "-w", "-o", "a.exe", "-L", ".", pfile) 67*760c253cSXin Li return 68*760c253cSXin Li } 69*760c253cSXin Li 70*760c253cSXin Li+func goRun(runcmd runCmd, flags []string, goname string, args ...string) (out []byte, err error) { 71*760c253cSXin Li+ cmd := []string{findGoCmd(), "run", goGcflags()} 72*760c253cSXin Li+ if len(findExecCmd()) > 0 { 73*760c253cSXin Li+ cmd = append(cmd, "-exec") 74*760c253cSXin Li+ cmd = append(cmd, findExecCmd()...) 75*760c253cSXin Li+ } 76*760c253cSXin Li+ cmd = append(cmd, flags...) 77*760c253cSXin Li+ cmd = append(cmd, goname) 78*760c253cSXin Li+ cmd = append(cmd, args...) 79*760c253cSXin Li+ return runcmd(cmd...) 80*760c253cSXin Li+} 81*760c253cSXin Li+ 82*760c253cSXin Li // skipError describes why a test was skipped. 83*760c253cSXin Li type skipError string 84*760c253cSXin Li 85*760c253cSXin Li func (s skipError) Error() string { return string(s) } 86*760c253cSXin Li 87*760c253cSXin Li func check(err error) { 88*760c253cSXin Li if err != nil { 89*760c253cSXin Li log.Fatal(err) 90*760c253cSXin Li@@ -590,18 +591,17 @@ func (t *test) run() { 91*760c253cSXin Li 92*760c253cSXin Li long := filepath.Join(cwd, t.goFileName()) 93*760c253cSXin Li switch action { 94*760c253cSXin Li default: 95*760c253cSXin Li t.err = fmt.Errorf("unimplemented action %q", action) 96*760c253cSXin Li 97*760c253cSXin Li case "errorcheck": 98*760c253cSXin Li // TODO(gri) remove need for -C (disable printing of columns in error messages) 99*760c253cSXin Li- cmdline := []string{"go", "tool", "compile", "-C", "-e", "-o", "a.o"} 100*760c253cSXin Li- // No need to add -dynlink even if linkshared if we're just checking for errors... 101*760c253cSXin Li+ cmdline := []string{findGoCmd(), "tool", "compile", "-C", "-e", "-o", "a.o"} 102*760c253cSXin Li cmdline = append(cmdline, flags...) 103*760c253cSXin Li cmdline = append(cmdline, long) 104*760c253cSXin Li out, err := runcmd(cmdline...) 105*760c253cSXin Li if wantError { 106*760c253cSXin Li if err == nil { 107*760c253cSXin Li t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out) 108*760c253cSXin Li return 109*760c253cSXin Li } 110*760c253cSXin Li@@ -704,17 +704,17 @@ func (t *test) run() { 111*760c253cSXin Li } 112*760c253cSXin Li if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { 113*760c253cSXin Li t.err = fmt.Errorf("incorrect output\n%s", out) 114*760c253cSXin Li } 115*760c253cSXin Li } 116*760c253cSXin Li } 117*760c253cSXin Li 118*760c253cSXin Li case "build": 119*760c253cSXin Li- _, err := runcmd("go", "build", goGcflags(), "-o", "a.exe", long) 120*760c253cSXin Li+ _, err := runcmd(findGoCmd(), "build", goGcflags(), "-o", "a.exe", long) 121*760c253cSXin Li if err != nil { 122*760c253cSXin Li t.err = err 123*760c253cSXin Li } 124*760c253cSXin Li 125*760c253cSXin Li case "builddir": 126*760c253cSXin Li // Build an executable from all the .go and .s files in a subdirectory. 127*760c253cSXin Li useTmp = true 128*760c253cSXin Li longdir := filepath.Join(cwd, t.goDirName()) 129*760c253cSXin Li@@ -730,177 +730,132 @@ func (t *test) run() { 130*760c253cSXin Li case ".go": 131*760c253cSXin Li gos = append(gos, file) 132*760c253cSXin Li case ".s": 133*760c253cSXin Li asms = append(asms, file) 134*760c253cSXin Li } 135*760c253cSXin Li 136*760c253cSXin Li } 137*760c253cSXin Li var objs []string 138*760c253cSXin Li- cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"} 139*760c253cSXin Li+ cmd := []string{findGoCmd(), "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"} 140*760c253cSXin Li if len(asms) > 0 { 141*760c253cSXin Li cmd = append(cmd, "-asmhdr", "go_asm.h") 142*760c253cSXin Li } 143*760c253cSXin Li for _, file := range gos { 144*760c253cSXin Li cmd = append(cmd, filepath.Join(longdir, file.Name())) 145*760c253cSXin Li } 146*760c253cSXin Li _, err := runcmd(cmd...) 147*760c253cSXin Li if err != nil { 148*760c253cSXin Li t.err = err 149*760c253cSXin Li break 150*760c253cSXin Li } 151*760c253cSXin Li objs = append(objs, "go.o") 152*760c253cSXin Li if len(asms) > 0 { 153*760c253cSXin Li- cmd = []string{"go", "tool", "asm", "-e", "-I", ".", "-o", "asm.o"} 154*760c253cSXin Li+ cmd = []string{findGoCmd(), "tool", "asm", "-e", "-I", ".", "-o", "asm.o"} 155*760c253cSXin Li for _, file := range asms { 156*760c253cSXin Li cmd = append(cmd, filepath.Join(longdir, file.Name())) 157*760c253cSXin Li } 158*760c253cSXin Li _, err = runcmd(cmd...) 159*760c253cSXin Li if err != nil { 160*760c253cSXin Li t.err = err 161*760c253cSXin Li break 162*760c253cSXin Li } 163*760c253cSXin Li objs = append(objs, "asm.o") 164*760c253cSXin Li } 165*760c253cSXin Li- cmd = []string{"go", "tool", "pack", "c", "all.a"} 166*760c253cSXin Li+ cmd = []string{findGoCmd(), "tool", "pack", "c", "all.a"} 167*760c253cSXin Li cmd = append(cmd, objs...) 168*760c253cSXin Li _, err = runcmd(cmd...) 169*760c253cSXin Li if err != nil { 170*760c253cSXin Li t.err = err 171*760c253cSXin Li break 172*760c253cSXin Li } 173*760c253cSXin Li- cmd = []string{"go", "tool", "link", "all.a"} 174*760c253cSXin Li+ cmd = []string{findGoCmd(), "tool", "link", "all.a"} 175*760c253cSXin Li _, err = runcmd(cmd...) 176*760c253cSXin Li if err != nil { 177*760c253cSXin Li t.err = err 178*760c253cSXin Li break 179*760c253cSXin Li } 180*760c253cSXin Li 181*760c253cSXin Li case "buildrun": // build binary, then run binary, instead of go run. Useful for timeout tests where failure mode is infinite loop. 182*760c253cSXin Li // TODO: not supported on NaCl 183*760c253cSXin Li useTmp = true 184*760c253cSXin Li- cmd := []string{"go", "build", goGcflags(), "-o", "a.exe"} 185*760c253cSXin Li- if *linkshared { 186*760c253cSXin Li- cmd = append(cmd, "-linkshared") 187*760c253cSXin Li- } 188*760c253cSXin Li+ cmd := []string{findGoCmd(), "build", goGcflags(), "-o", "a.exe"} 189*760c253cSXin Li longdirgofile := filepath.Join(filepath.Join(cwd, t.dir), t.gofile) 190*760c253cSXin Li cmd = append(cmd, flags...) 191*760c253cSXin Li cmd = append(cmd, longdirgofile) 192*760c253cSXin Li out, err := runcmd(cmd...) 193*760c253cSXin Li if err != nil { 194*760c253cSXin Li t.err = err 195*760c253cSXin Li return 196*760c253cSXin Li } 197*760c253cSXin Li- cmd = []string{"./a.exe"} 198*760c253cSXin Li+ cmd = []string{} 199*760c253cSXin Li+ if len(findExecCmd()) > 0 { 200*760c253cSXin Li+ cmd = append(cmd, findExecCmd()...) 201*760c253cSXin Li+ } 202*760c253cSXin Li+ cmd = append(cmd, "./a.exe") 203*760c253cSXin Li out, err = runcmd(append(cmd, args...)...) 204*760c253cSXin Li if err != nil { 205*760c253cSXin Li t.err = err 206*760c253cSXin Li return 207*760c253cSXin Li } 208*760c253cSXin Li 209*760c253cSXin Li if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { 210*760c253cSXin Li t.err = fmt.Errorf("incorrect output\n%s", out) 211*760c253cSXin Li } 212*760c253cSXin Li 213*760c253cSXin Li case "run": 214*760c253cSXin Li useTmp = false 215*760c253cSXin Li- var out []byte 216*760c253cSXin Li- var err error 217*760c253cSXin Li- if len(flags)+len(args) == 0 && goGcflags() == "" && !*linkshared { 218*760c253cSXin Li- // If we're not using special go command flags, 219*760c253cSXin Li- // skip all the go command machinery. 220*760c253cSXin Li- // This avoids any time the go command would 221*760c253cSXin Li- // spend checking whether, for example, the installed 222*760c253cSXin Li- // package runtime is up to date. 223*760c253cSXin Li- // Because we run lots of trivial test programs, 224*760c253cSXin Li- // the time adds up. 225*760c253cSXin Li- pkg := filepath.Join(t.tempDir, "pkg.a") 226*760c253cSXin Li- if _, err := runcmd("go", "tool", "compile", "-o", pkg, t.goFileName()); err != nil { 227*760c253cSXin Li- t.err = err 228*760c253cSXin Li- return 229*760c253cSXin Li- } 230*760c253cSXin Li- exe := filepath.Join(t.tempDir, "test.exe") 231*760c253cSXin Li- cmd := []string{"go", "tool", "link", "-s", "-w"} 232*760c253cSXin Li- cmd = append(cmd, "-o", exe, pkg) 233*760c253cSXin Li- if _, err := runcmd(cmd...); err != nil { 234*760c253cSXin Li- t.err = err 235*760c253cSXin Li- return 236*760c253cSXin Li- } 237*760c253cSXin Li- out, err = runcmd(append([]string{exe}, args...)...) 238*760c253cSXin Li- } else { 239*760c253cSXin Li- cmd := []string{"go", "run", goGcflags()} 240*760c253cSXin Li- if *linkshared { 241*760c253cSXin Li- cmd = append(cmd, "-linkshared") 242*760c253cSXin Li- } 243*760c253cSXin Li- cmd = append(cmd, flags...) 244*760c253cSXin Li- cmd = append(cmd, t.goFileName()) 245*760c253cSXin Li- out, err = runcmd(append(cmd, args...)...) 246*760c253cSXin Li- } 247*760c253cSXin Li+ out, err := goRun(runcmd, flags, t.goFileName(), args...) 248*760c253cSXin Li if err != nil { 249*760c253cSXin Li t.err = err 250*760c253cSXin Li return 251*760c253cSXin Li } 252*760c253cSXin Li if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { 253*760c253cSXin Li t.err = fmt.Errorf("incorrect output\n%s", out) 254*760c253cSXin Li } 255*760c253cSXin Li 256*760c253cSXin Li case "runoutput": 257*760c253cSXin Li rungatec <- true 258*760c253cSXin Li defer func() { 259*760c253cSXin Li <-rungatec 260*760c253cSXin Li }() 261*760c253cSXin Li useTmp = false 262*760c253cSXin Li- cmd := []string{"go", "run", goGcflags()} 263*760c253cSXin Li- if *linkshared { 264*760c253cSXin Li- cmd = append(cmd, "-linkshared") 265*760c253cSXin Li- } 266*760c253cSXin Li- cmd = append(cmd, t.goFileName()) 267*760c253cSXin Li- out, err := runcmd(append(cmd, args...)...) 268*760c253cSXin Li+ out, err := goRun(runcmd, nil, t.goFileName(), args...) 269*760c253cSXin Li if err != nil { 270*760c253cSXin Li t.err = err 271*760c253cSXin Li return 272*760c253cSXin Li } 273*760c253cSXin Li tfile := filepath.Join(t.tempDir, "tmp__.go") 274*760c253cSXin Li if err := ioutil.WriteFile(tfile, out, 0666); err != nil { 275*760c253cSXin Li t.err = fmt.Errorf("write tempfile:%s", err) 276*760c253cSXin Li return 277*760c253cSXin Li } 278*760c253cSXin Li- cmd = []string{"go", "run", goGcflags()} 279*760c253cSXin Li- if *linkshared { 280*760c253cSXin Li- cmd = append(cmd, "-linkshared") 281*760c253cSXin Li- } 282*760c253cSXin Li- cmd = append(cmd, tfile) 283*760c253cSXin Li- out, err = runcmd(cmd...) 284*760c253cSXin Li+ out, err = goRun(runcmd, nil, tfile) 285*760c253cSXin Li if err != nil { 286*760c253cSXin Li t.err = err 287*760c253cSXin Li return 288*760c253cSXin Li } 289*760c253cSXin Li if string(out) != t.expectedOutput() { 290*760c253cSXin Li t.err = fmt.Errorf("incorrect output\n%s", out) 291*760c253cSXin Li } 292*760c253cSXin Li 293*760c253cSXin Li case "errorcheckoutput": 294*760c253cSXin Li useTmp = false 295*760c253cSXin Li- cmd := []string{"go", "run", goGcflags()} 296*760c253cSXin Li- if *linkshared { 297*760c253cSXin Li- cmd = append(cmd, "-linkshared") 298*760c253cSXin Li- } 299*760c253cSXin Li- cmd = append(cmd, t.goFileName()) 300*760c253cSXin Li- out, err := runcmd(append(cmd, args...)...) 301*760c253cSXin Li+ out, err := goRun(runcmd, nil, t.goFileName(), args...) 302*760c253cSXin Li if err != nil { 303*760c253cSXin Li t.err = err 304*760c253cSXin Li return 305*760c253cSXin Li } 306*760c253cSXin Li tfile := filepath.Join(t.tempDir, "tmp__.go") 307*760c253cSXin Li err = ioutil.WriteFile(tfile, out, 0666) 308*760c253cSXin Li if err != nil { 309*760c253cSXin Li t.err = fmt.Errorf("write tempfile:%s", err) 310*760c253cSXin Li return 311*760c253cSXin Li } 312*760c253cSXin Li- cmdline := []string{"go", "tool", "compile", "-e", "-o", "a.o"} 313*760c253cSXin Li+ cmdline := []string{findGoCmd(), "tool", "compile", "-e", "-o", "a.o"} 314*760c253cSXin Li cmdline = append(cmdline, flags...) 315*760c253cSXin Li cmdline = append(cmdline, tfile) 316*760c253cSXin Li out, err = runcmd(cmdline...) 317*760c253cSXin Li if wantError { 318*760c253cSXin Li if err == nil { 319*760c253cSXin Li t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out) 320*760c253cSXin Li return 321*760c253cSXin Li } 322*760c253cSXin Li@@ -917,26 +872,37 @@ func (t *test) run() { 323*760c253cSXin Li 324*760c253cSXin Li var execCmd []string 325*760c253cSXin Li 326*760c253cSXin Li func findExecCmd() []string { 327*760c253cSXin Li if execCmd != nil { 328*760c253cSXin Li return execCmd 329*760c253cSXin Li } 330*760c253cSXin Li execCmd = []string{} // avoid work the second time 331*760c253cSXin Li+ if *target != "" { 332*760c253cSXin Li+ execCmd = []string{"go_" + *target + "_exec"} 333*760c253cSXin Li+ return execCmd 334*760c253cSXin Li+ } 335*760c253cSXin Li if goos == runtime.GOOS && goarch == runtime.GOARCH { 336*760c253cSXin Li return execCmd 337*760c253cSXin Li } 338*760c253cSXin Li path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch)) 339*760c253cSXin Li if err == nil { 340*760c253cSXin Li execCmd = []string{path} 341*760c253cSXin Li } 342*760c253cSXin Li return execCmd 343*760c253cSXin Li } 344*760c253cSXin Li 345*760c253cSXin Li+func findGoCmd() string { 346*760c253cSXin Li+ if *target != "" { 347*760c253cSXin Li+ return "go_" + *target 348*760c253cSXin Li+ } 349*760c253cSXin Li+ return "go" 350*760c253cSXin Li+} 351*760c253cSXin Li+ 352*760c253cSXin Li func (t *test) String() string { 353*760c253cSXin Li return filepath.Join(t.dir, t.gofile) 354*760c253cSXin Li } 355*760c253cSXin Li 356*760c253cSXin Li func (t *test) makeTempDir() { 357*760c253cSXin Li var err error 358*760c253cSXin Li t.tempDir, err = ioutil.TempDir("", "") 359*760c253cSXin Li check(err) 360