termtest

package module
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2022 License: BSD-3-Clause Imports: 17 Imported by: 1

README

termtest

GitHub Actions status

An automatable terminal session with send/expect controls.

This package leverages the go-expect package to test terminal applications on Linux, MacOS and Windows, which has been forked from Netflix/go-expect

It has been developed for CI testing of the ActiveState state tool

Example usage


import (
    "testing"

    "github.com/ActiveState/termtest"
    "github.com/stretchr/testify/suite"
)

func TestBash(t *testing.T) {
    opts := termtest.Options{
        CmdName: "/bin/bash",
    }
    cp, err := termtest.NewTest(t, opts)
    require.NoError(t, err, "create console process")
    defer cp.Close()

    cp.SendLine("echo hello world")
    cp.Expect("hello world")
    cp.SendLine("exit")
    cp.ExpectExitCode(0)
}

Multi-line matching

After each bytes termtest receives from the pseudo-terminal output, it updates the state of the virtual terminal like a terminal user would see it (including a scroll back buffer if necessary). The Expect() look for matches in this processed output. Of course, the terminal wraps its output after text gets longer than 80 columns (or whatever width you have configured for your terminal). As this makes it more difficult to match long string, the default Expect() removes all these automatic wraps.

Consider the following examples, that all assume a terminal width of 10 columns.

Programme sends a line with more than 10 characters
  • Programme sends string "0123456789012345".
  • Terminal output is "0123456789\n012345 \n".
cp.Expect("0123456789012345")  // this matches
Programme sends several lines separated by \n
  • Programme sends string "line 1\nline 2\n".
  • Terminal output is "line 1 \nline 2 \n".
  • The following does NOT match:
    cp.Expect("line 1\nline 2\n")  // this does NOT match
    
  • The following does MATCH:
    cp.Expect("line 1")
    cp.Expect("line 2")
    
  • The following does MATCH:
    cp.Expect("line 1    line 2    ")
    
Custom matchers

Custom matchers that match against either the raw / or processed pseudo-terminal output can be specified in the go-expect package. See expect_opt.go for examples.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoProcess is returned when a process was expected to be running
	ErrNoProcess = errors.New("no command process seems to be running")
)
View Source
var ErrWaitTimeout = errWaitTimeout{fmt.Errorf("timeout waiting for exit code")}

ErrWaitTimeout is returned when we time out waiting for the console process to exit

Functions

func TestExpectObserveFn

func TestExpectObserveFn(t *testing.T) expect.ExpectObserver

TestExpectObserveFn an example for a ExpectObserver function, it reports any error occurring durint expect calls to the supplied testing instance

func TestSendObserveFn

func TestSendObserveFn(t *testing.T) func(string, int, error)

TestSendObserveFn is an example for a SendObserver function, it reports any error during Send calls to the supplied testing instance

Types

type ConsoleProcess

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

ConsoleProcess bonds a command with a pseudo-terminal for automation

func New

func New(opts Options) (*ConsoleProcess, error)

New bonds a command process with a console pty.

func NewTest added in v0.5.0

func NewTest(t *testing.T, opts Options) (*ConsoleProcess, error)

NewTest bonds a command process with a console pty and sets it up for testing

func (*ConsoleProcess) Close

func (cp *ConsoleProcess) Close() error

Close cleans up all the resources allocated by the ConsoleProcess If the underlying process is still running, it is terminated with a SIGTERM signal.

func (*ConsoleProcess) Cmd added in v0.7.2

func (cp *ConsoleProcess) Cmd() *exec.Cmd

Cmd returns the underlying command

func (*ConsoleProcess) Executable

func (cp *ConsoleProcess) Executable() string

Executable returns the command name to be executed

func (*ConsoleProcess) Expect

func (cp *ConsoleProcess) Expect(value string, timeout ...time.Duration) (string, error)

Expect listens to the terminal output and returns once the expected value is found or a timeout occurs Default timeout is 10 seconds

func (*ConsoleProcess) ExpectCustom added in v0.7.2

func (cp *ConsoleProcess) ExpectCustom(opt expect.ExpectOpt, timeout ...time.Duration) (string, error)

ExpectCustom listens to the terminal output and returns once the supplied condition is satisfied or a timeout occurs Default timeout is 10 seconds

func (*ConsoleProcess) ExpectExitCode

func (cp *ConsoleProcess) ExpectExitCode(exitCode int, timeout ...time.Duration) (string, error)

ExpectExitCode waits for the program under test to terminate, and checks that the returned exit code meets expectations

func (*ConsoleProcess) ExpectLongString added in v0.5.5

func (cp *ConsoleProcess) ExpectLongString(value string, timeout ...time.Duration) (string, error)

ExpectLongString listens to the terminal output and returns once the expected value is found or a timeout occurs This function ignores mismatches caused by newline and space characters to account for wrappings at the maximum terminal width. Default timeout is 10 seconds

func (*ConsoleProcess) ExpectNotExitCode

func (cp *ConsoleProcess) ExpectNotExitCode(exitCode int, timeout ...time.Duration) (string, error)

ExpectNotExitCode waits for the program under test to terminate, and checks that the returned exit code is not the value provide

func (*ConsoleProcess) ExpectRe

func (cp *ConsoleProcess) ExpectRe(value string, timeout ...time.Duration) (string, error)

ExpectRe listens to the terminal output and returns once the expected regular expression is matched or a timeout occurs Default timeout is 10 seconds

func (*ConsoleProcess) MatchState added in v0.5.0

func (cp *ConsoleProcess) MatchState() *expect.MatchState

MatchState returns the current state of the expect-matcher

func (*ConsoleProcess) Send

func (cp *ConsoleProcess) Send(value string)

Send sends a new line to the terminal, as if a user typed it

func (*ConsoleProcess) SendCtrlC

func (cp *ConsoleProcess) SendCtrlC()

SendCtrlC tries to emulate what would happen in an interactive shell, when the user presses Ctrl-C Note: On Windows the Ctrl-C event is only reliable caught when the receiving process is listening for os.Interrupt signals.

func (*ConsoleProcess) SendLine

func (cp *ConsoleProcess) SendLine(value string)

SendLine sends a new line to the terminal, as if a user typed it, the newline sequence is OS aware

func (*ConsoleProcess) SendUnterminated added in v0.7.1

func (cp *ConsoleProcess) SendUnterminated(value string)

SendUnterminated sends a string to the terminal as if a user typed it

func (*ConsoleProcess) Signal

func (cp *ConsoleProcess) Signal(sig os.Signal) error

Signal sends an arbitrary signal to the running process

func (*ConsoleProcess) Snapshot

func (cp *ConsoleProcess) Snapshot() string

Snapshot returns a string containing a terminal snap-shot as a user would see it in a "real" terminal

func (*ConsoleProcess) Stop

func (cp *ConsoleProcess) Stop() error

Stop sends an interrupt signal for the tested process and fails if no process has been started yet. Note: This is not supported on Windows

func (*ConsoleProcess) TrimmedSnapshot

func (cp *ConsoleProcess) TrimmedSnapshot() string

TrimmedSnapshot displays the terminal output a user would see however the goroutine that creates this output is separate from this function so any output is not synced

func (*ConsoleProcess) Wait

func (cp *ConsoleProcess) Wait(timeout ...time.Duration)

Wait waits for the program under test to terminate, not caring about the exit code at all

func (*ConsoleProcess) WaitForInput

func (cp *ConsoleProcess) WaitForInput(timeout ...time.Duration) (string, error)

WaitForInput returns once a shell prompt is active on the terminal Default timeout is 10 seconds

func (*ConsoleProcess) WorkDirectory

func (cp *ConsoleProcess) WorkDirectory() string

WorkDirectory returns the directory in which the command shall be run

type Options

type Options struct {
	DefaultTimeout time.Duration
	WorkDirectory  string
	RetainWorkDir  bool
	Environment    []string
	ObserveSend    SendObserver
	ObserveExpect  expect.ExpectObserver
	CmdName        string
	Args           []string
	HideCmdLine    bool
	ExtraOpts      []expect.ConsoleOpt
}

Options contain optional values for ConsoleProcess construction and usage.

func (*Options) CleanUp

func (opts *Options) CleanUp() error

CleanUp cleans up the environment

func (*Options) Normalize

func (opts *Options) Normalize() error

Normalize fills in default options

type SendObserver

type SendObserver func(msg string, num int, err error)

SendObserver is function that is called when text is send to the console Arguments are the message, number of bytes written and an error message See TestSendObserveFn for an example

Directories

Path Synopsis
cmd
conpty module
expect module
internal
xpty module

Jump to

Keyboard shortcuts

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