Browse code

Clean some runCommandWithOutput accross integration-cli code

There is still ways to go

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2017/01/05 20:38:34
Showing 19 changed files
... ...
@@ -16,6 +16,7 @@ import (
16 16
 
17 17
 	"github.com/docker/docker/integration-cli/checker"
18 18
 	"github.com/docker/docker/pkg/testutil"
19
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
19 20
 	"github.com/docker/go-units"
20 21
 	"github.com/go-check/check"
21 22
 )
... ...
@@ -100,12 +101,10 @@ func (s *DockerSuite) TestBuildAddChangeOwnership(c *check.C) {
100 100
 		}
101 101
 		defer testFile.Close()
102 102
 
103
-		chownCmd := exec.Command("chown", "daemon:daemon", "foo")
104
-		chownCmd.Dir = tmpDir
105
-		out, _, err := runCommandWithOutput(chownCmd)
106
-		if err != nil {
107
-			c.Fatal(err, out)
108
-		}
103
+		icmd.RunCmd(icmd.Cmd{
104
+			Command: []string{"chown", "daemon:daemon", "foo"},
105
+			Dir: tmpDir,
106
+		}).Assert(c, icmd.Success)
109 107
 
110 108
 		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
111 109
 			c.Fatalf("failed to open destination dockerfile: %v", err)
... ...
@@ -12,6 +12,7 @@ import (
12 12
 	"github.com/docker/docker/api"
13 13
 	"github.com/docker/docker/dockerversion"
14 14
 	"github.com/docker/docker/integration-cli/checker"
15
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
15 16
 	"github.com/docker/docker/pkg/homedir"
16 17
 	"github.com/go-check/check"
17 18
 )
... ...
@@ -51,15 +52,15 @@ func (s *DockerSuite) TestConfigHTTPHeader(c *check.C) {
51 51
 	err = ioutil.WriteFile(tmpCfg, []byte(data), 0600)
52 52
 	c.Assert(err, checker.IsNil)
53 53
 
54
-	cmd := exec.Command(dockerBinary, "-H="+server.URL[7:], "ps")
55
-	out, _, _ := runCommandWithOutput(cmd)
54
+	result := icmd.RunCommand(dockerBinary, "-H="+server.URL[7:], "ps")
55
+	result.Assert(c, icmd.Success)
56 56
 
57 57
 	c.Assert(headers["User-Agent"], checker.NotNil, check.Commentf("Missing User-Agent"))
58 58
 
59
-	c.Assert(headers["User-Agent"][0], checker.Equals, "Docker-Client/"+dockerversion.Version+" ("+runtime.GOOS+")", check.Commentf("Badly formatted User-Agent,out:%v", out))
59
+	c.Assert(headers["User-Agent"][0], checker.Equals, "Docker-Client/"+dockerversion.Version+" ("+runtime.GOOS+")", check.Commentf("Badly formatted User-Agent,out:%v", result.Combined()))
60 60
 
61 61
 	c.Assert(headers["Myheader"], checker.NotNil)
62
-	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("Missing/bad header,out:%v", out))
62
+	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("Missing/bad header,out:%v", result.Combined()))
63 63
 
64 64
 }
65 65
 
... ...
@@ -72,11 +73,10 @@ func (s *DockerSuite) TestConfigDir(c *check.C) {
72 72
 	dockerCmd(c, "--config", cDir, "ps")
73 73
 
74 74
 	// Test with env var too
75
-	cmd := exec.Command(dockerBinary, "ps")
76
-	cmd.Env = appendBaseEnv(true, "DOCKER_CONFIG="+cDir)
77
-	out, _, err := runCommandWithOutput(cmd)
78
-
79
-	c.Assert(err, checker.IsNil, check.Commentf("ps2 didn't work,out:%v", out))
75
+	icmd.RunCmd(icm.Cmd{
76
+		Command: []string{dockerBinary, "ps"},
77
+		Env: appendBaseEnv(true, "DOCKER_CONFIG="+cDir),
78
+	}).Assert(c, icmd.Success)
80 79
 
81 80
 	// Start a server so we can check to see if the config file was
82 81
 	// loaded properly
... ...
@@ -99,42 +99,49 @@ func (s *DockerSuite) TestConfigDir(c *check.C) {
99 99
 
100 100
 	env := appendBaseEnv(false)
101 101
 
102
-	cmd = exec.Command(dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps")
103
-	cmd.Env = env
104
-	out, _, err = runCommandWithOutput(cmd)
105
-
106
-	c.Assert(err, checker.NotNil, check.Commentf("out:%v", out))
102
+	icmd.RunCmd(icmd.Cmd{
103
+		Command: []string{dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps"},
104
+		Env: env,
105
+	}).Assert(c, icmd.Exepected{
106
+		Error: "exit status 1",
107
+	})
107 108
 	c.Assert(headers["Myheader"], checker.NotNil)
108 109
 	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps3 - Missing header,out:%v", out))
109 110
 
110 111
 	// Reset headers and try again using env var this time
111 112
 	headers = map[string][]string{}
112
-	cmd = exec.Command(dockerBinary, "-H="+server.URL[7:], "ps")
113
-	cmd.Env = append(env, "DOCKER_CONFIG="+cDir)
114
-	out, _, err = runCommandWithOutput(cmd)
115
-
116
-	c.Assert(err, checker.NotNil, check.Commentf("%v", out))
113
+	icmd.RunCmd(icmd.Cmd{
114
+		Command: []string{dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps"},
115
+		Env: append(env, "DOCKER_CONFIG="+cDir),
116
+	}).Assert(c, icmd.Exepected{
117
+		Error: "exit status 1",
118
+	})
117 119
 	c.Assert(headers["Myheader"], checker.NotNil)
118 120
 	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps4 - Missing header,out:%v", out))
119 121
 
122
+	// FIXME(vdemeester) should be a unit test
120 123
 	// Reset headers and make sure flag overrides the env var
121 124
 	headers = map[string][]string{}
122
-	cmd = exec.Command(dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps")
123
-	cmd.Env = append(env, "DOCKER_CONFIG=MissingDir")
124
-	out, _, err = runCommandWithOutput(cmd)
125
-
126
-	c.Assert(err, checker.NotNil, check.Commentf("out:%v", out))
125
+	icmd.RunCmd(icmd.Cmd{
126
+		Command: []string{dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps"},
127
+		Env: append(env, "DOCKER_CONFIG=MissingDir"),
128
+	}).Assert(c, icmd.Exepected{
129
+		Error: "exit status 1",
130
+	})
127 131
 	c.Assert(headers["Myheader"], checker.NotNil)
128 132
 	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps5 - Missing header,out:%v", out))
129 133
 
134
+	// FIXME(vdemeester) should be a unit test
130 135
 	// Reset headers and make sure flag overrides the env var.
131 136
 	// Almost same as previous but make sure the "MissingDir" isn't
132 137
 	// ignore - we don't want to default back to the env var.
133 138
 	headers = map[string][]string{}
134
-	cmd = exec.Command(dockerBinary, "--config", "MissingDir", "-H="+server.URL[7:], "ps")
135
-	cmd.Env = append(env, "DOCKER_CONFIG="+cDir)
136
-	out, _, err = runCommandWithOutput(cmd)
139
+	icmd.RunCmd(icmd.Cmd{
140
+		Command: []string{dockerBinary, "--config", "MissingDir", "-H="+server.URL[7:], "ps"},
141
+		Env: append(env, "DOCKER_CONFIG="+cDir),
142
+	}).Assert(c, icmd.Exepected{
143
+		Error: "exit status 1",
144
+	})
137 145
 
138
-	c.Assert(err, checker.NotNil, check.Commentf("out:%v", out))
139 146
 	c.Assert(headers["Myheader"], checker.IsNil, check.Commentf("ps6 - Headers shouldn't be the expected value,out:%v", out))
140 147
 }
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"strings"
10 10
 	"syscall"
11 11
 
12
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
12 13
 	"github.com/docker/docker/integration-cli/checker"
13 14
 	"github.com/docker/docker/pkg/mount"
14 15
 	"github.com/go-check/check"
... ...
@@ -92,10 +93,7 @@ func (s *DockerDaemonSuite) TestDaemonKillLiveRestoreWithPlugins(c *check.C) {
92 92
 		c.Fatalf("Could not kill daemon: %v", err)
93 93
 	}
94 94
 
95
-	cmd := exec.Command("pgrep", "-f", pluginProcessName)
96
-	if out, ec, err := runCommandWithOutput(cmd); ec != 0 {
97
-		c.Fatalf("Expected exit code '0', got %d err: %v output: %s ", ec, err, out)
98
-	}
95
+	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success)
99 96
 }
100 97
 
101 98
 // TestDaemonShutdownLiveRestoreWithPlugins SIGTERMs daemon started with --live-restore.
... ...
@@ -121,10 +119,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C)
121 121
 		c.Fatalf("Could not kill daemon: %v", err)
122 122
 	}
123 123
 
124
-	cmd := exec.Command("pgrep", "-f", pluginProcessName)
125
-	if out, ec, err := runCommandWithOutput(cmd); ec != 0 {
126
-		c.Fatalf("Expected exit code '0', got %d err: %v output: %s ", ec, err, out)
127
-	}
124
+	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success)
128 125
 }
129 126
 
130 127
 // TestDaemonShutdownWithPlugins shuts down running plugins.
... ...
@@ -156,15 +151,13 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
156 156
 		}
157 157
 	}
158 158
 
159
-	cmd := exec.Command("pgrep", "-f", pluginProcessName)
160
-	if out, ec, err := runCommandWithOutput(cmd); ec != 1 {
161
-		c.Fatalf("Expected exit code '1', got %d err: %v output: %s ", ec, err, out)
162
-	}
159
+	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Expected{
160
+		ExitCode: 1,
161
+		Error: "exit status 1",
162
+	})
163 163
 
164 164
 	s.d.Start(c, "--live-restore")
165
-	cmd = exec.Command("pgrep", "-f", pluginProcessName)
166
-	out, _, err := runCommandWithOutput(cmd)
167
-	c.Assert(err, checker.IsNil, check.Commentf(out))
165
+	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success)
168 166
 }
169 167
 
170 168
 // TestVolumePlugin tests volume creation using a plugin.
... ...
@@ -262,30 +262,15 @@ func (s *DockerDaemonSuite) TestDaemonIptablesClean(c *check.C) {
262 262
 		c.Fatalf("Could not run top: %s, %v", out, err)
263 263
 	}
264 264
 
265
-	// get output from iptables with container running
266 265
 	ipTablesSearchString := "tcp dpt:80"
267
-	ipTablesCmd := exec.Command("iptables", "-nvL")
268
-	out, _, err := runCommandWithOutput(ipTablesCmd)
269
-	if err != nil {
270
-		c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
271
-	}
272 266
 
273
-	if !strings.Contains(out, ipTablesSearchString) {
274
-		c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
275
-	}
267
+	// get output from iptables with container running
268
+	verifyIPTablesContains(c, ipTablesSearchString)
276 269
 
277 270
 	s.d.Stop(c)
278 271
 
279 272
 	// get output from iptables after restart
280
-	ipTablesCmd = exec.Command("iptables", "-nvL")
281
-	out, _, err = runCommandWithOutput(ipTablesCmd)
282
-	if err != nil {
283
-		c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
284
-	}
285
-
286
-	if strings.Contains(out, ipTablesSearchString) {
287
-		c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out)
288
-	}
273
+	verifyIPTablesDoesNotContains(c, ipTablesSearchString)
289 274
 }
290 275
 
291 276
 func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) {
... ...
@@ -297,36 +282,36 @@ func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) {
297 297
 
298 298
 	// get output from iptables with container running
299 299
 	ipTablesSearchString := "tcp dpt:80"
300
-	ipTablesCmd := exec.Command("iptables", "-nvL")
301
-	out, _, err := runCommandWithOutput(ipTablesCmd)
302
-	if err != nil {
303
-		c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
304
-	}
305
-
306
-	if !strings.Contains(out, ipTablesSearchString) {
307
-		c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
308
-	}
300
+	verifyIPTablesContains(c, ipTablesSearchString)
309 301
 
310 302
 	s.d.Restart(c)
311 303
 
312 304
 	// make sure the container is not running
313 305
 	runningOut, err := s.d.Cmd("inspect", "--format={{.State.Running}}", "top")
314 306
 	if err != nil {
315
-		c.Fatalf("Could not inspect on container: %s, %v", out, err)
307
+		c.Fatalf("Could not inspect on container: %s, %v", runningOut, err)
316 308
 	}
317 309
 	if strings.TrimSpace(runningOut) != "true" {
318 310
 		c.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut))
319 311
 	}
320 312
 
321 313
 	// get output from iptables after restart
322
-	ipTablesCmd = exec.Command("iptables", "-nvL")
323
-	out, _, err = runCommandWithOutput(ipTablesCmd)
324
-	if err != nil {
325
-		c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
314
+	verifyIPTablesContains(c, ipTablesSearchString)
315
+}
316
+
317
+func verifyIPTablesContains(c *check.C, ipTablesSearchString string) {
318
+	result := icmd.RunCommand("iptables", "-nvL")
319
+	result.Assert(c, icmd.Success)
320
+	if !strings.Contains(result.Combined(), ipTablesSearchString) {
321
+		c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, result.Combined())
326 322
 	}
323
+}
327 324
 
328
-	if !strings.Contains(out, ipTablesSearchString) {
329
-		c.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out)
325
+func verifyIPTablesDoesNotContains(c *check.C, ipTablesSearchString string) {
326
+	result := icmd.RunCommand("iptables", "-nvL")
327
+	result.Assert(c, icmd.Success)
328
+	if strings.Contains(result.Combined(), ipTablesSearchString) {
329
+		c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, result.Combined())
330 330
 	}
331 331
 }
332 332
 
... ...
@@ -564,10 +549,7 @@ func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) {
564 564
 			c.Fatalf("Expected daemon not to start, got %v", err)
565 565
 		}
566 566
 		// look in the log and make sure we got the message that daemon is shutting down
567
-		runCmd := exec.Command("grep", "Error starting daemon", s.d.LogFileName())
568
-		if out, _, err := runCommandWithOutput(runCmd); err != nil {
569
-			c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err)
570
-		}
567
+		icmd.RunCommand("grep", "Error starting daemon", s.d.LogFileName()).Assert(c, icmd.Success)
571 568
 	} else {
572 569
 		//if we didn't get an error and the daemon is running, this is a failure
573 570
 		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) {
584 584
 	bridgeIP := "192.169.1.1/24"
585 585
 	_, bridgeIPNet, _ := net.ParseCIDR(bridgeIP)
586 586
 
587
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
588
-	c.Assert(err, check.IsNil, check.Commentf(out))
587
+	createInterface(c, "bridge", bridgeName, bridgeIP)
589 588
 	defer deleteInterface(c, bridgeName)
590 589
 
591 590
 	d.StartWithBusybox(c, "--bridge", bridgeName)
592 591
 
593 592
 	ipTablesSearchString := bridgeIPNet.String()
594
-	ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL")
595
-	out, _, err = runCommandWithOutput(ipTablesCmd)
596
-	c.Assert(err, check.IsNil)
597
-
598
-	c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true,
599
-		check.Commentf("iptables output should have contained %q, but was %q",
600
-			ipTablesSearchString, out))
593
+	icmd.RunCommand("iptables", "-t", "nat", "-nvL").Assert(c, icmd.Expected{
594
+		Out: ipTablesSearchString,
595
+	})
601 596
 
602 597
 	_, err = d.Cmd("run", "-d", "--name", "ExtContainer", "busybox", "top")
603 598
 	c.Assert(err, check.IsNil)
... ...
@@ -617,41 +594,27 @@ func (s *DockerDaemonSuite) TestDaemonBridgeNone(c *check.C) {
617 617
 	defer d.Restart(c)
618 618
 
619 619
 	// verify docker0 iface is not there
620
-	out, _, err := runCommandWithOutput(exec.Command("ifconfig", "docker0"))
621
-	c.Assert(err, check.NotNil, check.Commentf("docker0 should not be present if daemon started with --bridge=none"))
622
-	c.Assert(strings.Contains(out, "Device not found"), check.Equals, true)
620
+	icmd.RunCommand("ifconfig", "docker0").Assert(c, icmd.Expected{
621
+		ExitCode: 1,
622
+		Error:    "exit status 1",
623
+		Err:      "Device not found",
624
+	})
623 625
 
624 626
 	// verify default "bridge" network is not there
625
-	out, err = d.Cmd("network", "inspect", "bridge")
627
+	out, err := d.Cmd("network", "inspect", "bridge")
626 628
 	c.Assert(err, check.NotNil, check.Commentf("\"bridge\" network should not be present if daemon started with --bridge=none"))
627 629
 	c.Assert(strings.Contains(out, "No such network"), check.Equals, true)
628 630
 }
629 631
 
630
-func createInterface(c *check.C, ifType string, ifName string, ipNet string) (string, error) {
631
-	args := []string{"link", "add", "name", ifName, "type", ifType}
632
-	ipLinkCmd := exec.Command("ip", args...)
633
-	out, _, err := runCommandWithOutput(ipLinkCmd)
634
-	if err != nil {
635
-		return out, err
636
-	}
637
-
638
-	ifCfgCmd := exec.Command("ifconfig", ifName, ipNet, "up")
639
-	out, _, err = runCommandWithOutput(ifCfgCmd)
640
-	return out, err
632
+func createInterface(c *check.C, ifType string, ifName string, ipNet string) {
633
+	icmd.RunCommand("ip", "link", "add", "name", ifName, "type", ifType).Assert(c, icmd.Success)
634
+	icmd.RunCommand("ifconfig", ifName, ipNet, "up").Assert(c, icmd.Success)
641 635
 }
642 636
 
643 637
 func deleteInterface(c *check.C, ifName string) {
644
-	ifCmd := exec.Command("ip", "link", "delete", ifName)
645
-	out, _, err := runCommandWithOutput(ifCmd)
646
-	c.Assert(err, check.IsNil, check.Commentf(out))
647
-
648
-	flushCmd := exec.Command("iptables", "-t", "nat", "--flush")
649
-	out, _, err = runCommandWithOutput(flushCmd)
650
-	c.Assert(err, check.IsNil, check.Commentf(out))
651
-
652
-	flushCmd = exec.Command("iptables", "--flush")
653
-	out, _, err = runCommandWithOutput(flushCmd)
654
-	c.Assert(err, check.IsNil, check.Commentf(out))
638
+	icmd.RunCommand("ip", "link", "delete", ifName).Assert(c, icmd.Success)
639
+	icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(c, icmd.Success)
640
+	icmd.RunCommand("iptables", "--flush").Assert(c, icmd.Success)
655 641
 }
656 642
 
657 643
 func (s *DockerDaemonSuite) TestDaemonBridgeIP(c *check.C) {
... ...
@@ -723,8 +686,7 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) {
723 723
 	bridgeName := "external-bridge"
724 724
 	bridgeIP := "192.169.1.1/24"
725 725
 
726
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
727
-	c.Assert(err, check.IsNil, check.Commentf(out))
726
+	createInterface(c, "bridge", bridgeName, bridgeIP)
728 727
 	defer deleteInterface(c, bridgeName)
729 728
 
730 729
 	args := []string{"--bridge", bridgeName, "--fixed-cidr", "192.169.1.0/30"}
... ...
@@ -747,14 +709,13 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr2(c *check.C) {
747 747
 	bridgeName := "external-bridge"
748 748
 	bridgeIP := "10.2.2.1/16"
749 749
 
750
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
751
-	c.Assert(err, check.IsNil, check.Commentf(out))
750
+	createInterface(c, "bridge", bridgeName, bridgeIP)
752 751
 	defer deleteInterface(c, bridgeName)
753 752
 
754 753
 	d.StartWithBusybox(c, "--bip", bridgeIP, "--fixed-cidr", "10.2.2.0/24")
755 754
 	defer s.d.Restart(c)
756 755
 
757
-	out, err = d.Cmd("run", "-d", "--name", "bb", "busybox", "top")
756
+	out, err := d.Cmd("run", "-d", "--name", "bb", "busybox", "top")
758 757
 	c.Assert(err, checker.IsNil, check.Commentf(out))
759 758
 	defer d.Cmd("stop", "bb")
760 759
 
... ...
@@ -772,14 +733,13 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCIDREqualBridgeNetwork(c *check
772 772
 	bridgeName := "external-bridge"
773 773
 	bridgeIP := "172.27.42.1/16"
774 774
 
775
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
776
-	c.Assert(err, check.IsNil, check.Commentf(out))
775
+	createInterface(c, "bridge", bridgeName, bridgeIP)
777 776
 	defer deleteInterface(c, bridgeName)
778 777
 
779 778
 	d.StartWithBusybox(c, "--bridge", bridgeName, "--fixed-cidr", bridgeIP)
780 779
 	defer s.d.Restart(c)
781 780
 
782
-	out, err = d.Cmd("run", "-d", "busybox", "top")
781
+	out, err := d.Cmd("run", "-d", "busybox", "top")
783 782
 	c.Assert(err, check.IsNil, check.Commentf(out))
784 783
 	cid1 := strings.TrimSpace(out)
785 784
 	defer d.Cmd("stop", cid1)
... ...
@@ -871,21 +831,18 @@ func (s *DockerDaemonSuite) TestDaemonIP(c *check.C) {
871 871
 	c.Assert(strings.Contains(out, "Error starting userland proxy"), check.Equals, true)
872 872
 
873 873
 	ifName := "dummy"
874
-	out, err = createInterface(c, "dummy", ifName, ipStr)
875
-	c.Assert(err, check.IsNil, check.Commentf(out))
874
+	createInterface(c, "dummy", ifName, ipStr)
876 875
 	defer deleteInterface(c, ifName)
877 876
 
878 877
 	_, err = d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top")
879 878
 	c.Assert(err, check.IsNil)
880 879
 
881
-	ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL")
882
-	out, _, err = runCommandWithOutput(ipTablesCmd)
883
-	c.Assert(err, check.IsNil)
884
-
880
+	result := icmd.RunCommand("iptables", "-t", "nat", "-nvL")
881
+	result.Assert(c, icmd.Success)
885 882
 	regex := fmt.Sprintf("DNAT.*%s.*dpt:8000", ip.String())
886
-	matched, _ := regexp.MatchString(regex, out)
883
+	matched, _ := regexp.MatchString(regex, result.Combined())
887 884
 	c.Assert(matched, check.Equals, true,
888
-		check.Commentf("iptables output should have contained %q, but was %q", regex, out))
885
+		check.Commentf("iptables output should have contained %q, but was %q", regex, result.Combined()))
889 886
 }
890 887
 
891 888
 func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) {
... ...
@@ -895,22 +852,18 @@ func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) {
895 895
 	bridgeName := "external-bridge"
896 896
 	bridgeIP := "192.169.1.1/24"
897 897
 
898
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
899
-	c.Assert(err, check.IsNil, check.Commentf(out))
898
+	createInterface(c, "bridge", bridgeName, bridgeIP)
900 899
 	defer deleteInterface(c, bridgeName)
901 900
 
902
-	args := []string{"--bridge", bridgeName, "--icc=false"}
903
-	d.StartWithBusybox(c, args...)
901
+	d.StartWithBusybox(c, "--bridge", bridgeName, "--icc=false")
904 902
 	defer d.Restart(c)
905 903
 
906
-	ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD")
907
-	out, _, err = runCommandWithOutput(ipTablesCmd)
908
-	c.Assert(err, check.IsNil)
909
-
904
+	result := icmd.RunCommand("iptables", "-nvL", "FORWARD")
905
+	result.Assert(c, icmd.Success)
910 906
 	regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName)
911
-	matched, _ := regexp.MatchString(regex, out)
907
+	matched, _ := regexp.MatchString(regex, result.Combined())
912 908
 	c.Assert(matched, check.Equals, true,
913
-		check.Commentf("iptables output should have contained %q, but was %q", regex, out))
909
+		check.Commentf("iptables output should have contained %q, but was %q", regex, result.Combined()))
914 910
 
915 911
 	// Pinging another container must fail with --icc=false
916 912
 	pingContainers(c, d, true)
... ...
@@ -924,7 +877,7 @@ func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) {
924 924
 	// But, Pinging external or a Host interface must succeed
925 925
 	pingCmd := fmt.Sprintf("ping -c 1 %s -W 1", ip.String())
926 926
 	runArgs := []string{"run", "--rm", "busybox", "sh", "-c", pingCmd}
927
-	_, err = d.Cmd(runArgs...)
927
+	_, err := d.Cmd(runArgs...)
928 928
 	c.Assert(err, check.IsNil)
929 929
 }
930 930
 
... ...
@@ -934,24 +887,20 @@ func (s *DockerDaemonSuite) TestDaemonICCLinkExpose(c *check.C) {
934 934
 	bridgeName := "external-bridge"
935 935
 	bridgeIP := "192.169.1.1/24"
936 936
 
937
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
938
-	c.Assert(err, check.IsNil, check.Commentf(out))
937
+	createInterface(c, "bridge", bridgeName, bridgeIP)
939 938
 	defer deleteInterface(c, bridgeName)
940 939
 
941
-	args := []string{"--bridge", bridgeName, "--icc=false"}
942
-	d.StartWithBusybox(c, args...)
940
+	d.StartWithBusybox(c, "--bridge", bridgeName, "--icc=false")
943 941
 	defer d.Restart(c)
944 942
 
945
-	ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD")
946
-	out, _, err = runCommandWithOutput(ipTablesCmd)
947
-	c.Assert(err, check.IsNil)
948
-
943
+	result := icmd.RunCommand("iptables", "-nvL", "FORWARD")
944
+	result.Assert(c, icmd.Success)
949 945
 	regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName)
950
-	matched, _ := regexp.MatchString(regex, out)
946
+	matched, _ := regexp.MatchString(regex, result.Combined())
951 947
 	c.Assert(matched, check.Equals, true,
952
-		check.Commentf("iptables output should have contained %q, but was %q", regex, out))
948
+		check.Commentf("iptables output should have contained %q, but was %q", regex, result.Combined()))
953 949
 
954
-	out, err = d.Cmd("run", "-d", "--expose", "4567", "--name", "icc1", "busybox", "nc", "-l", "-p", "4567")
950
+	out, err := d.Cmd("run", "-d", "--expose", "4567", "--name", "icc1", "busybox", "nc", "-l", "-p", "4567")
955 951
 	c.Assert(err, check.IsNil, check.Commentf(out))
956 952
 
957 953
 	out, err = d.Cmd("run", "--link", "icc1:icc1", "busybox", "nc", "icc1", "4567")
... ...
@@ -962,14 +911,13 @@ func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *che
962 962
 	bridgeName := "external-bridge"
963 963
 	bridgeIP := "192.169.1.1/24"
964 964
 
965
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
966
-	c.Assert(err, check.IsNil, check.Commentf(out))
965
+	createInterface(c, "bridge", bridgeName, bridgeIP)
967 966
 	defer deleteInterface(c, bridgeName)
968 967
 
969 968
 	s.d.StartWithBusybox(c, "--bridge", bridgeName, "--icc=false")
970 969
 	defer s.d.Restart(c)
971 970
 
972
-	_, err = s.d.Cmd("run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top")
971
+	_, err := s.d.Cmd("run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top")
973 972
 	c.Assert(err, check.IsNil)
974 973
 	_, err = s.d.Cmd("run", "-d", "--name", "parent", "--link", "child:http", "busybox", "top")
975 974
 	c.Assert(err, check.IsNil)
... ...
@@ -1464,10 +1412,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *chec
1464 1464
 	c.Assert(strings.Contains(string(mountOut), id), check.Equals, true, comment)
1465 1465
 
1466 1466
 	// kill the container
1467
-	runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", id)
1468
-	if out, ec, err := runCommandWithOutput(runCmd); err != nil {
1469
-		c.Fatalf("Failed to run ctr, ExitCode: %d, err: %v output: %s id: %s\n", ec, err, out, id)
1470
-	}
1467
+	icmd.RunCommand(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", id).Assert(c, icmd.Success)
1471 1468
 
1472 1469
 	// restart daemon.
1473 1470
 	d.Restart(c)
... ...
@@ -1564,10 +1509,9 @@ func (s *DockerDaemonSuite) TestDaemonRestartCleanupNetns(c *check.C) {
1564 1564
 	}
1565 1565
 
1566 1566
 	// Test if the file still exists
1567
-	out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName))
1568
-	out = strings.TrimSpace(out)
1569
-	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
1570
-	c.Assert(out, check.Equals, fileName, check.Commentf("Output: %s", out))
1567
+	icmd.RunCommand("stat", "-c", "%n", fileName).Assert(c, icmd.Expected{
1568
+		Out: fileName,
1569
+	})
1571 1570
 
1572 1571
 	// Remove the container and restart the daemon
1573 1572
 	if out, err := s.d.Cmd("rm", "netns"); err != nil {
... ...
@@ -1577,32 +1521,34 @@ func (s *DockerDaemonSuite) TestDaemonRestartCleanupNetns(c *check.C) {
1577 1577
 	s.d.Restart(c)
1578 1578
 
1579 1579
 	// Test again and see now the netns file does not exist
1580
-	out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName))
1581
-	out = strings.TrimSpace(out)
1582
-	c.Assert(err, check.Not(check.IsNil), check.Commentf("Output: %s", out))
1580
+	icmd.RunCommand("stat", "-c", "%n", fileName).Assert(c, icmd.Expected{
1581
+		Err:      "No such file or directory",
1582
+		ExitCode: 1,
1583
+	})
1583 1584
 }
1584 1585
 
1585 1586
 // tests regression detailed in #13964 where DOCKER_TLS_VERIFY env is ignored
1586 1587
 func (s *DockerDaemonSuite) TestDaemonTLSVerifyIssue13964(c *check.C) {
1587 1588
 	host := "tcp://localhost:4271"
1588 1589
 	s.d.Start(c, "-H", host)
1589
-	cmd := exec.Command(dockerBinary, "-H", host, "info")
1590
-	cmd.Env = []string{"DOCKER_TLS_VERIFY=1", "DOCKER_CERT_PATH=fixtures/https"}
1591
-	out, _, err := runCommandWithOutput(cmd)
1592
-	c.Assert(err, check.Not(check.IsNil), check.Commentf("%s", out))
1593
-	c.Assert(strings.Contains(out, "error during connect"), check.Equals, true)
1594
-
1590
+	icmd.RunCmd(icmd.Cmd{
1591
+		Command: []string{dockerBinary, "-H", host, "info"},
1592
+		Env:     []string{"DOCKER_TLS_VERIFY=1", "DOCKER_CERT_PATH=fixtures/https"},
1593
+	}).Assert(c, icmd.Expected{
1594
+		ExitCode: 1,
1595
+		Err:      "error during connect",
1596
+	})
1595 1597
 }
1596 1598
 
1597 1599
 func setupV6(c *check.C) {
1598 1600
 	// Hack to get the right IPv6 address on docker0, which has already been created
1599 1601
 	result := icmd.RunCommand("ip", "addr", "add", "fe80::1/64", "dev", "docker0")
1600
-	result.Assert(c, icmd.Expected{})
1602
+	result.Assert(c, icmd.Success)
1601 1603
 }
1602 1604
 
1603 1605
 func teardownV6(c *check.C) {
1604 1606
 	result := icmd.RunCommand("ip", "addr", "del", "fe80::1/64", "dev", "docker0")
1605
-	result.Assert(c, icmd.Expected{})
1607
+	result.Assert(c, icmd.Success)
1606 1608
 }
1607 1609
 
1608 1610
 func (s *DockerDaemonSuite) TestDaemonRestartWithContainerWithRestartPolicyAlways(c *check.C) {
... ...
@@ -1708,10 +1654,7 @@ func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) {
1708 1708
 	})
1709 1709
 	c.Assert(d.StartWithError("--log-driver=syslog", "--log-opt", "syslog-address=corrupted:42"), check.NotNil)
1710 1710
 	expected := "Failed to set log opts: syslog-address should be in form proto://address"
1711
-	runCmd := exec.Command("grep", expected, d.LogFileName())
1712
-	if out, _, err := runCommandWithOutput(runCmd); err != nil {
1713
-		c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err)
1714
-	}
1711
+	icmd.RunCommand("grep", expected, d.LogFileName()).Assert(c, icmd.Success)
1715 1712
 }
1716 1713
 
1717 1714
 // FIXME(vdemeester) should be a unit test
... ...
@@ -1721,10 +1664,7 @@ func (s *DockerDaemonSuite) TestDaemonCorruptedFluentdAddress(c *check.C) {
1721 1721
 	})
1722 1722
 	c.Assert(d.StartWithError("--log-driver=fluentd", "--log-opt", "fluentd-address=corrupted:c"), check.NotNil)
1723 1723
 	expected := "Failed to set log opts: invalid fluentd-address corrupted:c: "
1724
-	runCmd := exec.Command("grep", expected, d.LogFileName())
1725
-	if out, _, err := runCommandWithOutput(runCmd); err != nil {
1726
-		c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err)
1727
-	}
1724
+	icmd.RunCommand("grep", expected, d.LogFileName()).Assert(c, icmd.Success)
1728 1725
 }
1729 1726
 
1730 1727
 // FIXME(vdemeester) Use a new daemon instance instead of the Suite one
... ...
@@ -1808,13 +1748,11 @@ func (s *DockerDaemonSuite) TestDaemonNoSpaceLeftOnDeviceError(c *check.C) {
1808 1808
 	// create a 2MiB image and mount it as graph root
1809 1809
 	// 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)
1810 1810
 	dockerCmd(c, "run", "--rm", "-v", testDir+":/test", "busybox", "sh", "-c", "dd of=/test/testfs.img bs=1M seek=2 count=0")
1811
-	out, _, err := runCommandWithOutput(exec.Command("mkfs.ext4", "-F", filepath.Join(testDir, "testfs.img"))) // `mkfs.ext4` is not in busybox
1812
-	c.Assert(err, checker.IsNil, check.Commentf(out))
1811
+	icmd.RunCommand("mkfs.ext4", "-F", filepath.Join(testDir, "testfs.img")).Assert(c, icmd.Success)
1813 1812
 
1814
-	cmd := exec.Command("losetup", "-f", "--show", filepath.Join(testDir, "testfs.img"))
1815
-	loout, err := cmd.CombinedOutput()
1816
-	c.Assert(err, checker.IsNil)
1817
-	loopname := strings.TrimSpace(string(loout))
1813
+	result := icmd.RunCommand("losetup", "-f", "--show", filepath.Join(testDir, "testfs.img"))
1814
+	result.Assert(c, icmd.Success)
1815
+	loopname := strings.TrimSpace(string(result.Combined()))
1818 1816
 	defer exec.Command("losetup", "-d", loopname).Run()
1819 1817
 
1820 1818
 	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
2007 2007
 	}
2008 2008
 
2009 2009
 	// kill the container
2010
-	runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", cid)
2011
-	if out, ec, err := runCommandWithOutput(runCmd); err != nil {
2012
-		t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid)
2013
-	}
2010
+	icmd.RunCommand(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", cid).Assert(c, icmd.Success)
2014 2011
 
2015 2012
 	// Give time to containerd to process the command if we don't
2016 2013
 	// the exit event might be received after we do the inspect
... ...
@@ -2,10 +2,10 @@ package main
2 2
 
3 3
 import (
4 4
 	"os"
5
-	"os/exec"
6 5
 	"strings"
7 6
 
8 7
 	"github.com/docker/docker/integration-cli/checker"
8
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
... ...
@@ -18,12 +18,13 @@ func (s *DockerSuite) TestExportContainerAndImportImage(c *check.C) {
18 18
 
19 19
 	out, _ := dockerCmd(c, "export", containerID)
20 20
 
21
-	importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1")
22
-	importCmd.Stdin = strings.NewReader(out)
23
-	out, _, err := runCommandWithOutput(importCmd)
24
-	c.Assert(err, checker.IsNil, check.Commentf("failed to import image repo/testexp:v1: %s", out))
21
+	result := icmd.RunCmd(icmd.Cmd{
22
+		Command: dockerBinary, "import", "-", "repo/testexp:v1",
23
+		Stdin: strings.NewReader(out),
24
+	})
25
+	result.Assert(c, icmd.Success)
25 26
 
26
-	cleanedImageID := strings.TrimSpace(out)
27
+	cleanedImageID := strings.TrimSpace(result.Combined())
27 28
 	c.Assert(cleanedImageID, checker.Not(checker.Equals), "", check.Commentf("output should have been an image id"))
28 29
 }
29 30
 
... ...
@@ -36,14 +37,15 @@ func (s *DockerSuite) TestExportContainerWithOutputAndImportImage(c *check.C) {
36 36
 	dockerCmd(c, "export", "--output=testexp.tar", containerID)
37 37
 	defer os.Remove("testexp.tar")
38 38
 
39
-	out, _, err := runCommandWithOutput(exec.Command("cat", "testexp.tar"))
40
-	c.Assert(err, checker.IsNil, check.Commentf(out))
39
+	resultCat := icmd.RunCommand("cat", "testexp.tar")
40
+	resultCat.Assert(c, icmd.Success)
41 41
 
42
-	importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1")
43
-	importCmd.Stdin = strings.NewReader(out)
44
-	out, _, err = runCommandWithOutput(importCmd)
45
-	c.Assert(err, checker.IsNil, check.Commentf("failed to import image repo/testexp:v1: %s", out))
42
+	result := icmd.RunCmd(icmd.Cmd{
43
+		Command: dockerBinary, "import", "-", "repo/testexp:v1",
44
+		Stdin: strings.NewReader(resultCat.Combined()),
45
+	})
46
+	result.Assert(c, icmd.Success)
46 47
 
47
-	cleanedImageID := strings.TrimSpace(out)
48
+	cleanedImageID := strings.TrimSpace(result.Combined())
48 49
 	c.Assert(cleanedImageID, checker.Not(checker.Equals), "", check.Commentf("output should have been an image id"))
49 50
 }
... ...
@@ -14,6 +14,7 @@ import (
14 14
 )
15 15
 
16 16
 func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
17
+	// FIXME(vdemeester) should be a unit test, probably using golden files ?
17 18
 	testRequires(c, DaemonIsLinux)
18 19
 
19 20
 	// Make sure main help text fits within 80 chars and that
... ...
@@ -52,11 +53,12 @@ func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
52 52
 		scanForHome := runtime.GOOS != "windows" && home != "/"
53 53
 
54 54
 		// Check main help text to make sure its not over 80 chars
55
-		helpCmd := exec.Command(dockerBinary, "help")
56
-		helpCmd.Env = newEnvs
57
-		out, _, err := runCommandWithOutput(helpCmd)
58
-		c.Assert(err, checker.IsNil, check.Commentf(out))
59
-		lines := strings.Split(out, "\n")
55
+		result := icmd.RunCmd(icmd.Cmd{
56
+			Command: []stirng{dockerBinary, "help"},
57
+			Env: newEnvs,
58
+		})
59
+		result.Assert(c, icmd.Success)
60
+		lines := strings.Split(result.Combined(), "\n")
60 61
 		for _, line := range lines {
61 62
 			// All lines should not end with a space
62 63
 			c.Assert(line, checker.Not(checker.HasSuffix), " ", check.Commentf("Line should not end with a space"))
... ...
@@ -75,16 +77,17 @@ func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
75 75
 		// Make sure each cmd's help text fits within 90 chars and that
76 76
 		// on non-windows system we use ~ when possible (to shorten things).
77 77
 		// Pull the list of commands from the "Commands:" section of docker help
78
-		helpCmd = exec.Command(dockerBinary, "help")
79
-		helpCmd.Env = newEnvs
80
-		out, _, err = runCommandWithOutput(helpCmd)
81
-		c.Assert(err, checker.IsNil, check.Commentf(out))
82
-		i := strings.Index(out, "Commands:")
83
-		c.Assert(i, checker.GreaterOrEqualThan, 0, check.Commentf("Missing 'Commands:' in:\n%s", out))
78
+		// FIXME(vdemeester) Why re-run help ?
79
+		//helpCmd = exec.Command(dockerBinary, "help")
80
+		//helpCmd.Env = newEnvs
81
+		//out, _, err = runCommandWithOutput(helpCmd)
82
+		//c.Assert(err, checker.IsNil, check.Commentf(out))
83
+		i := strings.Index(result.Combined(), "Commands:")
84
+		c.Assert(i, checker.GreaterOrEqualThan, 0, check.Commentf("Missing 'Commands:' in:\n%s", result.Combined()))
84 85
 
85 86
 		cmds := []string{}
86 87
 		// Grab all chars starting at "Commands:"
87
-		helpOut := strings.Split(out[i:], "\n")
88
+		helpOut := strings.Split(result.Combined()[i:], "\n")
88 89
 		// Skip first line, it is just "Commands:"
89 90
 		helpOut = helpOut[1:]
90 91
 
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"strings"
9 9
 	"time"
10 10
 
11
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
11 12
 	"github.com/docker/docker/integration-cli/checker"
12 13
 	"github.com/docker/docker/pkg/jsonlog"
13 14
 	"github.com/docker/docker/pkg/testutil"
... ...
@@ -188,14 +189,14 @@ func (s *DockerSuite) TestLogsSince(c *check.C) {
188 188
 
189 189
 	// Test with default value specified and parameter omitted
190 190
 	expected := []string{"log1", "log2", "log3"}
191
-	for _, cmd := range []*exec.Cmd{
192
-		exec.Command(dockerBinary, "logs", "-t", name),
193
-		exec.Command(dockerBinary, "logs", "-t", "--since=0", name),
191
+	for _, cmd := range [][]string{
192
+		[]string{dockerBinary, "logs", "-t", name},
193
+		[]string{dockerBinary, "logs", "-t", "--since=0", name},
194 194
 	} {
195
-		out, _, err = runCommandWithOutput(cmd)
196
-		c.Assert(err, checker.IsNil, check.Commentf("failed to log container: %s", out))
195
+		result := icmd.RunCommand(cmd...)
196
+		result.Assert(c, icmd.Success)
197 197
 		for _, v := range expected {
198
-			c.Assert(out, checker.Contains, v)
198
+			c.Assert(result.Combined(), checker.Contains, v)
199 199
 		}
200 200
 	}
201 201
 }
... ...
@@ -803,15 +803,14 @@ func (s *DockerDaemonSuite) TestDockerNetworkNoDiscoveryDefaultBridgeNetwork(c *
803 803
 	hostsFile := "/etc/hosts"
804 804
 	bridgeName := "external-bridge"
805 805
 	bridgeIP := "192.169.255.254/24"
806
-	out, err := createInterface(c, "bridge", bridgeName, bridgeIP)
807
-	c.Assert(err, check.IsNil, check.Commentf(out))
806
+	createInterface(c, "bridge", bridgeName, bridgeIP)
808 807
 	defer deleteInterface(c, bridgeName)
809 808
 
810 809
 	s.d.StartWithBusybox(c, "--bridge", bridgeName)
811 810
 	defer s.d.Restart(c)
812 811
 
813 812
 	// run two containers and store first container's etc/hosts content
814
-	out, err = s.d.Cmd("run", "-d", "busybox", "top")
813
+	out, err := s.d.Cmd("run", "-d", "busybox", "top")
815 814
 	c.Assert(err, check.IsNil)
816 815
 	cid1 := strings.TrimSpace(out)
817 816
 	defer s.d.Cmd("stop", cid1)
... ...
@@ -5,20 +5,18 @@ import (
5 5
 	"os/exec"
6 6
 	"strings"
7 7
 
8
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
8 9
 	"github.com/docker/docker/integration-cli/checker"
9 10
 	"github.com/go-check/check"
10 11
 )
11 12
 
12 13
 func (s *DockerSuite) TestCLIProxyDisableProxyUnixSock(c *check.C) {
13
-	testRequires(c, DaemonIsLinux)
14
-	testRequires(c, SameHostDaemon) // test is valid when DOCKER_HOST=unix://..
15
-
16
-	cmd := exec.Command(dockerBinary, "info")
17
-	cmd.Env = appendBaseEnv(false, "HTTP_PROXY=http://127.0.0.1:9999")
18
-
19
-	out, _, err := runCommandWithOutput(cmd)
20
-	c.Assert(err, checker.IsNil, check.Commentf("%v", out))
14
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
21 15
 
16
+	icmd.RunCmd(icm.Cmd{
17
+		Command: []string{dockerBinary, "info"},
18
+		Env: appendBaseEnv(false, "HTTP_PROXY=http://127.0.0.1:9999"),
19
+	}).Assert(c, icmd.Success)
22 20
 }
23 21
 
24 22
 // Can't use localhost here since go has a special case to not use proxy if connecting to localhost
... ...
@@ -41,12 +39,14 @@ func (s *DockerDaemonSuite) TestCLIProxyProxyTCPSock(c *check.C) {
41 41
 	c.Assert(ip, checker.Not(checker.Equals), "")
42 42
 
43 43
 	s.d.Start(c, "-H", "tcp://"+ip+":2375")
44
-	cmd := exec.Command(dockerBinary, "info")
45
-	cmd.Env = []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999"}
46
-	out, _, err := runCommandWithOutput(cmd)
47
-	c.Assert(err, checker.NotNil, check.Commentf("%v", out))
44
+
45
+	icmd.RunCmd(icmd.Cmd{
46
+		Command: []string{dockerBinary, "info"},
47
+		Env: []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999"},
48
+	}).Assert(c, icmd.Expected{Error:"exit status 1", ExitCode: 1})
48 49
 	// Test with no_proxy
49
-	cmd.Env = append(cmd.Env, "NO_PROXY="+ip)
50
-	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "info"))
51
-	c.Assert(err, checker.IsNil, check.Commentf("%v", out))
50
+	icmd.RunCommand(icmd.Cmd{
51
+		Command: []string{dockerBinary, "info"},
52
+		Env: []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999", "NO_PROXY="+ip},
53
+	}).Assert(c, icmd.Success)
52 54
 }
... ...
@@ -669,22 +669,19 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) {
669 669
 	originalImageName := "busybox:TestPsImageIDAfterUpdate-original"
670 670
 	updatedImageName := "busybox:TestPsImageIDAfterUpdate-updated"
671 671
 
672
-	runCmd := exec.Command(dockerBinary, "tag", "busybox:latest", originalImageName)
673
-	out, _, err := runCommandWithOutput(runCmd)
674
-	c.Assert(err, checker.IsNil)
672
+	icmd.RunCommand(dockerBinary, "tag", "busybox:latest", originalImageName).Assert(c, icmd.Success)
675 673
 
676 674
 	originalImageID, err := getIDByName(originalImageName)
677 675
 	c.Assert(err, checker.IsNil)
678 676
 
679
-	runCmd = exec.Command(dockerBinary, append([]string{"run", "-d", originalImageName}, sleepCommandForDaemonPlatform()...)...)
680
-	out, _, err = runCommandWithOutput(runCmd)
681
-	c.Assert(err, checker.IsNil)
682
-	containerID := strings.TrimSpace(out)
677
+	result := icmd.RunCommand(dockerBinary, append([]string{"run", "-d", originalImageName}, sleepCommandForDaemonPlatform()...)...)
678
+	result.Assert(c, icmd.Success)
679
+	containerID := strings.TrimSpace(result.Combined())
683 680
 
684
-	linesOut, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
685
-	c.Assert(err, checker.IsNil)
681
+	result = icmd.RunCommand(dockerBinary, "ps", "--no-trunc")
682
+	result.Assert(c, icmd.Success)
686 683
 
687
-	lines := strings.Split(strings.TrimSpace(string(linesOut)), "\n")
684
+	lines := strings.Split(strings.TrimSpace(string(result.Combined())), "\n")
688 685
 	// skip header
689 686
 	lines = lines[1:]
690 687
 	c.Assert(len(lines), checker.Equals, 1)
... ...
@@ -694,18 +691,13 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) {
694 694
 		c.Assert(f[1], checker.Equals, originalImageName)
695 695
 	}
696 696
 
697
-	runCmd = exec.Command(dockerBinary, "commit", containerID, updatedImageName)
698
-	out, _, err = runCommandWithOutput(runCmd)
699
-	c.Assert(err, checker.IsNil)
700
-
701
-	runCmd = exec.Command(dockerBinary, "tag", updatedImageName, originalImageName)
702
-	out, _, err = runCommandWithOutput(runCmd)
703
-	c.Assert(err, checker.IsNil)
697
+	icmd.RunCommand(dockerBinary, "commit", containerID, updatedImageName).Assert(c, icmd.Success)
698
+	icmd.RunCommand(dockerBinary, "tag", updatedImageName, originalImageName).Assert(c, icmd.Success)
704 699
 
705
-	linesOut, err = exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
706
-	c.Assert(err, checker.IsNil)
700
+	result = icmd.RunCommand(dockerBinary, "ps", "--no-trunc")
701
+	result.Assert(c, icmd.Success)
707 702
 
708
-	lines = strings.Split(strings.TrimSpace(string(linesOut)), "\n")
703
+	lines = strings.Split(strings.TrimSpace(string(result.Combined())), "\n")
709 704
 	// skip header
710 705
 	lines = lines[1:]
711 706
 	c.Assert(len(lines), checker.Equals, 1)
... ...
@@ -12,6 +12,7 @@ import (
12 12
 
13 13
 	"github.com/docker/distribution"
14 14
 	"github.com/docker/distribution/digest"
15
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
15 16
 	"github.com/docker/distribution/manifest"
16 17
 	"github.com/docker/distribution/manifest/manifestlist"
17 18
 	"github.com/docker/distribution/manifest/schema2"
... ...
@@ -87,8 +88,8 @@ func testConcurrentPullWholeRepo(c *check.C) {
87 87
 
88 88
 	for i := 0; i != numPulls; i++ {
89 89
 		go func() {
90
-			_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", "-a", repoName))
91
-			results <- err
90
+			result := icmd.RunCommand(dockerBinary, "pull", "-a", repoName)
91
+			results <- result.Error
92 92
 		}()
93 93
 	}
94 94
 
... ...
@@ -125,8 +126,8 @@ func testConcurrentFailingPull(c *check.C) {
125 125
 
126 126
 	for i := 0; i != numPulls; i++ {
127 127
 		go func() {
128
-			_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repoName+":asdfasdf"))
129
-			results <- err
128
+			result := icmd.RunCommand(dockerBinary, "pull", repoName+":asdfasdf")
129
+			results <- result.Error
130 130
 		}()
131 131
 	}
132 132
 
... ...
@@ -175,8 +176,8 @@ func testConcurrentPullMultipleTags(c *check.C) {
175 175
 
176 176
 	for _, repo := range repos {
177 177
 		go func(repo string) {
178
-			_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repo))
179
-			results <- err
178
+			result := icmd.RunCommand(dockerBinary, "pull", repo)
179
+			results <- result.Error
180 180
 		}(repo)
181 181
 	}
182 182
 
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	"time"
15 15
 
16 16
 	"github.com/docker/distribution/reference"
17
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
17 18
 	cliconfig "github.com/docker/docker/cli/config"
18 19
 	"github.com/docker/docker/integration-cli/checker"
19 20
 	"github.com/docker/docker/pkg/testutil"
... ...
@@ -135,10 +136,10 @@ func testPushEmptyLayer(c *check.C) {
135 135
 	c.Assert(err, check.IsNil, check.Commentf("Could not open test tarball"))
136 136
 	defer freader.Close()
137 137
 
138
-	importCmd := exec.Command(dockerBinary, "import", "-", repoName)
139
-	importCmd.Stdin = freader
140
-	out, _, err := runCommandWithOutput(importCmd)
141
-	c.Assert(err, check.IsNil, check.Commentf("import failed: %q", out))
138
+	icmd.RunCmd(icmd.Cmd{
139
+		Command: []string{dockerBinary, "import", "-", repoName},
140
+		Stdin: freader,
141
+	}).Assert(c, icmd.Success)
142 142
 
143 143
 	// Now verify we can push it
144 144
 	out, _, err = dockerCmdWithError("push", repoName)
... ...
@@ -177,8 +178,8 @@ func testConcurrentPush(c *check.C) {
177 177
 
178 178
 	for _, repo := range repos {
179 179
 		go func(repo string) {
180
-			_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "push", repo))
181
-			results <- err
180
+			result := icmd.RunCommand(dockerBinary, "push", repo)
181
+			results <- result.Error
182 182
 		}(repo)
183 183
 	}
184 184
 
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"strings"
7 7
 	"time"
8 8
 
9
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
9 10
 	"github.com/docker/docker/integration-cli/checker"
10 11
 	"github.com/docker/docker/pkg/stringid"
11 12
 	"github.com/go-check/check"
... ...
@@ -175,12 +176,11 @@ func (s *DockerSuite) TestRmiTagWithExistingContainers(c *check.C) {
175 175
 func (s *DockerSuite) TestRmiForceWithExistingContainers(c *check.C) {
176 176
 	image := "busybox-clone"
177 177
 
178
-	cmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", image, "-")
179
-	cmd.Stdin = strings.NewReader(`FROM busybox
178
+	icmd.RunCmd(icmd.Cmd{
179
+		Command: []string{dockerBinary, "build", "--no-cache", "-t", image, "-"},
180
+		Stdin: strings.NewReader(`FROM busybox
180 181
 MAINTAINER foo`)
181
-
182
-	out, _, err := runCommandWithOutput(cmd)
183
-	c.Assert(err, checker.IsNil, check.Commentf("Could not build %s: %s", image, out))
182
+	}).Assert(c, icmd.Success)
184 183
 
185 184
 	dockerCmd(c, "run", "--name", "test-force-rmi", image, "/bin/true")
186 185
 
... ...
@@ -819,21 +819,21 @@ func (s *DockerSuite) TestRunEnvironment(c *check.C) {
819 819
 	// TODO Windows: Environment handling is different between Linux and
820 820
 	// Windows and this test relies currently on unix functionality.
821 821
 	testRequires(c, DaemonIsLinux)
822
-	cmd := exec.Command(dockerBinary, "run", "-h", "testing", "-e=FALSE=true", "-e=TRUE", "-e=TRICKY", "-e=HOME=", "busybox", "env")
823
-	cmd.Env = append(os.Environ(),
824
-		"TRUE=false",
825
-		"TRICKY=tri\ncky\n",
826
-	)
827
-
828
-	out, _, err := runCommandWithOutput(cmd)
829
-	if err != nil {
830
-		c.Fatal(err, out)
831
-	}
822
+	result := icmd.RunCmd(icmd.Cmd{
823
+		Command: []string{dockerBinary, "run", "-h", "testing", "-e=FALSE=true", "-e=TRUE", "-e=TRICKY", "-e=HOME=", "busybox", "env"},
824
+		Env: append(os.Environ(),
825
+			"TRUE=false",
826
+			"TRICKY=tri\ncky\n",
827
+		),
828
+	})
829
+	result.Assert(c, icmd.Success)
832 830
 
833
-	actualEnv := strings.Split(strings.TrimSpace(out), "\n")
831
+	actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n")
834 832
 	sort.Strings(actualEnv)
835 833
 
836 834
 	goodEnv := []string{
835
+		// The first two should not be tested here, those are "inherent" environment variable. This test validates
836
+		// the -e behavior, not the default environment variable (that could be subject to change)
837 837
 		"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
838 838
 		"HOSTNAME=testing",
839 839
 		"FALSE=true",
... ...
@@ -863,15 +863,13 @@ func (s *DockerSuite) TestRunEnvironmentErase(c *check.C) {
863 863
 	// not set in our local env that they're removed (if present) in
864 864
 	// the container
865 865
 
866
-	cmd := exec.Command(dockerBinary, "run", "-e", "FOO", "-e", "HOSTNAME", "busybox", "env")
867
-	cmd.Env = appendBaseEnv(true)
868
-
869
-	out, _, err := runCommandWithOutput(cmd)
870
-	if err != nil {
871
-		c.Fatal(err, out)
872
-	}
866
+	result := icmd.RunCmd(icmd.Cmd{
867
+		Command: []string{dockerBinary, "run", "-e", "FOO", "-e", "HOSTNAME", "busybox", "env"},
868
+		Env: appendBaseEnd(true),
869
+	})
870
+	result.Assert(c, icmd.Success)
873 871
 
874
-	actualEnv := strings.Split(strings.TrimSpace(out), "\n")
872
+	actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n")
875 873
 	sort.Strings(actualEnv)
876 874
 
877 875
 	goodEnv := []string{
... ...
@@ -897,15 +895,13 @@ func (s *DockerSuite) TestRunEnvironmentOverride(c *check.C) {
897 897
 	// Test to make sure that when we use -e on env vars that are
898 898
 	// already in the env that we're overriding them
899 899
 
900
-	cmd := exec.Command(dockerBinary, "run", "-e", "HOSTNAME", "-e", "HOME=/root2", "busybox", "env")
901
-	cmd.Env = appendBaseEnv(true, "HOSTNAME=bar")
902
-
903
-	out, _, err := runCommandWithOutput(cmd)
904
-	if err != nil {
905
-		c.Fatal(err, out)
906
-	}
900
+	result := icmd.RunCmd(icmd.Cmd{
901
+		Command: []string{dockerBinary, "run", "-e", "HOSTNAME", "-e", "HOME=/root2", "busybox", "env"},
902
+		Env: appendBaseEnv(true, "HOSTNAME=bar"),
903
+	})
904
+	result.Assert(c, icmd.Success)
907 905
 
908
-	actualEnv := strings.Split(strings.TrimSpace(out), "\n")
906
+	actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n")
909 907
 	sort.Strings(actualEnv)
910 908
 
911 909
 	goodEnv := []string{
... ...
@@ -2111,12 +2107,9 @@ func (s *DockerSuite) TestRunDeallocatePortOnMissingIptablesRule(c *check.C) {
2111 2111
 
2112 2112
 	id := strings.TrimSpace(out)
2113 2113
 	ip := inspectField(c, id, "NetworkSettings.Networks.bridge.IPAddress")
2114
-	iptCmd := exec.Command("iptables", "-D", "DOCKER", "-d", fmt.Sprintf("%s/32", ip),
2115
-		"!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT")
2116
-	out, _, err := runCommandWithOutput(iptCmd)
2117
-	if err != nil {
2118
-		c.Fatal(err, out)
2119
-	}
2114
+	icmd.RunCommand("iptables", "-D", "DOCKER", "-d", fmt.Sprintf("%s/32", ip),
2115
+		"!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT").Assert(c, icmd.Success)
2116
+
2120 2117
 	if err := deleteContainer(false, id); err != nil {
2121 2118
 		c.Fatal(err)
2122 2119
 	}
... ...
@@ -4012,23 +4005,19 @@ func (s *DockerSuite) TestRunWrongCpusetMemsFlagValue(c *check.C) {
4012 4012
 // TestRunNonExecutableCmd checks that 'docker run busybox foo' exits with error code 127'
4013 4013
 func (s *DockerSuite) TestRunNonExecutableCmd(c *check.C) {
4014 4014
 	name := "testNonExecutableCmd"
4015
-	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "foo")
4016
-	_, exit, _ := runCommandWithOutput(runCmd)
4017
-	stateExitCode := findContainerExitCode(c, name)
4018
-	if !(exit == 127 && strings.Contains(stateExitCode, "127")) {
4019
-		c.Fatalf("Run non-executable command should have errored with exit code 127, but we got exit: %d, State.ExitCode: %s", exit, stateExitCode)
4020
-	}
4015
+	icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "foo").Assert(c, icmd.Expected{
4016
+		ExitCode: 127,
4017
+		Error: "exit status 127",
4018
+	})
4021 4019
 }
4022 4020
 
4023 4021
 // TestRunNonExistingCmd checks that 'docker run busybox /bin/foo' exits with code 127.
4024 4022
 func (s *DockerSuite) TestRunNonExistingCmd(c *check.C) {
4025 4023
 	name := "testNonExistingCmd"
4026
-	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "/bin/foo")
4027
-	_, exit, _ := runCommandWithOutput(runCmd)
4028
-	stateExitCode := findContainerExitCode(c, name)
4029
-	if !(exit == 127 && strings.Contains(stateExitCode, "127")) {
4030
-		c.Fatalf("Run non-existing command should have errored with exit code 127, but we got exit: %d, State.ExitCode: %s", exit, stateExitCode)
4031
-	}
4024
+	icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "/bin/foo").Assert(c, icmd.Expected{
4025
+		ExitCode: 127,
4026
+		Error: "exit status 127",
4027
+	})
4032 4028
 }
4033 4029
 
4034 4030
 // TestCmdCannotBeInvoked checks that 'docker run busybox /etc' exits with 126, or
... ...
@@ -4040,30 +4029,28 @@ func (s *DockerSuite) TestCmdCannotBeInvoked(c *check.C) {
4040 4040
 		expected = 127
4041 4041
 	}
4042 4042
 	name := "testCmdCannotBeInvoked"
4043
-	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "/etc")
4044
-	_, exit, _ := runCommandWithOutput(runCmd)
4045
-	stateExitCode := findContainerExitCode(c, name)
4046
-	if !(exit == expected && strings.Contains(stateExitCode, strconv.Itoa(expected))) {
4047
-		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)
4048
-	}
4043
+	icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "/etc").Assert(c, icmd.Expected{
4044
+		ExitCode: expected,
4045
+		Error: fmt.Sprintf("exit status %d", expected),
4046
+	})
4049 4047
 }
4050 4048
 
4051 4049
 // TestRunNonExistingImage checks that 'docker run foo' exits with error msg 125 and contains  'Unable to find image'
4050
+// FIXME(vdemeester) should be a unit test
4052 4051
 func (s *DockerSuite) TestRunNonExistingImage(c *check.C) {
4053
-	runCmd := exec.Command(dockerBinary, "run", "foo")
4054
-	out, exit, err := runCommandWithOutput(runCmd)
4055
-	if !(err != nil && exit == 125 && strings.Contains(out, "Unable to find image")) {
4056
-		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)
4057
-	}
4052
+	icmd.RunCommand(dockerBinary, "run", "foo").Assert(c, icmd.Expected{
4053
+		ExitCode: 125,
4054
+		Err: "Unable to find image",
4055
+	})
4058 4056
 }
4059 4057
 
4060 4058
 // TestDockerFails checks that 'docker run -foo busybox' exits with 125 to signal docker run failed
4059
+// FIXME(vdemeester) should be a unit test
4061 4060
 func (s *DockerSuite) TestDockerFails(c *check.C) {
4062
-	runCmd := exec.Command(dockerBinary, "run", "-foo", "busybox")
4063
-	out, exit, err := runCommandWithOutput(runCmd)
4064
-	if !(err != nil && exit == 125) {
4065
-		c.Fatalf("Docker run with flag not defined should exit with 125, but we got out: %s, exit: %d, err: %s", out, exit, err)
4066
-	}
4061
+	icmd.RunCommand(dockerBinary, "run", "-foo", "busybox").Assert(c, icmd.Expected{
4062
+		ExitCode: 125,
4063
+		Error: "exit status 125",
4064
+	})
4067 4065
 }
4068 4066
 
4069 4067
 // TestRunInvalidReference invokes docker run with a bad reference.
... ...
@@ -4490,9 +4477,9 @@ func (s *DockerSuite) TestRunServicingContainer(c *check.C) {
4490 4490
 	err := waitExited(containerID, 60*time.Second)
4491 4491
 	c.Assert(err, checker.IsNil)
4492 4492
 
4493
-	cmd := exec.Command("powershell", "echo", `(Get-WinEvent -ProviderName "Microsoft-Windows-Hyper-V-Compute" -FilterXPath 'Event[System[EventID=2010]]' -MaxEvents 1).Message`)
4494
-	out2, _, err := runCommandWithOutput(cmd)
4495
-	c.Assert(err, checker.IsNil)
4493
+	result := icmd.RunCommand("powershell", "echo", `(Get-WinEvent -ProviderName "Microsoft-Windows-Hyper-V-Compute" -FilterXPath 'Event[System[EventID=2010]]' -MaxEvents 1).Message`)
4494
+	result.Assert(c, icmd.Success)
4495
+	out2 := result.Combined()
4496 4496
 	c.Assert(out2, checker.Contains, `"Servicing":true`, check.Commentf("Servicing container does not appear to have been started: %s", out2))
4497 4497
 	c.Assert(out2, checker.Contains, `Windows Container (Servicing)`, check.Commentf("Didn't find 'Windows Container (Servicing): %s", out2))
4498 4498
 	c.Assert(out2, checker.Contains, containerID+"_servicing", check.Commentf("Didn't find '%s_servicing': %s", containerID+"_servicing", out2))
... ...
@@ -21,6 +21,7 @@ import (
21 21
 	"github.com/docker/docker/pkg/mount"
22 22
 	"github.com/docker/docker/pkg/parsers"
23 23
 	"github.com/docker/docker/pkg/sysinfo"
24
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
24 25
 	"github.com/go-check/check"
25 26
 	"github.com/kr/pty"
26 27
 )
... ...
@@ -884,7 +885,6 @@ func (s *DockerSuite) TestRunTmpfsMountsWithOptions(c *check.C) {
884 884
 }
885 885
 
886 886
 func (s *DockerSuite) TestRunSysctls(c *check.C) {
887
-
888 887
 	testRequires(c, DaemonIsLinux)
889 888
 	var err error
890 889
 
... ...
@@ -907,11 +907,11 @@ func (s *DockerSuite) TestRunSysctls(c *check.C) {
907 907
 	c.Assert(err, check.IsNil)
908 908
 	c.Assert(sysctls["net.ipv4.ip_forward"], check.Equals, "0")
909 909
 
910
-	runCmd := exec.Command(dockerBinary, "run", "--sysctl", "kernel.foobar=1", "--name", "test2", "busybox", "cat", "/proc/sys/kernel/foobar")
911
-	out, _, _ = runCommandWithOutput(runCmd)
912
-	if !strings.Contains(out, "invalid argument") {
913
-		c.Fatalf("expected --sysctl to fail, got %s", out)
914
-	}
910
+	icmd.RunCommand(dockerBinary, "run", "--sysctl", "kernel.foobar=1", "--name", "test2",
911
+		"busybox", "cat", "/proc/sys/kernel/foobar").Assert(c, icmd.Expected{
912
+		ExitCode: 1,
913
+		Err:      "invalid argument",
914
+	})
915 915
 }
916 916
 
917 917
 // 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) {
935 935
 	if _, err := tmpFile.Write([]byte(jsonData)); err != nil {
936 936
 		c.Fatal(err)
937 937
 	}
938
-	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")
939
-	out, _, _ := runCommandWithOutput(runCmd)
940
-	if !strings.Contains(out, "Operation not permitted") {
941
-		c.Fatalf("expected unshare with seccomp profile denied to fail, got %s", out)
942
-	}
938
+	icmd.RunCommand(dockerBinary, "run", "--security-opt", "apparmor=unconfined",
939
+		"--security-opt", "seccomp="+tmpFile.Name(),
940
+		"debian:jessie", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc").Assert(c, icmd.Expected{
941
+		ExitCode: 1,
942
+		Err: "Operation not permitted",
943
+	})
943 944
 }
944 945
 
945 946
 // 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) {
969 969
 	if _, err := tmpFile.Write([]byte(jsonData)); err != nil {
970 970
 		c.Fatal(err)
971 971
 	}
972
-	runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp="+tmpFile.Name(), "busybox", "chmod", "400", "/etc/hostname")
973
-	out, _, _ := runCommandWithOutput(runCmd)
974
-	if !strings.Contains(out, "Operation not permitted") {
975
-		c.Fatalf("expected chmod with seccomp profile denied to fail, got %s", out)
976
-	}
972
+	icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp="+tmpFile.Name(),
973
+		"busybox", "chmod", "400", "/etc/hostname").Assert(c, icmd.Expected{
974
+		ExitCode: 1,
975
+		Err: "Operation not permitted",
976
+	})
977 977
 }
978 978
 
979 979
 // 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) {
1006 1006
 	if _, err := tmpFile.Write([]byte(jsonData)); err != nil {
1007 1007
 		c.Fatal(err)
1008 1008
 	}
1009
-	runCmd := exec.Command(dockerBinary, "run", "--security-opt", "apparmor=unconfined", "--security-opt", "seccomp="+tmpFile.Name(), "debian:jessie", "unshare", "--map-root-user", "--user", "sh", "-c", "whoami")
1010
-	out, _, _ := runCommandWithOutput(runCmd)
1011
-	if !strings.Contains(out, "Operation not permitted") {
1012
-		c.Fatalf("expected unshare userns with seccomp profile denied to fail, got %s", out)
1013
-	}
1009
+	icmd.RunCommand(dockerBinary, "run",
1010
+		"--security-opt", "apparmor=unconfined", "--security-opt", "seccomp="+tmpFile.Name(),
1011
+		"debian:jessie", "unshare", "--map-root-user", "--user", "sh", "-c", "whoami").Assert(c, icmd.Expected{
1012
+		ExitCode: 1,
1013
+		Err: "Operation not permitted",
1014
+	})
1014 1015
 }
1015 1016
 
1016 1017
 // TestRunSeccompProfileDenyCloneUserns checks that 'docker run syscall-test'
... ...
@@ -1019,11 +1021,10 @@ func (s *DockerSuite) TestRunSeccompProfileDenyCloneUserns(c *check.C) {
1019 1019
 	testRequires(c, SameHostDaemon, seccompEnabled)
1020 1020
 	ensureSyscallTest(c)
1021 1021
 
1022
-	runCmd := exec.Command(dockerBinary, "run", "syscall-test", "userns-test", "id")
1023
-	out, _, err := runCommandWithOutput(runCmd)
1024
-	if err == nil || !strings.Contains(out, "clone failed: Operation not permitted") {
1025
-		c.Fatalf("expected clone userns with default seccomp profile denied to fail, got %s: %v", out, err)
1026
-	}
1022
+	icmd.RunCommand(dockerBinary, "run", "syscall-test", "userns-test", "id").Assert(c, icmd.Expected{
1023
+		ExitCode: 1,
1024
+		Err: "clone failed: Operation not permitted",
1025
+	})
1027 1026
 }
1028 1027
 
1029 1028
 // TestRunSeccompUnconfinedCloneUserns checks that
... ...
@@ -1033,10 +1034,10 @@ func (s *DockerSuite) TestRunSeccompUnconfinedCloneUserns(c *check.C) {
1033 1033
 	ensureSyscallTest(c)
1034 1034
 
1035 1035
 	// make sure running w privileged is ok
1036
-	runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "syscall-test", "userns-test", "id")
1037
-	if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "nobody") {
1038
-		c.Fatalf("expected clone userns with --security-opt seccomp=unconfined to succeed, got %s: %v", out, err)
1039
-	}
1036
+	icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp=unconfined",
1037
+		"syscall-test", "userns-test", "id").Assert(c, icmd.Expected{
1038
+		Out: "nobody",
1039
+	})
1040 1040
 }
1041 1041
 
1042 1042
 // TestRunSeccompAllowPrivCloneUserns checks that 'docker run --privileged syscall-test'
... ...
@@ -1046,10 +1047,9 @@ func (s *DockerSuite) TestRunSeccompAllowPrivCloneUserns(c *check.C) {
1046 1046
 	ensureSyscallTest(c)
1047 1047
 
1048 1048
 	// make sure running w privileged is ok
1049
-	runCmd := exec.Command(dockerBinary, "run", "--privileged", "syscall-test", "userns-test", "id")
1050
-	if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "nobody") {
1051
-		c.Fatalf("expected clone userns with --privileged to succeed, got %s: %v", out, err)
1052
-	}
1049
+	icmd.RunCommand(dockerBinary, "run", "--privileged", "syscall-test", "userns-test", "id").Assert(c, icmd.Expected{
1050
+		Out: "nobody",
1051
+	})
1053 1052
 }
1054 1053
 
1055 1054
 // TestRunSeccompProfileAllow32Bit checks that 32 bit code can run on x86_64
... ...
@@ -1058,10 +1058,7 @@ func (s *DockerSuite) TestRunSeccompProfileAllow32Bit(c *check.C) {
1058 1058
 	testRequires(c, SameHostDaemon, seccompEnabled, IsAmd64)
1059 1059
 	ensureSyscallTest(c)
1060 1060
 
1061
-	runCmd := exec.Command(dockerBinary, "run", "syscall-test", "exit32-test", "id")
1062
-	if out, _, err := runCommandWithOutput(runCmd); err != nil {
1063
-		c.Fatalf("expected to be able to run 32 bit code, got %s: %v", out, err)
1064
-	}
1061
+	icmd.RunCommand(dockerBinary, "run", "syscall-test", "exit32-test", "id").Assert(c, icmd.Success)
1065 1062
 }
1066 1063
 
1067 1064
 // TestRunSeccompAllowSetrlimit checks that 'docker run debian:jessie ulimit -v 1048510' succeeds.
... ...
@@ -1069,10 +1066,7 @@ func (s *DockerSuite) TestRunSeccompAllowSetrlimit(c *check.C) {
1069 1069
 	testRequires(c, SameHostDaemon, seccompEnabled)
1070 1070
 
1071 1071
 	// ulimit uses setrlimit, so we want to make sure we don't break it
1072
-	runCmd := exec.Command(dockerBinary, "run", "debian:jessie", "bash", "-c", "ulimit -v 1048510")
1073
-	if out, _, err := runCommandWithOutput(runCmd); err != nil {
1074
-		c.Fatalf("expected ulimit with seccomp to succeed, got %s: %v", out, err)
1075
-	}
1072
+	icmd.RunCommand(dockerBinary, "run", "debian:jessie", "bash", "-c", "ulimit -v 1048510").Assert(c, icmd.Success)
1076 1073
 }
1077 1074
 
1078 1075
 func (s *DockerSuite) TestRunSeccompDefaultProfileAcct(c *check.C) {
... ...
@@ -1147,10 +1141,10 @@ func (s *DockerSuite) TestRunNoNewPrivSetuid(c *check.C) {
1147 1147
 	ensureNNPTest(c)
1148 1148
 
1149 1149
 	// test that running a setuid binary results in no effective uid transition
1150
-	runCmd := exec.Command(dockerBinary, "run", "--security-opt", "no-new-privileges", "--user", "1000", "nnp-test", "/usr/bin/nnp-test")
1151
-	if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "EUID=1000") {
1152
-		c.Fatalf("expected output to contain EUID=1000, got %s: %v", out, err)
1153
-	}
1150
+	icmd.RunCommand(dockerBinary, "run", "--security-opt", "no-new-privileges", "--user", "1000",
1151
+		"nnp-test", "/usr/bin/nnp-test").Assert(c, icmd.Expected{
1152
+		Out: "EUID=1000",
1153
+	})
1154 1154
 }
1155 1155
 
1156 1156
 func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChown(c *check.C) {
... ...
@@ -1158,19 +1152,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChown(c *check.C) {
1158 1158
 	ensureSyscallTest(c)
1159 1159
 
1160 1160
 	// test that a root user has default capability CAP_CHOWN
1161
-	runCmd := exec.Command(dockerBinary, "run", "busybox", "chown", "100", "/tmp")
1162
-	_, _, err := runCommandWithOutput(runCmd)
1163
-	c.Assert(err, check.IsNil)
1161
+	dockerCmd("run", "busybox", "chown", "100", "/tmp")
1164 1162
 	// test that non root user does not have default capability CAP_CHOWN
1165
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "chown", "100", "/tmp")
1166
-	out, _, err := runCommandWithOutput(runCmd)
1167
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1168
-	c.Assert(out, checker.Contains, "Operation not permitted")
1163
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "chown", "100", "/tmp").Assert(c, icmd.Expected{
1164
+		ExitCode: 1,
1165
+		Err: "Operation not permitted",
1166
+	})
1169 1167
 	// test that root user can drop default capability CAP_CHOWN
1170
-	runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "chown", "busybox", "chown", "100", "/tmp")
1171
-	out, _, err = runCommandWithOutput(runCmd)
1172
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1173
-	c.Assert(out, checker.Contains, "Operation not permitted")
1168
+	icmd.RunCommand(dockerBinary, "run", "--cap-drop", "chown", "busybox", "chown", "100", "/tmp").Assert(c, icmd.Expected{
1169
+		ExitCode: 1,
1170
+		Err: "Operation not permitted",
1171
+	})
1174 1172
 }
1175 1173
 
1176 1174
 func (s *DockerSuite) TestUserNoEffectiveCapabilitiesDacOverride(c *check.C) {
... ...
@@ -1178,15 +1170,12 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesDacOverride(c *check.C) {
1178 1178
 	ensureSyscallTest(c)
1179 1179
 
1180 1180
 	// test that a root user has default capability CAP_DAC_OVERRIDE
1181
-	runCmd := exec.Command(dockerBinary, "run", "busybox", "sh", "-c", "echo test > /etc/passwd")
1182
-	_, _, err := runCommandWithOutput(runCmd)
1183
-	c.Assert(err, check.IsNil)
1181
+	dockerCmd("run", "busybox", "sh", "-c", "echo test > /etc/passwd")
1184 1182
 	// test that non root user does not have default capability CAP_DAC_OVERRIDE
1185
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "sh", "-c", "echo test > /etc/passwd")
1186
-	out, _, err := runCommandWithOutput(runCmd)
1187
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1188
-	c.Assert(out, checker.Contains, "Permission denied")
1189
-	// TODO test that root user can drop default capability CAP_DAC_OVERRIDE
1183
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "sh", "-c", "echo test > /etc/passwd").Assert(c, icmd.Expected{
1184
+		ExitCode: 1,
1185
+		Err: "Permission denied",
1186
+	})
1190 1187
 }
1191 1188
 
1192 1189
 func (s *DockerSuite) TestUserNoEffectiveCapabilitiesFowner(c *check.C) {
... ...
@@ -1194,14 +1183,12 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesFowner(c *check.C) {
1194 1194
 	ensureSyscallTest(c)
1195 1195
 
1196 1196
 	// test that a root user has default capability CAP_FOWNER
1197
-	runCmd := exec.Command(dockerBinary, "run", "busybox", "chmod", "777", "/etc/passwd")
1198
-	_, _, err := runCommandWithOutput(runCmd)
1199
-	c.Assert(err, check.IsNil)
1197
+	dockerCmd("run", "busybox", "chmod", "777", "/etc/passwd")
1200 1198
 	// test that non root user does not have default capability CAP_FOWNER
1201
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "chmod", "777", "/etc/passwd")
1202
-	out, _, err := runCommandWithOutput(runCmd)
1203
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1204
-	c.Assert(out, checker.Contains, "Operation not permitted")
1199
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "chmod", "777", "/etc/passwd").Assert(c, icmd.Expected{
1200
+		ExitCode: 1,
1201
+		Err: "Operation not permitted",
1202
+	})
1205 1203
 	// TODO test that root user can drop default capability CAP_FOWNER
1206 1204
 }
1207 1205
 
... ...
@@ -1212,19 +1199,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesSetuid(c *check.C) {
1212 1212
 	ensureSyscallTest(c)
1213 1213
 
1214 1214
 	// test that a root user has default capability CAP_SETUID
1215
-	runCmd := exec.Command(dockerBinary, "run", "syscall-test", "setuid-test")
1216
-	_, _, err := runCommandWithOutput(runCmd)
1217
-	c.Assert(err, check.IsNil)
1215
+	dockerCmd("run", "syscall-test", "setuid-test")
1218 1216
 	// test that non root user does not have default capability CAP_SETUID
1219
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setuid-test")
1220
-	out, _, err := runCommandWithOutput(runCmd)
1221
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1222
-	c.Assert(out, checker.Contains, "Operation not permitted")
1217
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setuid-test").Assert(c, icmd.Expected{
1218
+		ExitCode: 1,
1219
+		Err: "Operation not permitted",
1220
+	})
1223 1221
 	// test that root user can drop default capability CAP_SETUID
1224
-	runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "setuid", "syscall-test", "setuid-test")
1225
-	out, _, err = runCommandWithOutput(runCmd)
1226
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1227
-	c.Assert(out, checker.Contains, "Operation not permitted")
1222
+	icmd.RunCommand(dockerBinary, "run", "--cap-drop", "setuid", "syscall-test", "setuid-test").Assert(c, icmd.Expected{
1223
+		ExitCode: 1,
1224
+		Err: "Operation not permitted",
1225
+	})
1228 1226
 }
1229 1227
 
1230 1228
 func (s *DockerSuite) TestUserNoEffectiveCapabilitiesSetgid(c *check.C) {
... ...
@@ -1232,19 +1217,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesSetgid(c *check.C) {
1232 1232
 	ensureSyscallTest(c)
1233 1233
 
1234 1234
 	// test that a root user has default capability CAP_SETGID
1235
-	runCmd := exec.Command(dockerBinary, "run", "syscall-test", "setgid-test")
1236
-	_, _, err := runCommandWithOutput(runCmd)
1237
-	c.Assert(err, check.IsNil)
1235
+	dockerCmd("run", "syscall-test", "setgid-test")
1238 1236
 	// test that non root user does not have default capability CAP_SETGID
1239
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setgid-test")
1240
-	out, _, err := runCommandWithOutput(runCmd)
1241
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1242
-	c.Assert(out, checker.Contains, "Operation not permitted")
1237
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "setgid-test").Assert(c, icmd.Expected{
1238
+		ExitCode: 1,
1239
+		Err: "Operation not permitted",
1240
+	})
1243 1241
 	// test that root user can drop default capability CAP_SETGID
1244
-	runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "setgid", "syscall-test", "setgid-test")
1245
-	out, _, err = runCommandWithOutput(runCmd)
1246
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1247
-	c.Assert(out, checker.Contains, "Operation not permitted")
1242
+	icmd.RunCommand(dockerBinary, "run", "--cap-drop", "setgid", "syscall-test", "setgid-test").Assert(c, icmd.Expected{
1243
+		ExitCode: 1,
1244
+		Err: "Operation not permitted",
1245
+	})
1248 1246
 }
1249 1247
 
1250 1248
 // TODO CAP_SETPCAP
... ...
@@ -1254,19 +1237,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesNetBindService(c *check.C)
1254 1254
 	ensureSyscallTest(c)
1255 1255
 
1256 1256
 	// test that a root user has default capability CAP_NET_BIND_SERVICE
1257
-	runCmd := exec.Command(dockerBinary, "run", "syscall-test", "socket-test")
1258
-	_, _, err := runCommandWithOutput(runCmd)
1259
-	c.Assert(err, check.IsNil)
1257
+	dockerCmd("run", "syscall-test", "socket-test")
1260 1258
 	// test that non root user does not have default capability CAP_NET_BIND_SERVICE
1261
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "socket-test")
1262
-	out, _, err := runCommandWithOutput(runCmd)
1263
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1264
-	c.Assert(out, checker.Contains, "Permission denied")
1259
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "socket-test").Assert(c, icmd.Expected{
1260
+		ExitCode: 1,
1261
+		Err: "Permission denied",
1262
+	})
1265 1263
 	// test that root user can drop default capability CAP_NET_BIND_SERVICE
1266
-	runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "net_bind_service", "syscall-test", "socket-test")
1267
-	out, _, err = runCommandWithOutput(runCmd)
1268
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1269
-	c.Assert(out, checker.Contains, "Permission denied")
1264
+	icmd.RunCommand(dockerBinary, "run", "--cap-drop", "net_bind_service", "syscall-test", "socket-test").Assert(c, icmd.Expected{
1265
+		ExitCode: 1,
1266
+		Err: "Permission denied",
1267
+	})
1270 1268
 }
1271 1269
 
1272 1270
 func (s *DockerSuite) TestUserNoEffectiveCapabilitiesNetRaw(c *check.C) {
... ...
@@ -1274,19 +1255,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesNetRaw(c *check.C) {
1274 1274
 	ensureSyscallTest(c)
1275 1275
 
1276 1276
 	// test that a root user has default capability CAP_NET_RAW
1277
-	runCmd := exec.Command(dockerBinary, "run", "syscall-test", "raw-test")
1278
-	_, _, err := runCommandWithOutput(runCmd)
1279
-	c.Assert(err, check.IsNil)
1277
+	dockerCmd("run", "syscall-test", "raw-test")
1280 1278
 	// test that non root user does not have default capability CAP_NET_RAW
1281
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "raw-test")
1282
-	out, _, err := runCommandWithOutput(runCmd)
1283
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1284
-	c.Assert(out, checker.Contains, "Operation not permitted")
1279
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "syscall-test", "raw-test").Assert(c, icmd.Expected{
1280
+		ExitCode: 1,
1281
+		Err: "Operation not permitted",
1282
+	})
1285 1283
 	// test that root user can drop default capability CAP_NET_RAW
1286
-	runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "net_raw", "syscall-test", "raw-test")
1287
-	out, _, err = runCommandWithOutput(runCmd)
1288
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1289
-	c.Assert(out, checker.Contains, "Operation not permitted")
1284
+	icmd.RunCommand(dockerBinary, "run", "--cap-drop", "net_raw", "syscall-test", "raw-test").Assert(c, icmd.Expected{
1285
+		ExitCode: 1,
1286
+		Err: "Operation not permitted",
1287
+	})
1290 1288
 }
1291 1289
 
1292 1290
 func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChroot(c *check.C) {
... ...
@@ -1294,19 +1273,17 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesChroot(c *check.C) {
1294 1294
 	ensureSyscallTest(c)
1295 1295
 
1296 1296
 	// test that a root user has default capability CAP_SYS_CHROOT
1297
-	runCmd := exec.Command(dockerBinary, "run", "busybox", "chroot", "/", "/bin/true")
1298
-	_, _, err := runCommandWithOutput(runCmd)
1299
-	c.Assert(err, check.IsNil)
1297
+	dockerCmd("run", "busybox", "chroot", "/", "/bin/true")
1300 1298
 	// test that non root user does not have default capability CAP_SYS_CHROOT
1301
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "chroot", "/", "/bin/true")
1302
-	out, _, err := runCommandWithOutput(runCmd)
1303
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1304
-	c.Assert(out, checker.Contains, "Operation not permitted")
1299
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "chroot", "/", "/bin/true").Assert(c, icmd.Expected{
1300
+		ExitCode: 1,
1301
+		Err: "Operation not permitted",
1302
+	})
1305 1303
 	// test that root user can drop default capability CAP_SYS_CHROOT
1306
-	runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "sys_chroot", "busybox", "chroot", "/", "/bin/true")
1307
-	out, _, err = runCommandWithOutput(runCmd)
1308
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1309
-	c.Assert(out, checker.Contains, "Operation not permitted")
1304
+	icmd.RunCommand(dockerBinary, "run", "--cap-drop", "sys_chroot", "busybox", "chroot", "/", "/bin/true").Assert(c, icmd.Expected{
1305
+		ExitCode: 1,
1306
+		Err: "Operation not permitted",
1307
+	})
1310 1308
 }
1311 1309
 
1312 1310
 func (s *DockerSuite) TestUserNoEffectiveCapabilitiesMknod(c *check.C) {
... ...
@@ -1314,19 +1291,18 @@ func (s *DockerSuite) TestUserNoEffectiveCapabilitiesMknod(c *check.C) {
1314 1314
 	ensureSyscallTest(c)
1315 1315
 
1316 1316
 	// test that a root user has default capability CAP_MKNOD
1317
-	runCmd := exec.Command(dockerBinary, "run", "busybox", "mknod", "/tmp/node", "b", "1", "2")
1318
-	_, _, err := runCommandWithOutput(runCmd)
1319
-	c.Assert(err, check.IsNil)
1317
+	dockerCmd("run", "busybox", "mknod", "/tmp/node", "b", "1", "2")
1320 1318
 	// test that non root user does not have default capability CAP_MKNOD
1321
-	runCmd = exec.Command(dockerBinary, "run", "--user", "1000:1000", "busybox", "mknod", "/tmp/node", "b", "1", "2")
1322
-	out, _, err := runCommandWithOutput(runCmd)
1323
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1324
-	c.Assert(out, checker.Contains, "Operation not permitted")
1319
+	// test that root user can drop default capability CAP_SYS_CHROOT
1320
+	icmd.RunCommand(dockerBinary, "run", "--user", "1000:1000", "busybox", "mknod", "/tmp/node", "b", "1", "2").Assert(c, icmd.Expected{
1321
+		ExitCode: 1,
1322
+		Err: "Operation not permitted",
1323
+	})
1325 1324
 	// test that root user can drop default capability CAP_MKNOD
1326
-	runCmd = exec.Command(dockerBinary, "run", "--cap-drop", "mknod", "busybox", "mknod", "/tmp/node", "b", "1", "2")
1327
-	out, _, err = runCommandWithOutput(runCmd)
1328
-	c.Assert(err, checker.NotNil, check.Commentf(out))
1329
-	c.Assert(out, checker.Contains, "Operation not permitted")
1325
+	icmd.RunCommand(dockerBinary, "run", "--cap-drop", "mknod", "busybox", "mknod", "/tmp/node", "b", "1", "2").Assert(c, icmd.Expected{
1326
+		ExitCode: 1,
1327
+		Err: "Operation not permitted",
1328
+	})
1330 1329
 }
1331 1330
 
1332 1331
 // TODO CAP_AUDIT_WRITE
... ...
@@ -1336,14 +1312,16 @@ func (s *DockerSuite) TestRunApparmorProcDirectory(c *check.C) {
1336 1336
 	testRequires(c, SameHostDaemon, Apparmor)
1337 1337
 
1338 1338
 	// running w seccomp unconfined tests the apparmor profile
1339
-	runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/cgroup")
1340
-	if out, _, err := runCommandWithOutput(runCmd); err == nil || !(strings.Contains(out, "Permission denied") || strings.Contains(out, "Operation not permitted")) {
1341
-		c.Fatalf("expected chmod 777 /proc/1/cgroup to fail, got %s: %v", out, err)
1339
+	result := icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/cgroup")
1340
+	result.Assert(c, icmd.Expected{ExitCode: 1})
1341
+	if !(strings.Contains(result.Combined(), "Permission denied") || strings.Contains(result.Combined(), "Operation not permitted")) {
1342
+		c.Fatalf("expected chmod 777 /proc/1/cgroup to fail, got %s: %v", result.Combined(), err)
1342 1343
 	}
1343 1344
 
1344
-	runCmd = exec.Command(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/attr/current")
1345
-	if out, _, err := runCommandWithOutput(runCmd); err == nil || !(strings.Contains(out, "Permission denied") || strings.Contains(out, "Operation not permitted")) {
1346
-		c.Fatalf("expected chmod 777 /proc/1/attr/current to fail, got %s: %v", out, err)
1345
+	result = icmd.RunCommand(dockerBinary, "run", "--security-opt", "seccomp=unconfined", "busybox", "chmod", "777", "/proc/1/attr/current")
1346
+	result.Assert(c, icmd.Expected{ExitCode: 1})
1347
+	if !(strings.Contains(result.Combined(), "Permission denied") || strings.Contains(result.Combined(), "Operation not permitted")) {
1348
+		c.Fatalf("expected chmod 777 /proc/1/attr/current to fail, got %s: %v", result.Combined(), err)
1347 1349
 	}
1348 1350
 }
1349 1351
 
... ...
@@ -226,11 +226,11 @@ func (s *DockerSuite) TestVolumeCLIRm(c *check.C) {
226 226
 
227 227
 	volumeID := "testing"
228 228
 	dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar")
229
-	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "volume", "rm", "testing"))
230
-	c.Assert(
231
-		err,
232
-		check.Not(check.IsNil),
233
-		check.Commentf("Should not be able to remove volume that is in use by a container\n%s", out))
229
+
230
+	icmd.RunCommand(dockerBinary, "volume", "rm", "testing").Assert(c, icmd.Expected{
231
+		ExitCode: 1,
232
+		Error: "exit status 1",
233
+	})
234 234
 
235 235
 	out, _ = dockerCmd(c, "run", "--volumes-from=test", "--name=test2", "busybox", "sh", "-c", "cat /foo/bar")
236 236
 	c.Assert(strings.TrimSpace(out), check.Equals, "hello")
... ...
@@ -401,8 +401,7 @@ func (s *DockerSuite) TestVolumeCLIRmForce(c *check.C) {
401 401
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
402 402
 	// Mountpoint is in the form of "/var/lib/docker/volumes/.../_data", removing `/_data`
403 403
 	path := strings.TrimSuffix(strings.TrimSpace(out), "/_data")
404
-	out, _, err := runCommandWithOutput(exec.Command("rm", "-rf", path))
405
-	c.Assert(err, check.IsNil)
404
+	icmd.RunCommand("rm", "-rf", path).Assert(c, icmd.Success)
406 405
 
407 406
 	dockerCmd(c, "volume", "rm", "-f", "test")
408 407
 	out, _ = dockerCmd(c, "volume", "ls")
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"strings"
7 7
 	"time"
8 8
 
9
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
9 10
 	"github.com/docker/docker/integration-cli/checker"
10 11
 	"github.com/go-check/check"
11 12
 )
... ...
@@ -36,7 +37,7 @@ func (s *DockerSuite) TestWaitBlockedExitZero(c *check.C) {
36 36
 	chWait := make(chan string)
37 37
 	go func() {
38 38
 		chWait <- ""
39
-		out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "wait", containerID))
39
+		out := icmd.RunCommand(dockerBinary, "wait", containerID).Combined()
40 40
 		chWait <- out
41 41
 	}()
42 42
 
... ...
@@ -3,7 +3,6 @@
3 3
 package main
4 4
 
5 5
 import (
6
-	"os/exec"
7 6
 	"strings"
8 7
 	"time"
9 8
 
... ...
@@ -48,8 +47,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) {
48 48
 	// master dummy interface 'dm' abbreviation represents 'docker macvlan'
49 49
 	master := "dm-dummy0"
50 50
 	// simulate the master link the vlan tagged subinterface parent link will use
51
-	out, err := createMasterDummy(c, master)
52
-	c.Assert(err, check.IsNil, check.Commentf(out))
51
+	createMasterDummy(c, master)
53 52
 	// create a network specifying the desired sub-interface name
54 53
 	dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.60", "dm-persist")
55 54
 	assertNwIsAvailable(c, "dm-persist")
... ...
@@ -67,8 +65,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) {
67 67
 	// master dummy interface 'di' notation represent 'docker ipvlan'
68 68
 	master := "di-dummy0"
69 69
 	// simulate the master link the vlan tagged subinterface parent link will use
70
-	out, err := createMasterDummy(c, master)
71
-	c.Assert(err, check.IsNil, check.Commentf(out))
70
+	createMasterDummy(c, master)
72 71
 	// create a network specifying the desired sub-interface name
73 72
 	dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.70", "di-persist")
74 73
 	assertNwIsAvailable(c, "di-persist")
... ...
@@ -86,8 +83,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) {
86 86
 	// master dummy interface 'dm' abbreviation represents 'docker macvlan'
87 87
 	master := "dm-dummy0"
88 88
 	// simulate the master link the vlan tagged subinterface parent link will use
89
-	out, err := createMasterDummy(c, master)
90
-	c.Assert(err, check.IsNil, check.Commentf(out))
89
+	createMasterDummy(c, master)
91 90
 	// create a network specifying the desired sub-interface name
92 91
 	dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.50", "dm-subinterface")
93 92
 	assertNwIsAvailable(c, "dm-subinterface")
... ...
@@ -101,8 +97,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) {
101 101
 	// master dummy interface 'dm' abbreviation represents 'docker ipvlan'
102 102
 	master := "di-dummy0"
103 103
 	// simulate the master link the vlan tagged subinterface parent link will use
104
-	out, err := createMasterDummy(c, master)
105
-	c.Assert(err, check.IsNil, check.Commentf(out))
104
+	createMasterDummy(c, master)
106 105
 	// create a network specifying the desired sub-interface name
107 106
 	dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.60", "di-subinterface")
108 107
 	assertNwIsAvailable(c, "di-subinterface")
... ...
@@ -115,17 +110,15 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) {
115 115
 	testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
116 116
 	// master dummy interface 'dm' abbreviation represents 'docker macvlan'
117 117
 	master := "dm-dummy0"
118
-	out, err := createMasterDummy(c, master)
119
-	c.Assert(err, check.IsNil, check.Commentf(out))
120
-	out, err = createVlanInterface(c, master, "dm-dummy0.40", "40")
121
-	c.Assert(err, check.IsNil, check.Commentf(out))
118
+	createMasterDummy(c, master)
119
+	createVlanInterface(c, master, "dm-dummy0.40", "40")
122 120
 	// create a network using an existing parent interface
123 121
 	dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-subinterface")
124 122
 	assertNwIsAvailable(c, "dm-subinterface")
125 123
 	// attempt to create another network using the same parent iface that should fail
126
-	out, _, err = dockerCmdWithError("network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-parent-net-overlap")
124
+	out, _, err := dockerCmdWithError("network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-parent-net-overlap")
127 125
 	// verify that the overlap returns an error
128
-	c.Assert(err, check.NotNil)
126
+	c.Assert(err, check.NotNil, check.Commentf(out))
129 127
 	// cleanup the master interface which also collects the slave dev
130 128
 	deleteInterface(c, "dm-dummy0")
131 129
 }
... ...
@@ -135,17 +128,15 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) {
135 135
 	testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
136 136
 	// master dummy interface 'dm' abbreviation represents 'docker ipvlan'
137 137
 	master := "di-dummy0"
138
-	out, err := createMasterDummy(c, master)
139
-	c.Assert(err, check.IsNil, check.Commentf(out))
140
-	out, err = createVlanInterface(c, master, "di-dummy0.30", "30")
141
-	c.Assert(err, check.IsNil, check.Commentf(out))
138
+	createMasterDummy(c, master)
139
+	createVlanInterface(c, master, "di-dummy0.30", "30")
142 140
 	// create a network using an existing parent interface
143 141
 	dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-subinterface")
144 142
 	assertNwIsAvailable(c, "di-subinterface")
145 143
 	// attempt to create another network using the same parent iface that should fail
146
-	out, _, err = dockerCmdWithError("network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-parent-net-overlap")
144
+	out, _, err := dockerCmdWithError("network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-parent-net-overlap")
147 145
 	// verify that the overlap returns an error
148
-	c.Assert(err, check.NotNil)
146
+	c.Assert(err, check.NotNil, check.Commentf(out))
149 147
 	// cleanup the master interface which also collects the slave dev
150 148
 	deleteInterface(c, "di-dummy0")
151 149
 }
... ...
@@ -488,9 +479,8 @@ func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
488 488
 	// macvlan bridge mode - empty parent interface containers can reach each other internally but not externally
489 489
 	testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
490 490
 	netName := "dm-parent-exists"
491
-	out, err := createMasterDummy(c, "dm-dummy0")
491
+	createMasterDummy(c, "dm-dummy0")
492 492
 	//out, err := createVlanInterface(c, "dm-parent", "dm-slave", "macvlan", "bridge")
493
-	c.Assert(err, check.IsNil, check.Commentf(out))
494 493
 	// create a network using an existing parent interface
495 494
 	dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0", netName)
496 495
 	assertNwIsAvailable(c, netName)
... ...
@@ -498,20 +488,16 @@ func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
498 498
 	dockerCmd(c, "network", "rm", netName)
499 499
 	assertNwNotAvailable(c, netName)
500 500
 	// verify the network delete did not delete the predefined link
501
-	out, err = linkExists(c, "dm-dummy0")
502
-	c.Assert(err, check.IsNil, check.Commentf(out))
501
+	linkExists(c, "dm-dummy0")
503 502
 	deleteInterface(c, "dm-dummy0")
504
-	c.Assert(err, check.IsNil, check.Commentf(out))
505 503
 }
506 504
 
507 505
 func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
508 506
 	// macvlan bridge mode -  empty parent interface containers can reach each other internally but not externally
509 507
 	testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
510 508
 	netName := "dm-subinterface"
511
-	out, err := createMasterDummy(c, "dm-dummy0")
512
-	c.Assert(err, check.IsNil, check.Commentf(out))
513
-	out, err = createVlanInterface(c, "dm-dummy0", "dm-dummy0.20", "20")
514
-	c.Assert(err, check.IsNil, check.Commentf(out))
509
+	createMasterDummy(c, "dm-dummy0")
510
+	createVlanInterface(c, "dm-dummy0", "dm-dummy0.20", "20")
515 511
 	// create a network using an existing parent interface
516 512
 	dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.20", netName)
517 513
 	assertNwIsAvailable(c, netName)
... ...
@@ -522,7 +508,7 @@ func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
522 522
 	dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=second", "busybox", "top")
523 523
 	c.Assert(waitRun("second"), check.IsNil)
524 524
 	// verify containers can communicate
525
-	_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
525
+	_, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
526 526
 	c.Assert(err, check.IsNil)
527 527
 
528 528
 	// remove the containers
... ...
@@ -532,56 +518,25 @@ func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
532 532
 	dockerCmd(c, "network", "rm", netName)
533 533
 	assertNwNotAvailable(c, netName)
534 534
 	// verify the network delete did not delete the predefined sub-interface
535
-	out, err = linkExists(c, "dm-dummy0.20")
536
-	c.Assert(err, check.IsNil, check.Commentf(out))
535
+	linkExists(c, "dm-dummy0.20")
537 536
 	// delete the parent interface which also collects the slave
538 537
 	deleteInterface(c, "dm-dummy0")
539
-	c.Assert(err, check.IsNil, check.Commentf(out))
540 538
 }
541 539
 
542
-func createMasterDummy(c *check.C, master string) (string, error) {
540
+func createMasterDummy(c *check.C, master string) {
543 541
 	// ip link add <dummy_name> type dummy
544
-	args := []string{"link", "add", master, "type", "dummy"}
545
-	ipLinkCmd := exec.Command("ip", args...)
546
-	out, _, err := runCommandWithOutput(ipLinkCmd)
547
-	if err != nil {
548
-		return out, err
549
-	}
550
-	// ip link set dummy_name up
551
-	args = []string{"link", "set", master, "up"}
552
-	ipLinkCmd = exec.Command("ip", args...)
553
-	out, _, err = runCommandWithOutput(ipLinkCmd)
554
-	if err != nil {
555
-		return out, err
556
-	}
557
-	return out, err
542
+	icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(c, icmd.Success)
543
+	icmd.RunCommand("ip", "link", "set", master, "up").Assert(c, icmd.Success)
558 544
 }
559 545
 
560
-func createVlanInterface(c *check.C, master, slave, id string) (string, error) {
546
+func createVlanInterface(c *check.C, master, slave, id string) {
561 547
 	// ip link add link <master> name <master>.<VID> type vlan id <VID>
562
-	args := []string{"link", "add", "link", master, "name", slave, "type", "vlan", "id", id}
563
-	ipLinkCmd := exec.Command("ip", args...)
564
-	out, _, err := runCommandWithOutput(ipLinkCmd)
565
-	if err != nil {
566
-		return out, err
567
-	}
548
+	icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(c, icmd.Success)
568 549
 	// ip link set <sub_interface_name> up
569
-	args = []string{"link", "set", slave, "up"}
570
-	ipLinkCmd = exec.Command("ip", args...)
571
-	out, _, err = runCommandWithOutput(ipLinkCmd)
572
-	if err != nil {
573
-		return out, err
574
-	}
575
-	return out, err
550
+	icmd.RunCommand("ip", "link", "set", slave, "up").Assert(c, icmd.Success)
576 551
 }
577 552
 
578
-func linkExists(c *check.C, master string) (string, error) {
553
+func linkExists(c *check.C, master string) {
579 554
 	// verify the specified link exists, ip link show <link_name>
580
-	args := []string{"link", "show", master}
581
-	ipLinkCmd := exec.Command("ip", args...)
582
-	out, _, err := runCommandWithOutput(ipLinkCmd)
583
-	if err != nil {
584
-		return out, err
585
-	}
586
-	return out, err
555
+	icmd.RunCommand("ip", "link", "show", master).Assert(c, icmd.Success)
587 556
 }
... ...
@@ -818,10 +818,12 @@ func buildImageFromContextWithOut(name string, ctx *FakeContext, useCache bool,
818 818
 	}
819 819
 	args = append(args, buildFlags...)
820 820
 	args = append(args, ".")
821
-	buildCmd := exec.Command(dockerBinary, args...)
822
-	buildCmd.Dir = ctx.Dir
823
-	out, exitCode, err := runCommandWithOutput(buildCmd)
824
-	if err != nil || exitCode != 0 {
821
+	result := icmd.RunCmd(icmd.Cmd{
822
+		Command: append([]string{dockerBinary}, args...),
823
+		Dir:     ctx.Dir,
824
+	})
825
+	out := result.Combined()
826
+	if result.Error != nil || result.ExitCode != 0 {
825 827
 		return "", "", fmt.Errorf("failed to build the image: %s", out)
826 828
 	}
827 829
 	id, err := getIDByName(name)