Add e2e tests
This commit is contained in:
parent
99a355f25d
commit
601fb7dacf
1163 changed files with 289217 additions and 14195 deletions
103
vendor/github.com/onsi/ginkgo/internal/leafnodes/benchmarker.go
generated
vendored
Normal file
103
vendor/github.com/onsi/ginkgo/internal/leafnodes/benchmarker.go
generated
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"sync"
|
||||
|
||||
"github.com/onsi/ginkgo/types"
|
||||
)
|
||||
|
||||
type benchmarker struct {
|
||||
mu sync.Mutex
|
||||
measurements map[string]*types.SpecMeasurement
|
||||
orderCounter int
|
||||
}
|
||||
|
||||
func newBenchmarker() *benchmarker {
|
||||
return &benchmarker{
|
||||
measurements: make(map[string]*types.SpecMeasurement, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *benchmarker) Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration) {
|
||||
t := time.Now()
|
||||
body()
|
||||
elapsedTime = time.Since(t)
|
||||
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
measurement := b.getMeasurement(name, "Fastest Time", "Slowest Time", "Average Time", "s", 3, info...)
|
||||
measurement.Results = append(measurement.Results, elapsedTime.Seconds())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (b *benchmarker) RecordValue(name string, value float64, info ...interface{}) {
|
||||
measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", "", 3, info...)
|
||||
b.mu.Lock()
|
||||
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()
|
||||
defer b.mu.Unlock()
|
||||
measurement.Results = append(measurement.Results, value)
|
||||
}
|
||||
|
||||
func (b *benchmarker) getMeasurement(name string, smallestLabel string, largestLabel string, averageLabel string, units string, precision int, info ...interface{}) *types.SpecMeasurement {
|
||||
measurement, ok := b.measurements[name]
|
||||
if !ok {
|
||||
var computedInfo interface{}
|
||||
computedInfo = nil
|
||||
if len(info) > 0 {
|
||||
computedInfo = info[0]
|
||||
}
|
||||
measurement = &types.SpecMeasurement{
|
||||
Name: name,
|
||||
Info: computedInfo,
|
||||
Order: b.orderCounter,
|
||||
SmallestLabel: smallestLabel,
|
||||
LargestLabel: largestLabel,
|
||||
AverageLabel: averageLabel,
|
||||
Units: units,
|
||||
Precision: precision,
|
||||
Results: make([]float64, 0),
|
||||
}
|
||||
b.measurements[name] = measurement
|
||||
b.orderCounter++
|
||||
}
|
||||
|
||||
return measurement
|
||||
}
|
||||
|
||||
func (b *benchmarker) measurementsReport() map[string]*types.SpecMeasurement {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
for _, measurement := range b.measurements {
|
||||
measurement.Smallest = math.MaxFloat64
|
||||
measurement.Largest = -math.MaxFloat64
|
||||
sum := float64(0)
|
||||
sumOfSquares := float64(0)
|
||||
|
||||
for _, result := range measurement.Results {
|
||||
if result > measurement.Largest {
|
||||
measurement.Largest = result
|
||||
}
|
||||
if result < measurement.Smallest {
|
||||
measurement.Smallest = result
|
||||
}
|
||||
sum += result
|
||||
sumOfSquares += result * result
|
||||
}
|
||||
|
||||
n := float64(len(measurement.Results))
|
||||
measurement.Average = sum / n
|
||||
measurement.StdDeviation = math.Sqrt(sumOfSquares/n - (sum/n)*(sum/n))
|
||||
}
|
||||
|
||||
return b.measurements
|
||||
}
|
||||
19
vendor/github.com/onsi/ginkgo/internal/leafnodes/interfaces.go
generated
vendored
Normal file
19
vendor/github.com/onsi/ginkgo/internal/leafnodes/interfaces.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/types"
|
||||
)
|
||||
|
||||
type BasicNode interface {
|
||||
Type() types.SpecComponentType
|
||||
Run() (types.SpecState, types.SpecFailure)
|
||||
CodeLocation() types.CodeLocation
|
||||
}
|
||||
|
||||
type SubjectNode interface {
|
||||
BasicNode
|
||||
|
||||
Text() string
|
||||
Flag() types.FlagType
|
||||
Samples() int
|
||||
}
|
||||
46
vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go
generated
vendored
Normal file
46
vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ItNode struct {
|
||||
runner *runner
|
||||
|
||||
flag types.FlagType
|
||||
text string
|
||||
}
|
||||
|
||||
func NewItNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *ItNode {
|
||||
return &ItNode{
|
||||
runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeIt, componentIndex),
|
||||
flag: flag,
|
||||
text: text,
|
||||
}
|
||||
}
|
||||
|
||||
func (node *ItNode) Run() (outcome types.SpecState, failure types.SpecFailure) {
|
||||
return node.runner.run()
|
||||
}
|
||||
|
||||
func (node *ItNode) Type() types.SpecComponentType {
|
||||
return types.SpecComponentTypeIt
|
||||
}
|
||||
|
||||
func (node *ItNode) Text() string {
|
||||
return node.text
|
||||
}
|
||||
|
||||
func (node *ItNode) Flag() types.FlagType {
|
||||
return node.flag
|
||||
}
|
||||
|
||||
func (node *ItNode) CodeLocation() types.CodeLocation {
|
||||
return node.runner.codeLocation
|
||||
}
|
||||
|
||||
func (node *ItNode) Samples() int {
|
||||
return 1
|
||||
}
|
||||
22
vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node_test.go
generated
vendored
Normal file
22
vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/internal/leafnodes"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
)
|
||||
|
||||
var _ = Describe("It Nodes", func() {
|
||||
It("should report the correct type, text, flag, and code location", func() {
|
||||
codeLocation := codelocation.New(0)
|
||||
it := NewItNode("my it node", func() {}, types.FlagTypeFocused, codeLocation, 0, nil, 3)
|
||||
Ω(it.Type()).Should(Equal(types.SpecComponentTypeIt))
|
||||
Ω(it.Flag()).Should(Equal(types.FlagTypeFocused))
|
||||
Ω(it.Text()).Should(Equal("my it node"))
|
||||
Ω(it.CodeLocation()).Should(Equal(codeLocation))
|
||||
Ω(it.Samples()).Should(Equal(1))
|
||||
})
|
||||
})
|
||||
13
vendor/github.com/onsi/ginkgo/internal/leafnodes/leaf_node_suite_test.go
generated
vendored
Normal file
13
vendor/github.com/onsi/ginkgo/internal/leafnodes/leaf_node_suite_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLeafNode(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "LeafNode Suite")
|
||||
}
|
||||
61
vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node.go
generated
vendored
Normal file
61
vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node.go
generated
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type MeasureNode struct {
|
||||
runner *runner
|
||||
|
||||
text string
|
||||
flag types.FlagType
|
||||
samples int
|
||||
benchmarker *benchmarker
|
||||
}
|
||||
|
||||
func NewMeasureNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, samples int, failer *failer.Failer, componentIndex int) *MeasureNode {
|
||||
benchmarker := newBenchmarker()
|
||||
|
||||
wrappedBody := func() {
|
||||
reflect.ValueOf(body).Call([]reflect.Value{reflect.ValueOf(benchmarker)})
|
||||
}
|
||||
|
||||
return &MeasureNode{
|
||||
runner: newRunner(wrappedBody, codeLocation, 0, failer, types.SpecComponentTypeMeasure, componentIndex),
|
||||
|
||||
text: text,
|
||||
flag: flag,
|
||||
samples: samples,
|
||||
benchmarker: benchmarker,
|
||||
}
|
||||
}
|
||||
|
||||
func (node *MeasureNode) Run() (outcome types.SpecState, failure types.SpecFailure) {
|
||||
return node.runner.run()
|
||||
}
|
||||
|
||||
func (node *MeasureNode) MeasurementsReport() map[string]*types.SpecMeasurement {
|
||||
return node.benchmarker.measurementsReport()
|
||||
}
|
||||
|
||||
func (node *MeasureNode) Type() types.SpecComponentType {
|
||||
return types.SpecComponentTypeMeasure
|
||||
}
|
||||
|
||||
func (node *MeasureNode) Text() string {
|
||||
return node.text
|
||||
}
|
||||
|
||||
func (node *MeasureNode) Flag() types.FlagType {
|
||||
return node.flag
|
||||
}
|
||||
|
||||
func (node *MeasureNode) CodeLocation() types.CodeLocation {
|
||||
return node.runner.codeLocation
|
||||
}
|
||||
|
||||
func (node *MeasureNode) Samples() int {
|
||||
return node.samples
|
||||
}
|
||||
154
vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node_test.go
generated
vendored
Normal file
154
vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/internal/leafnodes"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
Failer "github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ = Describe("Measure Nodes", func() {
|
||||
It("should report the correct type, text, flag, and code location", func() {
|
||||
codeLocation := codelocation.New(0)
|
||||
measure := NewMeasureNode("my measure node", func(b Benchmarker) {}, types.FlagTypeFocused, codeLocation, 10, nil, 3)
|
||||
Ω(measure.Type()).Should(Equal(types.SpecComponentTypeMeasure))
|
||||
Ω(measure.Flag()).Should(Equal(types.FlagTypeFocused))
|
||||
Ω(measure.Text()).Should(Equal("my measure node"))
|
||||
Ω(measure.CodeLocation()).Should(Equal(codeLocation))
|
||||
Ω(measure.Samples()).Should(Equal(10))
|
||||
})
|
||||
|
||||
Describe("benchmarking", func() {
|
||||
var measure *MeasureNode
|
||||
|
||||
Describe("Value", func() {
|
||||
BeforeEach(func() {
|
||||
measure = NewMeasureNode("the measurement", func(b Benchmarker) {
|
||||
b.RecordValue("foo", 7, "info!")
|
||||
b.RecordValue("foo", 2)
|
||||
b.RecordValue("foo", 3)
|
||||
b.RecordValue("bar", 0.3)
|
||||
b.RecordValue("bar", 0.1)
|
||||
b.RecordValue("bar", 0.5)
|
||||
b.RecordValue("bar", 0.7)
|
||||
}, types.FlagTypeFocused, codelocation.New(0), 1, Failer.New(), 3)
|
||||
Ω(measure.Run()).Should(Equal(types.SpecStatePassed))
|
||||
})
|
||||
|
||||
It("records passed in values and reports on them", func() {
|
||||
report := measure.MeasurementsReport()
|
||||
Ω(report).Should(HaveLen(2))
|
||||
Ω(report["foo"].Name).Should(Equal("foo"))
|
||||
Ω(report["foo"].Info).Should(Equal("info!"))
|
||||
Ω(report["foo"].Order).Should(Equal(0))
|
||||
Ω(report["foo"].SmallestLabel).Should(Equal("Smallest"))
|
||||
Ω(report["foo"].LargestLabel).Should(Equal(" Largest"))
|
||||
Ω(report["foo"].AverageLabel).Should(Equal(" Average"))
|
||||
Ω(report["foo"].Units).Should(Equal(""))
|
||||
Ω(report["foo"].Results).Should(Equal([]float64{7, 2, 3}))
|
||||
Ω(report["foo"].Smallest).Should(BeNumerically("==", 2))
|
||||
Ω(report["foo"].Largest).Should(BeNumerically("==", 7))
|
||||
Ω(report["foo"].Average).Should(BeNumerically("==", 4))
|
||||
Ω(report["foo"].StdDeviation).Should(BeNumerically("~", 2.16, 0.01))
|
||||
|
||||
Ω(report["bar"].Name).Should(Equal("bar"))
|
||||
Ω(report["bar"].Info).Should(BeNil())
|
||||
Ω(report["bar"].SmallestLabel).Should(Equal("Smallest"))
|
||||
Ω(report["bar"].Order).Should(Equal(1))
|
||||
Ω(report["bar"].LargestLabel).Should(Equal(" Largest"))
|
||||
Ω(report["bar"].AverageLabel).Should(Equal(" Average"))
|
||||
Ω(report["bar"].Units).Should(Equal(""))
|
||||
Ω(report["bar"].Results).Should(Equal([]float64{0.3, 0.1, 0.5, 0.7}))
|
||||
Ω(report["bar"].Smallest).Should(BeNumerically("==", 0.1))
|
||||
Ω(report["bar"].Largest).Should(BeNumerically("==", 0.7))
|
||||
Ω(report["bar"].Average).Should(BeNumerically("==", 0.4))
|
||||
Ω(report["bar"].StdDeviation).Should(BeNumerically("~", 0.22, 0.01))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Value with precision", func() {
|
||||
BeforeEach(func() {
|
||||
measure = NewMeasureNode("the measurement", func(b Benchmarker) {
|
||||
b.RecordValueWithPrecision("foo", 7, "ms", 7, "info!")
|
||||
b.RecordValueWithPrecision("foo", 2, "ms", 6)
|
||||
b.RecordValueWithPrecision("foo", 3, "ms", 5)
|
||||
b.RecordValueWithPrecision("bar", 0.3, "ns", 4)
|
||||
b.RecordValueWithPrecision("bar", 0.1, "ns", 3)
|
||||
b.RecordValueWithPrecision("bar", 0.5, "ns", 2)
|
||||
b.RecordValueWithPrecision("bar", 0.7, "ns", 1)
|
||||
}, types.FlagTypeFocused, codelocation.New(0), 1, Failer.New(), 3)
|
||||
Ω(measure.Run()).Should(Equal(types.SpecStatePassed))
|
||||
})
|
||||
|
||||
It("records passed in values and reports on them", func() {
|
||||
report := measure.MeasurementsReport()
|
||||
Ω(report).Should(HaveLen(2))
|
||||
Ω(report["foo"].Name).Should(Equal("foo"))
|
||||
Ω(report["foo"].Info).Should(Equal("info!"))
|
||||
Ω(report["foo"].Order).Should(Equal(0))
|
||||
Ω(report["foo"].SmallestLabel).Should(Equal("Smallest"))
|
||||
Ω(report["foo"].LargestLabel).Should(Equal(" Largest"))
|
||||
Ω(report["foo"].AverageLabel).Should(Equal(" Average"))
|
||||
Ω(report["foo"].Units).Should(Equal("ms"))
|
||||
Ω(report["foo"].Results).Should(Equal([]float64{7, 2, 3}))
|
||||
Ω(report["foo"].Smallest).Should(BeNumerically("==", 2))
|
||||
Ω(report["foo"].Largest).Should(BeNumerically("==", 7))
|
||||
Ω(report["foo"].Average).Should(BeNumerically("==", 4))
|
||||
Ω(report["foo"].StdDeviation).Should(BeNumerically("~", 2.16, 0.01))
|
||||
|
||||
Ω(report["bar"].Name).Should(Equal("bar"))
|
||||
Ω(report["bar"].Info).Should(BeNil())
|
||||
Ω(report["bar"].SmallestLabel).Should(Equal("Smallest"))
|
||||
Ω(report["bar"].Order).Should(Equal(1))
|
||||
Ω(report["bar"].LargestLabel).Should(Equal(" Largest"))
|
||||
Ω(report["bar"].AverageLabel).Should(Equal(" Average"))
|
||||
Ω(report["bar"].Units).Should(Equal("ns"))
|
||||
Ω(report["bar"].Results).Should(Equal([]float64{0.3, 0.1, 0.5, 0.7}))
|
||||
Ω(report["bar"].Smallest).Should(BeNumerically("==", 0.1))
|
||||
Ω(report["bar"].Largest).Should(BeNumerically("==", 0.7))
|
||||
Ω(report["bar"].Average).Should(BeNumerically("==", 0.4))
|
||||
Ω(report["bar"].StdDeviation).Should(BeNumerically("~", 0.22, 0.01))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Time", func() {
|
||||
BeforeEach(func() {
|
||||
measure = NewMeasureNode("the measurement", func(b Benchmarker) {
|
||||
b.Time("foo", func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}, "info!")
|
||||
b.Time("foo", func() {
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
})
|
||||
b.Time("foo", func() {
|
||||
time.Sleep(170 * time.Millisecond)
|
||||
})
|
||||
}, types.FlagTypeFocused, codelocation.New(0), 1, Failer.New(), 3)
|
||||
Ω(measure.Run()).Should(Equal(types.SpecStatePassed))
|
||||
})
|
||||
|
||||
It("records passed in values and reports on them", func() {
|
||||
report := measure.MeasurementsReport()
|
||||
Ω(report).Should(HaveLen(1))
|
||||
Ω(report["foo"].Name).Should(Equal("foo"))
|
||||
Ω(report["foo"].Info).Should(Equal("info!"))
|
||||
Ω(report["foo"].SmallestLabel).Should(Equal("Fastest Time"))
|
||||
Ω(report["foo"].LargestLabel).Should(Equal("Slowest Time"))
|
||||
Ω(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))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
113
vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go
generated
vendored
Normal file
113
vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
"github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
type runner struct {
|
||||
isAsync bool
|
||||
asyncFunc func(chan<- interface{})
|
||||
syncFunc func()
|
||||
codeLocation types.CodeLocation
|
||||
timeoutThreshold time.Duration
|
||||
nodeType types.SpecComponentType
|
||||
componentIndex int
|
||||
failer *failer.Failer
|
||||
}
|
||||
|
||||
func newRunner(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, nodeType types.SpecComponentType, componentIndex int) *runner {
|
||||
bodyType := reflect.TypeOf(body)
|
||||
if bodyType.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("Expected a function but got something else at %v", codeLocation))
|
||||
}
|
||||
|
||||
runner := &runner{
|
||||
codeLocation: codeLocation,
|
||||
timeoutThreshold: timeout,
|
||||
failer: failer,
|
||||
nodeType: nodeType,
|
||||
componentIndex: componentIndex,
|
||||
}
|
||||
|
||||
switch bodyType.NumIn() {
|
||||
case 0:
|
||||
runner.syncFunc = body.(func())
|
||||
return runner
|
||||
case 1:
|
||||
if !(bodyType.In(0).Kind() == reflect.Chan && bodyType.In(0).Elem().Kind() == reflect.Interface) {
|
||||
panic(fmt.Sprintf("Must pass a Done channel to function at %v", codeLocation))
|
||||
}
|
||||
|
||||
wrappedBody := func(done chan<- interface{}) {
|
||||
bodyValue := reflect.ValueOf(body)
|
||||
bodyValue.Call([]reflect.Value{reflect.ValueOf(done)})
|
||||
}
|
||||
|
||||
runner.isAsync = true
|
||||
runner.asyncFunc = wrappedBody
|
||||
return runner
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("Too many arguments to function at %v", codeLocation))
|
||||
}
|
||||
|
||||
func (r *runner) run() (outcome types.SpecState, failure types.SpecFailure) {
|
||||
if r.isAsync {
|
||||
return r.runAsync()
|
||||
} else {
|
||||
return r.runSync()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *runner) runAsync() (outcome types.SpecState, failure types.SpecFailure) {
|
||||
done := make(chan interface{}, 1)
|
||||
|
||||
go func() {
|
||||
finished := false
|
||||
|
||||
defer func() {
|
||||
if e := recover(); e != nil || !finished {
|
||||
r.failer.Panic(codelocation.New(2), e)
|
||||
select {
|
||||
case <-done:
|
||||
break
|
||||
default:
|
||||
close(done)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
r.asyncFunc(done)
|
||||
finished = true
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(r.timeoutThreshold):
|
||||
r.failer.Timeout(r.codeLocation)
|
||||
}
|
||||
|
||||
failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation)
|
||||
return
|
||||
}
|
||||
func (r *runner) runSync() (outcome types.SpecState, failure types.SpecFailure) {
|
||||
finished := false
|
||||
|
||||
defer func() {
|
||||
if e := recover(); e != nil || !finished {
|
||||
r.failer.Panic(codelocation.New(2), e)
|
||||
}
|
||||
|
||||
failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation)
|
||||
}()
|
||||
|
||||
r.syncFunc()
|
||||
finished = true
|
||||
|
||||
return
|
||||
}
|
||||
41
vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go
generated
vendored
Normal file
41
vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SetupNode struct {
|
||||
runner *runner
|
||||
}
|
||||
|
||||
func (node *SetupNode) Run() (outcome types.SpecState, failure types.SpecFailure) {
|
||||
return node.runner.run()
|
||||
}
|
||||
|
||||
func (node *SetupNode) Type() types.SpecComponentType {
|
||||
return node.runner.nodeType
|
||||
}
|
||||
|
||||
func (node *SetupNode) CodeLocation() types.CodeLocation {
|
||||
return node.runner.codeLocation
|
||||
}
|
||||
|
||||
func NewBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode {
|
||||
return &SetupNode{
|
||||
runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeBeforeEach, componentIndex),
|
||||
}
|
||||
}
|
||||
|
||||
func NewAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode {
|
||||
return &SetupNode{
|
||||
runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeAfterEach, componentIndex),
|
||||
}
|
||||
}
|
||||
|
||||
func NewJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode {
|
||||
return &SetupNode{
|
||||
runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeJustBeforeEach, componentIndex),
|
||||
}
|
||||
}
|
||||
40
vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes_test.go
generated
vendored
Normal file
40
vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
. "github.com/onsi/ginkgo/internal/leafnodes"
|
||||
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
)
|
||||
|
||||
var _ = Describe("Setup Nodes", func() {
|
||||
Describe("BeforeEachNodes", func() {
|
||||
It("should report the correct type and code location", func() {
|
||||
codeLocation := codelocation.New(0)
|
||||
beforeEach := NewBeforeEachNode(func() {}, codeLocation, 0, nil, 3)
|
||||
Ω(beforeEach.Type()).Should(Equal(types.SpecComponentTypeBeforeEach))
|
||||
Ω(beforeEach.CodeLocation()).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("AfterEachNodes", func() {
|
||||
It("should report the correct type and code location", func() {
|
||||
codeLocation := codelocation.New(0)
|
||||
afterEach := NewAfterEachNode(func() {}, codeLocation, 0, nil, 3)
|
||||
Ω(afterEach.Type()).Should(Equal(types.SpecComponentTypeAfterEach))
|
||||
Ω(afterEach.CodeLocation()).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("JustBeforeEachNodes", func() {
|
||||
It("should report the correct type and code location", func() {
|
||||
codeLocation := codelocation.New(0)
|
||||
justBeforeEach := NewJustBeforeEachNode(func() {}, codeLocation, 0, nil, 3)
|
||||
Ω(justBeforeEach.Type()).Should(Equal(types.SpecComponentTypeJustBeforeEach))
|
||||
Ω(justBeforeEach.CodeLocation()).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
})
|
||||
356
vendor/github.com/onsi/ginkgo/internal/leafnodes/shared_runner_test.go
generated
vendored
Normal file
356
vendor/github.com/onsi/ginkgo/internal/leafnodes/shared_runner_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/internal/leafnodes"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
Failer "github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
)
|
||||
|
||||
type runnable interface {
|
||||
Run() (outcome types.SpecState, failure types.SpecFailure)
|
||||
CodeLocation() types.CodeLocation
|
||||
}
|
||||
|
||||
func SynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType, componentIndex int) {
|
||||
var (
|
||||
outcome types.SpecState
|
||||
failure types.SpecFailure
|
||||
|
||||
failer *Failer.Failer
|
||||
|
||||
componentCodeLocation types.CodeLocation
|
||||
innerCodeLocation types.CodeLocation
|
||||
|
||||
didRun bool
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
failer = Failer.New()
|
||||
componentCodeLocation = codelocation.New(0)
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
|
||||
didRun = false
|
||||
})
|
||||
|
||||
Describe("synchronous functions", func() {
|
||||
Context("when the function passes", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func() {
|
||||
didRun = true
|
||||
}, 0, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should have a succesful outcome", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStatePassed))
|
||||
Ω(failure).Should(BeZero())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when a failure occurs", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func() {
|
||||
didRun = true
|
||||
failer.Fail("bam", innerCodeLocation)
|
||||
panic("should not matter")
|
||||
}, 0, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should return the failure", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStateFailed))
|
||||
Ω(failure).Should(Equal(types.SpecFailure{
|
||||
Message: "bam",
|
||||
Location: innerCodeLocation,
|
||||
ForwardedPanic: "",
|
||||
ComponentIndex: componentIndex,
|
||||
ComponentType: componentType,
|
||||
ComponentCodeLocation: componentCodeLocation,
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when a panic occurs", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func() {
|
||||
didRun = true
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
panic("ack!")
|
||||
}, 0, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should return the panic", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStatePanicked))
|
||||
Ω(failure.ForwardedPanic).Should(Equal("ack!"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when a panic occurs with a nil value", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func() {
|
||||
didRun = true
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
panic(nil)
|
||||
}, 0, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should return the nil-valued panic", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStatePanicked))
|
||||
Ω(failure.ForwardedPanic).Should(Equal("<nil>"))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func AsynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType, componentIndex int) {
|
||||
var (
|
||||
outcome types.SpecState
|
||||
failure types.SpecFailure
|
||||
|
||||
failer *Failer.Failer
|
||||
|
||||
componentCodeLocation types.CodeLocation
|
||||
innerCodeLocation types.CodeLocation
|
||||
|
||||
didRun bool
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
failer = Failer.New()
|
||||
componentCodeLocation = codelocation.New(0)
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
|
||||
didRun = false
|
||||
})
|
||||
|
||||
Describe("asynchronous functions", func() {
|
||||
var timeoutDuration time.Duration
|
||||
|
||||
BeforeEach(func() {
|
||||
timeoutDuration = time.Duration(1 * float64(time.Second))
|
||||
})
|
||||
|
||||
Context("when running", func() {
|
||||
It("should run the function as a goroutine, and block until it's done", func() {
|
||||
proveAsync := make(chan bool)
|
||||
|
||||
build(func(done Done) {
|
||||
didRun = true
|
||||
proveAsync <- true
|
||||
close(done)
|
||||
}, timeoutDuration, failer, componentCodeLocation).Run()
|
||||
|
||||
Eventually(proveAsync).Should(Receive(Equal(true)))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the function passes", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func(done Done) {
|
||||
didRun = true
|
||||
close(done)
|
||||
}, timeoutDuration, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should have a succesful outcome", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
Ω(outcome).Should(Equal(types.SpecStatePassed))
|
||||
Ω(failure).Should(BeZero())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the function fails", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func(done Done) {
|
||||
didRun = true
|
||||
failer.Fail("bam", innerCodeLocation)
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
panic("doesn't matter")
|
||||
close(done)
|
||||
}, 10*time.Millisecond, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should return the failure", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStateFailed))
|
||||
Ω(failure).Should(Equal(types.SpecFailure{
|
||||
Message: "bam",
|
||||
Location: innerCodeLocation,
|
||||
ForwardedPanic: "",
|
||||
ComponentIndex: componentIndex,
|
||||
ComponentType: componentType,
|
||||
ComponentCodeLocation: componentCodeLocation,
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the function times out", 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() {
|
||||
<-guard
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStateTimedOut))
|
||||
Ω(failure).Should(Equal(types.SpecFailure{
|
||||
Message: "Timed out",
|
||||
Location: componentCodeLocation,
|
||||
ForwardedPanic: "",
|
||||
ComponentIndex: componentIndex,
|
||||
ComponentType: componentType,
|
||||
ComponentCodeLocation: componentCodeLocation,
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the function panics", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func(done Done) {
|
||||
didRun = true
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
panic("ack!")
|
||||
}, 100*time.Millisecond, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should return the panic", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStatePanicked))
|
||||
Ω(failure.ForwardedPanic).Should(Equal("ack!"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the function panics with a nil value", func() {
|
||||
BeforeEach(func() {
|
||||
outcome, failure = build(func(done Done) {
|
||||
didRun = true
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
panic(nil)
|
||||
}, 100*time.Millisecond, failer, componentCodeLocation).Run()
|
||||
})
|
||||
|
||||
It("should return the nil-valued panic", func() {
|
||||
Ω(didRun).Should(BeTrue())
|
||||
|
||||
Ω(outcome).Should(Equal(types.SpecStatePanicked))
|
||||
Ω(failure.ForwardedPanic).Should(Equal("<nil>"))
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func InvalidSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType) {
|
||||
var (
|
||||
failer *Failer.Failer
|
||||
componentCodeLocation types.CodeLocation
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
failer = Failer.New()
|
||||
componentCodeLocation = codelocation.New(0)
|
||||
})
|
||||
|
||||
Describe("invalid functions", func() {
|
||||
Context("when passed something that's not a function", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
build("not a function", 0, failer, componentCodeLocation)
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the function takes the wrong kind of argument", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
build(func(oops string) {}, 0, failer, componentCodeLocation)
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the function takes more than one argument", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
build(func(done Done, oops string) {}, 0, failer, componentCodeLocation)
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
var _ = Describe("Shared RunnableNode behavior", func() {
|
||||
Describe("It Nodes", func() {
|
||||
build := func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable {
|
||||
return NewItNode("", body, types.FlagTypeFocused, componentCodeLocation, timeout, failer, 3)
|
||||
}
|
||||
|
||||
SynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeIt, 3)
|
||||
AsynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeIt, 3)
|
||||
InvalidSharedRunnerBehaviors(build, types.SpecComponentTypeIt)
|
||||
})
|
||||
|
||||
Describe("Measure Nodes", func() {
|
||||
build := func(body interface{}, _ time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable {
|
||||
return NewMeasureNode("", func(Benchmarker) {
|
||||
reflect.ValueOf(body).Call([]reflect.Value{})
|
||||
}, types.FlagTypeFocused, componentCodeLocation, 10, failer, 3)
|
||||
}
|
||||
|
||||
SynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeMeasure, 3)
|
||||
})
|
||||
|
||||
Describe("BeforeEach Nodes", func() {
|
||||
build := func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable {
|
||||
return NewBeforeEachNode(body, componentCodeLocation, timeout, failer, 3)
|
||||
}
|
||||
|
||||
SynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeBeforeEach, 3)
|
||||
AsynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeBeforeEach, 3)
|
||||
InvalidSharedRunnerBehaviors(build, types.SpecComponentTypeBeforeEach)
|
||||
})
|
||||
|
||||
Describe("AfterEach Nodes", func() {
|
||||
build := func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable {
|
||||
return NewAfterEachNode(body, componentCodeLocation, timeout, failer, 3)
|
||||
}
|
||||
|
||||
SynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeAfterEach, 3)
|
||||
AsynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeAfterEach, 3)
|
||||
InvalidSharedRunnerBehaviors(build, types.SpecComponentTypeAfterEach)
|
||||
})
|
||||
|
||||
Describe("JustBeforeEach Nodes", func() {
|
||||
build := func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable {
|
||||
return NewJustBeforeEachNode(body, componentCodeLocation, timeout, failer, 3)
|
||||
}
|
||||
|
||||
SynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeJustBeforeEach, 3)
|
||||
AsynchronousSharedRunnerBehaviors(build, types.SpecComponentTypeJustBeforeEach, 3)
|
||||
InvalidSharedRunnerBehaviors(build, types.SpecComponentTypeJustBeforeEach)
|
||||
})
|
||||
})
|
||||
54
vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes.go
generated
vendored
Normal file
54
vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes.go
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SuiteNode interface {
|
||||
Run(parallelNode int, parallelTotal int, syncHost string) bool
|
||||
Passed() bool
|
||||
Summary() *types.SetupSummary
|
||||
}
|
||||
|
||||
type simpleSuiteNode struct {
|
||||
runner *runner
|
||||
outcome types.SpecState
|
||||
failure types.SpecFailure
|
||||
runTime time.Duration
|
||||
}
|
||||
|
||||
func (node *simpleSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool {
|
||||
t := time.Now()
|
||||
node.outcome, node.failure = node.runner.run()
|
||||
node.runTime = time.Since(t)
|
||||
|
||||
return node.outcome == types.SpecStatePassed
|
||||
}
|
||||
|
||||
func (node *simpleSuiteNode) Passed() bool {
|
||||
return node.outcome == types.SpecStatePassed
|
||||
}
|
||||
|
||||
func (node *simpleSuiteNode) Summary() *types.SetupSummary {
|
||||
return &types.SetupSummary{
|
||||
ComponentType: node.runner.nodeType,
|
||||
CodeLocation: node.runner.codeLocation,
|
||||
State: node.outcome,
|
||||
RunTime: node.runTime,
|
||||
Failure: node.failure,
|
||||
}
|
||||
}
|
||||
|
||||
func NewBeforeSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode {
|
||||
return &simpleSuiteNode{
|
||||
runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeBeforeSuite, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func NewAfterSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode {
|
||||
return &simpleSuiteNode{
|
||||
runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0),
|
||||
}
|
||||
}
|
||||
230
vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes_test.go
generated
vendored
Normal file
230
vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
. "github.com/onsi/ginkgo/internal/leafnodes"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
Failer "github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
)
|
||||
|
||||
var _ = Describe("SuiteNodes", func() {
|
||||
Describe("BeforeSuite nodes", func() {
|
||||
var befSuite SuiteNode
|
||||
var failer *Failer.Failer
|
||||
var codeLocation types.CodeLocation
|
||||
var innerCodeLocation types.CodeLocation
|
||||
var outcome bool
|
||||
|
||||
BeforeEach(func() {
|
||||
failer = Failer.New()
|
||||
codeLocation = codelocation.New(0)
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
})
|
||||
|
||||
Context("when the body passes", func() {
|
||||
BeforeEach(func() {
|
||||
befSuite = NewBeforeSuiteNode(func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}, codeLocation, 0, failer)
|
||||
outcome = befSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return true when run and report as passed", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
Ω(befSuite.Passed()).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := befSuite.Summary()
|
||||
Ω(summary.ComponentType).Should(Equal(types.SpecComponentTypeBeforeSuite))
|
||||
Ω(summary.CodeLocation).Should(Equal(codeLocation))
|
||||
Ω(summary.State).Should(Equal(types.SpecStatePassed))
|
||||
Ω(summary.RunTime).Should(BeNumerically(">=", 10*time.Millisecond))
|
||||
Ω(summary.Failure).Should(BeZero())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the body fails", func() {
|
||||
BeforeEach(func() {
|
||||
befSuite = NewBeforeSuiteNode(func() {
|
||||
failer.Fail("oops", innerCodeLocation)
|
||||
}, codeLocation, 0, failer)
|
||||
outcome = befSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return false when run and report as failed", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(befSuite.Passed()).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := befSuite.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStateFailed))
|
||||
Ω(summary.Failure.Message).Should(Equal("oops"))
|
||||
Ω(summary.Failure.Location).Should(Equal(innerCodeLocation))
|
||||
Ω(summary.Failure.ForwardedPanic).Should(BeEmpty())
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeBeforeSuite))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the body times out", func() {
|
||||
BeforeEach(func() {
|
||||
befSuite = NewBeforeSuiteNode(func(done Done) {
|
||||
}, codeLocation, time.Millisecond, failer)
|
||||
outcome = befSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return false when run and report as failed", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(befSuite.Passed()).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := befSuite.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStateTimedOut))
|
||||
Ω(summary.Failure.ForwardedPanic).Should(BeEmpty())
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeBeforeSuite))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the body panics", func() {
|
||||
BeforeEach(func() {
|
||||
befSuite = NewBeforeSuiteNode(func() {
|
||||
panic("bam")
|
||||
}, codeLocation, 0, failer)
|
||||
outcome = befSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return false when run and report as failed", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(befSuite.Passed()).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := befSuite.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStatePanicked))
|
||||
Ω(summary.Failure.ForwardedPanic).Should(Equal("bam"))
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeBeforeSuite))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("AfterSuite nodes", func() {
|
||||
var aftSuite SuiteNode
|
||||
var failer *Failer.Failer
|
||||
var codeLocation types.CodeLocation
|
||||
var innerCodeLocation types.CodeLocation
|
||||
var outcome bool
|
||||
|
||||
BeforeEach(func() {
|
||||
failer = Failer.New()
|
||||
codeLocation = codelocation.New(0)
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
})
|
||||
|
||||
Context("when the body passes", func() {
|
||||
BeforeEach(func() {
|
||||
aftSuite = NewAfterSuiteNode(func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}, codeLocation, 0, failer)
|
||||
outcome = aftSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return true when run and report as passed", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
Ω(aftSuite.Passed()).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := aftSuite.Summary()
|
||||
Ω(summary.ComponentType).Should(Equal(types.SpecComponentTypeAfterSuite))
|
||||
Ω(summary.CodeLocation).Should(Equal(codeLocation))
|
||||
Ω(summary.State).Should(Equal(types.SpecStatePassed))
|
||||
Ω(summary.RunTime).Should(BeNumerically(">=", 10*time.Millisecond))
|
||||
Ω(summary.Failure).Should(BeZero())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the body fails", func() {
|
||||
BeforeEach(func() {
|
||||
aftSuite = NewAfterSuiteNode(func() {
|
||||
failer.Fail("oops", innerCodeLocation)
|
||||
}, codeLocation, 0, failer)
|
||||
outcome = aftSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return false when run and report as failed", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(aftSuite.Passed()).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := aftSuite.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStateFailed))
|
||||
Ω(summary.Failure.Message).Should(Equal("oops"))
|
||||
Ω(summary.Failure.Location).Should(Equal(innerCodeLocation))
|
||||
Ω(summary.Failure.ForwardedPanic).Should(BeEmpty())
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeAfterSuite))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the body times out", func() {
|
||||
BeforeEach(func() {
|
||||
aftSuite = NewAfterSuiteNode(func(done Done) {
|
||||
}, codeLocation, time.Millisecond, failer)
|
||||
outcome = aftSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return false when run and report as failed", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(aftSuite.Passed()).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := aftSuite.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStateTimedOut))
|
||||
Ω(summary.Failure.ForwardedPanic).Should(BeEmpty())
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeAfterSuite))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the body panics", func() {
|
||||
BeforeEach(func() {
|
||||
aftSuite = NewAfterSuiteNode(func() {
|
||||
panic("bam")
|
||||
}, codeLocation, 0, failer)
|
||||
outcome = aftSuite.Run(0, 0, "")
|
||||
})
|
||||
|
||||
It("should return false when run and report as failed", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(aftSuite.Passed()).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should have the correct summary", func() {
|
||||
summary := aftSuite.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStatePanicked))
|
||||
Ω(summary.Failure.ForwardedPanic).Should(Equal("bam"))
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeAfterSuite))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
89
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node.go
generated
vendored
Normal file
89
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node.go
generated
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type synchronizedAfterSuiteNode struct {
|
||||
runnerA *runner
|
||||
runnerB *runner
|
||||
|
||||
outcome types.SpecState
|
||||
failure types.SpecFailure
|
||||
runTime time.Duration
|
||||
}
|
||||
|
||||
func NewSynchronizedAfterSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode {
|
||||
return &synchronizedAfterSuiteNode{
|
||||
runnerA: newRunner(bodyA, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0),
|
||||
runnerB: newRunner(bodyB, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (node *synchronizedAfterSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool {
|
||||
node.outcome, node.failure = node.runnerA.run()
|
||||
|
||||
if parallelNode == 1 {
|
||||
if parallelTotal > 1 {
|
||||
node.waitUntilOtherNodesAreDone(syncHost)
|
||||
}
|
||||
|
||||
outcome, failure := node.runnerB.run()
|
||||
|
||||
if node.outcome == types.SpecStatePassed {
|
||||
node.outcome, node.failure = outcome, failure
|
||||
}
|
||||
}
|
||||
|
||||
return node.outcome == types.SpecStatePassed
|
||||
}
|
||||
|
||||
func (node *synchronizedAfterSuiteNode) Passed() bool {
|
||||
return node.outcome == types.SpecStatePassed
|
||||
}
|
||||
|
||||
func (node *synchronizedAfterSuiteNode) Summary() *types.SetupSummary {
|
||||
return &types.SetupSummary{
|
||||
ComponentType: node.runnerA.nodeType,
|
||||
CodeLocation: node.runnerA.codeLocation,
|
||||
State: node.outcome,
|
||||
RunTime: node.runTime,
|
||||
Failure: node.failure,
|
||||
}
|
||||
}
|
||||
|
||||
func (node *synchronizedAfterSuiteNode) waitUntilOtherNodesAreDone(syncHost string) {
|
||||
for {
|
||||
if node.canRun(syncHost) {
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (node *synchronizedAfterSuiteNode) canRun(syncHost string) bool {
|
||||
resp, err := http.Get(syncHost + "/RemoteAfterSuiteData")
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
return false
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
afterSuiteData := types.RemoteAfterSuiteData{}
|
||||
err = json.Unmarshal(body, &afterSuiteData)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return afterSuiteData.CanRun
|
||||
}
|
||||
196
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node_test.go
generated
vendored
Normal file
196
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/internal/leafnodes"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
. "github.com/onsi/gomega"
|
||||
"sync"
|
||||
|
||||
"github.com/onsi/gomega/ghttp"
|
||||
"net/http"
|
||||
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
Failer "github.com/onsi/ginkgo/internal/failer"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ = Describe("SynchronizedAfterSuiteNode", func() {
|
||||
var failer *Failer.Failer
|
||||
var node SuiteNode
|
||||
var codeLocation types.CodeLocation
|
||||
var innerCodeLocation types.CodeLocation
|
||||
var outcome bool
|
||||
var server *ghttp.Server
|
||||
var things []string
|
||||
var lock *sync.Mutex
|
||||
|
||||
BeforeEach(func() {
|
||||
things = []string{}
|
||||
server = ghttp.NewServer()
|
||||
codeLocation = codelocation.New(0)
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
failer = Failer.New()
|
||||
lock = &sync.Mutex{}
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
server.Close()
|
||||
})
|
||||
|
||||
newNode := func(bodyA interface{}, bodyB interface{}) SuiteNode {
|
||||
return NewSynchronizedAfterSuiteNode(bodyA, bodyB, codeLocation, time.Millisecond, failer)
|
||||
}
|
||||
|
||||
ranThing := func(thing string) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
things = append(things, thing)
|
||||
}
|
||||
|
||||
thingsThatRan := func() []string {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
return things
|
||||
}
|
||||
|
||||
Context("when not running in parallel", func() {
|
||||
Context("when all is well", func() {
|
||||
BeforeEach(func() {
|
||||
node = newNode(func() {
|
||||
ranThing("A")
|
||||
}, func() {
|
||||
ranThing("B")
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should run A, then B", func() {
|
||||
Ω(thingsThatRan()).Should(Equal([]string{"A", "B"}))
|
||||
})
|
||||
|
||||
It("should report success", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
Ω(node.Passed()).Should(BeTrue())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStatePassed))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when A fails", func() {
|
||||
BeforeEach(func() {
|
||||
node = newNode(func() {
|
||||
ranThing("A")
|
||||
failer.Fail("bam", innerCodeLocation)
|
||||
}, func() {
|
||||
ranThing("B")
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should still run B", func() {
|
||||
Ω(thingsThatRan()).Should(Equal([]string{"A", "B"}))
|
||||
})
|
||||
|
||||
It("should report failure", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStateFailed))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when B fails", func() {
|
||||
BeforeEach(func() {
|
||||
node = newNode(func() {
|
||||
ranThing("A")
|
||||
}, func() {
|
||||
ranThing("B")
|
||||
failer.Fail("bam", innerCodeLocation)
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should run all the things", func() {
|
||||
Ω(thingsThatRan()).Should(Equal([]string{"A", "B"}))
|
||||
})
|
||||
|
||||
It("should report failure", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStateFailed))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when running in parallel", func() {
|
||||
Context("as the first node", func() {
|
||||
BeforeEach(func() {
|
||||
server.AppendHandlers(ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"),
|
||||
func(writer http.ResponseWriter, request *http.Request) {
|
||||
ranThing("Request1")
|
||||
},
|
||||
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{false}),
|
||||
), ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"),
|
||||
func(writer http.ResponseWriter, request *http.Request) {
|
||||
ranThing("Request2")
|
||||
},
|
||||
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{false}),
|
||||
), ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"),
|
||||
func(writer http.ResponseWriter, request *http.Request) {
|
||||
ranThing("Request3")
|
||||
},
|
||||
ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{true}),
|
||||
))
|
||||
|
||||
node = newNode(func() {
|
||||
ranThing("A")
|
||||
}, func() {
|
||||
ranThing("B")
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 3, server.URL())
|
||||
})
|
||||
|
||||
It("should run A and, when the server says its time, run B", func() {
|
||||
Ω(thingsThatRan()).Should(Equal([]string{"A", "Request1", "Request2", "Request3", "B"}))
|
||||
})
|
||||
|
||||
It("should report success", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
Ω(node.Passed()).Should(BeTrue())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStatePassed))
|
||||
})
|
||||
})
|
||||
|
||||
Context("as any other node", func() {
|
||||
BeforeEach(func() {
|
||||
node = newNode(func() {
|
||||
ranThing("A")
|
||||
}, func() {
|
||||
ranThing("B")
|
||||
})
|
||||
|
||||
outcome = node.Run(2, 3, server.URL())
|
||||
})
|
||||
|
||||
It("should run A, and not run B", func() {
|
||||
Ω(thingsThatRan()).Should(Equal([]string{"A"}))
|
||||
})
|
||||
|
||||
It("should not talk to the server", func() {
|
||||
Ω(server.ReceivedRequests()).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should report success", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
Ω(node.Passed()).Should(BeTrue())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStatePassed))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
182
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node.go
generated
vendored
Normal file
182
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node.go
generated
vendored
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
package leafnodes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
type synchronizedBeforeSuiteNode struct {
|
||||
runnerA *runner
|
||||
runnerB *runner
|
||||
|
||||
data []byte
|
||||
|
||||
outcome types.SpecState
|
||||
failure types.SpecFailure
|
||||
runTime time.Duration
|
||||
}
|
||||
|
||||
func NewSynchronizedBeforeSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode {
|
||||
node := &synchronizedBeforeSuiteNode{}
|
||||
|
||||
node.runnerA = newRunner(node.wrapA(bodyA), codeLocation, timeout, failer, types.SpecComponentTypeBeforeSuite, 0)
|
||||
node.runnerB = newRunner(node.wrapB(bodyB), codeLocation, timeout, failer, types.SpecComponentTypeBeforeSuite, 0)
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (node *synchronizedBeforeSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool {
|
||||
t := time.Now()
|
||||
defer func() {
|
||||
node.runTime = time.Since(t)
|
||||
}()
|
||||
|
||||
if parallelNode == 1 {
|
||||
node.outcome, node.failure = node.runA(parallelTotal, syncHost)
|
||||
} else {
|
||||
node.outcome, node.failure = node.waitForA(syncHost)
|
||||
}
|
||||
|
||||
if node.outcome != types.SpecStatePassed {
|
||||
return false
|
||||
}
|
||||
node.outcome, node.failure = node.runnerB.run()
|
||||
|
||||
return node.outcome == types.SpecStatePassed
|
||||
}
|
||||
|
||||
func (node *synchronizedBeforeSuiteNode) runA(parallelTotal int, syncHost string) (types.SpecState, types.SpecFailure) {
|
||||
outcome, failure := node.runnerA.run()
|
||||
|
||||
if parallelTotal > 1 {
|
||||
state := types.RemoteBeforeSuiteStatePassed
|
||||
if outcome != types.SpecStatePassed {
|
||||
state = types.RemoteBeforeSuiteStateFailed
|
||||
}
|
||||
json := (types.RemoteBeforeSuiteData{
|
||||
Data: node.data,
|
||||
State: state,
|
||||
}).ToJSON()
|
||||
http.Post(syncHost+"/BeforeSuiteState", "application/json", bytes.NewBuffer(json))
|
||||
}
|
||||
|
||||
return outcome, failure
|
||||
}
|
||||
|
||||
func (node *synchronizedBeforeSuiteNode) waitForA(syncHost string) (types.SpecState, types.SpecFailure) {
|
||||
failure := func(message string) types.SpecFailure {
|
||||
return types.SpecFailure{
|
||||
Message: message,
|
||||
Location: node.runnerA.codeLocation,
|
||||
ComponentType: node.runnerA.nodeType,
|
||||
ComponentIndex: node.runnerA.componentIndex,
|
||||
ComponentCodeLocation: node.runnerA.codeLocation,
|
||||
}
|
||||
}
|
||||
for {
|
||||
resp, err := http.Get(syncHost + "/BeforeSuiteState")
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
return types.SpecStateFailed, failure("Failed to fetch BeforeSuite state")
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return types.SpecStateFailed, failure("Failed to read BeforeSuite state")
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
beforeSuiteData := types.RemoteBeforeSuiteData{}
|
||||
err = json.Unmarshal(body, &beforeSuiteData)
|
||||
if err != nil {
|
||||
return types.SpecStateFailed, failure("Failed to decode BeforeSuite state")
|
||||
}
|
||||
|
||||
switch beforeSuiteData.State {
|
||||
case types.RemoteBeforeSuiteStatePassed:
|
||||
node.data = beforeSuiteData.Data
|
||||
return types.SpecStatePassed, types.SpecFailure{}
|
||||
case types.RemoteBeforeSuiteStateFailed:
|
||||
return types.SpecStateFailed, failure("BeforeSuite on Node 1 failed")
|
||||
case types.RemoteBeforeSuiteStateDisappeared:
|
||||
return types.SpecStateFailed, failure("Node 1 disappeared before completing BeforeSuite")
|
||||
}
|
||||
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
|
||||
return types.SpecStateFailed, failure("Shouldn't get here!")
|
||||
}
|
||||
|
||||
func (node *synchronizedBeforeSuiteNode) Passed() bool {
|
||||
return node.outcome == types.SpecStatePassed
|
||||
}
|
||||
|
||||
func (node *synchronizedBeforeSuiteNode) Summary() *types.SetupSummary {
|
||||
return &types.SetupSummary{
|
||||
ComponentType: node.runnerA.nodeType,
|
||||
CodeLocation: node.runnerA.codeLocation,
|
||||
State: node.outcome,
|
||||
RunTime: node.runTime,
|
||||
Failure: node.failure,
|
||||
}
|
||||
}
|
||||
|
||||
func (node *synchronizedBeforeSuiteNode) wrapA(bodyA interface{}) interface{} {
|
||||
typeA := reflect.TypeOf(bodyA)
|
||||
if typeA.Kind() != reflect.Func {
|
||||
panic("SynchronizedBeforeSuite expects a function as its first argument")
|
||||
}
|
||||
|
||||
takesNothing := typeA.NumIn() == 0
|
||||
takesADoneChannel := typeA.NumIn() == 1 && typeA.In(0).Kind() == reflect.Chan && typeA.In(0).Elem().Kind() == reflect.Interface
|
||||
returnsBytes := typeA.NumOut() == 1 && typeA.Out(0).Kind() == reflect.Slice && typeA.Out(0).Elem().Kind() == reflect.Uint8
|
||||
|
||||
if !((takesNothing || takesADoneChannel) && returnsBytes) {
|
||||
panic("SynchronizedBeforeSuite's first argument should be a function that returns []byte and either takes no arguments or takes a Done channel.")
|
||||
}
|
||||
|
||||
if takesADoneChannel {
|
||||
return func(done chan<- interface{}) {
|
||||
out := reflect.ValueOf(bodyA).Call([]reflect.Value{reflect.ValueOf(done)})
|
||||
node.data = out[0].Interface().([]byte)
|
||||
}
|
||||
}
|
||||
|
||||
return func() {
|
||||
out := reflect.ValueOf(bodyA).Call([]reflect.Value{})
|
||||
node.data = out[0].Interface().([]byte)
|
||||
}
|
||||
}
|
||||
|
||||
func (node *synchronizedBeforeSuiteNode) wrapB(bodyB interface{}) interface{} {
|
||||
typeB := reflect.TypeOf(bodyB)
|
||||
if typeB.Kind() != reflect.Func {
|
||||
panic("SynchronizedBeforeSuite expects a function as its second argument")
|
||||
}
|
||||
|
||||
returnsNothing := typeB.NumOut() == 0
|
||||
takesBytesOnly := typeB.NumIn() == 1 && typeB.In(0).Kind() == reflect.Slice && typeB.In(0).Elem().Kind() == reflect.Uint8
|
||||
takesBytesAndDone := typeB.NumIn() == 2 &&
|
||||
typeB.In(0).Kind() == reflect.Slice && typeB.In(0).Elem().Kind() == reflect.Uint8 &&
|
||||
typeB.In(1).Kind() == reflect.Chan && typeB.In(1).Elem().Kind() == reflect.Interface
|
||||
|
||||
if !((takesBytesOnly || takesBytesAndDone) && returnsNothing) {
|
||||
panic("SynchronizedBeforeSuite's second argument should be a function that returns nothing and either takes []byte or ([]byte, Done)")
|
||||
}
|
||||
|
||||
if takesBytesAndDone {
|
||||
return func(done chan<- interface{}) {
|
||||
reflect.ValueOf(bodyB).Call([]reflect.Value{reflect.ValueOf(node.data), reflect.ValueOf(done)})
|
||||
}
|
||||
}
|
||||
|
||||
return func() {
|
||||
reflect.ValueOf(bodyB).Call([]reflect.Value{reflect.ValueOf(node.data)})
|
||||
}
|
||||
}
|
||||
445
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node_test.go
generated
vendored
Normal file
445
vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,445 @@
|
|||
package leafnodes_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/internal/leafnodes"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/onsi/gomega/ghttp"
|
||||
"net/http"
|
||||
|
||||
"github.com/onsi/ginkgo/internal/codelocation"
|
||||
Failer "github.com/onsi/ginkgo/internal/failer"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ = Describe("SynchronizedBeforeSuiteNode", func() {
|
||||
var failer *Failer.Failer
|
||||
var node SuiteNode
|
||||
var codeLocation types.CodeLocation
|
||||
var innerCodeLocation types.CodeLocation
|
||||
var outcome bool
|
||||
var server *ghttp.Server
|
||||
|
||||
BeforeEach(func() {
|
||||
server = ghttp.NewServer()
|
||||
codeLocation = codelocation.New(0)
|
||||
innerCodeLocation = codelocation.New(0)
|
||||
failer = Failer.New()
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
server.Close()
|
||||
})
|
||||
|
||||
newNode := func(bodyA interface{}, bodyB interface{}) SuiteNode {
|
||||
return NewSynchronizedBeforeSuiteNode(bodyA, bodyB, codeLocation, time.Millisecond, failer)
|
||||
}
|
||||
|
||||
Describe("when not running in parallel", func() {
|
||||
Context("when all is well", func() {
|
||||
var data []byte
|
||||
BeforeEach(func() {
|
||||
data = nil
|
||||
|
||||
node = newNode(func() []byte {
|
||||
return []byte("my data")
|
||||
}, func(d []byte) {
|
||||
data = d
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should run A, then B passing the output from A to B", func() {
|
||||
Ω(data).Should(Equal([]byte("my data")))
|
||||
})
|
||||
|
||||
It("should report success", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
Ω(node.Passed()).Should(BeTrue())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStatePassed))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when A fails", func() {
|
||||
var ranB bool
|
||||
BeforeEach(func() {
|
||||
ranB = false
|
||||
node = newNode(func() []byte {
|
||||
failer.Fail("boom", innerCodeLocation)
|
||||
return nil
|
||||
}, func([]byte) {
|
||||
ranB = true
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should not run B", func() {
|
||||
Ω(ranB).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should report failure", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStateFailed))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when B fails", func() {
|
||||
BeforeEach(func() {
|
||||
node = newNode(func() []byte {
|
||||
return nil
|
||||
}, func([]byte) {
|
||||
failer.Fail("boom", innerCodeLocation)
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should report failure", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStateFailed))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when A times out", func() {
|
||||
var ranB bool
|
||||
BeforeEach(func() {
|
||||
ranB = false
|
||||
node = newNode(func(Done) []byte {
|
||||
time.Sleep(time.Second)
|
||||
return nil
|
||||
}, func([]byte) {
|
||||
ranB = true
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should not run B", func() {
|
||||
Ω(ranB).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should report failure", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStateTimedOut))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when B times out", func() {
|
||||
BeforeEach(func() {
|
||||
node = newNode(func() []byte {
|
||||
return nil
|
||||
}, func([]byte, Done) {
|
||||
time.Sleep(time.Second)
|
||||
})
|
||||
|
||||
outcome = node.Run(1, 1, server.URL())
|
||||
})
|
||||
|
||||
It("should report failure", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
Ω(node.Summary().State).Should(Equal(types.SpecStateTimedOut))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("when running in parallel", func() {
|
||||
var ranB bool
|
||||
var parallelNode, parallelTotal int
|
||||
BeforeEach(func() {
|
||||
ranB = false
|
||||
parallelNode, parallelTotal = 1, 3
|
||||
})
|
||||
|
||||
Context("as the first node, it runs A", func() {
|
||||
var expectedState types.RemoteBeforeSuiteData
|
||||
|
||||
BeforeEach(func() {
|
||||
parallelNode, parallelTotal = 1, 3
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
server.AppendHandlers(ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("POST", "/BeforeSuiteState"),
|
||||
ghttp.VerifyJSONRepresenting(expectedState),
|
||||
))
|
||||
|
||||
outcome = node.Run(parallelNode, parallelTotal, server.URL())
|
||||
})
|
||||
|
||||
Context("when A succeeds", func() {
|
||||
BeforeEach(func() {
|
||||
expectedState = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStatePassed}
|
||||
|
||||
node = newNode(func() []byte {
|
||||
return []byte("my data")
|
||||
}, func([]byte) {
|
||||
ranB = true
|
||||
})
|
||||
})
|
||||
|
||||
It("should post about A succeeding", func() {
|
||||
Ω(server.ReceivedRequests()).Should(HaveLen(1))
|
||||
})
|
||||
|
||||
It("should run B", func() {
|
||||
Ω(ranB).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("should report success", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when A fails", func() {
|
||||
BeforeEach(func() {
|
||||
expectedState = types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStateFailed}
|
||||
|
||||
node = newNode(func() []byte {
|
||||
panic("BAM")
|
||||
return []byte("my data")
|
||||
}, func([]byte) {
|
||||
ranB = true
|
||||
})
|
||||
})
|
||||
|
||||
It("should post about A failing", func() {
|
||||
Ω(server.ReceivedRequests()).Should(HaveLen(1))
|
||||
})
|
||||
|
||||
It("should not run B", func() {
|
||||
Ω(ranB).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should report failure", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("as the Nth node", func() {
|
||||
var statusCode int
|
||||
var response interface{}
|
||||
var ranA bool
|
||||
var bData []byte
|
||||
|
||||
BeforeEach(func() {
|
||||
ranA = false
|
||||
bData = nil
|
||||
|
||||
statusCode = http.StatusOK
|
||||
|
||||
server.AppendHandlers(ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("GET", "/BeforeSuiteState"),
|
||||
ghttp.RespondWith(http.StatusOK, string((types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}).ToJSON())),
|
||||
), ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("GET", "/BeforeSuiteState"),
|
||||
ghttp.RespondWith(http.StatusOK, string((types.RemoteBeforeSuiteData{nil, types.RemoteBeforeSuiteStatePending}).ToJSON())),
|
||||
), ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("GET", "/BeforeSuiteState"),
|
||||
ghttp.RespondWithJSONEncodedPtr(&statusCode, &response),
|
||||
))
|
||||
|
||||
node = newNode(func() []byte {
|
||||
ranA = true
|
||||
return nil
|
||||
}, func(data []byte) {
|
||||
bData = data
|
||||
})
|
||||
|
||||
parallelNode, parallelTotal = 2, 3
|
||||
})
|
||||
|
||||
Context("when A on node1 succeeds", func() {
|
||||
BeforeEach(func() {
|
||||
response = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStatePassed}
|
||||
outcome = node.Run(parallelNode, parallelTotal, server.URL())
|
||||
})
|
||||
|
||||
It("should not run A", func() {
|
||||
Ω(ranA).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should poll for A", func() {
|
||||
Ω(server.ReceivedRequests()).Should(HaveLen(3))
|
||||
})
|
||||
|
||||
It("should run B when the polling succeeds", func() {
|
||||
Ω(bData).Should(Equal([]byte("my data")))
|
||||
})
|
||||
|
||||
It("should succeed", func() {
|
||||
Ω(outcome).Should(BeTrue())
|
||||
Ω(node.Passed()).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when A on node1 fails", func() {
|
||||
BeforeEach(func() {
|
||||
response = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStateFailed}
|
||||
outcome = node.Run(parallelNode, parallelTotal, server.URL())
|
||||
})
|
||||
|
||||
It("should not run A", func() {
|
||||
Ω(ranA).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should poll for A", func() {
|
||||
Ω(server.ReceivedRequests()).Should(HaveLen(3))
|
||||
})
|
||||
|
||||
It("should not run B", func() {
|
||||
Ω(bData).Should(BeNil())
|
||||
})
|
||||
|
||||
It("should fail", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
|
||||
summary := node.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStateFailed))
|
||||
Ω(summary.Failure.Message).Should(Equal("BeforeSuite on Node 1 failed"))
|
||||
Ω(summary.Failure.Location).Should(Equal(codeLocation))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeBeforeSuite))
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when node1 disappears", func() {
|
||||
BeforeEach(func() {
|
||||
response = types.RemoteBeforeSuiteData{[]byte("my data"), types.RemoteBeforeSuiteStateDisappeared}
|
||||
outcome = node.Run(parallelNode, parallelTotal, server.URL())
|
||||
})
|
||||
|
||||
It("should not run A", func() {
|
||||
Ω(ranA).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("should poll for A", func() {
|
||||
Ω(server.ReceivedRequests()).Should(HaveLen(3))
|
||||
})
|
||||
|
||||
It("should not run B", func() {
|
||||
Ω(bData).Should(BeNil())
|
||||
})
|
||||
|
||||
It("should fail", func() {
|
||||
Ω(outcome).Should(BeFalse())
|
||||
Ω(node.Passed()).Should(BeFalse())
|
||||
|
||||
summary := node.Summary()
|
||||
Ω(summary.State).Should(Equal(types.SpecStateFailed))
|
||||
Ω(summary.Failure.Message).Should(Equal("Node 1 disappeared before completing BeforeSuite"))
|
||||
Ω(summary.Failure.Location).Should(Equal(codeLocation))
|
||||
Ω(summary.Failure.ComponentType).Should(Equal(types.SpecComponentTypeBeforeSuite))
|
||||
Ω(summary.Failure.ComponentIndex).Should(Equal(0))
|
||||
Ω(summary.Failure.ComponentCodeLocation).Should(Equal(codeLocation))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("construction", func() {
|
||||
Describe("the first function", func() {
|
||||
Context("when the first function returns a byte array", func() {
|
||||
Context("and takes nothing", func() {
|
||||
It("should be fine", func() {
|
||||
Ω(func() {
|
||||
newNode(func() []byte { return nil }, func([]byte) {})
|
||||
}).ShouldNot(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("and takes a done function", func() {
|
||||
It("should be fine", func() {
|
||||
Ω(func() {
|
||||
newNode(func(Done) []byte { return nil }, func([]byte) {})
|
||||
}).ShouldNot(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("and takes more than one thing", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
newNode(func(Done, Done) []byte { return nil }, func([]byte) {})
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("and takes something else", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
newNode(func(bool) []byte { return nil }, func([]byte) {})
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the first function does not return a byte array", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
newNode(func() {}, func([]byte) {})
|
||||
}).Should(Panic())
|
||||
|
||||
Ω(func() {
|
||||
newNode(func() []int { return nil }, func([]byte) {})
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("the second function", func() {
|
||||
Context("when the second function takes a byte array", func() {
|
||||
It("should be fine", func() {
|
||||
Ω(func() {
|
||||
newNode(func() []byte { return nil }, func([]byte) {})
|
||||
}).ShouldNot(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when it also takes a done channel", func() {
|
||||
It("should be fine", func() {
|
||||
Ω(func() {
|
||||
newNode(func() []byte { return nil }, func([]byte, Done) {})
|
||||
}).ShouldNot(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("if it takes anything else", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
newNode(func() []byte { return nil }, func([]byte, chan bool) {})
|
||||
}).Should(Panic())
|
||||
|
||||
Ω(func() {
|
||||
newNode(func() []byte { return nil }, func(string) {})
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("if it takes nothing at all", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
newNode(func() []byte { return nil }, func() {})
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
|
||||
Context("if it returns something", func() {
|
||||
It("should panic", func() {
|
||||
Ω(func() {
|
||||
newNode(func() []byte { return nil }, func([]byte) []byte { return nil })
|
||||
}).Should(Panic())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue