gexec

package
v0.0.0-...-4ee4f08 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2016 License: MIT, Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package gexec provides support for testing external processes.

Index

Constants

View Source
const INVALID_EXIT_CODE = 254

Variables

This section is empty.

Functions

func Build

func Build(packagePath string, args ...string) (compiledPath string, err error)

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 BuildIn

func BuildIn(gopath string, packagePath string, args ...string) (compiledPath string, err error)

BuildIn is identical to Build but allows you to specify a custom $GOPATH (the first argument).

func CleanupBuildArtifacts

func CleanupBuildArtifacts()

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 Exit

func Exit(optionalExitCode ...int) *exitMatcher

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))

Types

type Exiter

type Exiter interface {
	ExitCode() int
}

type PrefixedWriter

type PrefixedWriter struct {
	// contains filtered or unexported fields
}

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))

func NewPrefixedWriter

func NewPrefixedWriter(prefix string, writer io.Writer) *PrefixedWriter

func (*PrefixedWriter) Write

func (w *PrefixedWriter) Write(b []byte) (int, error)

type Session

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{}
	// contains filtered or unexported fields
}

func Start

func Start(command *exec.Cmd, outWriter io.Writer, errWriter io.Writer) (*Session, error)

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 (*Session) Buffer

func (s *Session) Buffer() *gbytes.Buffer

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 (*Session) ExitCode

func (s *Session) ExitCode() int

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 (*Session) Interrupt

func (s *Session) Interrupt() *Session

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 (*Session) Kill

func (s *Session) Kill() *Session

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 (*Session) Signal

func (s *Session) Signal(signal os.Signal) *Session

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 (*Session) Terminate

func (s *Session) Terminate() *Session

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 (*Session) Wait

func (s *Session) Wait(timeout ...interface{}) *Session

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL