From 23416315060bf7601e5779c3a6a2529d4d604584 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 4 Nov 2016 05:28:01 +0000 Subject: [PATCH] all: sprinkle t.Parallel on some slow tests I used the slowtests.go tool as described in https://golang.org/cl/32684 on packages that stood out. go test -short std drops from ~56 to ~52 seconds. This isn't a huge win, but it was mostly an exercise. Updates #17751 Change-Id: I9f3402e36a038d71e662d06ce2c1d52f6c4b674d Reviewed-on: https://go-review.googlesource.com/32751 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/compress/flate/deflate_test.go | 7 ++++ src/compress/flate/flate_test.go | 1 + src/compress/flate/writer_test.go | 3 ++ src/crypto/tls/handshake_client_test.go | 21 ++++++++++ src/crypto/tls/handshake_server_test.go | 2 + src/crypto/tls/tls_test.go | 1 + src/encoding/json/encode_test.go | 2 + src/encoding/json/scanner_test.go | 1 + src/go/printer/printer_test.go | 55 +++++++++++++++---------- src/log/syslog/syslog_test.go | 2 + src/mime/multipart/multipart_test.go | 2 + src/runtime/crash_cgo_test.go | 16 +++++++ src/runtime/crash_test.go | 2 + src/runtime/crash_unix_test.go | 2 + src/runtime/map_test.go | 1 + src/runtime/memmove_linux_amd64_test.go | 1 + src/runtime/memmove_test.go | 4 ++ src/runtime/runtime-gdb_test.go | 2 + 18 files changed, 103 insertions(+), 22 deletions(-) diff --git a/src/compress/flate/deflate_test.go b/src/compress/flate/deflate_test.go index 0f41695bf3..521a260365 100644 --- a/src/compress/flate/deflate_test.go +++ b/src/compress/flate/deflate_test.go @@ -342,6 +342,7 @@ func testToFromWithLimit(t *testing.T, input []byte, name string, limit [11]int) } func TestDeflateInflate(t *testing.T) { + t.Parallel() for i, h := range deflateInflateTests { testToFromWithLimit(t, h.in, fmt.Sprintf("#%d", i), [11]int{}) } @@ -376,6 +377,7 @@ var deflateInflateStringTests = []deflateInflateStringTest{ } func TestDeflateInflateString(t *testing.T) { + t.Parallel() if testing.Short() && testenv.Builder() == "" { t.Skip("skipping in short mode") } @@ -463,6 +465,7 @@ func TestRegression2508(t *testing.T) { } func TestWriterReset(t *testing.T) { + t.Parallel() for level := 0; level <= 9; level++ { if testing.Short() && level > 1 { break @@ -559,6 +562,7 @@ func testResetOutput(t *testing.T, newWriter func(w io.Writer) (*Writer, error)) // compressor.encSpeed method (0, 16, 128), as well as near maxStoreBlockSize // (65535). func TestBestSpeed(t *testing.T) { + t.Parallel() abc := make([]byte, 128) for i := range abc { abc[i] = byte(i) @@ -648,6 +652,7 @@ func (w *failWriter) Write(b []byte) (int, error) { } func TestWriterPersistentError(t *testing.T) { + t.Parallel() d, err := ioutil.ReadFile("../testdata/Mark.Twain-Tom.Sawyer.txt") if err != nil { t.Fatalf("ReadFile: %v", err) @@ -684,6 +689,7 @@ func TestWriterPersistentError(t *testing.T) { } func TestBestSpeedMatch(t *testing.T) { + t.Parallel() cases := []struct { previous, current []byte t, s, want int32 @@ -800,6 +806,7 @@ func TestBestSpeedMatch(t *testing.T) { } func TestBestSpeedMaxMatchOffset(t *testing.T) { + t.Parallel() const abc, xyz = "abcdefgh", "stuvwxyz" for _, matchBefore := range []bool{false, true} { for _, extra := range []int{0, inputMargin - 1, inputMargin, inputMargin + 1, 2 * inputMargin} { diff --git a/src/compress/flate/flate_test.go b/src/compress/flate/flate_test.go index 83c20498cc..1e45077bd5 100644 --- a/src/compress/flate/flate_test.go +++ b/src/compress/flate/flate_test.go @@ -281,6 +281,7 @@ func TestTruncatedStreams(t *testing.T) { // // See https://github.com/google/go-github/pull/317 for background. func TestReaderEarlyEOF(t *testing.T) { + t.Parallel() testSizes := []int{ 1, 2, 3, 4, 5, 6, 7, 8, 100, 1000, 10000, 100000, diff --git a/src/compress/flate/writer_test.go b/src/compress/flate/writer_test.go index 68de48b98f..c4d36aa37e 100644 --- a/src/compress/flate/writer_test.go +++ b/src/compress/flate/writer_test.go @@ -56,6 +56,7 @@ func (e *errorWriter) Write(b []byte) (int, error) { // Test if errors from the underlying writer is passed upwards. func TestWriteError(t *testing.T) { + t.Parallel() buf := new(bytes.Buffer) n := 65536 if !testing.Short() { @@ -113,6 +114,7 @@ func TestWriteError(t *testing.T) { // Test if two runs produce identical results // even when writing different sizes to the Writer. func TestDeterministic(t *testing.T) { + t.Parallel() for i := 0; i <= 9; i++ { t.Run(fmt.Sprint("L", i), func(t *testing.T) { testDeterministic(i, t) }) } @@ -120,6 +122,7 @@ func TestDeterministic(t *testing.T) { } func testDeterministic(i int, t *testing.T) { + t.Parallel() // Test so much we cross a good number of block boundaries. var length = maxStoreBlockSize*30 + 500 if testing.Short() { diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go index d603915e17..69ac15ba5f 100644 --- a/src/crypto/tls/handshake_client_test.go +++ b/src/crypto/tls/handshake_client_test.go @@ -22,6 +22,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" "testing" "time" ) @@ -420,7 +421,26 @@ func (test *clientTest) run(t *testing.T, write bool) { } } +var ( + didParMu sync.Mutex + didPar = map[*testing.T]bool{} +) + +// setParallel calls t.Parallel once. If you call it twice, it would +// panic. +func setParallel(t *testing.T) { + didParMu.Lock() + v := didPar[t] + didPar[t] = true + didParMu.Unlock() + if !v { + t.Parallel() + } +} + func runClientTestForVersion(t *testing.T, template *clientTest, prefix, option string) { + setParallel(t) + test := *template test.name = prefix + test.name if len(test.command) == 0 { @@ -1356,6 +1376,7 @@ func TestAlertFlushing(t *testing.T) { } func TestHandshakeRace(t *testing.T) { + t.Parallel() // This test races a Read and Write to try and complete a handshake in // order to provide some evidence that there are no races or deadlocks // in the handshake locking. diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go index 765a9745fc..fa93c8a8e0 100644 --- a/src/crypto/tls/handshake_server_test.go +++ b/src/crypto/tls/handshake_server_test.go @@ -660,6 +660,7 @@ func (test *serverTest) run(t *testing.T, write bool) { } func runServerTestForVersion(t *testing.T, template *serverTest, prefix, option string) { + setParallel(t) test := *template test.name = prefix + test.name if len(test.command) == 0 { @@ -1054,6 +1055,7 @@ FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd -----END EC PRIVATE KEY-----` func TestClientAuth(t *testing.T) { + setParallel(t) var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath string if *update { diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go index a0c09081a6..83b1f4ca9d 100644 --- a/src/crypto/tls/tls_test.go +++ b/src/crypto/tls/tls_test.go @@ -99,6 +99,7 @@ var keyPairTests = []struct { } func TestX509KeyPair(t *testing.T) { + t.Parallel() var pem []byte for _, test := range keyPairTests { pem = []byte(test.cert + test.key) diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index 28feeeffdf..b2c9e91dde 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -378,6 +378,7 @@ func TestDuplicatedFieldDisappears(t *testing.T) { } func TestStringBytes(t *testing.T) { + t.Parallel() // Test that encodeState.stringBytes and encodeState.string use the same encoding. var r []rune for i := '\u0000'; i <= unicode.MaxRune; i++ { @@ -616,6 +617,7 @@ var badFloatREs = []*regexp.Regexp{ } func TestMarshalFloat(t *testing.T) { + t.Parallel() nfail := 0 test := func(f float64, bits int) { vf := interface{}(f) diff --git a/src/encoding/json/scanner_test.go b/src/encoding/json/scanner_test.go index 70a28974f7..c5c1be31f1 100644 --- a/src/encoding/json/scanner_test.go +++ b/src/encoding/json/scanner_test.go @@ -119,6 +119,7 @@ func TestCompactBig(t *testing.T) { } func TestIndentBig(t *testing.T) { + t.Parallel() initBig() var buf bytes.Buffer if err := Indent(&buf, jsonBig, "", "\t"); err != nil { diff --git a/src/go/printer/printer_test.go b/src/go/printer/printer_test.go index 73f9ead5a3..0badbfba69 100644 --- a/src/go/printer/printer_test.go +++ b/src/go/printer/printer_test.go @@ -197,12 +197,17 @@ var data = []entry{ } func TestFiles(t *testing.T) { + t.Parallel() for _, e := range data { source := filepath.Join(dataDir, e.source) golden := filepath.Join(dataDir, e.golden) - check(t, source, golden, e.mode) - // TODO(gri) check that golden is idempotent - //check(t, golden, golden, e.mode) + mode := e.mode + t.Run(e.source, func(t *testing.T) { + t.Parallel() + check(t, source, golden, mode) + // TODO(gri) check that golden is idempotent + //check(t, golden, golden, e.mode) + }) } } @@ -295,6 +300,7 @@ func testComment(t *testing.T, f *ast.File, srclen int, comment *ast.Comment) { // even if the position information of comments introducing newlines // is incorrect. func TestBadComments(t *testing.T) { + t.Parallel() const src = ` // first comment - text and position changed by test package p @@ -481,6 +487,7 @@ func TestStmtLists(t *testing.T) { } func TestBaseIndent(t *testing.T) { + t.Parallel() // The testfile must not contain multi-line raw strings since those // are not indented (because their values must not change) and make // this test fail. @@ -495,28 +502,31 @@ func TestBaseIndent(t *testing.T) { panic(err) // error in test } - var buf bytes.Buffer for indent := 0; indent < 4; indent++ { - buf.Reset() - (&Config{Tabwidth: tabwidth, Indent: indent}).Fprint(&buf, fset, file) - // all code must be indented by at least 'indent' tabs - lines := bytes.Split(buf.Bytes(), []byte{'\n'}) - for i, line := range lines { - if len(line) == 0 { - continue // empty lines don't have indentation - } - n := 0 - for j, b := range line { - if b != '\t' { - // end of indentation - n = j - break + indent := indent + t.Run(fmt.Sprint(indent), func(t *testing.T) { + t.Parallel() + var buf bytes.Buffer + (&Config{Tabwidth: tabwidth, Indent: indent}).Fprint(&buf, fset, file) + // all code must be indented by at least 'indent' tabs + lines := bytes.Split(buf.Bytes(), []byte{'\n'}) + for i, line := range lines { + if len(line) == 0 { + continue // empty lines don't have indentation + } + n := 0 + for j, b := range line { + if b != '\t' { + // end of indentation + n = j + break + } + } + if n < indent { + t.Errorf("line %d: got only %d tabs; want at least %d: %q", i, n, indent, line) } } - if n < indent { - t.Errorf("line %d: got only %d tabs; want at least %d: %q", i, n, indent, line) - } - } + }) } } @@ -567,6 +577,7 @@ func (l *limitWriter) Write(buf []byte) (n int, err error) { // Test whether the printer stops writing after the first error func TestWriteErrors(t *testing.T) { + t.Parallel() const filename = "printer.go" src, err := ioutil.ReadFile(filename) if err != nil { diff --git a/src/log/syslog/syslog_test.go b/src/log/syslog/syslog_test.go index 52363f9f7c..5df0e47271 100644 --- a/src/log/syslog/syslog_test.go +++ b/src/log/syslog/syslog_test.go @@ -134,6 +134,7 @@ func startServer(n, la string, done chan<- string) (addr string, sock io.Closer, } func TestWithSimulated(t *testing.T) { + t.Parallel() msg := "Test 123" var transport []string for _, n := range []string{"unix", "unixgram", "udp", "tcp"} { @@ -262,6 +263,7 @@ func check(t *testing.T, in, out string) { } func TestWrite(t *testing.T) { + t.Parallel() tests := []struct { pri Priority pre string diff --git a/src/mime/multipart/multipart_test.go b/src/mime/multipart/multipart_test.go index 82a7f86e67..d74ef61b88 100644 --- a/src/mime/multipart/multipart_test.go +++ b/src/mime/multipart/multipart_test.go @@ -125,6 +125,7 @@ func TestMultipartSlowInput(t *testing.T) { } func testMultipart(t *testing.T, r io.Reader, onlyNewlines bool) { + t.Parallel() reader := NewReader(r, "MyBoundary") buf := new(bytes.Buffer) @@ -755,6 +756,7 @@ func partsFromReader(r *Reader) ([]headerBody, error) { } func TestParseAllSizes(t *testing.T) { + t.Parallel() const maxSize = 5 << 10 var buf bytes.Buffer body := strings.Repeat("a", maxSize) diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index 34d1f0594a..7014f119ad 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -19,10 +19,12 @@ import ( ) func TestCgoCrashHandler(t *testing.T) { + t.Parallel() testCrashHandler(t, true) } func TestCgoSignalDeadlock(t *testing.T) { + t.Parallel() if testing.Short() && runtime.GOOS == "windows" { t.Skip("Skipping in short mode") // takes up to 64 seconds } @@ -34,6 +36,7 @@ func TestCgoSignalDeadlock(t *testing.T) { } func TestCgoTraceback(t *testing.T) { + t.Parallel() got := runTestProg(t, "testprogcgo", "CgoTraceback") want := "OK\n" if got != want { @@ -42,6 +45,7 @@ func TestCgoTraceback(t *testing.T) { } func TestCgoCallbackGC(t *testing.T) { + t.Parallel() switch runtime.GOOS { case "plan9", "windows": t.Skipf("no pthreads on %s", runtime.GOOS) @@ -66,6 +70,7 @@ func TestCgoCallbackGC(t *testing.T) { } func TestCgoExternalThreadPanic(t *testing.T) { + t.Parallel() if runtime.GOOS == "plan9" { t.Skipf("no pthreads on %s", runtime.GOOS) } @@ -77,6 +82,7 @@ func TestCgoExternalThreadPanic(t *testing.T) { } func TestCgoExternalThreadSIGPROF(t *testing.T) { + t.Parallel() // issue 9456. switch runtime.GOOS { case "plan9", "windows": @@ -117,6 +123,7 @@ func TestCgoExternalThreadSIGPROF(t *testing.T) { } func TestCgoExternalThreadSignal(t *testing.T) { + t.Parallel() // issue 10139 switch runtime.GOOS { case "plan9", "windows": @@ -152,6 +159,7 @@ func TestCgoDLLImports(t *testing.T) { } func TestCgoExecSignalMask(t *testing.T) { + t.Parallel() // Test issue 13164. switch runtime.GOOS { case "windows", "plan9": @@ -165,6 +173,7 @@ func TestCgoExecSignalMask(t *testing.T) { } func TestEnsureDropM(t *testing.T) { + t.Parallel() // Test for issue 13881. switch runtime.GOOS { case "windows", "plan9": @@ -181,6 +190,7 @@ func TestEnsureDropM(t *testing.T) { // Test that the program that doesn't need any cgo pointer checking // takes about the same amount of time with it as without it. func TestCgoCheckBytes(t *testing.T) { + t.Parallel() // Make sure we don't count the build time as part of the run time. testenv.MustHaveGoBuild(t) exe, err := buildTestProg(t, "testprogcgo") @@ -220,6 +230,7 @@ func TestCgoCheckBytes(t *testing.T) { } func TestCgoPanicDeadlock(t *testing.T) { + t.Parallel() // test issue 14432 got := runTestProg(t, "testprogcgo", "CgoPanicDeadlock") want := "panic: cgo error\n\n" @@ -229,6 +240,7 @@ func TestCgoPanicDeadlock(t *testing.T) { } func TestCgoCCodeSIGPROF(t *testing.T) { + t.Parallel() got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF") want := "OK\n" if got != want { @@ -237,6 +249,7 @@ func TestCgoCCodeSIGPROF(t *testing.T) { } func TestCgoCrashTraceback(t *testing.T) { + t.Parallel() if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) } @@ -249,6 +262,7 @@ func TestCgoCrashTraceback(t *testing.T) { } func TestCgoTracebackContext(t *testing.T) { + t.Parallel() got := runTestProg(t, "testprogcgo", "TracebackContext") want := "OK\n" if got != want { @@ -257,6 +271,7 @@ func TestCgoTracebackContext(t *testing.T) { } func testCgoPprof(t *testing.T, buildArg, runArg string) { + t.Parallel() if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) } @@ -344,6 +359,7 @@ func TestRaceProf(t *testing.T) { } func TestRaceSignal(t *testing.T) { + t.Parallel() if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) } diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go index 1db0461242..1f7aa521e1 100644 --- a/src/runtime/crash_test.go +++ b/src/runtime/crash_test.go @@ -401,6 +401,7 @@ func TestRecoverBeforePanicAfterGoexit(t *testing.T) { } func TestNetpollDeadlock(t *testing.T) { + t.Parallel() output := runTestProg(t, "testprognet", "NetpollDeadlock") want := "done\n" if !strings.HasSuffix(output, want) { @@ -409,6 +410,7 @@ func TestNetpollDeadlock(t *testing.T) { } func TestPanicTraceback(t *testing.T) { + t.Parallel() output := runTestProg(t, "testprog", "PanicTraceback") want := "panic: hello" if !strings.HasPrefix(output, want) { diff --git a/src/runtime/crash_unix_test.go b/src/runtime/crash_unix_test.go index 12415d1995..97deed8b9d 100644 --- a/src/runtime/crash_unix_test.go +++ b/src/runtime/crash_unix_test.go @@ -37,6 +37,8 @@ func TestCrashDumpsAllThreads(t *testing.T) { checkStaleRuntime(t) + t.Parallel() + dir, err := ioutil.TempDir("", "go-build") if err != nil { t.Fatalf("failed to create temp directory: %v", err) diff --git a/src/runtime/map_test.go b/src/runtime/map_test.go index 496f8e8868..aacd091853 100644 --- a/src/runtime/map_test.go +++ b/src/runtime/map_test.go @@ -235,6 +235,7 @@ func TestIterGrowWithGC(t *testing.T) { } func testConcurrentReadsAfterGrowth(t *testing.T, useReflect bool) { + t.Parallel() if runtime.GOMAXPROCS(-1) == 1 { defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(16)) } diff --git a/src/runtime/memmove_linux_amd64_test.go b/src/runtime/memmove_linux_amd64_test.go index b69e8fc8de..d0e8b42a5a 100644 --- a/src/runtime/memmove_linux_amd64_test.go +++ b/src/runtime/memmove_linux_amd64_test.go @@ -16,6 +16,7 @@ import ( // TestMemmoveOverflow maps 3GB of memory and calls memmove on // the corresponding slice. func TestMemmoveOverflow(t *testing.T) { + t.Parallel() // Create a temporary file. tmp, err := ioutil.TempFile("", "go-memmovetest") if err != nil { diff --git a/src/runtime/memmove_test.go b/src/runtime/memmove_test.go index 080ca28667..dbfa284c28 100644 --- a/src/runtime/memmove_test.go +++ b/src/runtime/memmove_test.go @@ -13,6 +13,7 @@ import ( ) func TestMemmove(t *testing.T) { + t.Parallel() size := 256 if testing.Short() { size = 128 + 16 @@ -51,6 +52,7 @@ func TestMemmove(t *testing.T) { } func TestMemmoveAlias(t *testing.T) { + t.Parallel() size := 256 if testing.Short() { size = 128 + 16 @@ -85,6 +87,7 @@ func TestMemmoveAlias(t *testing.T) { } func TestMemmoveLarge0x180000(t *testing.T) { + t.Parallel() if race.Enabled { t.Skip("skipping large memmove test under race detector") } @@ -92,6 +95,7 @@ func TestMemmoveLarge0x180000(t *testing.T) { } func TestMemmoveOverlapLarge0x120000(t *testing.T) { + t.Parallel() if race.Enabled { t.Skip("skipping large memmove test under race detector") } diff --git a/src/runtime/runtime-gdb_test.go b/src/runtime/runtime-gdb_test.go index 3f2d74248b..06e61e9ced 100644 --- a/src/runtime/runtime-gdb_test.go +++ b/src/runtime/runtime-gdb_test.go @@ -84,6 +84,7 @@ func main() { ` func TestGdbPython(t *testing.T) { + t.Parallel() checkGdbEnvironment(t) checkGdbVersion(t) checkGdbPython(t) @@ -218,6 +219,7 @@ func main() { // TestGdbBacktrace tests that gdb can unwind the stack correctly // using only the DWARF debug info. func TestGdbBacktrace(t *testing.T) { + t.Parallel() checkGdbEnvironment(t) checkGdbVersion(t) -- 2.48.1