summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester_test.go')
-rw-r--r--src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester_test.go254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester_test.go
new file mode 100644
index 00000000000..d540c546d9a
--- /dev/null
+++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester_test.go
@@ -0,0 +1,254 @@
+package executor
+
+import (
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "testing"
+ "time"
+
+ . "github.com/smartystreets/goconvey/convey"
+ "github.com/smartystreets/goconvey/web/server/contract"
+)
+
+func init() {
+ log.SetOutput(ioutil.Discard)
+}
+
+func TestConcurrentTester(t *testing.T) {
+ t.Skip("BROKEN!")
+
+ Convey("Subject: Controlled execution of test packages", t, func() {
+ fixture := NewTesterFixture()
+
+ Convey("Whenever tests for each package are executed", func() {
+ fixture.InBatchesOf(1).RunTests()
+
+ Convey("The tester should execute the tests in each active package with the correct arguments",
+ fixture.ShouldHaveRecordOfExecutionCommands)
+
+ Convey("There should be a test output result for each active package",
+ fixture.ShouldHaveOneOutputPerInput)
+
+ Convey("The output should be as expected",
+ fixture.OutputShouldBeAsExpected)
+ })
+
+ Convey("When the tests for each package are executed synchronously", func() {
+ fixture.InBatchesOf(1).RunTests()
+
+ Convey("Each active package should be run synchronously and in the given order",
+ fixture.TestsShouldHaveRunContiguously)
+ })
+
+ Convey("When the tests for each package are executed synchronously with failures", func() {
+ fixture.InBatchesOf(1).SetupFailedTestSuites().RunTests()
+
+ Convey("The failed test packages should not result in any panics", func() {
+ So(fixture.recovered, ShouldBeNil)
+ })
+ })
+
+ Convey("When packages are tested concurrently", func() {
+ fixture.InBatchesOf(concurrentBatchSize).RunTests()
+
+ Convey("Active packages should be arranged and tested in batches of the appropriate size",
+ fixture.TestsShouldHaveRunInBatchesOfTwo)
+ })
+
+ Convey("When packages are tested concurrently with failures", func() {
+ fixture.InBatchesOf(concurrentBatchSize).SetupFailedTestSuites().RunTests()
+
+ Convey("The failed test packages should not result in any panics", func() {
+ So(fixture.recovered, ShouldBeNil)
+ })
+ })
+ })
+}
+
+const concurrentBatchSize = 2
+
+type TesterFixture struct {
+ tester *ConcurrentTester
+ shell *TimedShell
+ results []string
+ compilations []*ShellCommand
+ executions []*ShellCommand
+ packages []*contract.Package
+ recovered error
+}
+
+func NewTesterFixture() *TesterFixture {
+ self := new(TesterFixture)
+ self.shell = NewTimedShell()
+ self.tester = NewConcurrentTester(self.shell)
+ self.packages = []*contract.Package{
+ {Path: "a"},
+ {Path: "b"},
+ {Path: "c"},
+ {Path: "d"},
+ {Path: "e", Ignored: true},
+ {Path: "f"},
+ {Path: "g", HasImportCycle: true},
+ }
+ return self
+}
+
+func (self *TesterFixture) InBatchesOf(batchSize int) *TesterFixture {
+ self.tester.SetBatchSize(batchSize)
+ return self
+}
+
+func (self *TesterFixture) SetupAbnormalError(message string) *TesterFixture {
+ self.shell.setTripWire(message)
+ return self
+}
+
+func (self *TesterFixture) SetupFailedTestSuites() *TesterFixture {
+ self.shell.setExitWithError()
+ return self
+}
+
+func (self *TesterFixture) RunTests() {
+ defer func() {
+ if r := recover(); r != nil {
+ self.recovered = r.(error)
+ }
+ }()
+
+ self.tester.TestAll(self.packages)
+ for _, p := range self.packages {
+ self.results = append(self.results, p.Output)
+ }
+ self.executions = self.shell.Executions()
+}
+
+func (self *TesterFixture) ShouldHaveRecordOfExecutionCommands() {
+ executed := []string{"a", "b", "c", "d", "f"}
+ ignored := "e"
+ importCycle := "g"
+ actual := []string{}
+ for _, pkg := range self.executions {
+ actual = append(actual, pkg.Command)
+ }
+ So(actual, ShouldResemble, executed)
+ So(actual, ShouldNotContain, ignored)
+ So(actual, ShouldNotContain, importCycle)
+}
+
+func (self *TesterFixture) ShouldHaveOneOutputPerInput() {
+ So(len(self.results), ShouldEqual, len(self.packages))
+}
+
+func (self *TesterFixture) OutputShouldBeAsExpected() {
+ for _, p := range self.packages {
+ if p.HasImportCycle {
+ So(p.Output, ShouldContainSubstring, "can't load package: import cycle not allowed")
+ So(p.Error.Error(), ShouldContainSubstring, "can't load package: import cycle not allowed")
+ } else {
+ if p.Active() {
+ So(p.Output, ShouldEndWith, p.Path)
+ } else {
+ So(p.Output, ShouldBeBlank)
+ }
+ So(p.Error, ShouldBeNil)
+ }
+ }
+}
+
+func (self *TesterFixture) TestsShouldHaveRunContiguously() {
+ self.OutputShouldBeAsExpected()
+
+ So(self.shell.MaxConcurrentCommands(), ShouldEqual, 1)
+
+ for i := 0; i < len(self.executions)-1; i++ {
+ current := self.executions[i]
+ next := self.executions[i+1]
+ So(current.Started, ShouldHappenBefore, next.Started)
+ So(current.Ended, ShouldHappenOnOrBefore, next.Started)
+ }
+}
+
+func (self *TesterFixture) TestsShouldHaveRunInBatchesOfTwo() {
+ self.OutputShouldBeAsExpected()
+
+ So(self.shell.MaxConcurrentCommands(), ShouldEqual, concurrentBatchSize)
+}
+
+/**** Fakes ****/
+
+type ShellCommand struct {
+ Command string
+ Started time.Time
+ Ended time.Time
+}
+
+type TimedShell struct {
+ executions []*ShellCommand
+ panicMessage string
+ err error
+}
+
+func (self *TimedShell) Executions() []*ShellCommand {
+ return self.executions
+}
+
+func (self *TimedShell) MaxConcurrentCommands() int {
+ var concurrent int
+
+ for x, current := range self.executions {
+ concurrentWith_x := 1
+ for y, comparison := range self.executions {
+ if y == x {
+ continue
+ } else if concurrentWith(current, comparison) {
+ concurrentWith_x++
+ }
+ }
+ if concurrentWith_x > concurrent {
+ concurrent = concurrentWith_x
+ }
+ }
+ return concurrent
+}
+
+func concurrentWith(current, comparison *ShellCommand) bool {
+ return ((comparison.Started == current.Started || comparison.Started.After(current.Started)) &&
+ (comparison.Started.Before(current.Ended)))
+}
+
+func (self *TimedShell) setTripWire(message string) {
+ self.panicMessage = message
+}
+
+func (self *TimedShell) setExitWithError() {
+ self.err = errors.New("Simulate test failure")
+}
+
+func (self *TimedShell) GoTest(directory, packageName string, arguments, tags []string) (output string, err error) {
+ if self.panicMessage != "" {
+ return "", errors.New(self.panicMessage)
+ }
+
+ output = directory
+ err = self.err
+ self.executions = append(self.executions, self.composeCommand(directory))
+ return
+}
+
+func (self *TimedShell) composeCommand(commandText string) *ShellCommand {
+ start := time.Now()
+ time.Sleep(nap)
+ end := time.Now()
+ return &ShellCommand{commandText, start, end}
+}
+
+func NewTimedShell() *TimedShell {
+ self := new(TimedShell)
+ self.executions = []*ShellCommand{}
+ return self
+}
+
+var nap, _ = time.ParseDuration("10ms")
+var _ = fmt.Sprintf("fmt")