responding to review feedback
diff --git a/gocheck.go b/gocheck.go
index e6ab66c..8c727a3 100644
--- a/gocheck.go
+++ b/gocheck.go
@@ -54,15 +54,16 @@
}
type C struct {
- method *methodType
- kind funcKind
- status funcStatus
- logb logger
- logw io.Writer
- done chan *C
- reason string
- mustFail bool
- tempDir *tempDir
+ method *methodType
+ kind funcKind
+ status funcStatus
+ writeLock sync.Mutex // protects logb from concurrent writes
+ logb *bytes.Buffer
+ logw io.Writer
+ done chan *C
+ reason string
+ mustFail bool
+ tempDir *tempDir
timer
}
@@ -121,12 +122,6 @@
return path
}
-type logger interface {
- io.Writer
- io.WriterTo
- fmt.Stringer
-}
-
// -----------------------------------------------------------------------
// Low-level logging functions.
@@ -143,10 +138,12 @@
}
func (c *C) writeLog(buf []byte) {
+ c.writeLock.Lock()
c.logb.Write(buf)
if c.logw != nil {
c.logw.Write(buf)
}
+ c.writeLock.Unlock()
}
func hasStringOrError(x interface{}) (ok bool) {
@@ -590,13 +587,13 @@
// Create a call object with the given suite method, and fork a
// goroutine with the provided dispatcher for running it.
-func (runner *suiteRunner) forkCall(method *methodType, kind funcKind, logb logger, dispatcher func(c *C)) *C {
+func (runner *suiteRunner) forkCall(method *methodType, kind funcKind, logb *bytes.Buffer, dispatcher func(c *C)) *C {
var logw io.Writer
if runner.output.Stream {
logw = runner.output
}
if logb == nil {
- logb = &serialisedLogger{}
+ logb = bytes.NewBuffer(nil)
}
c := &C{
method: method,
@@ -616,32 +613,8 @@
return c
}
-// serialisedLogger serialises calls to the underlying buffer.
-type serialisedLogger struct {
- sync.Mutex
- b bytes.Buffer
-}
-
-func (l *serialisedLogger) Write(buf []byte) (int, error) {
- l.Lock()
- defer l.Unlock()
- return l.b.Write(buf)
-}
-
-func (l *serialisedLogger) WriteTo(w io.Writer) (int64, error) {
- l.Lock()
- defer l.Unlock()
- return l.b.WriteTo(w)
-}
-
-func (l *serialisedLogger) String() string {
- l.Lock()
- defer l.Unlock()
- return l.b.String()
-}
-
// Same as forkCall(), but wait for call to finish before returning.
-func (runner *suiteRunner) runFunc(method *methodType, kind funcKind, logb logger, dispatcher func(c *C)) *C {
+func (runner *suiteRunner) runFunc(method *methodType, kind funcKind, logb *bytes.Buffer, dispatcher func(c *C)) *C {
c := runner.forkCall(method, kind, logb, dispatcher)
<-c.done
return c
@@ -684,7 +657,7 @@
// goroutine like all suite methods, but this method will not return
// while the fixture goroutine is not done, because the fixture must be
// run in a desired order.
-func (runner *suiteRunner) runFixture(method *methodType, logb logger) *C {
+func (runner *suiteRunner) runFixture(method *methodType, logb *bytes.Buffer) *C {
if method != nil {
c := runner.runFunc(method, fixtureKd, logb, func(c *C) {
c.ResetTimer()
@@ -700,7 +673,7 @@
// Run the fixture method with runFixture(), but panic with a fixturePanic{}
// in case the fixture method panics. This makes it easier to track the
// fixture panic together with other call panics within forkTest().
-func (runner *suiteRunner) runFixtureWithPanic(method *methodType, logb logger, skipped *bool) *C {
+func (runner *suiteRunner) runFixtureWithPanic(method *methodType, logb *bytes.Buffer, skipped *bool) *C {
if *skipped {
return nil
}