]> Cypherpunks repositories - gostls13.git/commitdiff
test: Add rundir, rundircmpout and errorcheckdir commands to testlib and run.go
authorDaniel Morsing <daniel.morsing@gmail.com>
Sat, 6 Oct 2012 07:23:31 +0000 (09:23 +0200)
committerDaniel Morsing <daniel.morsing@gmail.com>
Sat, 6 Oct 2012 07:23:31 +0000 (09:23 +0200)
rundir will compile each file in the directory in lexicographic order, link the last file as the main package and run the resulting program. rundircmpout is an related command, that will compare the output of the program to an corresponding .out file

errorcheckdir will compile each file in a directory in lexicographic order, running errorcheck on each file as it compiles. All compilations are assumed to be successful except for the last file. However, If a -0 flag is present on the command, the last compilation will also be assumed successful

This CL also includes a small refactoring of run.go. It was getting unwieldy and the meaning of the run commands was hidden behind argument line formatting.

Fixes #4058.

R=rsc, minux.ma, remyoudompheng, iant
CC=golang-dev
https://golang.org/cl/6554071

test/run.go
test/testlib

index 10dbceff5d4f1234a105641ab73cbae6751a6f0b..49bcd96c94cf9c51e855b1609957ed01a13e3439 100644 (file)
@@ -165,6 +165,22 @@ func goFiles(dir string) []string {
        return names
 }
 
+type runCmd func(...string) ([]byte, error)
+
+func compileFile(runcmd runCmd, longname string) (out []byte, err error) {
+       return runcmd("go", "tool", gc, "-e", longname)
+}
+
+func compileInDir(runcmd runCmd, dir, name string) (out []byte, err error) {
+       return runcmd("go", "tool", gc, "-e", "-D.", "-I.", filepath.Join(dir, name))
+}
+
+func linkFile(runcmd runCmd, goname string) (err error) {
+       pfile := strings.Replace(goname, ".go", "."+letter, -1)
+       _, err = runcmd("go", "tool", ld, "-o", "run.out", "-L", ".", pfile)
+       return
+}
+
 // skipError describes why a test was skipped.
 type skipError string
 
@@ -230,6 +246,19 @@ func (t *test) goDirName() string {
        return filepath.Join(t.dir, strings.Replace(t.gofile, ".go", ".dir", -1))
 }
 
+func goDirFiles(longdir string) (filter []os.FileInfo, err error) {
+       files, dirErr := ioutil.ReadDir(longdir)
+       if dirErr != nil {
+               return nil, dirErr
+       }
+       for _, gofile := range files {
+               if filepath.Ext(gofile.Name()) == ".go" {
+                       filter = append(filter, gofile)
+               }
+       }
+       return
+}
+
 // run runs a test.
 func (t *test) run() {
        defer close(t.donec)
@@ -263,12 +292,15 @@ func (t *test) run() {
        }
 
        switch action {
+       case "rundircmpout":
+               action = "rundir"
+               t.action = "rundir"
        case "cmpout":
                action = "run" // the run case already looks for <dir>/<test>.out files
                fallthrough
-       case "compile", "compiledir", "build", "run", "runoutput":
+       case "compile", "compiledir", "build", "run", "runoutput", "rundir":
                t.action = action
-       case "errorcheck":
+       case "errorcheck", "errorcheckdir":
                t.action = action
                wantError = true
                for len(args) > 0 && strings.HasPrefix(args[0], "-") {
@@ -308,6 +340,9 @@ func (t *test) run() {
                        cmd.Dir = t.tempDir
                }
                err := cmd.Run()
+               if err != nil {
+                       err = fmt.Errorf("%s\n%s", err, buf.Bytes())
+               }
                return buf.Bytes(), err
        }
 
@@ -328,7 +363,7 @@ func (t *test) run() {
                        }
                } else {
                        if err != nil {
-                               t.err = fmt.Errorf("%s\n%s", err, out)
+                               t.err = err
                                return
                        }
                }
@@ -336,42 +371,95 @@ func (t *test) run() {
                return
 
        case "compile":
-               out, err := runcmd("go", "tool", gc, "-e", "-o", "a."+letter, long)
-               if err != nil {
-                       t.err = fmt.Errorf("%s\n%s", err, out)
-               }
+               _, t.err = compileFile(runcmd, long)
 
        case "compiledir":
                // Compile all files in the directory in lexicographic order.
                longdir := filepath.Join(cwd, t.goDirName())
-               files, dirErr := ioutil.ReadDir(longdir)
-               if dirErr != nil {
-                       t.err = dirErr
+               files, err := goDirFiles(longdir)
+               if err != nil {
+                       t.err = err
                        return
                }
                for _, gofile := range files {
-                       if filepath.Ext(gofile.Name()) != ".go" {
-                               continue
+                       _, t.err = compileInDir(runcmd, longdir, gofile.Name())
+                       if t.err != nil {
+                               return
                        }
-                       afile := strings.Replace(gofile.Name(), ".go", "."+letter, -1)
-                       out, err := runcmd("go", "tool", gc, "-e", "-D.", "-I.", "-o", afile, filepath.Join(longdir, gofile.Name()))
-                       if err != nil {
-                               t.err = fmt.Errorf("%s\n%s", err, out)
+               }
+
+       case "errorcheckdir":
+               // errorcheck all files in lexicographic order
+               // useful for finding importing errors
+               longdir := filepath.Join(cwd, t.goDirName())
+               files, err := goDirFiles(longdir)
+               if err != nil {
+                       t.err = err
+                       return
+               }
+               for i, gofile := range files {
+                       out, err := compileInDir(runcmd, longdir, gofile.Name())
+                       if i == len(files)-1 {
+                               if wantError && err == nil {
+                                       t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
+                                       return
+                               } else if !wantError && err != nil {
+                                       t.err = err
+                                       return
+                               }
+                       } else if err != nil {
+                               t.err = err
+                               return
+                       }
+                       longname := filepath.Join(longdir, gofile.Name())
+                       t.err = t.errorCheck(string(out), longname, gofile.Name())
+                       if t.err != nil {
                                break
                        }
                }
 
+       case "rundir":
+               // Compile all files in the directory in lexicographic order.
+               // then link as if the last file is the main package and run it
+               longdir := filepath.Join(cwd, t.goDirName())
+               files, err := goDirFiles(longdir)
+               if err != nil {
+                       t.err = err
+                       return
+               }
+               var gofile os.FileInfo
+               for _, gofile = range files {
+                       _, err := compileInDir(runcmd, longdir, gofile.Name())
+                       if err != nil {
+                               t.err = err
+                               return
+                       }
+               }
+               err = linkFile(runcmd, gofile.Name())
+               if err != nil {
+                       t.err = err
+                       return
+               }
+               out, err := runcmd(append([]string{filepath.Join(t.tempDir, "run.out")}, 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 "build":
-               out, err := runcmd("go", "build", "-o", "a.exe", long)
+               _, err := runcmd("go", "build", "-o", "a.exe", long)
                if err != nil {
-                       t.err = fmt.Errorf("%s\n%s", err, out)
+                       t.err = err
                }
 
        case "run":
                useTmp = false
                out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
                if err != nil {
-                       t.err = fmt.Errorf("%s\n%s", err, out)
+                       t.err = err
                }
                if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
                        t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -381,7 +469,7 @@ func (t *test) run() {
                useTmp = false
                out, err := runcmd("go", "run", t.goFileName())
                if err != nil {
-                       t.err = fmt.Errorf("%s\n%s", err, out)
+                       t.err = err
                }
                tfile := filepath.Join(t.tempDir, "tmp__.go")
                err = ioutil.WriteFile(tfile, out, 0666)
@@ -391,7 +479,7 @@ func (t *test) run() {
                }
                out, err = runcmd("go", "run", tfile)
                if err != nil {
-                       t.err = fmt.Errorf("%s\n%s", err, out)
+                       t.err = err
                }
                if string(out) != t.expectedOutput() {
                        t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -444,7 +532,7 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) {
                out[i] = strings.Replace(out[i], full, short, -1)
        }
 
-       for _, we := range t.wantedErrors() {
+       for _, we := range t.wantedErrors(full, short) {
                var errmsgs []string
                errmsgs, out = partitionStrings(we.filterRe, out)
                if len(errmsgs) == 0 {
@@ -505,8 +593,9 @@ var (
        lineRx      = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
 )
 
-func (t *test) wantedErrors() (errs []wantedError) {
-       for i, line := range strings.Split(t.src, "\n") {
+func (t *test) wantedErrors(file, short string) (errs []wantedError) {
+       src, _ := ioutil.ReadFile(file)
+       for i, line := range strings.Split(string(src), "\n") {
                lineNum := i + 1
                if strings.Contains(line, "////") {
                        // double comment disables ERROR
@@ -531,15 +620,15 @@ func (t *test) wantedErrors() (errs []wantedError) {
                                        delta, _ := strconv.Atoi(m[5:])
                                        n -= delta
                                }
-                               return fmt.Sprintf("%s:%d", t.gofile, n)
+                               return fmt.Sprintf("%s:%d", short, n)
                        })
-                       filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, t.gofile, lineNum)
+                       filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, short, lineNum)
                        errs = append(errs, wantedError{
                                reStr:    rx,
                                re:       regexp.MustCompile(rx),
                                filterRe: regexp.MustCompile(filterPattern),
                                lineNum:  lineNum,
-                               file:     t.gofile,
+                               file:     short,
                        })
                }
        }
index 29de7672ce1b6416898ecbf27ecebbebf951f0a9..8033b7f93cdb42b74e22297838def60b14bf5d39 100644 (file)
@@ -16,6 +16,46 @@ compiledir() {
        done
 }
 
+errorcheckdir() {
+       lastzero=""
+       if [ "$1" = "-0" ]; then
+               lastzero="-0"
+       fi
+       files=($D/$F.dir/*.go)
+       for gofile in ${files[@]}
+       do
+               zero="-0"
+               if [ ${files[${#files[@]}-1]} = $gofile ]; then
+                       zero=$lastzero
+               fi
+               errchk $zero $G -D. -I. -e $gofile
+       done
+}
+
+rundir() {
+       lastfile=""
+       for gofile in $D/$F.dir/*.go
+       do
+               name=$(basename ${gofile/\.go/} )
+               $G -D. -I. -e "$gofile" || return 1
+               lastfile=$name
+       done
+       $L -o $A.out -L. $lastfile.$A
+       ./$A.out
+}
+
+rundircmpout() {
+       lastfile=""
+       for gofile in $D/$F.dir/*.go
+       do
+               name=$(basename ${gofile/\.go/} )
+               $G -D. -I. -e "$gofile" || return 1
+               lastfile=$name
+       done
+       $L -o $A.out -L. $lastfile.$A
+       ./$A.out | cmp - $D/$F.out
+}
+
 build() {
        $G $D/$F.go && $L $F.$A
 }