test_with_docker

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Jan 12, 2017 License: MIT Imports: 17 Imported by: 1

README

test with docker

Testing service clients means having an instance of the service around. If you can get a docker container for the service, this'll let you make sure that the container is running, and get the ip address of the service to then test against.

Given a docker-compose.yml file somewhere, you can add something like this to an integration test:

func TestMain(m *testing.M) {
	os.Exit(wrapCompose(m))
}

func wrapCompose(m *testing.M) int {
	ip, started, err := test_with_docker.ComposeServices(
    "docker-machine-name",
    "dir/with/compose-yaml",
    map[string]uint{"ServiceName": 4321}
  )
  // if ComposeServices needs to do a docker-compose up, it will provide an object to use to shut the docker back down
	if started != nil {
		defer test_with_docker.Shutdown(started)
	}

	return m.Run()
}

ComposeServices will check to see if any of the named services are missing. If so, it'll run docker-compose in the appropriate directory to bring the services up. It'll then wait until those services are available before returning, so you can be sure that your test environment is ready. If all the named services are already available, ComposeServices returns immediates, so that you can start things up on your own in order to speed up your test cycle.

Finally, if the services needed to be started for the test, test_with_docker returns a non-nil value so that you can call Shutdown and clean up afterwards.

For now, test_with_docker assumes Docker Machine and Docker Compose. Maybe it's worth detecting the need for Machine and providing an option for just using docker up for simple setups.

Documentation

Overview

test_with_docker provides utilities for using docker-compose for writing integration tests.

Index

Constants

View Source
const (
	// DefaultTimeout is the default timeout for docker operations.
	DefaultTimeout = 30 * time.Second
)

Variables

This section is empty.

Functions

func UntilReady

func UntilReady(d, max time.Duration, fns ...ReadyFn) error

UntilReady waits for a series of conditions to be true, with optional cleanup

Types

type Agent

type Agent interface {
	//	ComposeServices uses docker-compose to set up one or more services, using
	//	serviceMap to check availability.
	//
	//	Importantly, the serviceMap is used both to determine if the services are
	//	already available - since docker-compose can take some time to execute, it
	//	can be handy to run the compose in a different console and let
	//	ComposeServices discover the services.
	//
	//	Finally, if ComposeServices determined that a service was missing and
	//	needed to be run, it will return a value that represents the
	//	docker-compose command that it executed. You can pass this value to
	//	Shutdown to shut down the docker-compose after tests have run.
	ComposeServices(string, serviceMap) (*command, error)

	// InstallFile puts a path found on the local machine to a path on the docker host.
	InstallFile(string, string) error

	// DifferingFile takes a list of pairs of [local, remote] paths, and filters them
	// for pairs whose contents differ.
	DifferingFiles(...[]string) ([][]string, error)

	// IP returns the IP address where the daemon is located.
	// In order to access the services provided by a docker-compose on a
	// docker-machine, we need to know the ip address. Some client test code
	// needs to know the IP address prior to starting up the services, which is
	// why this function is exposed
	IP() (net.IP, error)

	// MD5s computes digests of a list of paths
	// This can be used to compare to local digests and avoid copying files or
	// restarting the daemon
	MD5s(...string) (map[string]string, error)

	// RebuildService forces the rebuild of a docker-compose service.
	RebuildService(string, string) error

	// Shutdown terminates the set of services started by ComposeServices
	// If passed a nil (as ComposeServices returns in the event that all services
	// were available), Shutdown is a no-op
	Shutdown(*command)

	// ShutdownNow unconditionally terminates the agent.
	ShutdownNow()

	// RestartDaemon reboots the docker daemon
	RestartDaemon() error

	// Exec executes commands as root on the daemon host
	// It uses sudo
	Exec(...string) error

	// Cleanup performs the tasks required to shut down after a test
	Cleanup() error
}

An Agent manages operations directed at Docker This is an interface that abstracts the differece between local docker-daemons (useful, for instance, for Linux based CI (e.g. Travis)) and VM hosted docker-machine managed daemons (e.g. for OS X development.

func NewAgent

func NewAgent() (Agent, error)

NewAgent returns a new agent with the DefaultTimeout

func NewAgentWithTimeout

func NewAgentWithTimeout(timeout time.Duration) (Agent, error)

NewAgentWithTimeout returns a new agent with a user specified timeout

type LocalDaemon

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

func (*LocalDaemon) Cleanup

func (ld *LocalDaemon) Cleanup() error

func (*LocalDaemon) ComposeServices

func (ld *LocalDaemon) ComposeServices(dir string, svcs serviceMap) (*command, error)

func (*LocalDaemon) DifferingFiles

func (ld *LocalDaemon) DifferingFiles(pathPairs ...[]string) (differentPairs [][]string, err error)

DifferingFiles compares specific files involved in docker

func (*LocalDaemon) Exec

func (ld *LocalDaemon) Exec(args ...string) error

Exec executes commands as root on the daemon host It uses sudo

func (*LocalDaemon) IP

func (ld *LocalDaemon) IP() (net.IP, error)

IP returns the IP address where the daemon is located. In order to access the services provided by a docker-compose on a docker-machine, we need to know the ip address. Some client test code needs to know the IP address prior to starting up the services, which is why this function is exposed

func (*LocalDaemon) InstallFile

func (ld *LocalDaemon) InstallFile(src string, dest string) error

InstallFile puts a path found on the local machine to a path on the docker host.

func (*LocalDaemon) MD5s

func (ld *LocalDaemon) MD5s(paths ...string) (map[string]string, error)

MD5s computes digests of a list of paths This can be used to compare to local digests and avoid copying files or restarting the daemon

func (*LocalDaemon) RebuildService

func (ld *LocalDaemon) RebuildService(dir, name string) error

RebuildService forces the rebuild of a docker-compose service.

func (*LocalDaemon) RestartDaemon

func (ld *LocalDaemon) RestartDaemon() error

RestartDaemon reboots the docker daemon

func (*LocalDaemon) Shutdown

func (ld *LocalDaemon) Shutdown(c *command)

Shutdown terminates the set of services started by ComposeServices If passed a nil (as ComposeServices returns in the event that all services were available, Shutdown is a no-op

func (*LocalDaemon) ShutdownNow added in v0.0.3

func (ld *LocalDaemon) ShutdownNow()

ShutdownNow implements Agent for LocalDaemon

type Machine

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

Machine represents a Docker machine-based agent.

func (*Machine) Cleanup

func (m *Machine) Cleanup() error

Cleanup does nothing and always returns nil.

func (*Machine) ComposeServices

func (m *Machine) ComposeServices(dir string, servicePorts serviceMap) (shutdown *command, err error)

ComposeServices uses Docker compose to start services.

func (*Machine) DifferingFiles

func (m *Machine) DifferingFiles(pathPairs ...[]string) (differentPairs [][]string, err error)

DifferingFiles returns a slice of string slices representing files that differ in the Docker machine, compared with the provided list of paths on the host machine.

func (*Machine) Exec

func (m *Machine) Exec(args ...string) error

Exec is your out for anything that test_with_docker doesn't provide. It executes `docker-machine ssh <machineName> sudo <args...>` so that you can manipulate the running docker machine

func (*Machine) IP

func (m *Machine) IP() (ip net.IP, err error)

IP returns the IP address of the Docker machine this Machine relates to.

func (*Machine) InstallFile

func (m *Machine) InstallFile(sourcePath, destPath string) error

InstallFile installs a file into the docker-machine

func (*Machine) MD5s

func (m *Machine) MD5s(paths ...string) (md5s map[string]string, err error)

MD5s returns a map of paths to their MD5 hashes, according to the contents of files at paths inside the Docker machine.

func (*Machine) RebuildService

func (m *Machine) RebuildService(dir, name string) error

RebuildService builds a Docker image called name based on the Dockerfile in dir.

func (*Machine) RestartDaemon

func (m *Machine) RestartDaemon() error

RestartDaemon restarts the docker daemon on the docker machine VM

func (*Machine) Shutdown

func (m *Machine) Shutdown(c *command)

Shutdown receives a command as produced by ComposeServices is shuts down services launched for testing. If passed a nil command, it functions as a no-op. This means that you can do things like:

ip, cmd, err := ComposeServices(...)
defer Shutdown(cmd)

func (*Machine) ShutdownNow added in v0.0.3

func (m *Machine) ShutdownNow()

ShutdownNow implements Agent for Machine

type ReadyError

type ReadyError struct {
	Errs []error
	// contains filtered or unexported fields
}

A ReadyError is returned when UntilReady doesn't get a universal ready result

func (*ReadyError) Error

func (re *ReadyError) Error() string

type ReadyFn

type ReadyFn func() (desc string, test func() bool, defr func())

A ReadyFn is a high-order function that returns a predicate to test for readiness and a deferred cleanup function

Jump to

Keyboard shortcuts

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