diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index cc6cf98cf7..c2b20912cf 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -5433,7 +5433,7 @@ func (s *DockerTrustSuite) TestTrustedBuild(c *check.C) { name := "testtrustedbuild" buildCmd := buildImageCmd(name, dockerFile, true) - s.trustedCmd(buildCmd) + trustedExecCmd(buildCmd) out, _, err := runCommandWithOutput(buildCmd) if err != nil { c.Fatalf("Error running trusted build: %s\n%s", err, out) @@ -5464,7 +5464,7 @@ func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) { name := "testtrustedbuilduntrustedtag" buildCmd := buildImageCmd(name, dockerFile, true) - s.trustedCmd(buildCmd) + trustedExecCmd(buildCmd) out, _, err := runCommandWithOutput(buildCmd) if err == nil { c.Fatalf("Expected error on trusted build with untrusted tag: %s\n%s", err, out) @@ -5527,10 +5527,7 @@ func (s *DockerTrustSuite) TestTrustedBuildTagFromReleasesRole(c *check.C) { otherTag := fmt.Sprintf("%s:other", repoName) dockerCmd(c, "tag", "busybox", otherTag) - pushCmd := exec.Command(dockerBinary, "push", otherTag) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("Trusted push failed: %s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "push", otherTag), trustedCmd).Assert(c, icmd.Success) s.assertTargetInRoles(c, repoName, "other", "targets/releases") s.assertTargetNotInRoles(c, repoName, "other", "targets") @@ -5545,8 +5542,8 @@ func (s *DockerTrustSuite) TestTrustedBuildTagFromReleasesRole(c *check.C) { name := "testtrustedbuildreleasesrole" buildCmd := buildImageCmd(name, dockerFile, true) - s.trustedCmd(buildCmd) - out, _, err = runCommandWithOutput(buildCmd) + trustedExecCmd(buildCmd) + out, _, err := runCommandWithOutput(buildCmd) c.Assert(err, check.IsNil, check.Commentf("Trusted build failed: %s", out)) c.Assert(out, checker.Contains, fmt.Sprintf("FROM %s@sha", repoName)) } @@ -5566,10 +5563,7 @@ func (s *DockerTrustSuite) TestTrustedBuildTagIgnoresOtherDelegationRoles(c *che otherTag := fmt.Sprintf("%s:other", repoName) dockerCmd(c, "tag", "busybox", otherTag) - pushCmd := exec.Command(dockerBinary, "push", otherTag) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("Trusted push failed: %s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "push", otherTag), trustedCmd).Assert(c, icmd.Success) s.assertTargetInRoles(c, repoName, "other", "targets/other") s.assertTargetNotInRoles(c, repoName, "other", "targets") @@ -5584,8 +5578,8 @@ func (s *DockerTrustSuite) TestTrustedBuildTagIgnoresOtherDelegationRoles(c *che name := "testtrustedbuildotherrole" buildCmd := buildImageCmd(name, dockerFile, true) - s.trustedCmd(buildCmd) - out, _, err = runCommandWithOutput(buildCmd) + trustedExecCmd(buildCmd) + out, _, err := runCommandWithOutput(buildCmd) c.Assert(err, check.NotNil, check.Commentf("Trusted build expected to fail: %s", out)) } diff --git a/integration-cli/docker_cli_build_unix_test.go b/integration-cli/docker_cli_build_unix_test.go index aeda122fb5..386ca40360 100644 --- a/integration-cli/docker_cli_build_unix_test.go +++ b/integration-cli/docker_cli_build_unix_test.go @@ -16,6 +16,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/testutil" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/docker/go-units" "github.com/go-check/check" ) @@ -100,12 +101,10 @@ func (s *DockerSuite) TestBuildAddChangeOwnership(c *check.C) { } defer testFile.Close() - chownCmd := exec.Command("chown", "daemon:daemon", "foo") - chownCmd.Dir = tmpDir - out, _, err := runCommandWithOutput(chownCmd) - if err != nil { - c.Fatal(err, out) - } + icmd.RunCmd(icmd.Cmd{ + Command: []string{"chown", "daemon:daemon", "foo"}, + Dir: tmpDir, + }).Assert(c, icmd.Success) if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { c.Fatalf("failed to open destination dockerfile: %v", err) diff --git a/integration-cli/docker_cli_config_test.go b/integration-cli/docker_cli_config_test.go index 5ca83b75e9..efe2ea7618 100644 --- a/integration-cli/docker_cli_config_test.go +++ b/integration-cli/docker_cli_config_test.go @@ -5,7 +5,6 @@ import ( "net/http" "net/http/httptest" "os" - "os/exec" "path/filepath" "runtime" @@ -13,6 +12,7 @@ import ( "github.com/docker/docker/dockerversion" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/homedir" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -51,15 +51,18 @@ func (s *DockerSuite) TestConfigHTTPHeader(c *check.C) { err = ioutil.WriteFile(tmpCfg, []byte(data), 0600) c.Assert(err, checker.IsNil) - cmd := exec.Command(dockerBinary, "-H="+server.URL[7:], "ps") - out, _, _ := runCommandWithOutput(cmd) + result := icmd.RunCommand(dockerBinary, "-H="+server.URL[7:], "ps") + result.Assert(c, icmd.Expected{ + ExitCode: 1, + Error: "exit status 1", + }) c.Assert(headers["User-Agent"], checker.NotNil, check.Commentf("Missing User-Agent")) - c.Assert(headers["User-Agent"][0], checker.Equals, "Docker-Client/"+dockerversion.Version+" ("+runtime.GOOS+")", check.Commentf("Badly formatted User-Agent,out:%v", out)) + c.Assert(headers["User-Agent"][0], checker.Equals, "Docker-Client/"+dockerversion.Version+" ("+runtime.GOOS+")", check.Commentf("Badly formatted User-Agent,out:%v", result.Combined())) c.Assert(headers["Myheader"], checker.NotNil) - c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("Missing/bad header,out:%v", out)) + c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("Missing/bad header,out:%v", result.Combined())) } @@ -72,11 +75,10 @@ func (s *DockerSuite) TestConfigDir(c *check.C) { dockerCmd(c, "--config", cDir, "ps") // Test with env var too - cmd := exec.Command(dockerBinary, "ps") - cmd.Env = appendBaseEnv(true, "DOCKER_CONFIG="+cDir) - out, _, err := runCommandWithOutput(cmd) - - c.Assert(err, checker.IsNil, check.Commentf("ps2 didn't work,out:%v", out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "ps"}, + Env: appendBaseEnv(true, "DOCKER_CONFIG="+cDir), + }).Assert(c, icmd.Success) // Start a server so we can check to see if the config file was // loaded properly @@ -99,42 +101,51 @@ func (s *DockerSuite) TestConfigDir(c *check.C) { env := appendBaseEnv(false) - cmd = exec.Command(dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps") - cmd.Env = env - out, _, err = runCommandWithOutput(cmd) - - c.Assert(err, checker.NotNil, check.Commentf("out:%v", out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "--config", cDir, "-H=" + server.URL[7:], "ps"}, + Env: env, + }).Assert(c, icmd.Expected{ + ExitCode: 1, + Error: "exit status 1", + }) c.Assert(headers["Myheader"], checker.NotNil) - c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps3 - Missing header,out:%v", out)) + c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps3 - Missing header")) // Reset headers and try again using env var this time headers = map[string][]string{} - cmd = exec.Command(dockerBinary, "-H="+server.URL[7:], "ps") - cmd.Env = append(env, "DOCKER_CONFIG="+cDir) - out, _, err = runCommandWithOutput(cmd) - - c.Assert(err, checker.NotNil, check.Commentf("%v", out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "--config", cDir, "-H=" + server.URL[7:], "ps"}, + Env: append(env, "DOCKER_CONFIG="+cDir), + }).Assert(c, icmd.Expected{ + ExitCode: 1, + }) c.Assert(headers["Myheader"], checker.NotNil) - c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps4 - Missing header,out:%v", out)) + c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps4 - Missing header")) + // FIXME(vdemeester) should be a unit test // Reset headers and make sure flag overrides the env var headers = map[string][]string{} - cmd = exec.Command(dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps") - cmd.Env = append(env, "DOCKER_CONFIG=MissingDir") - out, _, err = runCommandWithOutput(cmd) - - c.Assert(err, checker.NotNil, check.Commentf("out:%v", out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "--config", cDir, "-H=" + server.URL[7:], "ps"}, + Env: append(env, "DOCKER_CONFIG=MissingDir"), + }).Assert(c, icmd.Expected{ + ExitCode: 1, + }) c.Assert(headers["Myheader"], checker.NotNil) - c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps5 - Missing header,out:%v", out)) + c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps5 - Missing header")) + // FIXME(vdemeester) should be a unit test // Reset headers and make sure flag overrides the env var. // Almost same as previous but make sure the "MissingDir" isn't // ignore - we don't want to default back to the env var. headers = map[string][]string{} - cmd = exec.Command(dockerBinary, "--config", "MissingDir", "-H="+server.URL[7:], "ps") - cmd.Env = append(env, "DOCKER_CONFIG="+cDir) - out, _, err = runCommandWithOutput(cmd) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "--config", "MissingDir", "-H=" + server.URL[7:], "ps"}, + Env: append(env, "DOCKER_CONFIG="+cDir), + }).Assert(c, icmd.Expected{ + ExitCode: 1, + Error: "exit status 1", + }) - c.Assert(err, checker.NotNil, check.Commentf("out:%v", out)) - c.Assert(headers["Myheader"], checker.IsNil, check.Commentf("ps6 - Headers shouldn't be the expected value,out:%v", out)) + c.Assert(headers["Myheader"], checker.IsNil, check.Commentf("ps6 - Headers shouldn't be the expected value")) } diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go index 0f7676f91e..d23d39c459 100644 --- a/integration-cli/docker_cli_create_test.go +++ b/integration-cli/docker_cli_create_test.go @@ -3,18 +3,16 @@ package main import ( "encoding/json" "fmt" + "io/ioutil" "os" "reflect" "strings" "time" - "os/exec" - - "io/ioutil" - "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/testutil" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/docker/go-connections/nat" "github.com/go-check/check" ) @@ -302,21 +300,12 @@ func (s *DockerTrustSuite) TestTrustedCreate(c *check.C) { repoName := s.setupTrustedImage(c, "trusted-create") // Try create - createCmd := exec.Command(dockerBinary, "create", repoName) - s.trustedCmd(createCmd) - out, _, err := runCommandWithOutput(createCmd) - c.Assert(err, check.IsNil) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf("Missing expected output on trusted push:\n%s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "create", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) // Try untrusted create to ensure we pushed the tag to the registry - createCmd = exec.Command(dockerBinary, "create", "--disable-content-trust=true", repoName) - s.trustedCmd(createCmd) - out, _, err = runCommandWithOutput(createCmd) - c.Assert(err, check.IsNil) - c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf("Missing expected output on trusted create with --disable-content-trust:\n%s", out)) - + icmd.RunCmd(icmd.Command(dockerBinary, "create", "--disable-content-trust=true", repoName), trustedCmd).Assert(c, SuccessDownloadedOnStderr) } func (s *DockerTrustSuite) TestUntrustedCreate(c *check.C) { @@ -328,23 +317,17 @@ func (s *DockerTrustSuite) TestUntrustedCreate(c *check.C) { dockerCmd(c, "rmi", withTagName) // Try trusted create on untrusted tag - createCmd := exec.Command(dockerBinary, "create", withTagName) - s.trustedCmd(createCmd) - out, _, err := runCommandWithOutput(createCmd) - c.Assert(err, check.Not(check.IsNil)) - c.Assert(string(out), checker.Contains, fmt.Sprintf("does not have trust data for %s", repoName), check.Commentf("Missing expected output on trusted create:\n%s", out)) - + icmd.RunCmd(icmd.Command(dockerBinary, "create", withTagName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: fmt.Sprintf("does not have trust data for %s", repoName), + }) } func (s *DockerTrustSuite) TestTrustedIsolatedCreate(c *check.C) { repoName := s.setupTrustedImage(c, "trusted-isolated-create") // Try create - createCmd := exec.Command(dockerBinary, "--config", "/tmp/docker-isolated-create", "create", repoName) - s.trustedCmd(createCmd) - out, _, err := runCommandWithOutput(createCmd) - c.Assert(err, check.IsNil) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf("Missing expected output on trusted push:\n%s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "--config", "/tmp/docker-isolated-create", "create", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) } @@ -358,20 +341,19 @@ func (s *DockerTrustSuite) TestCreateWhenCertExpired(c *check.C) { testutil.RunAtDifferentDate(elevenYearsFromNow, func() { // Try create - createCmd := exec.Command(dockerBinary, "create", repoName) - s.trustedCmd(createCmd) - out, _, err := runCommandWithOutput(createCmd) - c.Assert(err, check.Not(check.IsNil)) - c.Assert(string(out), checker.Contains, "could not validate the path to a trusted root", check.Commentf("Missing expected output on trusted create in the distant future:\n%s", out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "create", repoName}, + }, trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "could not validate the path to a trusted root", + }) }) testutil.RunAtDifferentDate(elevenYearsFromNow, func() { // Try create - createCmd := exec.Command(dockerBinary, "create", "--disable-content-trust", repoName) - s.trustedCmd(createCmd) - out, _, err := runCommandWithOutput(createCmd) - c.Assert(err, check.Not(check.IsNil)) - c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf("Missing expected output on trusted create in the distant future:\n%s", out)) + result := icmd.RunCmd(icmd.Command(dockerBinary, "create", "--disable-content-trust", repoName), trustedCmd) + c.Assert(result.Error, check.Not(check.IsNil)) + c.Assert(string(result.Combined()), checker.Contains, "Status: Downloaded", check.Commentf("Missing expected output on trusted create in the distant future:\n%s", result.Combined())) }) } @@ -384,20 +366,12 @@ func (s *DockerTrustSuite) TestTrustedCreateFromBadTrustServer(c *check.C) { // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil) - c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push:\n%s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) dockerCmd(c, "rmi", repoName) // Try create - createCmd := exec.Command(dockerBinary, "create", repoName) - s.trustedCmd(createCmd) - out, _, err = runCommandWithOutput(createCmd) - c.Assert(err, check.IsNil) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf("Missing expected output on trusted push:\n%s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "create", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) @@ -411,23 +385,13 @@ func (s *DockerTrustSuite) TestTrustedCreateFromBadTrustServer(c *check.C) { dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName) // Push up to the new server - pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err = runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil) - c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push:\n%s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Now, try creating with the original client from this new trust server. This should fail because the new root is invalid. - createCmd = exec.Command(dockerBinary, "create", repoName) - s.trustedCmd(createCmd) - out, _, err = runCommandWithOutput(createCmd) - if err == nil { - c.Fatalf("Continuing with cached data even though it's an invalid root rotation: %s\n%s", err, out) - } - if !strings.Contains(out, "could not rotate trust to a new trusted root") { - c.Fatalf("Missing expected output on trusted create:\n%s", out) - } - + icmd.RunCmd(icmd.Command(dockerBinary, "create", repoName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "could not rotate trust to a new trusted root", + }) } func (s *DockerSuite) TestCreateStopSignal(c *check.C) { diff --git a/integration-cli/docker_cli_daemon_plugins_test.go b/integration-cli/docker_cli_daemon_plugins_test.go index 70ed4b68f8..8457382c58 100644 --- a/integration-cli/docker_cli_daemon_plugins_test.go +++ b/integration-cli/docker_cli_daemon_plugins_test.go @@ -4,13 +4,13 @@ package main import ( "os" - "os/exec" "path/filepath" "strings" "syscall" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/mount" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -92,10 +92,7 @@ func (s *DockerDaemonSuite) TestDaemonKillLiveRestoreWithPlugins(c *check.C) { c.Fatalf("Could not kill daemon: %v", err) } - cmd := exec.Command("pgrep", "-f", pluginProcessName) - if out, ec, err := runCommandWithOutput(cmd); ec != 0 { - c.Fatalf("Expected exit code '0', got %d err: %v output: %s ", ec, err, out) - } + icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success) } // TestDaemonShutdownLiveRestoreWithPlugins SIGTERMs daemon started with --live-restore. @@ -121,10 +118,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) c.Fatalf("Could not kill daemon: %v", err) } - cmd := exec.Command("pgrep", "-f", pluginProcessName) - if out, ec, err := runCommandWithOutput(cmd); ec != 0 { - c.Fatalf("Expected exit code '0', got %d err: %v output: %s ", ec, err, out) - } + icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success) } // TestDaemonShutdownWithPlugins shuts down running plugins. @@ -156,15 +150,13 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) { } } - cmd := exec.Command("pgrep", "-f", pluginProcessName) - if out, ec, err := runCommandWithOutput(cmd); ec != 1 { - c.Fatalf("Expected exit code '1', got %d err: %v output: %s ", ec, err, out) - } + icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Expected{ + ExitCode: 1, + Error: "exit status 1", + }) s.d.Start(c, "--live-restore") - cmd = exec.Command("pgrep", "-f", pluginProcessName) - out, _, err := runCommandWithOutput(cmd) - c.Assert(err, checker.IsNil, check.Commentf(out)) + icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success) } // TestVolumePlugin tests volume creation using a plugin. diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index cecbb4fcb1..a2b2d8f28b 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -262,30 +262,15 @@ func (s *DockerDaemonSuite) TestDaemonIptablesClean(c *check.C) { c.Fatalf("Could not run top: %s, %v", out, err) } - // get output from iptables with container running ipTablesSearchString := "tcp dpt:80" - ipTablesCmd := exec.Command("iptables", "-nvL") - out, _, err := runCommandWithOutput(ipTablesCmd) - if err != nil { - c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) - } - if !strings.Contains(out, ipTablesSearchString) { - c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) - } + // get output from iptables with container running + verifyIPTablesContains(c, ipTablesSearchString) s.d.Stop(c) // get output from iptables after restart - ipTablesCmd = exec.Command("iptables", "-nvL") - out, _, err = runCommandWithOutput(ipTablesCmd) - if err != nil { - c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) - } - - if strings.Contains(out, ipTablesSearchString) { - c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out) - } + verifyIPTablesDoesNotContains(c, ipTablesSearchString) } func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) { @@ -297,36 +282,36 @@ func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) { // get output from iptables with container running ipTablesSearchString := "tcp dpt:80" - ipTablesCmd := exec.Command("iptables", "-nvL") - out, _, err := runCommandWithOutput(ipTablesCmd) - if err != nil { - c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) - } - - if !strings.Contains(out, ipTablesSearchString) { - c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) - } + verifyIPTablesContains(c, ipTablesSearchString) s.d.Restart(c) // make sure the container is not running runningOut, err := s.d.Cmd("inspect", "--format={{.State.Running}}", "top") if err != nil { - c.Fatalf("Could not inspect on container: %s, %v", out, err) + c.Fatalf("Could not inspect on container: %s, %v", runningOut, err) } if strings.TrimSpace(runningOut) != "true" { c.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut)) } // get output from iptables after restart - ipTablesCmd = exec.Command("iptables", "-nvL") - out, _, err = runCommandWithOutput(ipTablesCmd) - if err != nil { - c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) - } + verifyIPTablesContains(c, ipTablesSearchString) +} - if !strings.Contains(out, ipTablesSearchString) { - c.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out) +func verifyIPTablesContains(c *check.C, ipTablesSearchString string) { + result := icmd.RunCommand("iptables", "-nvL") + result.Assert(c, icmd.Success) + if !strings.Contains(result.Combined(), ipTablesSearchString) { + c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, result.Combined()) + } +} + +func verifyIPTablesDoesNotContains(c *check.C, ipTablesSearchString string) { + result := icmd.RunCommand("iptables", "-nvL") + result.Assert(c, icmd.Success) + if strings.Contains(result.Combined(), ipTablesSearchString) { + c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, result.Combined()) } } @@ -564,10 +549,7 @@ func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) { c.Fatalf("Expected daemon not to start, got %v", err) } // look in the log and make sure we got the message that daemon is shutting down - runCmd := exec.Command("grep", "Error starting daemon", s.d.LogFileName()) - if out, _, err := runCommandWithOutput(runCmd); err != nil { - c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err) - } + icmd.RunCommand("grep", "Error starting daemon", s.d.LogFileName()).Assert(c, icmd.Success) } else { //if we didn't get an error and the daemon is running, this is a failure c.Fatal("Conflicting options should cause the daemon to error out with a failure") @@ -584,20 +566,15 @@ func (s *DockerDaemonSuite) TestDaemonBridgeExternal(c *check.C) { bridgeIP := "192.169.1.1/24" _, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) d.StartWithBusybox(c, "--bridge", bridgeName) ipTablesSearchString := bridgeIPNet.String() - ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") - out, _, err = runCommandWithOutput(ipTablesCmd) - c.Assert(err, check.IsNil) - - c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true, - check.Commentf("iptables output should have contained %q, but was %q", - ipTablesSearchString, out)) + icmd.RunCommand("iptables", "-t", "nat", "-nvL").Assert(c, icmd.Expected{ + Out: ipTablesSearchString, + }) _, err = d.Cmd("run", "-d", "--name", "ExtContainer", "busybox", "top") c.Assert(err, check.IsNil) @@ -617,41 +594,27 @@ func (s *DockerDaemonSuite) TestDaemonBridgeNone(c *check.C) { defer d.Restart(c) // verify docker0 iface is not there - out, _, err := runCommandWithOutput(exec.Command("ifconfig", "docker0")) - c.Assert(err, check.NotNil, check.Commentf("docker0 should not be present if daemon started with --bridge=none")) - c.Assert(strings.Contains(out, "Device not found"), check.Equals, true) + icmd.RunCommand("ifconfig", "docker0").Assert(c, icmd.Expected{ + ExitCode: 1, + Error: "exit status 1", + Err: "Device not found", + }) // verify default "bridge" network is not there - out, err = d.Cmd("network", "inspect", "bridge") + out, err := d.Cmd("network", "inspect", "bridge") c.Assert(err, check.NotNil, check.Commentf("\"bridge\" network should not be present if daemon started with --bridge=none")) c.Assert(strings.Contains(out, "No such network"), check.Equals, true) } -func createInterface(c *check.C, ifType string, ifName string, ipNet string) (string, error) { - args := []string{"link", "add", "name", ifName, "type", ifType} - ipLinkCmd := exec.Command("ip", args...) - out, _, err := runCommandWithOutput(ipLinkCmd) - if err != nil { - return out, err - } - - ifCfgCmd := exec.Command("ifconfig", ifName, ipNet, "up") - out, _, err = runCommandWithOutput(ifCfgCmd) - return out, err +func createInterface(c *check.C, ifType string, ifName string, ipNet string) { + icmd.RunCommand("ip", "link", "add", "name", ifName, "type", ifType).Assert(c, icmd.Success) + icmd.RunCommand("ifconfig", ifName, ipNet, "up").Assert(c, icmd.Success) } func deleteInterface(c *check.C, ifName string) { - ifCmd := exec.Command("ip", "link", "delete", ifName) - out, _, err := runCommandWithOutput(ifCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - - flushCmd := exec.Command("iptables", "-t", "nat", "--flush") - out, _, err = runCommandWithOutput(flushCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - - flushCmd = exec.Command("iptables", "--flush") - out, _, err = runCommandWithOutput(flushCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) + icmd.RunCommand("ip", "link", "delete", ifName).Assert(c, icmd.Success) + icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(c, icmd.Success) + icmd.RunCommand("iptables", "--flush").Assert(c, icmd.Success) } func (s *DockerDaemonSuite) TestDaemonBridgeIP(c *check.C) { @@ -723,8 +686,7 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) { bridgeName := "external-bridge" bridgeIP := "192.169.1.1/24" - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) args := []string{"--bridge", bridgeName, "--fixed-cidr", "192.169.1.0/30"} @@ -747,14 +709,13 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr2(c *check.C) { bridgeName := "external-bridge" bridgeIP := "10.2.2.1/16" - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) d.StartWithBusybox(c, "--bip", bridgeIP, "--fixed-cidr", "10.2.2.0/24") defer s.d.Restart(c) - out, err = d.Cmd("run", "-d", "--name", "bb", "busybox", "top") + out, err := d.Cmd("run", "-d", "--name", "bb", "busybox", "top") c.Assert(err, checker.IsNil, check.Commentf(out)) defer d.Cmd("stop", "bb") @@ -772,14 +733,13 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCIDREqualBridgeNetwork(c *check bridgeName := "external-bridge" bridgeIP := "172.27.42.1/16" - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) d.StartWithBusybox(c, "--bridge", bridgeName, "--fixed-cidr", bridgeIP) defer s.d.Restart(c) - out, err = d.Cmd("run", "-d", "busybox", "top") + out, err := d.Cmd("run", "-d", "busybox", "top") c.Assert(err, check.IsNil, check.Commentf(out)) cid1 := strings.TrimSpace(out) defer d.Cmd("stop", cid1) @@ -871,21 +831,18 @@ func (s *DockerDaemonSuite) TestDaemonIP(c *check.C) { c.Assert(strings.Contains(out, "Error starting userland proxy"), check.Equals, true) ifName := "dummy" - out, err = createInterface(c, "dummy", ifName, ipStr) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "dummy", ifName, ipStr) defer deleteInterface(c, ifName) _, err = d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top") c.Assert(err, check.IsNil) - ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") - out, _, err = runCommandWithOutput(ipTablesCmd) - c.Assert(err, check.IsNil) - + result := icmd.RunCommand("iptables", "-t", "nat", "-nvL") + result.Assert(c, icmd.Success) regex := fmt.Sprintf("DNAT.*%s.*dpt:8000", ip.String()) - matched, _ := regexp.MatchString(regex, out) + matched, _ := regexp.MatchString(regex, result.Combined()) c.Assert(matched, check.Equals, true, - check.Commentf("iptables output should have contained %q, but was %q", regex, out)) + check.Commentf("iptables output should have contained %q, but was %q", regex, result.Combined())) } func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) { @@ -895,22 +852,18 @@ func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) { bridgeName := "external-bridge" bridgeIP := "192.169.1.1/24" - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) - args := []string{"--bridge", bridgeName, "--icc=false"} - d.StartWithBusybox(c, args...) + d.StartWithBusybox(c, "--bridge", bridgeName, "--icc=false") defer d.Restart(c) - ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") - out, _, err = runCommandWithOutput(ipTablesCmd) - c.Assert(err, check.IsNil) - + result := icmd.RunCommand("iptables", "-nvL", "FORWARD") + result.Assert(c, icmd.Success) regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) - matched, _ := regexp.MatchString(regex, out) + matched, _ := regexp.MatchString(regex, result.Combined()) c.Assert(matched, check.Equals, true, - check.Commentf("iptables output should have contained %q, but was %q", regex, out)) + check.Commentf("iptables output should have contained %q, but was %q", regex, result.Combined())) // Pinging another container must fail with --icc=false pingContainers(c, d, true) @@ -924,7 +877,7 @@ func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) { // But, Pinging external or a Host interface must succeed pingCmd := fmt.Sprintf("ping -c 1 %s -W 1", ip.String()) runArgs := []string{"run", "--rm", "busybox", "sh", "-c", pingCmd} - _, err = d.Cmd(runArgs...) + _, err := d.Cmd(runArgs...) c.Assert(err, check.IsNil) } @@ -934,24 +887,20 @@ func (s *DockerDaemonSuite) TestDaemonICCLinkExpose(c *check.C) { bridgeName := "external-bridge" bridgeIP := "192.169.1.1/24" - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) - args := []string{"--bridge", bridgeName, "--icc=false"} - d.StartWithBusybox(c, args...) + d.StartWithBusybox(c, "--bridge", bridgeName, "--icc=false") defer d.Restart(c) - ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") - out, _, err = runCommandWithOutput(ipTablesCmd) - c.Assert(err, check.IsNil) - + result := icmd.RunCommand("iptables", "-nvL", "FORWARD") + result.Assert(c, icmd.Success) regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) - matched, _ := regexp.MatchString(regex, out) + matched, _ := regexp.MatchString(regex, result.Combined()) c.Assert(matched, check.Equals, true, - check.Commentf("iptables output should have contained %q, but was %q", regex, out)) + check.Commentf("iptables output should have contained %q, but was %q", regex, result.Combined())) - out, err = d.Cmd("run", "-d", "--expose", "4567", "--name", "icc1", "busybox", "nc", "-l", "-p", "4567") + out, err := d.Cmd("run", "-d", "--expose", "4567", "--name", "icc1", "busybox", "nc", "-l", "-p", "4567") c.Assert(err, check.IsNil, check.Commentf(out)) out, err = d.Cmd("run", "--link", "icc1:icc1", "busybox", "nc", "icc1", "4567") @@ -962,14 +911,13 @@ func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *che bridgeName := "external-bridge" bridgeIP := "192.169.1.1/24" - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) s.d.StartWithBusybox(c, "--bridge", bridgeName, "--icc=false") defer s.d.Restart(c) - _, err = s.d.Cmd("run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top") + _, err := s.d.Cmd("run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top") c.Assert(err, check.IsNil) _, err = s.d.Cmd("run", "-d", "--name", "parent", "--link", "child:http", "busybox", "top") c.Assert(err, check.IsNil) @@ -1464,10 +1412,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *chec c.Assert(strings.Contains(string(mountOut), id), check.Equals, true, comment) // kill the container - runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", id) - if out, ec, err := runCommandWithOutput(runCmd); err != nil { - c.Fatalf("Failed to run ctr, ExitCode: %d, err: %v output: %s id: %s\n", ec, err, out, id) - } + icmd.RunCommand(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", id).Assert(c, icmd.Success) // restart daemon. d.Restart(c) @@ -1564,10 +1509,9 @@ func (s *DockerDaemonSuite) TestDaemonRestartCleanupNetns(c *check.C) { } // Test if the file still exists - out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName)) - out = strings.TrimSpace(out) - c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) - c.Assert(out, check.Equals, fileName, check.Commentf("Output: %s", out)) + icmd.RunCommand("stat", "-c", "%n", fileName).Assert(c, icmd.Expected{ + Out: fileName, + }) // Remove the container and restart the daemon if out, err := s.d.Cmd("rm", "netns"); err != nil { @@ -1577,32 +1521,34 @@ func (s *DockerDaemonSuite) TestDaemonRestartCleanupNetns(c *check.C) { s.d.Restart(c) // Test again and see now the netns file does not exist - out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName)) - out = strings.TrimSpace(out) - c.Assert(err, check.Not(check.IsNil), check.Commentf("Output: %s", out)) + icmd.RunCommand("stat", "-c", "%n", fileName).Assert(c, icmd.Expected{ + Err: "No such file or directory", + ExitCode: 1, + }) } // tests regression detailed in #13964 where DOCKER_TLS_VERIFY env is ignored func (s *DockerDaemonSuite) TestDaemonTLSVerifyIssue13964(c *check.C) { host := "tcp://localhost:4271" s.d.Start(c, "-H", host) - cmd := exec.Command(dockerBinary, "-H", host, "info") - cmd.Env = []string{"DOCKER_TLS_VERIFY=1", "DOCKER_CERT_PATH=fixtures/https"} - out, _, err := runCommandWithOutput(cmd) - c.Assert(err, check.Not(check.IsNil), check.Commentf("%s", out)) - c.Assert(strings.Contains(out, "error during connect"), check.Equals, true) - + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "-H", host, "info"}, + Env: []string{"DOCKER_TLS_VERIFY=1", "DOCKER_CERT_PATH=fixtures/https"}, + }).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "error during connect", + }) } func setupV6(c *check.C) { // Hack to get the right IPv6 address on docker0, which has already been created result := icmd.RunCommand("ip", "addr", "add", "fe80::1/64", "dev", "docker0") - result.Assert(c, icmd.Expected{}) + result.Assert(c, icmd.Success) } func teardownV6(c *check.C) { result := icmd.RunCommand("ip", "addr", "del", "fe80::1/64", "dev", "docker0") - result.Assert(c, icmd.Expected{}) + result.Assert(c, icmd.Success) } func (s *DockerDaemonSuite) TestDaemonRestartWithContainerWithRestartPolicyAlways(c *check.C) { @@ -1708,10 +1654,7 @@ func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) { }) c.Assert(d.StartWithError("--log-driver=syslog", "--log-opt", "syslog-address=corrupted:42"), check.NotNil) expected := "Failed to set log opts: syslog-address should be in form proto://address" - runCmd := exec.Command("grep", expected, d.LogFileName()) - if out, _, err := runCommandWithOutput(runCmd); err != nil { - c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err) - } + icmd.RunCommand("grep", expected, d.LogFileName()).Assert(c, icmd.Success) } // FIXME(vdemeester) should be a unit test @@ -1721,10 +1664,7 @@ func (s *DockerDaemonSuite) TestDaemonCorruptedFluentdAddress(c *check.C) { }) c.Assert(d.StartWithError("--log-driver=fluentd", "--log-opt", "fluentd-address=corrupted:c"), check.NotNil) expected := "Failed to set log opts: invalid fluentd-address corrupted:c: " - runCmd := exec.Command("grep", expected, d.LogFileName()) - if out, _, err := runCommandWithOutput(runCmd); err != nil { - c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err) - } + icmd.RunCommand("grep", expected, d.LogFileName()).Assert(c, icmd.Success) } // FIXME(vdemeester) Use a new daemon instance instead of the Suite one @@ -1808,13 +1748,11 @@ func (s *DockerDaemonSuite) TestDaemonNoSpaceLeftOnDeviceError(c *check.C) { // create a 2MiB image and mount it as graph root // Why in a container? Because `mount` sometimes behaves weirdly and often fails outright on this test in debian:jessie (which is what the test suite runs under if run from the Makefile) dockerCmd(c, "run", "--rm", "-v", testDir+":/test", "busybox", "sh", "-c", "dd of=/test/testfs.img bs=1M seek=2 count=0") - out, _, err := runCommandWithOutput(exec.Command("mkfs.ext4", "-F", filepath.Join(testDir, "testfs.img"))) // `mkfs.ext4` is not in busybox - c.Assert(err, checker.IsNil, check.Commentf(out)) + icmd.RunCommand("mkfs.ext4", "-F", filepath.Join(testDir, "testfs.img")).Assert(c, icmd.Success) - cmd := exec.Command("losetup", "-f", "--show", filepath.Join(testDir, "testfs.img")) - loout, err := cmd.CombinedOutput() - c.Assert(err, checker.IsNil) - loopname := strings.TrimSpace(string(loout)) + result := icmd.RunCommand("losetup", "-f", "--show", filepath.Join(testDir, "testfs.img")) + result.Assert(c, icmd.Success) + loopname := strings.TrimSpace(string(result.Combined())) defer exec.Command("losetup", "-d", loopname).Run() dockerCmd(c, "run", "--privileged", "--rm", "-v", testDir+":/test:shared", "busybox", "sh", "-c", fmt.Sprintf("mkdir -p /test/test-mount && mount -t ext4 -no loop,rw %v /test/test-mount", loopname)) @@ -2007,10 +1945,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithKilledRunningContainer(t *check } // kill the container - runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", cid) - if out, ec, err := runCommandWithOutput(runCmd); err != nil { - t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid) - } + icmd.RunCommand(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", cid).Assert(t, icmd.Success) // Give time to containerd to process the command if we don't // the exit event might be received after we do the inspect diff --git a/integration-cli/docker_cli_export_import_test.go b/integration-cli/docker_cli_export_import_test.go index a065d9cf96..fe117b9ae0 100644 --- a/integration-cli/docker_cli_export_import_test.go +++ b/integration-cli/docker_cli_export_import_test.go @@ -2,10 +2,10 @@ package main import ( "os" - "os/exec" "strings" "github.com/docker/docker/integration-cli/checker" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -18,12 +18,13 @@ func (s *DockerSuite) TestExportContainerAndImportImage(c *check.C) { out, _ := dockerCmd(c, "export", containerID) - importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1") - importCmd.Stdin = strings.NewReader(out) - out, _, err := runCommandWithOutput(importCmd) - c.Assert(err, checker.IsNil, check.Commentf("failed to import image repo/testexp:v1: %s", out)) + result := icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "import", "-", "repo/testexp:v1"}, + Stdin: strings.NewReader(out), + }) + result.Assert(c, icmd.Success) - cleanedImageID := strings.TrimSpace(out) + cleanedImageID := strings.TrimSpace(result.Combined()) c.Assert(cleanedImageID, checker.Not(checker.Equals), "", check.Commentf("output should have been an image id")) } @@ -36,14 +37,15 @@ func (s *DockerSuite) TestExportContainerWithOutputAndImportImage(c *check.C) { dockerCmd(c, "export", "--output=testexp.tar", containerID) defer os.Remove("testexp.tar") - out, _, err := runCommandWithOutput(exec.Command("cat", "testexp.tar")) - c.Assert(err, checker.IsNil, check.Commentf(out)) + resultCat := icmd.RunCommand("cat", "testexp.tar") + resultCat.Assert(c, icmd.Success) - importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1") - importCmd.Stdin = strings.NewReader(out) - out, _, err = runCommandWithOutput(importCmd) - c.Assert(err, checker.IsNil, check.Commentf("failed to import image repo/testexp:v1: %s", out)) + result := icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "import", "-", "repo/testexp:v1"}, + Stdin: strings.NewReader(resultCat.Combined()), + }) + result.Assert(c, icmd.Success) - cleanedImageID := strings.TrimSpace(out) + cleanedImageID := strings.TrimSpace(result.Combined()) c.Assert(cleanedImageID, checker.Not(checker.Equals), "", check.Commentf("output should have been an image id")) } diff --git a/integration-cli/docker_cli_help_test.go b/integration-cli/docker_cli_help_test.go index 04d5446795..7c486858f6 100644 --- a/integration-cli/docker_cli_help_test.go +++ b/integration-cli/docker_cli_help_test.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "os/exec" "runtime" "strings" "unicode" @@ -14,6 +13,7 @@ import ( ) func (s *DockerSuite) TestHelpTextVerify(c *check.C) { + // FIXME(vdemeester) should be a unit test, probably using golden files ? testRequires(c, DaemonIsLinux) // Make sure main help text fits within 80 chars and that @@ -52,11 +52,12 @@ func (s *DockerSuite) TestHelpTextVerify(c *check.C) { scanForHome := runtime.GOOS != "windows" && home != "/" // Check main help text to make sure its not over 80 chars - helpCmd := exec.Command(dockerBinary, "help") - helpCmd.Env = newEnvs - out, _, err := runCommandWithOutput(helpCmd) - c.Assert(err, checker.IsNil, check.Commentf(out)) - lines := strings.Split(out, "\n") + result := icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "help"}, + Env: newEnvs, + }) + result.Assert(c, icmd.Success) + lines := strings.Split(result.Combined(), "\n") for _, line := range lines { // All lines should not end with a space c.Assert(line, checker.Not(checker.HasSuffix), " ", check.Commentf("Line should not end with a space")) @@ -75,16 +76,17 @@ func (s *DockerSuite) TestHelpTextVerify(c *check.C) { // Make sure each cmd's help text fits within 90 chars and that // on non-windows system we use ~ when possible (to shorten things). // Pull the list of commands from the "Commands:" section of docker help - helpCmd = exec.Command(dockerBinary, "help") - helpCmd.Env = newEnvs - out, _, err = runCommandWithOutput(helpCmd) - c.Assert(err, checker.IsNil, check.Commentf(out)) - i := strings.Index(out, "Commands:") - c.Assert(i, checker.GreaterOrEqualThan, 0, check.Commentf("Missing 'Commands:' in:\n%s", out)) + // FIXME(vdemeester) Why re-run help ? + //helpCmd = exec.Command(dockerBinary, "help") + //helpCmd.Env = newEnvs + //out, _, err = runCommandWithOutput(helpCmd) + //c.Assert(err, checker.IsNil, check.Commentf(out)) + i := strings.Index(result.Combined(), "Commands:") + c.Assert(i, checker.GreaterOrEqualThan, 0, check.Commentf("Missing 'Commands:' in:\n%s", result.Combined())) cmds := []string{} // Grab all chars starting at "Commands:" - helpOut := strings.Split(out[i:], "\n") + helpOut := strings.Split(result.Combined()[i:], "\n") // Skip first line, it is just "Commands:" helpOut = helpOut[1:] diff --git a/integration-cli/docker_cli_logs_test.go b/integration-cli/docker_cli_logs_test.go index beec083f0e..47fb1ebc51 100644 --- a/integration-cli/docker_cli_logs_test.go +++ b/integration-cli/docker_cli_logs_test.go @@ -11,6 +11,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/jsonlog" "github.com/docker/docker/pkg/testutil" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -188,14 +189,14 @@ func (s *DockerSuite) TestLogsSince(c *check.C) { // Test with default value specified and parameter omitted expected := []string{"log1", "log2", "log3"} - for _, cmd := range []*exec.Cmd{ - exec.Command(dockerBinary, "logs", "-t", name), - exec.Command(dockerBinary, "logs", "-t", "--since=0", name), + for _, cmd := range [][]string{ + {"logs", "-t", name}, + {"logs", "-t", "--since=0", name}, } { - out, _, err = runCommandWithOutput(cmd) - c.Assert(err, checker.IsNil, check.Commentf("failed to log container: %s", out)) + result := icmd.RunCommand(dockerBinary, cmd...) + result.Assert(c, icmd.Success) for _, v := range expected { - c.Assert(out, checker.Contains, v) + c.Assert(result.Combined(), checker.Contains, v) } } } diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go index bcd19b1c1b..a619f886aa 100644 --- a/integration-cli/docker_cli_network_unix_test.go +++ b/integration-cli/docker_cli_network_unix_test.go @@ -803,15 +803,14 @@ func (s *DockerDaemonSuite) TestDockerNetworkNoDiscoveryDefaultBridgeNetwork(c * hostsFile := "/etc/hosts" bridgeName := "external-bridge" bridgeIP := "192.169.255.254/24" - out, err := createInterface(c, "bridge", bridgeName, bridgeIP) - c.Assert(err, check.IsNil, check.Commentf(out)) + createInterface(c, "bridge", bridgeName, bridgeIP) defer deleteInterface(c, bridgeName) s.d.StartWithBusybox(c, "--bridge", bridgeName) defer s.d.Restart(c) // run two containers and store first container's etc/hosts content - out, err = s.d.Cmd("run", "-d", "busybox", "top") + out, err := s.d.Cmd("run", "-d", "busybox", "top") c.Assert(err, check.IsNil) cid1 := strings.TrimSpace(out) defer s.d.Cmd("stop", cid1) diff --git a/integration-cli/docker_cli_plugins_test.go b/integration-cli/docker_cli_plugins_test.go index 74237065e5..7b402ad175 100644 --- a/integration-cli/docker_cli_plugins_test.go +++ b/integration-cli/docker_cli_plugins_test.go @@ -2,15 +2,14 @@ package main import ( "fmt" - "os/exec" - - "github.com/docker/docker/integration-cli/checker" - "github.com/go-check/check" - "io/ioutil" "os" "path/filepath" "strings" + + "github.com/docker/docker/integration-cli/checker" + icmd "github.com/docker/docker/pkg/testutil/cmd" + "github.com/go-check/check" ) var ( @@ -305,15 +304,11 @@ func (s *DockerTrustSuite) TestPluginTrustedInstall(c *check.C) { trustedName := s.setupTrustedplugin(c, pNameWithTag, "trusted-plugin-install") - installCmd := exec.Command(dockerBinary, "plugin", "install", "--grant-all-permissions", trustedName) - s.trustedCmd(installCmd) - out, _, err := runCommandWithOutput(installCmd) + icmd.RunCmd(icmd.Command(dockerBinary, "plugin", "install", "--grant-all-permissions", trustedName), trustedCmd).Assert(c, icmd.Expected{ + Out: trustedName, + }) - c.Assert(strings.TrimSpace(out), checker.Contains, trustedName) - c.Assert(err, checker.IsNil) - c.Assert(strings.TrimSpace(out), checker.Contains, trustedName) - - out, _, err = dockerCmdWithError("plugin", "ls") + out, _, err := dockerCmdWithError("plugin", "ls") c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "true") @@ -330,11 +325,7 @@ func (s *DockerTrustSuite) TestPluginTrustedInstall(c *check.C) { c.Assert(strings.TrimSpace(out), checker.Contains, trustedName) // Try untrusted pull to ensure we pushed the tag to the registry - installCmd = exec.Command(dockerBinary, "plugin", "install", "--disable-content-trust=true", "--grant-all-permissions", trustedName) - s.trustedCmd(installCmd) - out, _, err = runCommandWithOutput(installCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "plugin", "install", "--disable-content-trust=true", "--grant-all-permissions", trustedName), trustedCmd).Assert(c, SuccessDownloaded) out, _, err = dockerCmdWithError("plugin", "ls") c.Assert(err, checker.IsNil) @@ -352,12 +343,10 @@ func (s *DockerTrustSuite) TestPluginUntrustedInstall(c *check.C) { dockerCmd(c, "plugin", "rm", "-f", pluginName) // Try trusted install on untrusted plugin - installCmd := exec.Command(dockerBinary, "plugin", "install", "--grant-all-permissions", pluginName) - s.trustedCmd(installCmd) - out, _, err := runCommandWithOutput(installCmd) - - c.Assert(err, check.NotNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Error: remote trust data does not exist", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "plugin", "install", "--grant-all-permissions", pluginName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Error: remote trust data does not exist", + }) } func (s *DockerSuite) TestPluginIDPrefix(c *check.C) { diff --git a/integration-cli/docker_cli_proxy_test.go b/integration-cli/docker_cli_proxy_test.go index 6cd94aaab7..3344985a0a 100644 --- a/integration-cli/docker_cli_proxy_test.go +++ b/integration-cli/docker_cli_proxy_test.go @@ -2,23 +2,20 @@ package main import ( "net" - "os/exec" "strings" "github.com/docker/docker/integration-cli/checker" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) func (s *DockerSuite) TestCLIProxyDisableProxyUnixSock(c *check.C) { - testRequires(c, DaemonIsLinux) - testRequires(c, SameHostDaemon) // test is valid when DOCKER_HOST=unix://.. - - cmd := exec.Command(dockerBinary, "info") - cmd.Env = appendBaseEnv(false, "HTTP_PROXY=http://127.0.0.1:9999") - - out, _, err := runCommandWithOutput(cmd) - c.Assert(err, checker.IsNil, check.Commentf("%v", out)) + testRequires(c, DaemonIsLinux, SameHostDaemon) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "info"}, + Env: appendBaseEnv(false, "HTTP_PROXY=http://127.0.0.1:9999"), + }).Assert(c, icmd.Success) } // Can't use localhost here since go has a special case to not use proxy if connecting to localhost @@ -41,12 +38,14 @@ func (s *DockerDaemonSuite) TestCLIProxyProxyTCPSock(c *check.C) { c.Assert(ip, checker.Not(checker.Equals), "") s.d.Start(c, "-H", "tcp://"+ip+":2375") - cmd := exec.Command(dockerBinary, "info") - cmd.Env = []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999"} - out, _, err := runCommandWithOutput(cmd) - c.Assert(err, checker.NotNil, check.Commentf("%v", out)) + + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "info"}, + Env: []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999"}, + }).Assert(c, icmd.Expected{Error: "exit status 1", ExitCode: 1}) // Test with no_proxy - cmd.Env = append(cmd.Env, "NO_PROXY="+ip) - out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "info")) - c.Assert(err, checker.IsNil, check.Commentf("%v", out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "info"}, + Env: []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999", "NO_PROXY=" + ip}, + }).Assert(c, icmd.Success) } diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index 4baff63df7..b8920dd509 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -669,22 +669,19 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) { originalImageName := "busybox:TestPsImageIDAfterUpdate-original" updatedImageName := "busybox:TestPsImageIDAfterUpdate-updated" - runCmd := exec.Command(dockerBinary, "tag", "busybox:latest", originalImageName) - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.IsNil) + icmd.RunCommand(dockerBinary, "tag", "busybox:latest", originalImageName).Assert(c, icmd.Success) originalImageID, err := getIDByName(originalImageName) c.Assert(err, checker.IsNil) - runCmd = exec.Command(dockerBinary, append([]string{"run", "-d", originalImageName}, sleepCommandForDaemonPlatform()...)...) - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.IsNil) - containerID := strings.TrimSpace(out) + result := icmd.RunCommand(dockerBinary, append([]string{"run", "-d", originalImageName}, sleepCommandForDaemonPlatform()...)...) + result.Assert(c, icmd.Success) + containerID := strings.TrimSpace(result.Combined()) - linesOut, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput() - c.Assert(err, checker.IsNil) + result = icmd.RunCommand(dockerBinary, "ps", "--no-trunc") + result.Assert(c, icmd.Success) - lines := strings.Split(strings.TrimSpace(string(linesOut)), "\n") + lines := strings.Split(strings.TrimSpace(string(result.Combined())), "\n") // skip header lines = lines[1:] c.Assert(len(lines), checker.Equals, 1) @@ -694,18 +691,13 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) { c.Assert(f[1], checker.Equals, originalImageName) } - runCmd = exec.Command(dockerBinary, "commit", containerID, updatedImageName) - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.IsNil) + icmd.RunCommand(dockerBinary, "commit", containerID, updatedImageName).Assert(c, icmd.Success) + icmd.RunCommand(dockerBinary, "tag", updatedImageName, originalImageName).Assert(c, icmd.Success) - runCmd = exec.Command(dockerBinary, "tag", updatedImageName, originalImageName) - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.IsNil) + result = icmd.RunCommand(dockerBinary, "ps", "--no-trunc") + result.Assert(c, icmd.Success) - linesOut, err = exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput() - c.Assert(err, checker.IsNil) - - lines = strings.Split(strings.TrimSpace(string(linesOut)), "\n") + lines = strings.Split(strings.TrimSpace(string(result.Combined())), "\n") // skip header lines = lines[1:] c.Assert(len(lines), checker.Equals, 1) diff --git a/integration-cli/docker_cli_pull_local_test.go b/integration-cli/docker_cli_pull_local_test.go index c39566a587..c504f543f3 100644 --- a/integration-cli/docker_cli_pull_local_test.go +++ b/integration-cli/docker_cli_pull_local_test.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "os" - "os/exec" "path/filepath" "runtime" "strings" @@ -15,6 +14,7 @@ import ( "github.com/docker/distribution/manifest/manifestlist" "github.com/docker/distribution/manifest/schema2" "github.com/docker/docker/integration-cli/checker" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" "github.com/opencontainers/go-digest" ) @@ -87,8 +87,8 @@ func testConcurrentPullWholeRepo(c *check.C) { for i := 0; i != numPulls; i++ { go func() { - _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", "-a", repoName)) - results <- err + result := icmd.RunCommand(dockerBinary, "pull", "-a", repoName) + results <- result.Error }() } @@ -125,8 +125,8 @@ func testConcurrentFailingPull(c *check.C) { for i := 0; i != numPulls; i++ { go func() { - _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repoName+":asdfasdf")) - results <- err + result := icmd.RunCommand(dockerBinary, "pull", repoName+":asdfasdf") + results <- result.Error }() } @@ -175,8 +175,8 @@ func testConcurrentPullMultipleTags(c *check.C) { for _, repo := range repos { go func(repo string) { - _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repo)) - results <- err + result := icmd.RunCommand(dockerBinary, "pull", repo) + results <- result.Error }(repo) } diff --git a/integration-cli/docker_cli_pull_trusted_test.go b/integration-cli/docker_cli_pull_trusted_test.go index 59ccfd0d2e..b068bb23f3 100644 --- a/integration-cli/docker_cli_pull_trusted_test.go +++ b/integration-cli/docker_cli_pull_trusted_test.go @@ -3,12 +3,11 @@ package main import ( "fmt" "io/ioutil" - "os/exec" - "strings" "time" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/testutil" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -16,33 +15,18 @@ func (s *DockerTrustSuite) TestTrustedPull(c *check.C) { repoName := s.setupTrustedImage(c, "trusted-pull") // Try pull - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err := runCommandWithOutput(pullCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) // Try untrusted pull to ensure we pushed the tag to the registry - pullCmd = exec.Command(dockerBinary, "pull", "--disable-content-trust=true", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out)) - + icmd.RunCmd(icmd.Command(dockerBinary, "pull", "--disable-content-trust=true", repoName), trustedCmd).Assert(c, SuccessDownloaded) } func (s *DockerTrustSuite) TestTrustedIsolatedPull(c *check.C) { repoName := s.setupTrustedImage(c, "trusted-isolated-pull") // Try pull (run from isolated directory without trust information) - pullCmd := exec.Command(dockerBinary, "--config", "/tmp/docker-isolated", "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err := runCommandWithOutput(pullCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(string(out))) + icmd.RunCmd(icmd.Command(dockerBinary, "--config", "/tmp/docker-isolated", "pull", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) } @@ -55,12 +39,10 @@ func (s *DockerTrustSuite) TestUntrustedPull(c *check.C) { dockerCmd(c, "rmi", repoName) // Try trusted pull on untrusted tag - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err := runCommandWithOutput(pullCmd) - - c.Assert(err, check.NotNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Error: remote trust data does not exist", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Error: remote trust data does not exist", + }) } func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) { @@ -72,22 +54,19 @@ func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) { testutil.RunAtDifferentDate(elevenYearsFromNow, func() { // Try pull - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err := runCommandWithOutput(pullCmd) - - c.Assert(err, check.NotNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "could not validate the path to a trusted root", check.Commentf(out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "pull", repoName}, + }, trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "could not validate the path to a trusted root", + }) }) testutil.RunAtDifferentDate(elevenYearsFromNow, func() { // Try pull - pullCmd := exec.Command(dockerBinary, "pull", "--disable-content-trust", repoName) - s.trustedCmd(pullCmd) - out, _, err := runCommandWithOutput(pullCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "pull", "--disable-content-trust", repoName}, + }, trustedCmd).Assert(c, SuccessDownloaded) }) } @@ -101,21 +80,11 @@ func (s *DockerTrustSuite) TestTrustedPullFromBadTrustServer(c *check.C) { // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) dockerCmd(c, "rmi", repoName) // Try pull - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) // Kill the notary server, start a new "evil" one. @@ -129,23 +98,13 @@ func (s *DockerTrustSuite) TestTrustedPullFromBadTrustServer(c *check.C) { dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName) // Push up to the new server - pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err = runCommandWithOutput(pushCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Now, try pulling with the original client from this new trust server. This should fail because the new root is invalid. - pullCmd = exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - if err == nil { - c.Fatalf("Continuing with cached data even though it's an invalid root rotation: %s\n%s", err, out) - } - if !strings.Contains(out, "could not rotate trust to a new trusted root") { - c.Fatalf("Missing expected output on trusted pull:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "could not rotate trust to a new trusted root", + }) } func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) { @@ -155,13 +114,7 @@ func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) { dockerCmd(c, "tag", "busybox", repoName) // Push with default passphrases - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf(out)) - + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) dockerCmd(c, "rmi", repoName) // Snapshots last for three years. This should be expired @@ -169,41 +122,28 @@ func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) { testutil.RunAtDifferentDate(fourYearsLater, func() { // Try pull - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - - c.Assert(err, check.NotNil, check.Commentf("Missing expected error running trusted pull with expired snapshots")) - c.Assert(string(out), checker.Contains, "repository out-of-date", check.Commentf(out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "pull", repoName}, + }, trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "repository out-of-date", + }) }) } func (s *DockerTrustSuite) TestTrustedOfflinePull(c *check.C) { repoName := s.setupTrustedImage(c, "trusted-offline-pull") - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver") - out, _, err := runCommandWithOutput(pullCmd) - - c.Assert(err, check.NotNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "error contacting notary server", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmdWithServer("https://invalidnotaryserver")).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "error contacting notary server", + }) // Do valid trusted pull to warm cache - pullCmd = exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out)) - + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) // Try pull again with invalid notary server, should use cache - pullCmd = exec.Command(dockerBinary, "pull", repoName) - s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver") - out, _, err = runCommandWithOutput(pullCmd) - - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmdWithServer("https://invalidnotaryserver")).Assert(c, SuccessTagging) } func (s *DockerTrustSuite) TestTrustedPullDelete(c *check.C) { @@ -214,29 +154,16 @@ func (s *DockerTrustSuite) TestTrustedPullDelete(c *check.C) { CMD echo trustedpulldelete `, true) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - if err != nil { - c.Fatalf("Error running trusted push: %s\n%s", err, out) - } - if !strings.Contains(string(out), "Signing and pushing trust metadata") { - c.Fatalf("Missing expected output on trusted push:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) - if out, status := dockerCmd(c, "rmi", repoName); status != 0 { - c.Fatalf("Error removing image %q\n%s", repoName, out) - } + dockerCmd(c, "rmi", repoName) // Try pull - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) + result := icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd) + result.Assert(c, icmd.Success) - c.Assert(err, check.IsNil, check.Commentf(out)) - - matches := digestRegex.FindStringSubmatch(out) - c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", out)) + matches := digestRegex.FindStringSubmatch(result.Combined()) + c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", result.Combined())) pullDigest := matches[1] imageID := inspectField(c, repoName, "Id") @@ -263,18 +190,13 @@ func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) { // Push with targets first, initializing the repo dockerCmd(c, "tag", "busybox", targetName) - pushCmd := exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, icmd.Success) s.assertTargetInRoles(c, repoName, "latest", "targets") // Try pull, check we retrieve from targets role - pullCmd := exec.Command(dockerBinary, "-D", "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "retrieving target for targets role") + icmd.RunCmd(icmd.Command(dockerBinary, "-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + Err: "retrieving target for targets role", + }) // Now we'll create the releases role, and try pushing and pulling s.notaryCreateDelegation(c, repoName, "targets/releases", s.not.keys[0].Public) @@ -283,31 +205,23 @@ func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) { // try a pull, check that we can still pull because we can still read the // old tag in the targets role - pullCmd = exec.Command(dockerBinary, "-D", "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "retrieving target for targets role") + icmd.RunCmd(icmd.Command(dockerBinary, "-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + Err: "retrieving target for targets role", + }) // try a pull -a, check that it succeeds because we can still pull from the // targets role - pullCmd = exec.Command(dockerBinary, "-D", "pull", "-a", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "-D", "pull", "-a", repoName), trustedCmd).Assert(c, icmd.Success) // Push, should sign with targets/releases dockerCmd(c, "tag", "busybox", targetName) - pushCmd = exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err = runCommandWithOutput(pushCmd) + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, icmd.Success) s.assertTargetInRoles(c, repoName, "latest", "targets", "targets/releases") // Try pull, check we retrieve from targets/releases role - pullCmd = exec.Command(dockerBinary, "-D", "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(out, checker.Contains, "retrieving target for targets/releases role") + icmd.RunCmd(icmd.Command(dockerBinary, "-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + Err: "retrieving target for targets/releases role", + }) // Create another delegation that we'll sign with s.notaryCreateDelegation(c, repoName, "targets/other", s.not.keys[1].Public) @@ -315,16 +229,13 @@ func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) { s.notaryPublish(c, repoName) dockerCmd(c, "tag", "busybox", targetName) - pushCmd = exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err = runCommandWithOutput(pushCmd) + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, icmd.Success) s.assertTargetInRoles(c, repoName, "latest", "targets", "targets/releases", "targets/other") // Try pull, check we retrieve from targets/releases role - pullCmd = exec.Command(dockerBinary, "-D", "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(out, checker.Contains, "retrieving target for targets/releases role") + icmd.RunCmd(icmd.Command(dockerBinary, "-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + Err: "retrieving target for targets/releases role", + }) } func (s *DockerTrustSuite) TestTrustedPullIgnoresOtherDelegationRoles(c *check.C) { @@ -341,26 +252,22 @@ func (s *DockerTrustSuite) TestTrustedPullIgnoresOtherDelegationRoles(c *check.C // Push should write to the delegation role, not targets dockerCmd(c, "tag", "busybox", targetName) - pushCmd := exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, icmd.Success) s.assertTargetInRoles(c, repoName, "latest", "targets/other") s.assertTargetNotInRoles(c, repoName, "latest", "targets") // Try pull - we should fail, since pull will only pull from the targets/releases // role or the targets role - pullCmd := exec.Command(dockerBinary, "-D", "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "No trust data for") + dockerCmd(c, "tag", "busybox", targetName) + icmd.RunCmd(icmd.Command(dockerBinary, "-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "No trust data for", + }) // try a pull -a: we should fail since pull will only pull from the targets/releases // role or the targets role - pullCmd = exec.Command(dockerBinary, "-D", "pull", "-a", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "No trusted tags for") + icmd.RunCmd(icmd.Command(dockerBinary, "-D", "pull", "-a", repoName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "No trusted tags for", + }) } diff --git a/integration-cli/docker_cli_push_test.go b/integration-cli/docker_cli_push_test.go index 9cbac83f08..aa1b0bd9c0 100644 --- a/integration-cli/docker_cli_push_test.go +++ b/integration-cli/docker_cli_push_test.go @@ -7,7 +7,6 @@ import ( "net/http" "net/http/httptest" "os" - "os/exec" "path/filepath" "strings" "sync" @@ -17,6 +16,7 @@ import ( cliconfig "github.com/docker/docker/cli/config" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/testutil" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -135,13 +135,13 @@ func testPushEmptyLayer(c *check.C) { c.Assert(err, check.IsNil, check.Commentf("Could not open test tarball")) defer freader.Close() - importCmd := exec.Command(dockerBinary, "import", "-", repoName) - importCmd.Stdin = freader - out, _, err := runCommandWithOutput(importCmd) - c.Assert(err, check.IsNil, check.Commentf("import failed: %q", out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "import", "-", repoName}, + Stdin: freader, + }).Assert(c, icmd.Success) // Now verify we can push it - out, _, err = dockerCmdWithError("push", repoName) + out, _, err := dockerCmdWithError("push", repoName) c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out)) } @@ -177,8 +177,8 @@ func testConcurrentPush(c *check.C) { for _, repo := range repos { go func(repo string) { - _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "push", repo)) - results <- err + result := icmd.RunCommand(dockerBinary, "push", repo) + results <- result.Error }(repo) } @@ -287,18 +287,12 @@ func (s *DockerTrustSuite) TestTrustedPush(c *check.C) { // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Try pull after push - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + Out: "Status: Image is up to date", + }) // Assert that we rotated the snapshot key to the server by checking our local keystore contents, err := ioutil.ReadDir(filepath.Join(cliconfig.Dir(), "trust/private/tuf_keys", privateRegistryURL, "dockerclitrusted/pushtest")) @@ -312,18 +306,12 @@ func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) { // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmdWithPassphrases(pushCmd, "12345678", "12345678") - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmdWithPassphrases("12345678", "12345678")).Assert(c, SuccessSigningAndPushing) // Try pull after push - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + Out: "Status: Image is up to date", + }) } func (s *DockerTrustSuite) TestTrustedPushWithFailingServer(c *check.C) { @@ -331,12 +319,11 @@ func (s *DockerTrustSuite) TestTrustedPushWithFailingServer(c *check.C) { // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) // Using a name that doesn't resolve to an address makes this test faster - s.trustedCmdWithServer(pushCmd, "https://server.invalid:81/") - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.NotNil, check.Commentf("Missing error while running trusted push w/ no server")) - c.Assert(out, checker.Contains, "error contacting notary server", check.Commentf("Missing expected output on trusted push")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmdWithServer("https://server.invalid:81/")).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "error contacting notary server", + }) } func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C) { @@ -344,12 +331,9 @@ func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C) // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", "--disable-content-trust", repoName) - // Using a name that doesn't resolve to an address makes this test faster - s.trustedCmdWithServer(pushCmd, "https://server.invalid") - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push with no server and --disable-content-trust failed: %s\n%s", err, out)) - c.Assert(out, check.Not(checker.Contains), "Error establishing connection to notary repository", check.Commentf("Missing expected output on trusted push with --disable-content-trust:")) + result := icmd.RunCmd(icmd.Command(dockerBinary, "push", "--disable-content-trust", repoName), trustedCmdWithServer("https://server.invalid:81/")) + result.Assert(c, icmd.Success) + c.Assert(result.Combined(), check.Not(checker.Contains), "Error establishing connection to notary repository", check.Commentf("Missing expected output on trusted push with --disable-content-trust:")) } func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) { @@ -358,18 +342,12 @@ func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) { dockerCmd(c, "tag", "busybox", repoName) dockerCmd(c, "push", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Try pull after push - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, icmd.Expected{ + Out: "Status: Image is up to date", + }) } func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) { @@ -378,28 +356,14 @@ func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) { dockerCmd(c, "tag", "busybox", repoName) // Do a trusted push - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Do another trusted push - pushCmd = exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err = runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) - + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) dockerCmd(c, "rmi", repoName) // Try pull to ensure the double push did not break our ability to pull - pullCmd := exec.Command(dockerBinary, "pull", repoName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf("Error running trusted pull: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Status: Downloaded", check.Commentf("Missing expected output on trusted pull with --disable-content-trust")) - + icmd.RunCmd(icmd.Command(dockerBinary, "pull", repoName), trustedCmd).Assert(c, SuccessDownloaded) } func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *check.C) { @@ -408,18 +372,13 @@ func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *c dockerCmd(c, "tag", "busybox", repoName) // Push with default passphrases - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push:\n%s", out)) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Push with wrong passphrases - pushCmd = exec.Command(dockerBinary, "push", repoName) - s.trustedCmdWithPassphrases(pushCmd, "12345678", "87654321") - out, _, err = runCommandWithOutput(pushCmd) - c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with short targets passphrase: \n%s", out)) - c.Assert(out, checker.Contains, "could not find necessary signing keys", check.Commentf("Missing expected output on trusted push with short targets/snapsnot passphrase")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmdWithPassphrases("12345678", "87654321")).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "could not find necessary signing keys", + }) } func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) { @@ -429,22 +388,19 @@ func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) { dockerCmd(c, "tag", "busybox", repoName) // Push with default passphrases - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Snapshots last for three years. This should be expired fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4) testutil.RunAtDifferentDate(fourYearsLater, func() { // Push with wrong passphrases - pushCmd = exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err = runCommandWithOutput(pushCmd) - c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with expired snapshot: \n%s", out)) - c.Assert(out, checker.Contains, "repository out-of-date", check.Commentf("Missing expected output on trusted push with expired snapshot")) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "push", repoName}, + }, trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "repository out-of-date", + }) }) } @@ -455,22 +411,15 @@ func (s *DockerTrustSuite) TestTrustedPushWithExpiredTimestamp(c *check.C) { dockerCmd(c, "tag", "busybox", repoName) // Push with default passphrases - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // The timestamps expire in two weeks. Lets check three threeWeeksLater := time.Now().Add(time.Hour * 24 * 21) // Should succeed because the server transparently re-signs one testutil.RunAtDifferentDate(threeWeeksLater, func() { - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with expired timestamp")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), + trustedCmd).Assert(c, SuccessSigningAndPushing) }) } @@ -487,11 +436,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegationOnly(c *check.C) // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", targetName) - pushCmd := exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, SuccessSigningAndPushing) // check to make sure that the target has been added to targets/releases and not targets s.assertTargetInRoles(c, repoName, "latest", "targets/releases") s.assertTargetNotInRoles(c, repoName, "latest", "targets") @@ -499,11 +444,9 @@ func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegationOnly(c *check.C) // Try pull after push os.RemoveAll(filepath.Join(cliconfig.Dir(), "trust")) - pullCmd := exec.Command(dockerBinary, "pull", targetName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", targetName), trustedCmd).Assert(c, icmd.Expected{ + Out: "Status: Image is up to date", + }) } func (s *DockerTrustSuite) TestTrustedPushSignsAllFirstLevelRolesWeHaveKeysFor(c *check.C) { @@ -527,11 +470,7 @@ func (s *DockerTrustSuite) TestTrustedPushSignsAllFirstLevelRolesWeHaveKeysFor(c // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", targetName) - pushCmd := exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, SuccessSigningAndPushing) // check to make sure that the target has been added to targets/role1 and targets/role2, and // not targets (because there are delegations) or targets/role3 (due to missing key) or @@ -543,10 +482,9 @@ func (s *DockerTrustSuite) TestTrustedPushSignsAllFirstLevelRolesWeHaveKeysFor(c os.RemoveAll(filepath.Join(cliconfig.Dir(), "trust")) // pull should fail because none of these are the releases role - pullCmd := exec.Command(dockerBinary, "pull", targetName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.NotNil, check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", targetName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + }) } func (s *DockerTrustSuite) TestTrustedPushSignsForRolesWithKeysAndValidPaths(c *check.C) { @@ -568,11 +506,7 @@ func (s *DockerTrustSuite) TestTrustedPushSignsForRolesWithKeysAndValidPaths(c * // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", targetName) - pushCmd := exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) - c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, SuccessSigningAndPushing) // check to make sure that the target has been added to targets/role1 and targets/role4, and // not targets (because there are delegations) or targets/role2 (due to path restrictions) or @@ -584,10 +518,9 @@ func (s *DockerTrustSuite) TestTrustedPushSignsForRolesWithKeysAndValidPaths(c * os.RemoveAll(filepath.Join(cliconfig.Dir(), "trust")) // pull should fail because none of these are the releases role - pullCmd := exec.Command(dockerBinary, "pull", targetName) - s.trustedCmd(pullCmd) - out, _, err = runCommandWithOutput(pullCmd) - c.Assert(err, check.NotNil, check.Commentf(out)) + icmd.RunCmd(icmd.Command(dockerBinary, "pull", targetName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + }) } func (s *DockerTrustSuite) TestTrustedPushDoesntSignTargetsIfDelegationsExist(c *check.C) { @@ -603,13 +536,10 @@ func (s *DockerTrustSuite) TestTrustedPushDoesntSignTargetsIfDelegationsExist(c // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", targetName) - pushCmd := exec.Command(dockerBinary, "push", targetName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - c.Assert(err, check.NotNil, check.Commentf("trusted push succeeded but should have failed:\n%s", out)) - c.Assert(out, checker.Contains, "no valid signing keys", - check.Commentf("Missing expected output on trusted push without keys")) - + icmd.RunCmd(icmd.Command(dockerBinary, "push", targetName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "no valid signing keys", + }) s.assertTargetNotInRoles(c, repoName, "latest", "targets", "targets/role1") } diff --git a/integration-cli/docker_cli_rmi_test.go b/integration-cli/docker_cli_rmi_test.go index 4c0502ba9c..84ec6a8b00 100644 --- a/integration-cli/docker_cli_rmi_test.go +++ b/integration-cli/docker_cli_rmi_test.go @@ -2,12 +2,12 @@ package main import ( "fmt" - "os/exec" "strings" "time" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/pkg/stringid" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -175,12 +175,11 @@ func (s *DockerSuite) TestRmiTagWithExistingContainers(c *check.C) { func (s *DockerSuite) TestRmiForceWithExistingContainers(c *check.C) { image := "busybox-clone" - cmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", image, "-") - cmd.Stdin = strings.NewReader(`FROM busybox -MAINTAINER foo`) - - out, _, err := runCommandWithOutput(cmd) - c.Assert(err, checker.IsNil, check.Commentf("Could not build %s: %s", image, out)) + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "build", "--no-cache", "-t", image, "-"}, + Stdin: strings.NewReader(`FROM busybox +MAINTAINER foo`), + }).Assert(c, icmd.Success) dockerCmd(c, "run", "--name", "test-force-rmi", image, "/bin/true") diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index ed8ba4ba06..6f3d11b59e 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -819,21 +819,21 @@ func (s *DockerSuite) TestRunEnvironment(c *check.C) { // TODO Windows: Environment handling is different between Linux and // Windows and this test relies currently on unix functionality. testRequires(c, DaemonIsLinux) - cmd := exec.Command(dockerBinary, "run", "-h", "testing", "-e=FALSE=true", "-e=TRUE", "-e=TRICKY", "-e=HOME=", "busybox", "env") - cmd.Env = append(os.Environ(), - "TRUE=false", - "TRICKY=tri\ncky\n", - ) + result := icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "run", "-h", "testing", "-e=FALSE=true", "-e=TRUE", "-e=TRICKY", "-e=HOME=", "busybox", "env"}, + Env: append(os.Environ(), + "TRUE=false", + "TRICKY=tri\ncky\n", + ), + }) + result.Assert(c, icmd.Success) - out, _, err := runCommandWithOutput(cmd) - if err != nil { - c.Fatal(err, out) - } - - actualEnv := strings.Split(strings.TrimSpace(out), "\n") + actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n") sort.Strings(actualEnv) goodEnv := []string{ + // The first two should not be tested here, those are "inherent" environment variable. This test validates + // the -e behavior, not the default environment variable (that could be subject to change) "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "HOSTNAME=testing", "FALSE=true", @@ -863,15 +863,13 @@ func (s *DockerSuite) TestRunEnvironmentErase(c *check.C) { // not set in our local env that they're removed (if present) in // the container - cmd := exec.Command(dockerBinary, "run", "-e", "FOO", "-e", "HOSTNAME", "busybox", "env") - cmd.Env = appendBaseEnv(true) + result := icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "run", "-e", "FOO", "-e", "HOSTNAME", "busybox", "env"}, + Env: appendBaseEnv(true), + }) + result.Assert(c, icmd.Success) - out, _, err := runCommandWithOutput(cmd) - if err != nil { - c.Fatal(err, out) - } - - actualEnv := strings.Split(strings.TrimSpace(out), "\n") + actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n") sort.Strings(actualEnv) goodEnv := []string{ @@ -897,15 +895,13 @@ func (s *DockerSuite) TestRunEnvironmentOverride(c *check.C) { // Test to make sure that when we use -e on env vars that are // already in the env that we're overriding them - cmd := exec.Command(dockerBinary, "run", "-e", "HOSTNAME", "-e", "HOME=/root2", "busybox", "env") - cmd.Env = appendBaseEnv(true, "HOSTNAME=bar") + result := icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "run", "-e", "HOSTNAME", "-e", "HOME=/root2", "busybox", "env"}, + Env: appendBaseEnv(true, "HOSTNAME=bar"), + }) + result.Assert(c, icmd.Success) - out, _, err := runCommandWithOutput(cmd) - if err != nil { - c.Fatal(err, out) - } - - actualEnv := strings.Split(strings.TrimSpace(out), "\n") + actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n") sort.Strings(actualEnv) goodEnv := []string{ @@ -2111,12 +2107,9 @@ func (s *DockerSuite) TestRunDeallocatePortOnMissingIptablesRule(c *check.C) { id := strings.TrimSpace(out) ip := inspectField(c, id, "NetworkSettings.Networks.bridge.IPAddress") - iptCmd := exec.Command("iptables", "-D", "DOCKER", "-d", fmt.Sprintf("%s/32", ip), - "!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT") - out, _, err := runCommandWithOutput(iptCmd) - if err != nil { - c.Fatal(err, out) - } + icmd.RunCommand("iptables", "-D", "DOCKER", "-d", fmt.Sprintf("%s/32", ip), + "!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT").Assert(c, icmd.Success) + if err := deleteContainer(false, id); err != nil { c.Fatal(err) } @@ -3269,30 +3262,11 @@ func (s *DockerTrustSuite) TestTrustedRun(c *check.C) { repoName := s.setupTrustedImage(c, "trusted-run") // Try run - runCmd := exec.Command(dockerBinary, "run", repoName) - s.trustedCmd(runCmd) - out, _, err := runCommandWithOutput(runCmd) - if err != nil { - c.Fatalf("Error running trusted run: %s\n%s\n", err, out) - } - - if !strings.Contains(string(out), "Tagging") { - c.Fatalf("Missing expected output on trusted push:\n%s", out) - } - + icmd.RunCmd(icmd.Command(dockerBinary, "run", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) // Try untrusted run to ensure we pushed the tag to the registry - runCmd = exec.Command(dockerBinary, "run", "--disable-content-trust=true", repoName) - s.trustedCmd(runCmd) - out, _, err = runCommandWithOutput(runCmd) - if err != nil { - c.Fatalf("Error running trusted run: %s\n%s", err, out) - } - - if !strings.Contains(string(out), "Status: Downloaded") { - c.Fatalf("Missing expected output on trusted run with --disable-content-trust:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "run", "--disable-content-trust=true", repoName), trustedCmd).Assert(c, SuccessDownloadedOnStderr) } func (s *DockerTrustSuite) TestUntrustedRun(c *check.C) { @@ -3305,16 +3279,10 @@ func (s *DockerTrustSuite) TestUntrustedRun(c *check.C) { dockerCmd(c, "rmi", repoName) // Try trusted run on untrusted tag - runCmd := exec.Command(dockerBinary, "run", repoName) - s.trustedCmd(runCmd) - out, _, err := runCommandWithOutput(runCmd) - if err == nil { - c.Fatalf("Error expected when running trusted run with:\n%s", out) - } - - if !strings.Contains(string(out), "does not have trust data for") { - c.Fatalf("Missing expected output on trusted run:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "run", repoName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 125, + Err: "does not have trust data for", + }) } func (s *DockerTrustSuite) TestRunWhenCertExpired(c *check.C) { @@ -3328,30 +3296,19 @@ func (s *DockerTrustSuite) TestRunWhenCertExpired(c *check.C) { testutil.RunAtDifferentDate(elevenYearsFromNow, func() { // Try run - runCmd := exec.Command(dockerBinary, "run", repoName) - s.trustedCmd(runCmd) - out, _, err := runCommandWithOutput(runCmd) - if err == nil { - c.Fatalf("Error running trusted run in the distant future: %s\n%s", err, out) - } - - if !strings.Contains(string(out), "could not validate the path to a trusted root") { - c.Fatalf("Missing expected output on trusted run in the distant future:\n%s", out) - } + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "run", repoName}, + }, trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "could not validate the path to a trusted root", + }) }) testutil.RunAtDifferentDate(elevenYearsFromNow, func() { // Try run - runCmd := exec.Command(dockerBinary, "run", "--disable-content-trust", repoName) - s.trustedCmd(runCmd) - out, _, err := runCommandWithOutput(runCmd) - if err != nil { - c.Fatalf("Error running untrusted run in the distant future: %s\n%s", err, out) - } - - if !strings.Contains(string(out), "Status: Downloaded") { - c.Fatalf("Missing expected output on untrusted run in the distant future:\n%s", out) - } + icmd.RunCmd(icmd.Cmd{ + Command: []string{dockerBinary, "run", "--disable-content-trust", repoName}, + }, trustedCmd).Assert(c, SuccessDownloaded) }) } @@ -3367,30 +3324,11 @@ func (s *DockerTrustSuite) TestTrustedRunFromBadTrustServer(c *check.C) { // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - if err != nil { - c.Fatalf("Error running trusted push: %s\n%s", err, out) - } - if !strings.Contains(string(out), "Signing and pushing trust metadata") { - c.Fatalf("Missing expected output on trusted push:\n%s", out) - } - + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) dockerCmd(c, "rmi", repoName) // Try run - runCmd := exec.Command(dockerBinary, "run", repoName) - s.trustedCmd(runCmd) - out, _, err = runCommandWithOutput(runCmd) - if err != nil { - c.Fatalf("Error running trusted run: %s\n%s", err, out) - } - - if !strings.Contains(string(out), "Tagging") { - c.Fatalf("Missing expected output on trusted push:\n%s", out) - } - + icmd.RunCmd(icmd.Command(dockerBinary, "run", repoName), trustedCmd).Assert(c, SuccessTagging) dockerCmd(c, "rmi", repoName) // Kill the notary server, start a new "evil" one. @@ -3405,27 +3343,13 @@ func (s *DockerTrustSuite) TestTrustedRunFromBadTrustServer(c *check.C) { dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName) // Push up to the new server - pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err = runCommandWithOutput(pushCmd) - if err != nil { - c.Fatalf("Error running trusted push: %s\n%s", err, out) - } - if !strings.Contains(string(out), "Signing and pushing trust metadata") { - c.Fatalf("Missing expected output on trusted push:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) // Now, try running with the original client from this new trust server. This should fail because the new root is invalid. - runCmd = exec.Command(dockerBinary, "run", repoName) - s.trustedCmd(runCmd) - out, _, err = runCommandWithOutput(runCmd) - - if err == nil { - c.Fatalf("Continuing with cached data even though it's an invalid root rotation: %s\n%s", err, out) - } - if !strings.Contains(out, "could not rotate trust to a new trusted root") { - c.Fatalf("Missing expected output on trusted run:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "run", repoName), trustedCmd).Assert(c, icmd.Expected{ + ExitCode: 125, + Err: "could not rotate trust to a new trusted root", + }) } func (s *DockerSuite) TestPtraceContainerProcsFromHost(c *check.C) { @@ -4012,23 +3936,19 @@ func (s *DockerSuite) TestRunWrongCpusetMemsFlagValue(c *check.C) { // TestRunNonExecutableCmd checks that 'docker run busybox foo' exits with error code 127' func (s *DockerSuite) TestRunNonExecutableCmd(c *check.C) { name := "testNonExecutableCmd" - runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "foo") - _, exit, _ := runCommandWithOutput(runCmd) - stateExitCode := findContainerExitCode(c, name) - if !(exit == 127 && strings.Contains(stateExitCode, "127")) { - c.Fatalf("Run non-executable command should have errored with exit code 127, but we got exit: %d, State.ExitCode: %s", exit, stateExitCode) - } + icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "foo").Assert(c, icmd.Expected{ + ExitCode: 127, + Error: "exit status 127", + }) } // TestRunNonExistingCmd checks that 'docker run busybox /bin/foo' exits with code 127. func (s *DockerSuite) TestRunNonExistingCmd(c *check.C) { name := "testNonExistingCmd" - runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "/bin/foo") - _, exit, _ := runCommandWithOutput(runCmd) - stateExitCode := findContainerExitCode(c, name) - if !(exit == 127 && strings.Contains(stateExitCode, "127")) { - c.Fatalf("Run non-existing command should have errored with exit code 127, but we got exit: %d, State.ExitCode: %s", exit, stateExitCode) - } + icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "/bin/foo").Assert(c, icmd.Expected{ + ExitCode: 127, + Error: "exit status 127", + }) } // TestCmdCannotBeInvoked checks that 'docker run busybox /etc' exits with 126, or @@ -4040,30 +3960,28 @@ func (s *DockerSuite) TestCmdCannotBeInvoked(c *check.C) { expected = 127 } name := "testCmdCannotBeInvoked" - runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "/etc") - _, exit, _ := runCommandWithOutput(runCmd) - stateExitCode := findContainerExitCode(c, name) - if !(exit == expected && strings.Contains(stateExitCode, strconv.Itoa(expected))) { - c.Fatalf("Run cmd that cannot be invoked should have errored with code %d, but we got exit: %d, State.ExitCode: %s", expected, exit, stateExitCode) - } + icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "/etc").Assert(c, icmd.Expected{ + ExitCode: expected, + Error: fmt.Sprintf("exit status %d", expected), + }) } // TestRunNonExistingImage checks that 'docker run foo' exits with error msg 125 and contains 'Unable to find image' +// FIXME(vdemeester) should be a unit test func (s *DockerSuite) TestRunNonExistingImage(c *check.C) { - runCmd := exec.Command(dockerBinary, "run", "foo") - out, exit, err := runCommandWithOutput(runCmd) - if !(err != nil && exit == 125 && strings.Contains(out, "Unable to find image")) { - c.Fatalf("Run non-existing image should have errored with 'Unable to find image' code 125, but we got out: %s, exit: %d, err: %s", out, exit, err) - } + icmd.RunCommand(dockerBinary, "run", "foo").Assert(c, icmd.Expected{ + ExitCode: 125, + Err: "Unable to find image", + }) } // TestDockerFails checks that 'docker run -foo busybox' exits with 125 to signal docker run failed +// FIXME(vdemeester) should be a unit test func (s *DockerSuite) TestDockerFails(c *check.C) { - runCmd := exec.Command(dockerBinary, "run", "-foo", "busybox") - out, exit, err := runCommandWithOutput(runCmd) - if !(err != nil && exit == 125) { - c.Fatalf("Docker run with flag not defined should exit with 125, but we got out: %s, exit: %d, err: %s", out, exit, err) - } + icmd.RunCommand(dockerBinary, "run", "-foo", "busybox").Assert(c, icmd.Expected{ + ExitCode: 125, + Error: "exit status 125", + }) } // TestRunInvalidReference invokes docker run with a bad reference. @@ -4490,9 +4408,9 @@ func (s *DockerSuite) TestRunServicingContainer(c *check.C) { err := waitExited(containerID, 60*time.Second) c.Assert(err, checker.IsNil) - cmd := exec.Command("powershell", "echo", `(Get-WinEvent -ProviderName "Microsoft-Windows-Hyper-V-Compute" -FilterXPath 'Event[System[EventID=2010]]' -MaxEvents 1).Message`) - out2, _, err := runCommandWithOutput(cmd) - c.Assert(err, checker.IsNil) + result := icmd.RunCommand("powershell", "echo", `(Get-WinEvent -ProviderName "Microsoft-Windows-Hyper-V-Compute" -FilterXPath 'Event[System[EventID=2010]]' -MaxEvents 1).Message`) + result.Assert(c, icmd.Success) + out2 := result.Combined() c.Assert(out2, checker.Contains, `"Servicing":true`, check.Commentf("Servicing container does not appear to have been started: %s", out2)) c.Assert(out2, checker.Contains, `Windows Container (Servicing)`, check.Commentf("Didn't find 'Windows Container (Servicing): %s", out2)) c.Assert(out2, checker.Contains, containerID+"_servicing", check.Commentf("Didn't find '%s_servicing': %s", containerID+"_servicing", out2)) diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go index 7acefbc9a6..172368e793 100644 --- a/integration-cli/docker_cli_run_unix_test.go +++ b/integration-cli/docker_cli_run_unix_test.go @@ -21,6 +21,7 @@ import ( "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/sysinfo" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" "github.com/kr/pty" ) @@ -884,7 +885,6 @@ func (s *DockerSuite) TestRunTmpfsMountsWithOptions(c *check.C) { } func (s *DockerSuite) TestRunSysctls(c *check.C) { - testRequires(c, DaemonIsLinux) var err error @@ -907,11 +907,11 @@ func (s *DockerSuite) TestRunSysctls(c *check.C) { c.Assert(err, check.IsNil) c.Assert(sysctls["net.ipv4.ip_forward"], check.Equals, "0") - runCmd := exec.Command(dockerBinary, "run", "--sysctl", "kernel.foobar=1", "--name", "test2", "busybox", "cat", "/proc/sys/kernel/foobar") - out, _, _ = runCommandWithOutput(runCmd) - if !strings.Contains(out, "invalid argument") { - c.Fatalf("expected --sysctl to fail, got %s", out) - } + icmd.RunCommand(dockerBinary, "run", "--sysctl", "kernel.foobar=1", "--name", "test2", + "busybox", "cat", "/proc/sys/kernel/foobar").Assert(c, icmd.Expected{ + ExitCode: 125, + Err: "invalid argument", + }) } // TestRunSeccompProfileDenyUnshare checks that 'docker run --security-opt seccomp=/tmp/profile.json debian:jessie unshare' exits with operation not permitted. @@ -935,11 +935,12 @@ func (s *DockerSuite) TestRunSeccompProfileDenyUnshare(c *check.C) { if _, err := tmpFile.Write([]byte(jsonData)); err != nil { c.Fatal(err) } - runCmd := exec.Command(dockerBinary, "run", "--security-opt", "apparmor=unconfined", "--security-opt", "seccomp="+tmpFile.Name(), "debian:jessie", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc") - out, _, _ := runCommandWithOutput(runCmd) - if !strings.Contains(out, "Operation not permitted") { - c.Fatalf("expected unshare with seccomp profile denied to fail, got %s", out) - } + icmd.RunCommand(dockerBinary, "run", "--security-opt", "apparmor=unconfined", + "--security-opt", "seccomp="+tmpFile.Name(), + "debian:jessie", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } // TestRunSeccompProfileDenyChmod checks that 'docker run --security-opt seccomp=/tmp/profile.json busybox chmod 400 /etc/hostname' exits with operation not permitted. @@ -969,11 +970,11 @@ func (s *DockerSuite) TestRunSeccompProfileDenyChmod(c *check.C) { if _, err := tmpFile.Write([]byte(jsonData)); err != nil { c.Fatal(err) } - runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp="+tmpFile.Name(), "busybox", "chmod", "400", "/etc/hostname") - out, _, _ := runCommandWithOutput(runCmd) - if !strings.Contains(out, "Operation not permitted") { - c.Fatalf("expected chmod with seccomp profile denied to fail, got %s", out) - } + icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp="+tmpFile.Name(), + "busybox", "chmod", "400", "/etc/hostname").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } // TestRunSeccompProfileDenyUnshareUserns checks that 'docker run debian:jessie unshare --map-root-user --user sh -c whoami' with a specific profile to @@ -1006,11 +1007,12 @@ func (s *DockerSuite) TestRunSeccompProfileDenyUnshareUserns(c *check.C) { if _, err := tmpFile.Write([]byte(jsonData)); err != nil { c.Fatal(err) } - runCmd := exec.Command(dockerBinary, "run", "--security-opt", "apparmor=unconfined", "--security-opt", "seccomp="+tmpFile.Name(), "debian:jessie", "unshare", "--map-root-user", "--user", "sh", "-c", "whoami") - out, _, _ := runCommandWithOutput(runCmd) - if !strings.Contains(out, "Operation not permitted") { - c.Fatalf("expected unshare userns with seccomp profile denied to fail, got %s", out) - } + icmd.RunCommand(dockerBinary, "run", + "--security-opt", "apparmor=unconfined", "--security-opt", "seccomp="+tmpFile.Name(), + "debian:jessie", "unshare", "--map-root-user", "--user", "sh", "-c", "whoami").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } // TestRunSeccompProfileDenyCloneUserns checks that 'docker run syscall-test' @@ -1019,11 +1021,10 @@ func (s *DockerSuite) TestRunSeccompProfileDenyCloneUserns(c *check.C) { testRequires(c, SameHostDaemon, seccompEnabled) ensureSyscallTest(c) - runCmd := exec.Command(dockerBinary, "run", "syscall-test", "userns-test", "id") - out, _, err := runCommandWithOutput(runCmd) - if err == nil || !strings.Contains(out, "clone failed: Operation not permitted") { - c.Fatalf("expected clone userns with default seccomp profile denied to fail, got %s: %v", out, err) - } + icmd.RunCommand(dockerBinary, "run", "syscall-test", "userns-test", "id").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "clone failed: Operation not permitted", + }) } // TestRunSeccompUnconfinedCloneUserns checks that @@ -1033,10 +1034,10 @@ func (s *DockerSuite) TestRunSeccompUnconfinedCloneUserns(c *check.C) { ensureSyscallTest(c) // make sure running w privileged is ok - runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "syscall-test", "userns-test", "id") - if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "nobody") { - c.Fatalf("expected clone userns with --security-opt seccomp=unconfined to succeed, got %s: %v", out, err) - } + icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp=unconfined", + "syscall-test", "userns-test", "id").Assert(c, icmd.Expected{ + Out: "nobody", + }) } // TestRunSeccompAllowPrivCloneUserns checks that 'docker run --privileged syscall-test' @@ -1046,10 +1047,9 @@ func (s *DockerSuite) TestRunSeccompAllowPrivCloneUserns(c *check.C) { ensureSyscallTest(c) // make sure running w privileged is ok - runCmd := exec.Command(dockerBinary, "run", "--privileged", "syscall-test", "userns-test", "id") - if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "nobody") { - c.Fatalf("expected clone userns with --privileged to succeed, got %s: %v", out, err) - } + icmd.RunCommand(dockerBinary, "run", "--privileged", "syscall-test", "userns-test", "id").Assert(c, icmd.Expected{ + Out: "nobody", + }) } // TestRunSeccompProfileAllow32Bit checks that 32 bit code can run on x86_64 @@ -1058,10 +1058,7 @@ func (s *DockerSuite) TestRunSeccompProfileAllow32Bit(c *check.C) { testRequires(c, SameHostDaemon, seccompEnabled, IsAmd64) ensureSyscallTest(c) - runCmd := exec.Command(dockerBinary, "run", "syscall-test", "exit32-test", "id") - if out, _, err := runCommandWithOutput(runCmd); err != nil { - c.Fatalf("expected to be able to run 32 bit code, got %s: %v", out, err) - } + icmd.RunCommand(dockerBinary, "run", "syscall-test", "exit32-test", "id").Assert(c, icmd.Success) } // TestRunSeccompAllowSetrlimit checks that 'docker run debian:jessie ulimit -v 1048510' succeeds. @@ -1069,10 +1066,7 @@ func (s *DockerSuite) TestRunSeccompAllowSetrlimit(c *check.C) { testRequires(c, SameHostDaemon, seccompEnabled) // ulimit uses setrlimit, so we want to make sure we don't break it - runCmd := exec.Command(dockerBinary, "run", "debian:jessie", "bash", "-c", "ulimit -v 1048510") - if out, _, err := runCommandWithOutput(runCmd); err != nil { - c.Fatalf("expected ulimit with seccomp to succeed, got %s: %v", out, err) - } + icmd.RunCommand(dockerBinary, "run", "debian:jessie", "bash", "-c", "ulimit -v 1048510").Assert(c, icmd.Success) } func (s *DockerSuite) TestRunSeccompDefaultProfileAcct(c *check.C) { @@ -1147,10 +1141,10 @@ func (s *DockerSuite) TestRunNoNewPrivSetuid(c *check.C) { ensureNNPTest(c) // test that running a setuid binary results in no effective uid transition - runCmd := exec.Command(dockerBinary, "run", "--security-opt", "no-new-privileges", "--user", "1000", "nnp-test", "/usr/bin/nnp-test") - if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "EUID=1000") { - c.Fatalf("expected output to contain EUID=1000, got %s: %v", out, err) - } + icmd.RunCommand(dockerBinary, "run", "--security-opt", "no-new-privileges", "--user", "1000", + "nnp-test", "/usr/bin/nnp-test").Assert(c, icmd.Expected{ + Out: "EUID=1000", + }) } func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChown(c *check.C) { @@ -1158,19 +1152,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChown(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_CHOWN - runCmd := exec.Command(dockerBinary, "run", "busybox", "chown", "100", "/tmp") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "busybox", "chown", "100", "/tmp") // test that non root user does not have default capability CAP_CHOWN - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "chown", "100", "/tmp") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "chown", "100", "/tmp").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) // test that root user can drop default capability CAP_CHOWN - runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "chown", "busybox", "chown", "100", "/tmp") - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--cap-drop", "chown", "busybox", "chown", "100", "/tmp").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } func (s *DockerSuite) TestUserNoEffectiveCapabilitiesDacOverride(c *check.C) { @@ -1178,15 +1170,12 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesDacOverride(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_DAC_OVERRIDE - runCmd := exec.Command(dockerBinary, "run", "busybox", "sh", "-c", "echo test > /etc/passwd") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "busybox", "sh", "-c", "echo test > /etc/passwd") // test that non root user does not have default capability CAP_DAC_OVERRIDE - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "sh", "-c", "echo test > /etc/passwd") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Permission denied") - // TODO test that root user can drop default capability CAP_DAC_OVERRIDE + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "sh", "-c", "echo test > /etc/passwd").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Permission denied", + }) } func (s *DockerSuite) TestUserNoEffectiveCapabilitiesFowner(c *check.C) { @@ -1194,14 +1183,12 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesFowner(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_FOWNER - runCmd := exec.Command(dockerBinary, "run", "busybox", "chmod", "777", "/etc/passwd") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "busybox", "chmod", "777", "/etc/passwd") // test that non root user does not have default capability CAP_FOWNER - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "chmod", "777", "/etc/passwd") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "chmod", "777", "/etc/passwd").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) // TODO test that root user can drop default capability CAP_FOWNER } @@ -1212,19 +1199,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesSetuid(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_SETUID - runCmd := exec.Command(dockerBinary, "run", "syscall-test", "setuid-test") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "syscall-test", "setuid-test") // test that non root user does not have default capability CAP_SETUID - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setuid-test") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setuid-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) // test that root user can drop default capability CAP_SETUID - runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "setuid", "syscall-test", "setuid-test") - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--cap-drop", "setuid", "syscall-test", "setuid-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } func (s *DockerSuite) TestUserNoEffectiveCapabilitiesSetgid(c *check.C) { @@ -1232,19 +1217,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesSetgid(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_SETGID - runCmd := exec.Command(dockerBinary, "run", "syscall-test", "setgid-test") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "syscall-test", "setgid-test") // test that non root user does not have default capability CAP_SETGID - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setgid-test") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setgid-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) // test that root user can drop default capability CAP_SETGID - runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "setgid", "syscall-test", "setgid-test") - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--cap-drop", "setgid", "syscall-test", "setgid-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } // TODO CAP_SETPCAP @@ -1254,19 +1237,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesNetBindService(c *check.C) ensureSyscallTest(c) // test that a root user has default capability CAP_NET_BIND_SERVICE - runCmd := exec.Command(dockerBinary, "run", "syscall-test", "socket-test") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "syscall-test", "socket-test") // test that non root user does not have default capability CAP_NET_BIND_SERVICE - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "socket-test") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Permission denied") + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "socket-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Permission denied", + }) // test that root user can drop default capability CAP_NET_BIND_SERVICE - runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "net_bind_service", "syscall-test", "socket-test") - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Permission denied") + icmd.RunCommand(dockerBinary, "run", "--cap-drop", "net_bind_service", "syscall-test", "socket-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Permission denied", + }) } func (s *DockerSuite) TestUserNoEffectiveCapabilitiesNetRaw(c *check.C) { @@ -1274,19 +1255,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesNetRaw(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_NET_RAW - runCmd := exec.Command(dockerBinary, "run", "syscall-test", "raw-test") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "syscall-test", "raw-test") // test that non root user does not have default capability CAP_NET_RAW - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "raw-test") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "raw-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) // test that root user can drop default capability CAP_NET_RAW - runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "net_raw", "syscall-test", "raw-test") - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--cap-drop", "net_raw", "syscall-test", "raw-test").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChroot(c *check.C) { @@ -1294,19 +1273,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChroot(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_SYS_CHROOT - runCmd := exec.Command(dockerBinary, "run", "busybox", "chroot", "/", "/bin/true") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "busybox", "chroot", "/", "/bin/true") // test that non root user does not have default capability CAP_SYS_CHROOT - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "chroot", "/", "/bin/true") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "chroot", "/", "/bin/true").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) // test that root user can drop default capability CAP_SYS_CHROOT - runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "sys_chroot", "busybox", "chroot", "/", "/bin/true") - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--cap-drop", "sys_chroot", "busybox", "chroot", "/", "/bin/true").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } func (s *DockerSuite) TestUserNoEffectiveCapabilitiesMknod(c *check.C) { @@ -1314,19 +1291,18 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesMknod(c *check.C) { ensureSyscallTest(c) // test that a root user has default capability CAP_MKNOD - runCmd := exec.Command(dockerBinary, "run", "busybox", "mknod", "/tmp/node", "b", "1", "2") - _, _, err := runCommandWithOutput(runCmd) - c.Assert(err, check.IsNil) + dockerCmd(c, "run", "busybox", "mknod", "/tmp/node", "b", "1", "2") // test that non root user does not have default capability CAP_MKNOD - runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "mknod", "/tmp/node", "b", "1", "2") - out, _, err := runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + // test that root user can drop default capability CAP_SYS_CHROOT + icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "mknod", "/tmp/node", "b", "1", "2").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) // test that root user can drop default capability CAP_MKNOD - runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "mknod", "busybox", "mknod", "/tmp/node", "b", "1", "2") - out, _, err = runCommandWithOutput(runCmd) - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Operation not permitted") + icmd.RunCommand(dockerBinary, "run", "--cap-drop", "mknod", "busybox", "mknod", "/tmp/node", "b", "1", "2").Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "Operation not permitted", + }) } // TODO CAP_AUDIT_WRITE @@ -1336,14 +1312,16 @@ func (s *DockerSuite) TestRunApparmorProcDirectory(c *check.C) { testRequires(c, SameHostDaemon, Apparmor) // running w seccomp unconfined tests the apparmor profile - runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/cgroup") - if out, _, err := runCommandWithOutput(runCmd); err == nil || !(strings.Contains(out, "Permission denied") || strings.Contains(out, "Operation not permitted")) { - c.Fatalf("expected chmod 777 /proc/1/cgroup to fail, got %s: %v", out, err) + result := icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/cgroup") + result.Assert(c, icmd.Expected{ExitCode: 1}) + if !(strings.Contains(result.Combined(), "Permission denied") || strings.Contains(result.Combined(), "Operation not permitted")) { + c.Fatalf("expected chmod 777 /proc/1/cgroup to fail, got %s: %v", result.Combined(), result.Error) } - runCmd = exec.Command(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/attr/current") - if out, _, err := runCommandWithOutput(runCmd); err == nil || !(strings.Contains(out, "Permission denied") || strings.Contains(out, "Operation not permitted")) { - c.Fatalf("expected chmod 777 /proc/1/attr/current to fail, got %s: %v", out, err) + result = icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/attr/current") + result.Assert(c, icmd.Expected{ExitCode: 1}) + if !(strings.Contains(result.Combined(), "Permission denied") || strings.Contains(result.Combined(), "Operation not permitted")) { + c.Fatalf("expected chmod 777 /proc/1/attr/current to fail, got %s: %v", result.Combined(), result.Error) } } diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go index 3d04561c5f..f498914818 100644 --- a/integration-cli/docker_cli_swarm_test.go +++ b/integration-cli/docker_cli_swarm_test.go @@ -1383,7 +1383,7 @@ func (s *DockerTrustedSwarmSuite) TestTrustedServiceCreate(c *check.C) { name := "trusted" serviceCmd := d.Command("-D", "service", "create", "--name", name, repoName, "top") - s.trustSuite.trustedCmd(serviceCmd) + trustedExecCmd(serviceCmd) out, _, err := runCommandWithOutput(serviceCmd) c.Assert(err, checker.IsNil, check.Commentf(out)) c.Assert(out, checker.Contains, "resolved image tag to", check.Commentf(out)) @@ -1402,7 +1402,7 @@ func (s *DockerTrustedSwarmSuite) TestTrustedServiceCreate(c *check.C) { name = "untrusted" serviceCmd = d.Command("service", "create", "--name", name, repoName, "top") - s.trustSuite.trustedCmd(serviceCmd) + trustedExecCmd(serviceCmd) out, _, err = runCommandWithOutput(serviceCmd) c.Assert(err, check.NotNil, check.Commentf(out)) @@ -1431,7 +1431,7 @@ func (s *DockerTrustedSwarmSuite) TestTrustedServiceUpdate(c *check.C) { c.Assert(out, check.Not(checker.Contains), repoName+"@", check.Commentf(out)) serviceCmd := d.Command("-D", "service", "update", "--image", repoName, name) - s.trustSuite.trustedCmd(serviceCmd) + trustedExecCmd(serviceCmd) out, _, err = runCommandWithOutput(serviceCmd) c.Assert(err, checker.IsNil, check.Commentf(out)) c.Assert(out, checker.Contains, "resolved image tag to", check.Commentf(out)) @@ -1449,7 +1449,7 @@ func (s *DockerTrustedSwarmSuite) TestTrustedServiceUpdate(c *check.C) { dockerCmd(c, "rmi", repoName) serviceCmd = d.Command("service", "update", "--image", repoName, name) - s.trustSuite.trustedCmd(serviceCmd) + trustedExecCmd(serviceCmd) out, _, err = runCommandWithOutput(serviceCmd) c.Assert(err, check.NotNil, check.Commentf(out)) diff --git a/integration-cli/docker_cli_volume_test.go b/integration-cli/docker_cli_volume_test.go index a182f3a3b1..4c5b090864 100644 --- a/integration-cli/docker_cli_volume_test.go +++ b/integration-cli/docker_cli_volume_test.go @@ -213,11 +213,11 @@ func (s *DockerSuite) TestVolumeCLIRm(c *check.C) { volumeID := "testing" dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar") - out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "volume", "rm", "testing")) - c.Assert( - err, - check.Not(check.IsNil), - check.Commentf("Should not be able to remove volume that is in use by a container\n%s", out)) + + icmd.RunCommand(dockerBinary, "volume", "rm", "testing").Assert(c, icmd.Expected{ + ExitCode: 1, + Error: "exit status 1", + }) out, _ = dockerCmd(c, "run", "--volumes-from=test", "--name=test2", "busybox", "sh", "-c", "cat /foo/bar") c.Assert(strings.TrimSpace(out), check.Equals, "hello") @@ -419,8 +419,7 @@ func (s *DockerSuite) TestVolumeCLIRmForce(c *check.C) { c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") // Mountpoint is in the form of "/var/lib/docker/volumes/.../_data", removing `/_data` path := strings.TrimSuffix(strings.TrimSpace(out), "/_data") - out, _, err := runCommandWithOutput(exec.Command("rm", "-rf", path)) - c.Assert(err, check.IsNil) + icmd.RunCommand("rm", "-rf", path).Assert(c, icmd.Success) dockerCmd(c, "volume", "rm", "-f", "test") out, _ = dockerCmd(c, "volume", "ls") diff --git a/integration-cli/docker_cli_wait_test.go b/integration-cli/docker_cli_wait_test.go index 577ff3fd9b..6f45bf07a0 100644 --- a/integration-cli/docker_cli_wait_test.go +++ b/integration-cli/docker_cli_wait_test.go @@ -7,6 +7,7 @@ import ( "time" "github.com/docker/docker/integration-cli/checker" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -36,7 +37,7 @@ func (s *DockerSuite) TestWaitBlockedExitZero(c *check.C) { chWait := make(chan string) go func() { chWait <- "" - out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "wait", containerID)) + out := icmd.RunCommand(dockerBinary, "wait", containerID).Combined() chWait <- out }() diff --git a/integration-cli/docker_experimental_network_test.go b/integration-cli/docker_experimental_network_test.go index b32602aaaf..31ad7adf4a 100644 --- a/integration-cli/docker_experimental_network_test.go +++ b/integration-cli/docker_experimental_network_test.go @@ -3,7 +3,6 @@ package main import ( - "os/exec" "strings" "time" @@ -48,8 +47,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) { // master dummy interface 'dm' abbreviation represents 'docker macvlan' master := "dm-dummy0" // simulate the master link the vlan tagged subinterface parent link will use - out, err := createMasterDummy(c, master) - c.Assert(err, check.IsNil, check.Commentf(out)) + createMasterDummy(c, master) // create a network specifying the desired sub-interface name dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.60", "dm-persist") assertNwIsAvailable(c, "dm-persist") @@ -67,8 +65,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) { // master dummy interface 'di' notation represent 'docker ipvlan' master := "di-dummy0" // simulate the master link the vlan tagged subinterface parent link will use - out, err := createMasterDummy(c, master) - c.Assert(err, check.IsNil, check.Commentf(out)) + createMasterDummy(c, master) // create a network specifying the desired sub-interface name dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.70", "di-persist") assertNwIsAvailable(c, "di-persist") @@ -86,8 +83,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) { // master dummy interface 'dm' abbreviation represents 'docker macvlan' master := "dm-dummy0" // simulate the master link the vlan tagged subinterface parent link will use - out, err := createMasterDummy(c, master) - c.Assert(err, check.IsNil, check.Commentf(out)) + createMasterDummy(c, master) // create a network specifying the desired sub-interface name dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.50", "dm-subinterface") assertNwIsAvailable(c, "dm-subinterface") @@ -101,8 +97,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) { // master dummy interface 'dm' abbreviation represents 'docker ipvlan' master := "di-dummy0" // simulate the master link the vlan tagged subinterface parent link will use - out, err := createMasterDummy(c, master) - c.Assert(err, check.IsNil, check.Commentf(out)) + createMasterDummy(c, master) // create a network specifying the desired sub-interface name dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.60", "di-subinterface") assertNwIsAvailable(c, "di-subinterface") @@ -115,17 +110,15 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) { testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) // master dummy interface 'dm' abbreviation represents 'docker macvlan' master := "dm-dummy0" - out, err := createMasterDummy(c, master) - c.Assert(err, check.IsNil, check.Commentf(out)) - out, err = createVlanInterface(c, master, "dm-dummy0.40", "40") - c.Assert(err, check.IsNil, check.Commentf(out)) + createMasterDummy(c, master) + createVlanInterface(c, master, "dm-dummy0.40", "40") // create a network using an existing parent interface dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-subinterface") assertNwIsAvailable(c, "dm-subinterface") // attempt to create another network using the same parent iface that should fail - out, _, err = dockerCmdWithError("network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-parent-net-overlap") + out, _, err := dockerCmdWithError("network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-parent-net-overlap") // verify that the overlap returns an error - c.Assert(err, check.NotNil) + c.Assert(err, check.NotNil, check.Commentf(out)) // cleanup the master interface which also collects the slave dev deleteInterface(c, "dm-dummy0") } @@ -135,17 +128,15 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) { testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) // master dummy interface 'dm' abbreviation represents 'docker ipvlan' master := "di-dummy0" - out, err := createMasterDummy(c, master) - c.Assert(err, check.IsNil, check.Commentf(out)) - out, err = createVlanInterface(c, master, "di-dummy0.30", "30") - c.Assert(err, check.IsNil, check.Commentf(out)) + createMasterDummy(c, master) + createVlanInterface(c, master, "di-dummy0.30", "30") // create a network using an existing parent interface dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-subinterface") assertNwIsAvailable(c, "di-subinterface") // attempt to create another network using the same parent iface that should fail - out, _, err = dockerCmdWithError("network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-parent-net-overlap") + out, _, err := dockerCmdWithError("network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-parent-net-overlap") // verify that the overlap returns an error - c.Assert(err, check.NotNil) + c.Assert(err, check.NotNil, check.Commentf(out)) // cleanup the master interface which also collects the slave dev deleteInterface(c, "di-dummy0") } @@ -488,9 +479,8 @@ func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) { // macvlan bridge mode - empty parent interface containers can reach each other internally but not externally testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) netName := "dm-parent-exists" - out, err := createMasterDummy(c, "dm-dummy0") + createMasterDummy(c, "dm-dummy0") //out, err := createVlanInterface(c, "dm-parent", "dm-slave", "macvlan", "bridge") - c.Assert(err, check.IsNil, check.Commentf(out)) // create a network using an existing parent interface dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0", netName) assertNwIsAvailable(c, netName) @@ -498,20 +488,16 @@ func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) { dockerCmd(c, "network", "rm", netName) assertNwNotAvailable(c, netName) // verify the network delete did not delete the predefined link - out, err = linkExists(c, "dm-dummy0") - c.Assert(err, check.IsNil, check.Commentf(out)) + linkExists(c, "dm-dummy0") deleteInterface(c, "dm-dummy0") - c.Assert(err, check.IsNil, check.Commentf(out)) } func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) { // macvlan bridge mode - empty parent interface containers can reach each other internally but not externally testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) netName := "dm-subinterface" - out, err := createMasterDummy(c, "dm-dummy0") - c.Assert(err, check.IsNil, check.Commentf(out)) - out, err = createVlanInterface(c, "dm-dummy0", "dm-dummy0.20", "20") - c.Assert(err, check.IsNil, check.Commentf(out)) + createMasterDummy(c, "dm-dummy0") + createVlanInterface(c, "dm-dummy0", "dm-dummy0.20", "20") // create a network using an existing parent interface dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.20", netName) assertNwIsAvailable(c, netName) @@ -522,7 +508,7 @@ func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) { dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=second", "busybox", "top") c.Assert(waitRun("second"), check.IsNil) // verify containers can communicate - _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") + _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") c.Assert(err, check.IsNil) // remove the containers @@ -532,56 +518,25 @@ func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) { dockerCmd(c, "network", "rm", netName) assertNwNotAvailable(c, netName) // verify the network delete did not delete the predefined sub-interface - out, err = linkExists(c, "dm-dummy0.20") - c.Assert(err, check.IsNil, check.Commentf(out)) + linkExists(c, "dm-dummy0.20") // delete the parent interface which also collects the slave deleteInterface(c, "dm-dummy0") - c.Assert(err, check.IsNil, check.Commentf(out)) } -func createMasterDummy(c *check.C, master string) (string, error) { +func createMasterDummy(c *check.C, master string) { // ip link add type dummy - args := []string{"link", "add", master, "type", "dummy"} - ipLinkCmd := exec.Command("ip", args...) - out, _, err := runCommandWithOutput(ipLinkCmd) - if err != nil { - return out, err - } - // ip link set dummy_name up - args = []string{"link", "set", master, "up"} - ipLinkCmd = exec.Command("ip", args...) - out, _, err = runCommandWithOutput(ipLinkCmd) - if err != nil { - return out, err - } - return out, err + icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(c, icmd.Success) + icmd.RunCommand("ip", "link", "set", master, "up").Assert(c, icmd.Success) } -func createVlanInterface(c *check.C, master, slave, id string) (string, error) { +func createVlanInterface(c *check.C, master, slave, id string) { // ip link add link name . type vlan id - args := []string{"link", "add", "link", master, "name", slave, "type", "vlan", "id", id} - ipLinkCmd := exec.Command("ip", args...) - out, _, err := runCommandWithOutput(ipLinkCmd) - if err != nil { - return out, err - } + icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(c, icmd.Success) // ip link set up - args = []string{"link", "set", slave, "up"} - ipLinkCmd = exec.Command("ip", args...) - out, _, err = runCommandWithOutput(ipLinkCmd) - if err != nil { - return out, err - } - return out, err + icmd.RunCommand("ip", "link", "set", slave, "up").Assert(c, icmd.Success) } -func linkExists(c *check.C, master string) (string, error) { +func linkExists(c *check.C, master string) { // verify the specified link exists, ip link show - args := []string{"link", "show", master} - ipLinkCmd := exec.Command("ip", args...) - out, _, err := runCommandWithOutput(ipLinkCmd) - if err != nil { - return out, err - } - return out, err + icmd.RunCommand("ip", "link", "show", master).Assert(c, icmd.Success) } diff --git a/integration-cli/docker_utils_test.go b/integration-cli/docker_utils_test.go index f16544b815..3fd08077bf 100644 --- a/integration-cli/docker_utils_test.go +++ b/integration-cli/docker_utils_test.go @@ -739,10 +739,12 @@ func buildImageFromContextWithOut(name string, ctx *FakeContext, useCache bool, } args = append(args, buildFlags...) args = append(args, ".") - buildCmd := exec.Command(dockerBinary, args...) - buildCmd.Dir = ctx.Dir - out, exitCode, err := runCommandWithOutput(buildCmd) - if err != nil || exitCode != 0 { + result := icmd.RunCmd(icmd.Cmd{ + Command: append([]string{dockerBinary}, args...), + Dir: ctx.Dir, + }) + out := result.Combined() + if result.Error != nil || result.ExitCode != 0 { return "", "", fmt.Errorf("failed to build the image: %s", out) } id, err := getIDByName(name) diff --git a/integration-cli/trust_server_test.go b/integration-cli/trust_server_test.go index a11ccfbdee..947c51ce5b 100644 --- a/integration-cli/trust_server_test.go +++ b/integration-cli/trust_server_test.go @@ -13,6 +13,7 @@ import ( cliconfig "github.com/docker/docker/cli/config" "github.com/docker/docker/integration-cli/checker" + icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/docker/go-connections/tlsconfig" "github.com/go-check/check" ) @@ -34,6 +35,30 @@ type testNotary struct { const notaryHost = "localhost:4443" const notaryURL = "https://" + notaryHost +var SuccessTagging = icmd.Expected{ + Out: "Tagging", +} + +var SuccessSigningAndPushing = icmd.Expected{ + Out: "Signing and pushing trust metadata", +} + +var SuccessDownloaded = icmd.Expected{ + Out: "Status: Downloaded", +} + +var SuccessTaggingOnStderr = icmd.Expected{ + Err: "Tagging", +} + +var SuccessSigningAndPushingOnStderr = icmd.Expected{ + Err: "Signing and pushing trust metadata", +} + +var SuccessDownloadedOnStderr = icmd.Expected{ + Err: "Status: Downloaded", +} + func newTestNotary(c *check.C) (*testNotary, error) { // generate server config template := `{ @@ -164,28 +189,38 @@ func (t *testNotary) Close() { os.RemoveAll(t.dir) } -func (s *DockerTrustSuite) trustedCmd(cmd *exec.Cmd) { +// Deprecated: used trustedCmd instead +func trustedExecCmd(cmd *exec.Cmd) { pwd := "12345678" - trustCmdEnv(cmd, notaryURL, pwd, pwd) + cmd.Env = append(cmd.Env, trustEnv(notaryURL, pwd, pwd)...) } -func (s *DockerTrustSuite) trustedCmdWithServer(cmd *exec.Cmd, server string) { +func trustedCmd(cmd *icmd.Cmd) { pwd := "12345678" - trustCmdEnv(cmd, server, pwd, pwd) + cmd.Env = append(cmd.Env, trustEnv(notaryURL, pwd, pwd)...) } -func (s *DockerTrustSuite) trustedCmdWithPassphrases(cmd *exec.Cmd, rootPwd, repositoryPwd string) { - trustCmdEnv(cmd, notaryURL, rootPwd, repositoryPwd) +func trustedCmdWithServer(server string) func(*icmd.Cmd) { + return func(cmd *icmd.Cmd) { + pwd := "12345678" + cmd.Env = append(cmd.Env, trustEnv(server, pwd, pwd)...) + } } -func trustCmdEnv(cmd *exec.Cmd, server, rootPwd, repositoryPwd string) { - env := []string{ +func trustedCmdWithPassphrases(rootPwd, repositoryPwd string) func(*icmd.Cmd) { + return func(cmd *icmd.Cmd) { + cmd.Env = append(cmd.Env, trustEnv(notaryURL, rootPwd, repositoryPwd)...) + } +} + +func trustEnv(server, rootPwd, repositoryPwd string) []string { + env := append(os.Environ(), []string{ "DOCKER_CONTENT_TRUST=1", fmt.Sprintf("DOCKER_CONTENT_TRUST_SERVER=%s", server), fmt.Sprintf("DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE=%s", rootPwd), fmt.Sprintf("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE=%s", repositoryPwd), - } - cmd.Env = append(os.Environ(), env...) + }...) + return env } func (s *DockerTrustSuite) setupTrustedImage(c *check.C, name string) string { @@ -193,16 +228,7 @@ func (s *DockerTrustSuite) setupTrustedImage(c *check.C, name string) string { // tag the image and upload it to the private registry dockerCmd(c, "tag", "busybox", repoName) - pushCmd := exec.Command(dockerBinary, "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - - if err != nil { - c.Fatalf("Error running trusted push: %s\n%s", err, out) - } - if !strings.Contains(string(out), "Signing and pushing trust metadata") { - c.Fatalf("Missing expected output on trusted push:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) if out, status := dockerCmd(c, "rmi", repoName); status != 0 { c.Fatalf("Error removing image %q\n%s", repoName, out) @@ -216,16 +242,7 @@ func (s *DockerTrustSuite) setupTrustedplugin(c *check.C, source, name string) s // tag the image and upload it to the private registry dockerCmd(c, "plugin", "install", "--grant-all-permissions", "--alias", repoName, source) - pushCmd := exec.Command(dockerBinary, "plugin", "push", repoName) - s.trustedCmd(pushCmd) - out, _, err := runCommandWithOutput(pushCmd) - - if err != nil { - c.Fatalf("Error running trusted plugin push: %s\n%s", err, out) - } - if !strings.Contains(string(out), "Signing and pushing trust metadata") { - c.Fatalf("Missing expected output on trusted push:\n%s", out) - } + icmd.RunCmd(icmd.Command(dockerBinary, "plugin", "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing) if out, status := dockerCmd(c, "plugin", "rm", "-f", repoName); status != 0 { c.Fatalf("Error removing plugin %q\n%s", repoName, out) diff --git a/integration-cli/utils_test.go b/integration-cli/utils_test.go index 4e361cef5f..82d0b162ed 100644 --- a/integration-cli/utils_test.go +++ b/integration-cli/utils_test.go @@ -13,6 +13,7 @@ func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) { } // TODO: update code to call cmd.RunCmd directly, and remove this function +// Deprecated: use pkg/testutil/cmd instead func runCommandWithOutput(execCmd *exec.Cmd) (string, int, error) { result := cmd.RunCmd(transformCmd(execCmd)) return result.Combined(), result.ExitCode, result.Error diff --git a/pkg/testutil/cmd/command.go b/pkg/testutil/cmd/command.go index 2a886ab54c..3086574f4a 100644 --- a/pkg/testutil/cmd/command.go +++ b/pkg/testutil/cmd/command.go @@ -215,8 +215,16 @@ type Cmd struct { Env []string } +// Command create a simple Cmd with the specified command and arguments +func Command(command string, args ...string) Cmd { + return Cmd{Command: append([]string{command}, args...)} +} + // RunCmd runs a command and returns a Result -func RunCmd(cmd Cmd) *Result { +func RunCmd(cmd Cmd, cmdOperators ...func(*Cmd)) *Result { + for _, op := range cmdOperators { + op(&cmd) + } result := StartCmd(cmd) if result.Error != nil { return result @@ -226,7 +234,7 @@ func RunCmd(cmd Cmd) *Result { // RunCommand parses a command line and runs it, returning a result func RunCommand(command string, args ...string) *Result { - return RunCmd(Cmd{Command: append([]string{command}, args...)}) + return RunCmd(Command(command, args...)) } // StartCmd starts a command, but doesn't wait for it to finish