Skip to content

Commit

Permalink
runtime: move test programs out of source code, coalesce
Browse files Browse the repository at this point in the history
Now there are just three programs to compile instead of many,
and repeated tests can reuse the compilation result instead of
rebuilding it.

Combined, these changes reduce the time spent testing runtime
during all.bash on my laptop from about 60 to about 30 seconds.
(All.bash itself runs in 5½ minutes.)

For #10571.

Change-Id: Ie2c1798b847f1a635a860d11dcdab14375319ae9
Reviewed-on: https://go-review.googlesource.com/18085
Reviewed-by: Austin Clements <[email protected]>
Run-TryBot: Austin Clements <[email protected]>
  • Loading branch information
rsc committed Dec 29, 2015
1 parent a699320 commit 8d5ff2e
Show file tree
Hide file tree
Showing 24 changed files with 991 additions and 817 deletions.
390 changes: 12 additions & 378 deletions src/runtime/crash_cgo_test.go

Large diffs are not rendered by default.

399 changes: 81 additions & 318 deletions src/runtime/crash_test.go

Large diffs are not rendered by default.

48 changes: 1 addition & 47 deletions src/runtime/gc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,13 @@ func TestGcSys(t *testing.T) {
if os.Getenv("GOGC") == "off" {
t.Skip("skipping test; GOGC=off in environment")
}
data := struct{ Short bool }{testing.Short()}
got := executeTest(t, testGCSysSource, &data)
got := runTestProg(t, "testprog", "GCSys")
want := "OK\n"
if got != want {
t.Fatalf("expected %q, but got %q", want, got)
}
}

const testGCSysSource = `
package main
import (
"fmt"
"runtime"
)
func main() {
runtime.GOMAXPROCS(1)
memstats := new(runtime.MemStats)
runtime.GC()
runtime.ReadMemStats(memstats)
sys := memstats.Sys
runtime.MemProfileRate = 0 // disable profiler
itercount := 1000000
{{if .Short}}
itercount = 100000
{{end}}
for i := 0; i < itercount; i++ {
workthegc()
}
// Should only be using a few MB.
// We allocated 100 MB or (if not short) 1 GB.
runtime.ReadMemStats(memstats)
if sys > memstats.Sys {
sys = 0
} else {
sys = memstats.Sys - sys
}
if sys > 16<<20 {
fmt.Printf("using too much memory: %d bytes\n", sys)
return
}
fmt.Printf("OK\n")
}
func workthegc() []byte {
return make([]byte, 1029)
}
`

func TestGcDeepNesting(t *testing.T) {
type T [2][2][2][2][2][2][2][2][2][2]*int
a := new(T)
Expand Down
37 changes: 1 addition & 36 deletions src/runtime/proc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,48 +329,13 @@ func TestPreemptionGC(t *testing.T) {
}

func TestGCFairness(t *testing.T) {
output := executeTest(t, testGCFairnessSource, nil)
output := runTestProg(t, "testprog", "GCFairness")
want := "OK\n"
if output != want {
t.Fatalf("want %s, got %s\n", want, output)
}
}

const testGCFairnessSource = `
package main
import (
"fmt"
"os"
"runtime"
"time"
)
func main() {
runtime.GOMAXPROCS(1)
f, err := os.Open("/dev/null")
if os.IsNotExist(err) {
// This test tests what it is intended to test only if writes are fast.
// If there is no /dev/null, we just don't execute the test.
fmt.Println("OK")
return
}
if err != nil {
fmt.Println(err)
os.Exit(1)
}
for i := 0; i < 2; i++ {
go func() {
for {
f.Write([]byte("."))
}
}()
}
time.Sleep(10 * time.Millisecond)
fmt.Println("OK")
}
`

func TestPingPongHog(t *testing.T) {
if testing.Short() {
t.Skip("skipping in -short mode")
Expand Down
15 changes: 1 addition & 14 deletions src/runtime/string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,27 +125,14 @@ func TestStringW(t *testing.T) {
}

func TestLargeStringConcat(t *testing.T) {
output := executeTest(t, largeStringConcatSource, nil)
output := runTestProg(t, "testprog", "stringconcat")
want := "panic: " + strings.Repeat("0", 1<<10) + strings.Repeat("1", 1<<10) +
strings.Repeat("2", 1<<10) + strings.Repeat("3", 1<<10)
if !strings.HasPrefix(output, want) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
}

var largeStringConcatSource = `
package main
import "strings"
func main() {
s0 := strings.Repeat("0", 1<<10)
s1 := strings.Repeat("1", 1<<10)
s2 := strings.Repeat("2", 1<<10)
s3 := strings.Repeat("3", 1<<10)
s := s0 + s1 + s2 + s3
panic(s)
}
`

func TestGostringnocopy(t *testing.T) {
max := *runtime.Maxstring
b := make([]byte, max+10)
Expand Down
26 changes: 2 additions & 24 deletions src/runtime/syscall_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ func TestOutputDebugString(t *testing.T) {
}

func TestRaiseException(t *testing.T) {
o := executeTest(t, raiseExceptionSource, nil)
o := runTestProg(t, "testprog", "RaiseException")
if strings.Contains(o, "RaiseException should not return") {
t.Fatalf("RaiseException did not crash program: %v", o)
}
Expand All @@ -509,35 +509,13 @@ func TestRaiseException(t *testing.T) {
}
}

const raiseExceptionSource = `
package main
import "syscall"
func main() {
const EXCEPTION_NONCONTINUABLE = 1
mod := syscall.MustLoadDLL("kernel32.dll")
proc := mod.MustFindProc("RaiseException")
proc.Call(0xbad, EXCEPTION_NONCONTINUABLE, 0, 0)
println("RaiseException should not return")
}
`

func TestZeroDivisionException(t *testing.T) {
o := executeTest(t, zeroDivisionExceptionSource, nil)
o := runTestProg(t, "testprog", "ZeroDivisionException")
if !strings.Contains(o, "panic: runtime error: integer divide by zero") {
t.Fatalf("No stack trace: %v", o)
}
}

const zeroDivisionExceptionSource = `
package main
func main() {
x := 1
y := 0
z := x / y
println(z)
}
`

func TestWERDialogue(t *testing.T) {
if os.Getenv("TESTING_WER_DIALOGUE") == "1" {
defer os.Exit(0)
Expand Down
45 changes: 45 additions & 0 deletions src/runtime/testdata/testprog/crash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
"fmt"
"runtime"
)

func init() {
register("Crash", Crash)
}

func test(name string) {
defer func() {
if x := recover(); x != nil {
fmt.Printf(" recovered")
}
fmt.Printf(" done\n")
}()
fmt.Printf("%s:", name)
var s *string
_ = *s
fmt.Print("SHOULD NOT BE HERE")
}

func testInNewThread(name string) {
c := make(chan bool)
go func() {
runtime.LockOSThread()
test(name)
c <- true
}()
<-c
}

func Crash() {
runtime.LockOSThread()
test("main")
testInNewThread("new-thread")
testInNewThread("second-new-thread")
test("main-again")
}
Loading

0 comments on commit 8d5ff2e

Please sign in to comment.