libgo: update to final Go1.14 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/221158
This commit is contained in:
parent
051b9873e7
commit
c5decc83e4
|
@ -1,4 +1,4 @@
|
|||
658fe4f48374167bf8688e8dbd5f85eee155749e
|
||||
5fc21bb0d91d916940c21e6d4a3e10ad3f45343d
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
a068054af141c01df5a4519844f4b77273605f4e
|
||||
20a838ab94178c55bc4dc23ddc332fce8545a493
|
||||
|
||||
The first line of this file holds the git revision number of the
|
||||
last merge done from the master library sources.
|
||||
|
|
|
@ -1 +1 @@
|
|||
go1.14rc1
|
||||
go1.14
|
||||
|
|
|
@ -7,7 +7,6 @@ package modcmd
|
|||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
)
|
||||
|
||||
var CmdMod = &base.Command{
|
||||
|
@ -32,7 +31,3 @@ See 'go help modules' for an overview of module functionality.
|
|||
cmdWhy,
|
||||
},
|
||||
}
|
||||
|
||||
func addModFlags(cmd *base.Command) {
|
||||
cmd.Flag.StringVar(&cfg.ModFile, "modfile", "", "")
|
||||
}
|
||||
|
|
|
@ -184,9 +184,10 @@ func Import(path string) (m module.Version, dir string, err error) {
|
|||
if !pathIsStd {
|
||||
if cfg.BuildModReason == "" {
|
||||
queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod)
|
||||
}
|
||||
} else {
|
||||
queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason)
|
||||
}
|
||||
}
|
||||
return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: queryErr}
|
||||
}
|
||||
if modRoot == "" && !allowMissingModuleImports {
|
||||
|
|
|
@ -51,7 +51,9 @@ func runVet(cmd *base.Command, args []string) {
|
|||
|
||||
work.BuildInit()
|
||||
work.VetFlags = vetFlags
|
||||
if len(vetFlags) > 0 {
|
||||
work.VetExplicit = true
|
||||
}
|
||||
if vetTool != "" {
|
||||
var err error
|
||||
work.VetTool, err = filepath.Abs(vetTool)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package web defines minimal helper routines for accessing HTTP/HTTPS
|
||||
// resources without requiring external dependenicies on the net package.
|
||||
// resources without requiring external dependencies on the net package.
|
||||
//
|
||||
// If the cmd_go_bootstrap build tag is present, web avoids the use of the net
|
||||
// package and returns errors for all network operations.
|
||||
|
|
|
@ -2,49 +2,67 @@
|
|||
|
||||
# go/build's Import should find modules by invoking the go command
|
||||
|
||||
go build -o $WORK/testimport.exe ./testimport
|
||||
go build -o $WORK ./testimport ./testfindonly
|
||||
|
||||
# GO111MODULE=off
|
||||
env GO111MODULE=off
|
||||
! exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
|
||||
! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
|
||||
|
||||
# GO111MODULE=auto in GOPATH/src
|
||||
env GO111MODULE=auto
|
||||
exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
|
||||
exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
|
||||
|
||||
# GO111MODULE=auto outside GOPATH/src
|
||||
cd $GOPATH/other
|
||||
env GO111MODULE=auto
|
||||
exec $WORK/testimport.exe other/x/y/z/w .
|
||||
exec $WORK/testimport$GOEXE other/x/y/z/w .
|
||||
stdout w2.go
|
||||
|
||||
! exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
|
||||
! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
|
||||
stderr 'cannot find module providing package gobuild.example.com/x/y/z/w'
|
||||
|
||||
cd z
|
||||
exec $WORK/testimport.exe other/x/y/z/w .
|
||||
exec $WORK/testimport$GOEXE other/x/y/z/w .
|
||||
stdout w2.go
|
||||
|
||||
# GO111MODULE=on outside GOPATH/src
|
||||
env GO111MODULE=
|
||||
exec $WORK/testimport.exe other/x/y/z/w .
|
||||
exec $WORK/testimport$GOEXE other/x/y/z/w .
|
||||
stdout w2.go
|
||||
env GO111MODULE=on
|
||||
exec $WORK/testimport.exe other/x/y/z/w .
|
||||
exec $WORK/testimport$GOEXE other/x/y/z/w .
|
||||
stdout w2.go
|
||||
|
||||
# GO111MODULE=on in GOPATH/src
|
||||
cd $GOPATH/src
|
||||
env GO111MODULE=
|
||||
exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
|
||||
exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
|
||||
stdout w1.go
|
||||
env GO111MODULE=on
|
||||
exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
|
||||
exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
|
||||
stdout w1.go
|
||||
cd w
|
||||
exec $WORK/testimport.exe gobuild.example.com/x/y/z/w ..
|
||||
exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w ..
|
||||
stdout w1.go
|
||||
|
||||
# go/build's Import in FindOnly mode should find directories by invoking the go command
|
||||
#
|
||||
# Calling build.Import in build.FindOnly mode on an import path of a Go package
|
||||
# that produces errors when loading (e.g., due to build constraints not matching
|
||||
# the current build context) should return the package directory and nil error.
|
||||
|
||||
# Issue 31603: Import with non-empty srcDir should work.
|
||||
env GO111MODULE=on
|
||||
exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i $WORK
|
||||
! stdout 'build constraints'
|
||||
stdout '^dir=\$WORK.+i err=<nil>$'
|
||||
|
||||
# Issue 37153: Import with empty srcDir should work.
|
||||
env GO111MODULE=on
|
||||
exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i ''
|
||||
! stdout 'build constraints'
|
||||
stdout '^dir=\$WORK.+i err=<nil>$'
|
||||
|
||||
-- go.mod --
|
||||
module gobuild.example.com/x/y/z
|
||||
|
||||
|
@ -54,6 +72,11 @@ package z
|
|||
-- w/w1.go --
|
||||
package w
|
||||
|
||||
-- i/i.go --
|
||||
// +build i
|
||||
|
||||
package i
|
||||
|
||||
-- testimport/x.go --
|
||||
package main
|
||||
|
||||
|
@ -89,6 +112,20 @@ func main() {
|
|||
fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " "))
|
||||
}
|
||||
|
||||
-- testfindonly/x.go --
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/build"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
p, err := build.Import(os.Args[1], os.Args[2], build.FindOnly)
|
||||
fmt.Printf("dir=%s err=%v\n", p.Dir, err)
|
||||
}
|
||||
|
||||
-- $GOPATH/other/go.mod --
|
||||
module other/x/y
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ go mod edit -fmt
|
|||
cp go.mod go.mod.empty
|
||||
! go list all
|
||||
stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly'
|
||||
! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one.
|
||||
cmp go.mod go.mod.empty
|
||||
|
||||
# -mod=readonly should be set implicitly if the go.mod file is read-only
|
||||
|
|
|
@ -9,6 +9,17 @@ go vet -n -unreachable=false encoding/binary
|
|||
stderr '-unreachable=false'
|
||||
! stderr '-unsafeptr=false'
|
||||
|
||||
# Issue 37030: "go vet <std package>" without other flags should disable the
|
||||
# unsafeptr check by default.
|
||||
go vet -n encoding/binary
|
||||
stderr '-unsafeptr=false'
|
||||
! stderr '-unreachable=false'
|
||||
|
||||
# However, it should be enabled if requested explicitly.
|
||||
go vet -n -unsafeptr encoding/binary
|
||||
stderr '-unsafeptr'
|
||||
! stderr '-unsafeptr=false'
|
||||
|
||||
[short] stop
|
||||
env GOCACHE=$WORK/gocache
|
||||
env GOTMPDIR=$WORK/tmp
|
||||
|
|
|
@ -86,7 +86,8 @@ func NewGCM(cipher Block) (AEAD, error) {
|
|||
}
|
||||
|
||||
// NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois
|
||||
// Counter Mode, which accepts nonces of the given length.
|
||||
// Counter Mode, which accepts nonces of the given length. The length must not
|
||||
// be zero.
|
||||
//
|
||||
// Only use this function if you require compatibility with an existing
|
||||
// cryptosystem that uses non-standard nonce lengths. All other users should use
|
||||
|
@ -112,6 +113,10 @@ func newGCMWithNonceAndTagSize(cipher Block, nonceSize, tagSize int) (AEAD, erro
|
|||
return nil, errors.New("cipher: incorrect tag size given to GCM")
|
||||
}
|
||||
|
||||
if nonceSize <= 0 {
|
||||
return nil, errors.New("cipher: the nonce can't have zero length, or the security of the key will be immediately compromised")
|
||||
}
|
||||
|
||||
if cipher, ok := cipher.(gcmAble); ok {
|
||||
return cipher.NewGCM(nonceSize, tagSize)
|
||||
}
|
||||
|
|
|
@ -217,6 +217,13 @@ var aesGCMTests = []struct {
|
|||
"2b9680b886b3efb7c6354b38c63b5373",
|
||||
"e2b7e5ed5ff27fc8664148f5a628a46dcbf2015184fffb82f2651c36",
|
||||
},
|
||||
{
|
||||
"11754cd72aec309bf52f7687212e8957",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"250327c674aaf477aef2675748cf6971",
|
||||
},
|
||||
}
|
||||
|
||||
func TestAESGCM(t *testing.T) {
|
||||
|
@ -234,14 +241,22 @@ func TestAESGCM(t *testing.T) {
|
|||
|
||||
var aesgcm cipher.AEAD
|
||||
switch {
|
||||
// Handle non-standard nonce sizes
|
||||
// Handle non-standard tag sizes
|
||||
case tagSize != 16:
|
||||
aesgcm, err = cipher.NewGCMWithTagSize(aes, tagSize)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Handle non-standard tag sizes
|
||||
// Handle 0 nonce size (expect error and continue)
|
||||
case len(nonce) == 0:
|
||||
aesgcm, err = cipher.NewGCMWithNonceSize(aes, 0)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for zero nonce size")
|
||||
}
|
||||
continue
|
||||
|
||||
// Handle non-standard nonce sizes
|
||||
case len(nonce) != 12:
|
||||
aesgcm, err = cipher.NewGCMWithNonceSize(aes, len(nonce))
|
||||
if err != nil {
|
||||
|
|
|
@ -372,7 +372,12 @@ func initP521() {
|
|||
p521.BitSize = 521
|
||||
}
|
||||
|
||||
// P256 returns a Curve which implements P-256 (see FIPS 186-3, section D.2.3)
|
||||
// P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3),
|
||||
// also known as secp256r1 or prime256v1. The CurveParams.Name of this Curve is
|
||||
// "P-256".
|
||||
//
|
||||
// Multiple invocations of this function will return the same value, so it can
|
||||
// be used for equality checks and switch statements.
|
||||
//
|
||||
// The cryptographic operations are implemented using constant-time algorithms.
|
||||
func P256() Curve {
|
||||
|
@ -380,7 +385,11 @@ func P256() Curve {
|
|||
return p256
|
||||
}
|
||||
|
||||
// P384 returns a Curve which implements P-384 (see FIPS 186-3, section D.2.4)
|
||||
// P384 returns a Curve which implements NIST P-384 (FIPS 186-3, section D.2.4),
|
||||
// also known as secp384r1. The CurveParams.Name of this Curve is "P-384".
|
||||
//
|
||||
// Multiple invocations of this function will return the same value, so it can
|
||||
// be used for equality checks and switch statements.
|
||||
//
|
||||
// The cryptographic operations do not use constant-time algorithms.
|
||||
func P384() Curve {
|
||||
|
@ -388,7 +397,11 @@ func P384() Curve {
|
|||
return p384
|
||||
}
|
||||
|
||||
// P521 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5)
|
||||
// P521 returns a Curve which implements NIST P-521 (FIPS 186-3, section D.2.5),
|
||||
// also known as secp521r1. The CurveParams.Name of this Curve is "P-521".
|
||||
//
|
||||
// Multiple invocations of this function will return the same value, so it can
|
||||
// be used for equality checks and switch statements.
|
||||
//
|
||||
// The cryptographic operations do not use constant-time algorithms.
|
||||
func P521() Curve {
|
||||
|
|
|
@ -79,7 +79,7 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// MarshalPKCS8PrivateKey converts an RSA private key to PKCS#8, ASN.1 DER form.
|
||||
// MarshalPKCS8PrivateKey converts a private key to PKCS#8, ASN.1 DER form.
|
||||
//
|
||||
// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
|
||||
// and ed25519.PrivateKey. Unsupported key types result in an error.
|
||||
|
|
|
@ -1017,8 +1017,6 @@ var errNoModules = errors.New("not using modules")
|
|||
// Then we reinvoke it for every dependency. But this is still better than not working at all.
|
||||
// See golang.org/issue/26504.
|
||||
func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) error {
|
||||
const debugImportGo = false
|
||||
|
||||
// To invoke the go command,
|
||||
// we must not being doing special things like AllowBinary or IgnoreVendor,
|
||||
// and all the file system callbacks must be nil (we're meant to use the local file system).
|
||||
|
@ -1137,15 +1135,15 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode)
|
|||
}
|
||||
dir := f[0]
|
||||
errStr := strings.TrimSpace(f[4])
|
||||
if errStr != "" && p.Dir == "" {
|
||||
// If 'go list' could not locate the package, return the same error that
|
||||
// 'go list' reported.
|
||||
// If 'go list' did locate the package (p.Dir is not empty), ignore the
|
||||
// error. It was probably related to loading source files, and we'll
|
||||
// encounter it ourselves shortly.
|
||||
if errStr != "" && dir == "" {
|
||||
// If 'go list' could not locate the package (dir is empty),
|
||||
// return the same error that 'go list' reported.
|
||||
return errors.New(errStr)
|
||||
}
|
||||
|
||||
// If 'go list' did locate the package, ignore the error.
|
||||
// It was probably related to loading source files, and we'll
|
||||
// encounter it ourselves shortly if the FindOnly flag isn't set.
|
||||
p.Dir = dir
|
||||
p.ImportPath = f[1]
|
||||
p.Root = f[2]
|
||||
|
|
|
@ -138,9 +138,12 @@ func New(pkg *ast.Package, importPath string, mode Mode) *Package {
|
|||
// NewFromFiles computes documentation for a package.
|
||||
//
|
||||
// The package is specified by a list of *ast.Files and corresponding
|
||||
// file set, which must not be nil. NewFromFiles does not skip files
|
||||
// based on build constraints, so it is the caller's responsibility to
|
||||
// provide only the files that are matched by the build context.
|
||||
// file set, which must not be nil.
|
||||
// NewFromFiles uses all provided files when computing documentation,
|
||||
// so it is the caller's responsibility to provide only the files that
|
||||
// match the desired build context. "go/build".Context.MatchFile can
|
||||
// be used for determining whether a file matches a build context with
|
||||
// the desired GOOS and GOARCH values, and other build constraints.
|
||||
// The import path of the package is specified by importPath.
|
||||
//
|
||||
// Examples found in _test.go files are associated with the corresponding
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
// Package maphash provides hash functions on byte sequences.
|
||||
// These hash functions are intended to be used to implement hash tables or
|
||||
// other data structures that need to map arbitrary strings or byte
|
||||
// sequences to a uniform distribution of integers.
|
||||
// sequences to a uniform distribution on unsigned 64-bit integers.
|
||||
//
|
||||
// The hash functions are collision-resistant but not cryptographically secure.
|
||||
// (See crypto/sha256 and crypto/sha512 for cryptographic use.)
|
||||
//
|
||||
// The hash value of a given byte sequence is consistent within a
|
||||
// single process, but will be different in different processes.
|
||||
package maphash
|
||||
|
||||
import "unsafe"
|
||||
|
@ -66,7 +69,7 @@ type Hash struct {
|
|||
// which does call h.initSeed.)
|
||||
func (h *Hash) initSeed() {
|
||||
if h.seed.s == 0 {
|
||||
h.SetSeed(MakeSeed())
|
||||
h.setSeed(MakeSeed())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,12 +124,17 @@ func (h *Hash) Seed() Seed {
|
|||
// Two Hash objects with different seeds will very likely behave differently.
|
||||
// Any bytes added to h before this call will be discarded.
|
||||
func (h *Hash) SetSeed(seed Seed) {
|
||||
h.setSeed(seed)
|
||||
h.n = 0
|
||||
}
|
||||
|
||||
// setSeed sets seed without discarding accumulated data.
|
||||
func (h *Hash) setSeed(seed Seed) {
|
||||
if seed.s == 0 {
|
||||
panic("maphash: use of uninitialized Seed")
|
||||
}
|
||||
h.seed = seed
|
||||
h.state = seed
|
||||
h.n = 0
|
||||
}
|
||||
|
||||
// Reset discards all bytes added to h.
|
||||
|
|
|
@ -83,6 +83,29 @@ func TestHashHighBytes(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRepeat(t *testing.T) {
|
||||
h1 := new(Hash)
|
||||
h1.WriteString("testing")
|
||||
sum1 := h1.Sum64()
|
||||
|
||||
h1.Reset()
|
||||
h1.WriteString("testing")
|
||||
sum2 := h1.Sum64()
|
||||
|
||||
if sum1 != sum2 {
|
||||
t.Errorf("different sum after reseting: %#x != %#x", sum1, sum2)
|
||||
}
|
||||
|
||||
h2 := new(Hash)
|
||||
h2.SetSeed(h1.Seed())
|
||||
h2.WriteString("testing")
|
||||
sum3 := h2.Sum64()
|
||||
|
||||
if sum1 != sum3 {
|
||||
t.Errorf("different sum on the same seed: %#x != %#x", sum1, sum3)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure a Hash implements the hash.Hash and hash.Hash64 interfaces.
|
||||
var _ hash.Hash = &Hash{}
|
||||
var _ hash.Hash64 = &Hash{}
|
||||
|
|
|
@ -505,8 +505,8 @@ func (z *Int) Exp(x, y, m *Int) *Int {
|
|||
// GCD sets z to the greatest common divisor of a and b and returns z.
|
||||
// If x or y are not nil, GCD sets their value such that z = a*x + b*y.
|
||||
//
|
||||
// a and b may be positive, zero or negative.
|
||||
// Regardless of the signs of a and b, z is always >= 0.
|
||||
// a and b may be positive, zero or negative. (Before Go 1.14 both had
|
||||
// to be > 0.) Regardless of the signs of a and b, z is always >= 0.
|
||||
//
|
||||
// If a == b == 0, GCD sets z = x = y = 0.
|
||||
//
|
||||
|
|
|
@ -62,9 +62,10 @@
|
|||
// Allocating and freeing a large object uses the mheap
|
||||
// directly, bypassing the mcache and mcentral.
|
||||
//
|
||||
// Free object slots in an mspan are zeroed only if mspan.needzero is
|
||||
// false. If needzero is true, objects are zeroed as they are
|
||||
// allocated. There are various benefits to delaying zeroing this way:
|
||||
// If mspan.needzero is false, then free object slots in the mspan are
|
||||
// already zeroed. Otherwise if needzero is true, objects are zeroed as
|
||||
// they are allocated. There are various benefits to delaying zeroing
|
||||
// this way:
|
||||
//
|
||||
// 1. Stack frame allocation can avoid zeroing altogether.
|
||||
//
|
||||
|
|
|
@ -244,6 +244,15 @@ func genAMD64() {
|
|||
|
||||
// TODO: MXCSR register?
|
||||
|
||||
// Apparently, the signal handling code path in darwin kernel leaves
|
||||
// the upper bits of Y registers in a dirty state, which causes
|
||||
// many SSE operations (128-bit and narrower) become much slower.
|
||||
// Clear the upper bits to get to a clean state. See issue #37174.
|
||||
// It is safe here as Go code don't use the upper bits of Y registers.
|
||||
p("#ifdef GOOS_darwin")
|
||||
p("VZEROUPPER")
|
||||
p("#endif")
|
||||
|
||||
p("PUSHQ BP")
|
||||
p("MOVQ SP, BP")
|
||||
p("// Save flags before clobbering them")
|
||||
|
|
|
@ -13,16 +13,23 @@ var netpollWaiters uint32
|
|||
|
||||
var netpollStubLock mutex
|
||||
var netpollNote note
|
||||
var netpollBroken uint32
|
||||
|
||||
// netpollBroken, protected by netpollBrokenLock, avoids a double notewakeup.
|
||||
var netpollBrokenLock mutex
|
||||
var netpollBroken bool
|
||||
|
||||
func netpollGenericInit() {
|
||||
atomic.Store(&netpollInited, 1)
|
||||
}
|
||||
|
||||
func netpollBreak() {
|
||||
if atomic.Cas(&netpollBroken, 0, 1) {
|
||||
lock(&netpollBrokenLock)
|
||||
broken := netpollBroken
|
||||
netpollBroken = true
|
||||
if !broken {
|
||||
notewakeup(&netpollNote)
|
||||
}
|
||||
unlock(&netpollBrokenLock)
|
||||
}
|
||||
|
||||
// Polls for ready network connections.
|
||||
|
@ -34,8 +41,12 @@ func netpoll(delay int64) gList {
|
|||
// This lock ensures that only one goroutine tries to use
|
||||
// the note. It should normally be completely uncontended.
|
||||
lock(&netpollStubLock)
|
||||
|
||||
lock(&netpollBrokenLock)
|
||||
noteclear(&netpollNote)
|
||||
atomic.Store(&netpollBroken, 0)
|
||||
netpollBroken = false
|
||||
unlock(&netpollBrokenLock)
|
||||
|
||||
notetsleep(&netpollNote, delay)
|
||||
unlock(&netpollStubLock)
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ func (b *B) ReportAllocs() {
|
|||
func (b *B) runN(n int) {
|
||||
benchmarkLock.Lock()
|
||||
defer benchmarkLock.Unlock()
|
||||
defer b.runCleanup(normalPanic)
|
||||
// Try to get a comparable environment for each run
|
||||
// by clearing garbage from previous runs.
|
||||
runtime.GC()
|
||||
|
|
|
@ -613,6 +613,46 @@ func TestBRun(t *T) {
|
|||
t.Errorf("MemBytes was %v; want %v", got, 2*bufSize)
|
||||
}
|
||||
},
|
||||
}, {
|
||||
desc: "cleanup is called",
|
||||
f: func(b *B) {
|
||||
var calls, cleanups, innerCalls, innerCleanups int
|
||||
b.Run("", func(b *B) {
|
||||
calls++
|
||||
b.Cleanup(func() {
|
||||
cleanups++
|
||||
})
|
||||
b.Run("", func(b *B) {
|
||||
b.Cleanup(func() {
|
||||
innerCleanups++
|
||||
})
|
||||
innerCalls++
|
||||
})
|
||||
work(b)
|
||||
})
|
||||
if calls == 0 || calls != cleanups {
|
||||
t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
|
||||
}
|
||||
if innerCalls == 0 || innerCalls != innerCleanups {
|
||||
t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
|
||||
}
|
||||
},
|
||||
}, {
|
||||
desc: "cleanup is called on failure",
|
||||
failed: true,
|
||||
f: func(b *B) {
|
||||
var calls, cleanups int
|
||||
b.Run("", func(b *B) {
|
||||
calls++
|
||||
b.Cleanup(func() {
|
||||
cleanups++
|
||||
})
|
||||
b.Fatalf("failure")
|
||||
})
|
||||
if calls == 0 || calls != cleanups {
|
||||
t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
|
||||
}
|
||||
},
|
||||
}}
|
||||
for _, tc := range testCases {
|
||||
var ok bool
|
||||
|
|
|
@ -571,7 +571,6 @@ var _ TB = (*T)(nil)
|
|||
var _ TB = (*B)(nil)
|
||||
|
||||
// T is a type passed to Test functions to manage test state and support formatted test logs.
|
||||
// Logs are accumulated during execution and dumped to standard output when done.
|
||||
//
|
||||
// A test ends when its Test function returns or calls any of the methods
|
||||
// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods, as well as
|
||||
|
|
Loading…
Reference in New Issue