libgo: Update to weekly.2011-12-22.

From-SVN: r183150
This commit is contained in:
Ian Lance Taylor 2012-01-13 05:11:45 +00:00
parent f83fa0bf8f
commit df4aa89a5e
195 changed files with 3634 additions and 1287 deletions

View file

@ -23,8 +23,8 @@
// }
// The benchmark package will vary b.N until the benchmark function lasts
// long enough to be timed reliably. The output
// testing.BenchmarkHello 500000 4076 ns/op
// means that the loop ran 500000 times at a speed of 4076 ns per loop.
// testing.BenchmarkHello 10000000 282 ns/op
// means that the loop ran 10000000 times at a speed of 282 ns per loop.
//
// If a benchmark needs some expensive setup before running, the timer
// may be stopped:
@ -70,6 +70,17 @@ var (
cpuList []int
)
// common holds the elements common between T and B and
// captures common methods such as Errorf.
type common struct {
output []byte // Output generated by test or benchmark.
failed bool // Test or benchmark has failed.
start time.Time // Time test or benchmark started
duration time.Duration
self interface{} // To be sent on signal channel when done.
signal chan interface{} // Output for serial tests.
}
// Short reports whether the -test.short flag is set.
func Short() bool {
return *short
@ -79,7 +90,7 @@ func Short() bool {
// If addFileLine is true, it also prefixes the string with the file and line of the call site.
func decorate(s string, addFileLine bool) string {
if addFileLine {
_, file, line, ok := runtime.Caller(3) // decorate + log + public function.
_, file, line, ok := runtime.Caller(4) // decorate + log + public function.
if ok {
// Truncate file name at last file name separator.
if index := strings.LastIndex(file, "/"); index >= 0 {
@ -111,70 +122,68 @@ func decorate(s string, addFileLine bool) string {
// T is a type passed to Test functions to manage test state and support formatted test logs.
// Logs are accumulated during execution and dumped to standard error when done.
type T struct {
name string // Name of test.
errors string // Error string from test.
failed bool // Test has failed.
ch chan *T // Output for serial tests.
startParallel chan bool // Parallel tests will wait on this.
start time.Time // Time test started
dt time.Duration // Length of test
common
name string // Name of test.
startParallel chan bool // Parallel tests will wait on this.
}
// Fail marks the Test function as having failed but continues execution.
func (t *T) Fail() { t.failed = true }
// Fail marks the function as having failed but continues execution.
func (c *common) Fail() { c.failed = true }
// Failed returns whether the Test function has failed.
func (t *T) Failed() bool { return t.failed }
// Failed returns whether the function has failed.
func (c *common) Failed() bool { return c.failed }
// FailNow marks the Test function as having failed and stops its execution.
// FailNow marks the function as having failed and stops its execution.
// Execution will continue at the next Test.
func (t *T) FailNow() {
t.dt = time.Now().Sub(t.start)
t.Fail()
t.ch <- t
func (c *common) FailNow() {
c.duration = time.Now().Sub(c.start)
c.Fail()
c.signal <- c.self
runtime.Goexit()
}
// log generates the output. It's always at the same stack depth.
func (t *T) log(s string) { t.errors += decorate(s, true) }
func (c *common) log(s string) {
c.output = append(c.output, decorate(s, true)...)
}
// Log formats its arguments using default formatting, analogous to Print(),
// Log formats its arguments using default formatting, analogous to Println(),
// and records the text in the error log.
func (t *T) Log(args ...interface{}) { t.log(fmt.Sprintln(args...)) }
func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) }
// Logf formats its arguments according to the format, analogous to Printf(),
// and records the text in the error log.
func (t *T) Logf(format string, args ...interface{}) { t.log(fmt.Sprintf(format, args...)) }
func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) }
// Error is equivalent to Log() followed by Fail().
func (t *T) Error(args ...interface{}) {
t.log(fmt.Sprintln(args...))
t.Fail()
func (c *common) Error(args ...interface{}) {
c.log(fmt.Sprintln(args...))
c.Fail()
}
// Errorf is equivalent to Logf() followed by Fail().
func (t *T) Errorf(format string, args ...interface{}) {
t.log(fmt.Sprintf(format, args...))
t.Fail()
func (c *common) Errorf(format string, args ...interface{}) {
c.log(fmt.Sprintf(format, args...))
c.Fail()
}
// Fatal is equivalent to Log() followed by FailNow().
func (t *T) Fatal(args ...interface{}) {
t.log(fmt.Sprintln(args...))
t.FailNow()
func (c *common) Fatal(args ...interface{}) {
c.log(fmt.Sprintln(args...))
c.FailNow()
}
// Fatalf is equivalent to Logf() followed by FailNow().
func (t *T) Fatalf(format string, args ...interface{}) {
t.log(fmt.Sprintf(format, args...))
t.FailNow()
func (c *common) Fatalf(format string, args ...interface{}) {
c.log(fmt.Sprintf(format, args...))
c.FailNow()
}
// Parallel signals that this test is to be run in parallel with (and only with)
// other parallel tests in this CPU group.
func (t *T) Parallel() {
t.ch <- nil // Release main testing loop
<-t.startParallel // Wait for serial tests to finish
t.signal <- (*T)(nil) // Release main testing loop
<-t.startParallel // Wait for serial tests to finish
}
// An internal type but exported because it is cross-package; part of the implementation
@ -187,8 +196,8 @@ type InternalTest struct {
func tRunner(t *T, test *InternalTest) {
t.start = time.Now()
test.F(t)
t.dt = time.Now().Sub(t.start)
t.ch <- t
t.duration = time.Now().Sub(t.start)
t.signal <- t
}
// An internal function but exported because it is cross-package; part of the implementation
@ -211,13 +220,13 @@ func Main(matchString func(pat, str string) (bool, error), tests []InternalTest,
after()
}
func report(t *T) {
tstr := fmt.Sprintf("(%.2f seconds)", t.dt.Seconds())
func (t *T) report() {
tstr := fmt.Sprintf("(%.2f seconds)", t.duration.Seconds())
format := "--- %s: %s %s\n%s"
if t.failed {
fmt.Printf(format, "FAIL", t.name, tstr, t.errors)
fmt.Printf(format, "FAIL", t.name, tstr, t.output)
} else if *chatty {
fmt.Printf(format, "PASS", t.name, tstr, t.errors)
fmt.Printf(format, "PASS", t.name, tstr, t.output)
}
}
@ -227,9 +236,14 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
return
}
ch := make(chan *T)
for _, procs := range cpuList {
runtime.GOMAXPROCS(procs)
// We build a new channel tree for each run of the loop.
// collector merges in one channel all the upstream signals from parallel tests.
// If all tests pump to the same channel, a bug can occur where a test
// kicks off a goroutine that Fails, yet the test still delivers a completion signal,
// which skews the counting.
var collector = make(chan interface{})
numParallel := 0
startParallel := make(chan bool)
@ -247,17 +261,27 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
if procs != 1 {
testName = fmt.Sprintf("%s-%d", tests[i].Name, procs)
}
t := &T{ch: ch, name: testName, startParallel: startParallel}
t := &T{
common: common{
signal: make(chan interface{}),
},
name: testName,
startParallel: startParallel,
}
t.self = t
if *chatty {
fmt.Printf("=== RUN %s\n", t.name)
}
go tRunner(t, &tests[i])
out := <-t.ch
out := (<-t.signal).(*T)
if out == nil { // Parallel run.
go func() {
collector <- <-t.signal
}()
numParallel++
continue
}
report(t)
t.report()
ok = ok && !out.failed
}
@ -269,8 +293,8 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
numParallel--
continue
}
t := <-ch
report(t)
t := (<-collector).(*T)
t.report()
ok = ok && !t.failed
running--
}