test: add -target flag. --- test/run.go +++ test/run.go @@ -34,19 +34,19 @@ import ( var ( verbose = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.") keep = flag.Bool("k", false, "keep. keep temporary directory.") numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run") summary = flag.Bool("summary", false, "show summary of results") showSkips = flag.Bool("show_skips", false, "show skipped tests") runSkips = flag.Bool("run_skips", false, "run skipped tests (ignore skip and build tags)") - linkshared = flag.Bool("linkshared", false, "") updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output") runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run") + target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries") shard = flag.Int("shard", 0, "shard index to run. Only applicable if -shards is non-zero.") shards = flag.Int("shards", 0, "number of shards. If 0, all tests are run. This is used by the continuous build.") ) var ( goos, goarch string @@ -189,48 +189,49 @@ func goFiles(dir string) []string { } sort.Strings(names) return names } type runCmd func(...string) ([]byte, error) func compileFile(runcmd runCmd, longname string, flags []string) (out []byte, err error) { - cmd := []string{"go", "tool", "compile", "-e"} + cmd := []string{findGoCmd(), "tool", "compile", "-e"} cmd = append(cmd, flags...) - if *linkshared { - cmd = append(cmd, "-dynlink", "-installsuffix=dynlink") - } cmd = append(cmd, longname) return runcmd(cmd...) } func compileInDir(runcmd runCmd, dir string, flags []string, names ...string) (out []byte, err error) { - cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", "."} + cmd := []string{findGoCmd(), "tool", "compile", "-e", "-D", ".", "-I", "."} cmd = append(cmd, flags...) - if *linkshared { - cmd = append(cmd, "-dynlink", "-installsuffix=dynlink") - } for _, name := range names { cmd = append(cmd, filepath.Join(dir, name)) } return runcmd(cmd...) } func linkFile(runcmd runCmd, goname string) (err error) { pfile := strings.Replace(goname, ".go", ".o", -1) - cmd := []string{"go", "tool", "link", "-w", "-o", "a.exe", "-L", "."} - if *linkshared { - cmd = append(cmd, "-linkshared", "-installsuffix=dynlink") - } - cmd = append(cmd, pfile) - _, err = runcmd(cmd...) + _, err = runcmd(findGoCmd(), "tool", "link", "-w", "-o", "a.exe", "-L", ".", pfile) return } +func goRun(runcmd runCmd, flags []string, goname string, args ...string) (out []byte, err error) { + cmd := []string{findGoCmd(), "run", goGcflags()} + if len(findExecCmd()) > 0 { + cmd = append(cmd, "-exec") + cmd = append(cmd, findExecCmd()...) + } + cmd = append(cmd, flags...) + cmd = append(cmd, goname) + cmd = append(cmd, args...) + return runcmd(cmd...) +} + // skipError describes why a test was skipped. type skipError string func (s skipError) Error() string { return string(s) } func check(err error) { if err != nil { log.Fatal(err) @@ -590,18 +591,17 @@ func (t *test) run() { long := filepath.Join(cwd, t.goFileName()) switch action { default: t.err = fmt.Errorf("unimplemented action %q", action) case "errorcheck": // TODO(gri) remove need for -C (disable printing of columns in error messages) - cmdline := []string{"go", "tool", "compile", "-C", "-e", "-o", "a.o"} - // No need to add -dynlink even if linkshared if we're just checking for errors... + cmdline := []string{findGoCmd(), "tool", "compile", "-C", "-e", "-o", "a.o"} cmdline = append(cmdline, flags...) cmdline = append(cmdline, long) out, err := runcmd(cmdline...) if wantError { if err == nil { t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out) return } @@ -704,17 +704,17 @@ func (t *test) run() { } if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { t.err = fmt.Errorf("incorrect output\n%s", out) } } } case "build": - _, err := runcmd("go", "build", goGcflags(), "-o", "a.exe", long) + _, err := runcmd(findGoCmd(), "build", goGcflags(), "-o", "a.exe", long) if err != nil { t.err = err } case "builddir": // Build an executable from all the .go and .s files in a subdirectory. useTmp = true longdir := filepath.Join(cwd, t.goDirName()) @@ -730,177 +730,132 @@ func (t *test) run() { case ".go": gos = append(gos, file) case ".s": asms = append(asms, file) } } var objs []string - cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"} + cmd := []string{findGoCmd(), "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"} if len(asms) > 0 { cmd = append(cmd, "-asmhdr", "go_asm.h") } for _, file := range gos { cmd = append(cmd, filepath.Join(longdir, file.Name())) } _, err := runcmd(cmd...) if err != nil { t.err = err break } objs = append(objs, "go.o") if len(asms) > 0 { - cmd = []string{"go", "tool", "asm", "-e", "-I", ".", "-o", "asm.o"} + cmd = []string{findGoCmd(), "tool", "asm", "-e", "-I", ".", "-o", "asm.o"} for _, file := range asms { cmd = append(cmd, filepath.Join(longdir, file.Name())) } _, err = runcmd(cmd...) if err != nil { t.err = err break } objs = append(objs, "asm.o") } - cmd = []string{"go", "tool", "pack", "c", "all.a"} + cmd = []string{findGoCmd(), "tool", "pack", "c", "all.a"} cmd = append(cmd, objs...) _, err = runcmd(cmd...) if err != nil { t.err = err break } - cmd = []string{"go", "tool", "link", "all.a"} + cmd = []string{findGoCmd(), "tool", "link", "all.a"} _, err = runcmd(cmd...) if err != nil { t.err = err break } case "buildrun": // build binary, then run binary, instead of go run. Useful for timeout tests where failure mode is infinite loop. // TODO: not supported on NaCl useTmp = true - cmd := []string{"go", "build", goGcflags(), "-o", "a.exe"} - if *linkshared { - cmd = append(cmd, "-linkshared") - } + cmd := []string{findGoCmd(), "build", goGcflags(), "-o", "a.exe"} longdirgofile := filepath.Join(filepath.Join(cwd, t.dir), t.gofile) cmd = append(cmd, flags...) cmd = append(cmd, longdirgofile) out, err := runcmd(cmd...) if err != nil { t.err = err return } - cmd = []string{"./a.exe"} + cmd = []string{} + if len(findExecCmd()) > 0 { + cmd = append(cmd, findExecCmd()...) + } + cmd = append(cmd, "./a.exe") out, err = runcmd(append(cmd, args...)...) if err != nil { t.err = err return } if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { t.err = fmt.Errorf("incorrect output\n%s", out) } case "run": useTmp = false - var out []byte - var err error - if len(flags)+len(args) == 0 && goGcflags() == "" && !*linkshared { - // If we're not using special go command flags, - // skip all the go command machinery. - // This avoids any time the go command would - // spend checking whether, for example, the installed - // package runtime is up to date. - // Because we run lots of trivial test programs, - // the time adds up. - pkg := filepath.Join(t.tempDir, "pkg.a") - if _, err := runcmd("go", "tool", "compile", "-o", pkg, t.goFileName()); err != nil { - t.err = err - return - } - exe := filepath.Join(t.tempDir, "test.exe") - cmd := []string{"go", "tool", "link", "-s", "-w"} - cmd = append(cmd, "-o", exe, pkg) - if _, err := runcmd(cmd...); err != nil { - t.err = err - return - } - out, err = runcmd(append([]string{exe}, args...)...) - } else { - cmd := []string{"go", "run", goGcflags()} - if *linkshared { - cmd = append(cmd, "-linkshared") - } - cmd = append(cmd, flags...) - cmd = append(cmd, t.goFileName()) - out, err = runcmd(append(cmd, args...)...) - } + out, err := goRun(runcmd, flags, t.goFileName(), args...) if err != nil { t.err = err return } if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { t.err = fmt.Errorf("incorrect output\n%s", out) } case "runoutput": rungatec <- true defer func() { <-rungatec }() useTmp = false - cmd := []string{"go", "run", goGcflags()} - if *linkshared { - cmd = append(cmd, "-linkshared") - } - cmd = append(cmd, t.goFileName()) - out, err := runcmd(append(cmd, args...)...) + out, err := goRun(runcmd, nil, t.goFileName(), args...) if err != nil { t.err = err return } tfile := filepath.Join(t.tempDir, "tmp__.go") if err := ioutil.WriteFile(tfile, out, 0666); err != nil { t.err = fmt.Errorf("write tempfile:%s", err) return } - cmd = []string{"go", "run", goGcflags()} - if *linkshared { - cmd = append(cmd, "-linkshared") - } - cmd = append(cmd, tfile) - out, err = runcmd(cmd...) + out, err = goRun(runcmd, nil, tfile) if err != nil { t.err = err return } if string(out) != t.expectedOutput() { t.err = fmt.Errorf("incorrect output\n%s", out) } case "errorcheckoutput": useTmp = false - cmd := []string{"go", "run", goGcflags()} - if *linkshared { - cmd = append(cmd, "-linkshared") - } - cmd = append(cmd, t.goFileName()) - out, err := runcmd(append(cmd, args...)...) + out, err := goRun(runcmd, nil, t.goFileName(), args...) if err != nil { t.err = err return } tfile := filepath.Join(t.tempDir, "tmp__.go") err = ioutil.WriteFile(tfile, out, 0666) if err != nil { t.err = fmt.Errorf("write tempfile:%s", err) return } - cmdline := []string{"go", "tool", "compile", "-e", "-o", "a.o"} + cmdline := []string{findGoCmd(), "tool", "compile", "-e", "-o", "a.o"} cmdline = append(cmdline, flags...) cmdline = append(cmdline, tfile) out, err = runcmd(cmdline...) if wantError { if err == nil { t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out) return } @@ -917,26 +872,37 @@ func (t *test) run() { var execCmd []string func findExecCmd() []string { if execCmd != nil { return execCmd } execCmd = []string{} // avoid work the second time + if *target != "" { + execCmd = []string{"go_" + *target + "_exec"} + return execCmd + } if goos == runtime.GOOS && goarch == runtime.GOARCH { return execCmd } path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch)) if err == nil { execCmd = []string{path} } return execCmd } +func findGoCmd() string { + if *target != "" { + return "go_" + *target + } + return "go" +} + func (t *test) String() string { return filepath.Join(t.dir, t.gofile) } func (t *test) makeTempDir() { var err error t.tempDir, err = ioutil.TempDir("", "") check(err)