github.com/goplus/igop@v0.25.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", "go1.21", "go1.22":
    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  		if ver == "go1.21" || ver == "go1.22" {
    90  			gorootTestSkips["fixedbugs/issue19658.go"] = "skip command"
    91  		}
    92  		if ver == "go1.22" {
    93  			gorootTestSkips["fixedbugs/bug369.go"] = "skip command"
    94  			gorootTestSkips["fixedbugs/issue10607.go"] = "skip command"
    95  			gorootTestSkips["fixedbugs/issue21317.go"] = "skip command"
    96  			gorootTestSkips["fixedbugs/issue38093.go"] = "skip js"
    97  			gorootTestSkips["fixedbugs/issue64565.go"] = "skip command"
    98  			gorootTestSkips["fixedbugs/issue9355.go"] = "skip command"
    99  			gorootTestSkips["linkmain_run.go"] = "skip link"
   100  			gorootTestSkips["linkobj.go"] = "skip link"
   101  			gorootTestSkips["linkx_run.go"] = "skip link"
   102  			gorootTestSkips["chanlinear.go"] = "skip -gc-exp"
   103  		}
   104  	case "go1.16":
   105  		gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
   106  	case "go1.15":
   107  		gorootTestSkips["fixedbugs/issue15039.go"] = "BUG, uint64 -> string"
   108  		gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
   109  		gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
   110  	case "go1.14":
   111  		gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
   112  		gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
   113  	}
   114  
   115  	if runtime.GOOS == "windows" {
   116  		gorootTestSkips["env.go"] = "skip GOARCH"
   117  		gorootTestSkips["fixedbugs/issue15002.go"] = "skip windows"
   118  		gorootTestSkips["fixedbugs/issue5493.go"] = "skip windows"
   119  		gorootTestSkips["fixedbugs/issue5963.go"] = "skip windows"
   120  		if ver == "go1.22" {
   121  			gorootTestSkips["recover4.go"] = "skip windows"
   122  			gorootTestSkips["sigchld.go"] = "skip windows"
   123  		}
   124  
   125  		skips := make(map[string]string)
   126  		for k, v := range gorootTestSkips {
   127  			skips[filepath.FromSlash(k)] = v
   128  		}
   129  		gorootTestSkips = skips
   130  	} else if runtime.GOOS == "darwin" {
   131  		gorootTestSkips["locklinear.go"] = "skip github"
   132  		gorootTestSkips["env.go"] = "skip github"
   133  	}
   134  }
   135  
   136  var (
   137  	goCmd    string
   138  	gossaCmd string
   139  )
   140  
   141  func init() {
   142  	var err error
   143  	gossaCmd, err = exec.LookPath("igop")
   144  	if err != nil {
   145  		panic(fmt.Sprintf("not found igop: %v", err))
   146  	}
   147  	goCmd, err = exec.LookPath("go")
   148  	if err != nil {
   149  		panic(fmt.Sprintf("not found go: %v", err))
   150  	}
   151  }
   152  
   153  func runCommand(input string, chkout bool) bool {
   154  	fmt.Println("Input:", input)
   155  	start := time.Now()
   156  	cmd := exec.Command(gossaCmd, "run", "-exp-gc", input)
   157  	data, err := cmd.CombinedOutput()
   158  	if len(data) > 0 {
   159  		fmt.Println(string(data))
   160  	}
   161  	if chkout {
   162  		if chk, e := ioutil.ReadFile(input[:len(input)-3] + ".out"); e == nil {
   163  			if bytes.Compare(data, chk) != 0 {
   164  				err = fmt.Errorf("-- output check error --\n%v", string(chk))
   165  			}
   166  		}
   167  	}
   168  
   169  	sec := time.Since(start).Seconds()
   170  	if err != nil || bytes.Contains(data, []byte("BUG")) {
   171  		fmt.Println(err)
   172  		fmt.Printf("FAIL %0.3fs\n", sec)
   173  		return false
   174  	}
   175  	fmt.Printf("PASS %0.3fs\n", sec)
   176  	return true
   177  }
   178  
   179  func printFailures(failures []string) {
   180  	if failures != nil {
   181  		fmt.Println("The following tests failed:")
   182  		for _, f := range failures {
   183  			fmt.Printf("\t%s\n", f)
   184  		}
   185  	}
   186  }
   187  
   188  type runfile struct {
   189  	filePath string // go source file path
   190  	checkOut bool   // check output file.out
   191  }
   192  
   193  // $GOROOT/test/*.go runs
   194  func getGorootTestRuns() (dir string, run []runfile, runoutput []string) {
   195  	dir = filepath.Join(build.Default.GOROOT, "test")
   196  	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
   197  		if info.IsDir() {
   198  			if path == dir {
   199  				return nil
   200  			}
   201  			_, n := filepath.Split(path)
   202  			switch n {
   203  			case "bench", "dwarf", "codegen":
   204  				return filepath.SkipDir
   205  			case "typeparam":
   206  				ver := runtime.Version()[:6]
   207  				switch ver {
   208  				case "go1.18", "go1.19", "go1.20":
   209  					return nil
   210  				default:
   211  					return filepath.SkipDir
   212  				}
   213  			default:
   214  				if strings.Contains(n, ".dir") {
   215  					return filepath.SkipDir
   216  				}
   217  			}
   218  			return nil
   219  		}
   220  		if filepath.Ext(path) != ".go" {
   221  			return nil
   222  		}
   223  		data, err := ioutil.ReadFile(path)
   224  		if err != nil {
   225  			fmt.Printf("read %v error: %v\n", path, err)
   226  			return nil
   227  		}
   228  		lines := strings.Split(string(data), "\n")
   229  		if len(lines) > 0 {
   230  			line := strings.TrimSpace(lines[0])
   231  			if line == "// run" || line == "// run -gcflags=-G=3" {
   232  				rf := runfile{filePath: path}
   233  				if s, err := os.Stat(path[:len(path)-3] + ".out"); err == nil && !s.IsDir() {
   234  					rf.checkOut = true
   235  				}
   236  				run = append(run, rf)
   237  			} else if line == "// runoutput" {
   238  				runoutput = append(runoutput, path)
   239  			}
   240  		}
   241  		return nil
   242  	})
   243  	return
   244  }
   245  
   246  func execRunoutput(input string) (string, error) {
   247  	cmd := exec.Command(goCmd, "run", input)
   248  	data, err := cmd.CombinedOutput()
   249  	if err != nil {
   250  		return "", err
   251  	}
   252  	fileName := filepath.Join(os.TempDir(), "tmp.go")
   253  	err = ioutil.WriteFile(fileName, data, 0666)
   254  	if err != nil {
   255  		return "", err
   256  	}
   257  	return fileName, nil
   258  }
   259  
   260  func main() {
   261  	dir, runs, runoutput := getGorootTestRuns()
   262  	var failures []string
   263  	start := time.Now()
   264  	for _, input := range runs {
   265  		f := input.filePath[len(dir)+1:]
   266  		if info, ok := gorootTestSkips[f]; ok {
   267  			fmt.Println("Skip:", input.filePath, info)
   268  			continue
   269  		}
   270  		if !runCommand(input.filePath, input.checkOut) {
   271  			failures = append(failures, input.filePath)
   272  		}
   273  	}
   274  	for _, input := range runoutput {
   275  		f := input[len(dir)+1:]
   276  		if info, ok := gorootTestSkips[f]; ok {
   277  			fmt.Println("Skip:", input, info)
   278  			continue
   279  		}
   280  		fmt.Println("runoutput:", input)
   281  		file, err := execRunoutput(input)
   282  		if err != nil {
   283  			fmt.Printf("go run %v error, %v\n", input, err)
   284  			continue
   285  		}
   286  		if !runCommand(file, false) {
   287  			failures = append(failures, input)
   288  		}
   289  	}
   290  	printFailures(failures)
   291  	fmt.Printf("time: %.3fs\n", time.Since(start).Seconds())
   292  	if failures != nil {
   293  		os.Exit(2)
   294  	}
   295  }