summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell.go')
-rw-r--r--src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell.go174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell.go
new file mode 100644
index 00000000000..f2fa10711db
--- /dev/null
+++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell.go
@@ -0,0 +1,174 @@
+package system
+
+import (
+ "log"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+///////////////////////////////////////////////////////////////////////////////
+// Integration: ///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+type Shell struct {
+ coverage bool
+ gobin string
+ reportsPath string
+ defaultTimeout string
+}
+
+func NewShell(gobin, reportsPath string, coverage bool, defaultTimeout string) *Shell {
+ return &Shell{
+ coverage: coverage,
+ gobin: gobin,
+ reportsPath: reportsPath,
+ defaultTimeout: defaultTimeout,
+ }
+}
+
+func (self *Shell) GoTest(directory, packageName string, tags, arguments []string) (output string, err error) {
+ reportFilename := strings.Replace(packageName, "/", "-", -1)
+ reportPath := filepath.Join(self.reportsPath, reportFilename)
+ reportData := reportPath + ".txt"
+ reportHTML := reportPath + ".html"
+ tagsArg := "-tags=" + strings.Join(tags, ",")
+
+ goconvey := findGoConvey(directory, self.gobin, packageName, tagsArg).Execute()
+ compilation := compile(directory, self.gobin, tagsArg).Execute()
+ withCoverage := runWithCoverage(compilation, goconvey, self.coverage, reportData, directory, self.gobin, self.defaultTimeout, tagsArg, arguments).Execute()
+ final := runWithoutCoverage(compilation, withCoverage, goconvey, directory, self.gobin, self.defaultTimeout, tagsArg, arguments).Execute()
+ go generateReports(final, self.coverage, directory, self.gobin, reportData, reportHTML).Execute()
+
+ return final.Output, final.Error
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Functional Core:////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+func findGoConvey(directory, gobin, packageName, tagsArg string) Command {
+ return NewCommand(directory, gobin, "list", "-f", "'{{.TestImports}}'", tagsArg, packageName)
+}
+
+func compile(directory, gobin, tagsArg string) Command {
+ return NewCommand(directory, gobin, "test", "-i", tagsArg)
+}
+
+func runWithCoverage(compile, goconvey Command, coverage bool, reportPath, directory, gobin, defaultTimeout, tagsArg string, customArguments []string) Command {
+ if compile.Error != nil || goconvey.Error != nil {
+ return compile
+ }
+
+ if !coverage {
+ return compile
+ }
+
+ arguments := []string{"test", "-v", "-coverprofile=" + reportPath, tagsArg}
+
+ customArgsText := strings.Join(customArguments, "\t")
+ if !strings.Contains(customArgsText, "-covermode=") {
+ arguments = append(arguments, "-covermode=set")
+ }
+
+ if !strings.Contains(customArgsText, "-timeout=") {
+ arguments = append(arguments, "-timeout="+defaultTimeout)
+ }
+
+ if strings.Contains(goconvey.Output, goconveyDSLImport) {
+ arguments = append(arguments, "-json")
+ }
+
+ arguments = append(arguments, customArguments...)
+
+ return NewCommand(directory, gobin, arguments...)
+}
+
+func runWithoutCoverage(compile, withCoverage, goconvey Command, directory, gobin, defaultTimeout, tagsArg string, customArguments []string) Command {
+ if compile.Error != nil {
+ return compile
+ }
+
+ if goconvey.Error != nil {
+ log.Println(gopathProblem, goconvey.Output, goconvey.Error)
+ return goconvey
+ }
+
+ if coverageStatementRE.MatchString(withCoverage.Output) {
+ return withCoverage
+ }
+
+ log.Printf("Coverage output: %v", withCoverage.Output)
+
+ log.Print("Run without coverage")
+
+ arguments := []string{"test", "-v", tagsArg}
+ customArgsText := strings.Join(customArguments, "\t")
+ if !strings.Contains(customArgsText, "-timeout=") {
+ arguments = append(arguments, "-timeout="+defaultTimeout)
+ }
+
+ if strings.Contains(goconvey.Output, goconveyDSLImport) {
+ arguments = append(arguments, "-json")
+ }
+ arguments = append(arguments, customArguments...)
+ return NewCommand(directory, gobin, arguments...)
+}
+
+func generateReports(previous Command, coverage bool, directory, gobin, reportData, reportHTML string) Command {
+ if previous.Error != nil {
+ return previous
+ }
+
+ if !coverage {
+ return previous
+ }
+
+ return NewCommand(directory, gobin, "tool", "cover", "-html="+reportData, "-o", reportHTML)
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Imperative Shell: //////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+type Command struct {
+ directory string
+ executable string
+ arguments []string
+
+ Output string
+ Error error
+}
+
+func NewCommand(directory, executable string, arguments ...string) Command {
+ return Command{
+ directory: directory,
+ executable: executable,
+ arguments: arguments,
+ }
+}
+
+func (this Command) Execute() Command {
+ if len(this.executable) == 0 {
+ return this
+ }
+
+ if len(this.Output) > 0 || this.Error != nil {
+ return this
+ }
+
+ command := exec.Command(this.executable, this.arguments...)
+ command.Dir = this.directory
+ var rawOutput []byte
+ rawOutput, this.Error = command.CombinedOutput()
+ this.Output = string(rawOutput)
+ return this
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+const goconveyDSLImport = "github.com/smartystreets/goconvey/convey " // note the trailing space: we don't want to target packages nested in the /convey package.
+const gopathProblem = "Please run goconvey from within $GOPATH/src (also, symlinks might be problematic). Output and Error: "
+
+var coverageStatementRE = regexp.MustCompile(`(?m)^coverage: \d+\.\d% of statements(.*)$|^panic: test timed out after `)