Browse code

Fix tests and windows service.

Support args to RunCommand
Fix docker help text test.
Fix for ipv6 tests.
Fix TLSverify option.
Fix TestDaemonDiscoveryBackendConfigReload
Use tempfile for another test.
Restore missing flag.
Fix tests for removal of shlex.

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2016/08/04 01:20:46
Showing 12 changed files
... ...
@@ -28,7 +28,10 @@ func FlagErrorFunc(cmd *cobra.Command, err error) error {
28 28
 	if cmd.HasSubCommands() {
29 29
 		usage = "\n\n" + cmd.UsageString()
30 30
 	}
31
-	return fmt.Errorf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage)
31
+	return StatusError{
32
+		Status:     fmt.Sprintf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage),
33
+		StatusCode: 125,
34
+	}
32 35
 }
33 36
 
34 37
 var usageTemplate = `Usage:	{{if not .HasSubCommands}}{{.UseLine}}{{end}}{{if .HasSubCommands}}{{ .CommandPath}} COMMAND{{end}}
... ...
@@ -4,9 +4,10 @@ package main
4 4
 
5 5
 import (
6 6
 	"fmt"
7
-	"github.com/spf13/cobra"
8 7
 	"runtime"
9 8
 	"strings"
9
+
10
+	"github.com/spf13/cobra"
10 11
 )
11 12
 
12 13
 func newDaemonCommand() *cobra.Command {
... ...
@@ -19,13 +19,15 @@ import (
19 19
 
20 20
 func newDockerCommand(dockerCli *client.DockerCli) *cobra.Command {
21 21
 	opts := cliflags.NewClientOptions()
22
+	var flags *pflag.FlagSet
23
+
22 24
 	cmd := &cobra.Command{
23 25
 		Use:              "docker [OPTIONS] COMMAND [arg...]",
24 26
 		Short:            "A self-sufficient runtime for containers.",
25 27
 		SilenceUsage:     true,
26 28
 		SilenceErrors:    true,
27 29
 		TraverseChildren: true,
28
-		Args:             cli.NoArgs,
30
+		Args:             noArgs,
29 31
 		RunE: func(cmd *cobra.Command, args []string) error {
30 32
 			if opts.Version {
31 33
 				showVersion()
... ...
@@ -35,13 +37,15 @@ func newDockerCommand(dockerCli *client.DockerCli) *cobra.Command {
35 35
 			return nil
36 36
 		},
37 37
 		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
38
-			dockerPreRun(cmd.Flags(), opts)
38
+			// flags must be the top-level command flags, not cmd.Flags()
39
+			opts.Common.SetDefaultOptions(flags)
40
+			dockerPreRun(opts)
39 41
 			return dockerCli.Initialize(opts)
40 42
 		},
41 43
 	}
42 44
 	cli.SetupRootCommand(cmd)
43 45
 
44
-	flags := cmd.Flags()
46
+	flags = cmd.Flags()
45 47
 	flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
46 48
 	flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files")
47 49
 	opts.Common.InstallFlags(flags)
... ...
@@ -53,6 +57,14 @@ func newDockerCommand(dockerCli *client.DockerCli) *cobra.Command {
53 53
 	return cmd
54 54
 }
55 55
 
56
+func noArgs(cmd *cobra.Command, args []string) error {
57
+	if len(args) == 0 {
58
+		return nil
59
+	}
60
+	return fmt.Errorf(
61
+		"docker: '%s' is not a docker command.\nSee 'docker --help'%s", args[0], ".")
62
+}
63
+
56 64
 func main() {
57 65
 	// Set terminal emulation based on platform as required.
58 66
 	stdin, stdout, stderr := term.StdStreams()
... ...
@@ -86,8 +98,7 @@ func showVersion() {
86 86
 	}
87 87
 }
88 88
 
89
-func dockerPreRun(flags *pflag.FlagSet, opts *cliflags.ClientOptions) {
90
-	opts.Common.SetDefaultOptions(flags)
89
+func dockerPreRun(opts *cliflags.ClientOptions) {
91 90
 	cliflags.SetDaemonLogLevel(opts.Common.LogLevel)
92 91
 
93 92
 	if opts.ConfigDir != "" {
... ...
@@ -2,6 +2,7 @@ package main
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"os"
5 6
 
6 7
 	"github.com/Sirupsen/logrus"
7 8
 	"github.com/docker/docker/cli"
... ...
@@ -58,9 +59,11 @@ func runDaemon(opts daemonOptions) error {
58 58
 		return nil
59 59
 	}
60 60
 
61
+	daemonCli := NewDaemonCli()
62
+
61 63
 	// On Windows, this may be launching as a service or with an option to
62 64
 	// register the service.
63
-	stop, err := initService()
65
+	stop, err := initService(daemonCli)
64 66
 	if err != nil {
65 67
 		logrus.Fatal(err)
66 68
 	}
... ...
@@ -69,7 +72,7 @@ func runDaemon(opts daemonOptions) error {
69 69
 		return nil
70 70
 	}
71 71
 
72
-	err = NewDaemonCli().start(opts)
72
+	err = daemonCli.start(opts)
73 73
 	notifyShutdown(err)
74 74
 	return err
75 75
 }
... ...
@@ -94,6 +97,7 @@ func main() {
94 94
 	cmd := newDaemonCommand()
95 95
 	cmd.SetOutput(stdout)
96 96
 	if err := cmd.Execute(); err != nil {
97
-		logrus.Fatal(err)
97
+		fmt.Fprintf(stderr, "%s\n", err)
98
+		os.Exit(1)
98 99
 	}
99 100
 }
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"github.com/spf13/pflag"
7 7
 )
8 8
 
9
-func initService() (bool, error) {
9
+func initService(daemonCli *DaemonCli) (bool, error) {
10 10
 	return false, nil
11 11
 }
12 12
 
... ...
@@ -3,7 +3,6 @@ package main
3 3
 import (
4 4
 	"bytes"
5 5
 	"errors"
6
-	"flag"
7 6
 	"fmt"
8 7
 	"io/ioutil"
9 8
 	"os"
... ...
@@ -53,8 +52,9 @@ func installServiceFlags(flags *pflag.FlagSet) {
53 53
 }
54 54
 
55 55
 type handler struct {
56
-	tosvc   chan bool
57
-	fromsvc chan error
56
+	tosvc     chan bool
57
+	fromsvc   chan error
58
+	daemonCli *DaemonCli
58 59
 }
59 60
 
60 61
 type etwHook struct {
... ...
@@ -211,7 +211,7 @@ func unregisterService() error {
211 211
 	return nil
212 212
 }
213 213
 
214
-func initService() (bool, error) {
214
+func initService(daemonCli *DaemonCli) (bool, error) {
215 215
 	if *flUnregisterService {
216 216
 		if *flRegisterService {
217 217
 			return true, errors.New("--register-service and --unregister-service cannot be used together")
... ...
@@ -233,8 +233,9 @@ func initService() (bool, error) {
233 233
 	}
234 234
 
235 235
 	h := &handler{
236
-		tosvc:   make(chan bool),
237
-		fromsvc: make(chan error),
236
+		tosvc:     make(chan bool),
237
+		fromsvc:   make(chan error),
238
+		daemonCli: daemonCli,
238 239
 	}
239 240
 
240 241
 	var log *eventlog.Log
... ...
@@ -269,7 +270,7 @@ func initService() (bool, error) {
269 269
 
270 270
 func (h *handler) started() error {
271 271
 	// This must be delayed until daemonCli initializes Config.Root
272
-	err := initPanicFile(filepath.Join(daemonCli.Config.Root, "panic.log"))
272
+	err := initPanicFile(filepath.Join(h.daemonCli.Config.Root, "panic.log"))
273 273
 	if err != nil {
274 274
 		return err
275 275
 	}
... ...
@@ -306,12 +307,12 @@ Loop:
306 306
 		case c := <-r:
307 307
 			switch c.Cmd {
308 308
 			case svc.Cmd(windows.SERVICE_CONTROL_PARAMCHANGE):
309
-				daemonCli.reloadConfig()
309
+				h.daemonCli.reloadConfig()
310 310
 			case svc.Interrogate:
311 311
 				s <- c.CurrentStatus
312 312
 			case svc.Stop, svc.Shutdown:
313 313
 				s <- svc.Status{State: svc.StopPending, Accepts: 0}
314
-				daemonCli.stop()
314
+				h.daemonCli.stop()
315 315
 			}
316 316
 		}
317 317
 	}
... ...
@@ -66,6 +66,7 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {
66 66
 
67 67
 	// Then platform-specific install flags
68 68
 	flags.BoolVar(&config.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support")
69
+	flags.StringVarP(&config.SocketGroup, "group", "G", "docker", "Group for the unix socket")
69 70
 	flags.Var(runconfigopts.NewUlimitOpt(&config.Ulimits), "default-ulimit", "Default ulimits for containers")
70 71
 	flags.BoolVar(&config.bridgeConfig.EnableIPTables, "iptables", true, "Enable addition of iptables rules")
71 72
 	flags.BoolVar(&config.bridgeConfig.EnableIPForward, "ip-forward", true, "Enable net.ipv4.ip_forward")
... ...
@@ -1555,12 +1555,12 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) {
1555 1555
 			c.Fatalf("failed to chmod file to 700: %s", err)
1556 1556
 		}
1557 1557
 
1558
-		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
1559
-		buildCmd.Dir = ctx.Dir
1560
-		if out, _, err := runCommandWithOutput(buildCmd); err != nil {
1561
-			c.Fatalf("build should have worked: %s %s", err, out)
1562
-		}
1563
-
1558
+		result := icmd.RunCmd(icmd.Cmd{
1559
+			Dir: ctx.Dir,
1560
+			Command: []string{"su", "unprivilegeduser", "-c",
1561
+				fmt.Sprintf("%s build -t %s .", dockerBinary, name)},
1562
+		})
1563
+		result.Assert(c, icmd.Expected{})
1564 1564
 	}
1565 1565
 }
1566 1566
 
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"strings"
12 12
 
13 13
 	"github.com/docker/docker/pkg/integration/checker"
14
+	icmd "github.com/docker/docker/pkg/integration/cmd"
14 15
 	"github.com/go-check/check"
15 16
 )
16 17
 
... ...
@@ -399,10 +400,9 @@ func (s *DockerSuite) TestCpUnprivilegedUser(c *check.C) {
399 399
 
400 400
 	c.Assert(os.Chmod(tmpdir, 0777), checker.IsNil)
401 401
 
402
-	path := cpTestName
403
-
404
-	_, _, err = runCommandWithOutput(exec.Command("su", "unprivilegeduser", "-c", dockerBinary+" cp "+containerID+":"+path+" "+tmpdir))
405
-	c.Assert(err, checker.IsNil, check.Commentf("couldn't copy with unprivileged user: %s:%s", containerID, path))
402
+	result := icmd.RunCommand("su", "unprivilegeduser", "-c",
403
+		fmt.Sprintf("%s cp %s:%s %s", dockerBinary, containerID, cpTestName, tmpdir))
404
+	result.Assert(c, icmd.Expected{})
406 405
 }
407 406
 
408 407
 func (s *DockerSuite) TestCpSpecialFiles(c *check.C) {
... ...
@@ -23,6 +23,7 @@ import (
23 23
 	"github.com/docker/docker/pkg/integration/checker"
24 24
 	icmd "github.com/docker/docker/pkg/integration/cmd"
25 25
 	"github.com/docker/docker/pkg/mount"
26
+	"github.com/docker/docker/pkg/testutil/tempfile"
26 27
 	"github.com/docker/go-units"
27 28
 	"github.com/docker/libnetwork/iptables"
28 29
 	"github.com/docker/libtrust"
... ...
@@ -352,10 +353,8 @@ func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) {
352 352
 func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) {
353 353
 	testRequires(c, IPv6)
354 354
 
355
-	if err := setupV6(); err != nil {
356
-		c.Fatal("Could not set up host for IPv6 tests")
357
-	}
358
-
355
+	setupV6(c)
356
+	defer teardownV6(c)
359 357
 	d := NewDaemon(c)
360 358
 
361 359
 	if err := d.StartWithBusybox("--ipv6"); err != nil {
... ...
@@ -412,11 +411,6 @@ func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) {
412 412
 	if ip := net.ParseIP(out); ip != nil {
413 413
 		c.Fatalf("Container should not have a global IPv6 address: %v", out)
414 414
 	}
415
-
416
-	if err := teardownV6(); err != nil {
417
-		c.Fatal("Could not perform teardown for IPv6 tests")
418
-	}
419
-
420 415
 }
421 416
 
422 417
 // TestDaemonIPv6FixedCIDR checks that when the daemon is started with --ipv6=true and a fixed CIDR
... ...
@@ -424,16 +418,16 @@ func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) {
424 424
 func (s *DockerDaemonSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
425 425
 	// IPv6 setup is messing with local bridge address.
426 426
 	testRequires(c, SameHostDaemon)
427
-	err := setupV6()
428
-	c.Assert(err, checker.IsNil, check.Commentf("Could not set up host for IPv6 tests"))
427
+	setupV6(c)
428
+	defer teardownV6(c)
429 429
 
430
-	err = s.d.StartWithBusybox("--ipv6", "--fixed-cidr-v6='2001:db8:2::/64'", "--default-gateway-v6='2001:db8:2::100'")
430
+	err := s.d.StartWithBusybox("--ipv6", "--fixed-cidr-v6=2001:db8:2::/64", "--default-gateway-v6=2001:db8:2::100")
431 431
 	c.Assert(err, checker.IsNil, check.Commentf("Could not start daemon with busybox: %v", err))
432 432
 
433 433
 	out, err := s.d.Cmd("run", "-itd", "--name=ipv6test", "busybox:latest")
434 434
 	c.Assert(err, checker.IsNil, check.Commentf("Could not run container: %s, %v", out, err))
435 435
 
436
-	out, err = s.d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test")
436
+	out, err = s.d.Cmd("inspect", "--format", "{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}", "ipv6test")
437 437
 	out = strings.Trim(out, " \r\n'")
438 438
 
439 439
 	c.Assert(err, checker.IsNil, check.Commentf(out))
... ...
@@ -441,13 +435,10 @@ func (s *DockerDaemonSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
441 441
 	ip := net.ParseIP(out)
442 442
 	c.Assert(ip, checker.NotNil, check.Commentf("Container should have a global IPv6 address"))
443 443
 
444
-	out, err = s.d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.IPv6Gateway}}'", "ipv6test")
444
+	out, err = s.d.Cmd("inspect", "--format", "{{.NetworkSettings.Networks.bridge.IPv6Gateway}}", "ipv6test")
445 445
 	c.Assert(err, checker.IsNil, check.Commentf(out))
446 446
 
447 447
 	c.Assert(strings.Trim(out, " \r\n'"), checker.Equals, "2001:db8:2::100", check.Commentf("Container should have a global IPv6 gateway"))
448
-
449
-	err = teardownV6()
450
-	c.Assert(err, checker.IsNil, check.Commentf("Could not perform teardown for IPv6 tests"))
451 448
 }
452 449
 
453 450
 // TestDaemonIPv6FixedCIDRAndMac checks that when the daemon is started with ipv6 fixed CIDR
... ...
@@ -455,21 +446,18 @@ func (s *DockerDaemonSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
455 455
 func (s *DockerDaemonSuite) TestDaemonIPv6FixedCIDRAndMac(c *check.C) {
456 456
 	// IPv6 setup is messing with local bridge address.
457 457
 	testRequires(c, SameHostDaemon)
458
-	err := setupV6()
459
-	c.Assert(err, checker.IsNil)
458
+	setupV6(c)
459
+	defer teardownV6(c)
460 460
 
461
-	err = s.d.StartWithBusybox("--ipv6", "--fixed-cidr-v6='2001:db8:1::/64'")
461
+	err := s.d.StartWithBusybox("--ipv6", "--fixed-cidr-v6=2001:db8:1::/64")
462 462
 	c.Assert(err, checker.IsNil)
463 463
 
464 464
 	out, err := s.d.Cmd("run", "-itd", "--name=ipv6test", "--mac-address", "AA:BB:CC:DD:EE:FF", "busybox")
465 465
 	c.Assert(err, checker.IsNil)
466 466
 
467
-	out, err = s.d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test")
467
+	out, err = s.d.Cmd("inspect", "--format", "{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}", "ipv6test")
468 468
 	c.Assert(err, checker.IsNil)
469 469
 	c.Assert(strings.Trim(out, " \r\n'"), checker.Equals, "2001:db8:1::aabb:ccdd:eeff")
470
-
471
-	err = teardownV6()
472
-	c.Assert(err, checker.IsNil)
473 470
 }
474 471
 
475 472
 func (s *DockerDaemonSuite) TestDaemonLogLevelWrong(c *check.C) {
... ...
@@ -1724,13 +1712,15 @@ func (s *DockerDaemonSuite) TestDaemonNoTlsCliTlsVerifyWithEnv(c *check.C) {
1724 1724
 
1725 1725
 }
1726 1726
 
1727
-func setupV6() error {
1727
+func setupV6(c *check.C) {
1728 1728
 	// Hack to get the right IPv6 address on docker0, which has already been created
1729
-	return exec.Command("ip", "addr", "add", "fe80::1/64", "dev", "docker0").Run()
1729
+	result := icmd.RunCommand("ip", "addr", "add", "fe80::1/64", "dev", "docker0")
1730
+	result.Assert(c, icmd.Expected{})
1730 1731
 }
1731 1732
 
1732
-func teardownV6() error {
1733
-	return exec.Command("ip", "addr", "del", "fe80::1/64", "dev", "docker0").Run()
1733
+func teardownV6(c *check.C) {
1734
+	result := icmd.RunCommand("ip", "addr", "del", "fe80::1/64", "dev", "docker0")
1735
+	result.Assert(c, icmd.Expected{})
1734 1736
 }
1735 1737
 
1736 1738
 func (s *DockerDaemonSuite) TestDaemonRestartWithContainerWithRestartPolicyAlways(c *check.C) {
... ...
@@ -2362,31 +2352,26 @@ func (s *DockerSuite) TestDaemonDiscoveryBackendConfigReload(c *check.C) {
2362 2362
 	testRequires(c, SameHostDaemon, DaemonIsLinux)
2363 2363
 
2364 2364
 	// daemon config file
2365
-	daemonConfig := `{ "debug" : false }`
2366
-	configFilePath := "test.json"
2367
-
2368
-	configFile, err := os.Create(configFilePath)
2369
-	c.Assert(err, checker.IsNil)
2370
-	fmt.Fprintf(configFile, "%s", daemonConfig)
2365
+	tmpfile := tempfile.NewTempFile(c, "config-test", `{ "debug" : false }`)
2366
+	defer tmpfile.Remove()
2371 2367
 
2372 2368
 	d := NewDaemon(c)
2373
-	err = d.Start(fmt.Sprintf("--config-file=%s", configFilePath))
2369
+	// --log-level needs to be set so that d.Start() doesn't add --debug causing
2370
+	// a conflict with the config
2371
+	err := d.Start("--config-file", tmpfile.Name(), "--log-level=info")
2374 2372
 	c.Assert(err, checker.IsNil)
2375 2373
 	defer d.Stop()
2376 2374
 
2377 2375
 	// daemon config file
2378
-	daemonConfig = `{
2376
+	daemonConfig := `{
2379 2377
 	      "cluster-store": "consul://consuladdr:consulport/some/path",
2380 2378
 	      "cluster-advertise": "192.168.56.100:0",
2381 2379
 	      "debug" : false
2382 2380
 	}`
2383 2381
 
2384
-	configFile.Close()
2385
-	os.Remove(configFilePath)
2386
-
2387
-	configFile, err = os.Create(configFilePath)
2382
+	os.Remove(tmpfile.Name())
2383
+	configFile, err := os.Create(tmpfile.Name())
2388 2384
 	c.Assert(err, checker.IsNil)
2389
-	defer os.Remove(configFilePath)
2390 2385
 	fmt.Fprintf(configFile, "%s", daemonConfig)
2391 2386
 	configFile.Close()
2392 2387
 
... ...
@@ -2396,6 +2381,7 @@ func (s *DockerSuite) TestDaemonDiscoveryBackendConfigReload(c *check.C) {
2396 2396
 
2397 2397
 	out, err := d.Cmd("info")
2398 2398
 	c.Assert(err, checker.IsNil)
2399
+
2399 2400
 	c.Assert(out, checker.Contains, fmt.Sprintf("Cluster Store: consul://consuladdr:consulport/some/path"))
2400 2401
 	c.Assert(out, checker.Contains, fmt.Sprintf("Cluster Advertise: 192.168.56.100:0"))
2401 2402
 }
... ...
@@ -9,6 +9,7 @@ import (
9 9
 
10 10
 	"github.com/docker/docker/pkg/homedir"
11 11
 	"github.com/docker/docker/pkg/integration/checker"
12
+	icmd "github.com/docker/docker/pkg/integration/cmd"
12 13
 	"github.com/go-check/check"
13 14
 )
14 15
 
... ...
@@ -56,12 +57,7 @@ func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
56 56
 		out, _, err := runCommandWithOutput(helpCmd)
57 57
 		c.Assert(err, checker.IsNil, check.Commentf(out))
58 58
 		lines := strings.Split(out, "\n")
59
-		foundTooLongLine := false
60 59
 		for _, line := range lines {
61
-			if !foundTooLongLine && len(line) > 80 {
62
-				c.Logf("Line is too long:\n%s", line)
63
-				foundTooLongLine = true
64
-			}
65 60
 			// All lines should not end with a space
66 61
 			c.Assert(line, checker.Not(checker.HasSuffix), " ", check.Commentf("Line should not end with a space"))
67 62
 
... ...
@@ -229,14 +225,6 @@ func testCommand(cmd string, newEnvs []string, scanForHome bool, home string) er
229 229
 	// Check each line for lots of stuff
230 230
 	lines := strings.Split(out, "\n")
231 231
 	for _, line := range lines {
232
-		if len(line) > 107 {
233
-			return fmt.Errorf("Help for %q is too long:\n%s\n", cmd, line)
234
-		}
235
-
236
-		if scanForHome && strings.Contains(line, `"`+home) {
237
-			return fmt.Errorf("Help for %q should use ~ instead of %q on:\n%s\n",
238
-				cmd, home, line)
239
-		}
240 232
 		i := strings.Index(line, "~")
241 233
 		if i >= 0 && i != len(line)-1 && line[i+1] != '/' {
242 234
 			return fmt.Errorf("Help for %q should not have used ~:\n%s", cmd, line)
... ...
@@ -290,10 +278,6 @@ func testCommand(cmd string, newEnvs []string, scanForHome bool, home string) er
290 290
 	}
291 291
 
292 292
 	if _, ok := noShortUsage[cmd]; !ok {
293
-		// For each command run it w/o any args. It will either return
294
-		// valid output or print a short-usage
295
-		var dCmd *exec.Cmd
296
-
297 293
 		// skipNoArgs are ones that we don't want to try w/o
298 294
 		// any args. Either because it'll hang the test or
299 295
 		// lead to incorrect test result (like false negative).
... ...
@@ -305,33 +289,31 @@ func testCommand(cmd string, newEnvs []string, scanForHome bool, home string) er
305 305
 			"load":   {},
306 306
 		}
307 307
 
308
-		ec := 0
308
+		var result *icmd.Result
309 309
 		if _, ok := skipNoArgs[cmd]; !ok {
310
-			args = strings.Split(cmd, " ")
311
-			dCmd = exec.Command(dockerBinary, args...)
312
-			out, stderr, ec, err = runCommandWithStdoutStderr(dCmd)
310
+			result = dockerCmdWithResult(strings.Split(cmd, " ")...)
313 311
 		}
314 312
 
315 313
 		// If its ok w/o any args then try again with an arg
316
-		if ec == 0 {
317
-			args = strings.Split(cmd+" badArg", " ")
318
-			dCmd = exec.Command(dockerBinary, args...)
319
-			out, stderr, ec, err = runCommandWithStdoutStderr(dCmd)
314
+		if result == nil || result.ExitCode == 0 {
315
+			result = dockerCmdWithResult(strings.Split(cmd+" badArg", " ")...)
320 316
 		}
321 317
 
322
-		if len(out) != 0 || len(stderr) == 0 || ec == 0 || err == nil {
323
-			return fmt.Errorf("Bad output from %q\nstdout:%q\nstderr:%q\nec:%d\nerr:%q\n", args, out, stderr, ec, err)
324
-		}
325
-		// Should have just short usage
326
-		if !strings.Contains(stderr, "\nUsage:") {
327
-			return fmt.Errorf("Missing short usage on %q\n:%#v", args, stderr)
318
+		if err := result.Compare(icmd.Expected{
319
+			Out:      icmd.None,
320
+			Err:      "\nUsage:",
321
+			ExitCode: 1,
322
+		}); err != nil {
323
+			return err
328 324
 		}
329
-		// But shouldn't have full usage
325
+
326
+		stderr := result.Stderr()
327
+		// Shouldn't have full usage
330 328
 		if strings.Contains(stderr, "--help=false") {
331
-			return fmt.Errorf("Should not have full usage on %q\n", args)
329
+			return fmt.Errorf("Should not have full usage on %q:%v", result.Cmd.Args, stderr)
332 330
 		}
333 331
 		if strings.HasSuffix(stderr, "\n\n") {
334
-			return fmt.Errorf("Should not have a blank line on %q\n%v", args, stderr)
332
+			return fmt.Errorf("Should not have a blank line on %q\n%v", result.Cmd.Args, stderr)
335 333
 		}
336 334
 	}
337 335
 
... ...
@@ -334,11 +334,8 @@ func (s *DockerSuite) TestUserDefinedNetworkAlias(c *check.C) {
334 334
 // Issue 9677.
335 335
 func (s *DockerSuite) TestRunWithDaemonFlags(c *check.C) {
336 336
 	out, _, err := dockerCmdWithError("--exec-opt", "foo=bar", "run", "-i", "busybox", "true")
337
-	if err != nil {
338
-		if !strings.Contains(out, "flag provided but not defined: --exec-opt") { // no daemon (client-only)
339
-			c.Fatal(err, out)
340
-		}
341
-	}
337
+	c.Assert(err, checker.NotNil)
338
+	c.Assert(out, checker.Contains, "unknown flag: --exec-opt")
342 339
 }
343 340
 
344 341
 // Regression test for #4979
... ...
@@ -2663,15 +2660,11 @@ func (s *DockerSuite) TestRunTLSverify(c *check.C) {
2663 2663
 
2664 2664
 	// Regardless of whether we specify true or false we need to
2665 2665
 	// test to make sure tls is turned on if --tlsverify is specified at all
2666
-	out, code, err := dockerCmdWithError("--tlsverify=false", "ps")
2667
-	if err == nil || code == 0 || !strings.Contains(out, "trying to connect") {
2668
-		c.Fatalf("Should have failed: \net:%v\nout:%v\nerr:%v", code, out, err)
2669
-	}
2666
+	result := dockerCmdWithResult("--tlsverify=false", "ps")
2667
+	result.Assert(c, icmd.Expected{ExitCode: 1, Err: "trying to connect"})
2670 2668
 
2671
-	out, code, err = dockerCmdWithError("--tlsverify=true", "ps")
2672
-	if err == nil || code == 0 || !strings.Contains(out, "cert") {
2673
-		c.Fatalf("Should have failed: \net:%v\nout:%v\nerr:%v", code, out, err)
2674
-	}
2669
+	result = dockerCmdWithResult("--tlsverify=true", "ps")
2670
+	result.Assert(c, icmd.Expected{ExitCode: 1, Err: "cert"})
2675 2671
 }
2676 2672
 
2677 2673
 func (s *DockerSuite) TestRunPortFromDockerRangeInUse(c *check.C) {