summaryrefslogtreecommitdiff
path: root/gcc/testsuite/go.test/test/run.go
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/go.test/test/run.go')
-rw-r--r--gcc/testsuite/go.test/test/run.go134
1 files changed, 101 insertions, 33 deletions
diff --git a/gcc/testsuite/go.test/test/run.go b/gcc/testsuite/go.test/test/run.go
index 5e167d6b0cc..5c94de6400f 100644
--- a/gcc/testsuite/go.test/test/run.go
+++ b/gcc/testsuite/go.test/test/run.go
@@ -27,6 +27,8 @@ import (
"sort"
"strconv"
"strings"
+ "time"
+ "unicode"
)
var (
@@ -113,28 +115,39 @@ func main() {
failed := false
resCount := map[string]int{}
for _, test := range tests {
- <-test.donec
- _, isSkip := test.err.(skipError)
- errStr := "pass"
+ <-test.donec
+ status := "ok "
+ errStr := ""
+ if _, isSkip := test.err.(skipError); isSkip {
+ status = "skip"
+ test.err = nil
+ if !skipOkay[path.Join(test.dir, test.gofile)] {
+ errStr = "unexpected skip for " + path.Join(test.dir, test.gofile) + ": " + errStr
+ status = "FAIL"
+ }
+ }
if test.err != nil {
+ status = "FAIL"
errStr = test.err.Error()
- if !isSkip {
- failed = true
- }
}
- if isSkip && !skipOkay[path.Join(test.dir, test.gofile)] {
- errStr = "unexpected skip for " + path.Join(test.dir, test.gofile) + ": " + errStr
- isSkip = false
+ if status == "FAIL" {
failed = true
}
- resCount[errStr]++
- if isSkip && !*verbose && !*showSkips {
+ resCount[status]++
+ if status == "skip" && !*verbose && !*showSkips {
+ continue
+ }
+ dt := fmt.Sprintf("%.3fs", test.dt.Seconds())
+ if status == "FAIL" {
+ fmt.Printf("# go run run.go -- %s\n%s\nFAIL\t%s\t%s\n",
+ path.Join(test.dir, test.gofile),
+ errStr, test.goFileName(), dt)
continue
}
- if !*verbose && test.err == nil {
+ if !*verbose {
continue
}
- fmt.Printf("%-20s %-20s: %s\n", test.action, test.goFileName(), errStr)
+ fmt.Printf("%s\t%s\t%s\n", status, test.goFileName(), dt)
}
if *summary {
@@ -206,7 +219,8 @@ func check(err error) {
type test struct {
dir, gofile string
donec chan bool // closed when done
-
+ dt time.Duration
+
src string
action string // "compile", "build", etc.
@@ -299,14 +313,17 @@ func goDirPackages(longdir string) ([][]string, error) {
return pkgs, nil
}
+type context struct {
+ GOOS string
+ GOARCH string
+}
+
// 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, "//") {
@@ -318,34 +335,68 @@ func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
if len(line) == 0 || line[0] != '+' {
continue
}
+ ctxt := &context{
+ GOOS: goos,
+ GOARCH: goarch,
+ }
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, ""
- }
+ ok := false
+ for _, word := range words[1:] {
+ if ctxt.match(word) {
+ ok = true
+ break
}
}
- // no matching tag found.
- return false, line
+ if !ok {
+ // no matching tag found.
+ return false, line
+ }
}
}
- // no build tags.
+ // no build tags
return true, ""
}
+func (ctxt *context) match(name string) bool {
+ if name == "" {
+ return false
+ }
+ if i := strings.Index(name, ","); i >= 0 {
+ // comma-separated list
+ return ctxt.match(name[:i]) && ctxt.match(name[i+1:])
+ }
+ if strings.HasPrefix(name, "!!") { // bad syntax, reject always
+ return false
+ }
+ if strings.HasPrefix(name, "!") { // negation
+ return len(name) > 1 && !ctxt.match(name[1:])
+ }
+
+ // Tags must be letters, digits, underscores or dots.
+ // Unlike in Go identifiers, all digits are fine (e.g., "386").
+ for _, c := range name {
+ if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
+ return false
+ }
+ }
+
+ if name == ctxt.GOOS || name == ctxt.GOARCH {
+ return true
+ }
+
+ return false
+}
+
func init() { checkShouldTest() }
// run runs a test.
func (t *test) run() {
- defer close(t.donec)
+ start := time.Now()
+ defer func() {
+ t.dt = time.Since(start)
+ close(t.donec)
+ }()
srcBytes, err := ioutil.ReadFile(t.goFileName())
if err != nil {
@@ -815,7 +866,7 @@ func defaultRunOutputLimit() int {
return cpu
}
-// checkShouldTest runs canity checks on the shouldTest function.
+// checkShouldTest runs sanity checks on the shouldTest function.
func checkShouldTest() {
assert := func(ok bool, _ string) {
if !ok {
@@ -823,11 +874,28 @@ func checkShouldTest() {
}
}
assertNot := func(ok bool, _ string) { assert(!ok, "") }
+
+ // Simple tests.
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"))
+
+ // A file with no build tags will always be tested.
assert(shouldTest("// This is a test.", "os", "arch"))
+
+ // Build tags separated by a space are OR-ed together.
+ assertNot(shouldTest("// +build arm 386", "linux", "amd64"))
+
+ // Build tags seperated by a comma are AND-ed together.
+ assertNot(shouldTest("// +build !windows,!plan9", "windows", "amd64"))
+ assertNot(shouldTest("// +build !windows,!plan9", "plan9", "386"))
+
+ // Build tags on multiple lines are AND-ed together.
+ assert(shouldTest("// +build !windows\n// +build amd64", "linux", "amd64"))
+ assertNot(shouldTest("// +build !windows\n// +build amd64", "windows", "amd64"))
+
+ // Test that (!a OR !b) matches anything.
+ assert(shouldTest("// +build !windows !plan9", "windows", "amd64"))
}
// envForDir returns a copy of the environment