Browse code

Move dockerCmd… to pkg/integration…

… and add some tests on them.

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

Vincent Demeester authored on 2015/09/13 17:41:00
Showing 3 changed files
... ...
@@ -24,6 +24,7 @@ import (
24 24
 	"github.com/docker/docker/api/types"
25 25
 	"github.com/docker/docker/opts"
26 26
 	"github.com/docker/docker/pkg/httputils"
27
+	"github.com/docker/docker/pkg/integration"
27 28
 	"github.com/docker/docker/pkg/ioutils"
28 29
 	"github.com/docker/docker/pkg/stringutils"
29 30
 	"github.com/go-check/check"
... ...
@@ -621,52 +622,30 @@ func pullImageIfNotExist(image string) (err error) {
621 621
 }
622 622
 
623 623
 func dockerCmdWithError(args ...string) (string, int, error) {
624
-	return runCommandWithOutput(exec.Command(dockerBinary, args...))
624
+	return integration.DockerCmdWithError(dockerBinary, args...)
625 625
 }
626 626
 
627 627
 func dockerCmdWithStdoutStderr(c *check.C, args ...string) (string, string, int) {
628
-	stdout, stderr, status, err := runCommandWithStdoutStderr(exec.Command(dockerBinary, args...))
629
-	if c != nil {
630
-		c.Assert(err, check.IsNil, check.Commentf("%q failed with errors: %s, %v", strings.Join(args, " "), stderr, err))
631
-	}
632
-	return stdout, stderr, status
628
+	return integration.DockerCmdWithStdoutStderr(dockerBinary, c, args...)
633 629
 }
634 630
 
635 631
 func dockerCmd(c *check.C, args ...string) (string, int) {
636
-	out, status, err := runCommandWithOutput(exec.Command(dockerBinary, args...))
637
-	c.Assert(err, check.IsNil, check.Commentf("%q failed with errors: %s, %v", strings.Join(args, " "), out, err))
638
-	return out, status
632
+	return integration.DockerCmd(dockerBinary, c, args...)
639 633
 }
640 634
 
641 635
 // execute a docker command with a timeout
642 636
 func dockerCmdWithTimeout(timeout time.Duration, args ...string) (string, int, error) {
643
-	out, status, err := runCommandWithOutputAndTimeout(exec.Command(dockerBinary, args...), timeout)
644
-	if err != nil {
645
-		return out, status, fmt.Errorf("%q failed with errors: %v : %q)", strings.Join(args, " "), err, out)
646
-	}
647
-	return out, status, err
637
+	return integration.DockerCmdWithTimeout(dockerBinary, timeout, args...)
648 638
 }
649 639
 
650 640
 // execute a docker command in a directory
651 641
 func dockerCmdInDir(c *check.C, path string, args ...string) (string, int, error) {
652
-	dockerCommand := exec.Command(dockerBinary, args...)
653
-	dockerCommand.Dir = path
654
-	out, status, err := runCommandWithOutput(dockerCommand)
655
-	if err != nil {
656
-		return out, status, fmt.Errorf("%q failed with errors: %v : %q)", strings.Join(args, " "), err, out)
657
-	}
658
-	return out, status, err
642
+	return integration.DockerCmdInDir(dockerBinary, path, args...)
659 643
 }
660 644
 
661 645
 // execute a docker command in a directory with a timeout
662 646
 func dockerCmdInDirWithTimeout(timeout time.Duration, path string, args ...string) (string, int, error) {
663
-	dockerCommand := exec.Command(dockerBinary, args...)
664
-	dockerCommand.Dir = path
665
-	out, status, err := runCommandWithOutputAndTimeout(dockerCommand, timeout)
666
-	if err != nil {
667
-		return out, status, fmt.Errorf("%q failed with errors: %v : %q)", strings.Join(args, " "), err, out)
668
-	}
669
-	return out, status, err
647
+	return integration.DockerCmdInDirWithTimeout(dockerBinary, timeout, path, args...)
670 648
 }
671 649
 
672 650
 func findContainerIP(c *check.C, id string, vargs ...string) string {
673 651
new file mode 100644
... ...
@@ -0,0 +1,71 @@
0
+package integration
1
+
2
+import (
3
+	"fmt"
4
+	"os/exec"
5
+	"strings"
6
+	"time"
7
+
8
+	"github.com/go-check/check"
9
+)
10
+
11
+var execCommand = exec.Command
12
+
13
+// DockerCmdWithError executes a docker command that is supposed to fail and returns
14
+// the output, the exit code and the error.
15
+func DockerCmdWithError(dockerBinary string, args ...string) (string, int, error) {
16
+	return RunCommandWithOutput(execCommand(dockerBinary, args...))
17
+}
18
+
19
+// DockerCmdWithStdoutStderr executes a docker command and returns the content of the
20
+// stdout, stderr and the exit code. If a check.C is passed, it will fail and stop tests
21
+// if the error is not nil.
22
+func DockerCmdWithStdoutStderr(dockerBinary string, c *check.C, args ...string) (string, string, int) {
23
+	stdout, stderr, status, err := RunCommandWithStdoutStderr(execCommand(dockerBinary, args...))
24
+	if c != nil {
25
+		c.Assert(err, check.IsNil, check.Commentf("%q failed with errors: %s, %v", strings.Join(args, " "), stderr, err))
26
+	}
27
+	return stdout, stderr, status
28
+}
29
+
30
+// DockerCmd executes a docker command and returns the output and the exit code. If the
31
+// command returns an error, it will fail and stop the tests.
32
+func DockerCmd(dockerBinary string, c *check.C, args ...string) (string, int) {
33
+	out, status, err := RunCommandWithOutput(execCommand(dockerBinary, args...))
34
+	c.Assert(err, check.IsNil, check.Commentf("%q failed with errors: %s, %v", strings.Join(args, " "), out, err))
35
+	return out, status
36
+}
37
+
38
+// DockerCmdWithTimeout executes a docker command with a timeout, and returns the output,
39
+// the exit code and the error (if any).
40
+func DockerCmdWithTimeout(dockerBinary string, timeout time.Duration, args ...string) (string, int, error) {
41
+	out, status, err := RunCommandWithOutputAndTimeout(execCommand(dockerBinary, args...), timeout)
42
+	if err != nil {
43
+		return out, status, fmt.Errorf("%q failed with errors: %v : %q", strings.Join(args, " "), err, out)
44
+	}
45
+	return out, status, err
46
+}
47
+
48
+// DockerCmdInDir executes a docker command in a directory and returns the output, the
49
+// exit code and the error (if any).
50
+func DockerCmdInDir(dockerBinary string, path string, args ...string) (string, int, error) {
51
+	dockerCommand := execCommand(dockerBinary, args...)
52
+	dockerCommand.Dir = path
53
+	out, status, err := RunCommandWithOutput(dockerCommand)
54
+	if err != nil {
55
+		return out, status, fmt.Errorf("%q failed with errors: %v : %q", strings.Join(args, " "), err, out)
56
+	}
57
+	return out, status, err
58
+}
59
+
60
+// DockerCmdInDirWithTimeout executes a docker command in a directory with a timeout and
61
+// returns the output, the exit code and the error (if any).
62
+func DockerCmdInDirWithTimeout(dockerBinary string, timeout time.Duration, path string, args ...string) (string, int, error) {
63
+	dockerCommand := execCommand(dockerBinary, args...)
64
+	dockerCommand.Dir = path
65
+	out, status, err := RunCommandWithOutputAndTimeout(dockerCommand, timeout)
66
+	if err != nil {
67
+		return out, status, fmt.Errorf("%q failed with errors: %v : %q", strings.Join(args, " "), err, out)
68
+	}
69
+	return out, status, err
70
+}
0 71
new file mode 100644
... ...
@@ -0,0 +1,403 @@
0
+package integration
1
+
2
+import (
3
+	"fmt"
4
+	"os"
5
+	"os/exec"
6
+	"testing"
7
+
8
+	"github.com/go-check/check"
9
+	"io/ioutil"
10
+	"strings"
11
+	"time"
12
+)
13
+
14
+const dockerBinary = "docker"
15
+
16
+// Setup go-check for this test
17
+func Test(t *testing.T) {
18
+	check.TestingT(t)
19
+}
20
+
21
+func init() {
22
+	check.Suite(&DockerCmdSuite{})
23
+}
24
+
25
+type DockerCmdSuite struct{}
26
+
27
+// Fake the exec.Command to use our mock.
28
+func (s *DockerCmdSuite) SetUpTest(c *check.C) {
29
+	execCommand = fakeExecCommand
30
+}
31
+
32
+// And bring it back to normal after the test.
33
+func (s *DockerCmdSuite) TearDownTest(c *check.C) {
34
+	execCommand = exec.Command
35
+}
36
+
37
+// DockerCmdWithError tests
38
+
39
+func (s *DockerCmdSuite) TestDockerCmdWithError(c *check.C) {
40
+	cmds := []struct {
41
+		binary           string
42
+		args             []string
43
+		expectedOut      string
44
+		expectedExitCode int
45
+		expectedError    error
46
+	}{
47
+		{
48
+			"doesnotexists",
49
+			[]string{},
50
+			"Command doesnotexists not found.",
51
+			1,
52
+			fmt.Errorf("exit status 1"),
53
+		},
54
+		{
55
+			dockerBinary,
56
+			[]string{"an", "error"},
57
+			"an error has occurred",
58
+			1,
59
+			fmt.Errorf("exit status 1"),
60
+		},
61
+		{
62
+			dockerBinary,
63
+			[]string{"an", "exitCode", "127"},
64
+			"an error has occurred with exitCode 127",
65
+			127,
66
+			fmt.Errorf("exit status 127"),
67
+		},
68
+		{
69
+			dockerBinary,
70
+			[]string{"run", "-ti", "ubuntu", "echo", "hello"},
71
+			"hello",
72
+			0,
73
+			nil,
74
+		},
75
+	}
76
+	for _, cmd := range cmds {
77
+		out, exitCode, error := DockerCmdWithError(cmd.binary, cmd.args...)
78
+		c.Assert(out, check.Equals, cmd.expectedOut, check.Commentf("Expected output %q for arguments %v, got %q", cmd.expectedOut, cmd.args, out))
79
+		c.Assert(exitCode, check.Equals, cmd.expectedExitCode, check.Commentf("Expected exitCode %q for arguments %v, got %q", cmd.expectedExitCode, cmd.args, exitCode))
80
+		if cmd.expectedError != nil {
81
+			c.Assert(error, check.NotNil, check.Commentf("Expected an error %q, got nothing", cmd.expectedError))
82
+			c.Assert(error.Error(), check.Equals, cmd.expectedError.Error(), check.Commentf("Expected error %q for arguments %v, got %q", cmd.expectedError.Error(), cmd.args, error.Error()))
83
+		} else {
84
+			c.Assert(error, check.IsNil, check.Commentf("Expected no error, got %v", error))
85
+		}
86
+	}
87
+}
88
+
89
+// DockerCmdWithStdoutStderr tests
90
+
91
+type dockerCmdWithStdoutStderrErrorSuite struct{}
92
+
93
+func (s *dockerCmdWithStdoutStderrErrorSuite) Test(c *check.C) {
94
+	// Should fail, the test too
95
+	DockerCmdWithStdoutStderr(dockerBinary, c, "an", "error")
96
+}
97
+
98
+type dockerCmdWithStdoutStderrSuccessSuite struct{}
99
+
100
+func (s *dockerCmdWithStdoutStderrSuccessSuite) Test(c *check.C) {
101
+	stdout, stderr, exitCode := DockerCmdWithStdoutStderr(dockerBinary, c, "run", "-ti", "ubuntu", "echo", "hello")
102
+	c.Assert(stdout, check.Equals, "hello")
103
+	c.Assert(stderr, check.Equals, "")
104
+	c.Assert(exitCode, check.Equals, 0)
105
+
106
+}
107
+
108
+func (s *DockerCmdSuite) TestDockerCmdWithStdoutStderrError(c *check.C) {
109
+	// Run error suite, should fail.
110
+	output := String{}
111
+	result := check.Run(&dockerCmdWithStdoutStderrErrorSuite{}, &check.RunConf{Output: &output})
112
+	c.Check(result.Succeeded, check.Equals, 0)
113
+	c.Check(result.Failed, check.Equals, 1)
114
+}
115
+
116
+func (s *DockerCmdSuite) TestDockerCmdWithStdoutStderrSuccess(c *check.C) {
117
+	// Run error suite, should fail.
118
+	output := String{}
119
+	result := check.Run(&dockerCmdWithStdoutStderrSuccessSuite{}, &check.RunConf{Output: &output})
120
+	c.Check(result.Succeeded, check.Equals, 1)
121
+	c.Check(result.Failed, check.Equals, 0)
122
+}
123
+
124
+// DockerCmd tests
125
+
126
+type dockerCmdErrorSuite struct{}
127
+
128
+func (s *dockerCmdErrorSuite) Test(c *check.C) {
129
+	// Should fail, the test too
130
+	DockerCmd(dockerBinary, c, "an", "error")
131
+}
132
+
133
+type dockerCmdSuccessSuite struct{}
134
+
135
+func (s *dockerCmdSuccessSuite) Test(c *check.C) {
136
+	stdout, exitCode := DockerCmd(dockerBinary, c, "run", "-ti", "ubuntu", "echo", "hello")
137
+	c.Assert(stdout, check.Equals, "hello")
138
+	c.Assert(exitCode, check.Equals, 0)
139
+
140
+}
141
+
142
+func (s *DockerCmdSuite) TestDockerCmdError(c *check.C) {
143
+	// Run error suite, should fail.
144
+	output := String{}
145
+	result := check.Run(&dockerCmdErrorSuite{}, &check.RunConf{Output: &output})
146
+	c.Check(result.Succeeded, check.Equals, 0)
147
+	c.Check(result.Failed, check.Equals, 1)
148
+}
149
+
150
+func (s *DockerCmdSuite) TestDockerCmdSuccess(c *check.C) {
151
+	// Run error suite, should fail.
152
+	output := String{}
153
+	result := check.Run(&dockerCmdSuccessSuite{}, &check.RunConf{Output: &output})
154
+	c.Check(result.Succeeded, check.Equals, 1)
155
+	c.Check(result.Failed, check.Equals, 0)
156
+}
157
+
158
+// DockerCmdWithTimeout tests
159
+
160
+func (s *DockerCmdSuite) TestDockerCmdWithTimeout(c *check.C) {
161
+	cmds := []struct {
162
+		binary           string
163
+		args             []string
164
+		timeout          time.Duration
165
+		expectedOut      string
166
+		expectedExitCode int
167
+		expectedError    error
168
+	}{
169
+		{
170
+			"doesnotexists",
171
+			[]string{},
172
+			5 * time.Millisecond,
173
+			`Command doesnotexists not found.`,
174
+			1,
175
+			fmt.Errorf(`"" failed with errors: exit status 1 : "Command doesnotexists not found."`),
176
+		},
177
+		{
178
+			dockerBinary,
179
+			[]string{"an", "error"},
180
+			5 * time.Millisecond,
181
+			`an error has occurred`,
182
+			1,
183
+			fmt.Errorf(`"an error" failed with errors: exit status 1 : "an error has occurred"`),
184
+		},
185
+		{
186
+			dockerBinary,
187
+			[]string{"a", "command", "that", "times", "out"},
188
+			5 * time.Millisecond,
189
+			"",
190
+			0,
191
+			fmt.Errorf(`"a command that times out" failed with errors: command timed out : ""`),
192
+		},
193
+		{
194
+			dockerBinary,
195
+			[]string{"run", "-ti", "ubuntu", "echo", "hello"},
196
+			5 * time.Millisecond,
197
+			"hello",
198
+			0,
199
+			nil,
200
+		},
201
+	}
202
+	for _, cmd := range cmds {
203
+		out, exitCode, error := DockerCmdWithTimeout(cmd.binary, cmd.timeout, cmd.args...)
204
+		c.Assert(out, check.Equals, cmd.expectedOut, check.Commentf("Expected output %q for arguments %v, got %q", cmd.expectedOut, cmd.args, out))
205
+		c.Assert(exitCode, check.Equals, cmd.expectedExitCode, check.Commentf("Expected exitCode %q for arguments %v, got %q", cmd.expectedExitCode, cmd.args, exitCode))
206
+		if cmd.expectedError != nil {
207
+			c.Assert(error, check.NotNil, check.Commentf("Expected an error %q, got nothing", cmd.expectedError))
208
+			c.Assert(error.Error(), check.Equals, cmd.expectedError.Error(), check.Commentf("Expected error %q for arguments %v, got %q", cmd.expectedError.Error(), cmd.args, error.Error()))
209
+		} else {
210
+			c.Assert(error, check.IsNil, check.Commentf("Expected no error, got %v", error))
211
+		}
212
+	}
213
+}
214
+
215
+// DockerCmdInDir tests
216
+
217
+func (s *DockerCmdSuite) TestDockerCmdInDir(c *check.C) {
218
+	tempFolder, err := ioutil.TempDir("", "test-docker-cmd-in-dir")
219
+	c.Assert(err, check.IsNil)
220
+
221
+	cmds := []struct {
222
+		binary           string
223
+		args             []string
224
+		expectedOut      string
225
+		expectedExitCode int
226
+		expectedError    error
227
+	}{
228
+		{
229
+			"doesnotexists",
230
+			[]string{},
231
+			`Command doesnotexists not found.`,
232
+			1,
233
+			fmt.Errorf(`"dir:%s" failed with errors: exit status 1 : "Command doesnotexists not found."`, tempFolder),
234
+		},
235
+		{
236
+			dockerBinary,
237
+			[]string{"an", "error"},
238
+			`an error has occurred`,
239
+			1,
240
+			fmt.Errorf(`"dir:%s an error" failed with errors: exit status 1 : "an error has occurred"`, tempFolder),
241
+		},
242
+		{
243
+			dockerBinary,
244
+			[]string{"run", "-ti", "ubuntu", "echo", "hello"},
245
+			"hello",
246
+			0,
247
+			nil,
248
+		},
249
+	}
250
+	for _, cmd := range cmds {
251
+		// We prepend the arguments with dir:thefolder.. the fake command will check
252
+		// that the current workdir is the same as the one we are passing.
253
+		args := append([]string{"dir:" + tempFolder}, cmd.args...)
254
+		out, exitCode, error := DockerCmdInDir(cmd.binary, tempFolder, args...)
255
+		c.Assert(out, check.Equals, cmd.expectedOut, check.Commentf("Expected output %q for arguments %v, got %q", cmd.expectedOut, cmd.args, out))
256
+		c.Assert(exitCode, check.Equals, cmd.expectedExitCode, check.Commentf("Expected exitCode %q for arguments %v, got %q", cmd.expectedExitCode, cmd.args, exitCode))
257
+		if cmd.expectedError != nil {
258
+			c.Assert(error, check.NotNil, check.Commentf("Expected an error %q, got nothing", cmd.expectedError))
259
+			c.Assert(error.Error(), check.Equals, cmd.expectedError.Error(), check.Commentf("Expected error %q for arguments %v, got %q", cmd.expectedError.Error(), cmd.args, error.Error()))
260
+		} else {
261
+			c.Assert(error, check.IsNil, check.Commentf("Expected no error, got %v", error))
262
+		}
263
+	}
264
+}
265
+
266
+// DockerCmdInDirWithTimeout tests
267
+
268
+func (s *DockerCmdSuite) TestDockerCmdInDirWithTimeout(c *check.C) {
269
+	tempFolder, err := ioutil.TempDir("", "test-docker-cmd-in-dir")
270
+	c.Assert(err, check.IsNil)
271
+
272
+	cmds := []struct {
273
+		binary           string
274
+		args             []string
275
+		timeout          time.Duration
276
+		expectedOut      string
277
+		expectedExitCode int
278
+		expectedError    error
279
+	}{
280
+		{
281
+			"doesnotexists",
282
+			[]string{},
283
+			5 * time.Millisecond,
284
+			`Command doesnotexists not found.`,
285
+			1,
286
+			fmt.Errorf(`"dir:%s" failed with errors: exit status 1 : "Command doesnotexists not found."`, tempFolder),
287
+		},
288
+		{
289
+			dockerBinary,
290
+			[]string{"an", "error"},
291
+			5 * time.Millisecond,
292
+			`an error has occurred`,
293
+			1,
294
+			fmt.Errorf(`"dir:%s an error" failed with errors: exit status 1 : "an error has occurred"`, tempFolder),
295
+		},
296
+		{
297
+			dockerBinary,
298
+			[]string{"a", "command", "that", "times", "out"},
299
+			5 * time.Millisecond,
300
+			"",
301
+			0,
302
+			fmt.Errorf(`"dir:%s a command that times out" failed with errors: command timed out : ""`, tempFolder),
303
+		},
304
+		{
305
+			dockerBinary,
306
+			[]string{"run", "-ti", "ubuntu", "echo", "hello"},
307
+			5 * time.Millisecond,
308
+			"hello",
309
+			0,
310
+			nil,
311
+		},
312
+	}
313
+	for _, cmd := range cmds {
314
+		// We prepend the arguments with dir:thefolder.. the fake command will check
315
+		// that the current workdir is the same as the one we are passing.
316
+		args := append([]string{"dir:" + tempFolder}, cmd.args...)
317
+		out, exitCode, error := DockerCmdInDirWithTimeout(cmd.binary, cmd.timeout, tempFolder, args...)
318
+		c.Assert(out, check.Equals, cmd.expectedOut, check.Commentf("Expected output %q for arguments %v, got %q", cmd.expectedOut, cmd.args, out))
319
+		c.Assert(exitCode, check.Equals, cmd.expectedExitCode, check.Commentf("Expected exitCode %q for arguments %v, got %q", cmd.expectedExitCode, cmd.args, exitCode))
320
+		if cmd.expectedError != nil {
321
+			c.Assert(error, check.NotNil, check.Commentf("Expected an error %q, got nothing", cmd.expectedError))
322
+			c.Assert(error.Error(), check.Equals, cmd.expectedError.Error(), check.Commentf("Expected error %q for arguments %v, got %q", cmd.expectedError.Error(), cmd.args, error.Error()))
323
+		} else {
324
+			c.Assert(error, check.IsNil, check.Commentf("Expected no error, got %v", error))
325
+		}
326
+	}
327
+}
328
+
329
+// Helpers :)
330
+
331
+// Type implementing the io.Writer interface for analyzing output.
332
+type String struct {
333
+	value string
334
+}
335
+
336
+// The only function required by the io.Writer interface.  Will append
337
+// written data to the String.value string.
338
+func (s *String) Write(p []byte) (n int, err error) {
339
+	s.value += string(p)
340
+	return len(p), nil
341
+}
342
+
343
+// Helper function that mock the exec.Command call (and call the test binary)
344
+func fakeExecCommand(command string, args ...string) *exec.Cmd {
345
+	cs := []string{"-test.run=TestHelperProcess", "--", command}
346
+	cs = append(cs, args...)
347
+	cmd := exec.Command(os.Args[0], cs...)
348
+	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
349
+	return cmd
350
+}
351
+
352
+func TestHelperProcess(t *testing.T) {
353
+	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
354
+		return
355
+	}
356
+	args := os.Args
357
+
358
+	// Previous arguments are tests stuff, that looks like :
359
+	// /tmp/go-build970079519/…/_test/integration.test -test.run=TestHelperProcess --
360
+	cmd, args := args[3], args[4:]
361
+	// Handle the case where args[0] is dir:...
362
+	if len(args) > 0 && strings.HasPrefix(args[0], "dir:") {
363
+		expectedCwd := args[0][4:]
364
+		if len(args) > 1 {
365
+			args = args[1:]
366
+		}
367
+		cwd, err := os.Getwd()
368
+		if err != nil {
369
+			fmt.Fprintf(os.Stderr, "Failed to get workingdir: %v", err)
370
+			os.Exit(1)
371
+		}
372
+		// This checks that the given path is the same as the currend working dire
373
+		if expectedCwd != cwd {
374
+			fmt.Fprintf(os.Stderr, "Current workdir should be %q, but is %q", expectedCwd, cwd)
375
+		}
376
+	}
377
+	switch cmd {
378
+	case dockerBinary:
379
+		argsStr := strings.Join(args, " ")
380
+		switch argsStr {
381
+		case "an exitCode 127":
382
+			fmt.Fprintf(os.Stderr, "an error has occurred with exitCode 127")
383
+			os.Exit(127)
384
+		case "an error":
385
+			fmt.Fprintf(os.Stderr, "an error has occurred")
386
+			os.Exit(1)
387
+		case "a command that times out":
388
+			time.Sleep(10 * time.Millisecond)
389
+			fmt.Fprintf(os.Stdout, "too long, should be killed")
390
+			os.Exit(0)
391
+		case "run -ti ubuntu echo hello":
392
+			fmt.Fprintf(os.Stdout, "hello")
393
+		default:
394
+			fmt.Fprintf(os.Stdout, "no arguments")
395
+		}
396
+	default:
397
+		fmt.Fprintf(os.Stderr, "Command %s not found.", cmd)
398
+		os.Exit(1)
399
+	}
400
+	// some code here to check arguments perhaps?
401
+	os.Exit(0)
402
+}