Use Go 1.5 vendoring instead of Godeps
Change made by: - running "gvt fetch" on each of the packages mentioned in Godeps/Godeps.json - `rm -rf Godeps` - tweaking the build scripts to not mention Godeps - tweaking the build scripts to test `./lib/...`, `./cmd/...` explicitly (to avoid testing vendor) - tweaking the build scripts to not juggle GOPATH for Godeps and instead set GO15VENDOREXPERIMENT. This also results in some updated packages at the same time I bet. Building with Go 1.3 and 1.4 still *works* but won't use our vendored dependencies - the user needs to have the actual packages in their GOPATH then, which they'll get with a normal "go get". Building with Go 1.6+ will get our vendored dependencies by default even when not using our build script, which is nice. By doing this we gain some freedom in that we can pick and choose manually what to include in vendor, as it's not based on just dependency analysis of our own code. This is also a risk as we might pick up dependencies we are unaware of, as the build may work locally with those packages present in GOPATH. On the other hand the build server will detect this as it has no packages in it's GOPATH beyond what is included in the repo. Recommended tool to manage dependencies is github.com/FiloSottile/gvt.
This commit is contained in:
36
vendor/github.com/onsi/gomega/gexec/_fixture/firefly/main.go
generated
vendored
Normal file
36
vendor/github.com/onsi/gomega/gexec/_fixture/firefly/main.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var outQuote = "We've done the impossible, and that makes us mighty."
|
||||
var errQuote = "Ah, curse your sudden but inevitable betrayal!"
|
||||
|
||||
var randomQuotes = []string{
|
||||
"Can we maybe vote on the whole murdering people issue?",
|
||||
"I swear by my pretty floral bonnet, I will end you.",
|
||||
"My work's illegal, but at least it's honest.",
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Fprintln(os.Stdout, outQuote)
|
||||
fmt.Fprintln(os.Stderr, errQuote)
|
||||
|
||||
randomIndex := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(len(randomQuotes))
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
fmt.Fprintln(os.Stdout, randomQuotes[randomIndex])
|
||||
|
||||
if len(os.Args) == 2 {
|
||||
exitCode, _ := strconv.Atoi(os.Args[1])
|
||||
os.Exit(exitCode)
|
||||
} else {
|
||||
os.Exit(randomIndex)
|
||||
}
|
||||
}
|
||||
78
vendor/github.com/onsi/gomega/gexec/build.go
generated
vendored
Normal file
78
vendor/github.com/onsi/gomega/gexec/build.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package gexec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var tmpDir string
|
||||
|
||||
/*
|
||||
Build uses go build to compile the package at packagePath. The resulting binary is saved off in a temporary directory.
|
||||
A path pointing to this binary is returned.
|
||||
|
||||
Build uses the $GOPATH set in your environment. It passes the variadic args on to `go build`.
|
||||
*/
|
||||
func Build(packagePath string, args ...string) (compiledPath string, err error) {
|
||||
return BuildIn(os.Getenv("GOPATH"), packagePath, args...)
|
||||
}
|
||||
|
||||
/*
|
||||
BuildIn is identical to Build but allows you to specify a custom $GOPATH (the first argument).
|
||||
*/
|
||||
func BuildIn(gopath string, packagePath string, args ...string) (compiledPath string, err error) {
|
||||
tmpDir, err := temporaryDirectory()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(gopath) == 0 {
|
||||
return "", errors.New("$GOPATH not provided when building " + packagePath)
|
||||
}
|
||||
|
||||
executable := filepath.Join(tmpDir, path.Base(packagePath))
|
||||
if runtime.GOOS == "windows" {
|
||||
executable = executable + ".exe"
|
||||
}
|
||||
|
||||
cmdArgs := append([]string{"build"}, args...)
|
||||
cmdArgs = append(cmdArgs, "-o", executable, packagePath)
|
||||
|
||||
build := exec.Command("go", cmdArgs...)
|
||||
build.Env = append([]string{"GOPATH=" + gopath}, os.Environ()...)
|
||||
|
||||
output, err := build.CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to build %s:\n\nError:\n%s\n\nOutput:\n%s", packagePath, err, string(output))
|
||||
}
|
||||
|
||||
return executable, nil
|
||||
}
|
||||
|
||||
/*
|
||||
You should call CleanupBuildArtifacts before your test ends to clean up any temporary artifacts generated by
|
||||
gexec. In Ginkgo this is typically done in an AfterSuite callback.
|
||||
*/
|
||||
func CleanupBuildArtifacts() {
|
||||
if tmpDir != "" {
|
||||
os.RemoveAll(tmpDir)
|
||||
}
|
||||
}
|
||||
|
||||
func temporaryDirectory() (string, error) {
|
||||
var err error
|
||||
if tmpDir == "" {
|
||||
tmpDir, err = ioutil.TempDir("", "gexec_artifacts")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return ioutil.TempDir(tmpDir, "g")
|
||||
}
|
||||
88
vendor/github.com/onsi/gomega/gexec/exit_matcher.go
generated
vendored
Normal file
88
vendor/github.com/onsi/gomega/gexec/exit_matcher.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package gexec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/onsi/gomega/format"
|
||||
)
|
||||
|
||||
/*
|
||||
The Exit matcher operates on a session:
|
||||
|
||||
Ω(session).Should(Exit(<optional status code>))
|
||||
|
||||
Exit passes if the session has already exited.
|
||||
|
||||
If no status code is provided, then Exit will succeed if the session has exited regardless of exit code.
|
||||
Otherwise, Exit will only succeed if the process has exited with the provided status code.
|
||||
|
||||
Note that the process must have already exited. To wait for a process to exit, use Eventually:
|
||||
|
||||
Eventually(session, 3).Should(Exit(0))
|
||||
*/
|
||||
func Exit(optionalExitCode ...int) *exitMatcher {
|
||||
exitCode := -1
|
||||
if len(optionalExitCode) > 0 {
|
||||
exitCode = optionalExitCode[0]
|
||||
}
|
||||
|
||||
return &exitMatcher{
|
||||
exitCode: exitCode,
|
||||
}
|
||||
}
|
||||
|
||||
type exitMatcher struct {
|
||||
exitCode int
|
||||
didExit bool
|
||||
actualExitCode int
|
||||
}
|
||||
|
||||
type Exiter interface {
|
||||
ExitCode() int
|
||||
}
|
||||
|
||||
func (m *exitMatcher) Match(actual interface{}) (success bool, err error) {
|
||||
exiter, ok := actual.(Exiter)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("Exit must be passed a gexec.Exiter (Missing method ExitCode() int) Got:\n%s", format.Object(actual, 1))
|
||||
}
|
||||
|
||||
m.actualExitCode = exiter.ExitCode()
|
||||
|
||||
if m.actualExitCode == -1 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if m.exitCode == -1 {
|
||||
return true, nil
|
||||
}
|
||||
return m.exitCode == m.actualExitCode, nil
|
||||
}
|
||||
|
||||
func (m *exitMatcher) FailureMessage(actual interface{}) (message string) {
|
||||
if m.actualExitCode == -1 {
|
||||
return "Expected process to exit. It did not."
|
||||
} else {
|
||||
return format.Message(m.actualExitCode, "to match exit code:", m.exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *exitMatcher) NegatedFailureMessage(actual interface{}) (message string) {
|
||||
if m.actualExitCode == -1 {
|
||||
return "you really shouldn't be able to see this!"
|
||||
} else {
|
||||
if m.exitCode == -1 {
|
||||
return "Expected process not to exit. It did."
|
||||
} else {
|
||||
return format.Message(m.actualExitCode, "not to match exit code:", m.exitCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *exitMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
|
||||
session, ok := actual.(*Session)
|
||||
if ok {
|
||||
return session.ExitCode() == -1
|
||||
}
|
||||
return true
|
||||
}
|
||||
113
vendor/github.com/onsi/gomega/gexec/exit_matcher_test.go
generated
vendored
Normal file
113
vendor/github.com/onsi/gomega/gexec/exit_matcher_test.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
package gexec_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega/gexec"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
type NeverExits struct{}
|
||||
|
||||
func (e NeverExits) ExitCode() int {
|
||||
return -1
|
||||
}
|
||||
|
||||
var _ = Describe("ExitMatcher", func() {
|
||||
var command *exec.Cmd
|
||||
var session *Session
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
command = exec.Command(fireflyPath, "0")
|
||||
session, err = Start(command, nil, nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
|
||||
Describe("when passed something that is an Exiter", func() {
|
||||
It("should act normally", func() {
|
||||
failures := InterceptGomegaFailures(func() {
|
||||
Ω(NeverExits{}).Should(Exit())
|
||||
})
|
||||
|
||||
Ω(failures[0]).Should(ContainSubstring("Expected process to exit. It did not."))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("when passed something that is not an Exiter", func() {
|
||||
It("should error", func() {
|
||||
failures := InterceptGomegaFailures(func() {
|
||||
Ω("aardvark").Should(Exit())
|
||||
})
|
||||
|
||||
Ω(failures[0]).Should(ContainSubstring("Exit must be passed a gexec.Exiter"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("with no exit code", func() {
|
||||
It("should say the right things when it fails", func() {
|
||||
Ω(session).ShouldNot(Exit())
|
||||
|
||||
failures := InterceptGomegaFailures(func() {
|
||||
Ω(session).Should(Exit())
|
||||
})
|
||||
|
||||
Ω(failures[0]).Should(ContainSubstring("Expected process to exit. It did not."))
|
||||
|
||||
Eventually(session).Should(Exit())
|
||||
|
||||
Ω(session).Should(Exit())
|
||||
|
||||
failures = InterceptGomegaFailures(func() {
|
||||
Ω(session).ShouldNot(Exit())
|
||||
})
|
||||
|
||||
Ω(failures[0]).Should(ContainSubstring("Expected process not to exit. It did."))
|
||||
})
|
||||
})
|
||||
|
||||
Context("with an exit code", func() {
|
||||
It("should say the right things when it fails", func() {
|
||||
Ω(session).ShouldNot(Exit(0))
|
||||
Ω(session).ShouldNot(Exit(1))
|
||||
|
||||
failures := InterceptGomegaFailures(func() {
|
||||
Ω(session).Should(Exit(0))
|
||||
})
|
||||
|
||||
Ω(failures[0]).Should(ContainSubstring("Expected process to exit. It did not."))
|
||||
|
||||
Eventually(session).Should(Exit(0))
|
||||
|
||||
Ω(session).Should(Exit(0))
|
||||
|
||||
failures = InterceptGomegaFailures(func() {
|
||||
Ω(session).Should(Exit(1))
|
||||
})
|
||||
|
||||
Ω(failures[0]).Should(ContainSubstring("to match exit code:"))
|
||||
|
||||
Ω(session).ShouldNot(Exit(1))
|
||||
|
||||
failures = InterceptGomegaFailures(func() {
|
||||
Ω(session).ShouldNot(Exit(0))
|
||||
})
|
||||
|
||||
Ω(failures[0]).Should(ContainSubstring("not to match exit code:"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("bailing out early", func() {
|
||||
It("should bail out early once the process exits", func() {
|
||||
t := time.Now()
|
||||
|
||||
failures := InterceptGomegaFailures(func() {
|
||||
Eventually(session).Should(Exit(1))
|
||||
})
|
||||
Ω(time.Since(t)).Should(BeNumerically("<=", 500*time.Millisecond))
|
||||
Ω(failures).Should(HaveLen(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
26
vendor/github.com/onsi/gomega/gexec/gexec_suite_test.go
generated
vendored
Normal file
26
vendor/github.com/onsi/gomega/gexec/gexec_suite_test.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package gexec_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/gexec"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
var fireflyPath string
|
||||
|
||||
func TestGexec(t *testing.T) {
|
||||
BeforeSuite(func() {
|
||||
var err error
|
||||
fireflyPath, err = gexec.Build("./_fixture/firefly")
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterSuite(func() {
|
||||
gexec.CleanupBuildArtifacts()
|
||||
})
|
||||
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Gexec Suite")
|
||||
}
|
||||
53
vendor/github.com/onsi/gomega/gexec/prefixed_writer.go
generated
vendored
Normal file
53
vendor/github.com/onsi/gomega/gexec/prefixed_writer.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
package gexec
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
/*
|
||||
PrefixedWriter wraps an io.Writer, emiting the passed in prefix at the beginning of each new line.
|
||||
This can be useful when running multiple gexec.Sessions concurrently - you can prefix the log output of each
|
||||
session by passing in a PrefixedWriter:
|
||||
|
||||
gexec.Start(cmd, NewPrefixedWriter("[my-cmd] ", GinkgoWriter), NewPrefixedWriter("[my-cmd] ", GinkgoWriter))
|
||||
*/
|
||||
type PrefixedWriter struct {
|
||||
prefix []byte
|
||||
writer io.Writer
|
||||
lock *sync.Mutex
|
||||
atStartOfLine bool
|
||||
}
|
||||
|
||||
func NewPrefixedWriter(prefix string, writer io.Writer) *PrefixedWriter {
|
||||
return &PrefixedWriter{
|
||||
prefix: []byte(prefix),
|
||||
writer: writer,
|
||||
lock: &sync.Mutex{},
|
||||
atStartOfLine: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *PrefixedWriter) Write(b []byte) (int, error) {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
|
||||
toWrite := []byte{}
|
||||
|
||||
for _, c := range b {
|
||||
if w.atStartOfLine {
|
||||
toWrite = append(toWrite, w.prefix...)
|
||||
}
|
||||
|
||||
toWrite = append(toWrite, c)
|
||||
|
||||
w.atStartOfLine = c == '\n'
|
||||
}
|
||||
|
||||
_, err := w.writer.Write(toWrite)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return len(b), nil
|
||||
}
|
||||
43
vendor/github.com/onsi/gomega/gexec/prefixed_writer_test.go
generated
vendored
Normal file
43
vendor/github.com/onsi/gomega/gexec/prefixed_writer_test.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package gexec_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
. "github.com/onsi/gomega/gexec"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("PrefixedWriter", func() {
|
||||
var buffer *bytes.Buffer
|
||||
var writer *PrefixedWriter
|
||||
BeforeEach(func() {
|
||||
buffer = &bytes.Buffer{}
|
||||
writer = NewPrefixedWriter("[p]", buffer)
|
||||
})
|
||||
|
||||
It("should emit the prefix on newlines", func() {
|
||||
writer.Write([]byte("abc"))
|
||||
writer.Write([]byte("def\n"))
|
||||
writer.Write([]byte("hij\n"))
|
||||
writer.Write([]byte("\n\n"))
|
||||
writer.Write([]byte("klm\n\nnop"))
|
||||
writer.Write([]byte(""))
|
||||
writer.Write([]byte("qrs"))
|
||||
writer.Write([]byte("\ntuv\nwx"))
|
||||
writer.Write([]byte("yz\n\n"))
|
||||
|
||||
Ω(buffer.String()).Should(Equal(`[p]abcdef
|
||||
[p]hij
|
||||
[p]
|
||||
[p]
|
||||
[p]klm
|
||||
[p]
|
||||
[p]nopqrs
|
||||
[p]tuv
|
||||
[p]wxyz
|
||||
[p]
|
||||
`))
|
||||
})
|
||||
})
|
||||
214
vendor/github.com/onsi/gomega/gexec/session.go
generated
vendored
Normal file
214
vendor/github.com/onsi/gomega/gexec/session.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
Package gexec provides support for testing external processes.
|
||||
*/
|
||||
package gexec
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/gbytes"
|
||||
)
|
||||
|
||||
const INVALID_EXIT_CODE = 254
|
||||
|
||||
type Session struct {
|
||||
//The wrapped command
|
||||
Command *exec.Cmd
|
||||
|
||||
//A *gbytes.Buffer connected to the command's stdout
|
||||
Out *gbytes.Buffer
|
||||
|
||||
//A *gbytes.Buffer connected to the command's stderr
|
||||
Err *gbytes.Buffer
|
||||
|
||||
//A channel that will close when the command exits
|
||||
Exited <-chan struct{}
|
||||
|
||||
lock *sync.Mutex
|
||||
exitCode int
|
||||
}
|
||||
|
||||
/*
|
||||
Start starts the passed-in *exec.Cmd command. It wraps the command in a *gexec.Session.
|
||||
|
||||
The session pipes the command's stdout and stderr to two *gbytes.Buffers available as properties on the session: session.Out and session.Err.
|
||||
These buffers can be used with the gbytes.Say matcher to match against unread output:
|
||||
|
||||
Ω(session.Out).Should(gbytes.Say("foo-out"))
|
||||
Ω(session.Err).Should(gbytes.Say("foo-err"))
|
||||
|
||||
In addition, Session satisfies the gbytes.BufferProvider interface and provides the stdout *gbytes.Buffer. This allows you to replace the first line, above, with:
|
||||
|
||||
Ω(session).Should(gbytes.Say("foo-out"))
|
||||
|
||||
When outWriter and/or errWriter are non-nil, the session will pipe stdout and/or stderr output both into the session *gybtes.Buffers and to the passed-in outWriter/errWriter.
|
||||
This is useful for capturing the process's output or logging it to screen. In particular, when using Ginkgo it can be convenient to direct output to the GinkgoWriter:
|
||||
|
||||
session, err := Start(command, GinkgoWriter, GinkgoWriter)
|
||||
|
||||
This will log output when running tests in verbose mode, but - otherwise - will only log output when a test fails.
|
||||
|
||||
The session wrapper is responsible for waiting on the *exec.Cmd command. You *should not* call command.Wait() yourself.
|
||||
Instead, to assert that the command has exited you can use the gexec.Exit matcher:
|
||||
|
||||
Ω(session).Should(gexec.Exit())
|
||||
|
||||
When the session exits it closes the stdout and stderr gbytes buffers. This will short circuit any
|
||||
Eventuallys waiting fo the buffers to Say something.
|
||||
*/
|
||||
func Start(command *exec.Cmd, outWriter io.Writer, errWriter io.Writer) (*Session, error) {
|
||||
exited := make(chan struct{})
|
||||
|
||||
session := &Session{
|
||||
Command: command,
|
||||
Out: gbytes.NewBuffer(),
|
||||
Err: gbytes.NewBuffer(),
|
||||
Exited: exited,
|
||||
lock: &sync.Mutex{},
|
||||
exitCode: -1,
|
||||
}
|
||||
|
||||
var commandOut, commandErr io.Writer
|
||||
|
||||
commandOut, commandErr = session.Out, session.Err
|
||||
|
||||
if outWriter != nil && !reflect.ValueOf(outWriter).IsNil() {
|
||||
commandOut = io.MultiWriter(commandOut, outWriter)
|
||||
}
|
||||
|
||||
if errWriter != nil && !reflect.ValueOf(errWriter).IsNil() {
|
||||
commandErr = io.MultiWriter(commandErr, errWriter)
|
||||
}
|
||||
|
||||
command.Stdout = commandOut
|
||||
command.Stderr = commandErr
|
||||
|
||||
err := command.Start()
|
||||
if err == nil {
|
||||
go session.monitorForExit(exited)
|
||||
}
|
||||
|
||||
return session, err
|
||||
}
|
||||
|
||||
/*
|
||||
Buffer implements the gbytes.BufferProvider interface and returns s.Out
|
||||
This allows you to make gbytes.Say matcher assertions against stdout without having to reference .Out:
|
||||
|
||||
Eventually(session).Should(gbytes.Say("foo"))
|
||||
*/
|
||||
func (s *Session) Buffer() *gbytes.Buffer {
|
||||
return s.Out
|
||||
}
|
||||
|
||||
/*
|
||||
ExitCode returns the wrapped command's exit code. If the command hasn't exited yet, ExitCode returns -1.
|
||||
|
||||
To assert that the command has exited it is more convenient to use the Exit matcher:
|
||||
|
||||
Eventually(s).Should(gexec.Exit())
|
||||
|
||||
When the process exits because it has received a particular signal, the exit code will be 128+signal-value
|
||||
(See http://www.tldp.org/LDP/abs/html/exitcodes.html and http://man7.org/linux/man-pages/man7/signal.7.html)
|
||||
|
||||
*/
|
||||
func (s *Session) ExitCode() int {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
return s.exitCode
|
||||
}
|
||||
|
||||
/*
|
||||
Wait waits until the wrapped command exits. It can be passed an optional timeout.
|
||||
If the command does not exit within the timeout, Wait will trigger a test failure.
|
||||
|
||||
Wait returns the session, making it possible to chain:
|
||||
|
||||
session.Wait().Out.Contents()
|
||||
|
||||
will wait for the command to exit then return the entirety of Out's contents.
|
||||
|
||||
Wait uses eventually under the hood and accepts the same timeout/polling intervals that eventually does.
|
||||
*/
|
||||
func (s *Session) Wait(timeout ...interface{}) *Session {
|
||||
EventuallyWithOffset(1, s, timeout...).Should(Exit())
|
||||
return s
|
||||
}
|
||||
|
||||
/*
|
||||
Kill sends the running command a SIGKILL signal. It does not wait for the process to exit.
|
||||
|
||||
If the command has already exited, Kill returns silently.
|
||||
|
||||
The session is returned to enable chaining.
|
||||
*/
|
||||
func (s *Session) Kill() *Session {
|
||||
if s.ExitCode() != -1 {
|
||||
return s
|
||||
}
|
||||
s.Command.Process.Kill()
|
||||
return s
|
||||
}
|
||||
|
||||
/*
|
||||
Interrupt sends the running command a SIGINT signal. It does not wait for the process to exit.
|
||||
|
||||
If the command has already exited, Interrupt returns silently.
|
||||
|
||||
The session is returned to enable chaining.
|
||||
*/
|
||||
func (s *Session) Interrupt() *Session {
|
||||
return s.Signal(syscall.SIGINT)
|
||||
}
|
||||
|
||||
/*
|
||||
Terminate sends the running command a SIGTERM signal. It does not wait for the process to exit.
|
||||
|
||||
If the command has already exited, Terminate returns silently.
|
||||
|
||||
The session is returned to enable chaining.
|
||||
*/
|
||||
func (s *Session) Terminate() *Session {
|
||||
return s.Signal(syscall.SIGTERM)
|
||||
}
|
||||
|
||||
/*
|
||||
Terminate sends the running command the passed in signal. It does not wait for the process to exit.
|
||||
|
||||
If the command has already exited, Signal returns silently.
|
||||
|
||||
The session is returned to enable chaining.
|
||||
*/
|
||||
func (s *Session) Signal(signal os.Signal) *Session {
|
||||
if s.ExitCode() != -1 {
|
||||
return s
|
||||
}
|
||||
s.Command.Process.Signal(signal)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Session) monitorForExit(exited chan<- struct{}) {
|
||||
err := s.Command.Wait()
|
||||
s.lock.Lock()
|
||||
s.Out.Close()
|
||||
s.Err.Close()
|
||||
status := s.Command.ProcessState.Sys().(syscall.WaitStatus)
|
||||
if status.Signaled() {
|
||||
s.exitCode = 128 + int(status.Signal())
|
||||
} else {
|
||||
exitStatus := status.ExitStatus()
|
||||
if exitStatus == -1 && err != nil {
|
||||
s.exitCode = INVALID_EXIT_CODE
|
||||
}
|
||||
s.exitCode = exitStatus
|
||||
}
|
||||
s.lock.Unlock()
|
||||
|
||||
close(exited)
|
||||
}
|
||||
178
vendor/github.com/onsi/gomega/gexec/session_test.go
generated
vendored
Normal file
178
vendor/github.com/onsi/gomega/gexec/session_test.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
package gexec_test
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/gomega/gbytes"
|
||||
. "github.com/onsi/gomega/gexec"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Session", func() {
|
||||
var command *exec.Cmd
|
||||
var session *Session
|
||||
|
||||
var outWriter, errWriter *Buffer
|
||||
|
||||
BeforeEach(func() {
|
||||
outWriter = nil
|
||||
errWriter = nil
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
command = exec.Command(fireflyPath)
|
||||
var err error
|
||||
session, err = Start(command, outWriter, errWriter)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("running a command", func() {
|
||||
It("should start the process", func() {
|
||||
Ω(command.Process).ShouldNot(BeNil())
|
||||
})
|
||||
|
||||
It("should wrap the process's stdout and stderr with gbytes buffers", func(done Done) {
|
||||
Eventually(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
|
||||
Eventually(session.Err).Should(Say("Ah, curse your sudden but inevitable betrayal!"))
|
||||
defer session.Out.CancelDetects()
|
||||
|
||||
select {
|
||||
case <-session.Out.Detect("Can we maybe vote on the whole murdering people issue"):
|
||||
Eventually(session).Should(Exit(0))
|
||||
case <-session.Out.Detect("I swear by my pretty floral bonnet, I will end you."):
|
||||
Eventually(session).Should(Exit(1))
|
||||
case <-session.Out.Detect("My work's illegal, but at least it's honest."):
|
||||
Eventually(session).Should(Exit(2))
|
||||
}
|
||||
|
||||
close(done)
|
||||
})
|
||||
|
||||
It("should satisfy the gbytes.BufferProvider interface, passing Stdout", func() {
|
||||
Eventually(session).Should(Say("We've done the impossible, and that makes us mighty"))
|
||||
Eventually(session).Should(Exit())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("providing the exit code", func() {
|
||||
It("should provide the app's exit code", func() {
|
||||
Ω(session.ExitCode()).Should(Equal(-1))
|
||||
|
||||
Eventually(session).Should(Exit())
|
||||
Ω(session.ExitCode()).Should(BeNumerically(">=", 0))
|
||||
Ω(session.ExitCode()).Should(BeNumerically("<", 3))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("wait", func() {
|
||||
It("should wait till the command exits", func() {
|
||||
Ω(session.ExitCode()).Should(Equal(-1))
|
||||
Ω(session.Wait().ExitCode()).Should(BeNumerically(">=", 0))
|
||||
Ω(session.Wait().ExitCode()).Should(BeNumerically("<", 3))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("exited", func() {
|
||||
It("should close when the command exits", func() {
|
||||
Eventually(session.Exited).Should(BeClosed())
|
||||
Ω(session.ExitCode()).ShouldNot(Equal(-1))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("kill", func() {
|
||||
It("should kill the command and wait for it to exit", func() {
|
||||
session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
|
||||
session.Kill()
|
||||
Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
|
||||
Eventually(session).Should(Exit(128 + 9))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("interrupt", func() {
|
||||
It("should interrupt the command", func() {
|
||||
session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
|
||||
session.Interrupt()
|
||||
Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
|
||||
Eventually(session).Should(Exit(128 + 2))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("terminate", func() {
|
||||
It("should terminate the command", func() {
|
||||
session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
|
||||
session.Terminate()
|
||||
Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
|
||||
Eventually(session).Should(Exit(128 + 15))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("signal", func() {
|
||||
It("should send the signal to the command", func() {
|
||||
session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
|
||||
session.Signal(syscall.SIGABRT)
|
||||
Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
|
||||
Eventually(session).Should(Exit(128 + 6))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the command exits", func() {
|
||||
It("should close the buffers", func() {
|
||||
Eventually(session).Should(Exit())
|
||||
|
||||
Ω(session.Out.Closed()).Should(BeTrue())
|
||||
Ω(session.Err.Closed()).Should(BeTrue())
|
||||
|
||||
Ω(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
|
||||
})
|
||||
|
||||
var So = It
|
||||
|
||||
So("this means that eventually should short circuit", func() {
|
||||
t := time.Now()
|
||||
failures := InterceptGomegaFailures(func() {
|
||||
Eventually(session).Should(Say("blah blah blah blah blah"))
|
||||
})
|
||||
Ω(time.Since(t)).Should(BeNumerically("<=", 500*time.Millisecond))
|
||||
Ω(failures).Should(HaveLen(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when wrapping out and err", func() {
|
||||
BeforeEach(func() {
|
||||
outWriter = NewBuffer()
|
||||
errWriter = NewBuffer()
|
||||
})
|
||||
|
||||
It("should route to both the provided writers and the gbytes buffers", func() {
|
||||
Eventually(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
|
||||
Eventually(session.Err).Should(Say("Ah, curse your sudden but inevitable betrayal!"))
|
||||
|
||||
Ω(outWriter.Contents()).Should(ContainSubstring("We've done the impossible, and that makes us mighty"))
|
||||
Ω(errWriter.Contents()).Should(ContainSubstring("Ah, curse your sudden but inevitable betrayal!"))
|
||||
|
||||
Eventually(session).Should(Exit())
|
||||
|
||||
Ω(outWriter.Contents()).Should(Equal(session.Out.Contents()))
|
||||
Ω(errWriter.Contents()).Should(Equal(session.Err.Contents()))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("when the command fails to start", func() {
|
||||
It("should return an error", func() {
|
||||
_, err := Start(exec.Command("agklsjdfas"), nil, nil)
|
||||
Ω(err).Should(HaveOccurred())
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user