From 14480f21a0d927bdb9fdcad7edbd934abe81767a Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Thu, 28 Apr 2016 14:12:43 -0400 Subject: [PATCH] cmd/guru: for determinism, sort referrers output in test Previously we were sorting only JSON objects, but we must do the same for plain output too to avoid sporadic failures. Tested 20 times. Change-Id: Ic60363b720c2afc91b57864bc93e298f83e85b99 Reviewed-on: https://go-review.googlesource.com/22555 Reviewed-by: Robert Griesemer --- cmd/guru/guru_test.go | 33 +++++++++------- cmd/guru/testdata/src/referrers/main.golden | 44 ++++++++++----------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/cmd/guru/guru_test.go b/cmd/guru/guru_test.go index b1cb335a..b4073d94 100644 --- a/cmd/guru/guru_test.go +++ b/cmd/guru/guru_test.go @@ -162,21 +162,20 @@ func doQuery(out io.Writer, q *query, json bool) { gopathAbs, _ := filepath.Abs(buildContext.GOPATH) - var outputMu sync.Mutex // guards out, jsons - var jsons []string - output := func(fset *token.FileSet, qr guru.QueryResult) { + var outputMu sync.Mutex // guards outputs + var outputs []string // JSON objects or lines of text + outputFn := func(fset *token.FileSet, qr guru.QueryResult) { outputMu.Lock() defer outputMu.Unlock() if json { jsonstr := string(qr.JSON(fset)) // Sanitize any absolute filenames that creep in. jsonstr = strings.Replace(jsonstr, gopathAbs, "$GOPATH", -1) - jsons = append(jsons, jsonstr) + outputs = append(outputs, jsonstr) } else { // suppress position information qr.PrintPlain(func(_ interface{}, format string, args ...interface{}) { - fmt.Fprintf(out, format, args...) - io.WriteString(out, "\n") + outputs = append(outputs, fmt.Sprintf(format, args...)) }) } } @@ -186,7 +185,7 @@ func doQuery(out io.Writer, q *query, json bool) { Build: &buildContext, Scope: []string{pkg}, Reflection: true, - Output: output, + Output: outputFn, } if err := guru.Run(q.verb, &query); err != nil { @@ -194,14 +193,18 @@ func doQuery(out io.Writer, q *query, json bool) { return } - if json { - if q.verb == "referrers" { - sort.Strings(jsons[1:]) // for determinism - } - for _, json := range jsons { - fmt.Fprintf(out, "%s\n", json) - } - } else { + // In a "referrers" query, references are sorted within each + // package but packages are visited in arbitrary order, + // so for determinism we sort them. Line 0 is a caption. + if q.verb == "referrers" { + sort.Strings(outputs[1:]) + } + + for _, output := range outputs { + fmt.Fprintf(out, "%s\n", output) + } + + if !json { io.WriteString(out, "\n") } } diff --git a/cmd/guru/testdata/src/referrers/main.golden b/cmd/guru/testdata/src/referrers/main.golden index b3da0376..9cac5040 100644 --- a/cmd/guru/testdata/src/referrers/main.golden +++ b/cmd/guru/testdata/src/referrers/main.golden @@ -9,42 +9,42 @@ references to type s struct{f int} -------- @referrers ref-package -------- references to package lib + _ = (lib.Type).Method // ref from external test package + _ = (lib.Type).Method // ref from internal test package + const c = lib.Const // @describe ref-const "Const" + lib.Func() // @describe ref-func "Func" + lib.Var++ // @describe ref-var "Var" + var _ lib.Const // @definition qualified-const "Const" + var _ lib.Func // @definition qualified-func "Func" + var _ lib.Nonesuch // @definition qualified-nomember "Nonesuch" + var _ lib.Outer // @describe lib-outer "Outer" + var _ lib.Type // @definition qualified-type "Type" + var _ lib.Type // @describe ref-pkg "lib" + var _ lib.Var // @definition qualified-var "Var" + var _ lib2.Type // @definition qualified-type-renaming "Type" + var t lib.Type // @describe ref-type "Type" var v lib.Type = lib.Const // @referrers ref-package "lib" var v lib.Type = lib.Const // @referrers ref-package "lib" var v lib.Type = lib.Const // @referrers ref-package "lib" var v lib.Type = lib.Const // @referrers ref-package "lib" var x lib.T // @definition lexical-pkgname "lib" - var _ lib.Type // @definition qualified-type "Type" - var _ lib.Func // @definition qualified-func "Func" - var _ lib.Var // @definition qualified-var "Var" - var _ lib.Const // @definition qualified-const "Const" - var _ lib2.Type // @definition qualified-type-renaming "Type" - var _ lib.Nonesuch // @definition qualified-nomember "Nonesuch" - var _ lib.Outer // @describe lib-outer "Outer" - const c = lib.Const // @describe ref-const "Const" - lib.Func() // @describe ref-func "Func" - lib.Var++ // @describe ref-var "Var" - var t lib.Type // @describe ref-type "Type" - var _ lib.Type // @describe ref-pkg "lib" - _ = (lib.Type).Method // ref from internal test package - _ = (lib.Type).Method // ref from external test package -------- @referrers ref-method -------- references to func (Type).Method(x *int) *int - _ = v.Method // @referrers ref-method "Method" - _ = v.Method - _ = v.Method // @referrers ref-method "Method" - _ = v.Method - p := t.Method(&a) // @describe ref-method "Method" - _ = (lib.Type).Method // ref from internal test package _ = (lib.Type).Method // ref from external test package + _ = (lib.Type).Method // ref from internal test package + _ = v.Method + _ = v.Method + _ = v.Method // @referrers ref-method "Method" + _ = v.Method // @referrers ref-method "Method" + p := t.Method(&a) // @describe ref-method "Method" -------- @referrers ref-local -------- references to var v lib.Type - _ = v.Method // @referrers ref-method "Method" _ = v.Method - v++ //@referrers ref-local "v" + _ = v.Method // @referrers ref-method "Method" v++ + v++ //@referrers ref-local "v" -------- @referrers ref-field -------- references to field f int