mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 13:01:21 +08:00
libgo: update to Go 1.8.1 release
Reviewed-on: https://go-review.googlesource.com/40775 From-SVN: r246957
This commit is contained in:
parent
1adb82e117
commit
ea250f5612
@ -1,4 +1,4 @@
|
||||
cd6b6202dd1559b3ac63179b45f1833fcfbe7eca
|
||||
a4c18f063b6659079ca2848ca217a0587dabc001
|
||||
|
||||
The first line of this file holds the git revision number of the
|
||||
last merge done from the master library sources.
|
||||
|
@ -1 +1 @@
|
||||
go1.8
|
||||
go1.8.1
|
||||
|
@ -2227,6 +2227,24 @@ func TestTestEmpty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
|
@ -970,10 +970,6 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
|
||||
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,
|
||||
|
@ -548,6 +548,10 @@ func runTest(cmd *Command, args []string) {
|
||||
|
||||
// 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()
|
||||
@ -639,6 +643,23 @@ func runTest(cmd *Command, args []string) {
|
||||
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 {
|
||||
|
@ -563,6 +563,7 @@ func (c *Config) Clone() *Config {
|
||||
Certificates: c.Certificates,
|
||||
NameToCertificate: c.NameToCertificate,
|
||||
GetCertificate: c.GetCertificate,
|
||||
GetClientCertificate: c.GetClientCertificate,
|
||||
GetConfigForClient: c.GetConfigForClient,
|
||||
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
||||
RootCAs: c.RootCAs,
|
||||
|
@ -13,13 +13,11 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"testing/quick"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -568,11 +566,50 @@ func TestConnCloseWrite(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -581,40 +618,49 @@ func TestClone(t *testing.T) {
|
||||
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
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
q, ok := quick.Value(f.Type(), rnd)
|
||||
if !ok {
|
||||
t.Fatalf("quick.Value failed on field %s", fn)
|
||||
}
|
||||
f.Set(q)
|
||||
}
|
||||
|
||||
c2 := c1.Clone()
|
||||
|
@ -2428,7 +2428,10 @@ func TestIssue16158(t *testing.T) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,8 @@ func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return copyValue(val, []byte(attr.Value))
|
||||
copyValue(val, []byte(attr.Value))
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -797,3 +797,37 @@ func TestIssue12417(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -612,6 +612,11 @@ func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image
|
||||
}
|
||||
}
|
||||
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:
|
||||
|
@ -629,3 +629,13 @@ func BenchmarkDecodeRGB(b *testing.B) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +141,15 @@ func MustHaveExternalNetwork(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
|
11
libgo/go/internal/testenv/testenv_cgo.go
Normal file
11
libgo/go/internal/testenv/testenv_cgo.go
Normal file
@ -0,0 +1,11 @@
|
||||
// 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
|
||||
}
|
@ -20,7 +20,7 @@ const maxInt64 = 1<<63 - 1
|
||||
|
||||
// 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.
|
||||
|
@ -468,7 +468,7 @@ func (e *OpError) Error() string {
|
||||
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.
|
||||
|
@ -266,9 +266,13 @@ func TestStdinCloseRace(t *testing.T) {
|
||||
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
|
||||
|
@ -1681,6 +1681,11 @@ func (p Point) GCMethod(k int) int {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@ -1709,6 +1714,15 @@ func TestMethod(t *testing.T) {
|
||||
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)
|
||||
@ -1723,6 +1737,15 @@ func TestMethod(t *testing.T) {
|
||||
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)
|
||||
@ -1741,6 +1764,8 @@ func TestMethod(t *testing.T) {
|
||||
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)
|
||||
@ -1759,6 +1784,8 @@ func TestMethod(t *testing.T) {
|
||||
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.
|
||||
@ -1808,6 +1835,9 @@ func TestMethodValue(t *testing.T) {
|
||||
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)
|
||||
@ -1826,6 +1856,9 @@ func TestMethodValue(t *testing.T) {
|
||||
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
|
||||
@ -1881,7 +1914,7 @@ func TestVariadicMethodValue(t *testing.T) {
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ package runtime_test
|
||||
import (
|
||||
"bytes"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -153,6 +154,78 @@ func loop(i int, c chan bool) {
|
||||
}
|
||||
`
|
||||
|
||||
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")
|
||||
|
@ -243,3 +243,16 @@ func CountPagesInUse() (pagesInUse, counted uintptr) {
|
||||
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)
|
||||
}
|
||||
|
@ -280,6 +280,12 @@ func check() {
|
||||
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")
|
||||
|
@ -171,6 +171,7 @@ func semrelease(addr *uint32) {
|
||||
for x := root.head; x != nil; x = x.next {
|
||||
if x.elem == unsafe.Pointer(addr) {
|
||||
x.acquiretime = t0
|
||||
break
|
||||
}
|
||||
}
|
||||
mutexevent(t0-s.acquiretime, 3)
|
||||
|
@ -363,7 +363,7 @@ func TestEmptyTemplate(t *testing.T) {
|
||||
{[]string{"{{.}}", ""}, "twice", ""},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
for i, c := range cases {
|
||||
root := New("root")
|
||||
|
||||
var (
|
||||
@ -378,10 +378,43 @@ func TestEmptyTemplate(t *testing.T) {
|
||||
}
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error
|
||||
// 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
|
||||
@ -215,7 +215,7 @@ func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) {
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user