-cd6b6202dd1559b3ac63179b45f1833fcfbe7eca
+a4c18f063b6659079ca2848ca217a0587dabc001
The first line of this file holds the git revision number of the
last merge done from the master library sources.
}
}
+func TestTestRaceInstall(t *testing.T) {
+ if !canRace {
+ t.Skip("no race detector")
+ }
+
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+
+ tg.tempDir("pkg")
+ pkgdir := tg.path("pkg")
+ tg.run("install", "-race", "-pkgdir="+pkgdir, "std")
+ tg.run("test", "-race", "-pkgdir="+pkgdir, "-i", "-v", "empty/pkg")
+ if tg.getStderr() != "" {
+ t.Error("go test -i -race: rebuilds cached packages")
+ }
+}
+
func TestBuildDryRunWithCgo(t *testing.T) {
if !canCgo {
t.Skip("skipping because cgo not enabled")
if p.Name == "main" && goarch == "arm" {
importPaths = append(importPaths, "math")
}
- // In coverage atomic mode everything depends on sync/atomic.
- if testCoverMode == "atomic" && (!p.Standard || (p.ImportPath != "runtime/cgo" && p.ImportPath != "runtime/race" && p.ImportPath != "sync/atomic")) {
- importPaths = append(importPaths, "sync/atomic")
- }
}
// Runtime and its internal packages depend on runtime/internal/sys,
// Prepare build + run + print actions for all packages being tested.
for _, p := range pkgs {
+ // sync/atomic import is inserted by the cover tool. See #18486
+ if testCover && testCoverMode == "atomic" {
+ ensureImport(p, "sync/atomic")
+ }
buildTest, runTest, printTest, err := b.test(p)
if err != nil {
str := err.Error()
b.do(root)
}
+// ensures that package p imports the named package.
+func ensureImport(p *Package, pkg string) {
+ for _, d := range p.deps {
+ if d.Name == pkg {
+ return
+ }
+ }
+
+ a := loadPackage(pkg, &importStack{})
+ if a.Error != nil {
+ fatalf("load %s: %v", pkg, a.Error)
+ }
+ computeStale(a)
+
+ p.imports = append(p.imports, a)
+}
+
func contains(x []string, s string) bool {
for _, t := range x {
if t == s {
Certificates: c.Certificates,
NameToCertificate: c.NameToCertificate,
GetCertificate: c.GetCertificate,
+ GetClientCertificate: c.GetClientCertificate,
GetConfigForClient: c.GetConfigForClient,
VerifyPeerCertificate: c.VerifyPeerCertificate,
RootCAs: c.RootCAs,
"io"
"io/ioutil"
"math"
- "math/rand"
"net"
"os"
"reflect"
"strings"
"testing"
- "testing/quick"
"time"
)
}
}
-func TestClone(t *testing.T) {
+func TestCloneFuncFields(t *testing.T) {
+ const expectedCount = 5
+ called := 0
+
+ c1 := Config{
+ Time: func() time.Time {
+ called |= 1 << 0
+ return time.Time{}
+ },
+ GetCertificate: func(*ClientHelloInfo) (*Certificate, error) {
+ called |= 1 << 1
+ return nil, nil
+ },
+ GetClientCertificate: func(*CertificateRequestInfo) (*Certificate, error) {
+ called |= 1 << 2
+ return nil, nil
+ },
+ GetConfigForClient: func(*ClientHelloInfo) (*Config, error) {
+ called |= 1 << 3
+ return nil, nil
+ },
+ VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+ called |= 1 << 4
+ return nil
+ },
+ }
+
+ c2 := c1.Clone()
+
+ c2.Time()
+ c2.GetCertificate(nil)
+ c2.GetClientCertificate(nil)
+ c2.GetConfigForClient(nil)
+ c2.VerifyPeerCertificate(nil, nil)
+
+ if called != (1<<expectedCount)-1 {
+ t.Fatalf("expected %d calls but saw calls %b", expectedCount, called)
+ }
+}
+
+func TestCloneNonFuncFields(t *testing.T) {
var c1 Config
v := reflect.ValueOf(&c1).Elem()
- rnd := rand.New(rand.NewSource(time.Now().Unix()))
typ := v.Type()
for i := 0; i < typ.NumField(); i++ {
f := v.Field(i)
continue
}
- // testing/quick can't handle functions or interfaces.
- fn := typ.Field(i).Name
- switch fn {
+ // testing/quick can't handle functions or interfaces and so
+ // isn't used here.
+ switch fn := typ.Field(i).Name; fn {
case "Rand":
f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
- continue
case "Time", "GetCertificate", "GetConfigForClient", "VerifyPeerCertificate", "GetClientCertificate":
- // DeepEqual can't compare functions.
- continue
+ // DeepEqual can't compare functions. If you add a
+ // function field to this list, you must also change
+ // TestCloneFuncFields to ensure that the func field is
+ // cloned.
case "Certificates":
f.Set(reflect.ValueOf([]Certificate{
{Certificate: [][]byte{{'b'}}},
}))
- continue
case "NameToCertificate":
f.Set(reflect.ValueOf(map[string]*Certificate{"a": nil}))
- continue
case "RootCAs", "ClientCAs":
f.Set(reflect.ValueOf(x509.NewCertPool()))
- continue
case "ClientSessionCache":
f.Set(reflect.ValueOf(NewLRUClientSessionCache(10)))
- continue
case "KeyLogWriter":
f.Set(reflect.ValueOf(io.Writer(os.Stdout)))
- continue
-
- }
-
- q, ok := quick.Value(f.Type(), rnd)
- if !ok {
- t.Fatalf("quick.Value failed on field %s", fn)
+ case "NextProtos":
+ f.Set(reflect.ValueOf([]string{"a", "b"}))
+ case "ServerName":
+ f.Set(reflect.ValueOf("b"))
+ case "ClientAuth":
+ f.Set(reflect.ValueOf(VerifyClientCertIfGiven))
+ case "InsecureSkipVerify", "SessionTicketsDisabled", "DynamicRecordSizingDisabled", "PreferServerCipherSuites":
+ f.Set(reflect.ValueOf(true))
+ case "MinVersion", "MaxVersion":
+ f.Set(reflect.ValueOf(uint16(VersionTLS12)))
+ case "SessionTicketKey":
+ f.Set(reflect.ValueOf([32]byte{}))
+ case "CipherSuites":
+ f.Set(reflect.ValueOf([]uint16{1, 2}))
+ case "CurvePreferences":
+ f.Set(reflect.ValueOf([]CurveID{CurveP256}))
+ case "Renegotiation":
+ f.Set(reflect.ValueOf(RenegotiateOnceAsClient))
+ default:
+ t.Errorf("all fields must be accounted for, but saw unknown field %q", fn)
}
- f.Set(q)
}
c2 := c1.Clone()
err := Unmarshal([]byte(data), &struct {
B byte `xml:"b,attr,omitempty"`
}{})
- if err == nil {
- t.Errorf("Unmarshal: expected error, got nil")
+
+ // For Go 1.8.1 we've restored the old "no errors reported" behavior.
+ // We'll try again in Go 1.9 to report errors.
+ if err != nil {
+ t.Errorf("Unmarshal: expected nil, got error")
}
}
return nil
}
- return copyValue(val, []byte(attr.Value))
+ copyValue(val, []byte(attr.Value))
+ return nil
}
var (
}
}
}
+
+func TestIssue19333(t *testing.T) {
+ type X struct {
+ XMLName Name `xml:"X"`
+ A int `xml:",attr"`
+ C int
+ }
+
+ var tests = []struct {
+ input string
+ ok bool
+ }{
+ {`<X></X>`, true},
+ {`<X A=""></X>`, true},
+ {`<X A="bad"></X>`, true},
+ {`<X></X>`, true},
+ {`<X><C></C></X>`, false},
+ {`<X><C/></X>`, false},
+ {`<X><C>bad</C></X>`, false},
+ }
+
+ for _, tt := range tests {
+ err := Unmarshal([]byte(tt.input), new(X))
+ if tt.ok {
+ if err != nil {
+ t.Errorf("%s: unexpected error: %v", tt.input, err)
+ }
+ } else {
+ if err == nil {
+ t.Errorf("%s: unexpected success", tt.input)
+ }
+ }
+ }
+}
}
}
case cbG8:
+ if d.useTransparent {
+ // Match error from Go 1.7 and earlier.
+ // Go 1.9 will decode this properly.
+ return nil, chunkOrderError
+ }
copy(gray.Pix[pixOffset:], cdat)
pixOffset += gray.Stride
case cbGA8:
func BenchmarkDecodeInterlacing(b *testing.B) {
benchmarkDecode(b, "testdata/benchRGB-interlace.png", 4)
}
+
+func TestIssue19553(t *testing.T) {
+ var buf = []byte{
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x85, 0x2c, 0x88, 0x80, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, 0x53, 0x00, 0xff, 0x5b, 0x91, 0x22, 0xb5, 0x00, 0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0a, 0xf0, 0x00, 0x00, 0x0a, 0xf0, 0x01, 0x42, 0xac, 0x34, 0x98, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xd5, 0x04, 0x02, 0x12, 0x11, 0x11, 0xf7, 0x65, 0x3d, 0x8b, 0x00, 0x00, 0x00, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff, 0xff, 0xff, 0xb9, 0xbd, 0x70, 0xf0, 0x8c, 0x01, 0xc8, 0xaf, 0x6e, 0x99, 0x02, 0x05, 0xd9, 0x7b, 0xc1, 0xfc, 0x6b, 0xff, 0xa1, 0xa0, 0x87, 0x30, 0xff, 0xd9, 0xde, 0xbd, 0xd5, 0x4b, 0xf7, 0xee, 0xfd, 0x0e, 0xe3, 0xef, 0xcd, 0x06, 0x19, 0x14, 0xf5, 0x1e, 0xce, 0xef, 0x01, 0x31, 0x92, 0xd7, 0x82, 0x41, 0x31, 0x9c, 0x3f, 0x07, 0x02, 0xee, 0xa1, 0xaa, 0xff, 0xff, 0x9f, 0xe1, 0xd9, 0x56, 0x30, 0xf8, 0x0e, 0xe5, 0x03, 0x00, 0xa9, 0x42, 0x84, 0x3d, 0xdf, 0x8f, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+ }
+ _, err := Decode(bytes.NewReader(buf))
+ if err != chunkOrderError {
+ t.Errorf("Decode: expected chunkOrderError for transparent gray8, got %v", err)
+ }
+}
}
}
+var haveCGO bool
+
+// MustHaveCGO calls t.Skip if cgo is not available.
+func MustHaveCGO(t *testing.T) {
+ if !haveCGO {
+ t.Skipf("skipping test: no cgo")
+ }
+}
+
// HasSymlink reports whether the current system can use os.Symlink.
func HasSymlink() bool {
ok, _ := hasSymlink()
--- /dev/null
+// Copyright 2017 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.
+
+// +build cgo
+
+package testenv
+
+func init() {
+ haveCGO = true
+}
// aLongTimeAgo is a non-zero time, far in the past, used for
// immediate cancelation of network operations.
-var aLongTimeAgo = time.Unix(233431200, 0)
+var aLongTimeAgo = time.Unix(1, 0)
// TODO(bradfitz): move common stuff here. The other files have accumulated
// generic http stuff in random places.
var (
// aLongTimeAgo is a non-zero time, far in the past, used for
// immediate cancelation of dials.
- aLongTimeAgo = time.Unix(233431200, 0)
+ aLongTimeAgo = time.Unix(1, 0)
// nonDeadline and noCancel are just zero values for
// readability with functions taking too many parameters.
t.Fatalf("Start: %v", err)
}
go func() {
- if err := cmd.Process.Kill(); err != nil {
- t.Errorf("Kill: %v", err)
- }
+ // We don't check the error return of Kill. It is
+ // possible that the process has already exited, in
+ // which case Kill will return an error "process
+ // already finished". The purpose of this test is to
+ // see whether the race detector reports an error; it
+ // doesn't matter whether this Kill succeeds or not.
+ cmd.Process.Kill()
}()
go func() {
// Send the wrong string, so that the child fails even
}
// This will be index 3.
+func (p Point) NoArgs() {
+ // Exercise no-argument/no-result paths.
+}
+
+// This will be index 4.
func (p Point) TotalDist(points ...Point) int {
tot := 0
for _, q := range points {
t.Errorf("Type MethodByName returned %d; want 275", i)
}
+ m, ok = TypeOf(p).MethodByName("NoArgs")
+ if !ok {
+ t.Fatalf("method by name failed")
+ }
+ n := len(m.Func.Call([]Value{ValueOf(p)}))
+ if n != 0 {
+ t.Errorf("NoArgs returned %d values; want 0", n)
+ }
+
i = TypeOf(&p).Method(1).Func.Call([]Value{ValueOf(&p), ValueOf(12)})[0].Int()
if i != 300 {
t.Errorf("Pointer Type Method returned %d; want 300", i)
t.Errorf("Pointer Type MethodByName returned %d; want 325", i)
}
+ m, ok = TypeOf(&p).MethodByName("NoArgs")
+ if !ok {
+ t.Fatalf("method by name failed")
+ }
+ n = len(m.Func.Call([]Value{ValueOf(&p)}))
+ if n != 0 {
+ t.Errorf("NoArgs returned %d values; want 0", n)
+ }
+
// Curried method of value.
tfunc := TypeOf((func(int) int)(nil))
v := ValueOf(p).Method(1)
if i != 375 {
t.Errorf("Value MethodByName returned %d; want 375", i)
}
+ v = ValueOf(p).MethodByName("NoArgs")
+ v.Call(nil)
// Curried method of pointer.
v = ValueOf(&p).Method(1)
if i != 425 {
t.Errorf("Pointer Value MethodByName returned %d; want 425", i)
}
+ v = ValueOf(&p).MethodByName("NoArgs")
+ v.Call(nil)
// Curried method of interface value.
// Have to wrap interface value in a struct to get at it.
if i != 275 {
t.Errorf("Value MethodByName returned %d; want 275", i)
}
+ v = ValueOf(p).MethodByName("NoArgs")
+ ValueOf(v.Interface()).Call(nil)
+ v.Interface().(func())()
// Curried method of pointer.
v = ValueOf(&p).Method(1)
if i != 325 {
t.Errorf("Pointer Value MethodByName returned %d; want 325", i)
}
+ v = ValueOf(&p).MethodByName("NoArgs")
+ ValueOf(v.Interface()).Call(nil)
+ v.Interface().(func())()
// Curried method of pointer to pointer.
pp := &p
// Curried method of value.
tfunc := TypeOf((func(...Point) int)(nil))
- v := ValueOf(p).Method(3)
+ v := ValueOf(p).Method(4)
if tt := v.Type(); tt != tfunc {
t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc)
}
import (
"bytes"
"internal/testenv"
+ "io"
"io/ioutil"
"os"
"os/exec"
}
`
+func TestPanicSystemstack(t *testing.T) {
+ // Test that GOTRACEBACK=crash prints both the system and user
+ // stack of other threads.
+
+ // The GOTRACEBACK=crash handler takes 0.1 seconds even if
+ // it's not writing a core file and potentially much longer if
+ // it is. Skip in short mode.
+ if testing.Short() {
+ t.Skip("Skipping in short mode (GOTRACEBACK=crash is slow)")
+ }
+
+ t.Parallel()
+ cmd := exec.Command(os.Args[0], "testPanicSystemstackInternal")
+ cmd = testEnv(cmd)
+ cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ t.Fatal("creating pipe: ", err)
+ }
+ cmd.Stderr = pw
+ if err := cmd.Start(); err != nil {
+ t.Fatal("starting command: ", err)
+ }
+ defer cmd.Process.Wait()
+ defer cmd.Process.Kill()
+ if err := pw.Close(); err != nil {
+ t.Log("closing write pipe: ", err)
+ }
+ defer pr.Close()
+
+ // Wait for "x\nx\n" to indicate readiness.
+ buf := make([]byte, 4)
+ _, err = io.ReadFull(pr, buf)
+ if err != nil || string(buf) != "x\nx\n" {
+ t.Fatal("subprocess failed; output:\n", string(buf))
+ }
+
+ // Send SIGQUIT.
+ if err := cmd.Process.Signal(syscall.SIGQUIT); err != nil {
+ t.Fatal("signaling subprocess: ", err)
+ }
+
+ // Get traceback.
+ tb, err := ioutil.ReadAll(pr)
+ if err != nil {
+ t.Fatal("reading traceback from pipe: ", err)
+ }
+
+ // Traceback should have two testPanicSystemstackInternal's
+ // and two blockOnSystemStackInternal's.
+ if bytes.Count(tb, []byte("testPanicSystemstackInternal")) != 2 {
+ t.Fatal("traceback missing user stack:\n", string(tb))
+ } else if bytes.Count(tb, []byte("blockOnSystemStackInternal")) != 2 {
+ t.Fatal("traceback missing system stack:\n", string(tb))
+ }
+}
+
+func init() {
+ if len(os.Args) >= 2 && os.Args[1] == "testPanicSystemstackInternal" {
+ // Get two threads running on the system stack with
+ // something recognizable in the stack trace.
+ runtime.GOMAXPROCS(2)
+ go testPanicSystemstackInternal()
+ testPanicSystemstackInternal()
+ }
+}
+
+func testPanicSystemstackInternal() {
+ runtime.BlockOnSystemStack()
+ os.Exit(1) // Should be unreachable.
+}
+
func TestSignalExitStatus(t *testing.T) {
testenv.MustHaveGoBuild(t)
exe, err := buildTestProg(t, "testprog")
return
}
*/
+
+// BlockOnSystemStack switches to the system stack, prints "x\n" to
+// stderr, and blocks in a stack containing
+// "runtime.blockOnSystemStackInternal".
+func BlockOnSystemStack() {
+ systemstack(blockOnSystemStackInternal)
+}
+
+func blockOnSystemStackInternal() {
+ print("x\n")
+ lock(&deadlock)
+ lock(&deadlock)
+}
throw("atomicor8")
}
+ m = [4]byte{0xff, 0xff, 0xff, 0xff}
+ atomic.And8(&m[1], 0x1)
+ if m[0] != 0xff || m[1] != 0x1 || m[2] != 0xff || m[3] != 0xff {
+ throw("atomicand8")
+ }
+
*(*uint64)(unsafe.Pointer(&j)) = ^uint64(0)
if j == j {
throw("float64nan")
for x := root.head; x != nil; x = x.next {
if x.elem == unsafe.Pointer(addr) {
x.acquiretime = t0
+ break
}
}
mutexevent(t0-s.acquiretime, 3)
{[]string{"{{.}}", ""}, "twice", ""},
}
- for _, c := range cases {
+ for i, c := range cases {
root := New("root")
var (
}
buf := &bytes.Buffer{}
if err := m.Execute(buf, c.in); err != nil {
- t.Fatal(err)
+ t.Error(i, err)
+ continue
}
if buf.String() != c.want {
t.Errorf("expected string %q: got %q", c.want, buf.String())
}
}
}
+
+// Issue 19249 was a regression in 1.8 caused by the handling of empty
+// templates added in that release, which got different answers depending
+// on the order templates appeared in the internal map.
+func TestIssue19294(t *testing.T) {
+ // The empty block in "xhtml" should be replaced during execution
+ // by the contents of "stylesheet", but if the internal map associating
+ // names with templates is built in the wrong order, the empty block
+ // looks non-empty and this doesn't happen.
+ var inlined = map[string]string{
+ "stylesheet": `{{define "stylesheet"}}stylesheet{{end}}`,
+ "xhtml": `{{block "stylesheet" .}}{{end}}`,
+ }
+ all := []string{"stylesheet", "xhtml"}
+ for i := 0; i < 100; i++ {
+ res, err := New("title.xhtml").Parse(`{{template "xhtml" .}}`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, name := range all {
+ _, err := res.New(name).Parse(inlined[name])
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ var buf bytes.Buffer
+ res.Execute(&buf, 0)
+ if buf.String() != "stylesheet" {
+ t.Fatalf("iteration %d: got %q; expected %q", i, buf.String(), "stylesheet")
+ }
+ }
+}
// Even if nt == t, we need to install it in the common.tmpl map.
if replace, err := t.associate(nt, tree); err != nil {
return nil, err
- } else if replace {
+ } else if replace || nt.Tree == nil {
nt.Tree = tree
}
return nt, nil
if new.common != t.common {
panic("internal error: associate not common")
}
- if t.tmpl[new.name] != nil && parse.IsEmptyTree(tree.Root) && t.Tree != nil {
+ if old := t.tmpl[new.name]; old != nil && parse.IsEmptyTree(tree.Root) && old.Tree != nil {
// If a template by that name exists,
// don't replace it with an empty template.
return false, nil