testutil

package
v0.0.0-...-1a9f8b1 Latest Latest
Warning

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

Go to latest
Published: Dec 23, 2024 License: Apache-2.0, MIT Imports: 31 Imported by: 32

Documentation

Overview

Package testutil contains utility functions for runsc tests.

Index

Constants

View Source
const Prompt = "PROMPT> "

Prompt is used as shell prompt. It is meant to be unique enough to not be seen in command outputs.

Variables

View Source
var (

	// TestEnvSupportsNetAdmin indicates whether a test sandbox can perform
	// all net admin tasks. Note that some test environments cannot perform
	// some tasks despite the presence of CAP_NET_ADMIN.
	TestEnvSupportsNetAdmin = true
)

Functions

func BoolFromEnv

func BoolFromEnv(name string, def bool) bool

BoolFromEnv returns the boolean value of the named environment variable, or `def` if unset/empty. It is useful for defining flags where the default value can be specified through the environment.

func ConfigureExePath

func ConfigureExePath() error

ConfigureExePath configures the executable for runsc in the test environment.

func Copy

func Copy(src, dst string) error

Copy copies file from src to dst.

func DurationFromEnv

func DurationFromEnv(name string, def time.Duration) time.Duration

DurationFromEnv returns the duration of the named environment variable, or `def` if unset/empty. It is useful for defining flags where the default value can be specified through the environment.

func FindFile

func FindFile(path string) (string, error)

FindFile searches for a file inside the test run environment. It returns the full path to the file. It fails if none or more than one file is found.

func ImageByName

func ImageByName(name string) string

ImageByName mangles the image name used locally. This depends on the image build infrastructure in images/ and tools/vm.

func IntFromEnv

func IntFromEnv(name string, def int) int

IntFromEnv returns the integer value of the named environment variable, or `def` if unset/empty. It is useful for defining flags where the default value can be specified through the environment.

func IsCheckpointSupported

func IsCheckpointSupported() bool

IsCheckpointSupported returns the relevant command line flag.

func IsRunningWithHostNet

func IsRunningWithHostNet() bool

IsRunningWithHostNet returns the relevant command line flag.

func IsRunningWithNetRaw

func IsRunningWithNetRaw() bool

IsRunningWithNetRaw returns the relevant command line flag.

func IsRunningWithOverlay

func IsRunningWithOverlay() bool

IsRunningWithOverlay returns the relevant command line flag.

func IsRunningWithSaveRestoreNetstack

func IsRunningWithSaveRestoreNetstack() bool

IsRunningWithSaveRestoreNetstack returns the relevant command line flag.

func IsStatic

func IsStatic(filename string) (bool, error)

IsStatic returns true iff the given file is a static binary.

func KillCommand

func KillCommand(cmd *exec.Cmd) error

KillCommand kills the process running cmd unless it hasn't been started. It returns an error if it cannot kill the process unless the reason is that the process has already exited.

KillCommand will also reap the process.

func NewSpecWithArgs

func NewSpecWithArgs(args ...string) *specs.Spec

NewSpecWithArgs creates a simple spec with the given args suitable for use in tests.

func Poll

func Poll(cb func() error, timeout time.Duration) error

Poll is a shorthand function to poll for something with given timeout.

func PollContext

func PollContext(ctx context.Context, cb func() error) error

PollContext is like Poll, but takes a context instead of a timeout.

func RandomContainerID

func RandomContainerID() string

RandomContainerID generates a random container id for each test.

The container id is used to create an abstract unix domain socket, which must be unique. While the container forbids creating two containers with the same name, sometimes between test runs the socket does not get cleaned up quickly enough, causing container creation to fail.

func RandomID

func RandomID(prefix string) string

RandomID returns 20 random bytes following the given prefix.

func SetupBundleDir

func SetupBundleDir(spec *specs.Spec) (string, func(), error)

SetupBundleDir creates a bundle dir and writes the spec to config.json.

func SetupContainer

func SetupContainer(spec *specs.Spec, conf *config.Config) (rootDir, bundleDir string, cleanup func(), err error)

SetupContainer creates a bundle and root dir for the container, generates a test config, and writes the spec to config.json in the bundle dir.

func SetupRootDir

func SetupRootDir() (string, func(), error)

SetupRootDir creates a root directory for containers.

func StartReaper

func StartReaper() func()

StartReaper is a helper that starts a new Reaper and returns a function to stop it.

func StringFromEnv

func StringFromEnv(name, def string) string

StringFromEnv returns the value of the named environment variable, or `def` if unset/empty. It is useful for defining flags where the default value can be specified through the environment.

func TestConfig

func TestConfig(t *testing.T) *config.Config

TestConfig returns the default configuration to use in tests. Note that 'RootDir' must be set by caller if required.

func TestIndicesForShard

func TestIndicesForShard(numTests int) ([]int, error)

TestIndicesForShard returns indices for this test shard based on the TEST_SHARD_INDEX and TEST_TOTAL_SHARDS environment vars, as well as the passed partition flags.

If either of the env vars are not present, then the function will return all tests. If there are more shards than there are tests, then the returned list may be empty.

func TmpDir

func TmpDir() string

TmpDir returns the absolute path to a writable directory that can be used as scratch by the test.

func TouchShardStatusFile

func TouchShardStatusFile() error

TouchShardStatusFile indicates to Bazel that the test runner supports sharding by creating or updating the last modified date of the file specified by TEST_SHARD_STATUS_FILE.

See https://docs.bazel.build/versions/master/test-encyclopedia.html#role-of-the-test-runner.

func WaitForHTTP

func WaitForHTTP(ip string, port int, timeout time.Duration) error

WaitForHTTP tries GET requests on a port until the call succeeds or timeout.

func WaitUntilRead

func WaitUntilRead(r io.Reader, want string, timeout time.Duration) error

WaitUntilRead reads from the given reader until the wanted string is found or until timeout.

func WriteTmpFile

func WriteTmpFile(pattern, text string) (string, func(), error)

WriteTmpFile writes text to a temporary file, closes the file, and returns the name of the file. A cleanup function is also returned.

Types

type Cmd

type Cmd struct {
	*exec.Cmd
	// contains filtered or unexported fields
}

Cmd is a simple wrapper.

func Command

func Command(logger Logger, args ...string) *Cmd

Command is a simple wrapper around exec.Command, that logs.

func (*Cmd) CombinedOutput

func (c *Cmd) CombinedOutput() ([]byte, error)

CombinedOutput returns the output and logs.

type DefaultLogger

type DefaultLogger string

DefaultLogger logs using the log package.

func (DefaultLogger) Logf

func (d DefaultLogger) Logf(fmt string, args ...any)

Logf implements Logger.Logf.

func (DefaultLogger) Name

func (d DefaultLogger) Name() string

Name implements Logger.Name.

type Logger

type Logger interface {
	Name() string
	Logf(fmt string, args ...any)
}

Logger is a simple logging wrapper.

This is designed to be implemented by *testing.T.

func NewMultiLogger

func NewMultiLogger(loggers ...Logger) Logger

NewMultiLogger returns a new Logger that logs on multiple Loggers.

type Reaper

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

Reaper reaps child processes.

func (*Reaper) Start

func (r *Reaper) Start()

Start starts reaping child processes.

func (*Reaper) Stop

func (r *Reaper) Stop()

Stop stops reaping child processes.

type Shell

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

Shell manages a /bin/sh invocation with convenience functions to handle I/O. The shell is run in its own interactive TTY and should present its prompt.

func NewShell

func NewShell(ctx context.Context, logger Logger) (*Shell, func(), error)

NewShell returns a new managed sh process along with a cleanup function. The caller is expected to call this function once it no longer needs the shell. The optional passed-in logger will be used for logging.

func (*Shell) Expect

func (s *Shell) Expect(ctx context.Context, want []byte) error

Expect verifies that the next `len(want)` bytes we read match `want`.

func (*Shell) ExpectEmptyLine

func (s *Shell) ExpectEmptyLine(ctx context.Context) error

ExpectEmptyLine verifies that the next few bytes we read are an empty line, as defined by any number of carriage or line break characters.

func (*Shell) ExpectLine

func (s *Shell) ExpectLine(ctx context.Context, want string) error

ExpectLine verifies that the next `len(want)` bytes we read match `want`, followed by carriage returns or newline characters.

func (*Shell) ExpectPrompt

func (s *Shell) ExpectPrompt(ctx context.Context) error

ExpectPrompt verifies that the next few bytes we read are the shell prompt.

func (*Shell) ExpectString

func (s *Shell) ExpectString(ctx context.Context, want string) error

ExpectString verifies that the next `len(want)` bytes we read match `want`.

func (*Shell) GetCommandOutput

func (s *Shell) GetCommandOutput(ctx context.Context) ([]byte, error)

GetCommandOutput gets all following bytes until the prompt is encountered. This is useful for matching the output of a command. All \r are removed for ease of matching.

func (*Shell) ReadUntil

func (s *Shell) ReadUntil(ctx context.Context, finalLine string) ([]byte, error)

ReadUntil gets all following bytes until a certain line is encountered. This final line is not returned as part of the output, but everything before it (including the \n) is included. This is useful for matching the output of a command. All \r are removed for ease of matching.

func (*Shell) RefreshSTTY

func (s *Shell) RefreshSTTY(ctx context.Context, expectPrompt string) error

RefreshSTTY interprets output from `stty -a` to check whether we are in echo mode and other settings. It will assume that any line matching `expectPrompt` means the end of the `stty -a` output. Why do this rather than using `tcgets`? Because this function can be used in conjunction with sub-shell processes that can allocate their own TTYs.

func (*Shell) RunCommand

func (s *Shell) RunCommand(ctx context.Context, cmd ...string) ([]byte, error)

RunCommand is a convenience wrapper for StartCommand + GetCommandOutput.

func (*Shell) SendEOF

func (s *Shell) SendEOF(ctx context.Context, expectLinebreak bool) error

SendEOF sends the \x04 (Ctrl+D) control character to the shell.

func (*Shell) SendInterrupt

func (s *Shell) SendInterrupt(ctx context.Context, expectLinebreak bool) error

SendInterrupt sends the \x03 (Ctrl+C) control character to the shell.

func (*Shell) StartCommand

func (s *Shell) StartCommand(ctx context.Context, cmd ...string) error

StartCommand is a convenience wrapper for WriteLine that mimics entering a command line and pressing Enter. It does some basic shell argument escaping.

func (*Shell) Write

func (s *Shell) Write(b []byte) error

Write writes `b` to the shell and verifies that all of them get written.

func (*Shell) WriteLine

func (s *Shell) WriteLine(ctx context.Context, line string) error

WriteLine writes `line` (to which \n will be appended) to the shell. If the shell is in `echo` mode, it will also check that we got these bytes back to read.

type Tree

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

Tree represents a hierarchy of tests and sub-tests. It is a nested structure built out of a flat list of fully-qualified test names, and can then execute them using nested `t.Run`s. It is useful to run a series of hierarchical Go tests in cases where the hierarchy is not known at test compilation time.

func NewTree

func NewTree(testNames []string, separator string) *Tree

NewTree creates a new test tree out of the given test names. Each test name is split by `separator`, which indicates nesting. Only leaf nodes are considered actual tests. For example: `NewTree([]string{"a/b", "a/c", "a/c/d"}, "/")` contains two tests: `a/b` and `a/c/d`.

func (*Tree) Run

func (tree *Tree) Run(t *testing.T, fn func(t *testing.T, testName string))

Run calls `t.Run` on each leaf test, preserving test hierarchy. `fn` is called on each leaf node with the fully-qualified test name as argument.

func (*Tree) RunParallel

func (tree *Tree) RunParallel(t *testing.T, fn func(t *testing.T, testName string))

RunParallel calls `t.Run` on each test in parallel, preserving hierarchy. `fn` is called on each leaf node with the fully-qualified test name as argument. `fn` does not need to call `t.Parallel`.

Jump to

Keyboard shortcuts

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