mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Deduplicate identical typecheck errors between platforms.
This commit is contained in:
parent
da440386d6
commit
137268d332
@ -24,6 +24,7 @@ import (
|
|||||||
"go/build"
|
"go/build"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -60,6 +61,8 @@ var (
|
|||||||
"linux/arm64", "linux/ppc64le",
|
"linux/arm64", "linux/ppc64le",
|
||||||
"linux/s390x", "darwin/386",
|
"linux/s390x", "darwin/386",
|
||||||
}
|
}
|
||||||
|
darwinPlatString = "darwin/386,darwin/amd64"
|
||||||
|
windowsPlatString = "windows/386,windows/amd64"
|
||||||
)
|
)
|
||||||
|
|
||||||
type analyzer struct {
|
type analyzer struct {
|
||||||
@ -69,6 +72,7 @@ type analyzer struct {
|
|||||||
failed bool
|
failed bool
|
||||||
platform string
|
platform string
|
||||||
donePaths map[string]interface{}
|
donePaths map[string]interface{}
|
||||||
|
errors []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAnalyzer(platform string) *analyzer {
|
func newAnalyzer(platform string) *analyzer {
|
||||||
@ -120,11 +124,19 @@ func (a *analyzer) handleError(err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO(rmmh): dedup errors across platforms?
|
a.errors = append(a.errors, err.Error())
|
||||||
fmt.Fprintf(os.Stderr, "%sERROR(%s) %s\n", logPrefix, a.platform, err)
|
if *serial {
|
||||||
|
fmt.Fprintf(os.Stderr, "%sERROR(%s) %s\n", logPrefix, a.platform, err)
|
||||||
|
}
|
||||||
a.failed = true
|
a.failed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *analyzer) dumpAndResetErrors() []string {
|
||||||
|
es := a.errors
|
||||||
|
a.errors = nil
|
||||||
|
return es
|
||||||
|
}
|
||||||
|
|
||||||
// collect extracts test metadata from a file.
|
// collect extracts test metadata from a file.
|
||||||
func (a *analyzer) collect(dir string) {
|
func (a *analyzer) collect(dir string) {
|
||||||
if _, ok := a.donePaths[dir]; ok {
|
if _, ok := a.donePaths[dir]; ok {
|
||||||
@ -262,6 +274,51 @@ func (c *collector) handlePath(path string, info os.FileInfo, err error) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type analyzerResult struct {
|
||||||
|
platform string
|
||||||
|
dir string
|
||||||
|
errors []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func dedupeErrors(out io.Writer, results chan analyzerResult, nDirs, nPlatforms int) {
|
||||||
|
pkgRes := make(map[string][]analyzerResult)
|
||||||
|
for done := 0; done < nDirs; {
|
||||||
|
res := <-results
|
||||||
|
pkgRes[res.dir] = append(pkgRes[res.dir], res)
|
||||||
|
if len(pkgRes[res.dir]) != nPlatforms {
|
||||||
|
continue // expect more results for dir
|
||||||
|
}
|
||||||
|
done++
|
||||||
|
// Collect list of platforms for each error
|
||||||
|
errPlats := map[string][]string{}
|
||||||
|
for _, res := range pkgRes[res.dir] {
|
||||||
|
for _, err := range res.errors {
|
||||||
|
errPlats[err] = append(errPlats[err], res.platform)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Print each error (in the same order!) once.
|
||||||
|
for _, res := range pkgRes[res.dir] {
|
||||||
|
for _, err := range res.errors {
|
||||||
|
if errPlats[err] == nil {
|
||||||
|
continue // already printed
|
||||||
|
}
|
||||||
|
sort.Strings(errPlats[err])
|
||||||
|
plats := strings.Join(errPlats[err], ",")
|
||||||
|
if len(errPlats[err]) == len(crossPlatforms) {
|
||||||
|
plats = "all"
|
||||||
|
} else if plats == darwinPlatString {
|
||||||
|
plats = "darwin"
|
||||||
|
} else if plats == windowsPlatString {
|
||||||
|
plats = "windows"
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "%sERROR(%s) %s\n", logPrefix, plats, err)
|
||||||
|
delete(errPlats, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete(pkgRes, res.dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
args := flag.Args()
|
args := flag.Args()
|
||||||
@ -296,6 +353,15 @@ func main() {
|
|||||||
var processedDirs int64
|
var processedDirs int64
|
||||||
var currentWork int64 // (dir_index << 8) | platform_index
|
var currentWork int64 // (dir_index << 8) | platform_index
|
||||||
statuses := make([]int, len(ps))
|
statuses := make([]int, len(ps))
|
||||||
|
var results chan analyzerResult
|
||||||
|
if !*serial {
|
||||||
|
results = make(chan analyzerResult)
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
dedupeErrors(os.Stderr, results, len(c.dirs), len(ps))
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
for i, p := range ps {
|
for i, p := range ps {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
fn := func(i int, p string) {
|
fn := func(i int, p string) {
|
||||||
@ -305,6 +371,9 @@ func main() {
|
|||||||
a.collect(dir)
|
a.collect(dir)
|
||||||
atomic.AddInt64(&processedDirs, 1)
|
atomic.AddInt64(&processedDirs, 1)
|
||||||
atomic.StoreInt64(¤tWork, int64(n<<8|i))
|
atomic.StoreInt64(¤tWork, int64(n<<8|i))
|
||||||
|
if results != nil {
|
||||||
|
results <- analyzerResult{p, dir, a.dumpAndResetErrors()}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if a.failed {
|
if a.failed {
|
||||||
statuses[i] = 1
|
statuses[i] = 1
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
@ -155,3 +156,38 @@ func TestHandlePath(t *testing.T) {
|
|||||||
t.Error("should skip vendor")
|
t.Error("should skip vendor")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDedupeErrors(t *testing.T) {
|
||||||
|
testcases := []struct {
|
||||||
|
nPlatforms int
|
||||||
|
results []analyzerResult
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{1, []analyzerResult{}, ""},
|
||||||
|
{1, []analyzerResult{{"linux/arm", "test", nil}}, ""},
|
||||||
|
{1, []analyzerResult{
|
||||||
|
{"linux/arm", "test", []string{"a"}}},
|
||||||
|
"ERROR(linux/arm) a\n"},
|
||||||
|
{3, []analyzerResult{
|
||||||
|
{"linux/arm", "test", []string{"a"}},
|
||||||
|
{"windows/386", "test", []string{"b"}},
|
||||||
|
{"windows/amd64", "test", []string{"b", "c"}}},
|
||||||
|
"ERROR(linux/arm) a\n" +
|
||||||
|
"ERROR(windows) b\n" +
|
||||||
|
"ERROR(windows/amd64) c\n"},
|
||||||
|
}
|
||||||
|
for _, tc := range testcases {
|
||||||
|
out := &bytes.Buffer{}
|
||||||
|
results := make(chan analyzerResult, len(tc.results))
|
||||||
|
for _, res := range tc.results {
|
||||||
|
results <- res
|
||||||
|
}
|
||||||
|
close(results)
|
||||||
|
dedupeErrors(out, results, len(tc.results)/tc.nPlatforms, tc.nPlatforms)
|
||||||
|
outString := out.String()
|
||||||
|
if outString != tc.expected {
|
||||||
|
t.Errorf("dedupeErrors(%v) = '%s', expected '%s'",
|
||||||
|
tc.results, outString, tc.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user