mirror of
https://github.com/golang/go
synced 2024-11-26 12:09:04 -07:00
[dev.typeparams] cmd/compile: add "toolstash -cmp"-like test of -d=unified
This CL adds a longtest test to make sure -d=unified=1 produces output identical to -d=unified=0. Change-Id: I2c5d38f67dbc8fecd8332a91ba7cae22225b090c Reviewed-on: https://go-review.googlesource.com/c/go/+/329429 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
e9c01f9804
commit
3f7a3133da
151
src/cmd/compile/internal/noder/unified_test.go
Normal file
151
src/cmd/compile/internal/noder/unified_test.go
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package noder_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
exec "internal/execabs"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
flagPkgs = flag.String("pkgs", "std", "list of packages to compare")
|
||||
flagAll = flag.Bool("all", false, "enable testing of all GOOS/GOARCH targets")
|
||||
flagParallel = flag.Bool("parallel", false, "test GOOS/GOARCH targets in parallel")
|
||||
)
|
||||
|
||||
// TestUnifiedCompare implements a test similar to running:
|
||||
//
|
||||
// $ go build -toolexec="toolstash -cmp" std
|
||||
//
|
||||
// The -pkgs flag controls the list of packages tested.
|
||||
//
|
||||
// By default, only the native GOOS/GOARCH target is enabled. The -all
|
||||
// flag enables testing of non-native targets. The -parallel flag
|
||||
// additionally enables testing of targets in parallel.
|
||||
//
|
||||
// Caution: Testing all targets is very resource intensive! On an IBM
|
||||
// P920 (dual Intel Xeon Gold 6154 CPUs; 36 cores, 192GB RAM), testing
|
||||
// all targets in parallel takes about 5 minutes. Using the 'go test'
|
||||
// command's -run flag for subtest matching is recommended for less
|
||||
// powerful machines.
|
||||
func TestUnifiedCompare(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode")
|
||||
}
|
||||
|
||||
targets, err := exec.Command("go", "tool", "dist", "list").Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, target := range strings.Fields(string(targets)) {
|
||||
t.Run(target, func(t *testing.T) {
|
||||
parts := strings.Split(target, "/")
|
||||
goos, goarch := parts[0], parts[1]
|
||||
|
||||
if !(*flagAll || goos == runtime.GOOS && goarch == runtime.GOARCH) {
|
||||
t.Skip("skipping non-native target (use -all to enable)")
|
||||
}
|
||||
if *flagParallel {
|
||||
t.Parallel()
|
||||
}
|
||||
|
||||
pkgs1 := loadPackages(t, goos, goarch, "-d=unified=0 -d=inlfuncswithclosures=0")
|
||||
pkgs2 := loadPackages(t, goos, goarch, "-d=unified=1 -d=inlfuncswithclosures=0")
|
||||
|
||||
if len(pkgs1) != len(pkgs2) {
|
||||
t.Fatalf("length mismatch: %v != %v", len(pkgs1), len(pkgs2))
|
||||
}
|
||||
|
||||
for i := range pkgs1 {
|
||||
pkg1 := pkgs1[i]
|
||||
pkg2 := pkgs2[i]
|
||||
|
||||
path := pkg1.ImportPath
|
||||
if path != pkg2.ImportPath {
|
||||
t.Fatalf("mismatched paths: %q != %q", path, pkg2.ImportPath)
|
||||
}
|
||||
|
||||
// Packages that don't have any source files (e.g., packages
|
||||
// unsafe, embed/internal/embedtest, and cmd/internal/moddeps).
|
||||
if pkg1.Export == "" && pkg2.Export == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if pkg1.BuildID == pkg2.BuildID {
|
||||
t.Errorf("package %q: build IDs unexpectedly matched", path)
|
||||
}
|
||||
|
||||
// Unlike toolstash -cmp, we're comparing the same compiler
|
||||
// binary against itself, just with different flags. So we
|
||||
// don't need to worry about skipping over mismatched version
|
||||
// strings, but we do need to account for differing build IDs.
|
||||
//
|
||||
// Fortunately, build IDs are cryptographic 256-bit hashes,
|
||||
// and cmd/go provides us with them up front. So we can just
|
||||
// use them as delimeters to split the files, and then check
|
||||
// that the substrings are all equal.
|
||||
file1 := strings.Split(readFile(t, pkg1.Export), pkg1.BuildID)
|
||||
file2 := strings.Split(readFile(t, pkg2.Export), pkg2.BuildID)
|
||||
if !reflect.DeepEqual(file1, file2) {
|
||||
t.Errorf("package %q: compile output differs", path)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type pkg struct {
|
||||
ImportPath string
|
||||
Export string
|
||||
BuildID string
|
||||
Incomplete bool
|
||||
}
|
||||
|
||||
func loadPackages(t *testing.T, goos, goarch, gcflags string) []pkg {
|
||||
args := []string{"list", "-e", "-export", "-json", "-gcflags=all=" + gcflags, "--"}
|
||||
args = append(args, strings.Fields(*flagPkgs)...)
|
||||
|
||||
cmd := exec.Command("go", args...)
|
||||
cmd.Env = append(os.Environ(), "GOOS="+goos, "GOARCH="+goarch)
|
||||
cmd.Stderr = os.Stderr
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var res []pkg
|
||||
for dec := json.NewDecoder(stdout); dec.More(); {
|
||||
var pkg pkg
|
||||
if err := dec.Decode(&pkg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if pkg.Incomplete {
|
||||
t.Fatalf("incomplete package: %q", pkg.ImportPath)
|
||||
}
|
||||
res = append(res, pkg)
|
||||
}
|
||||
if err := cmd.Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func readFile(t *testing.T, name string) string {
|
||||
buf, err := os.ReadFile(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return string(buf)
|
||||
}
|
Loading…
Reference in New Issue
Block a user