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