podrick

package module
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2020 License: MIT Imports: 8 Imported by: 0

README

Podrick

CircleCI GoDoc Go Report Card Code Coverage Releases License

Dynamically create and destroy containers for tests, within your Go application. Support for both Podman and Docker runtimes is built-in.

Inspired by dockertest.

Usage

package some_test

import (
	"net/http"
	"testing"

	"github.com/uw-labs/podrick"
	_ "github.com/uw-labs/podrick/runtimes/docker" // Register the docker runtime.
	_ "github.com/uw-labs/podrick/runtimes/podman" // Register the podman runtime.
)

func TestDatabase(t *testing.T) {
	ctx := context.Background()

	ctr, err := podrick.StartContainer(ctx, "kennethreitz/httpbin", "latest", "80")
	if err != nil {
		t.Fatalf("Failed to start container: %v", err)
	}
	defer func() {
		err := ctr.Close(ctx) // Stops and removes the container.
		if err != nil {
			t.Error(err.Error())
		}
	}()

	// Use ctr.Address().
	resp, err = http.Get("http://" + ctr.Address() + "/get")
}

Podrick automatically selects a runtime if one isn't explicitly specified. This allows the user to use both podman and docker, depending on the support of the environment. It's also possible to explicitly specify which runtime to use, or use a custom runtime implementation.

Advanced usage

package some_test

import (
	"database/sql"
	"testing"

	"github.com/sirupsen/logrus"
	"github.com/uw-labs/podrick"
	"github.com/uw-labs/podrick/runtimes/podman"
	logrusadapter "logur.dev/adapters/logrus"
)

func TestDatabase(t *testing.T) {
	log := logrusadapter.New(logrus.New())
	ctx := context.Background()

	ctr, err := podrick.StartContainer(ctx, "cockroachdb/cockroach", "v19.1.3", "26257",
		podrick.WithUlimit([]podrick.Ulimit{{
			Name: "nofile",
			Soft: 1956,
			Hard: 1956,
		}}),
		podrick.WithCmd([]string{
			"start",
			"--insecure",
		}),
		podrick.WithLogger(log),
		// Use of the podman runtime only.
		// The environment variable PODMAN_VARLINK_ADDRESS
		// can be used to configure where podrick should
		// look for the varlink API.
		podrick.WithRuntime(&podman.Runtime{
			Logger: log,
		}),
		podrick.WithLivenessCheck(func(address string) error {
			_, err := http.Get("http://"+address+"/get")
			return err
		}),
	)
	if err != nil {
		t.Fatal(err.Error())
	}

	defer func() {
		err := ctr.Close(ctx)
		if err != nil {
			t.Error(err.Error())
		}
	}()

	db, err := sql.Open("postgres://root@" + ctr.Address() + "/defaultdb")
	// ... make database calls, etc
}

Using podrick in CI

While podrick makes it really easy to run tests locally on users machines, it can be challenging to run the tests in CI, since it requires the permission to run containers that are accessible to the local environment. Circle CI is the only environment confirmed to work well with podrick, both using podman and docker.

Circle CI

The podrick CI tests themselves illustrate how to use podrick with Circle CI. It requires the use of the machine executor type, and there is some setup required to get a recent Go version. Please see the CI files for concrete examples of this.

If you are using Circle CI with the docker runtime, it is obviously not necessary to install podman.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterAutoRuntime

func RegisterAutoRuntime(r Runtime)

RegisterAutoRuntime allows a runtime to register itself for auto-selection of a runtime, when one isn't explicitly specified.

Types

type Container

type Container interface {
	// Context releases resources associated with the container.
	Close(context.Context) error
	// Address returns the IP and port of the running container.
	Address() string
	// AddressForPort returns the address for the specified port,
	// or an error, if the port was not exposed.
	AddressForPort(string) (string, error)
	// StreamLogs asynchronously streams logs from the
	// running container to the writer. The writer must
	// be safe for concurrent use.
	// If the context is cancelled after logging has been set up,
	// it has no effect. Use Close to stop logging.
	// This function is called automatically on the runtimes
	// configured logger, so there is no need to explicitly call this.
	StreamLogs(context.Context, io.Writer) error
}

Container represents a running container.

func StartContainer

func StartContainer(ctx context.Context, repo, tag, port string, opts ...Option) (_ Container, err error)

StartContainer starts a container using the configured runtime. By default, a runtime is chosen automatically from those registered.

type ContainerConfig

type ContainerConfig struct {
	Repo string
	Tag  string
	Port string

	// Optional
	Env        []string
	Entrypoint *string
	Cmd        []string
	Ulimits    []Ulimit
	Files      []File
	ExtraPorts []string
}

ContainerConfig is used by runtimes to start containers.

type File added in v0.4.0

type File struct {
	Content io.Reader
	Path    string
	Size    int
	Mode    os.FileMode
}

File describes a file in a container. All fields are mandatory.

type LivenessCheck added in v0.2.0

type LivenessCheck func(address string) error

LivenessCheck is a type used to check the successful startup of a container.

type Logger

type Logger interface {
	Trace(msg string, fields ...map[string]interface{})
	Debug(msg string, fields ...map[string]interface{})
	Info(msg string, fields ...map[string]interface{})
	Warn(msg string, fields ...map[string]interface{})
	Error(msg string, fields ...map[string]interface{})
}

Logger must be implemented to log events. See https://logur.dev/logur for some adapters for popular logging libraries.

type Option added in v0.4.0

type Option func(*config)

Option configures the configuration of the started container.

func WithCmd

func WithCmd(in []string) Option

WithCmd configures the command of the container.

func WithEntrypoint

func WithEntrypoint(in string) Option

WithEntrypoint configures the entrypoint of the container.

func WithEnv

func WithEnv(in []string) Option

WithEnv configures the environment of the container.

func WithExposePort added in v0.4.0

func WithExposePort(port string) Option

WithExposePort adds extra ports that should be exposed from the started container.

func WithFileUpload added in v0.4.0

func WithFileUpload(f File) Option

WithFileUpload writes the content of the reader to the provided path inside the container, before starting the container. This can be specified multiple times.

func WithLivenessCheck added in v0.2.0

func WithLivenessCheck(lc LivenessCheck) Option

WithLivenessCheck defines a function to call repeatedly until it does not error, to ascertain the successful startup of the container. The function will be retried for 10 seconds, and if it does not return a non-nil error before that time, the last error will be returned.

func WithLogger

func WithLogger(in Logger) Option

WithLogger configures the logger of the container. The containers logs will be logged at Info level to this logger. Some errors during closing may also be logged at Error level.

func WithRuntime

func WithRuntime(in Runtime) Option

WithRuntime configures the Runtime to use to launch the container. By default, the auto runtime is used.

func WithUlimit

func WithUlimit(in []Ulimit) Option

WithUlimit configures the ulimits of the container.

type Runtime

type Runtime interface {
	Close(context.Context) error
	Connect(context.Context) error
	StartContainer(context.Context, *ContainerConfig) (Container, error)
}

Runtime supports starting containers.

type Ulimit

type Ulimit struct {
	Name string
	Soft int64
	Hard int64
}

Ulimit describes a container ulimit.

Directories

Path Synopsis
runtimes
podman/iopodman
Podman Service Interface and API description.
Podman Service Interface and API description.

Jump to

Keyboard shortcuts

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