소스 검색

[test-integration] Migrate some more tests to `cli` package

Add some required command operators to the `cli` package, and update
some tests to use this package, in order to remove a few functions
from `docker_utils_test.go`

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Vincent Demeester 8 년 전
부모
커밋
eeaa6c96d8

+ 54 - 5
integration-cli/cli/cli.go

@@ -2,12 +2,15 @@ package cli
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"io"
+	"strings"
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/daemon"
 	"github.com/docker/docker/integration-cli/daemon"
 	"github.com/docker/docker/integration-cli/environment"
 	"github.com/docker/docker/integration-cli/environment"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
+	"github.com/pkg/errors"
 )
 )
 
 
 var (
 var (
@@ -40,8 +43,8 @@ type testingT interface {
 }
 }
 
 
 // DockerCmd executes the specified docker command and expect a success
 // DockerCmd executes the specified docker command and expect a success
-func DockerCmd(t testingT, command string, args ...string) *icmd.Result {
-	return Docker(Cmd(command, args...)).Assert(t, icmd.Success)
+func DockerCmd(t testingT, args ...string) *icmd.Result {
+	return Docker(Args(args...)).Assert(t, icmd.Success)
 }
 }
 
 
 // BuildCmd executes the specified docker build command and expect a success
 // BuildCmd executes the specified docker build command and expect a success
@@ -63,9 +66,32 @@ func Docker(cmd icmd.Cmd, cmdOperators ...CmdOperator) *icmd.Result {
 		}
 		}
 	}
 	}
 	appendDocker(&cmd)
 	appendDocker(&cmd)
+	if err := validateArgs(cmd.Command...); err != nil {
+		return &icmd.Result{
+			Error: err,
+		}
+	}
 	return icmd.RunCmd(cmd)
 	return icmd.RunCmd(cmd)
 }
 }
 
 
+// validateArgs is a checker to ensure tests are not running commands which are
+// not supported on platforms. Specifically on Windows this is 'busybox top'.
+func validateArgs(args ...string) error {
+	if testEnv.DaemonPlatform() != "windows" {
+		return nil
+	}
+	foundBusybox := -1
+	for key, value := range args {
+		if strings.ToLower(value) == "busybox" {
+			foundBusybox = key
+		}
+		if (foundBusybox != -1) && (key == foundBusybox+1) && (strings.ToLower(value) == "top") {
+			return errors.New("cannot use 'busybox top' in tests on Windows. Use runSleepingContainer()")
+		}
+	}
+	return nil
+}
+
 // Build executes the specified docker build command
 // Build executes the specified docker build command
 func Build(name string) icmd.Cmd {
 func Build(name string) icmd.Cmd {
 	return icmd.Command("build", "-t", name)
 	return icmd.Command("build", "-t", name)
@@ -91,9 +117,16 @@ func appendDocker(cmd *icmd.Cmd) {
 	cmd.Command = append([]string{testEnv.DockerBinary()}, cmd.Command...)
 	cmd.Command = append([]string{testEnv.DockerBinary()}, cmd.Command...)
 }
 }
 
 
-// Cmd build an icmd.Cmd struct from the specified command and arguments
-func Cmd(command string, args ...string) icmd.Cmd {
-	return icmd.Command(command, args...)
+// Args build an icmd.Cmd struct from the specified arguments
+func Args(args ...string) icmd.Cmd {
+	switch len(args) {
+	case 0:
+		return icmd.Cmd{}
+	case 1:
+		return icmd.Command(args[0])
+	default:
+		return icmd.Command(args[0], args[1:]...)
+	}
 }
 }
 
 
 // Daemon points to the specified daemon
 // Daemon points to the specified daemon
@@ -127,3 +160,19 @@ func WithFlags(flags ...string) func(*icmd.Cmd) func() {
 		return nil
 		return nil
 	}
 	}
 }
 }
+
+// InDir sets the folder in which the command should be executed
+func InDir(path string) func(*icmd.Cmd) func() {
+	return func(cmd *icmd.Cmd) func() {
+		cmd.Dir = path
+		return nil
+	}
+}
+
+// WithStdout sets the standard output writer of the command
+func WithStdout(writer io.Writer) func(*icmd.Cmd) func() {
+	return func(cmd *icmd.Cmd) func() {
+		cmd.Stdout = writer
+		return nil
+	}
+}

+ 2 - 4
integration-cli/docker_api_test.go

@@ -11,6 +11,7 @@ import (
 
 
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/docker/pkg/testutil"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
@@ -71,10 +72,7 @@ func (s *DockerSuite) TestAPIDockerAPIVersion(c *check.C) {
 	defer server.Close()
 	defer server.Close()
 
 
 	// Test using the env var first
 	// Test using the env var first
-	result := icmd.RunCmd(icmd.Cmd{
-		Command: binaryWithArgs("-H="+server.URL[7:], "version"),
-		Env:     appendBaseEnv(false, "DOCKER_API_VERSION=xxx"),
-	})
+	result := cli.Docker(cli.Args("-H="+server.URL[7:], "version"), cli.WithEnvironmentVariables("DOCKER_API_VERSION=xxx"))
 	c.Assert(result, icmd.Matches, icmd.Expected{Out: "API version:  xxx", ExitCode: 1})
 	c.Assert(result, icmd.Matches, icmd.Expected{Out: "API version:  xxx", ExitCode: 1})
 	c.Assert(svrVersion, check.Equals, "/vxxx/version", check.Commentf("%s", result.Compare(icmd.Success)))
 	c.Assert(svrVersion, check.Equals, "/vxxx/version", check.Commentf("%s", result.Compare(icmd.Success)))
 }
 }

+ 32 - 70
integration-cli/docker_cli_build_test.go

@@ -3565,37 +3565,21 @@ func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
 		})
 		})
 	defer ctx.Close()
 	defer ctx.Close()
 
 
-	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
-	if err != nil {
-		c.Fatalf("Failed to build: %s\n%s", out, err)
-	}
-	if !strings.Contains(out, "from Dockerfile") {
-		c.Fatalf("test1 should have used Dockerfile, output:%s", out)
-	}
+	cli.Docker(cli.Args("build", "-t", "test1", "."), cli.InDir(ctx.Dir)).Assert(c, icmd.Expected{
+		Out: "from Dockerfile",
+	})
 
 
-	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
-	if err != nil {
-		c.Fatal(err)
-	}
-	if !strings.Contains(out, "from files/Dockerfile") {
-		c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
-	}
+	cli.Docker(cli.Args("build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", "."), cli.InDir(ctx.Dir)).Assert(c, icmd.Expected{
+		Out: "from files/Dockerfile",
+	})
 
 
-	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
-	if err != nil {
-		c.Fatal(err)
-	}
-	if !strings.Contains(out, "from files/dFile") {
-		c.Fatalf("test3 should have used files/dFile, output:%s", out)
-	}
+	cli.Docker(cli.Args("build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", "."), cli.InDir(ctx.Dir)).Assert(c, icmd.Expected{
+		Out: "from files/dFile",
+	})
 
 
-	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
-	if err != nil {
-		c.Fatal(err)
-	}
-	if !strings.Contains(out, "from dFile") {
-		c.Fatalf("test4 should have used dFile, output:%s", out)
-	}
+	cli.Docker(cli.Args("build", "--file=dFile", "-t", "test4", "."), cli.InDir(ctx.Dir)).Assert(c, icmd.Expected{
+		Out: "from dFile",
+	})
 
 
 	dirWithNoDockerfile, err := ioutil.TempDir(os.TempDir(), "test5")
 	dirWithNoDockerfile, err := ioutil.TempDir(os.TempDir(), "test5")
 	c.Assert(err, check.IsNil)
 	c.Assert(err, check.IsNil)
@@ -3603,54 +3587,32 @@ func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
 	if _, err = os.Create(nonDockerfileFile); err != nil {
 	if _, err = os.Create(nonDockerfileFile); err != nil {
 		c.Fatal(err)
 		c.Fatal(err)
 	}
 	}
-	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
-
-	if err == nil {
-		c.Fatalf("test5 was supposed to fail to find passwd")
-	}
-
-	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
-		c.Fatalf("wrong error message:%v\nexpected to contain=%v", out, expected)
-	}
+	cli.Docker(cli.Args("build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", "."), cli.InDir(ctx.Dir)).Assert(c, icmd.Expected{
+		ExitCode: 1,
+		Err:      fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile),
+	})
 
 
-	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
-	if err != nil {
-		c.Fatalf("test6 failed: %s", err)
-	}
-	if !strings.Contains(out, "from Dockerfile") {
-		c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
-	}
+	cli.Docker(cli.Args("build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", ".."), cli.InDir(filepath.Join(ctx.Dir, "files"))).Assert(c, icmd.Expected{
+		Out: "from Dockerfile",
+	})
 
 
-	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
-	if err != nil {
-		c.Fatalf("test7 failed: %s", err)
-	}
-	if !strings.Contains(out, "from files/Dockerfile") {
-		c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
-	}
+	cli.Docker(cli.Args("build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", ".."), cli.InDir(filepath.Join(ctx.Dir, "files"))).Assert(c, icmd.Expected{
+		Out: "from files/Dockerfile",
+	})
 
 
-	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
-	if err == nil || !strings.Contains(out, "must be within the build context") {
-		c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
-	}
+	cli.Docker(cli.Args("build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", "."), cli.InDir(filepath.Join(ctx.Dir, "files"))).Assert(c, icmd.Expected{
+		ExitCode: 1,
+		Err:      "must be within the build context",
+	})
 
 
 	tmpDir := os.TempDir()
 	tmpDir := os.TempDir()
-	out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
-	if err != nil {
-		c.Fatalf("test9 - failed: %s", err)
-	}
-	if !strings.Contains(out, "from Dockerfile") {
-		c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
-	}
-
-	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
-	if err != nil {
-		c.Fatalf("test10 should have worked: %s", err)
-	}
-	if !strings.Contains(out, "from files/dFile2") {
-		c.Fatalf("test10 should have used files/dFile2, output:%s", out)
-	}
+	cli.Docker(cli.Args("build", "-t", "test9", ctx.Dir), cli.InDir(tmpDir)).Assert(c, icmd.Expected{
+		Out: "from Dockerfile",
+	})
 
 
+	cli.Docker(cli.Args("build", "-f", "dFile2", "-t", "test10", "."), cli.InDir(filepath.Join(ctx.Dir, "files"))).Assert(c, icmd.Expected{
+		Out: "from files/dFile2",
+	})
 }
 }
 
 
 func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
 func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {

+ 8 - 7
integration-cli/docker_cli_build_unix_test.go

@@ -15,6 +15,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/docker/pkg/testutil"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/docker/go-units"
 	"github.com/docker/go-units"
@@ -29,12 +30,12 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
 	FROM hello-world:frozen
 	FROM hello-world:frozen
 	RUN ["/hello"]
 	RUN ["/hello"]
 	`, map[string]string{})
 	`, map[string]string{})
-	_, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "-t", name, ".")
-	if err != nil {
-		c.Fatal(err)
-	}
+	cli.Docker(
+		cli.Args("build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "-t", name, "."),
+		cli.InDir(ctx.Dir),
+	).Assert(c, icmd.Success)
 
 
-	out, _ := dockerCmd(c, "ps", "-lq")
+	out := cli.DockerCmd(c, "ps", "-lq").Combined()
 	cID := strings.TrimSpace(out)
 	cID := strings.TrimSpace(out)
 
 
 	type hostConfig struct {
 	type hostConfig struct {
@@ -50,7 +51,7 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
 	cfg := inspectFieldJSON(c, cID, "HostConfig")
 	cfg := inspectFieldJSON(c, cID, "HostConfig")
 
 
 	var c1 hostConfig
 	var c1 hostConfig
-	err = json.Unmarshal([]byte(cfg), &c1)
+	err := json.Unmarshal([]byte(cfg), &c1)
 	c.Assert(err, checker.IsNil, check.Commentf(cfg))
 	c.Assert(err, checker.IsNil, check.Commentf(cfg))
 
 
 	c.Assert(c1.Memory, checker.Equals, int64(64*1024*1024), check.Commentf("resource constraints not set properly for Memory"))
 	c.Assert(c1.Memory, checker.Equals, int64(64*1024*1024), check.Commentf("resource constraints not set properly for Memory"))
@@ -63,7 +64,7 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
 	c.Assert(c1.Ulimits[0].Hard, checker.Equals, int64(42), check.Commentf("resource constraints not set properly for Ulimits"))
 	c.Assert(c1.Ulimits[0].Hard, checker.Equals, int64(42), check.Commentf("resource constraints not set properly for Ulimits"))
 
 
 	// Make sure constraints aren't saved to image
 	// Make sure constraints aren't saved to image
-	dockerCmd(c, "run", "--name=test", name)
+	cli.DockerCmd(c, "run", "--name=test", name)
 
 
 	cfg = inspectFieldJSON(c, "test", "HostConfig")
 	cfg = inspectFieldJSON(c, "test", "HostConfig")
 
 

+ 3 - 3
integration-cli/docker_cli_daemon_test.go

@@ -49,19 +49,19 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithRunningContainersPorts(c *check
 	s.d.StartWithBusybox(c)
 	s.d.StartWithBusybox(c)
 
 
 	cli.Docker(
 	cli.Docker(
-		cli.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"),
+		cli.Args("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"),
 		cli.Daemon(s.d),
 		cli.Daemon(s.d),
 	).Assert(c, icmd.Success)
 	).Assert(c, icmd.Success)
 
 
 	cli.Docker(
 	cli.Docker(
-		cli.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"),
+		cli.Args("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"),
 		cli.Daemon(s.d),
 		cli.Daemon(s.d),
 	).Assert(c, icmd.Success)
 	).Assert(c, icmd.Success)
 
 
 	testRun := func(m map[string]bool, prefix string) {
 	testRun := func(m map[string]bool, prefix string) {
 		var format string
 		var format string
 		for cont, shouldRun := range m {
 		for cont, shouldRun := range m {
-			out := cli.Docker(cli.Cmd("ps"), cli.Daemon(s.d)).Assert(c, icmd.Success).Combined()
+			out := cli.Docker(cli.Args("ps"), cli.Daemon(s.d)).Assert(c, icmd.Success).Combined()
 			if shouldRun {
 			if shouldRun {
 				format = "%scontainer %q is not running"
 				format = "%scontainer %q is not running"
 			} else {
 			} else {

+ 8 - 8
integration-cli/docker_cli_help_test.go

@@ -7,6 +7,7 @@ import (
 	"unicode"
 	"unicode"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/pkg/homedir"
 	"github.com/docker/docker/pkg/homedir"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
@@ -149,29 +150,29 @@ func (s *DockerSuite) TestHelpExitCodesHelpOutput(c *check.C) {
 	// various good and bad cases are what we expect
 	// various good and bad cases are what we expect
 
 
 	// docker : stdout=all, stderr=empty, rc=0
 	// docker : stdout=all, stderr=empty, rc=0
-	out, _ := dockerCmd(c)
+	out := cli.DockerCmd(c).Combined()
 	// Be really pick
 	// Be really pick
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker'\n"))
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker'\n"))
 
 
 	// docker help: stdout=all, stderr=empty, rc=0
 	// docker help: stdout=all, stderr=empty, rc=0
-	out, _ = dockerCmd(c, "help")
+	out = cli.DockerCmd(c, "help").Combined()
 	// Be really pick
 	// Be really pick
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker help'\n"))
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker help'\n"))
 
 
 	// docker --help: stdout=all, stderr=empty, rc=0
 	// docker --help: stdout=all, stderr=empty, rc=0
-	out, _ = dockerCmd(c, "--help")
+	out = cli.DockerCmd(c, "--help").Combined()
 	// Be really pick
 	// Be really pick
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker --help'\n"))
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker --help'\n"))
 
 
 	// docker inspect busybox: stdout=all, stderr=empty, rc=0
 	// docker inspect busybox: stdout=all, stderr=empty, rc=0
 	// Just making sure stderr is empty on valid cmd
 	// Just making sure stderr is empty on valid cmd
-	out, _ = dockerCmd(c, "inspect", "busybox")
+	out = cli.DockerCmd(c, "inspect", "busybox").Combined()
 	// Be really pick
 	// Be really pick
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker inspect busyBox'\n"))
 	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker inspect busyBox'\n"))
 
 
 	// docker rm: stdout=empty, stderr=all, rc!=0
 	// docker rm: stdout=empty, stderr=all, rc!=0
 	// testing the min arg error msg
 	// testing the min arg error msg
-	icmd.RunCommand(dockerBinary, "rm").Assert(c, icmd.Expected{
+	cli.Docker(cli.Args("rm")).Assert(c, icmd.Expected{
 		ExitCode: 1,
 		ExitCode: 1,
 		Error:    "exit status 1",
 		Error:    "exit status 1",
 		Out:      "",
 		Out:      "",
@@ -182,8 +183,7 @@ func (s *DockerSuite) TestHelpExitCodesHelpOutput(c *check.C) {
 
 
 	// docker rm NoSuchContainer: stdout=empty, stderr=all, rc=0
 	// docker rm NoSuchContainer: stdout=empty, stderr=all, rc=0
 	// testing to make sure no blank line on error
 	// testing to make sure no blank line on error
-	result := icmd.RunCommand(dockerBinary, "rm", "NoSuchContainer")
-	result.Assert(c, icmd.Expected{
+	result := cli.Docker(cli.Args("rm", "NoSuchContainer")).Assert(c, icmd.Expected{
 		ExitCode: 1,
 		ExitCode: 1,
 		Error:    "exit status 1",
 		Error:    "exit status 1",
 		Out:      "",
 		Out:      "",
@@ -193,7 +193,7 @@ func (s *DockerSuite) TestHelpExitCodesHelpOutput(c *check.C) {
 	c.Assert(result.Stderr(), checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker rm'\n"))
 	c.Assert(result.Stderr(), checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker rm'\n"))
 
 
 	// docker BadCmd: stdout=empty, stderr=all, rc=0
 	// docker BadCmd: stdout=empty, stderr=all, rc=0
-	icmd.RunCommand(dockerBinary, "BadCmd").Assert(c, icmd.Expected{
+	cli.Docker(cli.Args("BadCmd")).Assert(c, icmd.Expected{
 		ExitCode: 1,
 		ExitCode: 1,
 		Error:    "exit status 1",
 		Error:    "exit status 1",
 		Out:      "",
 		Out:      "",

+ 5 - 9
integration-cli/docker_cli_import_test.go

@@ -10,6 +10,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/docker/pkg/testutil"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
@@ -126,22 +127,17 @@ func (s *DockerSuite) TestImportFileNonExistentFile(c *check.C) {
 
 
 func (s *DockerSuite) TestImportWithQuotedChanges(c *check.C) {
 func (s *DockerSuite) TestImportWithQuotedChanges(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
-	dockerCmd(c, "run", "--name", "test-import", "busybox", "true")
+	cli.DockerCmd(c, "run", "--name", "test-import", "busybox", "true")
 
 
 	temporaryFile, err := ioutil.TempFile("", "exportImportTest")
 	temporaryFile, err := ioutil.TempFile("", "exportImportTest")
 	c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary file"))
 	c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary file"))
 	defer os.Remove(temporaryFile.Name())
 	defer os.Remove(temporaryFile.Name())
 
 
-	result := icmd.RunCmd(icmd.Cmd{
-		Command: binaryWithArgs("export", "test-import"),
-		Stdout:  bufio.NewWriter(temporaryFile),
-	})
-	c.Assert(result, icmd.Matches, icmd.Success)
+	cli.Docker(cli.Args("export", "test-import"), cli.WithStdout(bufio.NewWriter(temporaryFile))).Assert(c, icmd.Success)
 
 
-	result = dockerCmdWithResult("import", "-c", `ENTRYPOINT ["/bin/sh", "-c"]`, temporaryFile.Name())
-	c.Assert(result, icmd.Matches, icmd.Success)
+	result := cli.DockerCmd(c, "import", "-c", `ENTRYPOINT ["/bin/sh", "-c"]`, temporaryFile.Name())
 	image := strings.TrimSpace(result.Stdout())
 	image := strings.TrimSpace(result.Stdout())
 
 
-	result = dockerCmdWithResult("run", "--rm", image, "true")
+	result = cli.DockerCmd(c, "run", "--rm", image, "true")
 	c.Assert(result, icmd.Matches, icmd.Expected{Out: icmd.None})
 	c.Assert(result, icmd.Matches, icmd.Expected{Out: icmd.None})
 }
 }

+ 21 - 27
integration-cli/docker_cli_logs_test.go

@@ -9,6 +9,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/pkg/jsonlog"
 	"github.com/docker/docker/pkg/jsonlog"
 	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/docker/pkg/testutil"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
@@ -65,18 +66,13 @@ func (s *DockerSuite) TestLogsTimestamps(c *check.C) {
 
 
 func (s *DockerSuite) TestLogsSeparateStderr(c *check.C) {
 func (s *DockerSuite) TestLogsSeparateStderr(c *check.C) {
 	msg := "stderr_log"
 	msg := "stderr_log"
-	out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg))
-
+	out := cli.DockerCmd(c, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg)).Combined()
 	id := strings.TrimSpace(out)
 	id := strings.TrimSpace(out)
-	dockerCmd(c, "wait", id)
-
-	stdout, stderr, _ := dockerCmdWithStdoutStderr(c, "logs", id)
-
-	c.Assert(stdout, checker.Equals, "")
-
-	stderr = strings.TrimSpace(stderr)
-
-	c.Assert(stderr, checker.Equals, msg)
+	cli.DockerCmd(c, "wait", id)
+	cli.DockerCmd(c, "logs", id).Assert(c, icmd.Expected{
+		Out: "",
+		Err: msg,
+	})
 }
 }
 
 
 func (s *DockerSuite) TestLogsStderrInStdout(c *check.C) {
 func (s *DockerSuite) TestLogsStderrInStdout(c *check.C) {
@@ -84,46 +80,44 @@ func (s *DockerSuite) TestLogsStderrInStdout(c *check.C) {
 	// a bunch of ANSI escape sequences before the "stderr_log" message.
 	// a bunch of ANSI escape sequences before the "stderr_log" message.
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	msg := "stderr_log"
 	msg := "stderr_log"
-	out, _ := dockerCmd(c, "run", "-d", "-t", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg))
-
+	out := cli.DockerCmd(c, "run", "-d", "-t", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg)).Combined()
 	id := strings.TrimSpace(out)
 	id := strings.TrimSpace(out)
-	dockerCmd(c, "wait", id)
+	cli.DockerCmd(c, "wait", id)
 
 
-	stdout, stderr, _ := dockerCmdWithStdoutStderr(c, "logs", id)
-	c.Assert(stderr, checker.Equals, "")
-
-	stdout = strings.TrimSpace(stdout)
-	c.Assert(stdout, checker.Equals, msg)
+	cli.DockerCmd(c, "logs", id).Assert(c, icmd.Expected{
+		Out: msg,
+		Err: "",
+	})
 }
 }
 
 
 func (s *DockerSuite) TestLogsTail(c *check.C) {
 func (s *DockerSuite) TestLogsTail(c *check.C) {
 	testLen := 100
 	testLen := 100
-	out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo =; done;", testLen))
+	out := cli.DockerCmd(c, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo =; done;", testLen)).Combined()
 
 
 	id := strings.TrimSpace(out)
 	id := strings.TrimSpace(out)
-	dockerCmd(c, "wait", id)
+	cli.DockerCmd(c, "wait", id)
 
 
-	out, _ = dockerCmd(c, "logs", "--tail", "0", id)
+	out = cli.DockerCmd(c, "logs", "--tail", "0", id).Combined()
 	lines := strings.Split(out, "\n")
 	lines := strings.Split(out, "\n")
 	c.Assert(lines, checker.HasLen, 1)
 	c.Assert(lines, checker.HasLen, 1)
 
 
-	out, _ = dockerCmd(c, "logs", "--tail", "5", id)
+	out = cli.DockerCmd(c, "logs", "--tail", "5", id).Combined()
 	lines = strings.Split(out, "\n")
 	lines = strings.Split(out, "\n")
 	c.Assert(lines, checker.HasLen, 6)
 	c.Assert(lines, checker.HasLen, 6)
 
 
-	out, _ = dockerCmd(c, "logs", "--tail", "99", id)
+	out = cli.DockerCmd(c, "logs", "--tail", "99", id).Combined()
 	lines = strings.Split(out, "\n")
 	lines = strings.Split(out, "\n")
 	c.Assert(lines, checker.HasLen, 100)
 	c.Assert(lines, checker.HasLen, 100)
 
 
-	out, _ = dockerCmd(c, "logs", "--tail", "all", id)
+	out = cli.DockerCmd(c, "logs", "--tail", "all", id).Combined()
 	lines = strings.Split(out, "\n")
 	lines = strings.Split(out, "\n")
 	c.Assert(lines, checker.HasLen, testLen+1)
 	c.Assert(lines, checker.HasLen, testLen+1)
 
 
-	out, _ = dockerCmd(c, "logs", "--tail", "-1", id)
+	out = cli.DockerCmd(c, "logs", "--tail", "-1", id).Combined()
 	lines = strings.Split(out, "\n")
 	lines = strings.Split(out, "\n")
 	c.Assert(lines, checker.HasLen, testLen+1)
 	c.Assert(lines, checker.HasLen, testLen+1)
 
 
-	out, _, _ = dockerCmdWithStdoutStderr(c, "logs", "--tail", "random", id)
+	out = cli.DockerCmd(c, "logs", "--tail", "random", id).Combined()
 	lines = strings.Split(out, "\n")
 	lines = strings.Split(out, "\n")
 	c.Assert(lines, checker.HasLen, testLen+1)
 	c.Assert(lines, checker.HasLen, testLen+1)
 }
 }

+ 11 - 10
integration-cli/docker_cli_ps_test.go

@@ -11,6 +11,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
@@ -185,26 +186,26 @@ func (s *DockerSuite) TestPsListContainersSize(c *check.C) {
 
 
 func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
 func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
 	// start exited container
 	// start exited container
-	out, _ := dockerCmd(c, "run", "-d", "busybox")
+	out := cli.DockerCmd(c, "run", "-d", "busybox").Combined()
 	firstID := strings.TrimSpace(out)
 	firstID := strings.TrimSpace(out)
 
 
 	// make sure the exited container is not running
 	// make sure the exited container is not running
-	dockerCmd(c, "wait", firstID)
+	cli.DockerCmd(c, "wait", firstID)
 
 
 	// start running container
 	// start running container
-	out, _ = dockerCmd(c, "run", "-itd", "busybox")
+	out = cli.DockerCmd(c, "run", "-itd", "busybox").Combined()
 	secondID := strings.TrimSpace(out)
 	secondID := strings.TrimSpace(out)
 
 
 	// filter containers by exited
 	// filter containers by exited
-	out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=exited")
+	out = cli.DockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=exited").Combined()
 	containerOut := strings.TrimSpace(out)
 	containerOut := strings.TrimSpace(out)
 	c.Assert(containerOut, checker.Equals, firstID)
 	c.Assert(containerOut, checker.Equals, firstID)
 
 
-	out, _ = dockerCmd(c, "ps", "-a", "--no-trunc", "-q", "--filter=status=running")
+	out = cli.DockerCmd(c, "ps", "-a", "--no-trunc", "-q", "--filter=status=running").Combined()
 	containerOut = strings.TrimSpace(out)
 	containerOut = strings.TrimSpace(out)
 	c.Assert(containerOut, checker.Equals, secondID)
 	c.Assert(containerOut, checker.Equals, secondID)
 
 
-	result := dockerCmdWithTimeout(time.Second*60, "ps", "-a", "-q", "--filter=status=rubbish")
+	result := cli.Docker(cli.Args("ps", "-a", "-q", "--filter=status=rubbish"), cli.WithTimeout(time.Second*60))
 	c.Assert(result, icmd.Matches, icmd.Expected{
 	c.Assert(result, icmd.Matches, icmd.Expected{
 		ExitCode: 1,
 		ExitCode: 1,
 		Err:      "Unrecognised filter value for status",
 		Err:      "Unrecognised filter value for status",
@@ -213,13 +214,13 @@ func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
 	// Windows doesn't support pausing of containers
 	// Windows doesn't support pausing of containers
 	if testEnv.DaemonPlatform() != "windows" {
 	if testEnv.DaemonPlatform() != "windows" {
 		// pause running container
 		// pause running container
-		out, _ = dockerCmd(c, "run", "-itd", "busybox")
+		out = cli.DockerCmd(c, "run", "-itd", "busybox").Combined()
 		pausedID := strings.TrimSpace(out)
 		pausedID := strings.TrimSpace(out)
-		dockerCmd(c, "pause", pausedID)
+		cli.DockerCmd(c, "pause", pausedID)
 		// make sure the container is unpaused to let the daemon stop it properly
 		// make sure the container is unpaused to let the daemon stop it properly
-		defer func() { dockerCmd(c, "unpause", pausedID) }()
+		defer func() { cli.DockerCmd(c, "unpause", pausedID) }()
 
 
-		out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=paused")
+		out = cli.DockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=paused").Combined()
 		containerOut = strings.TrimSpace(out)
 		containerOut = strings.TrimSpace(out)
 		c.Assert(containerOut, checker.Equals, pausedID)
 		c.Assert(containerOut, checker.Equals, pausedID)
 	}
 	}

+ 32 - 28
integration-cli/docker_cli_run_test.go

@@ -22,6 +22,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
@@ -1285,19 +1286,19 @@ func (s *DockerSuite) TestRunDNSOptions(c *check.C) {
 	// Not applicable on Windows as Windows does not support --dns*, or
 	// Not applicable on Windows as Windows does not support --dns*, or
 	// the Unix-specific functionality of resolv.conf.
 	// the Unix-specific functionality of resolv.conf.
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
-	out, stderr, _ := dockerCmdWithStdoutStderr(c, "run", "--dns=127.0.0.1", "--dns-search=mydomain", "--dns-opt=ndots:9", "busybox", "cat", "/etc/resolv.conf")
+	result := cli.DockerCmd(c, "run", "--dns=127.0.0.1", "--dns-search=mydomain", "--dns-opt=ndots:9", "busybox", "cat", "/etc/resolv.conf")
 
 
 	// The client will get a warning on stderr when setting DNS to a localhost address; verify this:
 	// The client will get a warning on stderr when setting DNS to a localhost address; verify this:
-	if !strings.Contains(stderr, "Localhost DNS setting") {
-		c.Fatalf("Expected warning on stderr about localhost resolver, but got %q", stderr)
+	if !strings.Contains(result.Stderr(), "Localhost DNS setting") {
+		c.Fatalf("Expected warning on stderr about localhost resolver, but got %q", result.Stderr())
 	}
 	}
 
 
-	actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
+	actual := strings.Replace(strings.Trim(result.Stdout(), "\r\n"), "\n", " ", -1)
 	if actual != "search mydomain nameserver 127.0.0.1 options ndots:9" {
 	if actual != "search mydomain nameserver 127.0.0.1 options ndots:9" {
 		c.Fatalf("expected 'search mydomain nameserver 127.0.0.1 options ndots:9', but says: %q", actual)
 		c.Fatalf("expected 'search mydomain nameserver 127.0.0.1 options ndots:9', but says: %q", actual)
 	}
 	}
 
 
-	out, _ = dockerCmd(c, "run", "--dns=1.1.1.1", "--dns-search=.", "--dns-opt=ndots:3", "busybox", "cat", "/etc/resolv.conf")
+	out := cli.DockerCmd(c, "run", "--dns=1.1.1.1", "--dns-search=.", "--dns-opt=ndots:3", "busybox", "cat", "/etc/resolv.conf").Combined()
 
 
 	actual = strings.Replace(strings.Trim(strings.Trim(out, "\r\n"), " "), "\n", " ", -1)
 	actual = strings.Replace(strings.Trim(strings.Trim(out, "\r\n"), " "), "\n", " ", -1)
 	if actual != "nameserver 1.1.1.1 options ndots:3" {
 	if actual != "nameserver 1.1.1.1 options ndots:3" {
@@ -1307,7 +1308,7 @@ func (s *DockerSuite) TestRunDNSOptions(c *check.C) {
 
 
 func (s *DockerSuite) TestRunDNSRepeatOptions(c *check.C) {
 func (s *DockerSuite) TestRunDNSRepeatOptions(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
-	out, _, _ := dockerCmdWithStdoutStderr(c, "run", "--dns=1.1.1.1", "--dns=2.2.2.2", "--dns-search=mydomain", "--dns-search=mydomain2", "--dns-opt=ndots:9", "--dns-opt=timeout:3", "busybox", "cat", "/etc/resolv.conf")
+	out := cli.DockerCmd(c, "run", "--dns=1.1.1.1", "--dns=2.2.2.2", "--dns-search=mydomain", "--dns-search=mydomain2", "--dns-opt=ndots:9", "--dns-opt=timeout:3", "busybox", "cat", "/etc/resolv.conf").Stdout()
 
 
 	actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
 	actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
 	if actual != "search mydomain mydomain2 nameserver 1.1.1.1 nameserver 2.2.2.2 options ndots:9 timeout:3" {
 	if actual != "search mydomain mydomain2 nameserver 1.1.1.1 nameserver 2.2.2.2 options ndots:9 timeout:3" {
@@ -4093,26 +4094,30 @@ func (s *DockerSuite) TestRunDNSInHostMode(c *check.C) {
 
 
 	expectedOutput := "nameserver 127.0.0.1"
 	expectedOutput := "nameserver 127.0.0.1"
 	expectedWarning := "Localhost DNS setting"
 	expectedWarning := "Localhost DNS setting"
-	out, stderr, _ := dockerCmdWithStdoutStderr(c, "run", "--dns=127.0.0.1", "--net=host", "busybox", "cat", "/etc/resolv.conf")
-	c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
-	c.Assert(stderr, checker.Contains, expectedWarning, check.Commentf("Expected warning on stderr about localhost resolver, but got %q", stderr))
+	cli.DockerCmd(c, "run", "--dns=127.0.0.1", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
+		Out: expectedOutput,
+		Err: expectedWarning,
+	})
 
 
 	expectedOutput = "nameserver 1.2.3.4"
 	expectedOutput = "nameserver 1.2.3.4"
-	out, _ = dockerCmd(c, "run", "--dns=1.2.3.4", "--net=host", "busybox", "cat", "/etc/resolv.conf")
-	c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
+	cli.DockerCmd(c, "run", "--dns=1.2.3.4", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
+		Out: expectedOutput,
+	})
 
 
 	expectedOutput = "search example.com"
 	expectedOutput = "search example.com"
-	out, _ = dockerCmd(c, "run", "--dns-search=example.com", "--net=host", "busybox", "cat", "/etc/resolv.conf")
-	c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
+	cli.DockerCmd(c, "run", "--dns-search=example.com", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
+		Out: expectedOutput,
+	})
 
 
 	expectedOutput = "options timeout:3"
 	expectedOutput = "options timeout:3"
-	out, _ = dockerCmd(c, "run", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf")
-	c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
+	cli.DockerCmd(c, "run", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
+		Out: expectedOutput,
+	})
 
 
 	expectedOutput1 := "nameserver 1.2.3.4"
 	expectedOutput1 := "nameserver 1.2.3.4"
 	expectedOutput2 := "search example.com"
 	expectedOutput2 := "search example.com"
 	expectedOutput3 := "options timeout:3"
 	expectedOutput3 := "options timeout:3"
-	out, _ = dockerCmd(c, "run", "--dns=1.2.3.4", "--dns-search=example.com", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf")
+	out := cli.DockerCmd(c, "run", "--dns=1.2.3.4", "--dns-search=example.com", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf").Combined()
 	c.Assert(out, checker.Contains, expectedOutput1, check.Commentf("Expected '%s', but got %q", expectedOutput1, out))
 	c.Assert(out, checker.Contains, expectedOutput1, check.Commentf("Expected '%s', but got %q", expectedOutput1, out))
 	c.Assert(out, checker.Contains, expectedOutput2, check.Commentf("Expected '%s', but got %q", expectedOutput2, out))
 	c.Assert(out, checker.Contains, expectedOutput2, check.Commentf("Expected '%s', but got %q", expectedOutput2, out))
 	c.Assert(out, checker.Contains, expectedOutput3, check.Commentf("Expected '%s', but got %q", expectedOutput3, out))
 	c.Assert(out, checker.Contains, expectedOutput3, check.Commentf("Expected '%s', but got %q", expectedOutput3, out))
@@ -4139,25 +4144,24 @@ func (s *DockerSuite) TestRunRmAndWait(c *check.C) {
 // Test that auto-remove is performed by the daemon (API 1.25 and above)
 // Test that auto-remove is performed by the daemon (API 1.25 and above)
 func (s *DockerSuite) TestRunRm(c *check.C) {
 func (s *DockerSuite) TestRunRm(c *check.C) {
 	name := "miss-me-when-im-gone"
 	name := "miss-me-when-im-gone"
-	dockerCmd(c, "run", "--name="+name, "--rm", "busybox")
+	cli.DockerCmd(c, "run", "--name="+name, "--rm", "busybox")
 
 
-	_, err := inspectFieldWithError(name, "name")
-	c.Assert(err, checker.Not(check.IsNil))
-	c.Assert(err.Error(), checker.Contains, "No such object: "+name)
+	cli.Docker(cli.Inspect(name), cli.Format(".name")).Assert(c, icmd.Expected{
+		ExitCode: 1,
+		Err:      "No such object: " + name,
+	})
 }
 }
 
 
 // Test that auto-remove is performed by the client on API versions that do not support daemon-side api-remove (API < 1.25)
 // Test that auto-remove is performed by the client on API versions that do not support daemon-side api-remove (API < 1.25)
 func (s *DockerSuite) TestRunRmPre125Api(c *check.C) {
 func (s *DockerSuite) TestRunRmPre125Api(c *check.C) {
 	name := "miss-me-when-im-gone"
 	name := "miss-me-when-im-gone"
-	result := icmd.RunCmd(icmd.Cmd{
-		Command: binaryWithArgs("run", "--name="+name, "--rm", "busybox"),
-		Env:     appendBaseEnv(false, "DOCKER_API_VERSION=1.24"),
-	})
-	c.Assert(result, icmd.Matches, icmd.Success)
+	envs := appendBaseEnv(false, "DOCKER_API_VERSION=1.24")
+	cli.Docker(cli.Args("run", "--name="+name, "--rm", "busybox"), cli.WithEnvironmentVariables(envs...)).Assert(c, icmd.Success)
 
 
-	_, err := inspectFieldWithError(name, "name")
-	c.Assert(err, checker.Not(check.IsNil))
-	c.Assert(err.Error(), checker.Contains, "No such object: "+name)
+	cli.Docker(cli.Inspect(name), cli.Format(".name")).Assert(c, icmd.Expected{
+		ExitCode: 1,
+		Err:      "No such object: " + name,
+	})
 }
 }
 
 
 // Test case for #23498
 // Test case for #23498

+ 16 - 11
integration-cli/docker_cli_run_unix_test.go

@@ -17,6 +17,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/pkg/homedir"
 	"github.com/docker/docker/pkg/homedir"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/mount"
@@ -495,11 +496,13 @@ func (s *DockerSuite) TestRunWithKernelMemory(c *check.C) {
 	testRequires(c, kernelMemorySupport)
 	testRequires(c, kernelMemorySupport)
 
 
 	file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"
 	file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"
-	stdout, _, _ := dockerCmdWithStdoutStderr(c, "run", "--kernel-memory", "50M", "--name", "test1", "busybox", "cat", file)
-	c.Assert(strings.TrimSpace(stdout), checker.Equals, "52428800")
+	cli.DockerCmd(c, "run", "--kernel-memory", "50M", "--name", "test1", "busybox", "cat", file).Assert(c, icmd.Expected{
+		Out: "52428800",
+	})
 
 
-	out := inspectField(c, "test1", "HostConfig.KernelMemory")
-	c.Assert(out, check.Equals, "52428800")
+	cli.InspectCmd(c, "test1", cli.Format(".HostConfig.KernelMemory")).Assert(c, icmd.Expected{
+		Out: "52428800",
+	})
 }
 }
 
 
 func (s *DockerSuite) TestRunWithInvalidKernelMemory(c *check.C) {
 func (s *DockerSuite) TestRunWithInvalidKernelMemory(c *check.C) {
@@ -531,8 +534,9 @@ func (s *DockerSuite) TestRunWithCPUShares(c *check.C) {
 func (s *DockerSuite) TestRunEchoStdoutWithCPUSharesAndMemoryLimit(c *check.C) {
 func (s *DockerSuite) TestRunEchoStdoutWithCPUSharesAndMemoryLimit(c *check.C) {
 	testRequires(c, cpuShare)
 	testRequires(c, cpuShare)
 	testRequires(c, memoryLimitSupport)
 	testRequires(c, memoryLimitSupport)
-	out, _, _ := dockerCmdWithStdoutStderr(c, "run", "--cpu-shares", "1000", "-m", "32m", "busybox", "echo", "test")
-	c.Assert(out, checker.Equals, "test\n", check.Commentf("container should've printed 'test'"))
+	cli.DockerCmd(c, "run", "--cpu-shares", "1000", "-m", "32m", "busybox", "echo", "test").Assert(c, icmd.Expected{
+		Out: "test\n",
+	})
 }
 }
 
 
 func (s *DockerSuite) TestRunWithCpusetCpus(c *check.C) {
 func (s *DockerSuite) TestRunWithCpusetCpus(c *check.C) {
@@ -629,11 +633,12 @@ func (s *DockerSuite) TestRunWithMemoryLimit(c *check.C) {
 	testRequires(c, memoryLimitSupport)
 	testRequires(c, memoryLimitSupport)
 
 
 	file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
 	file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
-	stdout, _, _ := dockerCmdWithStdoutStderr(c, "run", "-m", "32M", "--name", "test", "busybox", "cat", file)
-	c.Assert(strings.TrimSpace(stdout), checker.Equals, "33554432")
-
-	out := inspectField(c, "test", "HostConfig.Memory")
-	c.Assert(out, check.Equals, "33554432")
+	cli.DockerCmd(c, "run", "-m", "32M", "--name", "test", "busybox", "cat", file).Assert(c, icmd.Expected{
+		Out: "33554432",
+	})
+	cli.InspectCmd(c, "test", cli.Format(".HostConfig.Memory")).Assert(c, icmd.Expected{
+		Out: "33554432",
+	})
 }
 }
 
 
 // TestRunWithoutMemoryswapLimit sets memory limit and disables swap
 // TestRunWithoutMemoryswapLimit sets memory limit and disables swap

+ 6 - 8
integration-cli/docker_cli_start_test.go

@@ -6,6 +6,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
 )
 )
@@ -42,18 +43,15 @@ func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) {
 // gh#8555: Exit code should be passed through when using start -a
 // gh#8555: Exit code should be passed through when using start -a
 func (s *DockerSuite) TestStartAttachCorrectExitCode(c *check.C) {
 func (s *DockerSuite) TestStartAttachCorrectExitCode(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
-	out, _, _ := dockerCmdWithStdoutStderr(c, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1")
+	out := cli.DockerCmd(c, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1").Stdout()
 	out = strings.TrimSpace(out)
 	out = strings.TrimSpace(out)
 
 
 	// make sure the container has exited before trying the "start -a"
 	// make sure the container has exited before trying the "start -a"
-	dockerCmd(c, "wait", out)
-
-	startOut, exitCode, err := dockerCmdWithError("start", "-a", out)
-	// start command should fail
-	c.Assert(err, checker.NotNil, check.Commentf("startOut: %s", startOut))
-	// start -a did not respond with proper exit code
-	c.Assert(exitCode, checker.Equals, 1, check.Commentf("startOut: %s", startOut))
+	cli.DockerCmd(c, "wait", out)
 
 
+	cli.Docker(cli.Args("start", "-a", out)).Assert(c, icmd.Expected{
+		ExitCode: 1,
+	})
 }
 }
 
 
 func (s *DockerSuite) TestStartAttachSilent(c *check.C) {
 func (s *DockerSuite) TestStartAttachSilent(c *check.C) {

+ 5 - 5
integration-cli/docker_cli_swarm_test.go

@@ -58,7 +58,7 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
 		return sw.Spec
 		return sw.Spec
 	}
 	}
 
 
-	cli.Docker(cli.Cmd("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s"),
+	cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s"),
 		cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
 		cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
 
 
 	spec := getSpec()
 	spec := getSpec()
@@ -67,7 +67,7 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
 
 
 	c.Assert(d.Leave(true), checker.IsNil)
 	c.Assert(d.Leave(true), checker.IsNil)
 	time.Sleep(500 * time.Millisecond) // https://github.com/docker/swarmkit/issues/1421
 	time.Sleep(500 * time.Millisecond) // https://github.com/docker/swarmkit/issues/1421
-	cli.Docker(cli.Cmd("swarm", "init"), cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
+	cli.Docker(cli.Args("swarm", "init"), cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
 
 
 	spec = getSpec()
 	spec = getSpec()
 	c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 90*24*time.Hour)
 	c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 90*24*time.Hour)
@@ -77,12 +77,12 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
 func (s *DockerSwarmSuite) TestSwarmInitIPv6(c *check.C) {
 func (s *DockerSwarmSuite) TestSwarmInitIPv6(c *check.C) {
 	testRequires(c, IPv6)
 	testRequires(c, IPv6)
 	d1 := s.AddDaemon(c, false, false)
 	d1 := s.AddDaemon(c, false, false)
-	cli.Docker(cli.Cmd("swarm", "init", "--listen-add", "::1"), cli.Daemon(d1.Daemon)).Assert(c, icmd.Success)
+	cli.Docker(cli.Args("swarm", "init", "--listen-add", "::1"), cli.Daemon(d1.Daemon)).Assert(c, icmd.Success)
 
 
 	d2 := s.AddDaemon(c, false, false)
 	d2 := s.AddDaemon(c, false, false)
-	cli.Docker(cli.Cmd("swarm", "join", "::1"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success)
+	cli.Docker(cli.Args("swarm", "join", "::1"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success)
 
 
-	out := cli.Docker(cli.Cmd("info"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success).Combined()
+	out := cli.Docker(cli.Args("info"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success).Combined()
 	c.Assert(out, checker.Contains, "Swarm: active")
 	c.Assert(out, checker.Contains, "Swarm: active")
 }
 }
 
 

+ 16 - 18
integration-cli/docker_experimental_network_test.go

@@ -7,6 +7,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
@@ -368,24 +369,23 @@ func (s *DockerSuite) TestDockerNetworkMacVlanBridgeNilParent(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkMacVlanBridgeInternalMode(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkMacVlanBridgeInternalMode(c *check.C) {
 	// macvlan bridge mode --internal containers can communicate inside the network but not externally
 	// macvlan bridge mode --internal containers can communicate inside the network but not externally
 	testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
 	testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
-	dockerCmd(c, "network", "create", "--driver=macvlan", "--internal", "dm-internal")
+	cli.DockerCmd(c, "network", "create", "--driver=macvlan", "--internal", "dm-internal")
 	assertNwIsAvailable(c, "dm-internal")
 	assertNwIsAvailable(c, "dm-internal")
 	nr := getNetworkResource(c, "dm-internal")
 	nr := getNetworkResource(c, "dm-internal")
 	c.Assert(nr.Internal, checker.True)
 	c.Assert(nr.Internal, checker.True)
 
 
 	// start two containers on the same subnet
 	// start two containers on the same subnet
-	dockerCmd(c, "run", "-d", "--net=dm-internal", "--name=first", "busybox", "top")
+	cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=first", "busybox", "top")
 	c.Assert(waitRun("first"), check.IsNil)
 	c.Assert(waitRun("first"), check.IsNil)
-	dockerCmd(c, "run", "-d", "--net=dm-internal", "--name=second", "busybox", "top")
+	cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=second", "busybox", "top")
 	c.Assert(waitRun("second"), check.IsNil)
 	c.Assert(waitRun("second"), check.IsNil)
 
 
 	// access outside of the network should fail
 	// access outside of the network should fail
-	result := dockerCmdWithTimeout(time.Second, "exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8")
+	result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second))
 	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
 	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
 
 
 	// intra-network communications should succeed
 	// intra-network communications should succeed
-	_, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
-	c.Assert(err, check.IsNil)
+	cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first")
 }
 }
 
 
 func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) {
@@ -408,23 +408,22 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkIpvlanL2InternalMode(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkIpvlanL2InternalMode(c *check.C) {
 	// ipvlan l2 mode --internal containers can communicate inside the network but not externally
 	// ipvlan l2 mode --internal containers can communicate inside the network but not externally
 	testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
 	testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
-	dockerCmd(c, "network", "create", "--driver=ipvlan", "--internal", "di-internal")
+	cli.DockerCmd(c, "network", "create", "--driver=ipvlan", "--internal", "di-internal")
 	assertNwIsAvailable(c, "di-internal")
 	assertNwIsAvailable(c, "di-internal")
 	nr := getNetworkResource(c, "di-internal")
 	nr := getNetworkResource(c, "di-internal")
 	c.Assert(nr.Internal, checker.True)
 	c.Assert(nr.Internal, checker.True)
 
 
 	// start two containers on the same subnet
 	// start two containers on the same subnet
-	dockerCmd(c, "run", "-d", "--net=di-internal", "--name=first", "busybox", "top")
+	cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=first", "busybox", "top")
 	c.Assert(waitRun("first"), check.IsNil)
 	c.Assert(waitRun("first"), check.IsNil)
-	dockerCmd(c, "run", "-d", "--net=di-internal", "--name=second", "busybox", "top")
+	cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=second", "busybox", "top")
 	c.Assert(waitRun("second"), check.IsNil)
 	c.Assert(waitRun("second"), check.IsNil)
 
 
 	// access outside of the network should fail
 	// access outside of the network should fail
-	result := dockerCmdWithTimeout(time.Second, "exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8")
+	result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second))
 	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
 	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
 	// intra-network communications should succeed
 	// intra-network communications should succeed
-	_, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
-	c.Assert(err, check.IsNil)
+	cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first")
 }
 }
 
 
 func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) {
@@ -448,24 +447,23 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) {
 	// ipvlan l3 mode --internal containers can communicate inside the network but not externally
 	// ipvlan l3 mode --internal containers can communicate inside the network but not externally
 	testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
 	testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
-	dockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24",
+	cli.DockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24",
 		"--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "--internal", "di-internal-l3")
 		"--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "--internal", "di-internal-l3")
 	assertNwIsAvailable(c, "di-internal-l3")
 	assertNwIsAvailable(c, "di-internal-l3")
 	nr := getNetworkResource(c, "di-internal-l3")
 	nr := getNetworkResource(c, "di-internal-l3")
 	c.Assert(nr.Internal, checker.True)
 	c.Assert(nr.Internal, checker.True)
 
 
 	// start two containers on separate subnets
 	// start two containers on separate subnets
-	dockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-internal-l3", "--name=first", "busybox", "top")
+	cli.DockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-internal-l3", "--name=first", "busybox", "top")
 	c.Assert(waitRun("first"), check.IsNil)
 	c.Assert(waitRun("first"), check.IsNil)
-	dockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-internal-l3", "--name=second", "busybox", "top")
+	cli.DockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-internal-l3", "--name=second", "busybox", "top")
 	c.Assert(waitRun("second"), check.IsNil)
 	c.Assert(waitRun("second"), check.IsNil)
 
 
 	// access outside of the network should fail
 	// access outside of the network should fail
-	result := dockerCmdWithTimeout(time.Second, "exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8")
+	result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second))
 	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
 	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
 	// intra-network communications should succeed
 	// intra-network communications should succeed
-	_, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
-	c.Assert(err, check.IsNil)
+	cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first")
 }
 }
 
 
 func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {

+ 15 - 59
integration-cli/docker_utils_test.go

@@ -79,77 +79,24 @@ func deleteImages(images ...string) error {
 	return icmd.RunCmd(icmd.Cmd{Command: append(args, images...)}).Error
 	return icmd.RunCmd(icmd.Cmd{Command: append(args, images...)}).Error
 }
 }
 
 
+// Deprecated: use cli.Docker or cli.DockerCmd
 func dockerCmdWithError(args ...string) (string, int, error) {
 func dockerCmdWithError(args ...string) (string, int, error) {
-	if err := validateArgs(args...); err != nil {
-		return "", 0, err
-	}
-	result := icmd.RunCommand(dockerBinary, args...)
+	result := cli.Docker(cli.Args(args...))
 	if result.Error != nil {
 	if result.Error != nil {
 		return result.Combined(), result.ExitCode, result.Compare(icmd.Success)
 		return result.Combined(), result.ExitCode, result.Compare(icmd.Success)
 	}
 	}
 	return result.Combined(), result.ExitCode, result.Error
 	return result.Combined(), result.ExitCode, result.Error
 }
 }
 
 
-func dockerCmdWithStdoutStderr(c *check.C, args ...string) (string, string, int) {
-	if err := validateArgs(args...); err != nil {
-		c.Fatalf(err.Error())
-	}
-
-	result := icmd.RunCommand(dockerBinary, args...)
-	c.Assert(result, icmd.Matches, icmd.Success)
-	return result.Stdout(), result.Stderr(), result.ExitCode
-}
-
+// Deprecated: use cli.Docker or cli.DockerCmd
 func dockerCmd(c *check.C, args ...string) (string, int) {
 func dockerCmd(c *check.C, args ...string) (string, int) {
-	if err := validateArgs(args...); err != nil {
-		c.Fatalf(err.Error())
-	}
-	result := icmd.RunCommand(dockerBinary, args...)
-	c.Assert(result, icmd.Matches, icmd.Success)
+	result := cli.DockerCmd(c, args...)
 	return result.Combined(), result.ExitCode
 	return result.Combined(), result.ExitCode
 }
 }
 
 
+// Deprecated: use cli.Docker or cli.DockerCmd
 func dockerCmdWithResult(args ...string) *icmd.Result {
 func dockerCmdWithResult(args ...string) *icmd.Result {
-	return icmd.RunCommand(dockerBinary, args...)
-}
-
-func binaryWithArgs(args ...string) []string {
-	return append([]string{dockerBinary}, args...)
-}
-
-// execute a docker command with a timeout
-func dockerCmdWithTimeout(timeout time.Duration, args ...string) *icmd.Result {
-	if err := validateArgs(args...); err != nil {
-		return &icmd.Result{Error: err}
-	}
-	return icmd.RunCmd(icmd.Cmd{Command: binaryWithArgs(args...), Timeout: timeout})
-}
-
-// execute a docker command in a directory
-func dockerCmdInDir(c *check.C, path string, args ...string) (string, int, error) {
-	if err := validateArgs(args...); err != nil {
-		c.Fatalf(err.Error())
-	}
-	result := icmd.RunCmd(icmd.Cmd{Command: binaryWithArgs(args...), Dir: path})
-	return result.Combined(), result.ExitCode, result.Error
-}
-
-// validateArgs is a checker to ensure tests are not running commands which are
-// not supported on platforms. Specifically on Windows this is 'busybox top'.
-func validateArgs(args ...string) error {
-	if testEnv.DaemonPlatform() != "windows" {
-		return nil
-	}
-	foundBusybox := -1
-	for key, value := range args {
-		if strings.ToLower(value) == "busybox" {
-			foundBusybox = key
-		}
-		if (foundBusybox != -1) && (key == foundBusybox+1) && (strings.ToLower(value) == "top") {
-			return errors.New("cannot use 'busybox top' in tests on Windows. Use runSleepingContainer()")
-		}
-	}
-	return nil
+	return cli.Docker(cli.Args(args...))
 }
 }
 
 
 func findContainerIP(c *check.C, id string, network string) string {
 func findContainerIP(c *check.C, id string, network string) string {
@@ -391,6 +338,7 @@ func inspectFieldAndUnmarshall(c *check.C, name, field string, output interface{
 	}
 	}
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectFilter(name, filter string) (string, error) {
 func inspectFilter(name, filter string) (string, error) {
 	format := fmt.Sprintf("{{%s}}", filter)
 	format := fmt.Sprintf("{{%s}}", filter)
 	result := icmd.RunCommand(dockerBinary, "inspect", "-f", format, name)
 	result := icmd.RunCommand(dockerBinary, "inspect", "-f", format, name)
@@ -400,10 +348,12 @@ func inspectFilter(name, filter string) (string, error) {
 	return strings.TrimSpace(result.Combined()), nil
 	return strings.TrimSpace(result.Combined()), nil
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectFieldWithError(name, field string) (string, error) {
 func inspectFieldWithError(name, field string) (string, error) {
 	return inspectFilter(name, fmt.Sprintf(".%s", field))
 	return inspectFilter(name, fmt.Sprintf(".%s", field))
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectField(c *check.C, name, field string) string {
 func inspectField(c *check.C, name, field string) string {
 	out, err := inspectFilter(name, fmt.Sprintf(".%s", field))
 	out, err := inspectFilter(name, fmt.Sprintf(".%s", field))
 	if c != nil {
 	if c != nil {
@@ -412,6 +362,7 @@ func inspectField(c *check.C, name, field string) string {
 	return out
 	return out
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectFieldJSON(c *check.C, name, field string) string {
 func inspectFieldJSON(c *check.C, name, field string) string {
 	out, err := inspectFilter(name, fmt.Sprintf("json .%s", field))
 	out, err := inspectFilter(name, fmt.Sprintf("json .%s", field))
 	if c != nil {
 	if c != nil {
@@ -420,6 +371,7 @@ func inspectFieldJSON(c *check.C, name, field string) string {
 	return out
 	return out
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectFieldMap(c *check.C, name, path, field string) string {
 func inspectFieldMap(c *check.C, name, path, field string) string {
 	out, err := inspectFilter(name, fmt.Sprintf("index .%s %q", path, field))
 	out, err := inspectFilter(name, fmt.Sprintf("index .%s %q", path, field))
 	if c != nil {
 	if c != nil {
@@ -428,6 +380,7 @@ func inspectFieldMap(c *check.C, name, path, field string) string {
 	return out
 	return out
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectMountSourceField(name, destination string) (string, error) {
 func inspectMountSourceField(name, destination string) (string, error) {
 	m, err := inspectMountPoint(name, destination)
 	m, err := inspectMountPoint(name, destination)
 	if err != nil {
 	if err != nil {
@@ -436,6 +389,7 @@ func inspectMountSourceField(name, destination string) (string, error) {
 	return m.Source, nil
 	return m.Source, nil
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectMountPoint(name, destination string) (types.MountPoint, error) {
 func inspectMountPoint(name, destination string) (types.MountPoint, error) {
 	out, err := inspectFilter(name, "json .Mounts")
 	out, err := inspectFilter(name, "json .Mounts")
 	if err != nil {
 	if err != nil {
@@ -447,6 +401,7 @@ func inspectMountPoint(name, destination string) (types.MountPoint, error) {
 
 
 var errMountNotFound = errors.New("mount point not found")
 var errMountNotFound = errors.New("mount point not found")
 
 
+// Deprecated: use cli.Inspect
 func inspectMountPointJSON(j, destination string) (types.MountPoint, error) {
 func inspectMountPointJSON(j, destination string) (types.MountPoint, error) {
 	var mp []types.MountPoint
 	var mp []types.MountPoint
 	if err := json.Unmarshal([]byte(j), &mp); err != nil {
 	if err := json.Unmarshal([]byte(j), &mp); err != nil {
@@ -468,6 +423,7 @@ func inspectMountPointJSON(j, destination string) (types.MountPoint, error) {
 	return *m, nil
 	return *m, nil
 }
 }
 
 
+// Deprecated: use cli.Inspect
 func inspectImage(c *check.C, name, filter string) string {
 func inspectImage(c *check.C, name, filter string) string {
 	args := []string{"inspect", "--type", "image"}
 	args := []string{"inspect", "--type", "image"}
 	if filter != "" {
 	if filter != "" {