Commit d5887c5a authored by Russ Cox's avatar Russ Cox

test/run: make errorcheck tests faster

Some of the errorcheck tests have many many identical regexps.
Use a map to avoid storing the compiled form many many times
in memory. Change the filterRe to a simple string to avoid
the expense of those regexps as well.

Cuts the time for run.go on index2.go by almost 50x.

Noticed during debugging of issue 7344.

LGTM=bradfitz
R=bradfitz, josharian
CC=golang-codereviews
https://golang.org/cl/74380043
parent ab844022
...@@ -760,7 +760,7 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) { ...@@ -760,7 +760,7 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
for _, we := range want { for _, we := range want {
var errmsgs []string var errmsgs []string
errmsgs, out = partitionStrings(we.filterRe, out) errmsgs, out = partitionStrings(we.prefix, out)
if len(errmsgs) == 0 { if len(errmsgs) == 0 {
errs = append(errs, fmt.Errorf("%s:%d: missing error %q", we.file, we.lineNum, we.reStr)) errs = append(errs, fmt.Errorf("%s:%d: missing error %q", we.file, we.lineNum, we.reStr))
continue continue
...@@ -802,9 +802,29 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) { ...@@ -802,9 +802,29 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
} }
func partitionStrings(rx *regexp.Regexp, strs []string) (matched, unmatched []string) { // matchPrefix reports whether s is of the form ^(.*/)?prefix(:|[),
// That is, it needs the file name prefix followed by a : or a [,
// and possibly preceded by a directory name.
func matchPrefix(s, prefix string) bool {
i := strings.Index(s, ":")
if i < 0 {
return false
}
j := strings.LastIndex(s[:i], "/")
s = s[j+1:]
if len(s) <= len(prefix) || s[:len(prefix)] != prefix {
return false
}
switch s[len(prefix)] {
case '[', ':':
return true
}
return false
}
func partitionStrings(prefix string, strs []string) (matched, unmatched []string) {
for _, s := range strs { for _, s := range strs {
if rx.MatchString(s) { if matchPrefix(s, prefix) {
matched = append(matched, s) matched = append(matched, s)
} else { } else {
unmatched = append(unmatched, s) unmatched = append(unmatched, s)
...@@ -818,7 +838,7 @@ type wantedError struct { ...@@ -818,7 +838,7 @@ type wantedError struct {
re *regexp.Regexp re *regexp.Regexp
lineNum int lineNum int
file string file string
filterRe *regexp.Regexp // /^file:linenum\b/m prefix string
} }
var ( var (
...@@ -828,6 +848,8 @@ var ( ...@@ -828,6 +848,8 @@ var (
) )
func (t *test) wantedErrors(file, short string) (errs []wantedError) { func (t *test) wantedErrors(file, short string) (errs []wantedError) {
cache := make(map[string]*regexp.Regexp)
src, _ := ioutil.ReadFile(file) src, _ := ioutil.ReadFile(file)
for i, line := range strings.Split(string(src), "\n") { for i, line := range strings.Split(string(src), "\n") {
lineNum := i + 1 lineNum := i + 1
...@@ -856,15 +878,20 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) { ...@@ -856,15 +878,20 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
} }
return fmt.Sprintf("%s:%d", short, n) return fmt.Sprintf("%s:%d", short, n)
}) })
re, err := regexp.Compile(rx) re := cache[rx]
if re == nil {
var err error
re, err = regexp.Compile(rx)
if err != nil { if err != nil {
log.Fatalf("%s:%d: invalid regexp in ERROR line: %v", t.goFileName(), lineNum, err) log.Fatalf("%s:%d: invalid regexp in ERROR line: %v", t.goFileName(), lineNum, err)
} }
filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, regexp.QuoteMeta(short), lineNum) cache[rx] = re
}
prefix := fmt.Sprintf("%s:%d", short, lineNum)
errs = append(errs, wantedError{ errs = append(errs, wantedError{
reStr: rx, reStr: rx,
re: re, re: re,
filterRe: regexp.MustCompile(filterPattern), prefix: prefix,
lineNum: lineNum, lineNum: lineNum,
file: short, file: short,
}) })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment