github.com/goplus/gossa@v0.3.25/cmd/gossatest/main.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"go/build"
     7  	"io/ioutil"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"runtime"
    12  	"strings"
    13  	"time"
    14  )
    15  
    16  var (
    17  	gorootTestSkips = make(map[string]string)
    18  )
    19  
    20  func init() {
    21  	if runtime.GOARCH == "386" {
    22  		gorootTestSkips["printbig.go"] = "load failed"
    23  		gorootTestSkips["peano.go"] = "stack overflow"
    24  	}
    25  	gorootTestSkips["closure.go"] = "runtime.ReadMemStats"
    26  	gorootTestSkips["divmod.go"] = "slow, 1m18s"
    27  	gorootTestSkips["copy.go"] = "slow, 13s"
    28  	gorootTestSkips["finprofiled.go"] = "slow, 21s"
    29  	gorootTestSkips["gcgort.go"] = "slow, 2s"
    30  	gorootTestSkips["inline_literal.go"] = "TODO, runtime.FuncForPC"
    31  	gorootTestSkips["nilptr.go"] = "skip drawin"
    32  	gorootTestSkips["heapsampling.go"] = "runtime.MemProfileRecord"
    33  	gorootTestSkips["makeslice.go"] = "TODO, panic info, allocation size out of range"
    34  	gorootTestSkips["stackobj.go"] = "skip gc"
    35  	gorootTestSkips["stackobj3.go"] = "skip gc"
    36  	gorootTestSkips["nilptr_aix.go"] = "skip"
    37  	gorootTestSkips["init1.go"] = "skip gc"
    38  	gorootTestSkips["ken/divconst.go"] = "slow, 3.5s"
    39  	gorootTestSkips["ken/modconst.go"] = "slow, 3.3s"
    40  	gorootTestSkips["fixedbugs/bug347.go"] = "runtime.Caller"
    41  	gorootTestSkips["fixedbugs/bug348.go"] = "runtime.Caller"
    42  	gorootTestSkips["fixedbugs/issue24491b.go"] = "timeout"
    43  	//gorootTestSkips["fixedbugs/issue22781.go"] = "slow, 1.4s"
    44  	gorootTestSkips["fixedbugs/issue16249.go"] = "slow, 4.5s"
    45  	gorootTestSkips["fixedbugs/issue13169.go"] = "slow, 5.9s"
    46  	gorootTestSkips["fixedbugs/bug261.go"] = "BUG, ssa slice[low|high] https://github.com/golang/tools/pull/341"
    47  	gorootTestSkips["fixedbugs/issue11656.go"] = "runtime.Caller"
    48  	gorootTestSkips["fixedbugs/issue15281.go"] = "runtime.ReadMemStats"
    49  	gorootTestSkips["fixedbugs/issue17381.go"] = "runtime.FuncForPC"
    50  	gorootTestSkips["fixedbugs/issue18149.go"] = "runtime.Caller"
    51  	gorootTestSkips["fixedbugs/issue22083.go"] = "debug.Stack"
    52  	gorootTestSkips["fixedbugs/issue22662.go"] = "runtime.Caller"
    53  	gorootTestSkips["fixedbugs/issue27201.go"] = "runtime.Caller"
    54  	gorootTestSkips["fixedbugs/issue27201.go"] = "runtime.Caller"
    55  	gorootTestSkips["fixedbugs/issue27518b.go"] = "BUG, runtime.SetFinalizer"
    56  	gorootTestSkips["fixedbugs/issue29504.go"] = "runtime.Caller"
    57  	gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
    58  	gorootTestSkips["fixedbugs/issue41239.go"] = "BUG, reflect.Append: different capacity on append"
    59  	gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
    60  	gorootTestSkips["fixedbugs/issue45175.go"] = "BUG, ssa.Phi call order"
    61  	gorootTestSkips["fixedbugs/issue4562.go"] = "runtime.Caller"
    62  	gorootTestSkips["fixedbugs/issue4618.go"] = "testing.AllocsPerRun"
    63  	gorootTestSkips["fixedbugs/issue4667.go"] = "testing.AllocsPerRun"
    64  	gorootTestSkips["fixedbugs/issue5856.go"] = "runtime.Caller"
    65  	//gorootTestSkips["fixedbugs/issue5963.go"] = "BUG, recover"
    66  	gorootTestSkips["fixedbugs/issue7690.go"] = "runtime.Stack"
    67  	gorootTestSkips["fixedbugs/issue8606b.go"] = "BUG, optimization check"
    68  	gorootTestSkips["fixedbugs/issue30116u.go"] = "BUG, slice bound check"
    69  	//gorootTestSkips["fixedbugs/bug295.go"] = "skip, gossa not import testing"
    70  	//gorootTestSkips["fixedbugs/issue27695.go"] = "runtime/debug.SetGCPercent"
    71  	//gorootTestSkips["atomicload.go"] = "slow, 0.5"
    72  	gorootTestSkips["chan/select5.go"] = "bug, select case expr call order"
    73  	gorootTestSkips["fixedbugs/issue21879.go"] = "runtime.Callers"
    74  
    75  	// fixedbugs/issue7740.go
    76  	// const ulp = (1.0 + (2.0 / 3.0)) - (5.0 / 3.0)
    77  	// Go 1.14 1.15 1.16 ulp = 1.4916681462400413e-154
    78  	// Go 1.17 1.18 ulp = 0
    79  
    80  	ver := runtime.Version()[:6]
    81  	switch ver {
    82  	case "go1.17", "go1.18":
    83  		gorootTestSkips["fixedbugs/issue45045.go"] = "runtime.SetFinalizer"
    84  		gorootTestSkips["fixedbugs/issue46725.go"] = "runtime.SetFinalizer"
    85  		gorootTestSkips["abi/fibish.go"] = "slow, 34s"
    86  		gorootTestSkips["abi/fibish_closure.go"] = "slow, 35s"
    87  		gorootTestSkips["abi/uglyfib.go"] = "5m48s"
    88  		gorootTestSkips["fixedbugs/issue23017.go"] = "BUG"
    89  	case "go1.16":
    90  		gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
    91  	case "go1.15":
    92  		gorootTestSkips["fixedbugs/issue15039.go"] = "BUG, uint64 -> string"
    93  		gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
    94  		gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
    95  	case "go1.14":
    96  		gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
    97  		gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
    98  	}
    99  
   100  	if runtime.GOOS == "windows" {
   101  		gorootTestSkips["env.go"] = "skip GOARCH"
   102  		gorootTestSkips["fixedbugs/issue15002.go"] = "skip windows"
   103  		gorootTestSkips["fixedbugs/issue5493.go"] = "skip windows"
   104  		gorootTestSkips["fixedbugs/issue5963.go"] = "skip windows"
   105  
   106  		skips := make(map[string]string)
   107  		for k, v := range gorootTestSkips {
   108  			skips[filepath.FromSlash(k)] = v
   109  		}
   110  		gorootTestSkips = skips
   111  	} else if runtime.GOOS == "darwin" {
   112  		gorootTestSkips["locklinear.go"] = "skip github"
   113  	}
   114  }
   115  
   116  var (
   117  	goCmd    string
   118  	gossaCmd string
   119  )
   120  
   121  func init() {
   122  	var err error
   123  	gossaCmd, err = exec.LookPath("gossa")
   124  	if err != nil {
   125  		panic(fmt.Sprintf("not found gossa: %v", err))
   126  	}
   127  	goCmd, err = exec.LookPath("go")
   128  	if err != nil {
   129  		panic(fmt.Sprintf("not found go: %v", err))
   130  	}
   131  }
   132  
   133  func runCommand(input string, chkout bool) bool {
   134  	fmt.Println("Input:", input)
   135  	start := time.Now()
   136  	cmd := exec.Command(gossaCmd, "run", input)
   137  	data, err := cmd.CombinedOutput()
   138  	if len(data) > 0 {
   139  		fmt.Println(string(data))
   140  	}
   141  	if chkout {
   142  		if chk, e := ioutil.ReadFile(input[:len(input)-3] + ".out"); e == nil {
   143  			if bytes.Compare(data, chk) != 0 {
   144  				err = fmt.Errorf("-- output check error --\n%v", string(chk))
   145  			}
   146  		}
   147  	}
   148  
   149  	sec := time.Since(start).Seconds()
   150  	if err != nil || bytes.Contains(data, []byte("BUG")) {
   151  		fmt.Println(err)
   152  		fmt.Printf("FAIL %0.3fs\n", sec)
   153  		return false
   154  	}
   155  	fmt.Printf("PASS %0.3fs\n", sec)
   156  	return true
   157  }
   158  
   159  func printFailures(failures []string) {
   160  	if failures != nil {
   161  		fmt.Println("The following tests failed:")
   162  		for _, f := range failures {
   163  			fmt.Printf("\t%s\n", f)
   164  		}
   165  	}
   166  }
   167  
   168  type runfile struct {
   169  	filePath string // go source file path
   170  	checkOut bool   // check output file.out
   171  }
   172  
   173  // $GOROOT/test/*.go runs
   174  func getGorootTestRuns() (dir string, run []runfile, runoutput []string) {
   175  	dir = filepath.Join(build.Default.GOROOT, "test")
   176  	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
   177  		if info.IsDir() {
   178  			if path == dir {
   179  				return nil
   180  			}
   181  			_, n := filepath.Split(path)
   182  			switch n {
   183  			case "bench", "dwarf", "codegen":
   184  				return filepath.SkipDir
   185  			default:
   186  				if strings.Contains(n, ".dir") {
   187  					return filepath.SkipDir
   188  				}
   189  			}
   190  			return nil
   191  		}
   192  		if filepath.Ext(path) != ".go" {
   193  			return nil
   194  		}
   195  		data, err := ioutil.ReadFile(path)
   196  		if err != nil {
   197  			fmt.Printf("read %v error: %v\n", path, err)
   198  			return nil
   199  		}
   200  		lines := strings.Split(string(data), "\n")
   201  		if len(lines) > 0 {
   202  			line := strings.TrimSpace(lines[0])
   203  			if line == "// run" {
   204  				rf := runfile{filePath: path}
   205  				if s, err := os.Stat(path[:len(path)-3] + ".out"); err == nil && !s.IsDir() {
   206  					rf.checkOut = true
   207  				}
   208  				run = append(run, rf)
   209  			} else if line == "// runoutput" {
   210  				runoutput = append(runoutput, path)
   211  			}
   212  		}
   213  		return nil
   214  	})
   215  	return
   216  }
   217  
   218  func execRunoutput(input string) (string, error) {
   219  	cmd := exec.Command(goCmd, "run", input)
   220  	data, err := cmd.CombinedOutput()
   221  	if err != nil {
   222  		return "", err
   223  	}
   224  	fileName := filepath.Join(os.TempDir(), "tmp.go")
   225  	err = ioutil.WriteFile(fileName, data, 0666)
   226  	if err != nil {
   227  		return "", err
   228  	}
   229  	return fileName, nil
   230  }
   231  
   232  func main() {
   233  	dir, runs, runoutput := getGorootTestRuns()
   234  	var failures []string
   235  	start := time.Now()
   236  	for _, input := range runs {
   237  		f := input.filePath[len(dir)+1:]
   238  		if info, ok := gorootTestSkips[f]; ok {
   239  			fmt.Println("Skip:", input.filePath, info)
   240  			continue
   241  		}
   242  		if !runCommand(input.filePath, input.checkOut) {
   243  			failures = append(failures, input.filePath)
   244  		}
   245  	}
   246  	for _, input := range runoutput {
   247  		f := input[len(dir)+1:]
   248  		if info, ok := gorootTestSkips[f]; ok {
   249  			fmt.Println("Skip:", input, info)
   250  			continue
   251  		}
   252  		fmt.Println("runoutput:", input)
   253  		file, err := execRunoutput(input)
   254  		if err != nil {
   255  			fmt.Printf("go run %v error, %v\n", input, err)
   256  			continue
   257  		}
   258  		if !runCommand(file, false) {
   259  			failures = append(failures, input)
   260  		}
   261  	}
   262  	printFailures(failures)
   263  	fmt.Printf("time: %.3fs\n", time.Since(start).Seconds())
   264  	if failures != nil {
   265  		os.Exit(2)
   266  	}
   267  }