dotcloud/docker

View on GitHub
integration-cli/daemon/daemon.go

Summary

Maintainability
A
0 mins
Test Coverage
package daemon // import "github.com/docker/docker/integration-cli/daemon"

import (
    "context"
    "fmt"
    "strings"
    "testing"
    "time"

    "github.com/docker/docker/testutil/daemon"
    "github.com/pkg/errors"
    "gotest.tools/v3/assert"
    "gotest.tools/v3/icmd"
)

// Daemon represents a Docker daemon for the testing framework.
type Daemon struct {
    *daemon.Daemon
    dockerBinary string
}

// New returns a Daemon instance to be used for testing.
// This will create a directory such as d123456789 in the folder specified by $DOCKER_INTEGRATION_DAEMON_DEST or $DEST.
// The daemon will not automatically start.
func New(t testing.TB, dockerBinary string, dockerdBinary string, ops ...daemon.Option) *Daemon {
    t.Helper()
    ops = append(ops, daemon.WithDockerdBinary(dockerdBinary))
    d := daemon.New(t, ops...)
    return &Daemon{
        Daemon:       d,
        dockerBinary: dockerBinary,
    }
}

// Cmd executes a docker CLI command against this daemon.
// Example: d.Cmd("version") will run docker -H unix://path/to/unix.sock version
func (d *Daemon) Cmd(args ...string) (string, error) {
    result := icmd.RunCmd(d.Command(args...))
    return result.Combined(), result.Error
}

// Command creates a docker CLI command against this daemon, to be executed later.
// Example: d.Command("version") creates a command to run "docker -H unix://path/to/unix.sock version"
func (d *Daemon) Command(args ...string) icmd.Cmd {
    return icmd.Command(d.dockerBinary, d.PrependHostArg(args)...)
}

// PrependHostArg prepend the specified arguments by the daemon host flags
func (d *Daemon) PrependHostArg(args []string) []string {
    for _, arg := range args {
        if arg == "--host" || arg == "-H" {
            return args
        }
    }
    return append([]string{"--host", d.Sock()}, args...)
}

// GetIDByName returns the ID of an object (container, volume, …) given its name
func (d *Daemon) GetIDByName(name string) (string, error) {
    return d.inspectFieldWithError(name, "Id")
}

// InspectField returns the field filter by 'filter'
func (d *Daemon) InspectField(name, filter string) (string, error) {
    return d.inspectFilter(name, filter)
}

func (d *Daemon) inspectFilter(name, filter string) (string, error) {
    format := fmt.Sprintf("{{%s}}", filter)
    out, err := d.Cmd("inspect", "-f", format, name)
    if err != nil {
        return "", errors.Errorf("failed to inspect %s: %s", name, out)
    }
    return strings.TrimSpace(out), nil
}

func (d *Daemon) inspectFieldWithError(name, field string) (string, error) {
    return d.inspectFilter(name, "."+field)
}

// CheckActiveContainerCount returns the number of active containers
// FIXME(vdemeester) should re-use ActivateContainers in some way
func (d *Daemon) CheckActiveContainerCount(ctx context.Context) func(t *testing.T) (interface{}, string) {
    return func(t *testing.T) (interface{}, string) {
        t.Helper()
        out, err := d.Cmd("ps", "-q")
        assert.NilError(t, err)
        if len(strings.TrimSpace(out)) == 0 {
            return 0, ""
        }
        return len(strings.Split(strings.TrimSpace(out), "\n")), fmt.Sprintf("output: %q", out)
    }
}

// WaitRun waits for a container to be running for 10s
func (d *Daemon) WaitRun(contID string) error {
    args := []string{"--host", d.Sock()}
    return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...)
}

// WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time.
// Deprecated: use cli.WaitCmd instead
func WaitInspectWithArgs(dockerBinary, name, expr, expected string, timeout time.Duration, arg ...string) error {
    after := time.After(timeout)

    args := append(arg, "inspect", "-f", expr, name)
    for {
        result := icmd.RunCommand(dockerBinary, args...)
        if result.Error != nil {
            if !strings.Contains(strings.ToLower(result.Stderr()), "no such") {
                return errors.Errorf("error executing docker inspect: %v\n%s",
                    result.Stderr(), result.Stdout())
            }
            select {
            case <-after:
                return result.Error
            default:
                time.Sleep(10 * time.Millisecond)
                continue
            }
        }

        out := strings.TrimSpace(result.Stdout())
        if out == expected {
            break
        }

        select {
        case <-after:
            return errors.Errorf("condition \"%q == %q\" not true in time (%v)", out, expected, timeout)
        default:
        }

        time.Sleep(100 * time.Millisecond)
    }
    return nil
}