Update dependencies

- uses newer version of go-ethereum required for go1.11
This commit is contained in:
Rob Mulholand
2018-09-13 16:14:35 -05:00
parent 939ead0c82
commit 560305f601
2356 changed files with 331656 additions and 128304 deletions
+2 -1
View File
@@ -1,11 +1,12 @@
package codelocation_test
import (
"runtime"
. "github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/internal/codelocation"
"github.com/onsi/ginkgo/types"
. "github.com/onsi/gomega"
"runtime"
)
var _ = Describe("CodeLocation", func() {
@@ -1,9 +1,10 @@
package containernode_test
import (
"github.com/onsi/ginkgo/internal/leafnodes"
"math/rand"
"github.com/onsi/ginkgo/internal/leafnodes"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+2 -2
View File
@@ -35,15 +35,15 @@ func (b *benchmarker) Time(name string, body func(), info ...interface{}) (elaps
}
func (b *benchmarker) RecordValue(name string, value float64, info ...interface{}) {
measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", "", 3, info...)
b.mu.Lock()
measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", "", 3, info...)
defer b.mu.Unlock()
measurement.Results = append(measurement.Results, value)
}
func (b *benchmarker) RecordValueWithPrecision(name string, value float64, units string, precision int, info ...interface{}) {
measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", units, precision, info...)
b.mu.Lock()
measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", units, precision, info...)
defer b.mu.Unlock()
measurement.Results = append(measurement.Results, value)
}
+2 -1
View File
@@ -1,9 +1,10 @@
package leafnodes
import (
"time"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"time"
)
type ItNode struct {
+2 -1
View File
@@ -1,9 +1,10 @@
package leafnodes
import (
"reflect"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"reflect"
)
type MeasureNode struct {
+12 -11
View File
@@ -5,10 +5,11 @@ import (
. "github.com/onsi/ginkgo/internal/leafnodes"
. "github.com/onsi/gomega"
"time"
"github.com/onsi/ginkgo/internal/codelocation"
Failer "github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"time"
)
var _ = Describe("Measure Nodes", func() {
@@ -119,13 +120,13 @@ var _ = Describe("Measure Nodes", func() {
BeforeEach(func() {
measure = NewMeasureNode("the measurement", func(b Benchmarker) {
b.Time("foo", func() {
time.Sleep(100 * time.Millisecond)
time.Sleep(200 * time.Millisecond)
}, "info!")
b.Time("foo", func() {
time.Sleep(200 * time.Millisecond)
time.Sleep(300 * time.Millisecond)
})
b.Time("foo", func() {
time.Sleep(170 * time.Millisecond)
time.Sleep(250 * time.Millisecond)
})
}, types.FlagTypeFocused, codelocation.New(0), 1, Failer.New(), 3)
Ω(measure.Run()).Should(Equal(types.SpecStatePassed))
@@ -141,13 +142,13 @@ var _ = Describe("Measure Nodes", func() {
Ω(report["foo"].AverageLabel).Should(Equal("Average Time"))
Ω(report["foo"].Units).Should(Equal("s"))
Ω(report["foo"].Results).Should(HaveLen(3))
Ω(report["foo"].Results[0]).Should(BeNumerically("~", 0.1, 0.01))
Ω(report["foo"].Results[1]).Should(BeNumerically("~", 0.2, 0.01))
Ω(report["foo"].Results[2]).Should(BeNumerically("~", 0.17, 0.01))
Ω(report["foo"].Smallest).Should(BeNumerically("~", 0.1, 0.01))
Ω(report["foo"].Largest).Should(BeNumerically("~", 0.2, 0.01))
Ω(report["foo"].Average).Should(BeNumerically("~", 0.16, 0.01))
Ω(report["foo"].StdDeviation).Should(BeNumerically("~", 0.04, 0.01))
Ω(report["foo"].Results[0]).Should(BeNumerically("~", 0.2, 0.06))
Ω(report["foo"].Results[1]).Should(BeNumerically("~", 0.3, 0.06))
Ω(report["foo"].Results[2]).Should(BeNumerically("~", 0.25, 0.06))
Ω(report["foo"].Smallest).Should(BeNumerically("~", 0.2, 0.06))
Ω(report["foo"].Largest).Should(BeNumerically("~", 0.3, 0.06))
Ω(report["foo"].Average).Should(BeNumerically("~", 0.25, 0.06))
Ω(report["foo"].StdDeviation).Should(BeNumerically("~", 0.07, 0.04))
})
})
})
+6 -2
View File
@@ -2,11 +2,12 @@ package leafnodes
import (
"fmt"
"reflect"
"time"
"github.com/onsi/ginkgo/internal/codelocation"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"reflect"
"time"
)
type runner struct {
@@ -86,6 +87,9 @@ func (r *runner) runAsync() (outcome types.SpecState, failure types.SpecFailure)
finished = true
}()
// If this goroutine gets no CPU time before the select block,
// the <-done case may complete even if the test took longer than the timeoutThreshold.
// This can cause flaky behaviour, but we haven't seen it in the wild.
select {
case <-done:
case <-time.After(r.timeoutThreshold):
+2 -1
View File
@@ -1,9 +1,10 @@
package leafnodes
import (
"time"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"time"
)
type SetupNode struct {
+3 -6
View File
@@ -179,8 +179,8 @@ func AsynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time
didRun = true
failer.Fail("bam", innerCodeLocation)
time.Sleep(20 * time.Millisecond)
defer close(done)
panic("doesn't matter")
close(done)
}, 10*time.Millisecond, failer, componentCodeLocation).Run()
})
@@ -199,21 +199,18 @@ func AsynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time
})
})
Context("when the function times out", func() {
Context("when the function doesn't close the done channel in time", func() {
var guard chan struct{}
BeforeEach(func() {
guard = make(chan struct{})
outcome, failure = build(func(done Done) {
didRun = true
time.Sleep(20 * time.Millisecond)
close(guard)
panic("doesn't matter")
close(done)
}, 10*time.Millisecond, failer, componentCodeLocation).Run()
})
It("should return the timeout", func() {
It("should return a timeout", func() {
<-guard
Ω(didRun).Should(BeTrue())
+2 -1
View File
@@ -1,9 +1,10 @@
package leafnodes
import (
"time"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"time"
)
type SuiteNode interface {
@@ -2,11 +2,12 @@ package leafnodes
import (
"encoding/json"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"io/ioutil"
"net/http"
"time"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
)
type synchronizedAfterSuiteNode struct {
@@ -1,18 +1,21 @@
package leafnodes_test
import (
"sync"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/internal/leafnodes"
"github.com/onsi/ginkgo/types"
. "github.com/onsi/gomega"
"sync"
"net/http"
"github.com/onsi/gomega/ghttp"
"net/http"
"time"
"github.com/onsi/ginkgo/internal/codelocation"
Failer "github.com/onsi/ginkgo/internal/failer"
"time"
)
var _ = Describe("SynchronizedAfterSuiteNode", func() {
@@ -132,19 +135,19 @@ var _ = Describe("SynchronizedAfterSuiteNode", func() {
func(writer http.ResponseWriter, request *http.Request) {
ranThing("Request1")
},
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{false}),
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{CanRun: false}),
), ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"),
func(writer http.ResponseWriter, request *http.Request) {
ranThing("Request2")
},
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{false}),
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{CanRun: false}),
), ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"),
func(writer http.ResponseWriter, request *http.Request) {
ranThing("Request3")
},
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{true}),
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{CanRun: true}),
))
node = newNode(func() {
@@ -3,12 +3,13 @@ package leafnodes
import (
"bytes"
"encoding/json"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"io/ioutil"
"net/http"
"reflect"
"time"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
)
type synchronizedBeforeSuiteNode struct {
@@ -109,8 +110,6 @@ func (node *synchronizedBeforeSuiteNode) waitForA(syncHost string) (types.SpecSt
time.Sleep(50 * time.Millisecond)
}
return types.SpecStateFailed, failure("Shouldn't get here!")
}
func (node *synchronizedBeforeSuiteNode) Passed() bool {
@@ -5,13 +5,15 @@ import (
. "github.com/onsi/ginkgo/internal/leafnodes"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/ghttp"
"net/http"
"github.com/onsi/gomega/ghttp"
"time"
"github.com/onsi/ginkgo/internal/codelocation"
Failer "github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/types"
"time"
)
var _ = Describe("SynchronizedBeforeSuiteNode", func() {
@@ -176,7 +178,7 @@ var _ = Describe("SynchronizedBeforeSuiteNode", func() {
Context("when A succeeds", func() {
BeforeEach(func() {
expectedState = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStatePassed}
expectedState = types.RemoteBeforeSuiteData{Data: []byte("my data"), State: types.RemoteBeforeSuiteStatePassed}
node = newNode(func() []byte {
return []byte("my data")
@@ -200,11 +202,10 @@ var _ = Describe("SynchronizedBeforeSuiteNode", func() {
Context("when A fails", func() {
BeforeEach(func() {
expectedState = types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStateFailed}
expectedState = types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStateFailed}
node = newNode(func() []byte {
panic("BAM")
return []byte("my data")
}, func([]byte) {
ranB = true
})
@@ -238,10 +239,10 @@ var _ = Describe("SynchronizedBeforeSuiteNode", func() {
server.AppendHandlers(ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/BeforeSuiteState"),
ghttp.RespondWith(http.StatusOK, string((types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}).ToJSON())),
ghttp.RespondWith(http.StatusOK, string((types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending}).ToJSON())),
), ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/BeforeSuiteState"),
ghttp.RespondWith(http.StatusOK, string((types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}).ToJSON())),
ghttp.RespondWith(http.StatusOK, string((types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending}).ToJSON())),
), ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/BeforeSuiteState"),
ghttp.RespondWithJSONEncodedPtr(&statusCode, &response),
@@ -259,7 +260,7 @@ var _ = Describe("SynchronizedBeforeSuiteNode", func() {
Context("when A on node1 succeeds", func() {
BeforeEach(func() {
response = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStatePassed}
response = types.RemoteBeforeSuiteData{Data: []byte("my data"), State: types.RemoteBeforeSuiteStatePassed}
outcome = node.Run(parallelNode, parallelTotal, server.URL())
})
@@ -283,7 +284,7 @@ var _ = Describe("SynchronizedBeforeSuiteNode", func() {
Context("when A on node1 fails", func() {
BeforeEach(func() {
response = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStateFailed}
response = types.RemoteBeforeSuiteData{Data: []byte("my data"), State: types.RemoteBeforeSuiteStateFailed}
outcome = node.Run(parallelNode, parallelTotal, server.URL())
})
@@ -315,7 +316,7 @@ var _ = Describe("SynchronizedBeforeSuiteNode", func() {
Context("when node1 disappears", func() {
BeforeEach(func() {
response = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStateDisappeared}
response = types.RemoteBeforeSuiteData{Data: []byte("my data"), State: types.RemoteBeforeSuiteStateDisappeared}
outcome = node.Run(parallelNode, parallelTotal, server.URL())
})
+1 -1
View File
@@ -207,7 +207,7 @@ func (aggregator *Aggregator) announceSpec(specSummary *types.SpecSummary) {
case types.SpecStatePending:
aggregator.stenographer.AnnouncePendingSpec(specSummary, aggregator.config.NoisyPendings && !aggregator.config.Succinct)
case types.SpecStateSkipped:
aggregator.stenographer.AnnounceSkippedSpec(specSummary, aggregator.config.Succinct, aggregator.config.FullTrace)
aggregator.stenographer.AnnounceSkippedSpec(specSummary, aggregator.config.Succinct || !aggregator.config.NoisySkippings, aggregator.config.FullTrace)
case types.SpecStateTimedOut:
aggregator.stenographer.AnnounceSpecTimedOut(specSummary, aggregator.config.Succinct, aggregator.config.FullTrace)
case types.SpecStatePanicked:
@@ -1,5 +1,7 @@
package remote_test
import "os"
type fakeOutputInterceptor struct {
DidStartInterceptingOutput bool
DidStopInterceptingOutput bool
@@ -15,3 +17,6 @@ func (interceptor *fakeOutputInterceptor) StopInterceptingAndReturnOutput() (str
interceptor.DidStopInterceptingOutput = true
return interceptor.InterceptedOutput, nil
}
func (interceptor *fakeOutputInterceptor) StreamTo(*os.File) {
}
+59 -2
View File
@@ -3,8 +3,14 @@ package remote
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"github.com/onsi/ginkgo/internal/writer"
"github.com/onsi/ginkgo/reporters"
"github.com/onsi/ginkgo/reporters/stenographer"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/types"
@@ -30,14 +36,41 @@ type ForwardingReporter struct {
serverHost string
poster Poster
outputInterceptor OutputInterceptor
debugMode bool
debugFile *os.File
nestedReporter *reporters.DefaultReporter
}
func NewForwardingReporter(serverHost string, poster Poster, outputInterceptor OutputInterceptor) *ForwardingReporter {
return &ForwardingReporter{
func NewForwardingReporter(config config.DefaultReporterConfigType, serverHost string, poster Poster, outputInterceptor OutputInterceptor, ginkgoWriter *writer.Writer, debugFile string) *ForwardingReporter {
reporter := &ForwardingReporter{
serverHost: serverHost,
poster: poster,
outputInterceptor: outputInterceptor,
}
if debugFile != "" {
var err error
reporter.debugMode = true
reporter.debugFile, err = os.Create(debugFile)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if !config.Verbose {
//if verbose is true then the GinkgoWriter emits to stdout. Don't _also_ redirect GinkgoWriter output as that will result in duplication.
ginkgoWriter.AndRedirectTo(reporter.debugFile)
}
outputInterceptor.StreamTo(reporter.debugFile) //This is not working
stenographer := stenographer.New(false, true, reporter.debugFile)
config.Succinct = false
config.Verbose = true
config.FullTrace = true
reporter.nestedReporter = reporters.NewDefaultReporter(config, stenographer)
}
return reporter
}
func (reporter *ForwardingReporter) post(path string, data interface{}) {
@@ -56,6 +89,10 @@ func (reporter *ForwardingReporter) SpecSuiteWillBegin(conf config.GinkgoConfigT
}
reporter.outputInterceptor.StartInterceptingOutput()
if reporter.debugMode {
reporter.nestedReporter.SpecSuiteWillBegin(conf, summary)
reporter.debugFile.Sync()
}
reporter.post("/SpecSuiteWillBegin", data)
}
@@ -63,10 +100,18 @@ func (reporter *ForwardingReporter) BeforeSuiteDidRun(setupSummary *types.SetupS
output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput()
reporter.outputInterceptor.StartInterceptingOutput()
setupSummary.CapturedOutput = output
if reporter.debugMode {
reporter.nestedReporter.BeforeSuiteDidRun(setupSummary)
reporter.debugFile.Sync()
}
reporter.post("/BeforeSuiteDidRun", setupSummary)
}
func (reporter *ForwardingReporter) SpecWillRun(specSummary *types.SpecSummary) {
if reporter.debugMode {
reporter.nestedReporter.SpecWillRun(specSummary)
reporter.debugFile.Sync()
}
reporter.post("/SpecWillRun", specSummary)
}
@@ -74,6 +119,10 @@ func (reporter *ForwardingReporter) SpecDidComplete(specSummary *types.SpecSumma
output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput()
reporter.outputInterceptor.StartInterceptingOutput()
specSummary.CapturedOutput = output
if reporter.debugMode {
reporter.nestedReporter.SpecDidComplete(specSummary)
reporter.debugFile.Sync()
}
reporter.post("/SpecDidComplete", specSummary)
}
@@ -81,10 +130,18 @@ func (reporter *ForwardingReporter) AfterSuiteDidRun(setupSummary *types.SetupSu
output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput()
reporter.outputInterceptor.StartInterceptingOutput()
setupSummary.CapturedOutput = output
if reporter.debugMode {
reporter.nestedReporter.AfterSuiteDidRun(setupSummary)
reporter.debugFile.Sync()
}
reporter.post("/AfterSuiteDidRun", setupSummary)
}
func (reporter *ForwardingReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
reporter.outputInterceptor.StopInterceptingAndReturnOutput()
if reporter.debugMode {
reporter.nestedReporter.SpecSuiteDidEnd(summary)
reporter.debugFile.Sync()
}
reporter.post("/SpecSuiteDidEnd", summary)
}
+2 -1
View File
@@ -2,6 +2,7 @@ package remote_test
import (
"encoding/json"
. "github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/config"
. "github.com/onsi/ginkgo/internal/remote"
@@ -29,7 +30,7 @@ var _ = Describe("ForwardingReporter", func() {
InterceptedOutput: "The intercepted output!",
}
reporter = NewForwardingReporter(serverHost, poster, interceptor)
reporter = NewForwardingReporter(config.DefaultReporterConfigType{}, serverHost, poster, interceptor, nil, "")
suiteSummary = &types.SuiteSummary{
SuiteDescription: "My Test Suite",
+3
View File
@@ -1,5 +1,7 @@
package remote
import "os"
/*
The OutputInterceptor is used by the ForwardingReporter to
intercept and capture all stdin and stderr output during a test run.
@@ -7,4 +9,5 @@ intercept and capture all stdin and stderr output during a test run.
type OutputInterceptor interface {
StartInterceptingOutput() error
StopInterceptingAndReturnOutput() (string, error)
StreamTo(*os.File)
}
@@ -6,6 +6,8 @@ import (
"errors"
"io/ioutil"
"os"
"github.com/hpcloud/tail"
)
func NewOutputInterceptor() OutputInterceptor {
@@ -14,7 +16,10 @@ func NewOutputInterceptor() OutputInterceptor {
type outputInterceptor struct {
redirectFile *os.File
streamTarget *os.File
intercepting bool
tailer *tail.Tail
doneTailing chan bool
}
func (interceptor *outputInterceptor) StartInterceptingOutput() error {
@@ -37,6 +42,18 @@ func (interceptor *outputInterceptor) StartInterceptingOutput() error {
syscallDup(int(interceptor.redirectFile.Fd()), 1)
syscallDup(int(interceptor.redirectFile.Fd()), 2)
if interceptor.streamTarget != nil {
interceptor.tailer, _ = tail.TailFile(interceptor.redirectFile.Name(), tail.Config{Follow: true})
interceptor.doneTailing = make(chan bool)
go func() {
for line := range interceptor.tailer.Lines {
interceptor.streamTarget.Write([]byte(line.Text + "\n"))
}
close(interceptor.doneTailing)
}()
}
return nil
}
@@ -51,5 +68,16 @@ func (interceptor *outputInterceptor) StopInterceptingAndReturnOutput() (string,
interceptor.intercepting = false
if interceptor.streamTarget != nil {
interceptor.tailer.Stop()
interceptor.tailer.Cleanup()
<-interceptor.doneTailing
interceptor.streamTarget.Sync()
}
return string(output), err
}
func (interceptor *outputInterceptor) StreamTo(out *os.File) {
interceptor.streamTarget = out
}
@@ -4,6 +4,7 @@ package remote
import (
"errors"
"os"
)
func NewOutputInterceptor() OutputInterceptor {
@@ -31,3 +32,5 @@ func (interceptor *outputInterceptor) StopInterceptingAndReturnOutput() (string,
return "", nil
}
func (interceptor *outputInterceptor) StreamTo(*os.File) {}
+1 -1
View File
@@ -45,7 +45,7 @@ func NewServer(parallelTotal int) (*Server, error) {
listener: listener,
lock: &sync.Mutex{},
alives: make([]func() bool, parallelTotal),
beforeSuiteData: types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending},
beforeSuiteData: types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending},
parallelTotal: parallelTotal,
}, nil
}
+7 -7
View File
@@ -47,7 +47,7 @@ var _ = Describe("Server", func() {
server.RegisterReporters(reporterA, reporterB)
forwardingReporter = NewForwardingReporter(server.Address(), &http.Client{}, &fakeOutputInterceptor{})
forwardingReporter = NewForwardingReporter(config.DefaultReporterConfigType{}, server.Address(), &http.Client{}, &fakeOutputInterceptor{}, nil, "")
suiteSummary = &types.SuiteSummary{
SuiteDescription: "My Test Suite",
@@ -146,10 +146,10 @@ var _ = Describe("Server", func() {
Context("when the first node's Alive has not been registered yet", func() {
It("should return pending", func() {
state := getBeforeSuite()
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}))
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending}))
state = getBeforeSuite()
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}))
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending}))
})
})
@@ -162,10 +162,10 @@ var _ = Describe("Server", func() {
It("should return pending", func() {
state := getBeforeSuite()
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}))
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending}))
state = getBeforeSuite()
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}))
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending}))
})
})
@@ -198,10 +198,10 @@ var _ = Describe("Server", func() {
It("should return disappeared", func() {
state := getBeforeSuite()
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStateDisappeared}))
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStateDisappeared}))
state = getBeforeSuite()
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStateDisappeared}))
Ω(state).Should(Equal(types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStateDisappeared}))
})
})
})
+1 -1
View File
@@ -8,4 +8,4 @@ import "syscall"
// use the nearly identical syscall.Dup3 instead
func syscallDup(oldfd int, newfd int) (err error) {
return syscall.Dup3(oldfd, newfd, 0)
}
}
+1 -1
View File
@@ -6,4 +6,4 @@ import "golang.org/x/sys/unix"
func syscallDup(oldfd int, newfd int) (err error) {
return unix.Dup2(oldfd, newfd)
}
}
+1 -1
View File
@@ -8,4 +8,4 @@ import "syscall"
func syscallDup(oldfd int, newfd int) (err error) {
return syscall.Dup2(oldfd, newfd)
}
}
+50 -21
View File
@@ -5,6 +5,8 @@ import (
"io"
"time"
"sync"
"github.com/onsi/ginkgo/internal/containernode"
"github.com/onsi/ginkgo/internal/leafnodes"
"github.com/onsi/ginkgo/types"
@@ -19,8 +21,11 @@ type Spec struct {
state types.SpecState
runTime time.Duration
startTime time.Time
failure types.SpecFailure
previousFailures bool
stateMutex *sync.Mutex
}
func New(subject leafnodes.SubjectNode, containers []*containernode.ContainerNode, announceProgress bool) *Spec {
@@ -29,6 +34,7 @@ func New(subject leafnodes.SubjectNode, containers []*containernode.ContainerNod
containers: containers,
focused: subject.Flag() == types.FlagTypeFocused,
announceProgress: announceProgress,
stateMutex: &sync.Mutex{},
}
spec.processFlag(subject.Flag())
@@ -43,32 +49,32 @@ func (spec *Spec) processFlag(flag types.FlagType) {
if flag == types.FlagTypeFocused {
spec.focused = true
} else if flag == types.FlagTypePending {
spec.state = types.SpecStatePending
spec.setState(types.SpecStatePending)
}
}
func (spec *Spec) Skip() {
spec.state = types.SpecStateSkipped
spec.setState(types.SpecStateSkipped)
}
func (spec *Spec) Failed() bool {
return spec.state == types.SpecStateFailed || spec.state == types.SpecStatePanicked || spec.state == types.SpecStateTimedOut
return spec.getState() == types.SpecStateFailed || spec.getState() == types.SpecStatePanicked || spec.getState() == types.SpecStateTimedOut
}
func (spec *Spec) Passed() bool {
return spec.state == types.SpecStatePassed
return spec.getState() == types.SpecStatePassed
}
func (spec *Spec) Flaked() bool {
return spec.state == types.SpecStatePassed && spec.previousFailures
return spec.getState() == types.SpecStatePassed && spec.previousFailures
}
func (spec *Spec) Pending() bool {
return spec.state == types.SpecStatePending
return spec.getState() == types.SpecStatePending
}
func (spec *Spec) Skipped() bool {
return spec.state == types.SpecStateSkipped
return spec.getState() == types.SpecStateSkipped
}
func (spec *Spec) Focused() bool {
@@ -91,13 +97,18 @@ func (spec *Spec) Summary(suiteID string) *types.SpecSummary {
componentTexts[len(spec.containers)] = spec.subject.Text()
componentCodeLocations[len(spec.containers)] = spec.subject.CodeLocation()
runTime := spec.runTime
if runTime == 0 && !spec.startTime.IsZero() {
runTime = time.Since(spec.startTime)
}
return &types.SpecSummary{
IsMeasurement: spec.IsMeasurement(),
NumberOfSamples: spec.subject.Samples(),
ComponentTexts: componentTexts,
ComponentCodeLocations: componentCodeLocations,
State: spec.state,
RunTime: spec.runTime,
State: spec.getState(),
RunTime: runTime,
Failure: spec.failure,
Measurements: spec.measurementsReport(),
SuiteID: suiteID,
@@ -114,26 +125,38 @@ func (spec *Spec) ConcatenatedString() string {
}
func (spec *Spec) Run(writer io.Writer) {
if spec.state == types.SpecStateFailed {
if spec.getState() == types.SpecStateFailed {
spec.previousFailures = true
}
startTime := time.Now()
spec.startTime = time.Now()
defer func() {
spec.runTime = time.Since(startTime)
spec.runTime = time.Since(spec.startTime)
}()
for sample := 0; sample < spec.subject.Samples(); sample++ {
spec.runSample(sample, writer)
if spec.state != types.SpecStatePassed {
if spec.getState() != types.SpecStatePassed {
return
}
}
}
func (spec *Spec) getState() types.SpecState {
spec.stateMutex.Lock()
defer spec.stateMutex.Unlock()
return spec.state
}
func (spec *Spec) setState(state types.SpecState) {
spec.stateMutex.Lock()
defer spec.stateMutex.Unlock()
spec.state = state
}
func (spec *Spec) runSample(sample int, writer io.Writer) {
spec.state = types.SpecStatePassed
spec.setState(types.SpecStatePassed)
spec.failure = types.SpecFailure{}
innerMostContainerIndexToUnwind := -1
@@ -143,8 +166,8 @@ func (spec *Spec) runSample(sample int, writer io.Writer) {
for _, afterEach := range container.SetupNodesOfType(types.SpecComponentTypeAfterEach) {
spec.announceSetupNode(writer, "AfterEach", container, afterEach)
afterEachState, afterEachFailure := afterEach.Run()
if afterEachState != types.SpecStatePassed && spec.state == types.SpecStatePassed {
spec.state = afterEachState
if afterEachState != types.SpecStatePassed && spec.getState() == types.SpecStatePassed {
spec.setState(afterEachState)
spec.failure = afterEachFailure
}
}
@@ -155,8 +178,10 @@ func (spec *Spec) runSample(sample int, writer io.Writer) {
innerMostContainerIndexToUnwind = i
for _, beforeEach := range container.SetupNodesOfType(types.SpecComponentTypeBeforeEach) {
spec.announceSetupNode(writer, "BeforeEach", container, beforeEach)
spec.state, spec.failure = beforeEach.Run()
if spec.state != types.SpecStatePassed {
s, f := beforeEach.Run()
spec.failure = f
spec.setState(s)
if spec.getState() != types.SpecStatePassed {
return
}
}
@@ -165,15 +190,19 @@ func (spec *Spec) runSample(sample int, writer io.Writer) {
for _, container := range spec.containers {
for _, justBeforeEach := range container.SetupNodesOfType(types.SpecComponentTypeJustBeforeEach) {
spec.announceSetupNode(writer, "JustBeforeEach", container, justBeforeEach)
spec.state, spec.failure = justBeforeEach.Run()
if spec.state != types.SpecStatePassed {
s, f := justBeforeEach.Run()
spec.failure = f
spec.setState(s)
if spec.getState() != types.SpecStatePassed {
return
}
}
}
spec.announceSubject(writer, spec.subject)
spec.state, spec.failure = spec.subject.Run()
s, f := spec.subject.Run()
spec.failure = f
spec.setState(s)
}
func (spec *Spec) announceSetupNode(writer io.Writer, nodeType string, container *containernode.ContainerNode, setupNode leafnodes.BasicNode) {
+7
View File
@@ -569,6 +569,13 @@ var _ = Describe("Spec", func() {
Ω(summary.RunTime).Should(BeNumerically(">=", 10*time.Millisecond))
})
It("should have a runtime which remains consistent after spec run", func() {
totalRunTime := summary.RunTime
Ω(totalRunTime).Should(BeNumerically(">=", 10*time.Millisecond))
Consistently(func() time.Duration { return spec.Summary("suite id").RunTime }).Should(Equal(totalRunTime))
})
It("should not be a measurement, or have a measurement summary", func() {
Ω(summary.IsMeasurement).Should(BeFalse())
Ω(summary.Measurements).Should(BeEmpty())
@@ -2,7 +2,6 @@ package spec_iterator
import (
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -31,7 +30,7 @@ func (s *ParallelIterator) Next() (*spec.Spec, error) {
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(fmt.Sprintf("unexpected status code %d", resp.StatusCode))
return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode)
}
var counter Counter
@@ -64,10 +64,10 @@ var _ = Describe("ParallelSpecIterator", func() {
Describe("when the server returns well-formed responses", func() {
BeforeEach(func() {
server.AppendHandlers(
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{0}),
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{1}),
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{3}),
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{4}),
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{Index: 0}),
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{Index: 1}),
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{Index: 3}),
ghttp.RespondWithJSONEncoded(http.StatusOK, Counter{Index: 4}),
)
})
+5 -2
View File
@@ -56,7 +56,9 @@ func (runner *SpecRunner) Run() bool {
}
runner.reportSuiteWillBegin()
go runner.registerForInterrupts()
signalRegistered := make(chan struct{})
go runner.registerForInterrupts(signalRegistered)
<-signalRegistered
suitePassed := runner.runBeforeSuite()
@@ -213,9 +215,10 @@ func (runner *SpecRunner) CurrentSpecSummary() (*types.SpecSummary, bool) {
return runner.runningSpec.Summary(runner.suiteID), true
}
func (runner *SpecRunner) registerForInterrupts() {
func (runner *SpecRunner) registerForInterrupts(signalRegistered chan struct{}) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
close(signalRegistered)
<-c
signal.Stop(c)
+7 -1
View File
@@ -18,7 +18,6 @@ import (
)
var noneFlag = types.FlagTypeNone
var focusedFlag = types.FlagTypeFocused
var pendingFlag = types.FlagTypePending
var _ = Describe("Spec Runner", func() {
@@ -236,6 +235,13 @@ var _ = Describe("Spec Runner", func() {
Ω(reporter1.EndSummary.NumberOfPassedSpecs).Should(Equal(0))
Ω(reporter1.EndSummary.NumberOfFailedSpecs).Should(Equal(0))
})
It("should not report a slow test", func() {
summaries := reporter1.SpecSummaries
for _, s := range summaries {
Expect(s.RunTime).To(BeZero())
}
})
})
})
+5 -5
View File
@@ -149,35 +149,35 @@ func (suite *Suite) PushContainerNode(text string, body func(), flag types.FlagT
func (suite *Suite) PushItNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call It from within a Describe or Context", codeLocation)
suite.failer.Fail("You may only call It from within a Describe, Context or When", codeLocation)
}
suite.currentContainer.PushSubjectNode(leafnodes.NewItNode(text, body, flag, codeLocation, timeout, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushMeasureNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, samples int) {
if suite.running {
suite.failer.Fail("You may only call Measure from within a Describe or Context", codeLocation)
suite.failer.Fail("You may only call Measure from within a Describe, Context or When", codeLocation)
}
suite.currentContainer.PushSubjectNode(leafnodes.NewMeasureNode(text, body, flag, codeLocation, samples, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call BeforeEach from within a Describe or Context", codeLocation)
suite.failer.Fail("You may only call BeforeEach from within a Describe, Context or When", codeLocation)
}
suite.currentContainer.PushSetupNode(leafnodes.NewBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call JustBeforeEach from within a Describe or Context", codeLocation)
suite.failer.Fail("You may only call JustBeforeEach from within a Describe, Context or When", codeLocation)
}
suite.currentContainer.PushSetupNode(leafnodes.NewJustBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call AfterEach from within a Describe or Context", codeLocation)
suite.failer.Fail("You may only call AfterEach from within a Describe, Context or When", codeLocation)
}
suite.currentContainer.PushSetupNode(leafnodes.NewAfterEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex))
}
+14
View File
@@ -121,6 +121,7 @@ var _ = Describe("Suite", func() {
Ω(description.LineNumber).Should(BeNumerically(">", 50))
Ω(description.LineNumber).Should(BeNumerically("<", 150))
Ω(description.Failed).Should(BeFalse())
Ω(description.Duration).Should(BeNumerically(">", 0))
})
Measure("should run measurements", func(b Benchmarker) {
@@ -152,6 +153,19 @@ var _ = Describe("Suite", func() {
"AfterSuite",
}))
})
Context("when in an AfterEach block", func() {
AfterEach(func() {
description := CurrentGinkgoTestDescription()
Ω(description.IsMeasurement).Should(BeFalse())
Ω(description.FileName).Should(ContainSubstring("suite_test.go"))
Ω(description.Failed).Should(BeFalse())
Ω(description.Duration).Should(BeNumerically(">", 0))
})
It("still provides information about the current test", func() {
Ω(true).To(BeTrue())
})
})
Context("when told to randomize all specs", func() {
BeforeEach(func() {
+12 -4
View File
@@ -16,10 +16,11 @@ type WriterInterface interface {
}
type Writer struct {
buffer *bytes.Buffer
outWriter io.Writer
lock *sync.Mutex
stream bool
buffer *bytes.Buffer
outWriter io.Writer
lock *sync.Mutex
stream bool
redirector io.Writer
}
func New(outWriter io.Writer) *Writer {
@@ -31,6 +32,10 @@ func New(outWriter io.Writer) *Writer {
}
}
func (w *Writer) AndRedirectTo(writer io.Writer) {
w.redirector = writer
}
func (w *Writer) SetStream(stream bool) {
w.lock.Lock()
defer w.lock.Unlock()
@@ -42,6 +47,9 @@ func (w *Writer) Write(b []byte) (n int, err error) {
defer w.lock.Unlock()
n, err = w.buffer.Write(b)
if w.redirector != nil {
w.redirector.Write(b)
}
if w.stream {
return w.outWriter.Write(b)
}