github.com/goplus/igop@v0.17.0/cmd/igoptest/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["nilptr.go"] = "skip drawin"
    31  	gorootTestSkips["heapsampling.go"] = "runtime.MemProfileRecord"
    32  	gorootTestSkips["makeslice.go"] = "TODO, panic info, allocation size out of range"
    33  	// gorootTestSkips["stackobj.go"] = "skip gc"
    34  	// gorootTestSkips["stackobj3.go"] = "skip gc"
    35  	gorootTestSkips["nilptr_aix.go"] = "skip"
    36  	// gorootTestSkips["init1.go"] = "skip gc"
    37  	gorootTestSkips["ken/divconst.go"] = "slow, 3.5s"
    38  	gorootTestSkips["ken/modconst.go"] = "slow, 3.3s"
    39  	gorootTestSkips["fixedbugs/issue24491b.go"] = "timeout"
    40  	gorootTestSkips["fixedbugs/issue16249.go"] = "slow, 4.5s"
    41  	gorootTestSkips["fixedbugs/issue13169.go"] = "slow, 5.9s"
    42  	gorootTestSkips["fixedbugs/issue11656.go"] = "ignore"
    43  	// gorootTestSkips["fixedbugs/issue15281.go"] = "runtime.ReadMemStats"
    44  	gorootTestSkips["fixedbugs/issue18149.go"] = "runtime.Caller macos //line not support c:/foo/bar.go:987"
    45  	gorootTestSkips["fixedbugs/issue22662.go"] = "runtime.Caller got $goroot/test/fixedbugs/foo.go:1; want foo.go:1"
    46  	// gorootTestSkips["fixedbugs/issue27518b.go"] = "BUG, runtime.SetFinalizer"
    47  	// gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
    48  	gorootTestSkips["fixedbugs/issue41239.go"] = "BUG, reflect.Append: different capacity on append"
    49  	// gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
    50  	gorootTestSkips["fixedbugs/issue45175.go"] = "BUG, ssa.Phi call order"
    51  	gorootTestSkips["fixedbugs/issue4618.go"] = "testing.AllocsPerRun"
    52  	gorootTestSkips["fixedbugs/issue4667.go"] = "testing.AllocsPerRun"
    53  	gorootTestSkips["fixedbugs/issue8606b.go"] = "BUG, optimization check"
    54  	gorootTestSkips["fixedbugs/issue30116u.go"] = "BUG, slice bound check"
    55  	gorootTestSkips["chan/select5.go"] = "bug, select case expr call order"
    56  
    57  	// fixedbugs/issue7740.go
    58  	// const ulp = (1.0 + (2.0 / 3.0)) - (5.0 / 3.0)
    59  	// Go 1.14 1.15 1.16 ulp = 1.4916681462400413e-154
    60  	// Go 1.17 1.18 ulp = 0
    61  
    62  	ver := runtime.Version()[:6]
    63  	switch ver {
    64  	case "go1.17", "go1.18", "go1.19", "go1.20":
    65  		// gorootTestSkips["fixedbugs/issue45045.go"] = "runtime.SetFinalizer"
    66  		// gorootTestSkips["fixedbugs/issue46725.go"] = "runtime.SetFinalizer"
    67  		gorootTestSkips["abi/fibish.go"] = "slow, 34s"
    68  		gorootTestSkips["abi/fibish_closure.go"] = "slow, 35s"
    69  		gorootTestSkips["abi/uglyfib.go"] = "5m48s"
    70  		// gorootTestSkips["fixedbugs/issue23017.go"] = "BUG" //fixed https://github.com/golang/go/issues/55086
    71  
    72  		gorootTestSkips["typeparam/chans.go"] = "runtime.SetFinalizer, maybe broken for go1.18 on linux workflows"
    73  		// gorootTestSkips["typeparam/issue376214.go"] = "build SSA package error: variadic parameter must be of unnamed slice type"
    74  		if ver != "go1.20" {
    75  			gorootTestSkips["typeparam/nested.go"] = "skip, run pass but output same as go1.20"
    76  		}
    77  		//go1.20
    78  		gorootTestSkips["fixedbugs/bug514.go"] = "skip cgo"
    79  		gorootTestSkips["fixedbugs/issue40954.go"] = "skip cgo"
    80  		gorootTestSkips["fixedbugs/issue42032.go"] = "skip cgo"
    81  		gorootTestSkips["fixedbugs/issue42076.go"] = "skip cgo"
    82  		gorootTestSkips["fixedbugs/issue46903.go"] = "skip cgo"
    83  		gorootTestSkips["fixedbugs/issue51733.go"] = "skip cgo"
    84  		// gorootTestSkips["fixedbugs/issue57823.go"] = "GC"
    85  		if ver == "go1.18" {
    86  			gorootTestSkips["typeparam/cons.go"] = "skip golang.org/x/tools v0.7.0 on go1.18"
    87  			gorootTestSkips["typeparam/list2.go"] = "skip golang.org/x/tools v0.7.0 on go1.18"
    88  		}
    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("igop")
   124  	if err != nil {
   125  		panic(fmt.Sprintf("not found igop: %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", "-exp-gc", 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  			case "typeparam":
   186  				ver := runtime.Version()[:6]
   187  				switch ver {
   188  				case "go1.18", "go1.19", "go1.20":
   189  					return nil
   190  				default:
   191  					return filepath.SkipDir
   192  				}
   193  			default:
   194  				if strings.Contains(n, ".dir") {
   195  					return filepath.SkipDir
   196  				}
   197  			}
   198  			return nil
   199  		}
   200  		if filepath.Ext(path) != ".go" {
   201  			return nil
   202  		}
   203  		data, err := ioutil.ReadFile(path)
   204  		if err != nil {
   205  			fmt.Printf("read %v error: %v\n", path, err)
   206  			return nil
   207  		}
   208  		lines := strings.Split(string(data), "\n")
   209  		if len(lines) > 0 {
   210  			line := strings.TrimSpace(lines[0])
   211  			if line == "// run" || line == "// run -gcflags=-G=3" {
   212  				rf := runfile{filePath: path}
   213  				if s, err := os.Stat(path[:len(path)-3] + ".out"); err == nil && !s.IsDir() {
   214  					rf.checkOut = true
   215  				}
   216  				run = append(run, rf)
   217  			} else if line == "// runoutput" {
   218  				runoutput = append(runoutput, path)
   219  			}
   220  		}
   221  		return nil
   222  	})
   223  	return
   224  }
   225  
   226  func execRunoutput(input string) (string, error) {
   227  	cmd := exec.Command(goCmd, "run", input)
   228  	data, err := cmd.CombinedOutput()
   229  	if err != nil {
   230  		return "", err
   231  	}
   232  	fileName := filepath.Join(os.TempDir(), "tmp.go")
   233  	err = ioutil.WriteFile(fileName, data, 0666)
   234  	if err != nil {
   235  		return "", err
   236  	}
   237  	return fileName, nil
   238  }
   239  
   240  func main() {
   241  	dir, runs, runoutput := getGorootTestRuns()
   242  	var failures []string
   243  	start := time.Now()
   244  	for _, input := range runs {
   245  		f := input.filePath[len(dir)+1:]
   246  		if info, ok := gorootTestSkips[f]; ok {
   247  			fmt.Println("Skip:", input.filePath, info)
   248  			continue
   249  		}
   250  		if !runCommand(input.filePath, input.checkOut) {
   251  			failures = append(failures, input.filePath)
   252  		}
   253  	}
   254  	for _, input := range runoutput {
   255  		f := input[len(dir)+1:]
   256  		if info, ok := gorootTestSkips[f]; ok {
   257  			fmt.Println("Skip:", input, info)
   258  			continue
   259  		}
   260  		fmt.Println("runoutput:", input)
   261  		file, err := execRunoutput(input)
   262  		if err != nil {
   263  			fmt.Printf("go run %v error, %v\n", input, err)
   264  			continue
   265  		}
   266  		if !runCommand(file, false) {
   267  			failures = append(failures, input)
   268  		}
   269  	}
   270  	printFailures(failures)
   271  	fmt.Printf("time: %.3fs\n", time.Since(start).Seconds())
   272  	if failures != nil {
   273  		os.Exit(2)
   274  	}
   275  }