test: add support for build tags.
This enables a few tests that were only executed
unconditionnally.
R=rsc, minux.ma, bradfitz
CC=golang-dev
https://golang.org/cl/7103051
diff --git a/test/run.go b/test/run.go
index fb528fa..bc545df 100644
--- a/test/run.go
+++ b/test/run.go
@@ -299,6 +299,50 @@
return pkgs, nil
}
+// shouldTest looks for build tags in a source file and returns
+// whether the file should be used according to the tags.
+func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
+ if idx := strings.Index(src, "\npackage"); idx >= 0 {
+ src = src[:idx]
+ }
+ notgoos := "!" + goos
+ notgoarch := "!" + goarch
+ for _, line := range strings.Split(src, "\n") {
+ line = strings.TrimSpace(line)
+ if strings.HasPrefix(line, "//") {
+ line = line[2:]
+ } else {
+ continue
+ }
+ line = strings.TrimSpace(line)
+ if len(line) == 0 || line[0] != '+' {
+ continue
+ }
+ words := strings.Fields(line)
+ if words[0] == "+build" {
+ for _, word := range words {
+ switch word {
+ case goos, goarch:
+ return true, ""
+ case notgoos, notgoarch:
+ continue
+ default:
+ if word[0] == '!' {
+ // NOT something-else
+ return true, ""
+ }
+ }
+ }
+ // no matching tag found.
+ return false, line
+ }
+ }
+ // no build tags.
+ return true, ""
+}
+
+func init() { checkShouldTest() }
+
// run runs a test.
func (t *test) run() {
defer close(t.donec)
@@ -318,7 +362,18 @@
t.err = errors.New("double newline not found")
return
}
+ if ok, why := shouldTest(t.src, runtime.GOOS, runtime.GOARCH); !ok {
+ t.action = "skip"
+ if *showSkips {
+ fmt.Printf("%-20s %-20s: %s\n", t.action, t.goFileName(), why)
+ }
+ return
+ }
action := t.src[:pos]
+ if nl := strings.Index(action, "\n"); nl >= 0 && strings.Contains(action[:nl], "+build") {
+ // skip first line
+ action = action[nl+1:]
+ }
if strings.HasPrefix(action, "//") {
action = action[2:]
}
@@ -732,17 +787,14 @@
}
var skipOkay = map[string]bool{
- "linkx.go": true,
- "sigchld.go": true,
- "sinit.go": true,
- "fixedbugs/bug248.go": true, // combines errorcheckdir and rundir in the same dir.
- "fixedbugs/bug302.go": true, // tests both .$O and .a imports.
- "fixedbugs/bug345.go": true, // needs the appropriate flags in gc invocation.
- "fixedbugs/bug369.go": true, // needs compiler flags.
- "fixedbugs/bug385_32.go": true, // arch-specific errors.
- "fixedbugs/bug385_64.go": true, // arch-specific errors.
- "fixedbugs/bug429.go": true,
- "bugs/bug395.go": true,
+ "linkx.go": true, // like "run" but wants linker flags
+ "sinit.go": true,
+ "fixedbugs/bug248.go": true, // combines errorcheckdir and rundir in the same dir.
+ "fixedbugs/bug302.go": true, // tests both .$O and .a imports.
+ "fixedbugs/bug345.go": true, // needs the appropriate flags in gc invocation.
+ "fixedbugs/bug369.go": true, // needs compiler flags.
+ "fixedbugs/bug429.go": true, // like "run" but program should fail
+ "bugs/bug395.go": true,
}
// defaultRunOutputLimit returns the number of runoutput tests that
@@ -756,3 +808,18 @@
}
return cpu
}
+
+// checkShouldTest runs canity checks on the shouldTest function.
+func checkShouldTest() {
+ assert := func(ok bool, _ string) {
+ if !ok {
+ panic("fail")
+ }
+ }
+ assertNot := func(ok bool, _ string) { assert(!ok, "") }
+ assert(shouldTest("// +build linux", "linux", "arm"))
+ assert(shouldTest("// +build !windows", "linux", "arm"))
+ assertNot(shouldTest("// +build !windows", "windows", "amd64"))
+ assertNot(shouldTest("// +build arm 386", "linux", "amd64"))
+ assert(shouldTest("// This is a test.", "os", "arch"))
+}