libgo: update to Go1.15.2 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/256618
This commit is contained in:
parent
82b77dee75
commit
10a83805e0
|
@ -1,4 +1,4 @@
|
||||||
cfee06e20a172753552b1515dd3a4fde5d5cad7b
|
6a7648c97c3e0cdbecbec7e760b30246521a6d90
|
||||||
|
|
||||||
The first line of this file holds the git revision number of the last
|
The first line of this file holds the git revision number of the last
|
||||||
merge done from the gofrontend repository.
|
merge done from the gofrontend repository.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
c4f8cb43caf0bcd0c730d7d04a3fce129393cecc
|
9706f510a5e2754595d716bd64be8375997311fb
|
||||||
|
|
||||||
The first line of this file holds the git revision number of the
|
The first line of this file holds the git revision number of the
|
||||||
last merge done from the master library sources.
|
last merge done from the master library sources.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
go1.15rc2
|
go1.15.2
|
||||||
|
|
|
@ -1079,9 +1079,13 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var stdout io.Writer = os.Stdout
|
var stdout io.Writer = os.Stdout
|
||||||
|
var err error
|
||||||
if testJSON {
|
if testJSON {
|
||||||
json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
|
json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
|
||||||
defer json.Close()
|
defer func() {
|
||||||
|
json.Exited(err)
|
||||||
|
json.Close()
|
||||||
|
}()
|
||||||
stdout = json
|
stdout = json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1185,7 +1189,7 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
err := cmd.Start()
|
err = cmd.Start()
|
||||||
|
|
||||||
// This is a last-ditch deadline to detect and
|
// This is a last-ditch deadline to detect and
|
||||||
// stop wedged test binaries, to keep the builders
|
// stop wedged test binaries, to keep the builders
|
||||||
|
|
|
@ -214,9 +214,13 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
||||||
|
|
||||||
explicitArgs := make([]string, 0, len(args))
|
explicitArgs := make([]string, 0, len(args))
|
||||||
inPkgList := false
|
inPkgList := false
|
||||||
|
afterFlagWithoutValue := false
|
||||||
for len(args) > 0 {
|
for len(args) > 0 {
|
||||||
f, remainingArgs, err := cmdflag.ParseOne(&CmdTest.Flag, args)
|
f, remainingArgs, err := cmdflag.ParseOne(&CmdTest.Flag, args)
|
||||||
|
|
||||||
|
wasAfterFlagWithoutValue := afterFlagWithoutValue
|
||||||
|
afterFlagWithoutValue = false // provisionally
|
||||||
|
|
||||||
if errors.Is(err, flag.ErrHelp) {
|
if errors.Is(err, flag.ErrHelp) {
|
||||||
exitWithUsage()
|
exitWithUsage()
|
||||||
}
|
}
|
||||||
|
@ -233,10 +237,24 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
||||||
if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) {
|
if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) {
|
||||||
if !inPkgList && packageNames != nil {
|
if !inPkgList && packageNames != nil {
|
||||||
// We already saw the package list previously, and this argument is not
|
// We already saw the package list previously, and this argument is not
|
||||||
// a flag, so it — and everything after it — must be a literal argument
|
// a flag, so it — and everything after it — must be either a value for
|
||||||
// to the test binary.
|
// a preceding flag or a literal argument to the test binary.
|
||||||
explicitArgs = append(explicitArgs, args...)
|
if wasAfterFlagWithoutValue {
|
||||||
break
|
// This argument could syntactically be a flag value, so
|
||||||
|
// optimistically assume that it is and keep looking for go command
|
||||||
|
// flags after it.
|
||||||
|
//
|
||||||
|
// (If we're wrong, we'll at least be consistent with historical
|
||||||
|
// behavior; see https://golang.org/issue/40763.)
|
||||||
|
explicitArgs = append(explicitArgs, nf.RawArg)
|
||||||
|
args = remainingArgs
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
// This argument syntactically cannot be a flag value, so it must be a
|
||||||
|
// positional argument, and so must everything after it.
|
||||||
|
explicitArgs = append(explicitArgs, args...)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inPkgList = true
|
inPkgList = true
|
||||||
|
@ -272,6 +290,9 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
||||||
|
|
||||||
explicitArgs = append(explicitArgs, nd.RawArg)
|
explicitArgs = append(explicitArgs, nd.RawArg)
|
||||||
args = remainingArgs
|
args = remainingArgs
|
||||||
|
if !nd.HasValue {
|
||||||
|
afterFlagWithoutValue = true
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
env GO111MODULE=on
|
||||||
|
|
||||||
|
[short] skip
|
||||||
|
|
||||||
|
# Arguments after the flag terminator should be ignored.
|
||||||
|
# If we pass '-- -test.v', we should not get verbose output
|
||||||
|
# *and* output from the test should not be echoed.
|
||||||
|
go test ./x -- -test.v
|
||||||
|
stdout '\Aok\s+example.com/x\s+[0-9.s]+\n\z'
|
||||||
|
! stderr .
|
||||||
|
|
||||||
|
# For backward-compatibility with previous releases of the 'go' command,
|
||||||
|
# arguments that appear after unrecognized flags should not be treated
|
||||||
|
# as packages, even if they are unambiguously not arguments to flags.
|
||||||
|
# Even though ./x looks like a package path, the real package should be
|
||||||
|
# the implicit '.'.
|
||||||
|
! go test --answer=42 ./x
|
||||||
|
stderr '^no Go files in .+$'
|
||||||
|
! stderr '/x'
|
||||||
|
|
||||||
|
# However, *flags* that appear after unrecognized flags should still be
|
||||||
|
# interpreted as flags, under the (possibly-erroneous) assumption that
|
||||||
|
# unrecognized flags are non-boolean.
|
||||||
|
|
||||||
|
go test -v -x ./x -timeout 24h -boolflag=true foo -timeout 25h
|
||||||
|
stdout 'args: foo -timeout 25h'
|
||||||
|
stdout 'timeout: 24h0m0s$' # -timeout is unambiguously not a flag, so the real flag wins.
|
||||||
|
|
||||||
|
go test -v -x ./x -timeout 24h -boolflag foo -timeout 25h
|
||||||
|
stdout 'args: foo -test\.timeout=25h0m0s' # For legacy reasons, '-timeout ' is erroneously rewritten to -test.timeout; see https://golang.org/issue/40763.
|
||||||
|
stdout 'timeout: 24h0m0s$' # Actual flag wins.
|
||||||
|
|
||||||
|
go test -v -x ./x -timeout 24h -stringflag foo -timeout 25h
|
||||||
|
stdout 'args: $'
|
||||||
|
stdout 'timeout: 25h0m0s$' # Later flag wins.
|
||||||
|
|
||||||
|
# An explicit '-outputdir=' argument should set test.outputdir
|
||||||
|
# to the 'go' command's working directory, not zero it out
|
||||||
|
# for the test binary.
|
||||||
|
go test -x -coverprofile=cover.out '-outputdir=' ./x
|
||||||
|
stderr '-test.outputdir=[^ ]'
|
||||||
|
exists ./cover.out
|
||||||
|
! exists ./x/cover.out
|
||||||
|
|
||||||
|
# Test flags from GOFLAGS should be forwarded to the test binary,
|
||||||
|
# with the 'test.' prefix in the GOFLAGS entry...
|
||||||
|
env GOFLAGS='-test.timeout=24h0m0s -count=1'
|
||||||
|
go test -v -x ./x
|
||||||
|
stdout 'timeout: 24h0m0s$'
|
||||||
|
stderr '-test.count=1'
|
||||||
|
|
||||||
|
# ...or without.
|
||||||
|
env GOFLAGS='-timeout=24h0m0s -count=1'
|
||||||
|
go test -v -x ./x
|
||||||
|
stdout 'timeout: 24h0m0s$'
|
||||||
|
stderr '-test.count=1'
|
||||||
|
|
||||||
|
# Arguments from the command line should override GOFLAGS...
|
||||||
|
go test -v -x -timeout=25h0m0s ./x
|
||||||
|
stdout 'timeout: 25h0m0s$'
|
||||||
|
stderr '-test.count=1'
|
||||||
|
|
||||||
|
# ...even if they use a different flag name.
|
||||||
|
go test -v -x -test.timeout=26h0m0s ./x
|
||||||
|
stdout 'timeout: 26h0m0s$'
|
||||||
|
stderr '-test\.timeout=26h0m0s'
|
||||||
|
! stderr 'timeout=24h0m0s'
|
||||||
|
stderr '-test.count=1'
|
||||||
|
|
||||||
|
# Invalid flags should be reported exactly once.
|
||||||
|
! go test -covermode=walrus ./x
|
||||||
|
stderr -count=1 'invalid value "walrus" for flag -covermode: valid modes are .*$'
|
||||||
|
stderr '^usage: go test .*$'
|
||||||
|
stderr '^Run ''go help test'' and ''go help testflag'' for details.$'
|
||||||
|
|
||||||
|
# Passing -help to the test binary should show flag help.
|
||||||
|
go test ./x -args -help
|
||||||
|
stdout 'usage_message'
|
||||||
|
|
||||||
|
# -covermode, -coverpkg, and -coverprofile should imply -cover
|
||||||
|
go test -covermode=set ./x
|
||||||
|
stdout '\s+coverage:\s+'
|
||||||
|
|
||||||
|
go test -coverpkg=encoding/binary ./x
|
||||||
|
stdout '\s+coverage:\s+'
|
||||||
|
|
||||||
|
go test -coverprofile=cover.out ./x
|
||||||
|
stdout '\s+coverage:\s+'
|
||||||
|
exists ./cover.out
|
||||||
|
rm ./cover.out
|
||||||
|
|
||||||
|
# -*profile and -trace flags should force output to the current working directory
|
||||||
|
# or -outputdir, not the directory containing the test.
|
||||||
|
|
||||||
|
go test -memprofile=mem.out ./x
|
||||||
|
exists ./mem.out
|
||||||
|
rm ./mem.out
|
||||||
|
|
||||||
|
go test -trace=trace.out ./x
|
||||||
|
exists ./trace.out
|
||||||
|
rm ./trace.out
|
||||||
|
|
||||||
|
# Relative paths with -outputdir should be relative to the go command's working
|
||||||
|
# directory, not the directory containing the test.
|
||||||
|
mkdir profiles
|
||||||
|
go test -memprofile=mem.out -outputdir=./profiles ./x
|
||||||
|
exists ./profiles/mem.out
|
||||||
|
rm profiles
|
||||||
|
|
||||||
|
-- go.mod --
|
||||||
|
module example.com
|
||||||
|
go 1.14
|
||||||
|
-- x/x_test.go --
|
||||||
|
package x
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = flag.String("usage_message", "", "dummy flag to check usage message")
|
||||||
|
var boolflag = flag.Bool("boolflag", false, "ignored boolean flag")
|
||||||
|
var stringflag = flag.String("stringflag", "", "ignored string flag")
|
||||||
|
|
||||||
|
func TestLogTimeout(t *testing.T) {
|
||||||
|
t.Logf("timeout: %v", flag.Lookup("test.timeout").Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogArgs(t *testing.T) {
|
||||||
|
t.Logf("args: %s", strings.Join(flag.Args(), " "))
|
||||||
|
}
|
|
@ -45,10 +45,10 @@ type textBytes []byte
|
||||||
|
|
||||||
func (b textBytes) MarshalText() ([]byte, error) { return b, nil }
|
func (b textBytes) MarshalText() ([]byte, error) { return b, nil }
|
||||||
|
|
||||||
// A converter holds the state of a test-to-JSON conversion.
|
// A Converter holds the state of a test-to-JSON conversion.
|
||||||
// It implements io.WriteCloser; the caller writes test output in,
|
// It implements io.WriteCloser; the caller writes test output in,
|
||||||
// and the converter writes JSON output to w.
|
// and the converter writes JSON output to w.
|
||||||
type converter struct {
|
type Converter struct {
|
||||||
w io.Writer // JSON output stream
|
w io.Writer // JSON output stream
|
||||||
pkg string // package to name in events
|
pkg string // package to name in events
|
||||||
mode Mode // mode bits
|
mode Mode // mode bits
|
||||||
|
@ -100,9 +100,9 @@ var (
|
||||||
//
|
//
|
||||||
// The pkg string, if present, specifies the import path to
|
// The pkg string, if present, specifies the import path to
|
||||||
// report in the JSON stream.
|
// report in the JSON stream.
|
||||||
func NewConverter(w io.Writer, pkg string, mode Mode) io.WriteCloser {
|
func NewConverter(w io.Writer, pkg string, mode Mode) *Converter {
|
||||||
c := new(converter)
|
c := new(Converter)
|
||||||
*c = converter{
|
*c = Converter{
|
||||||
w: w,
|
w: w,
|
||||||
pkg: pkg,
|
pkg: pkg,
|
||||||
mode: mode,
|
mode: mode,
|
||||||
|
@ -122,15 +122,31 @@ func NewConverter(w io.Writer, pkg string, mode Mode) io.WriteCloser {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes the test input to the converter.
|
// Write writes the test input to the converter.
|
||||||
func (c *converter) Write(b []byte) (int, error) {
|
func (c *Converter) Write(b []byte) (int, error) {
|
||||||
c.input.write(b)
|
c.input.write(b)
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exited marks the test process as having exited with the given error.
|
||||||
|
func (c *Converter) Exited(err error) {
|
||||||
|
if err == nil {
|
||||||
|
c.result = "pass"
|
||||||
|
} else {
|
||||||
|
c.result = "fail"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// printed by test on successful run.
|
||||||
bigPass = []byte("PASS\n")
|
bigPass = []byte("PASS\n")
|
||||||
|
|
||||||
|
// printed by test after a normal test failure.
|
||||||
bigFail = []byte("FAIL\n")
|
bigFail = []byte("FAIL\n")
|
||||||
|
|
||||||
|
// printed by 'go test' along with an error if the test binary terminates
|
||||||
|
// with an error.
|
||||||
|
bigFailErrorPrefix = []byte("FAIL\t")
|
||||||
|
|
||||||
updates = [][]byte{
|
updates = [][]byte{
|
||||||
[]byte("=== RUN "),
|
[]byte("=== RUN "),
|
||||||
[]byte("=== PAUSE "),
|
[]byte("=== PAUSE "),
|
||||||
|
@ -153,9 +169,9 @@ var (
|
||||||
// handleInputLine handles a single whole test output line.
|
// handleInputLine handles a single whole test output line.
|
||||||
// It must write the line to c.output but may choose to do so
|
// It must write the line to c.output but may choose to do so
|
||||||
// before or after emitting other events.
|
// before or after emitting other events.
|
||||||
func (c *converter) handleInputLine(line []byte) {
|
func (c *Converter) handleInputLine(line []byte) {
|
||||||
// Final PASS or FAIL.
|
// Final PASS or FAIL.
|
||||||
if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) {
|
if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) || bytes.HasPrefix(line, bigFailErrorPrefix) {
|
||||||
c.flushReport(0)
|
c.flushReport(0)
|
||||||
c.output.write(line)
|
c.output.write(line)
|
||||||
if bytes.Equal(line, bigPass) {
|
if bytes.Equal(line, bigPass) {
|
||||||
|
@ -204,8 +220,18 @@ func (c *converter) handleInputLine(line []byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not a special test output line.
|
||||||
if !ok {
|
if !ok {
|
||||||
// Not a special test output line.
|
// Lookup the name of the test which produced the output using the
|
||||||
|
// indentation of the output as an index into the stack of the current
|
||||||
|
// subtests.
|
||||||
|
// If the indentation is greater than the number of current subtests
|
||||||
|
// then the output must have included extra indentation. We can't
|
||||||
|
// determine which subtest produced this output, so we default to the
|
||||||
|
// old behaviour of assuming the most recently run subtest produced it.
|
||||||
|
if indent > 0 && indent <= len(c.report) {
|
||||||
|
c.testName = c.report[indent-1].Test
|
||||||
|
}
|
||||||
c.output.write(origLine)
|
c.output.write(origLine)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -269,7 +295,7 @@ func (c *converter) handleInputLine(line []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// flushReport flushes all pending PASS/FAIL reports at levels >= depth.
|
// flushReport flushes all pending PASS/FAIL reports at levels >= depth.
|
||||||
func (c *converter) flushReport(depth int) {
|
func (c *Converter) flushReport(depth int) {
|
||||||
c.testName = ""
|
c.testName = ""
|
||||||
for len(c.report) > depth {
|
for len(c.report) > depth {
|
||||||
e := c.report[len(c.report)-1]
|
e := c.report[len(c.report)-1]
|
||||||
|
@ -281,23 +307,22 @@ func (c *converter) flushReport(depth int) {
|
||||||
// Close marks the end of the go test output.
|
// Close marks the end of the go test output.
|
||||||
// It flushes any pending input and then output (only partial lines at this point)
|
// It flushes any pending input and then output (only partial lines at this point)
|
||||||
// and then emits the final overall package-level pass/fail event.
|
// and then emits the final overall package-level pass/fail event.
|
||||||
func (c *converter) Close() error {
|
func (c *Converter) Close() error {
|
||||||
c.input.flush()
|
c.input.flush()
|
||||||
c.output.flush()
|
c.output.flush()
|
||||||
e := &event{Action: "fail"}
|
|
||||||
if c.result != "" {
|
if c.result != "" {
|
||||||
e.Action = c.result
|
e := &event{Action: c.result}
|
||||||
|
if c.mode&Timestamp != 0 {
|
||||||
|
dt := time.Since(c.start).Round(1 * time.Millisecond).Seconds()
|
||||||
|
e.Elapsed = &dt
|
||||||
|
}
|
||||||
|
c.writeEvent(e)
|
||||||
}
|
}
|
||||||
if c.mode&Timestamp != 0 {
|
|
||||||
dt := time.Since(c.start).Round(1 * time.Millisecond).Seconds()
|
|
||||||
e.Elapsed = &dt
|
|
||||||
}
|
|
||||||
c.writeEvent(e)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeOutputEvent writes a single output event with the given bytes.
|
// writeOutputEvent writes a single output event with the given bytes.
|
||||||
func (c *converter) writeOutputEvent(out []byte) {
|
func (c *Converter) writeOutputEvent(out []byte) {
|
||||||
c.writeEvent(&event{
|
c.writeEvent(&event{
|
||||||
Action: "output",
|
Action: "output",
|
||||||
Output: (*textBytes)(&out),
|
Output: (*textBytes)(&out),
|
||||||
|
@ -306,7 +331,7 @@ func (c *converter) writeOutputEvent(out []byte) {
|
||||||
|
|
||||||
// writeEvent writes a single event.
|
// writeEvent writes a single event.
|
||||||
// It adds the package, time (if requested), and test name (if needed).
|
// It adds the package, time (if requested), and test name (if needed).
|
||||||
func (c *converter) writeEvent(e *event) {
|
func (c *Converter) writeEvent(e *event) {
|
||||||
e.Package = c.pkg
|
e.Package = c.pkg
|
||||||
if c.mode&Timestamp != 0 {
|
if c.mode&Timestamp != 0 {
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
|
|
|
@ -4,4 +4,3 @@
|
||||||
{"Action":"output","Output":"# but to avoid questions of timing, we just use a file with no \\n at all.\n"}
|
{"Action":"output","Output":"# but to avoid questions of timing, we just use a file with no \\n at all.\n"}
|
||||||
{"Action":"output","Output":"BenchmarkFoo \t"}
|
{"Action":"output","Output":"BenchmarkFoo \t"}
|
||||||
{"Action":"output","Output":"10000 early EOF"}
|
{"Action":"output","Output":"10000 early EOF"}
|
||||||
{"Action":"fail"}
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
{"Action":"run","Test":"TestOutputWithSubtest"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":"=== RUN TestOutputWithSubtest\n"}
|
||||||
|
{"Action":"run","Test":"TestOutputWithSubtest/sub_test"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":"=== RUN TestOutputWithSubtest/sub_test\n"}
|
||||||
|
{"Action":"run","Test":"TestOutputWithSubtest/sub_test/sub2"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test/sub2","Output":"=== RUN TestOutputWithSubtest/sub_test/sub2\n"}
|
||||||
|
{"Action":"run","Test":"TestOutputWithSubtest/sub_test2"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":"=== RUN TestOutputWithSubtest/sub_test2\n"}
|
||||||
|
{"Action":"run","Test":"TestOutputWithSubtest/sub_test2/sub2"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2/sub2","Output":"=== RUN TestOutputWithSubtest/sub_test2/sub2\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":"--- FAIL: TestOutputWithSubtest (0.00s)\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:6: output before sub tests\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:10: output from root test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:15: output from root test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" --- PASS: TestOutputWithSubtest/sub_test (0.00s)\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" foo_test.go:9: output from sub test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" foo_test.go:11: more output from sub test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" foo_test.go:16: more output from sub test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test/sub2","Output":" --- PASS: TestOutputWithSubtest/sub_test/sub2 (0.00s)\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test/sub2","Output":" foo_test.go:14: output from sub2 test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:22: output from root test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:27: output from root test\n"}
|
||||||
|
{"Action":"pass","Test":"TestOutputWithSubtest/sub_test/sub2"}
|
||||||
|
{"Action":"pass","Test":"TestOutputWithSubtest/sub_test"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" --- PASS: TestOutputWithSubtest/sub_test2 (0.00s)\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" foo_test.go:21: output from sub test2\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" foo_test.go:23: more output from sub test2\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" foo_test.go:28: more output from sub test2\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2/sub2","Output":" --- PASS: TestOutputWithSubtest/sub_test2/sub2 (0.00s)\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest/sub_test2/sub2","Output":" foo_test.go:26: output from sub2 test\n"}
|
||||||
|
{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:32: output after sub test\n"}
|
||||||
|
{"Action":"pass","Test":"TestOutputWithSubtest/sub_test2/sub2"}
|
||||||
|
{"Action":"pass","Test":"TestOutputWithSubtest/sub_test2"}
|
||||||
|
{"Action":"fail","Test":"TestOutputWithSubtest"}
|
||||||
|
{"Action":"output","Output":"FAIL\n"}
|
||||||
|
{"Action":"output","Output":"FAIL\tgotest.tools/gotestsum/foo\t0.001s\n"}
|
||||||
|
{"Action":"output","Output":"FAIL\n"}
|
||||||
|
{"Action":"fail"}
|
|
@ -0,0 +1,27 @@
|
||||||
|
=== RUN TestOutputWithSubtest
|
||||||
|
=== RUN TestOutputWithSubtest/sub_test
|
||||||
|
=== RUN TestOutputWithSubtest/sub_test/sub2
|
||||||
|
=== RUN TestOutputWithSubtest/sub_test2
|
||||||
|
=== RUN TestOutputWithSubtest/sub_test2/sub2
|
||||||
|
--- FAIL: TestOutputWithSubtest (0.00s)
|
||||||
|
foo_test.go:6: output before sub tests
|
||||||
|
foo_test.go:10: output from root test
|
||||||
|
foo_test.go:15: output from root test
|
||||||
|
--- PASS: TestOutputWithSubtest/sub_test (0.00s)
|
||||||
|
foo_test.go:9: output from sub test
|
||||||
|
foo_test.go:11: more output from sub test
|
||||||
|
foo_test.go:16: more output from sub test
|
||||||
|
--- PASS: TestOutputWithSubtest/sub_test/sub2 (0.00s)
|
||||||
|
foo_test.go:14: output from sub2 test
|
||||||
|
foo_test.go:22: output from root test
|
||||||
|
foo_test.go:27: output from root test
|
||||||
|
--- PASS: TestOutputWithSubtest/sub_test2 (0.00s)
|
||||||
|
foo_test.go:21: output from sub test2
|
||||||
|
foo_test.go:23: more output from sub test2
|
||||||
|
foo_test.go:28: more output from sub test2
|
||||||
|
--- PASS: TestOutputWithSubtest/sub_test2/sub2 (0.00s)
|
||||||
|
foo_test.go:26: output from sub2 test
|
||||||
|
foo_test.go:32: output after sub test
|
||||||
|
FAIL
|
||||||
|
FAIL gotest.tools/gotestsum/foo 0.001s
|
||||||
|
FAIL
|
|
@ -0,0 +1,19 @@
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"--- FAIL: TestPanic (0.00s)\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"panic: oops [recovered]\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"\tpanic: oops\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"goroutine 7 [running]:\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"testing.tRunner.func1(0xc000092100)\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"\t/go/src/testing/testing.go:874 +0x3a3\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"panic(0x1110ea0, 0x116aea0)\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"\t/go/src/runtime/panic.go:679 +0x1b2\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"command-line-arguments.TestPanic(0xc000092100)\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"\ta_test.go:6 +0x39\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"testing.tRunner(0xc000092100, 0x114f500)\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"\tgo/src/testing/testing.go:909 +0xc9\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"created by testing.(*T).Run\n"}
|
||||||
|
{"Action":"output","Test":"TestPanic","Output":"\tgo/src/testing/testing.go:960 +0x350\n"}
|
||||||
|
{"Action":"fail","Test":"TestPanic"}
|
||||||
|
{"Action":"output","Output":"FAIL\tcommand-line-arguments\t0.042s\n"}
|
||||||
|
{"Action":"output","Output":"FAIL\n"}
|
||||||
|
{"Action":"fail"}
|
|
@ -0,0 +1,17 @@
|
||||||
|
--- FAIL: TestPanic (0.00s)
|
||||||
|
panic: oops [recovered]
|
||||||
|
panic: oops
|
||||||
|
|
||||||
|
goroutine 7 [running]:
|
||||||
|
testing.tRunner.func1(0xc000092100)
|
||||||
|
/go/src/testing/testing.go:874 +0x3a3
|
||||||
|
panic(0x1110ea0, 0x116aea0)
|
||||||
|
/go/src/runtime/panic.go:679 +0x1b2
|
||||||
|
command-line-arguments.TestPanic(0xc000092100)
|
||||||
|
a_test.go:6 +0x39
|
||||||
|
testing.tRunner(0xc000092100, 0x114f500)
|
||||||
|
go/src/testing/testing.go:909 +0xc9
|
||||||
|
created by testing.(*T).Run
|
||||||
|
go/src/testing/testing.go:960 +0x350
|
||||||
|
FAIL command-line-arguments 0.042s
|
||||||
|
FAIL
|
|
@ -116,13 +116,13 @@
|
||||||
{"Action":"output","Test":"Test☺☹/2","Output":"=== CONT Test☺☹/2\n"}
|
{"Action":"output","Test":"Test☺☹/2","Output":"=== CONT Test☺☹/2\n"}
|
||||||
{"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"}
|
{"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" --- PASS: TestTags/x_testtag_y (0.04s)\n"}
|
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" --- PASS: TestTags/x_testtag_y (0.04s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" \tvet_test.go:187: -tags=x testtag y\n"}
|
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" vet_test.go:187: -tags=x testtag y\n"}
|
||||||
{"Action":"pass","Test":"TestTags/x_testtag_y"}
|
{"Action":"pass","Test":"TestTags/x_testtag_y"}
|
||||||
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" --- PASS: TestTags/x,testtag,y (0.04s)\n"}
|
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" --- PASS: TestTags/x,testtag,y (0.04s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" \tvet_test.go:187: -tags=x,testtag,y\n"}
|
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" vet_test.go:187: -tags=x,testtag,y\n"}
|
||||||
{"Action":"pass","Test":"TestTags/x,testtag,y"}
|
{"Action":"pass","Test":"TestTags/x,testtag,y"}
|
||||||
{"Action":"output","Test":"TestTags/testtag","Output":" --- PASS: TestTags/testtag (0.04s)\n"}
|
{"Action":"output","Test":"TestTags/testtag","Output":" --- PASS: TestTags/testtag (0.04s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/testtag","Output":" \tvet_test.go:187: -tags=testtag\n"}
|
{"Action":"output","Test":"TestTags/testtag","Output":" vet_test.go:187: -tags=testtag\n"}
|
||||||
{"Action":"pass","Test":"TestTags/testtag"}
|
{"Action":"pass","Test":"TestTags/testtag"}
|
||||||
{"Action":"pass","Test":"TestTags"}
|
{"Action":"pass","Test":"TestTags"}
|
||||||
{"Action":"cont","Test":"Test☺☹/1"}
|
{"Action":"cont","Test":"Test☺☹/1"}
|
||||||
|
@ -139,28 +139,28 @@
|
||||||
{"Action":"output","Test":"Test☺☹Dirs/cgo","Output":"=== CONT Test☺☹Dirs/cgo\n"}
|
{"Action":"output","Test":"Test☺☹Dirs/cgo","Output":"=== CONT Test☺☹Dirs/cgo\n"}
|
||||||
{"Action":"output","Test":"Test☺☹","Output":"--- PASS: Test☺☹ (0.39s)\n"}
|
{"Action":"output","Test":"Test☺☹","Output":"--- PASS: Test☺☹ (0.39s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/5","Output":" --- PASS: Test☺☹/5 (0.07s)\n"}
|
{"Action":"output","Test":"Test☺☹/5","Output":" --- PASS: Test☺☹/5 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/5","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/5","Output":" vet_test.go:114: φιλεσ: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/5"}
|
{"Action":"pass","Test":"Test☺☹/5"}
|
||||||
{"Action":"output","Test":"Test☺☹/3","Output":" --- PASS: Test☺☹/3 (0.07s)\n"}
|
{"Action":"output","Test":"Test☺☹/3","Output":" --- PASS: Test☺☹/3 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/3","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/3","Output":" vet_test.go:114: φιλεσ: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/3"}
|
{"Action":"pass","Test":"Test☺☹/3"}
|
||||||
{"Action":"output","Test":"Test☺☹/6","Output":" --- PASS: Test☺☹/6 (0.07s)\n"}
|
{"Action":"output","Test":"Test☺☹/6","Output":" --- PASS: Test☺☹/6 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/6","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/6","Output":" vet_test.go:114: φιλεσ: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/6"}
|
{"Action":"pass","Test":"Test☺☹/6"}
|
||||||
{"Action":"output","Test":"Test☺☹/2","Output":" --- PASS: Test☺☹/2 (0.07s)\n"}
|
{"Action":"output","Test":"Test☺☹/2","Output":" --- PASS: Test☺☹/2 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/2","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/2","Output":" vet_test.go:114: φιλεσ: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/2"}
|
{"Action":"pass","Test":"Test☺☹/2"}
|
||||||
{"Action":"output","Test":"Test☺☹/0","Output":" --- PASS: Test☺☹/0 (0.13s)\n"}
|
{"Action":"output","Test":"Test☺☹/0","Output":" --- PASS: Test☺☹/0 (0.13s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/0","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/0","Output":" vet_test.go:114: φιλεσ: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/0"}
|
{"Action":"pass","Test":"Test☺☹/0"}
|
||||||
{"Action":"output","Test":"Test☺☹/4","Output":" --- PASS: Test☺☹/4 (0.16s)\n"}
|
{"Action":"output","Test":"Test☺☹/4","Output":" --- PASS: Test☺☹/4 (0.16s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/4","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/4","Output":" vet_test.go:114: φιλεσ: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/4"}
|
{"Action":"pass","Test":"Test☺☹/4"}
|
||||||
{"Action":"output","Test":"Test☺☹/1","Output":" --- PASS: Test☺☹/1 (0.07s)\n"}
|
{"Action":"output","Test":"Test☺☹/1","Output":" --- PASS: Test☺☹/1 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/1","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/1","Output":" vet_test.go:114: φιλεσ: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/1"}
|
{"Action":"pass","Test":"Test☺☹/1"}
|
||||||
{"Action":"output","Test":"Test☺☹/7","Output":" --- PASS: Test☺☹/7 (0.19s)\n"}
|
{"Action":"output","Test":"Test☺☹/7","Output":" --- PASS: Test☺☹/7 (0.19s)\n"}
|
||||||
{"Action":"output","Test":"Test☺☹/7","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"}
|
{"Action":"output","Test":"Test☺☹/7","Output":" vet_test.go:114: φιλεσ: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"}
|
||||||
{"Action":"pass","Test":"Test☺☹/7"}
|
{"Action":"pass","Test":"Test☺☹/7"}
|
||||||
{"Action":"pass","Test":"Test☺☹"}
|
{"Action":"pass","Test":"Test☺☹"}
|
||||||
{"Action":"output","Test":"Test☺☹Dirs","Output":"--- PASS: Test☺☹Dirs (0.01s)\n"}
|
{"Action":"output","Test":"Test☺☹Dirs","Output":"--- PASS: Test☺☹Dirs (0.01s)\n"}
|
||||||
|
|
|
@ -58,11 +58,11 @@
|
||||||
=== CONT Test☺☹/2
|
=== CONT Test☺☹/2
|
||||||
--- PASS: TestTags (0.00s)
|
--- PASS: TestTags (0.00s)
|
||||||
--- PASS: TestTags/x_testtag_y (0.04s)
|
--- PASS: TestTags/x_testtag_y (0.04s)
|
||||||
vet_test.go:187: -tags=x testtag y
|
vet_test.go:187: -tags=x testtag y
|
||||||
--- PASS: TestTags/x,testtag,y (0.04s)
|
--- PASS: TestTags/x,testtag,y (0.04s)
|
||||||
vet_test.go:187: -tags=x,testtag,y
|
vet_test.go:187: -tags=x,testtag,y
|
||||||
--- PASS: TestTags/testtag (0.04s)
|
--- PASS: TestTags/testtag (0.04s)
|
||||||
vet_test.go:187: -tags=testtag
|
vet_test.go:187: -tags=testtag
|
||||||
=== CONT Test☺☹/1
|
=== CONT Test☺☹/1
|
||||||
=== CONT Test☺☹Dirs/testingpkg
|
=== CONT Test☺☹Dirs/testingpkg
|
||||||
=== CONT Test☺☹Dirs/buildtag
|
=== CONT Test☺☹Dirs/buildtag
|
||||||
|
@ -71,21 +71,21 @@
|
||||||
=== CONT Test☺☹Dirs/cgo
|
=== CONT Test☺☹Dirs/cgo
|
||||||
--- PASS: Test☺☹ (0.39s)
|
--- PASS: Test☺☹ (0.39s)
|
||||||
--- PASS: Test☺☹/5 (0.07s)
|
--- PASS: Test☺☹/5 (0.07s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/copylock_func.go" "testdata/rangeloop.go"]
|
vet_test.go:114: φιλεσ: ["testdata/copylock_func.go" "testdata/rangeloop.go"]
|
||||||
--- PASS: Test☺☹/3 (0.07s)
|
--- PASS: Test☺☹/3 (0.07s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/composite.go" "testdata/nilfunc.go"]
|
vet_test.go:114: φιλεσ: ["testdata/composite.go" "testdata/nilfunc.go"]
|
||||||
--- PASS: Test☺☹/6 (0.07s)
|
--- PASS: Test☺☹/6 (0.07s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/copylock_range.go" "testdata/shadow.go"]
|
vet_test.go:114: φιλεσ: ["testdata/copylock_range.go" "testdata/shadow.go"]
|
||||||
--- PASS: Test☺☹/2 (0.07s)
|
--- PASS: Test☺☹/2 (0.07s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"]
|
vet_test.go:114: φιλεσ: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"]
|
||||||
--- PASS: Test☺☹/0 (0.13s)
|
--- PASS: Test☺☹/0 (0.13s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"]
|
vet_test.go:114: φιλεσ: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"]
|
||||||
--- PASS: Test☺☹/4 (0.16s)
|
--- PASS: Test☺☹/4 (0.16s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/copylock.go" "testdata/print.go"]
|
vet_test.go:114: φιλεσ: ["testdata/copylock.go" "testdata/print.go"]
|
||||||
--- PASS: Test☺☹/1 (0.07s)
|
--- PASS: Test☺☹/1 (0.07s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"]
|
vet_test.go:114: φιλεσ: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"]
|
||||||
--- PASS: Test☺☹/7 (0.19s)
|
--- PASS: Test☺☹/7 (0.19s)
|
||||||
vet_test.go:114: φιλεσ: ["testdata/deadcode.go" "testdata/shift.go"]
|
vet_test.go:114: φιλεσ: ["testdata/deadcode.go" "testdata/shift.go"]
|
||||||
--- PASS: Test☺☹Dirs (0.01s)
|
--- PASS: Test☺☹Dirs (0.01s)
|
||||||
--- PASS: Test☺☹Dirs/testingpkg (0.06s)
|
--- PASS: Test☺☹Dirs/testingpkg (0.06s)
|
||||||
--- PASS: Test☺☹Dirs/divergent (0.05s)
|
--- PASS: Test☺☹Dirs/divergent (0.05s)
|
||||||
|
|
|
@ -116,13 +116,13 @@
|
||||||
{"Action":"output","Test":"TestVet/2","Output":"=== CONT TestVet/2\n"}
|
{"Action":"output","Test":"TestVet/2","Output":"=== CONT TestVet/2\n"}
|
||||||
{"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"}
|
{"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" --- PASS: TestTags/x_testtag_y (0.04s)\n"}
|
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" --- PASS: TestTags/x_testtag_y (0.04s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" \tvet_test.go:187: -tags=x testtag y\n"}
|
{"Action":"output","Test":"TestTags/x_testtag_y","Output":" vet_test.go:187: -tags=x testtag y\n"}
|
||||||
{"Action":"pass","Test":"TestTags/x_testtag_y"}
|
{"Action":"pass","Test":"TestTags/x_testtag_y"}
|
||||||
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" --- PASS: TestTags/x,testtag,y (0.04s)\n"}
|
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" --- PASS: TestTags/x,testtag,y (0.04s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" \tvet_test.go:187: -tags=x,testtag,y\n"}
|
{"Action":"output","Test":"TestTags/x,testtag,y","Output":" vet_test.go:187: -tags=x,testtag,y\n"}
|
||||||
{"Action":"pass","Test":"TestTags/x,testtag,y"}
|
{"Action":"pass","Test":"TestTags/x,testtag,y"}
|
||||||
{"Action":"output","Test":"TestTags/testtag","Output":" --- PASS: TestTags/testtag (0.04s)\n"}
|
{"Action":"output","Test":"TestTags/testtag","Output":" --- PASS: TestTags/testtag (0.04s)\n"}
|
||||||
{"Action":"output","Test":"TestTags/testtag","Output":" \tvet_test.go:187: -tags=testtag\n"}
|
{"Action":"output","Test":"TestTags/testtag","Output":" vet_test.go:187: -tags=testtag\n"}
|
||||||
{"Action":"pass","Test":"TestTags/testtag"}
|
{"Action":"pass","Test":"TestTags/testtag"}
|
||||||
{"Action":"pass","Test":"TestTags"}
|
{"Action":"pass","Test":"TestTags"}
|
||||||
{"Action":"cont","Test":"TestVet/1"}
|
{"Action":"cont","Test":"TestVet/1"}
|
||||||
|
@ -139,28 +139,28 @@
|
||||||
{"Action":"output","Test":"TestVetDirs/cgo","Output":"=== CONT TestVetDirs/cgo\n"}
|
{"Action":"output","Test":"TestVetDirs/cgo","Output":"=== CONT TestVetDirs/cgo\n"}
|
||||||
{"Action":"output","Test":"TestVet","Output":"--- PASS: TestVet (0.39s)\n"}
|
{"Action":"output","Test":"TestVet","Output":"--- PASS: TestVet (0.39s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/5","Output":" --- PASS: TestVet/5 (0.07s)\n"}
|
{"Action":"output","Test":"TestVet/5","Output":" --- PASS: TestVet/5 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/5","Output":" \tvet_test.go:114: files: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"}
|
{"Action":"output","Test":"TestVet/5","Output":" vet_test.go:114: files: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/5"}
|
{"Action":"pass","Test":"TestVet/5"}
|
||||||
{"Action":"output","Test":"TestVet/3","Output":" --- PASS: TestVet/3 (0.07s)\n"}
|
{"Action":"output","Test":"TestVet/3","Output":" --- PASS: TestVet/3 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/3","Output":" \tvet_test.go:114: files: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"}
|
{"Action":"output","Test":"TestVet/3","Output":" vet_test.go:114: files: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/3"}
|
{"Action":"pass","Test":"TestVet/3"}
|
||||||
{"Action":"output","Test":"TestVet/6","Output":" --- PASS: TestVet/6 (0.07s)\n"}
|
{"Action":"output","Test":"TestVet/6","Output":" --- PASS: TestVet/6 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/6","Output":" \tvet_test.go:114: files: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"}
|
{"Action":"output","Test":"TestVet/6","Output":" vet_test.go:114: files: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/6"}
|
{"Action":"pass","Test":"TestVet/6"}
|
||||||
{"Action":"output","Test":"TestVet/2","Output":" --- PASS: TestVet/2 (0.07s)\n"}
|
{"Action":"output","Test":"TestVet/2","Output":" --- PASS: TestVet/2 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/2","Output":" \tvet_test.go:114: files: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"}
|
{"Action":"output","Test":"TestVet/2","Output":" vet_test.go:114: files: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/2"}
|
{"Action":"pass","Test":"TestVet/2"}
|
||||||
{"Action":"output","Test":"TestVet/0","Output":" --- PASS: TestVet/0 (0.13s)\n"}
|
{"Action":"output","Test":"TestVet/0","Output":" --- PASS: TestVet/0 (0.13s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/0","Output":" \tvet_test.go:114: files: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"}
|
{"Action":"output","Test":"TestVet/0","Output":" vet_test.go:114: files: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/0"}
|
{"Action":"pass","Test":"TestVet/0"}
|
||||||
{"Action":"output","Test":"TestVet/4","Output":" --- PASS: TestVet/4 (0.16s)\n"}
|
{"Action":"output","Test":"TestVet/4","Output":" --- PASS: TestVet/4 (0.16s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/4","Output":" \tvet_test.go:114: files: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"}
|
{"Action":"output","Test":"TestVet/4","Output":" vet_test.go:114: files: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/4"}
|
{"Action":"pass","Test":"TestVet/4"}
|
||||||
{"Action":"output","Test":"TestVet/1","Output":" --- PASS: TestVet/1 (0.07s)\n"}
|
{"Action":"output","Test":"TestVet/1","Output":" --- PASS: TestVet/1 (0.07s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/1","Output":" \tvet_test.go:114: files: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"}
|
{"Action":"output","Test":"TestVet/1","Output":" vet_test.go:114: files: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/1"}
|
{"Action":"pass","Test":"TestVet/1"}
|
||||||
{"Action":"output","Test":"TestVet/7","Output":" --- PASS: TestVet/7 (0.19s)\n"}
|
{"Action":"output","Test":"TestVet/7","Output":" --- PASS: TestVet/7 (0.19s)\n"}
|
||||||
{"Action":"output","Test":"TestVet/7","Output":" \tvet_test.go:114: files: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"}
|
{"Action":"output","Test":"TestVet/7","Output":" vet_test.go:114: files: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"}
|
||||||
{"Action":"pass","Test":"TestVet/7"}
|
{"Action":"pass","Test":"TestVet/7"}
|
||||||
{"Action":"pass","Test":"TestVet"}
|
{"Action":"pass","Test":"TestVet"}
|
||||||
{"Action":"output","Test":"TestVetDirs","Output":"--- PASS: TestVetDirs (0.01s)\n"}
|
{"Action":"output","Test":"TestVetDirs","Output":"--- PASS: TestVetDirs (0.01s)\n"}
|
||||||
|
|
|
@ -58,11 +58,11 @@
|
||||||
=== CONT TestVet/2
|
=== CONT TestVet/2
|
||||||
--- PASS: TestTags (0.00s)
|
--- PASS: TestTags (0.00s)
|
||||||
--- PASS: TestTags/x_testtag_y (0.04s)
|
--- PASS: TestTags/x_testtag_y (0.04s)
|
||||||
vet_test.go:187: -tags=x testtag y
|
vet_test.go:187: -tags=x testtag y
|
||||||
--- PASS: TestTags/x,testtag,y (0.04s)
|
--- PASS: TestTags/x,testtag,y (0.04s)
|
||||||
vet_test.go:187: -tags=x,testtag,y
|
vet_test.go:187: -tags=x,testtag,y
|
||||||
--- PASS: TestTags/testtag (0.04s)
|
--- PASS: TestTags/testtag (0.04s)
|
||||||
vet_test.go:187: -tags=testtag
|
vet_test.go:187: -tags=testtag
|
||||||
=== CONT TestVet/1
|
=== CONT TestVet/1
|
||||||
=== CONT TestVetDirs/testingpkg
|
=== CONT TestVetDirs/testingpkg
|
||||||
=== CONT TestVetDirs/buildtag
|
=== CONT TestVetDirs/buildtag
|
||||||
|
@ -71,21 +71,21 @@
|
||||||
=== CONT TestVetDirs/cgo
|
=== CONT TestVetDirs/cgo
|
||||||
--- PASS: TestVet (0.39s)
|
--- PASS: TestVet (0.39s)
|
||||||
--- PASS: TestVet/5 (0.07s)
|
--- PASS: TestVet/5 (0.07s)
|
||||||
vet_test.go:114: files: ["testdata/copylock_func.go" "testdata/rangeloop.go"]
|
vet_test.go:114: files: ["testdata/copylock_func.go" "testdata/rangeloop.go"]
|
||||||
--- PASS: TestVet/3 (0.07s)
|
--- PASS: TestVet/3 (0.07s)
|
||||||
vet_test.go:114: files: ["testdata/composite.go" "testdata/nilfunc.go"]
|
vet_test.go:114: files: ["testdata/composite.go" "testdata/nilfunc.go"]
|
||||||
--- PASS: TestVet/6 (0.07s)
|
--- PASS: TestVet/6 (0.07s)
|
||||||
vet_test.go:114: files: ["testdata/copylock_range.go" "testdata/shadow.go"]
|
vet_test.go:114: files: ["testdata/copylock_range.go" "testdata/shadow.go"]
|
||||||
--- PASS: TestVet/2 (0.07s)
|
--- PASS: TestVet/2 (0.07s)
|
||||||
vet_test.go:114: files: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"]
|
vet_test.go:114: files: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"]
|
||||||
--- PASS: TestVet/0 (0.13s)
|
--- PASS: TestVet/0 (0.13s)
|
||||||
vet_test.go:114: files: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"]
|
vet_test.go:114: files: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"]
|
||||||
--- PASS: TestVet/4 (0.16s)
|
--- PASS: TestVet/4 (0.16s)
|
||||||
vet_test.go:114: files: ["testdata/copylock.go" "testdata/print.go"]
|
vet_test.go:114: files: ["testdata/copylock.go" "testdata/print.go"]
|
||||||
--- PASS: TestVet/1 (0.07s)
|
--- PASS: TestVet/1 (0.07s)
|
||||||
vet_test.go:114: files: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"]
|
vet_test.go:114: files: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"]
|
||||||
--- PASS: TestVet/7 (0.19s)
|
--- PASS: TestVet/7 (0.19s)
|
||||||
vet_test.go:114: files: ["testdata/deadcode.go" "testdata/shift.go"]
|
vet_test.go:114: files: ["testdata/deadcode.go" "testdata/shift.go"]
|
||||||
--- PASS: TestVetDirs (0.01s)
|
--- PASS: TestVetDirs (0.01s)
|
||||||
--- PASS: TestVetDirs/testingpkg (0.06s)
|
--- PASS: TestVetDirs/testingpkg (0.06s)
|
||||||
--- PASS: TestVetDirs/divergent (0.05s)
|
--- PASS: TestVetDirs/divergent (0.05s)
|
||||||
|
|
|
@ -118,12 +118,16 @@ func main() {
|
||||||
w := &countWriter{0, c}
|
w := &countWriter{0, c}
|
||||||
cmd.Stdout = w
|
cmd.Stdout = w
|
||||||
cmd.Stderr = w
|
cmd.Stderr = w
|
||||||
if err := cmd.Run(); err != nil {
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
if w.n > 0 {
|
if w.n > 0 {
|
||||||
// Assume command printed why it failed.
|
// Assume command printed why it failed.
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(c, "test2json: %v\n", err)
|
fmt.Fprintf(c, "test2json: %v\n", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
c.Exited(err)
|
||||||
|
if err != nil {
|
||||||
c.Close()
|
c.Close()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err
|
||||||
// use copy_file_range(2) again.
|
// use copy_file_range(2) again.
|
||||||
atomic.StoreInt32(©FileRangeSupported, 0)
|
atomic.StoreInt32(©FileRangeSupported, 0)
|
||||||
return 0, false, nil
|
return 0, false, nil
|
||||||
case syscall.EXDEV, syscall.EINVAL:
|
case syscall.EXDEV, syscall.EINVAL, syscall.EOPNOTSUPP, syscall.EPERM:
|
||||||
// Prior to Linux 5.3, it was not possible to
|
// Prior to Linux 5.3, it was not possible to
|
||||||
// copy_file_range across file systems. Similarly to
|
// copy_file_range across file systems. Similarly to
|
||||||
// the ENOSYS case above, if we see EXDEV, we have
|
// the ENOSYS case above, if we see EXDEV, we have
|
||||||
|
@ -52,6 +52,14 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err
|
||||||
// dst or src refer to a pipe rather than a regular
|
// dst or src refer to a pipe rather than a regular
|
||||||
// file. This is another case where no data has been
|
// file. This is another case where no data has been
|
||||||
// transfered, so we consider it unhandled.
|
// transfered, so we consider it unhandled.
|
||||||
|
//
|
||||||
|
// If the file is on NFS, we can see EOPNOTSUPP.
|
||||||
|
// See issue #40731.
|
||||||
|
//
|
||||||
|
// If the process is running inside a Docker container,
|
||||||
|
// we might see EPERM instead of ENOSYS. See issue
|
||||||
|
// #40893. Since EPERM might also be a legitimate error,
|
||||||
|
// don't mark copy_file_range(2) as unsupported.
|
||||||
return 0, false, nil
|
return 0, false, nil
|
||||||
case nil:
|
case nil:
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
|
|
|
@ -163,10 +163,12 @@ func Serve(handler http.Handler) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type response struct {
|
type response struct {
|
||||||
req *http.Request
|
req *http.Request
|
||||||
header http.Header
|
header http.Header
|
||||||
bufw *bufio.Writer
|
code int
|
||||||
headerSent bool
|
wroteHeader bool
|
||||||
|
wroteCGIHeader bool
|
||||||
|
bufw *bufio.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *response) Flush() {
|
func (r *response) Flush() {
|
||||||
|
@ -178,26 +180,38 @@ func (r *response) Header() http.Header {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *response) Write(p []byte) (n int, err error) {
|
func (r *response) Write(p []byte) (n int, err error) {
|
||||||
if !r.headerSent {
|
if !r.wroteHeader {
|
||||||
r.WriteHeader(http.StatusOK)
|
r.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
if !r.wroteCGIHeader {
|
||||||
|
r.writeCGIHeader(p)
|
||||||
|
}
|
||||||
return r.bufw.Write(p)
|
return r.bufw.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *response) WriteHeader(code int) {
|
func (r *response) WriteHeader(code int) {
|
||||||
if r.headerSent {
|
if r.wroteHeader {
|
||||||
// Note: explicitly using Stderr, as Stdout is our HTTP output.
|
// Note: explicitly using Stderr, as Stdout is our HTTP output.
|
||||||
fmt.Fprintf(os.Stderr, "CGI attempted to write header twice on request for %s", r.req.URL)
|
fmt.Fprintf(os.Stderr, "CGI attempted to write header twice on request for %s", r.req.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.headerSent = true
|
r.wroteHeader = true
|
||||||
fmt.Fprintf(r.bufw, "Status: %d %s\r\n", code, http.StatusText(code))
|
r.code = code
|
||||||
|
}
|
||||||
|
|
||||||
// Set a default Content-Type
|
// writeCGIHeader finalizes the header sent to the client and writes it to the output.
|
||||||
if _, hasType := r.header["Content-Type"]; !hasType {
|
// p is not written by writeHeader, but is the first chunk of the body
|
||||||
r.header.Add("Content-Type", "text/html; charset=utf-8")
|
// that will be written. It is sniffed for a Content-Type if none is
|
||||||
|
// set explicitly.
|
||||||
|
func (r *response) writeCGIHeader(p []byte) {
|
||||||
|
if r.wroteCGIHeader {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.wroteCGIHeader = true
|
||||||
|
fmt.Fprintf(r.bufw, "Status: %d %s\r\n", r.code, http.StatusText(r.code))
|
||||||
|
if _, hasType := r.header["Content-Type"]; !hasType {
|
||||||
|
r.header.Set("Content-Type", http.DetectContentType(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
r.header.Write(r.bufw)
|
r.header.Write(r.bufw)
|
||||||
r.bufw.WriteString("\r\n")
|
r.bufw.WriteString("\r\n")
|
||||||
r.bufw.Flush()
|
r.bufw.Flush()
|
||||||
|
|
|
@ -7,6 +7,11 @@
|
||||||
package cgi
|
package cgi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -148,3 +153,67 @@ func TestRequestWithoutRemotePort(t *testing.T) {
|
||||||
t.Errorf("RemoteAddr: got %q; want %q", g, e)
|
t.Errorf("RemoteAddr: got %q; want %q", g, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type countingWriter int
|
||||||
|
|
||||||
|
func (c *countingWriter) Write(p []byte) (int, error) {
|
||||||
|
*c += countingWriter(len(p))
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
func (c *countingWriter) WriteString(p string) (int, error) {
|
||||||
|
*c += countingWriter(len(p))
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResponse(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
body string
|
||||||
|
wantCT string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no body",
|
||||||
|
wantCT: "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "html",
|
||||||
|
body: "<html><head><title>test page</title></head><body>This is a body</body></html>",
|
||||||
|
wantCT: "text/html; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "text",
|
||||||
|
body: strings.Repeat("gopher", 86),
|
||||||
|
wantCT: "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jpg",
|
||||||
|
body: "\xFF\xD8\xFF" + strings.Repeat("B", 1024),
|
||||||
|
wantCT: "image/jpeg",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
resp := response{
|
||||||
|
req: httptest.NewRequest("GET", "/", nil),
|
||||||
|
header: http.Header{},
|
||||||
|
bufw: bufio.NewWriter(&buf),
|
||||||
|
}
|
||||||
|
n, err := resp.Write([]byte(tt.body))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Write: unexpected %v", err)
|
||||||
|
}
|
||||||
|
if want := len(tt.body); n != want {
|
||||||
|
t.Errorf("reported short Write: got %v want %v", n, want)
|
||||||
|
}
|
||||||
|
resp.writeCGIHeader(nil)
|
||||||
|
resp.Flush()
|
||||||
|
if got := resp.Header().Get("Content-Type"); got != tt.wantCT {
|
||||||
|
t.Errorf("wrong content-type: got %q, want %q", got, tt.wantCT)
|
||||||
|
}
|
||||||
|
if !bytes.HasSuffix(buf.Bytes(), []byte(tt.body)) {
|
||||||
|
t.Errorf("body was not correctly written")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -52,7 +54,7 @@ func TestHostingOurselves(t *testing.T) {
|
||||||
}
|
}
|
||||||
replay := runCgiTest(t, h, "GET /test.go?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
|
replay := runCgiTest(t, h, "GET /test.go?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
|
||||||
|
|
||||||
if expected, got := "text/html; charset=utf-8", replay.Header().Get("Content-Type"); got != expected {
|
if expected, got := "text/plain; charset=utf-8", replay.Header().Get("Content-Type"); got != expected {
|
||||||
t.Errorf("got a Content-Type of %q; expected %q", got, expected)
|
t.Errorf("got a Content-Type of %q; expected %q", got, expected)
|
||||||
}
|
}
|
||||||
if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected {
|
if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected {
|
||||||
|
@ -152,6 +154,51 @@ func TestChildOnlyHeaders(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestChildContentType(t *testing.T) {
|
||||||
|
testenv.MustHaveExec(t)
|
||||||
|
|
||||||
|
h := &Handler{
|
||||||
|
Path: os.Args[0],
|
||||||
|
Root: "/test.go",
|
||||||
|
Args: []string{"-test.run=TestBeChildCGIProcess"},
|
||||||
|
}
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
body string
|
||||||
|
wantCT string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no body",
|
||||||
|
wantCT: "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "html",
|
||||||
|
body: "<html><head><title>test page</title></head><body>This is a body</body></html>",
|
||||||
|
wantCT: "text/html; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "text",
|
||||||
|
body: strings.Repeat("gopher", 86),
|
||||||
|
wantCT: "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jpg",
|
||||||
|
body: "\xFF\xD8\xFF" + strings.Repeat("B", 1024),
|
||||||
|
wantCT: "image/jpeg",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
expectedMap := map[string]string{"_body": tt.body}
|
||||||
|
req := fmt.Sprintf("GET /test.go?exact-body=%s HTTP/1.0\nHost: example.com\n\n", url.QueryEscape(tt.body))
|
||||||
|
replay := runCgiTest(t, h, req, expectedMap)
|
||||||
|
if got := replay.Header().Get("Content-Type"); got != tt.wantCT {
|
||||||
|
t.Errorf("got a Content-Type of %q; expected it to start with %q", got, tt.wantCT)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// golang.org/issue/7198
|
// golang.org/issue/7198
|
||||||
func Test500WithNoHeaders(t *testing.T) { want500Test(t, "/immediate-disconnect") }
|
func Test500WithNoHeaders(t *testing.T) { want500Test(t, "/immediate-disconnect") }
|
||||||
func Test500WithNoContentType(t *testing.T) { want500Test(t, "/no-content-type") }
|
func Test500WithNoContentType(t *testing.T) { want500Test(t, "/no-content-type") }
|
||||||
|
@ -203,6 +250,10 @@ func TestBeChildCGIProcess(t *testing.T) {
|
||||||
if req.FormValue("no-body") == "1" {
|
if req.FormValue("no-body") == "1" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if eb, ok := req.Form["exact-body"]; ok {
|
||||||
|
io.WriteString(rw, eb[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
if req.FormValue("write-forever") == "1" {
|
if req.FormValue("write-forever") == "1" {
|
||||||
io.Copy(rw, neverEnding('a'))
|
io.Copy(rw, neverEnding('a'))
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -74,10 +74,12 @@ func (r *request) parseParams() {
|
||||||
|
|
||||||
// response implements http.ResponseWriter.
|
// response implements http.ResponseWriter.
|
||||||
type response struct {
|
type response struct {
|
||||||
req *request
|
req *request
|
||||||
header http.Header
|
header http.Header
|
||||||
w *bufWriter
|
code int
|
||||||
wroteHeader bool
|
wroteHeader bool
|
||||||
|
wroteCGIHeader bool
|
||||||
|
w *bufWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
func newResponse(c *child, req *request) *response {
|
func newResponse(c *child, req *request) *response {
|
||||||
|
@ -92,11 +94,14 @@ func (r *response) Header() http.Header {
|
||||||
return r.header
|
return r.header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *response) Write(data []byte) (int, error) {
|
func (r *response) Write(p []byte) (n int, err error) {
|
||||||
if !r.wroteHeader {
|
if !r.wroteHeader {
|
||||||
r.WriteHeader(http.StatusOK)
|
r.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
return r.w.Write(data)
|
if !r.wroteCGIHeader {
|
||||||
|
r.writeCGIHeader(p)
|
||||||
|
}
|
||||||
|
return r.w.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *response) WriteHeader(code int) {
|
func (r *response) WriteHeader(code int) {
|
||||||
|
@ -104,22 +109,34 @@ func (r *response) WriteHeader(code int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.wroteHeader = true
|
r.wroteHeader = true
|
||||||
|
r.code = code
|
||||||
if code == http.StatusNotModified {
|
if code == http.StatusNotModified {
|
||||||
// Must not have body.
|
// Must not have body.
|
||||||
r.header.Del("Content-Type")
|
r.header.Del("Content-Type")
|
||||||
r.header.Del("Content-Length")
|
r.header.Del("Content-Length")
|
||||||
r.header.Del("Transfer-Encoding")
|
r.header.Del("Transfer-Encoding")
|
||||||
} else if r.header.Get("Content-Type") == "" {
|
|
||||||
r.header.Set("Content-Type", "text/html; charset=utf-8")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.header.Get("Date") == "" {
|
if r.header.Get("Date") == "" {
|
||||||
r.header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
|
r.header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Fprintf(r.w, "Status: %d %s\r\n", code, http.StatusText(code))
|
// writeCGIHeader finalizes the header sent to the client and writes it to the output.
|
||||||
|
// p is not written by writeHeader, but is the first chunk of the body
|
||||||
|
// that will be written. It is sniffed for a Content-Type if none is
|
||||||
|
// set explicitly.
|
||||||
|
func (r *response) writeCGIHeader(p []byte) {
|
||||||
|
if r.wroteCGIHeader {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.wroteCGIHeader = true
|
||||||
|
fmt.Fprintf(r.w, "Status: %d %s\r\n", r.code, http.StatusText(r.code))
|
||||||
|
if _, hasType := r.header["Content-Type"]; r.code != http.StatusNotModified && !hasType {
|
||||||
|
r.header.Set("Content-Type", http.DetectContentType(p))
|
||||||
|
}
|
||||||
r.header.Write(r.w)
|
r.header.Write(r.w)
|
||||||
r.w.WriteString("\r\n")
|
r.w.WriteString("\r\n")
|
||||||
|
r.w.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *response) Flush() {
|
func (r *response) Flush() {
|
||||||
|
@ -290,6 +307,8 @@ func (c *child) serveRequest(req *request, body io.ReadCloser) {
|
||||||
httpReq = httpReq.WithContext(envVarCtx)
|
httpReq = httpReq.WithContext(envVarCtx)
|
||||||
c.handler.ServeHTTP(r, httpReq)
|
c.handler.ServeHTTP(r, httpReq)
|
||||||
}
|
}
|
||||||
|
// Make sure we serve something even if nothing was written to r
|
||||||
|
r.Write(nil)
|
||||||
r.Close()
|
r.Close()
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
delete(c.requests, req.reqId)
|
delete(c.requests, req.reqId)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -344,3 +345,55 @@ func TestChildServeReadsEnvVars(t *testing.T) {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResponseWriterSniffsContentType(t *testing.T) {
|
||||||
|
t.Skip("this test is flaky, see Issue 41167")
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
body string
|
||||||
|
wantCT string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no body",
|
||||||
|
wantCT: "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "html",
|
||||||
|
body: "<html><head><title>test page</title></head><body>This is a body</body></html>",
|
||||||
|
wantCT: "text/html; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "text",
|
||||||
|
body: strings.Repeat("gopher", 86),
|
||||||
|
wantCT: "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jpg",
|
||||||
|
body: "\xFF\xD8\xFF" + strings.Repeat("B", 1024),
|
||||||
|
wantCT: "image/jpeg",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
input := make([]byte, len(streamFullRequestStdin))
|
||||||
|
copy(input, streamFullRequestStdin)
|
||||||
|
rc := nopWriteCloser{bytes.NewBuffer(input)}
|
||||||
|
done := make(chan bool)
|
||||||
|
var resp *response
|
||||||
|
c := newChild(rc, http.HandlerFunc(func(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
|
io.WriteString(w, tt.body)
|
||||||
|
resp = w.(*response)
|
||||||
|
done <- true
|
||||||
|
}))
|
||||||
|
defer c.cleanUp()
|
||||||
|
go c.serve()
|
||||||
|
<-done
|
||||||
|
if got := resp.Header().Get("Content-Type"); got != tt.wantCT {
|
||||||
|
t.Errorf("got a Content-Type of %q; expected it to start with %q", got, tt.wantCT)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -279,9 +279,6 @@ func (p *addrParser) parseAddressList() ([]*Address, error) {
|
||||||
if p.consume(',') {
|
if p.consume(',') {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if p.empty() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
addrs, err := p.parseAddress(true)
|
addrs, err := p.parseAddress(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -295,9 +292,17 @@ func (p *addrParser) parseAddressList() ([]*Address, error) {
|
||||||
if p.empty() {
|
if p.empty() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !p.consume(',') {
|
if p.peek() != ',' {
|
||||||
return nil, errors.New("mail: expected comma")
|
return nil, errors.New("mail: expected comma")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip empty entries for obs-addr-list.
|
||||||
|
for p.consume(',') {
|
||||||
|
p.skipSpace()
|
||||||
|
}
|
||||||
|
if p.empty() {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -445,6 +445,19 @@ func TestAddressParsing(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
` , joe@where.test,,John <jdoe@one.test>,,`,
|
||||||
|
[]*Address{
|
||||||
|
{
|
||||||
|
Name: "",
|
||||||
|
Address: "joe@where.test",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "John",
|
||||||
|
Address: "jdoe@one.test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
`Group1: <addr1@example.com>;, Group 2: addr2@example.com;, John <addr3@example.com>`,
|
`Group1: <addr1@example.com>;, Group 2: addr2@example.com;, John <addr3@example.com>`,
|
||||||
[]*Address{
|
[]*Address{
|
||||||
|
@ -1067,3 +1080,22 @@ func TestAddressFormattingAndParsing(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEmptyAddress(t *testing.T) {
|
||||||
|
parsed, err := ParseAddress("")
|
||||||
|
if parsed != nil || err == nil {
|
||||||
|
t.Errorf(`ParseAddress("") = %v, %v, want nil, error`, parsed, err)
|
||||||
|
}
|
||||||
|
list, err := ParseAddressList("")
|
||||||
|
if len(list) > 0 || err == nil {
|
||||||
|
t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err)
|
||||||
|
}
|
||||||
|
list, err = ParseAddressList(",")
|
||||||
|
if len(list) > 0 || err == nil {
|
||||||
|
t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err)
|
||||||
|
}
|
||||||
|
list, err = ParseAddressList("a@b c@d")
|
||||||
|
if len(list) > 0 || err == nil {
|
||||||
|
t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ func TestCheckPtr(t *testing.T) {
|
||||||
{"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"},
|
{"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"},
|
||||||
{"CheckPtrAlignmentNoPtr", ""},
|
{"CheckPtrAlignmentNoPtr", ""},
|
||||||
{"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
|
{"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
|
||||||
|
{"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
|
||||||
{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
|
{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
|
||||||
{"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"},
|
{"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"},
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,29 @@ func getLockRank(l *mutex) lockRank {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following functions may be called in nosplit context.
|
||||||
|
// Nosplit is not strictly required for lockWithRank, unlockWithRank
|
||||||
|
// and lockWithRankMayAcquire, but these nosplit annotations must
|
||||||
|
// be kept consistent with the equivalent functions in lockrank_on.go.
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func lockWithRank(l *mutex, rank lockRank) {
|
func lockWithRank(l *mutex, rank lockRank) {
|
||||||
lock2(l)
|
lock2(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func acquireLockRank(rank lockRank) {
|
func acquireLockRank(rank lockRank) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func unlockWithRank(l *mutex) {
|
func unlockWithRank(l *mutex) {
|
||||||
unlock2(l)
|
unlock2(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func releaseLockRank(rank lockRank) {
|
func releaseLockRank(rank lockRank) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func lockWithRankMayAcquire(l *mutex, rank lockRank) {
|
func lockWithRankMayAcquire(l *mutex, rank lockRank) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ func init() {
|
||||||
register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
|
register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
|
||||||
register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
|
register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
|
||||||
register("CheckPtrArithmetic", CheckPtrArithmetic)
|
register("CheckPtrArithmetic", CheckPtrArithmetic)
|
||||||
|
register("CheckPtrArithmetic2", CheckPtrArithmetic2)
|
||||||
register("CheckPtrSize", CheckPtrSize)
|
register("CheckPtrSize", CheckPtrSize)
|
||||||
register("CheckPtrSmall", CheckPtrSmall)
|
register("CheckPtrSmall", CheckPtrSmall)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +33,13 @@ func CheckPtrArithmetic() {
|
||||||
sink2 = (*int)(unsafe.Pointer(i))
|
sink2 = (*int)(unsafe.Pointer(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckPtrArithmetic2() {
|
||||||
|
var x [2]int64
|
||||||
|
p := unsafe.Pointer(&x[1])
|
||||||
|
var one uintptr = 1
|
||||||
|
sink2 = unsafe.Pointer(uintptr(p) & ^one)
|
||||||
|
}
|
||||||
|
|
||||||
func CheckPtrSize() {
|
func CheckPtrSize() {
|
||||||
p := new(int64)
|
p := new(int64)
|
||||||
sink2 = p
|
sink2 = p
|
||||||
|
|
|
@ -274,6 +274,7 @@ func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) {
|
||||||
e, ok = read.m[key]
|
e, ok = read.m[key]
|
||||||
if !ok && read.amended {
|
if !ok && read.amended {
|
||||||
e, ok = m.dirty[key]
|
e, ok = m.dirty[key]
|
||||||
|
delete(m.dirty, key)
|
||||||
// Regardless of whether the entry was present, record a miss: this key
|
// Regardless of whether the entry was present, record a miss: this key
|
||||||
// will take the slow path until the dirty map is promoted to the read
|
// will take the slow path until the dirty map is promoted to the read
|
||||||
// map.
|
// map.
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"testing/quick"
|
"testing/quick"
|
||||||
)
|
)
|
||||||
|
@ -171,3 +172,26 @@ func TestConcurrentRange(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue40999(t *testing.T) {
|
||||||
|
var m sync.Map
|
||||||
|
|
||||||
|
// Since the miss-counting in missLocked (via Delete)
|
||||||
|
// compares the miss count with len(m.dirty),
|
||||||
|
// add an initial entry to bias len(m.dirty) above the miss count.
|
||||||
|
m.Store(nil, struct{}{})
|
||||||
|
|
||||||
|
var finalized uint32
|
||||||
|
|
||||||
|
// Set finalizers that count for collected keys. A non-zero count
|
||||||
|
// indicates that keys have not been leaked.
|
||||||
|
for atomic.LoadUint32(&finalized) == 0 {
|
||||||
|
p := new(int)
|
||||||
|
runtime.SetFinalizer(p, func(*int) {
|
||||||
|
atomic.AddUint32(&finalized, 1)
|
||||||
|
})
|
||||||
|
m.Store(p, struct{}{})
|
||||||
|
m.Delete(p)
|
||||||
|
runtime.GC()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -357,10 +357,19 @@ func (p *testPrinter) Fprint(w io.Writer, testName, out string) {
|
||||||
defer p.lastNameMu.Unlock()
|
defer p.lastNameMu.Unlock()
|
||||||
|
|
||||||
if !p.chatty ||
|
if !p.chatty ||
|
||||||
strings.HasPrefix(out, "--- PASS") ||
|
strings.HasPrefix(out, "--- PASS: ") ||
|
||||||
strings.HasPrefix(out, "--- FAIL") ||
|
strings.HasPrefix(out, "--- FAIL: ") ||
|
||||||
strings.HasPrefix(out, "=== CONT") ||
|
strings.HasPrefix(out, "--- SKIP: ") ||
|
||||||
strings.HasPrefix(out, "=== RUN") {
|
strings.HasPrefix(out, "=== RUN ") ||
|
||||||
|
strings.HasPrefix(out, "=== CONT ") ||
|
||||||
|
strings.HasPrefix(out, "=== PAUSE ") {
|
||||||
|
// If we're buffering test output (!p.chatty), we don't really care which
|
||||||
|
// test is emitting which line so long as they are serialized.
|
||||||
|
//
|
||||||
|
// If the message already implies an association with a specific new test,
|
||||||
|
// we don't need to check what the old test name was or log an extra CONT
|
||||||
|
// line for it. (We're updating it anyway, and the current message already
|
||||||
|
// includes the test name.)
|
||||||
p.lastName = testName
|
p.lastName = testName
|
||||||
fmt.Fprint(w, out)
|
fmt.Fprint(w, out)
|
||||||
return
|
return
|
||||||
|
@ -887,11 +896,15 @@ func (c *common) Cleanup(f func()) {
|
||||||
c.cleanup = func() {
|
c.cleanup = func() {
|
||||||
if oldCleanup != nil {
|
if oldCleanup != nil {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
c.mu.Lock()
|
||||||
c.cleanupPc = oldCleanupPc
|
c.cleanupPc = oldCleanupPc
|
||||||
|
c.mu.Unlock()
|
||||||
oldCleanup()
|
oldCleanup()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
c.mu.Lock()
|
||||||
c.cleanupName = callerName(0)
|
c.cleanupName = callerName(0)
|
||||||
|
c.mu.Unlock()
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
var pc [maxStackLen]uintptr
|
var pc [maxStackLen]uintptr
|
||||||
|
@ -1012,7 +1025,13 @@ func (t *T) Parallel() {
|
||||||
for ; root.parent != nil; root = root.parent {
|
for ; root.parent != nil; root = root.parent {
|
||||||
}
|
}
|
||||||
root.mu.Lock()
|
root.mu.Lock()
|
||||||
fmt.Fprintf(root.w, "=== PAUSE %s\n", t.name)
|
// Unfortunately, even though PAUSE indicates that the named test is *no
|
||||||
|
// longer* running, cmd/test2json interprets it as changing the active test
|
||||||
|
// for the purpose of log parsing. We could fix cmd/test2json, but that
|
||||||
|
// won't fix existing deployments of third-party tools that already shell
|
||||||
|
// out to older builds of cmd/test2json — so merely fixing cmd/test2json
|
||||||
|
// isn't enough for now.
|
||||||
|
printer.Fprint(root.w, t.name, fmt.Sprintf("=== PAUSE %s\n", t.name))
|
||||||
root.mu.Unlock()
|
root.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ echo ${rev} > VERSION
|
||||||
(cd ${NEWDIR}/src && find . -name '*.go' -print) | while read f; do
|
(cd ${NEWDIR}/src && find . -name '*.go' -print) | while read f; do
|
||||||
skip=false
|
skip=false
|
||||||
case "$f" in
|
case "$f" in
|
||||||
./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* | ./cmd/vendor/golang.org/x/mod/* | ./cmd/vendor/golang.org/x/xerrors/* | ./cmd/vendor/golang.org/x/crypto/ed25519)
|
./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/test2json/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/test2json/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* | ./cmd/vendor/golang.org/x/mod/* | ./cmd/vendor/golang.org/x/xerrors/* | ./cmd/vendor/golang.org/x/crypto/ed25519)
|
||||||
;;
|
;;
|
||||||
./cmd/*)
|
./cmd/*)
|
||||||
skip=true
|
skip=true
|
||||||
|
@ -150,7 +150,7 @@ done
|
||||||
(cd ${NEWDIR}/src && find . -name testdata -print) | while read d; do
|
(cd ${NEWDIR}/src && find . -name testdata -print) | while read d; do
|
||||||
skip=false
|
skip=false
|
||||||
case "$d" in
|
case "$d" in
|
||||||
./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/diff/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/*)
|
./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/test2json/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/diff/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/test2json/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/*)
|
||||||
;;
|
;;
|
||||||
./cmd/*)
|
./cmd/*)
|
||||||
skip=true
|
skip=true
|
||||||
|
|
Loading…
Reference in New Issue