Browse code

Remove pkg/integration and move it to testutil or integration-cli

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

Vincent Demeester authored on 2016/12/31 02:23:00
Showing 128 changed files
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"strings"
9 9
 	"sync"
10 10
 
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
15 15
new file mode 100644
... ...
@@ -0,0 +1,46 @@
0
+// Package checker provides Docker specific implementations of the go-check.Checker interface.
1
+package checker
2
+
3
+import (
4
+	"github.com/go-check/check"
5
+	"github.com/vdemeester/shakers"
6
+)
7
+
8
+// As a commodity, we bring all check.Checker variables into the current namespace to avoid having
9
+// to think about check.X versus checker.X.
10
+var (
11
+	DeepEquals   = check.DeepEquals
12
+	ErrorMatches = check.ErrorMatches
13
+	FitsTypeOf   = check.FitsTypeOf
14
+	HasLen       = check.HasLen
15
+	Implements   = check.Implements
16
+	IsNil        = check.IsNil
17
+	Matches      = check.Matches
18
+	Not          = check.Not
19
+	NotNil       = check.NotNil
20
+	PanicMatches = check.PanicMatches
21
+	Panics       = check.Panics
22
+
23
+	Contains           = shakers.Contains
24
+	ContainsAny        = shakers.ContainsAny
25
+	Count              = shakers.Count
26
+	Equals             = shakers.Equals
27
+	EqualFold          = shakers.EqualFold
28
+	False              = shakers.False
29
+	GreaterOrEqualThan = shakers.GreaterOrEqualThan
30
+	GreaterThan        = shakers.GreaterThan
31
+	HasPrefix          = shakers.HasPrefix
32
+	HasSuffix          = shakers.HasSuffix
33
+	Index              = shakers.Index
34
+	IndexAny           = shakers.IndexAny
35
+	IsAfter            = shakers.IsAfter
36
+	IsBefore           = shakers.IsBefore
37
+	IsBetween          = shakers.IsBetween
38
+	IsLower            = shakers.IsLower
39
+	IsUpper            = shakers.IsUpper
40
+	LessOrEqualThan    = shakers.LessOrEqualThan
41
+	LessThan           = shakers.LessThan
42
+	TimeEquals         = shakers.TimeEquals
43
+	True               = shakers.True
44
+	TimeIgnore         = shakers.TimeIgnore
45
+)
... ...
@@ -19,12 +19,12 @@ import (
19 19
 	"time"
20 20
 
21 21
 	"github.com/docker/docker/api/types/events"
22
+	"github.com/docker/docker/integration-cli/checker"
22 23
 	"github.com/docker/docker/opts"
23
-	"github.com/docker/docker/pkg/integration"
24
-	"github.com/docker/docker/pkg/integration/checker"
25
-	icmd "github.com/docker/docker/pkg/integration/cmd"
26 24
 	"github.com/docker/docker/pkg/ioutils"
27 25
 	"github.com/docker/docker/pkg/stringid"
26
+	"github.com/docker/docker/pkg/testutil"
27
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
28 28
 	"github.com/docker/go-connections/sockets"
29 29
 	"github.com/docker/go-connections/tlsconfig"
30 30
 	"github.com/go-check/check"
... ...
@@ -543,7 +543,7 @@ func (d *Daemon) queryRootDir() (string, error) {
543 543
 	}
544 544
 	var b []byte
545 545
 	var i Info
546
-	b, err = integration.ReadBody(body)
546
+	b, err = testutil.ReadBody(body)
547 547
 	if err == nil && resp.StatusCode == http.StatusOK {
548 548
 		// read the docker root dir
549 549
 		if err = json.Unmarshal(b, &i); err == nil {
... ...
@@ -570,7 +570,7 @@ func (d *Daemon) WaitRun(contID string) error {
570 570
 
571 571
 // GetBaseDeviceSize returns the base device size of the daemon
572 572
 func (d *Daemon) GetBaseDeviceSize(c *check.C) int64 {
573
-	infoCmdOutput, _, err := integration.RunCommandPipelineWithOutput(
573
+	infoCmdOutput, _, err := testutil.RunCommandPipelineWithOutput(
574 574
 		exec.Command(d.dockerBinary, "-H", d.Sock(), "info"),
575 575
 		exec.Command("grep", "Base Device Size"),
576 576
 	)
... ...
@@ -617,7 +617,7 @@ func (d *Daemon) SockRequest(method, endpoint string, data interface{}) (int, []
617 617
 	if err != nil {
618 618
 		return -1, nil, err
619 619
 	}
620
-	b, err := integration.ReadBody(body)
620
+	b, err := testutil.ReadBody(body)
621 621
 	return res.StatusCode, b, err
622 622
 }
623 623
 
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"github.com/docker/docker/api/types"
11 11
 	"github.com/docker/docker/api/types/filters"
12 12
 	"github.com/docker/docker/api/types/swarm"
13
-	"github.com/docker/docker/pkg/integration/checker"
13
+	"github.com/docker/docker/integration-cli/checker"
14 14
 	"github.com/go-check/check"
15 15
 	"github.com/pkg/errors"
16 16
 )
... ...
@@ -12,9 +12,9 @@ import (
12 12
 
13 13
 	"github.com/docker/docker/api/types"
14 14
 	"github.com/docker/docker/client"
15
-	"github.com/docker/docker/pkg/integration"
16
-	"github.com/docker/docker/pkg/integration/checker"
15
+	"github.com/docker/docker/integration-cli/checker"
17 16
 	"github.com/docker/docker/pkg/stdcopy"
17
+	"github.com/docker/docker/pkg/testutil"
18 18
 	"github.com/go-check/check"
19 19
 	"golang.org/x/net/websocket"
20 20
 )
... ...
@@ -80,7 +80,7 @@ func (s *DockerSuite) TestPostContainersAttachContainerNotFound(c *check.C) {
80 80
 	// connection will shutdown, err should be "persistent connection closed"
81 81
 	c.Assert(err, checker.NotNil) // Server shutdown connection
82 82
 
83
-	body, err := integration.ReadBody(resp.Body)
83
+	body, err := testutil.ReadBody(resp.Body)
84 84
 	c.Assert(err, checker.IsNil)
85 85
 	c.Assert(resp.StatusCode, checker.Equals, http.StatusNotFound)
86 86
 	expected := "No such container: doesnotexist\r\n"
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"net/http"
5 5
 
6 6
 	"github.com/docker/docker/api/types"
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -7,8 +7,8 @@ import (
7 7
 	"regexp"
8 8
 	"strings"
9 9
 
10
-	"github.com/docker/docker/pkg/integration"
11
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11
+	"github.com/docker/docker/pkg/testutil"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -35,7 +35,7 @@ RUN find /tmp/`
35 35
 	c.Assert(err, checker.IsNil)
36 36
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
37 37
 
38
-	buf, err := integration.ReadBody(body)
38
+	buf, err := testutil.ReadBody(body)
39 39
 	c.Assert(err, checker.IsNil)
40 40
 
41 41
 	// Make sure Dockerfile exists.
... ...
@@ -126,7 +126,7 @@ RUN echo 'right'
126 126
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
127 127
 
128 128
 	defer body.Close()
129
-	content, err := integration.ReadBody(body)
129
+	content, err := testutil.ReadBody(body)
130 130
 	c.Assert(err, checker.IsNil)
131 131
 
132 132
 	// Build used the wrong dockerfile.
... ...
@@ -145,7 +145,7 @@ RUN echo from dockerfile`,
145 145
 	c.Assert(err, checker.IsNil)
146 146
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
147 147
 
148
-	buf, err := integration.ReadBody(body)
148
+	buf, err := testutil.ReadBody(body)
149 149
 	c.Assert(err, checker.IsNil)
150 150
 
151 151
 	out := string(buf)
... ...
@@ -167,7 +167,7 @@ RUN echo from Dockerfile`,
167 167
 	c.Assert(err, checker.IsNil)
168 168
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
169 169
 
170
-	buf, err := integration.ReadBody(body)
170
+	buf, err := testutil.ReadBody(body)
171 171
 	c.Assert(err, checker.IsNil)
172 172
 
173 173
 	out := string(buf)
... ...
@@ -190,7 +190,7 @@ RUN echo from dockerfile`,
190 190
 	c.Assert(err, checker.IsNil)
191 191
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
192 192
 
193
-	buf, err := integration.ReadBody(body)
193
+	buf, err := testutil.ReadBody(body)
194 194
 	c.Assert(err, checker.IsNil)
195 195
 
196 196
 	out := string(buf)
... ...
@@ -237,7 +237,7 @@ func (s *DockerSuite) TestBuildAPIUnnormalizedTarPaths(c *check.C) {
237 237
 		c.Assert(err, checker.IsNil)
238 238
 		c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
239 239
 
240
-		out, err := integration.ReadBody(body)
240
+		out, err := testutil.ReadBody(body)
241 241
 		c.Assert(err, checker.IsNil)
242 242
 		lines := strings.Split(string(out), "\n")
243 243
 		c.Assert(len(lines), checker.GreaterThan, 1)
... ...
@@ -21,11 +21,11 @@ import (
21 21
 	containertypes "github.com/docker/docker/api/types/container"
22 22
 	mounttypes "github.com/docker/docker/api/types/mount"
23 23
 	networktypes "github.com/docker/docker/api/types/network"
24
-	"github.com/docker/docker/pkg/integration"
25
-	"github.com/docker/docker/pkg/integration/checker"
24
+	"github.com/docker/docker/integration-cli/checker"
26 25
 	"github.com/docker/docker/pkg/ioutils"
27 26
 	"github.com/docker/docker/pkg/mount"
28 27
 	"github.com/docker/docker/pkg/stringid"
28
+	"github.com/docker/docker/pkg/testutil"
29 29
 	"github.com/docker/docker/volume"
30 30
 	"github.com/go-check/check"
31 31
 )
... ...
@@ -215,7 +215,7 @@ func (s *DockerSuite) TestGetContainerStatsRmRunning(c *check.C) {
215 215
 	out, _ := runSleepingContainer(c)
216 216
 	id := strings.TrimSpace(out)
217 217
 
218
-	buf := &integration.ChannelBuffer{make(chan []byte, 1)}
218
+	buf := &testutil.ChannelBuffer{make(chan []byte, 1)}
219 219
 	defer buf.Close()
220 220
 
221 221
 	_, body, err := sockRequestRaw("GET", "/containers/"+id+"/stats?stream=1", nil, "application/json")
... ...
@@ -723,7 +723,7 @@ func (s *DockerSuite) TestContainerAPIInvalidPortSyntax(c *check.C) {
723 723
 	c.Assert(err, checker.IsNil)
724 724
 	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
725 725
 
726
-	b, err := integration.ReadBody(body)
726
+	b, err := testutil.ReadBody(body)
727 727
 	c.Assert(err, checker.IsNil)
728 728
 	c.Assert(string(b[:]), checker.Contains, "invalid port")
729 729
 }
... ...
@@ -743,7 +743,7 @@ func (s *DockerSuite) TestContainerAPIRestartPolicyInvalidPolicyName(c *check.C)
743 743
 	c.Assert(err, checker.IsNil)
744 744
 	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
745 745
 
746
-	b, err := integration.ReadBody(body)
746
+	b, err := testutil.ReadBody(body)
747 747
 	c.Assert(err, checker.IsNil)
748 748
 	c.Assert(string(b[:]), checker.Contains, "invalid restart policy")
749 749
 }
... ...
@@ -763,7 +763,7 @@ func (s *DockerSuite) TestContainerAPIRestartPolicyRetryMismatch(c *check.C) {
763 763
 	c.Assert(err, checker.IsNil)
764 764
 	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
765 765
 
766
-	b, err := integration.ReadBody(body)
766
+	b, err := testutil.ReadBody(body)
767 767
 	c.Assert(err, checker.IsNil)
768 768
 	c.Assert(string(b[:]), checker.Contains, "maximum retry count cannot be used with restart policy")
769 769
 }
... ...
@@ -783,7 +783,7 @@ func (s *DockerSuite) TestContainerAPIRestartPolicyNegativeRetryCount(c *check.C
783 783
 	c.Assert(err, checker.IsNil)
784 784
 	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
785 785
 
786
-	b, err := integration.ReadBody(body)
786
+	b, err := testutil.ReadBody(body)
787 787
 	c.Assert(err, checker.IsNil)
788 788
 	c.Assert(string(b[:]), checker.Contains, "maximum retry count cannot be negative")
789 789
 }
... ...
@@ -834,7 +834,7 @@ func (s *DockerSuite) TestContainerAPIPostCreateNull(c *check.C) {
834 834
 	c.Assert(err, checker.IsNil)
835 835
 	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
836 836
 
837
-	b, err := integration.ReadBody(body)
837
+	b, err := testutil.ReadBody(body)
838 838
 	c.Assert(err, checker.IsNil)
839 839
 	type createResp struct {
840 840
 		ID string
... ...
@@ -863,7 +863,7 @@ func (s *DockerSuite) TestCreateWithTooLowMemoryLimit(c *check.C) {
863 863
 
864 864
 	res, body, err := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json")
865 865
 	c.Assert(err, checker.IsNil)
866
-	b, err2 := integration.ReadBody(body)
866
+	b, err2 := testutil.ReadBody(body)
867 867
 	c.Assert(err2, checker.IsNil)
868 868
 
869 869
 	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
... ...
@@ -3,7 +3,7 @@ package main
3 3
 import (
4 4
 	"net/http"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strings"
10 10
 	"time"
11 11
 
12
-	"github.com/docker/docker/pkg/integration/checker"
12
+	"github.com/docker/docker/integration-cli/checker"
13 13
 	"github.com/docker/docker/pkg/jsonmessage"
14 14
 	"github.com/go-check/check"
15 15
 )
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strings"
10 10
 	"sync"
11 11
 
12
-	"github.com/docker/docker/pkg/integration/checker"
12
+	"github.com/docker/docker/integration-cli/checker"
13 13
 	"github.com/go-check/check"
14 14
 )
15 15
 
... ...
@@ -10,8 +10,8 @@ import (
10 10
 	"strings"
11 11
 	"time"
12 12
 
13
-	"github.com/docker/docker/pkg/integration"
14
-	"github.com/docker/docker/pkg/integration/checker"
13
+	"github.com/docker/docker/integration-cli/checker"
14
+	"github.com/docker/docker/pkg/testutil"
15 15
 	"github.com/go-check/check"
16 16
 )
17 17
 
... ...
@@ -41,7 +41,7 @@ func (s *DockerSuite) TestExecAPICreateNoValidContentType(c *check.C) {
41 41
 	c.Assert(err, checker.IsNil)
42 42
 	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
43 43
 
44
-	b, err := integration.ReadBody(body)
44
+	b, err := testutil.ReadBody(body)
45 45
 	c.Assert(err, checker.IsNil)
46 46
 
47 47
 	comment := check.Commentf("Expected message when creating exec command with invalid Content-Type specified")
... ...
@@ -108,7 +108,7 @@ func (s *DockerSuite) TestExecAPIStartBackwardsCompatible(c *check.C) {
108 108
 	resp, body, err := sockRequestRaw("POST", fmt.Sprintf("/v1.20/exec/%s/start", id), strings.NewReader(`{"Detach": true}`), "text/plain")
109 109
 	c.Assert(err, checker.IsNil)
110 110
 
111
-	b, err := integration.ReadBody(body)
111
+	b, err := testutil.ReadBody(body)
112 112
 	comment := check.Commentf("response body: %s", b)
113 113
 	c.Assert(err, checker.IsNil, comment)
114 114
 	c.Assert(resp.StatusCode, checker.Equals, http.StatusOK, comment)
... ...
@@ -157,7 +157,7 @@ func (s *DockerSuite) TestExecAPIStartWithDetach(c *check.C) {
157 157
 	_, body, err := sockRequestRaw("POST", fmt.Sprintf("/exec/%s/start", createResp.ID), strings.NewReader(`{"Detach": true}`), "application/json")
158 158
 	c.Assert(err, checker.IsNil)
159 159
 
160
-	b, err = integration.ReadBody(body)
160
+	b, err = testutil.ReadBody(body)
161 161
 	comment := check.Commentf("response body: %s", b)
162 162
 	c.Assert(err, checker.IsNil, comment)
163 163
 
... ...
@@ -183,7 +183,7 @@ func startExec(c *check.C, id string, code int) {
183 183
 	resp, body, err := sockRequestRaw("POST", fmt.Sprintf("/exec/%s/start", id), strings.NewReader(`{"Detach": true}`), "application/json")
184 184
 	c.Assert(err, checker.IsNil)
185 185
 
186
-	b, err := integration.ReadBody(body)
186
+	b, err := testutil.ReadBody(body)
187 187
 	comment := check.Commentf("response body: %s", b)
188 188
 	c.Assert(err, checker.IsNil, comment)
189 189
 	c.Assert(resp.StatusCode, checker.Equals, code, comment)
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"strings"
8 8
 
9 9
 	"github.com/docker/docker/api/types"
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -3,7 +3,7 @@ package main
3 3
 import (
4 4
 	"net/http"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -7,7 +7,7 @@ import (
7 7
 
8 8
 	"github.com/docker/docker/api/types"
9 9
 	"github.com/docker/docker/api/types/versions/v1p20"
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/docker/docker/pkg/stringutils"
12 12
 	"github.com/go-check/check"
13 13
 )
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"fmt"
8 8
 	"net/http"
9 9
 
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"strings"
9 9
 	"time"
10 10
 
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -11,7 +11,7 @@ import (
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/filters"
13 13
 	"github.com/docker/docker/api/types/network"
14
-	"github.com/docker/docker/pkg/integration/checker"
14
+	"github.com/docker/docker/integration-cli/checker"
15 15
 	"github.com/go-check/check"
16 16
 )
17 17
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"net/http"
5 5
 	"strings"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -4,8 +4,8 @@ package main
4 4
 
5 5
 import (
6 6
 	"github.com/docker/docker/api/types/swarm"
7
+	"github.com/docker/docker/integration-cli/checker"
7 8
 	"github.com/docker/docker/integration-cli/daemon"
8
-	"github.com/docker/docker/pkg/integration/checker"
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
... ...
@@ -13,7 +13,7 @@ import (
13 13
 
14 14
 	"github.com/docker/docker/api/types"
15 15
 	"github.com/docker/docker/api/types/versions"
16
-	"github.com/docker/docker/pkg/integration/checker"
16
+	"github.com/docker/docker/integration-cli/checker"
17 17
 	"github.com/go-check/check"
18 18
 )
19 19
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"net/http"
9 9
 
10 10
 	"github.com/docker/docker/api/types"
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -14,8 +14,8 @@ import (
14 14
 	"time"
15 15
 
16 16
 	"github.com/docker/docker/api/types/swarm"
17
+	"github.com/docker/docker/integration-cli/checker"
17 18
 	"github.com/docker/docker/integration-cli/daemon"
18
-	"github.com/docker/docker/pkg/integration/checker"
19 19
 	"github.com/go-check/check"
20 20
 )
21 21
 
... ...
@@ -9,9 +9,9 @@ import (
9 9
 	"strings"
10 10
 
11 11
 	"github.com/docker/docker/api"
12
-	"github.com/docker/docker/pkg/integration"
13
-	"github.com/docker/docker/pkg/integration/checker"
14
-	icmd "github.com/docker/docker/pkg/integration/cmd"
12
+	"github.com/docker/docker/integration-cli/checker"
13
+	"github.com/docker/docker/pkg/testutil"
14
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
15 15
 	"github.com/go-check/check"
16 16
 )
17 17
 
... ...
@@ -79,7 +79,7 @@ func (s *DockerSuite) TestAPIErrorJSON(c *check.C) {
79 79
 	c.Assert(err, checker.IsNil)
80 80
 	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusInternalServerError)
81 81
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Equals, "application/json")
82
-	b, err := integration.ReadBody(body)
82
+	b, err := testutil.ReadBody(body)
83 83
 	c.Assert(err, checker.IsNil)
84 84
 	c.Assert(getErrorMessage(c, b), checker.Equals, "Config cannot be empty in order to create a container")
85 85
 }
... ...
@@ -92,7 +92,7 @@ func (s *DockerSuite) TestAPIErrorPlainText(c *check.C) {
92 92
 	c.Assert(err, checker.IsNil)
93 93
 	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusInternalServerError)
94 94
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Contains, "text/plain")
95
-	b, err := integration.ReadBody(body)
95
+	b, err := testutil.ReadBody(body)
96 96
 	c.Assert(err, checker.IsNil)
97 97
 	c.Assert(strings.TrimSpace(string(b)), checker.Equals, "Config cannot be empty in order to create a container")
98 98
 }
... ...
@@ -103,7 +103,7 @@ func (s *DockerSuite) TestAPIErrorNotFoundJSON(c *check.C) {
103 103
 	c.Assert(err, checker.IsNil)
104 104
 	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusNotFound)
105 105
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Equals, "application/json")
106
-	b, err := integration.ReadBody(body)
106
+	b, err := testutil.ReadBody(body)
107 107
 	c.Assert(err, checker.IsNil)
108 108
 	c.Assert(getErrorMessage(c, b), checker.Equals, "page not found")
109 109
 }
... ...
@@ -113,7 +113,7 @@ func (s *DockerSuite) TestAPIErrorNotFoundPlainText(c *check.C) {
113 113
 	c.Assert(err, checker.IsNil)
114 114
 	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusNotFound)
115 115
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Contains, "text/plain")
116
-	b, err := integration.ReadBody(body)
116
+	b, err := testutil.ReadBody(body)
117 117
 	c.Assert(err, checker.IsNil)
118 118
 	c.Assert(strings.TrimSpace(string(b)), checker.Equals, "page not found")
119 119
 }
... ...
@@ -5,7 +5,7 @@ package main
5 5
 import (
6 6
 	"strings"
7 7
 
8
-	"github.com/docker/docker/pkg/integration/checker"
8
+	"github.com/docker/docker/integration-cli/checker"
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 
7 7
 	"github.com/docker/docker/api/types"
8 8
 	"github.com/docker/docker/dockerversion"
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -7,7 +7,7 @@ import (
7 7
 
8 8
 	"github.com/docker/docker/api/types"
9 9
 	volumetypes "github.com/docker/docker/api/types/volume"
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"sync"
11 11
 	"time"
12 12
 
13
-	icmd "github.com/docker/docker/pkg/integration/cmd"
13
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
14 14
 	"github.com/go-check/check"
15 15
 )
16 16
 
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strings"
10 10
 	"time"
11 11
 
12
-	"github.com/docker/docker/pkg/integration/checker"
12
+	"github.com/docker/docker/integration-cli/checker"
13 13
 	"github.com/docker/docker/pkg/stringid"
14 14
 	"github.com/go-check/check"
15 15
 	"github.com/kr/pty"
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"fmt"
7 7
 	"strings"
8 8
 
9
+	"github.com/docker/docker/integration-cli/checker"
9 10
 	"github.com/docker/docker/integration-cli/daemon"
10
-	"github.com/docker/docker/pkg/integration/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -22,9 +22,9 @@ import (
22 22
 	"net/http/httputil"
23 23
 	"net/url"
24 24
 
25
+	"github.com/docker/docker/integration-cli/checker"
25 26
 	"github.com/docker/docker/integration-cli/daemon"
26 27
 	"github.com/docker/docker/pkg/authorization"
27
-	"github.com/docker/docker/pkg/integration/checker"
28 28
 	"github.com/docker/docker/pkg/plugins"
29 29
 	"github.com/go-check/check"
30 30
 )
... ...
@@ -18,11 +18,11 @@ import (
18 18
 	"time"
19 19
 
20 20
 	"github.com/docker/docker/builder/dockerfile/command"
21
+	"github.com/docker/docker/integration-cli/checker"
21 22
 	"github.com/docker/docker/pkg/archive"
22
-	"github.com/docker/docker/pkg/integration"
23
-	"github.com/docker/docker/pkg/integration/checker"
24
-	icmd "github.com/docker/docker/pkg/integration/cmd"
25 23
 	"github.com/docker/docker/pkg/stringutils"
24
+	"github.com/docker/docker/pkg/testutil"
25
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
26 26
 	"github.com/go-check/check"
27 27
 )
28 28
 
... ...
@@ -2086,7 +2086,7 @@ func (s *DockerSuite) TestBuildContextCleanup(c *check.C) {
2086 2086
 	if err != nil {
2087 2087
 		c.Fatalf("failed to list contents of tmp dir: %s", err)
2088 2088
 	}
2089
-	if err = integration.CompareDirectoryEntries(entries, entriesFinal); err != nil {
2089
+	if err = testutil.CompareDirectoryEntries(entries, entriesFinal); err != nil {
2090 2090
 		c.Fatalf("context should have been deleted, but wasn't")
2091 2091
 	}
2092 2092
 
... ...
@@ -2111,7 +2111,7 @@ func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
2111 2111
 	if err != nil {
2112 2112
 		c.Fatalf("failed to list contents of tmp dir: %s", err)
2113 2113
 	}
2114
-	if err = integration.CompareDirectoryEntries(entries, entriesFinal); err != nil {
2114
+	if err = testutil.CompareDirectoryEntries(entries, entriesFinal); err != nil {
2115 2115
 		c.Fatalf("context should have been deleted, but wasn't")
2116 2116
 	}
2117 2117
 
... ...
@@ -5342,7 +5342,7 @@ func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
5342 5342
 	if err != nil {
5343 5343
 		c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
5344 5344
 	}
5345
-	selfCgroupPaths := integration.ParseCgroupPaths(string(data))
5345
+	selfCgroupPaths := testutil.ParseCgroupPaths(string(data))
5346 5346
 	_, found := selfCgroupPaths["memory"]
5347 5347
 	if !found {
5348 5348
 		c.Fatalf("unable to find self memory cgroup path. CgroupsPath: %v", selfCgroupPaths)
... ...
@@ -14,8 +14,8 @@ import (
14 14
 	"strings"
15 15
 	"time"
16 16
 
17
-	"github.com/docker/docker/pkg/integration"
18
-	"github.com/docker/docker/pkg/integration/checker"
17
+	"github.com/docker/docker/integration-cli/checker"
18
+	"github.com/docker/docker/pkg/testutil"
19 19
 	"github.com/docker/go-units"
20 20
 	"github.com/go-check/check"
21 21
 )
... ...
@@ -194,7 +194,7 @@ func (s *DockerSuite) TestBuildCancellationKillsSleep(c *check.C) {
194 194
 	}
195 195
 
196 196
 	// Get the exit status of `docker build`, check it exited because killed.
197
-	if err := buildCmd.Wait(); err != nil && !integration.IsKilled(err) {
197
+	if err := buildCmd.Wait(); err != nil && !testutil.IsKilled(err) {
198 198
 		c.Fatalf("wait failed during build run: %T %s", err, err)
199 199
 	}
200 200
 
... ...
@@ -12,7 +12,7 @@ import (
12 12
 	"github.com/docker/distribution/manifest/schema1"
13 13
 	"github.com/docker/distribution/manifest/schema2"
14 14
 	"github.com/docker/docker/api/types"
15
-	"github.com/docker/docker/pkg/integration/checker"
15
+	"github.com/docker/docker/integration-cli/checker"
16 16
 	"github.com/docker/docker/pkg/stringutils"
17 17
 	"github.com/go-check/check"
18 18
 )
... ...
@@ -3,7 +3,7 @@ package main
3 3
 import (
4 4
 	"strings"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -11,8 +11,8 @@ import (
11 11
 
12 12
 	"github.com/docker/docker/api"
13 13
 	"github.com/docker/docker/dockerversion"
14
+	"github.com/docker/docker/integration-cli/checker"
14 15
 	"github.com/docker/docker/pkg/homedir"
15
-	"github.com/docker/docker/pkg/integration/checker"
16 16
 	"github.com/go-check/check"
17 17
 )
18 18
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"os"
5 5
 	"path/filepath"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -10,9 +10,9 @@ import (
10 10
 	"path/filepath"
11 11
 	"strings"
12 12
 
13
-	"github.com/docker/docker/pkg/integration"
14
-	"github.com/docker/docker/pkg/integration/checker"
15
-	icmd "github.com/docker/docker/pkg/integration/cmd"
13
+	"github.com/docker/docker/integration-cli/checker"
14
+	"github.com/docker/docker/pkg/testutil"
15
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
16 16
 	"github.com/go-check/check"
17 17
 )
18 18
 
... ...
@@ -546,7 +546,7 @@ func (s *DockerSuite) TestCpToStdout(c *check.C) {
546 546
 	// failed to set up container
547 547
 	c.Assert(strings.TrimSpace(out), checker.Equals, "0")
548 548
 
549
-	out, _, err := integration.RunCommandPipelineWithOutput(
549
+	out, _, err := testutil.RunCommandPipelineWithOutput(
550 550
 		exec.Command(dockerBinary, "cp", containerID+":/test", "-"),
551 551
 		exec.Command("tar", "-vtf", "-"))
552 552
 
... ...
@@ -3,7 +3,7 @@ package main
3 3
 import (
4 4
 	"os"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strconv"
10 10
 	"strings"
11 11
 
12
-	"github.com/docker/docker/pkg/integration/checker"
12
+	"github.com/docker/docker/integration-cli/checker"
13 13
 	"github.com/docker/docker/pkg/system"
14 14
 	"github.com/go-check/check"
15 15
 )
... ...
@@ -9,8 +9,8 @@ import (
9 9
 	"path/filepath"
10 10
 	"strings"
11 11
 
12
+	"github.com/docker/docker/integration-cli/checker"
12 13
 	"github.com/docker/docker/pkg/archive"
13
-	"github.com/docker/docker/pkg/integration/checker"
14 14
 	"github.com/go-check/check"
15 15
 )
16 16
 
... ...
@@ -12,9 +12,9 @@ import (
12 12
 
13 13
 	"io/ioutil"
14 14
 
15
-	"github.com/docker/docker/pkg/integration"
16
-	"github.com/docker/docker/pkg/integration/checker"
15
+	"github.com/docker/docker/integration-cli/checker"
17 16
 	"github.com/docker/docker/pkg/stringid"
17
+	"github.com/docker/docker/pkg/testutil"
18 18
 	"github.com/docker/go-connections/nat"
19 19
 	"github.com/go-check/check"
20 20
 )
... ...
@@ -356,7 +356,7 @@ func (s *DockerTrustSuite) TestCreateWhenCertExpired(c *check.C) {
356 356
 	// Certificates have 10 years of expiration
357 357
 	elevenYearsFromNow := time.Now().Add(time.Hour * 24 * 365 * 11)
358 358
 
359
-	integration.RunAtDifferentDate(elevenYearsFromNow, func() {
359
+	testutil.RunAtDifferentDate(elevenYearsFromNow, func() {
360 360
 		// Try create
361 361
 		createCmd := exec.Command(dockerBinary, "create", repoName)
362 362
 		s.trustedCmd(createCmd)
... ...
@@ -365,7 +365,7 @@ func (s *DockerTrustSuite) TestCreateWhenCertExpired(c *check.C) {
365 365
 		c.Assert(string(out), checker.Contains, "could not validate the path to a trusted root", check.Commentf("Missing expected output on trusted create in the distant future:\n%s", out))
366 366
 	})
367 367
 
368
-	integration.RunAtDifferentDate(elevenYearsFromNow, func() {
368
+	testutil.RunAtDifferentDate(elevenYearsFromNow, func() {
369 369
 		// Try create
370 370
 		createCmd := exec.Command(dockerBinary, "create", "--disable-content-trust", repoName)
371 371
 		s.trustedCmd(createCmd)
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strings"
10 10
 	"syscall"
11 11
 
12
-	"github.com/docker/docker/pkg/integration/checker"
12
+	"github.com/docker/docker/integration-cli/checker"
13 13
 	"github.com/docker/docker/pkg/mount"
14 14
 	"github.com/go-check/check"
15 15
 )
... ...
@@ -21,12 +21,12 @@ import (
21 21
 	"syscall"
22 22
 	"time"
23 23
 
24
+	"github.com/docker/docker/integration-cli/checker"
24 25
 	"github.com/docker/docker/integration-cli/daemon"
25
-	"github.com/docker/docker/pkg/integration"
26
-	"github.com/docker/docker/pkg/integration/checker"
27
-	icmd "github.com/docker/docker/pkg/integration/cmd"
28 26
 	"github.com/docker/docker/pkg/mount"
29 27
 	"github.com/docker/docker/pkg/stringid"
28
+	"github.com/docker/docker/pkg/testutil"
29
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
30 30
 	"github.com/docker/go-units"
31 31
 	"github.com/docker/libnetwork/iptables"
32 32
 	"github.com/docker/libtrust"
... ...
@@ -1899,7 +1899,7 @@ func (s *DockerDaemonSuite) TestDaemonCgroupParent(c *check.C) {
1899 1899
 
1900 1900
 	out, err := s.d.Cmd("run", "--name", name, "busybox", "cat", "/proc/self/cgroup")
1901 1901
 	c.Assert(err, checker.IsNil)
1902
-	cgroupPaths := integration.ParseCgroupPaths(string(out))
1902
+	cgroupPaths := testutil.ParseCgroupPaths(string(out))
1903 1903
 	c.Assert(len(cgroupPaths), checker.Not(checker.Equals), 0, check.Commentf("unexpected output - %q", string(out)))
1904 1904
 	out, err = s.d.Cmd("inspect", "-f", "{{.Id}}", name)
1905 1905
 	c.Assert(err, checker.IsNil)
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"strings"
5 5
 	"time"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -14,9 +14,9 @@ import (
14 14
 
15 15
 	eventtypes "github.com/docker/docker/api/types/events"
16 16
 	eventstestutils "github.com/docker/docker/daemon/events/testutils"
17
-	"github.com/docker/docker/pkg/integration"
18
-	"github.com/docker/docker/pkg/integration/checker"
19
-	icmd "github.com/docker/docker/pkg/integration/cmd"
17
+	"github.com/docker/docker/integration-cli/checker"
18
+	"github.com/docker/docker/pkg/testutil"
19
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
20 20
 	"github.com/go-check/check"
21 21
 )
22 22
 
... ...
@@ -222,7 +222,7 @@ func (s *DockerSuite) TestEventsImageImport(c *check.C) {
222 222
 	cleanedContainerID := strings.TrimSpace(out)
223 223
 
224 224
 	since := daemonUnixTime(c)
225
-	out, _, err := integration.RunCommandPipelineWithOutput(
225
+	out, _, err := testutil.RunCommandPipelineWithOutput(
226 226
 		exec.Command(dockerBinary, "export", cleanedContainerID),
227 227
 		exec.Command(dockerBinary, "import", "-"),
228 228
 	)
... ...
@@ -14,7 +14,7 @@ import (
14 14
 	"time"
15 15
 	"unicode"
16 16
 
17
-	"github.com/docker/docker/pkg/integration/checker"
17
+	"github.com/docker/docker/integration-cli/checker"
18 18
 	"github.com/go-check/check"
19 19
 	"github.com/kr/pty"
20 20
 )
... ...
@@ -15,8 +15,8 @@ import (
15 15
 	"sync"
16 16
 	"time"
17 17
 
18
-	"github.com/docker/docker/pkg/integration/checker"
19
-	icmd "github.com/docker/docker/pkg/integration/cmd"
18
+	"github.com/docker/docker/integration-cli/checker"
19
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
20 20
 	"github.com/go-check/check"
21 21
 )
22 22
 
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strings"
10 10
 	"time"
11 11
 
12
-	"github.com/docker/docker/pkg/integration/checker"
12
+	"github.com/docker/docker/integration-cli/checker"
13 13
 	"github.com/go-check/check"
14 14
 	"github.com/kr/pty"
15 15
 )
... ...
@@ -3,7 +3,7 @@ package main
3 3
 import (
4 4
 	"strings"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"os/exec"
6 6
 	"strings"
7 7
 
8
-	"github.com/docker/docker/pkg/integration/checker"
8
+	"github.com/docker/docker/integration-cli/checker"
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
... ...
@@ -16,8 +16,8 @@ import (
16 16
 	"time"
17 17
 
18 18
 	"github.com/docker/docker/api/types"
19
+	"github.com/docker/docker/integration-cli/checker"
19 20
 	"github.com/docker/docker/integration-cli/daemon"
20
-	"github.com/docker/docker/pkg/integration/checker"
21 21
 	"github.com/docker/docker/pkg/stringid"
22 22
 	"github.com/docker/docker/volume"
23 23
 	"github.com/go-check/check"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"time"
9 9
 
10 10
 	"github.com/docker/docker/api/types"
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -7,9 +7,9 @@ import (
7 7
 	"strings"
8 8
 	"unicode"
9 9
 
10
+	"github.com/docker/docker/integration-cli/checker"
10 11
 	"github.com/docker/docker/pkg/homedir"
11
-	"github.com/docker/docker/pkg/integration/checker"
12
-	icmd "github.com/docker/docker/pkg/integration/cmd"
12
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
13 13
 	"github.com/go-check/check"
14 14
 )
15 15
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strconv"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"strings"
11 11
 	"time"
12 12
 
13
-	"github.com/docker/docker/pkg/integration/checker"
13
+	"github.com/docker/docker/integration-cli/checker"
14 14
 	"github.com/docker/docker/pkg/stringid"
15 15
 	"github.com/go-check/check"
16 16
 )
... ...
@@ -9,9 +9,9 @@ import (
9 9
 	"regexp"
10 10
 	"strings"
11 11
 
12
-	"github.com/docker/docker/pkg/integration"
13
-	"github.com/docker/docker/pkg/integration/checker"
14
-	icmd "github.com/docker/docker/pkg/integration/cmd"
12
+	"github.com/docker/docker/integration-cli/checker"
13
+	"github.com/docker/docker/pkg/testutil"
14
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
15 15
 	"github.com/go-check/check"
16 16
 )
17 17
 
... ...
@@ -20,7 +20,7 @@ func (s *DockerSuite) TestImportDisplay(c *check.C) {
20 20
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
21 21
 	cleanedContainerID := strings.TrimSpace(out)
22 22
 
23
-	out, _, err := integration.RunCommandPipelineWithOutput(
23
+	out, _, err := testutil.RunCommandPipelineWithOutput(
24 24
 		exec.Command(dockerBinary, "export", cleanedContainerID),
25 25
 		exec.Command(dockerBinary, "import", "-"),
26 26
 	)
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"net"
7 7
 	"strings"
8 8
 
9
+	"github.com/docker/docker/integration-cli/checker"
9 10
 	"github.com/docker/docker/integration-cli/daemon"
10
-	"github.com/docker/docker/pkg/integration/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -3,7 +3,7 @@
3 3
 package main
4 4
 
5 5
 import (
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -10,9 +10,9 @@ import (
10 10
 
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/container"
13
+	"github.com/docker/docker/integration-cli/checker"
13 14
 	"github.com/docker/docker/integration-cli/environment"
14
-	"github.com/docker/docker/pkg/integration/checker"
15
-	icmd "github.com/docker/docker/pkg/integration/cmd"
15
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
16 16
 	"github.com/go-check/check"
17 17
 )
18 18
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strings"
7 7
 	"time"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"regexp"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/docker/pkg/integration"
10
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10
+	"github.com/docker/docker/pkg/testutil"
11 11
 	"github.com/docker/docker/runconfig"
12 12
 	"github.com/go-check/check"
13 13
 )
... ...
@@ -102,7 +102,7 @@ func (s *DockerSuite) TestLinksInspectLinksStarted(c *check.C) {
102 102
 	err := json.Unmarshal([]byte(links), &result)
103 103
 	c.Assert(err, checker.IsNil)
104 104
 
105
-	output := integration.ConvertSliceOfStringsToMap(result)
105
+	output := testutil.ConvertSliceOfStringsToMap(result)
106 106
 
107 107
 	c.Assert(output, checker.DeepEquals, expected)
108 108
 }
... ...
@@ -121,7 +121,7 @@ func (s *DockerSuite) TestLinksInspectLinksStopped(c *check.C) {
121 121
 	err := json.Unmarshal([]byte(links), &result)
122 122
 	c.Assert(err, checker.IsNil)
123 123
 
124
-	output := integration.ConvertSliceOfStringsToMap(result)
124
+	output := testutil.ConvertSliceOfStringsToMap(result)
125 125
 
126 126
 	c.Assert(output, checker.DeepEquals, expected)
127 127
 }
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"io/ioutil"
7 7
 	"os"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"bytes"
5 5
 	"os/exec"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"os/exec"
9 9
 	"path/filepath"
10 10
 
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -8,9 +8,9 @@ import (
8 8
 	"strings"
9 9
 	"time"
10 10
 
11
-	"github.com/docker/docker/pkg/integration"
12
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
13 12
 	"github.com/docker/docker/pkg/jsonlog"
13
+	"github.com/docker/docker/pkg/testutil"
14 14
 	"github.com/go-check/check"
15 15
 )
16 16
 
... ...
@@ -254,11 +254,11 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) {
254 254
 	c.Assert(logCmd.Start(), checker.IsNil)
255 255
 
256 256
 	// First read slowly
257
-	bytes1, err := integration.ConsumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
257
+	bytes1, err := testutil.ConsumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
258 258
 	c.Assert(err, checker.IsNil)
259 259
 
260 260
 	// After the container has finished we can continue reading fast
261
-	bytes2, err := integration.ConsumeWithSpeed(stdout, 32*1024, 0, nil)
261
+	bytes2, err := testutil.ConsumeWithSpeed(stdout, 32*1024, 0, nil)
262 262
 	c.Assert(err, checker.IsNil)
263 263
 
264 264
 	actual := bytes1 + bytes2
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"net"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -1,7 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"github.com/docker/docker/pkg/integration/checker"
4
+	"github.com/docker/docker/integration-cli/checker"
5 5
 	"github.com/docker/docker/runconfig"
6 6
 	"github.com/go-check/check"
7 7
 )
... ...
@@ -16,10 +16,10 @@ import (
16 16
 
17 17
 	"github.com/docker/docker/api/types"
18 18
 	"github.com/docker/docker/api/types/versions/v1p20"
19
+	"github.com/docker/docker/integration-cli/checker"
19 20
 	"github.com/docker/docker/integration-cli/daemon"
20
-	"github.com/docker/docker/pkg/integration/checker"
21
-	icmd "github.com/docker/docker/pkg/integration/cmd"
22 21
 	"github.com/docker/docker/pkg/stringid"
22
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
23 23
 	"github.com/docker/docker/runconfig"
24 24
 	"github.com/docker/libnetwork/driverapi"
25 25
 	remoteapi "github.com/docker/libnetwork/drivers/remote/api"
... ...
@@ -3,7 +3,7 @@
3 3
 package main
4 4
 
5 5
 import (
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -3,7 +3,7 @@ package main
3 3
 import (
4 4
 	"strings"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"os/exec"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 
10 10
 	"io/ioutil"
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"sort"
8 8
 	"strings"
9 9
 
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"os/exec"
6 6
 	"strings"
7 7
 
8
-	"github.com/docker/docker/pkg/integration/checker"
8
+	"github.com/docker/docker/integration-cli/checker"
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"strconv"
7 7
 	"strings"
8 8
 
9
+	"github.com/docker/docker/integration-cli/checker"
9 10
 	"github.com/docker/docker/integration-cli/daemon"
10
-	"github.com/docker/docker/pkg/integration/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -11,9 +11,9 @@ import (
11 11
 	"strings"
12 12
 	"time"
13 13
 
14
-	"github.com/docker/docker/pkg/integration/checker"
15
-	icmd "github.com/docker/docker/pkg/integration/cmd"
14
+	"github.com/docker/docker/integration-cli/checker"
16 15
 	"github.com/docker/docker/pkg/stringid"
16
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
17 17
 	"github.com/go-check/check"
18 18
 )
19 19
 
... ...
@@ -15,7 +15,7 @@ import (
15 15
 	"github.com/docker/distribution/manifest"
16 16
 	"github.com/docker/distribution/manifest/manifestlist"
17 17
 	"github.com/docker/distribution/manifest/schema2"
18
-	"github.com/docker/docker/pkg/integration/checker"
18
+	"github.com/docker/docker/integration-cli/checker"
19 19
 	"github.com/go-check/check"
20 20
 )
21 21
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"time"
9 9
 
10 10
 	"github.com/docker/distribution/digest"
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -7,8 +7,8 @@ import (
7 7
 	"strings"
8 8
 	"time"
9 9
 
10
-	"github.com/docker/docker/pkg/integration"
11
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11
+	"github.com/docker/docker/pkg/testutil"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -70,7 +70,7 @@ func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) {
70 70
 	// Certificates have 10 years of expiration
71 71
 	elevenYearsFromNow := time.Now().Add(time.Hour * 24 * 365 * 11)
72 72
 
73
-	integration.RunAtDifferentDate(elevenYearsFromNow, func() {
73
+	testutil.RunAtDifferentDate(elevenYearsFromNow, func() {
74 74
 		// Try pull
75 75
 		pullCmd := exec.Command(dockerBinary, "pull", repoName)
76 76
 		s.trustedCmd(pullCmd)
... ...
@@ -80,7 +80,7 @@ func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) {
80 80
 		c.Assert(string(out), checker.Contains, "could not validate the path to a trusted root", check.Commentf(out))
81 81
 	})
82 82
 
83
-	integration.RunAtDifferentDate(elevenYearsFromNow, func() {
83
+	testutil.RunAtDifferentDate(elevenYearsFromNow, func() {
84 84
 		// Try pull
85 85
 		pullCmd := exec.Command(dockerBinary, "pull", "--disable-content-trust", repoName)
86 86
 		s.trustedCmd(pullCmd)
... ...
@@ -167,7 +167,7 @@ func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) {
167 167
 	// Snapshots last for three years. This should be expired
168 168
 	fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4)
169 169
 
170
-	integration.RunAtDifferentDate(fourYearsLater, func() {
170
+	testutil.RunAtDifferentDate(fourYearsLater, func() {
171 171
 		// Try pull
172 172
 		pullCmd := exec.Command(dockerBinary, "pull", repoName)
173 173
 		s.trustedCmd(pullCmd)
... ...
@@ -15,8 +15,8 @@ import (
15 15
 
16 16
 	"github.com/docker/distribution/reference"
17 17
 	cliconfig "github.com/docker/docker/cli/config"
18
-	"github.com/docker/docker/pkg/integration"
19
-	"github.com/docker/docker/pkg/integration/checker"
18
+	"github.com/docker/docker/integration-cli/checker"
19
+	"github.com/docker/docker/pkg/testutil"
20 20
 	"github.com/go-check/check"
21 21
 )
22 22
 
... ...
@@ -438,7 +438,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) {
438 438
 	// Snapshots last for three years. This should be expired
439 439
 	fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4)
440 440
 
441
-	integration.RunAtDifferentDate(fourYearsLater, func() {
441
+	testutil.RunAtDifferentDate(fourYearsLater, func() {
442 442
 		// Push with wrong passphrases
443 443
 		pushCmd = exec.Command(dockerBinary, "push", repoName)
444 444
 		s.trustedCmd(pushCmd)
... ...
@@ -465,7 +465,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithExpiredTimestamp(c *check.C) {
465 465
 	threeWeeksLater := time.Now().Add(time.Hour * 24 * 21)
466 466
 
467 467
 	// Should succeed because the server transparently re-signs one
468
-	integration.RunAtDifferentDate(threeWeeksLater, func() {
468
+	testutil.RunAtDifferentDate(threeWeeksLater, func() {
469 469
 		pushCmd := exec.Command(dockerBinary, "push", repoName)
470 470
 		s.trustedCmd(pushCmd)
471 471
 		out, _, err := runCommandWithOutput(pushCmd)
... ...
@@ -3,9 +3,9 @@ package main
3 3
 import (
4 4
 	"strings"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
7
-	icmd "github.com/docker/docker/pkg/integration/cmd"
6
+	"github.com/docker/docker/integration-cli/checker"
8 7
 	"github.com/docker/docker/pkg/stringid"
8
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strings"
7 7
 	"time"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"io/ioutil"
5 5
 	"os"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strings"
7 7
 	"time"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/docker/docker/pkg/stringid"
11 11
 	"github.com/go-check/check"
12 12
 )
... ...
@@ -21,12 +21,12 @@ import (
21 21
 	"sync"
22 22
 	"time"
23 23
 
24
-	"github.com/docker/docker/pkg/integration"
25
-	"github.com/docker/docker/pkg/integration/checker"
26
-	icmd "github.com/docker/docker/pkg/integration/cmd"
24
+	"github.com/docker/docker/integration-cli/checker"
27 25
 	"github.com/docker/docker/pkg/mount"
28 26
 	"github.com/docker/docker/pkg/stringid"
29 27
 	"github.com/docker/docker/pkg/stringutils"
28
+	"github.com/docker/docker/pkg/testutil"
29
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
30 30
 	"github.com/docker/docker/runconfig"
31 31
 	"github.com/docker/go-connections/nat"
32 32
 	"github.com/docker/libnetwork/resolvconf"
... ...
@@ -498,7 +498,7 @@ func (s *DockerSuite) TestRunVolumesFromInReadWriteMode(c *check.C) {
498 498
 func (s *DockerSuite) TestVolumesFromGetsProperMode(c *check.C) {
499 499
 	testRequires(c, SameHostDaemon)
500 500
 	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
501
-	hostpath := integration.RandomTmpDirPath("test", daemonPlatform)
501
+	hostpath := testutil.RandomTmpDirPath("test", daemonPlatform)
502 502
 	if err := os.MkdirAll(hostpath, 0755); err != nil {
503 503
 		c.Fatalf("Failed to create %s: %q", hostpath, err)
504 504
 	}
... ...
@@ -521,8 +521,8 @@ func (s *DockerSuite) TestVolumesFromGetsProperMode(c *check.C) {
521 521
 
522 522
 // Test for GH#10618
523 523
 func (s *DockerSuite) TestRunNoDupVolumes(c *check.C) {
524
-	path1 := integration.RandomTmpDirPath("test1", daemonPlatform)
525
-	path2 := integration.RandomTmpDirPath("test2", daemonPlatform)
524
+	path1 := testutil.RandomTmpDirPath("test1", daemonPlatform)
525
+	path2 := testutil.RandomTmpDirPath("test2", daemonPlatform)
526 526
 
527 527
 	someplace := ":/someplace"
528 528
 	if daemonPlatform == "windows" {
... ...
@@ -2275,7 +2275,7 @@ func (s *DockerSuite) TestVolumesNoCopyData(c *check.C) {
2275 2275
 		c.Fatalf("Data was copied on volumes-from but shouldn't be:\n%q", out)
2276 2276
 	}
2277 2277
 
2278
-	tmpDir := integration.RandomTmpDirPath("docker_test_bind_mount_copy_data", daemonPlatform)
2278
+	tmpDir := testutil.RandomTmpDirPath("docker_test_bind_mount_copy_data", daemonPlatform)
2279 2279
 	if out, _, err := dockerCmdWithError("run", "-v", tmpDir+":/foo", "dataimage", "ls", "-lh", "/foo/bar"); err == nil || !strings.Contains(out, "No such file or directory") {
2280 2280
 		c.Fatalf("Data was copied on bind-mount but shouldn't be:\n%q", out)
2281 2281
 	}
... ...
@@ -2344,7 +2344,7 @@ func (s *DockerSuite) TestRunSlowStdoutConsumer(c *check.C) {
2344 2344
 	if err := cont.Start(); err != nil {
2345 2345
 		c.Fatal(err)
2346 2346
 	}
2347
-	n, err := integration.ConsumeWithSpeed(stdout, 10000, 5*time.Millisecond, nil)
2347
+	n, err := testutil.ConsumeWithSpeed(stdout, 10000, 5*time.Millisecond, nil)
2348 2348
 	if err != nil {
2349 2349
 		c.Fatal(err)
2350 2350
 	}
... ...
@@ -3326,7 +3326,7 @@ func (s *DockerTrustSuite) TestRunWhenCertExpired(c *check.C) {
3326 3326
 	// Certificates have 10 years of expiration
3327 3327
 	elevenYearsFromNow := time.Now().Add(time.Hour * 24 * 365 * 11)
3328 3328
 
3329
-	integration.RunAtDifferentDate(elevenYearsFromNow, func() {
3329
+	testutil.RunAtDifferentDate(elevenYearsFromNow, func() {
3330 3330
 		// Try run
3331 3331
 		runCmd := exec.Command(dockerBinary, "run", repoName)
3332 3332
 		s.trustedCmd(runCmd)
... ...
@@ -3340,7 +3340,7 @@ func (s *DockerTrustSuite) TestRunWhenCertExpired(c *check.C) {
3340 3340
 		}
3341 3341
 	})
3342 3342
 
3343
-	integration.RunAtDifferentDate(elevenYearsFromNow, func() {
3343
+	testutil.RunAtDifferentDate(elevenYearsFromNow, func() {
3344 3344
 		// Try run
3345 3345
 		runCmd := exec.Command(dockerBinary, "run", "--disable-content-trust", repoName)
3346 3346
 		s.trustedCmd(runCmd)
... ...
@@ -3532,7 +3532,7 @@ func (s *DockerSuite) TestRunContainerWithCgroupParent(c *check.C) {
3532 3532
 	if err != nil {
3533 3533
 		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
3534 3534
 	}
3535
-	cgroupPaths := integration.ParseCgroupPaths(string(out))
3535
+	cgroupPaths := testutil.ParseCgroupPaths(string(out))
3536 3536
 	if len(cgroupPaths) == 0 {
3537 3537
 		c.Fatalf("unexpected output - %q", string(out))
3538 3538
 	}
... ...
@@ -3561,7 +3561,7 @@ func (s *DockerSuite) TestRunContainerWithCgroupParentAbsPath(c *check.C) {
3561 3561
 	if err != nil {
3562 3562
 		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
3563 3563
 	}
3564
-	cgroupPaths := integration.ParseCgroupPaths(string(out))
3564
+	cgroupPaths := testutil.ParseCgroupPaths(string(out))
3565 3565
 	if len(cgroupPaths) == 0 {
3566 3566
 		c.Fatalf("unexpected output - %q", string(out))
3567 3567
 	}
... ...
@@ -3600,7 +3600,7 @@ func (s *DockerSuite) TestRunInvalidCgroupParent(c *check.C) {
3600 3600
 		c.Fatalf("SECURITY: --cgroup-parent with ../../ relative paths cause files to be created in the host (this is bad) !!")
3601 3601
 	}
3602 3602
 
3603
-	cgroupPaths := integration.ParseCgroupPaths(string(out))
3603
+	cgroupPaths := testutil.ParseCgroupPaths(string(out))
3604 3604
 	if len(cgroupPaths) == 0 {
3605 3605
 		c.Fatalf("unexpected output - %q", string(out))
3606 3606
 	}
... ...
@@ -3639,7 +3639,7 @@ func (s *DockerSuite) TestRunAbsoluteInvalidCgroupParent(c *check.C) {
3639 3639
 		c.Fatalf("SECURITY: --cgroup-parent with /../../ garbage paths cause files to be created in the host (this is bad) !!")
3640 3640
 	}
3641 3641
 
3642
-	cgroupPaths := integration.ParseCgroupPaths(string(out))
3642
+	cgroupPaths := testutil.ParseCgroupPaths(string(out))
3643 3643
 	if len(cgroupPaths) == 0 {
3644 3644
 		c.Fatalf("unexpected output - %q", string(out))
3645 3645
 	}
... ...
@@ -16,8 +16,8 @@ import (
16 16
 	"syscall"
17 17
 	"time"
18 18
 
19
+	"github.com/docker/docker/integration-cli/checker"
19 20
 	"github.com/docker/docker/pkg/homedir"
20
-	"github.com/docker/docker/pkg/integration/checker"
21 21
 	"github.com/docker/docker/pkg/mount"
22 22
 	"github.com/docker/docker/pkg/parsers"
23 23
 	"github.com/docker/docker/pkg/sysinfo"
... ...
@@ -14,8 +14,8 @@ import (
14 14
 	"time"
15 15
 
16 16
 	"github.com/docker/distribution/digest"
17
-	"github.com/docker/docker/pkg/integration"
18
-	"github.com/docker/docker/pkg/integration/checker"
17
+	"github.com/docker/docker/integration-cli/checker"
18
+	"github.com/docker/docker/pkg/testutil"
19 19
 	"github.com/go-check/check"
20 20
 )
21 21
 
... ...
@@ -30,7 +30,7 @@ func (s *DockerSuite) TestSaveXzAndLoadRepoStdout(c *check.C) {
30 30
 
31 31
 	dockerCmd(c, "inspect", repoName)
32 32
 
33
-	repoTarball, _, err := integration.RunCommandPipelineWithOutput(
33
+	repoTarball, _, err := testutil.RunCommandPipelineWithOutput(
34 34
 		exec.Command(dockerBinary, "save", repoName),
35 35
 		exec.Command("xz", "-c"),
36 36
 		exec.Command("gzip", "-c"))
... ...
@@ -57,7 +57,7 @@ func (s *DockerSuite) TestSaveXzGzAndLoadRepoStdout(c *check.C) {
57 57
 
58 58
 	dockerCmd(c, "inspect", repoName)
59 59
 
60
-	out, _, err := integration.RunCommandPipelineWithOutput(
60
+	out, _, err := testutil.RunCommandPipelineWithOutput(
61 61
 		exec.Command(dockerBinary, "save", repoName),
62 62
 		exec.Command("xz", "-c"),
63 63
 		exec.Command("gzip", "-c"))
... ...
@@ -82,7 +82,7 @@ func (s *DockerSuite) TestSaveSingleTag(c *check.C) {
82 82
 	out, _ := dockerCmd(c, "images", "-q", "--no-trunc", repoName)
83 83
 	cleanedImageID := strings.TrimSpace(out)
84 84
 
85
-	out, _, err := integration.RunCommandPipelineWithOutput(
85
+	out, _, err := testutil.RunCommandPipelineWithOutput(
86 86
 		exec.Command(dockerBinary, "save", fmt.Sprintf("%v:latest", repoName)),
87 87
 		exec.Command("tar", "t"),
88 88
 		exec.Command("grep", "-E", fmt.Sprintf("(^repositories$|%v)", cleanedImageID)))
... ...
@@ -101,7 +101,7 @@ func (s *DockerSuite) TestSaveCheckTimes(c *check.C) {
101 101
 	c.Assert(err, checker.IsNil, check.Commentf("failed to marshal from %q: err %v", repoName, err))
102 102
 	c.Assert(len(data), checker.Not(checker.Equals), 0, check.Commentf("failed to marshal the data from %q", repoName))
103 103
 	tarTvTimeFormat := "2006-01-02 15:04"
104
-	out, _, err = integration.RunCommandPipelineWithOutput(
104
+	out, _, err = testutil.RunCommandPipelineWithOutput(
105 105
 		exec.Command(dockerBinary, "save", repoName),
106 106
 		exec.Command("tar", "tv"),
107 107
 		exec.Command("grep", "-E", fmt.Sprintf("%s %s", data[0].Created.Format(tarTvTimeFormat), digest.Digest(data[0].ID).Hex())))
... ...
@@ -159,7 +159,7 @@ func (s *DockerSuite) TestSaveAndLoadRepoFlags(c *check.C) {
159 159
 
160 160
 	before, _ := dockerCmd(c, "inspect", repoName)
161 161
 
162
-	out, _, err := integration.RunCommandPipelineWithOutput(
162
+	out, _, err := testutil.RunCommandPipelineWithOutput(
163 163
 		exec.Command(dockerBinary, "save", repoName),
164 164
 		exec.Command(dockerBinary, "load"))
165 165
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
... ...
@@ -188,7 +188,7 @@ func (s *DockerSuite) TestSaveMultipleNames(c *check.C) {
188 188
 	// Make two images
189 189
 	dockerCmd(c, "tag", "emptyfs:latest", fmt.Sprintf("%v-two:latest", repoName))
190 190
 
191
-	out, _, err := integration.RunCommandPipelineWithOutput(
191
+	out, _, err := testutil.RunCommandPipelineWithOutput(
192 192
 		exec.Command(dockerBinary, "save", fmt.Sprintf("%v-one", repoName), fmt.Sprintf("%v-two:latest", repoName)),
193 193
 		exec.Command("tar", "xO", "repositories"),
194 194
 		exec.Command("grep", "-q", "-E", "(-one|-two)"),
... ...
@@ -220,7 +220,7 @@ func (s *DockerSuite) TestSaveRepoWithMultipleImages(c *check.C) {
220 220
 	deleteImages(repoName)
221 221
 
222 222
 	// create the archive
223
-	out, _, err := integration.RunCommandPipelineWithOutput(
223
+	out, _, err := testutil.RunCommandPipelineWithOutput(
224 224
 		exec.Command(dockerBinary, "save", repoName, "busybox:latest"),
225 225
 		exec.Command("tar", "t"))
226 226
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save multiple images: %s, %v", out, err))
... ...
@@ -267,7 +267,7 @@ func (s *DockerSuite) TestSaveDirectoryPermissions(c *check.C) {
267 267
 		true)
268 268
 	c.Assert(err, checker.IsNil, check.Commentf("%v", err))
269 269
 
270
-	out, _, err := integration.RunCommandPipelineWithOutput(
270
+	out, _, err := testutil.RunCommandPipelineWithOutput(
271 271
 		exec.Command(dockerBinary, "save", name),
272 272
 		exec.Command("tar", "-xf", "-", "-C", extractionDirectory),
273 273
 	)
... ...
@@ -286,7 +286,7 @@ func (s *DockerSuite) TestSaveDirectoryPermissions(c *check.C) {
286 286
 			c.Assert(err, checker.IsNil, check.Commentf("failed to open %s: %s", layerPath, err))
287 287
 			defer f.Close()
288 288
 
289
-			entries, err := integration.ListTar(f)
289
+			entries, err := testutil.ListTar(f)
290 290
 			for _, e := range entries {
291 291
 				if !strings.Contains(e, "dev/") {
292 292
 					entriesSansDev = append(entriesSansDev, e)
... ...
@@ -364,7 +364,7 @@ func (s *DockerSuite) TestSaveLoadNoTag(c *check.C) {
364 364
 	id := inspectField(c, name, "Id")
365 365
 
366 366
 	// Test to make sure that save w/o name just shows imageID during load
367
-	out, _, err := integration.RunCommandPipelineWithOutput(
367
+	out, _, err := testutil.RunCommandPipelineWithOutput(
368 368
 		exec.Command(dockerBinary, "save", id),
369 369
 		exec.Command(dockerBinary, "load"))
370 370
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
... ...
@@ -375,7 +375,7 @@ func (s *DockerSuite) TestSaveLoadNoTag(c *check.C) {
375 375
 	c.Assert(out, checker.Contains, id)
376 376
 
377 377
 	// Test to make sure that save by name shows that name during load
378
-	out, _, err = integration.RunCommandPipelineWithOutput(
378
+	out, _, err = testutil.RunCommandPipelineWithOutput(
379 379
 		exec.Command(dockerBinary, "save", name),
380 380
 		exec.Command(dockerBinary, "load"))
381 381
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
... ...
@@ -11,8 +11,8 @@ import (
11 11
 	"strings"
12 12
 	"time"
13 13
 
14
-	"github.com/docker/docker/pkg/integration/checker"
15
-	icmd "github.com/docker/docker/pkg/integration/cmd"
14
+	"github.com/docker/docker/integration-cli/checker"
15
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
16 16
 	"github.com/go-check/check"
17 17
 	"github.com/kr/pty"
18 18
 )
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"strings"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"strings"
9 9
 
10 10
 	"github.com/docker/docker/api/types/swarm"
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"encoding/json"
7 7
 
8 8
 	"github.com/docker/docker/api/types/swarm"
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"github.com/docker/docker/api/types"
11 11
 	"github.com/docker/docker/api/types/mount"
12 12
 	"github.com/docker/docker/api/types/swarm"
13
-	"github.com/docker/docker/pkg/integration/checker"
13
+	"github.com/docker/docker/integration-cli/checker"
14 14
 	"github.com/go-check/check"
15 15
 )
16 16
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 
9 9
 	"github.com/docker/docker/api/types/swarm"
10 10
 	"github.com/docker/docker/daemon/cluster/executor/container"
11
-	"github.com/docker/docker/pkg/integration/checker"
11
+	"github.com/docker/docker/integration-cli/checker"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"os/exec"
10 10
 	"strings"
11 11
 
12
-	"github.com/docker/docker/pkg/integration/checker"
12
+	"github.com/docker/docker/integration-cli/checker"
13 13
 	"github.com/go-check/check"
14 14
 )
15 15
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"fmt"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"fmt"
8 8
 
9 9
 	"github.com/docker/docker/api/types/swarm"
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"io/ioutil"
5 5
 	"os"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -5,8 +5,8 @@ import (
5 5
 	"strings"
6 6
 	"time"
7 7
 
8
-	"github.com/docker/docker/pkg/integration/checker"
9
-	icmd "github.com/docker/docker/pkg/integration/cmd"
8
+	"github.com/docker/docker/integration-cli/checker"
9
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"strings"
8 8
 	"time"
9 9
 
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -1,7 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"github.com/docker/docker/pkg/integration/checker"
4
+	"github.com/docker/docker/integration-cli/checker"
5 5
 	"github.com/go-check/check"
6 6
 )
7 7
 
... ...
@@ -15,8 +15,8 @@ import (
15 15
 	"time"
16 16
 
17 17
 	"github.com/docker/docker/api/types/swarm"
18
+	"github.com/docker/docker/integration-cli/checker"
18 19
 	"github.com/docker/docker/integration-cli/daemon"
19
-	"github.com/docker/docker/pkg/integration/checker"
20 20
 	"github.com/docker/libnetwork/driverapi"
21 21
 	"github.com/docker/libnetwork/ipamapi"
22 22
 	remoteipam "github.com/docker/libnetwork/ipams/remote/api"
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"strings"
8 8
 
9 9
 	"github.com/docker/docker/api/types/swarm"
10
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11 11
 	"github.com/go-check/check"
12 12
 )
13 13
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"strings"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/docker/docker/pkg/stringid"
9 9
 	"github.com/docker/docker/pkg/stringutils"
10 10
 	"github.com/go-check/check"
... ...
@@ -3,8 +3,8 @@ package main
3 3
 import (
4 4
 	"strings"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
7
-	icmd "github.com/docker/docker/pkg/integration/cmd"
6
+	"github.com/docker/docker/integration-cli/checker"
7
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"strings"
5 5
 	"time"
6 6
 
7
-	"github.com/docker/docker/pkg/integration/checker"
7
+	"github.com/docker/docker/integration-cli/checker"
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
... ...
@@ -11,7 +11,7 @@ import (
11 11
 	"time"
12 12
 
13 13
 	"github.com/docker/docker/api/types"
14
-	"github.com/docker/docker/pkg/integration/checker"
14
+	"github.com/docker/docker/integration-cli/checker"
15 15
 	"github.com/docker/docker/pkg/parsers/kernel"
16 16
 	"github.com/go-check/check"
17 17
 )
... ...
@@ -12,10 +12,10 @@ import (
12 12
 	"strconv"
13 13
 	"strings"
14 14
 
15
-	"github.com/docker/docker/pkg/integration"
16
-	"github.com/docker/docker/pkg/integration/checker"
15
+	"github.com/docker/docker/integration-cli/checker"
17 16
 	"github.com/docker/docker/pkg/stringid"
18 17
 	"github.com/docker/docker/pkg/system"
18
+	"github.com/docker/docker/pkg/testutil"
19 19
 	"github.com/go-check/check"
20 20
 )
21 21
 
... ...
@@ -62,12 +62,12 @@ func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) {
62 62
 	c.Assert(err, checker.IsNil, check.Commentf("Could not inspect running container: out: %q", pid))
63 63
 	// check the uid and gid maps for the PID to ensure root is remapped
64 64
 	// (cmd = cat /proc/<pid>/uid_map | grep -E '0\s+9999\s+1')
65
-	out, rc1, err := integration.RunCommandPipelineWithOutput(
65
+	out, rc1, err := testutil.RunCommandPipelineWithOutput(
66 66
 		exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/uid_map"),
67 67
 		exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", uid)))
68 68
 	c.Assert(rc1, checker.Equals, 0, check.Commentf("Didn't match uid_map: output: %s", out))
69 69
 
70
-	out, rc2, err := integration.RunCommandPipelineWithOutput(
70
+	out, rc2, err := testutil.RunCommandPipelineWithOutput(
71 71
 		exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/gid_map"),
72 72
 		exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", gid)))
73 73
 	c.Assert(rc2, checker.Equals, 0, check.Commentf("Didn't match gid_map: output: %s", out))
... ...
@@ -3,7 +3,7 @@ package main
3 3
 import (
4 4
 	"strings"
5 5
 
6
-	"github.com/docker/docker/pkg/integration/checker"
6
+	"github.com/docker/docker/integration-cli/checker"
7 7
 	"github.com/go-check/check"
8 8
 )
9 9
 
... ...
@@ -8,8 +8,8 @@ import (
8 8
 	"path/filepath"
9 9
 	"strings"
10 10
 
11
-	"github.com/docker/docker/pkg/integration/checker"
12
-	icmd "github.com/docker/docker/pkg/integration/cmd"
11
+	"github.com/docker/docker/integration-cli/checker"
12
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
13 13
 	"github.com/go-check/check"
14 14
 )
15 15
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strings"
7 7
 	"time"
8 8
 
9
-	"github.com/docker/docker/pkg/integration/checker"
9
+	"github.com/docker/docker/integration-cli/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -7,8 +7,8 @@ import (
7 7
 	"net/http"
8 8
 	"strings"
9 9
 
10
-	"github.com/docker/docker/pkg/integration"
11
-	"github.com/docker/docker/pkg/integration/checker"
10
+	"github.com/docker/docker/integration-cli/checker"
11
+	"github.com/docker/docker/pkg/testutil"
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
... ...
@@ -45,7 +45,7 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumeBinds(c *check.C) {
45 45
 	c.Assert(err, checker.IsNil)
46 46
 	c.Assert(status, checker.Equals, http.StatusCreated)
47 47
 
48
-	bindPath := integration.RandomTmpDirPath("test", daemonPlatform)
48
+	bindPath := testutil.RandomTmpDirPath("test", daemonPlatform)
49 49
 	config = map[string]interface{}{
50 50
 		"Binds": []string{bindPath + ":" + path},
51 51
 	}
... ...
@@ -72,8 +72,8 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartDupVolumeBinds(c *check.C)
72 72
 	c.Assert(err, checker.IsNil)
73 73
 	c.Assert(status, checker.Equals, http.StatusCreated)
74 74
 
75
-	bindPath1 := integration.RandomTmpDirPath("test1", daemonPlatform)
76
-	bindPath2 := integration.RandomTmpDirPath("test2", daemonPlatform)
75
+	bindPath1 := testutil.RandomTmpDirPath("test1", daemonPlatform)
76
+	bindPath2 := testutil.RandomTmpDirPath("test2", daemonPlatform)
77 77
 
78 78
 	config = map[string]interface{}{
79 79
 		"Binds": []string{bindPath1 + ":/tmp", bindPath2 + ":/tmp"},
... ...
@@ -151,7 +151,7 @@ func (s *DockerSuite) TestDeprecatedStartWithTooLowMemoryLimit(c *check.C) {
151 151
 
152 152
 	res, body, err := sockRequestRaw("POST", formatV123StartAPIURL("/containers/"+containerID+"/start"), strings.NewReader(config), "application/json")
153 153
 	c.Assert(err, checker.IsNil)
154
-	b, err2 := integration.ReadBody(body)
154
+	b, err2 := testutil.ReadBody(body)
155 155
 	c.Assert(err2, checker.IsNil)
156 156
 	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
157 157
 	c.Assert(string(b), checker.Contains, "Minimum memory limit allowed is 4MB")
... ...
@@ -5,7 +5,7 @@ package main
5 5
 import (
6 6
 	"fmt"
7 7
 
8
-	"github.com/docker/docker/pkg/integration/checker"
8
+	"github.com/docker/docker/integration-cli/checker"
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
... ...
@@ -7,9 +7,9 @@ import (
7 7
 	"strings"
8 8
 	"time"
9 9
 
10
-	"github.com/docker/docker/pkg/integration/checker"
11
-	icmd "github.com/docker/docker/pkg/integration/cmd"
10
+	"github.com/docker/docker/integration-cli/checker"
12 11
 	"github.com/docker/docker/pkg/parsers/kernel"
12
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
13 13
 	"github.com/go-check/check"
14 14
 )
15 15
 
... ...
@@ -5,8 +5,8 @@ import (
5 5
 	"runtime"
6 6
 	"strings"
7 7
 
8
+	"github.com/docker/docker/integration-cli/checker"
8 9
 	"github.com/docker/docker/integration-cli/daemon"
9
-	"github.com/docker/docker/pkg/integration/checker"
10 10
 	"github.com/go-check/check"
11 11
 )
12 12
 
... ...
@@ -23,13 +23,13 @@ import (
23 23
 
24 24
 	"github.com/docker/docker/api/types"
25 25
 	volumetypes "github.com/docker/docker/api/types/volume"
26
+	"github.com/docker/docker/integration-cli/checker"
26 27
 	"github.com/docker/docker/integration-cli/daemon"
27 28
 	"github.com/docker/docker/opts"
28
-	"github.com/docker/docker/pkg/integration"
29
-	"github.com/docker/docker/pkg/integration/checker"
30
-	icmd "github.com/docker/docker/pkg/integration/cmd"
31 29
 	"github.com/docker/docker/pkg/ioutils"
32 30
 	"github.com/docker/docker/pkg/stringutils"
31
+	"github.com/docker/docker/pkg/testutil"
32
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
33 33
 	"github.com/go-check/check"
34 34
 )
35 35
 
... ...
@@ -59,7 +59,7 @@ func sockRequest(method, endpoint string, data interface{}) (int, []byte, error)
59 59
 	if err != nil {
60 60
 		return -1, nil, err
61 61
 	}
62
-	b, err := integration.ReadBody(body)
62
+	b, err := testutil.ReadBody(body)
63 63
 	return res.StatusCode, b, err
64 64
 }
65 65
 
... ...
@@ -11,7 +11,7 @@ import (
11 11
 
12 12
 	"github.com/Sirupsen/logrus"
13 13
 	eventstestutils "github.com/docker/docker/daemon/events/testutils"
14
-	"github.com/docker/docker/pkg/integration/checker"
14
+	"github.com/docker/docker/integration-cli/checker"
15 15
 	"github.com/go-check/check"
16 16
 )
17 17
 
... ...
@@ -10,8 +10,8 @@ import (
10 10
 	"strings"
11 11
 	"sync"
12 12
 
13
+	"github.com/docker/docker/integration-cli/checker"
13 14
 	"github.com/docker/docker/integration-cli/fixtures/load"
14
-	"github.com/docker/docker/pkg/integration/checker"
15 15
 	"github.com/go-check/check"
16 16
 )
17 17
 
... ...
@@ -12,7 +12,7 @@ import (
12 12
 	"time"
13 13
 
14 14
 	cliconfig "github.com/docker/docker/cli/config"
15
-	"github.com/docker/docker/pkg/integration/checker"
15
+	"github.com/docker/docker/integration-cli/checker"
16 16
 	"github.com/docker/go-connections/tlsconfig"
17 17
 	"github.com/go-check/check"
18 18
 )
... ...
@@ -1,7 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"github.com/docker/docker/pkg/integration/cmd"
4
+	"github.com/docker/docker/pkg/testutil/cmd"
5 5
 	"os/exec"
6 6
 )
7 7
 
8 8
deleted file mode 100644
... ...
@@ -1,46 +0,0 @@
1
-// Package checker provides Docker specific implementations of the go-check.Checker interface.
2
-package checker
3
-
4
-import (
5
-	"github.com/go-check/check"
6
-	"github.com/vdemeester/shakers"
7
-)
8
-
9
-// As a commodity, we bring all check.Checker variables into the current namespace to avoid having
10
-// to think about check.X versus checker.X.
11
-var (
12
-	DeepEquals   = check.DeepEquals
13
-	ErrorMatches = check.ErrorMatches
14
-	FitsTypeOf   = check.FitsTypeOf
15
-	HasLen       = check.HasLen
16
-	Implements   = check.Implements
17
-	IsNil        = check.IsNil
18
-	Matches      = check.Matches
19
-	Not          = check.Not
20
-	NotNil       = check.NotNil
21
-	PanicMatches = check.PanicMatches
22
-	Panics       = check.Panics
23
-
24
-	Contains           = shakers.Contains
25
-	ContainsAny        = shakers.ContainsAny
26
-	Count              = shakers.Count
27
-	Equals             = shakers.Equals
28
-	EqualFold          = shakers.EqualFold
29
-	False              = shakers.False
30
-	GreaterOrEqualThan = shakers.GreaterOrEqualThan
31
-	GreaterThan        = shakers.GreaterThan
32
-	HasPrefix          = shakers.HasPrefix
33
-	HasSuffix          = shakers.HasSuffix
34
-	Index              = shakers.Index
35
-	IndexAny           = shakers.IndexAny
36
-	IsAfter            = shakers.IsAfter
37
-	IsBefore           = shakers.IsBefore
38
-	IsBetween          = shakers.IsBetween
39
-	IsLower            = shakers.IsLower
40
-	IsUpper            = shakers.IsUpper
41
-	LessOrEqualThan    = shakers.LessOrEqualThan
42
-	LessThan           = shakers.LessThan
43
-	TimeEquals         = shakers.TimeEquals
44
-	True               = shakers.True
45
-	TimeIgnore         = shakers.TimeIgnore
46
-)
47 1
deleted file mode 100644
... ...
@@ -1,294 +0,0 @@
1
-package cmd
2
-
3
-import (
4
-	"bytes"
5
-	"fmt"
6
-	"io"
7
-	"os/exec"
8
-	"path/filepath"
9
-	"runtime"
10
-	"strings"
11
-	"sync"
12
-	"time"
13
-
14
-	"github.com/docker/docker/pkg/system"
15
-	"github.com/go-check/check"
16
-)
17
-
18
-type testingT interface {
19
-	Fatalf(string, ...interface{})
20
-}
21
-
22
-const (
23
-	// None is a token to inform Result.Assert that the output should be empty
24
-	None string = "<NOTHING>"
25
-)
26
-
27
-type lockedBuffer struct {
28
-	m   sync.RWMutex
29
-	buf bytes.Buffer
30
-}
31
-
32
-func (buf *lockedBuffer) Write(b []byte) (int, error) {
33
-	buf.m.Lock()
34
-	defer buf.m.Unlock()
35
-	return buf.buf.Write(b)
36
-}
37
-
38
-func (buf *lockedBuffer) String() string {
39
-	buf.m.RLock()
40
-	defer buf.m.RUnlock()
41
-	return buf.buf.String()
42
-}
43
-
44
-// Result stores the result of running a command
45
-type Result struct {
46
-	Cmd      *exec.Cmd
47
-	ExitCode int
48
-	Error    error
49
-	// Timeout is true if the command was killed because it ran for too long
50
-	Timeout   bool
51
-	outBuffer *lockedBuffer
52
-	errBuffer *lockedBuffer
53
-}
54
-
55
-// Assert compares the Result against the Expected struct, and fails the test if
56
-// any of the expcetations are not met.
57
-func (r *Result) Assert(t testingT, exp Expected) {
58
-	err := r.Compare(exp)
59
-	if err == nil {
60
-		return
61
-	}
62
-
63
-	_, file, line, _ := runtime.Caller(1)
64
-	t.Fatalf("at %s:%d\n%s", filepath.Base(file), line, err.Error())
65
-}
66
-
67
-// Compare returns a formatted error with the command, stdout, stderr, exit
68
-// code, and any failed expectations
69
-func (r *Result) Compare(exp Expected) error {
70
-	errors := []string{}
71
-	add := func(format string, args ...interface{}) {
72
-		errors = append(errors, fmt.Sprintf(format, args...))
73
-	}
74
-
75
-	if exp.ExitCode != r.ExitCode {
76
-		add("ExitCode was %d expected %d", r.ExitCode, exp.ExitCode)
77
-	}
78
-	if exp.Timeout != r.Timeout {
79
-		if exp.Timeout {
80
-			add("Expected command to timeout")
81
-		} else {
82
-			add("Expected command to finish, but it hit the timeout")
83
-		}
84
-	}
85
-	if !matchOutput(exp.Out, r.Stdout()) {
86
-		add("Expected stdout to contain %q", exp.Out)
87
-	}
88
-	if !matchOutput(exp.Err, r.Stderr()) {
89
-		add("Expected stderr to contain %q", exp.Err)
90
-	}
91
-	switch {
92
-	// If a non-zero exit code is expected there is going to be an error.
93
-	// Don't require an error message as well as an exit code because the
94
-	// error message is going to be "exit status <code> which is not useful
95
-	case exp.Error == "" && exp.ExitCode != 0:
96
-	case exp.Error == "" && r.Error != nil:
97
-		add("Expected no error")
98
-	case exp.Error != "" && r.Error == nil:
99
-		add("Expected error to contain %q, but there was no error", exp.Error)
100
-	case exp.Error != "" && !strings.Contains(r.Error.Error(), exp.Error):
101
-		add("Expected error to contain %q", exp.Error)
102
-	}
103
-
104
-	if len(errors) == 0 {
105
-		return nil
106
-	}
107
-	return fmt.Errorf("%s\nFailures:\n%s\n", r, strings.Join(errors, "\n"))
108
-}
109
-
110
-func matchOutput(expected string, actual string) bool {
111
-	switch expected {
112
-	case None:
113
-		return actual == ""
114
-	default:
115
-		return strings.Contains(actual, expected)
116
-	}
117
-}
118
-
119
-func (r *Result) String() string {
120
-	var timeout string
121
-	if r.Timeout {
122
-		timeout = " (timeout)"
123
-	}
124
-
125
-	return fmt.Sprintf(`
126
-Command: %s
127
-ExitCode: %d%s, Error: %s
128
-Stdout: %v
129
-Stderr: %v
130
-`,
131
-		strings.Join(r.Cmd.Args, " "),
132
-		r.ExitCode,
133
-		timeout,
134
-		r.Error,
135
-		r.Stdout(),
136
-		r.Stderr())
137
-}
138
-
139
-// Expected is the expected output from a Command. This struct is compared to a
140
-// Result struct by Result.Assert().
141
-type Expected struct {
142
-	ExitCode int
143
-	Timeout  bool
144
-	Error    string
145
-	Out      string
146
-	Err      string
147
-}
148
-
149
-// Success is the default expected result
150
-var Success = Expected{}
151
-
152
-// Stdout returns the stdout of the process as a string
153
-func (r *Result) Stdout() string {
154
-	return r.outBuffer.String()
155
-}
156
-
157
-// Stderr returns the stderr of the process as a string
158
-func (r *Result) Stderr() string {
159
-	return r.errBuffer.String()
160
-}
161
-
162
-// Combined returns the stdout and stderr combined into a single string
163
-func (r *Result) Combined() string {
164
-	return r.outBuffer.String() + r.errBuffer.String()
165
-}
166
-
167
-// SetExitError sets Error and ExitCode based on Error
168
-func (r *Result) SetExitError(err error) {
169
-	if err == nil {
170
-		return
171
-	}
172
-	r.Error = err
173
-	r.ExitCode = system.ProcessExitCode(err)
174
-}
175
-
176
-type matches struct{}
177
-
178
-// Info returns the CheckerInfo
179
-func (m *matches) Info() *check.CheckerInfo {
180
-	return &check.CheckerInfo{
181
-		Name:   "CommandMatches",
182
-		Params: []string{"result", "expected"},
183
-	}
184
-}
185
-
186
-// Check compares a result against the expected
187
-func (m *matches) Check(params []interface{}, names []string) (bool, string) {
188
-	result, ok := params[0].(*Result)
189
-	if !ok {
190
-		return false, fmt.Sprintf("result must be a *Result, not %T", params[0])
191
-	}
192
-	expected, ok := params[1].(Expected)
193
-	if !ok {
194
-		return false, fmt.Sprintf("expected must be an Expected, not %T", params[1])
195
-	}
196
-
197
-	err := result.Compare(expected)
198
-	if err == nil {
199
-		return true, ""
200
-	}
201
-	return false, err.Error()
202
-}
203
-
204
-// Matches is a gocheck.Checker for comparing a Result against an Expected
205
-var Matches = &matches{}
206
-
207
-// Cmd contains the arguments and options for a process to run as part of a test
208
-// suite.
209
-type Cmd struct {
210
-	Command []string
211
-	Timeout time.Duration
212
-	Stdin   io.Reader
213
-	Stdout  io.Writer
214
-	Dir     string
215
-	Env     []string
216
-}
217
-
218
-// RunCmd runs a command and returns a Result
219
-func RunCmd(cmd Cmd) *Result {
220
-	result := StartCmd(cmd)
221
-	if result.Error != nil {
222
-		return result
223
-	}
224
-	return WaitOnCmd(cmd.Timeout, result)
225
-}
226
-
227
-// RunCommand parses a command line and runs it, returning a result
228
-func RunCommand(command string, args ...string) *Result {
229
-	return RunCmd(Cmd{Command: append([]string{command}, args...)})
230
-}
231
-
232
-// StartCmd starts a command, but doesn't wait for it to finish
233
-func StartCmd(cmd Cmd) *Result {
234
-	result := buildCmd(cmd)
235
-	if result.Error != nil {
236
-		return result
237
-	}
238
-	result.SetExitError(result.Cmd.Start())
239
-	return result
240
-}
241
-
242
-func buildCmd(cmd Cmd) *Result {
243
-	var execCmd *exec.Cmd
244
-	switch len(cmd.Command) {
245
-	case 1:
246
-		execCmd = exec.Command(cmd.Command[0])
247
-	default:
248
-		execCmd = exec.Command(cmd.Command[0], cmd.Command[1:]...)
249
-	}
250
-	outBuffer := new(lockedBuffer)
251
-	errBuffer := new(lockedBuffer)
252
-
253
-	execCmd.Stdin = cmd.Stdin
254
-	execCmd.Dir = cmd.Dir
255
-	execCmd.Env = cmd.Env
256
-	if cmd.Stdout != nil {
257
-		execCmd.Stdout = io.MultiWriter(outBuffer, cmd.Stdout)
258
-	} else {
259
-		execCmd.Stdout = outBuffer
260
-	}
261
-	execCmd.Stderr = errBuffer
262
-	return &Result{
263
-		Cmd:       execCmd,
264
-		outBuffer: outBuffer,
265
-		errBuffer: errBuffer,
266
-	}
267
-}
268
-
269
-// WaitOnCmd waits for a command to complete. If timeout is non-nil then
270
-// only wait until the timeout.
271
-func WaitOnCmd(timeout time.Duration, result *Result) *Result {
272
-	if timeout == time.Duration(0) {
273
-		result.SetExitError(result.Cmd.Wait())
274
-		return result
275
-	}
276
-
277
-	done := make(chan error, 1)
278
-	// Wait for command to exit in a goroutine
279
-	go func() {
280
-		done <- result.Cmd.Wait()
281
-	}()
282
-
283
-	select {
284
-	case <-time.After(timeout):
285
-		killErr := result.Cmd.Process.Kill()
286
-		if killErr != nil {
287
-			fmt.Printf("failed to kill (pid=%d): %v\n", result.Cmd.Process.Pid, killErr)
288
-		}
289
-		result.Timeout = true
290
-	case err := <-done:
291
-		result.SetExitError(err)
292
-	}
293
-	return result
294
-}
295 1
deleted file mode 100644
... ...
@@ -1,118 +0,0 @@
1
-package cmd
2
-
3
-import (
4
-	"runtime"
5
-	"strings"
6
-	"testing"
7
-	"time"
8
-
9
-	"github.com/docker/docker/pkg/testutil/assert"
10
-)
11
-
12
-func TestRunCommand(t *testing.T) {
13
-	// TODO Windows: Port this test
14
-	if runtime.GOOS == "windows" {
15
-		t.Skip("Needs porting to Windows")
16
-	}
17
-
18
-	var cmd string
19
-	if runtime.GOOS == "solaris" {
20
-		cmd = "gls"
21
-	} else {
22
-		cmd = "ls"
23
-	}
24
-	result := RunCommand(cmd)
25
-	result.Assert(t, Expected{})
26
-
27
-	result = RunCommand("doesnotexists")
28
-	expectedError := `exec: "doesnotexists": executable file not found`
29
-	result.Assert(t, Expected{ExitCode: 127, Error: expectedError})
30
-
31
-	result = RunCommand(cmd, "-z")
32
-	result.Assert(t, Expected{
33
-		ExitCode: 2,
34
-		Error:    "exit status 2",
35
-		Err:      "invalid option",
36
-	})
37
-	assert.Contains(t, result.Combined(), "invalid option")
38
-}
39
-
40
-func TestRunCommandWithCombined(t *testing.T) {
41
-	// TODO Windows: Port this test
42
-	if runtime.GOOS == "windows" {
43
-		t.Skip("Needs porting to Windows")
44
-	}
45
-
46
-	result := RunCommand("ls", "-a")
47
-	result.Assert(t, Expected{})
48
-
49
-	assert.Contains(t, result.Combined(), "..")
50
-	assert.Contains(t, result.Stdout(), "..")
51
-}
52
-
53
-func TestRunCommandWithTimeoutFinished(t *testing.T) {
54
-	// TODO Windows: Port this test
55
-	if runtime.GOOS == "windows" {
56
-		t.Skip("Needs porting to Windows")
57
-	}
58
-
59
-	result := RunCmd(Cmd{
60
-		Command: []string{"ls", "-a"},
61
-		Timeout: 50 * time.Millisecond,
62
-	})
63
-	result.Assert(t, Expected{Out: ".."})
64
-}
65
-
66
-func TestRunCommandWithTimeoutKilled(t *testing.T) {
67
-	// TODO Windows: Port this test
68
-	if runtime.GOOS == "windows" {
69
-		t.Skip("Needs porting to Windows")
70
-	}
71
-
72
-	command := []string{"sh", "-c", "while true ; do echo 1 ; sleep .5 ; done"}
73
-	result := RunCmd(Cmd{Command: command, Timeout: 1250 * time.Millisecond})
74
-	result.Assert(t, Expected{Timeout: true})
75
-
76
-	ones := strings.Split(result.Stdout(), "\n")
77
-	assert.Equal(t, len(ones), 4)
78
-}
79
-
80
-func TestRunCommandWithErrors(t *testing.T) {
81
-	result := RunCommand("/foobar")
82
-	result.Assert(t, Expected{Error: "foobar", ExitCode: 127})
83
-}
84
-
85
-func TestRunCommandWithStdoutStderr(t *testing.T) {
86
-	result := RunCommand("echo", "hello", "world")
87
-	result.Assert(t, Expected{Out: "hello world\n", Err: None})
88
-}
89
-
90
-func TestRunCommandWithStdoutStderrError(t *testing.T) {
91
-	result := RunCommand("doesnotexists")
92
-
93
-	expected := `exec: "doesnotexists": executable file not found`
94
-	result.Assert(t, Expected{Out: None, Err: None, ExitCode: 127, Error: expected})
95
-
96
-	switch runtime.GOOS {
97
-	case "windows":
98
-		expected = "ls: unknown option"
99
-	case "solaris":
100
-		expected = "gls: invalid option"
101
-	default:
102
-		expected = "ls: invalid option"
103
-	}
104
-
105
-	var cmd string
106
-	if runtime.GOOS == "solaris" {
107
-		cmd = "gls"
108
-	} else {
109
-		cmd = "ls"
110
-	}
111
-	result = RunCommand(cmd, "-z")
112
-	result.Assert(t, Expected{
113
-		Out:      None,
114
-		Err:      expected,
115
-		ExitCode: 2,
116
-		Error:    "exit status 2",
117
-	})
118
-}
119 1
deleted file mode 100644
... ...
@@ -1,234 +0,0 @@
1
-package integration
2
-
3
-import (
4
-	"archive/tar"
5
-	"errors"
6
-	"fmt"
7
-	"io"
8
-	"io/ioutil"
9
-	"os"
10
-	"os/exec"
11
-	"path/filepath"
12
-	"reflect"
13
-	"strings"
14
-	"syscall"
15
-	"time"
16
-
17
-	icmd "github.com/docker/docker/pkg/integration/cmd"
18
-	"github.com/docker/docker/pkg/stringutils"
19
-	"github.com/docker/docker/pkg/system"
20
-)
21
-
22
-// IsKilled process the specified error and returns whether the process was killed or not.
23
-func IsKilled(err error) bool {
24
-	if exitErr, ok := err.(*exec.ExitError); ok {
25
-		status, ok := exitErr.Sys().(syscall.WaitStatus)
26
-		if !ok {
27
-			return false
28
-		}
29
-		// status.ExitStatus() is required on Windows because it does not
30
-		// implement Signal() nor Signaled(). Just check it had a bad exit
31
-		// status could mean it was killed (and in tests we do kill)
32
-		return (status.Signaled() && status.Signal() == os.Kill) || status.ExitStatus() != 0
33
-	}
34
-	return false
35
-}
36
-
37
-func runCommandWithOutput(cmd *exec.Cmd) (output string, exitCode int, err error) {
38
-	exitCode = 0
39
-	out, err := cmd.CombinedOutput()
40
-	exitCode = system.ProcessExitCode(err)
41
-	output = string(out)
42
-	return
43
-}
44
-
45
-// RunCommandPipelineWithOutput runs the array of commands with the output
46
-// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
47
-// It returns the final output, the exitCode different from 0 and the error
48
-// if something bad happened.
49
-func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, exitCode int, err error) {
50
-	if len(cmds) < 2 {
51
-		return "", 0, errors.New("pipeline does not have multiple cmds")
52
-	}
53
-
54
-	// connect stdin of each cmd to stdout pipe of previous cmd
55
-	for i, cmd := range cmds {
56
-		if i > 0 {
57
-			prevCmd := cmds[i-1]
58
-			cmd.Stdin, err = prevCmd.StdoutPipe()
59
-
60
-			if err != nil {
61
-				return "", 0, fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
62
-			}
63
-		}
64
-	}
65
-
66
-	// start all cmds except the last
67
-	for _, cmd := range cmds[:len(cmds)-1] {
68
-		if err = cmd.Start(); err != nil {
69
-			return "", 0, fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
70
-		}
71
-	}
72
-
73
-	defer func() {
74
-		var pipeErrMsgs []string
75
-		// wait all cmds except the last to release their resources
76
-		for _, cmd := range cmds[:len(cmds)-1] {
77
-			if pipeErr := cmd.Wait(); pipeErr != nil {
78
-				pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
79
-			}
80
-		}
81
-		if len(pipeErrMsgs) > 0 && err == nil {
82
-			err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
83
-		}
84
-	}()
85
-
86
-	// wait on last cmd
87
-	return runCommandWithOutput(cmds[len(cmds)-1])
88
-}
89
-
90
-// ConvertSliceOfStringsToMap converts a slices of string in a map
91
-// with the strings as key and an empty string as values.
92
-func ConvertSliceOfStringsToMap(input []string) map[string]struct{} {
93
-	output := make(map[string]struct{})
94
-	for _, v := range input {
95
-		output[v] = struct{}{}
96
-	}
97
-	return output
98
-}
99
-
100
-// CompareDirectoryEntries compares two sets of FileInfo (usually taken from a directory)
101
-// and returns an error if different.
102
-func CompareDirectoryEntries(e1 []os.FileInfo, e2 []os.FileInfo) error {
103
-	var (
104
-		e1Entries = make(map[string]struct{})
105
-		e2Entries = make(map[string]struct{})
106
-	)
107
-	for _, e := range e1 {
108
-		e1Entries[e.Name()] = struct{}{}
109
-	}
110
-	for _, e := range e2 {
111
-		e2Entries[e.Name()] = struct{}{}
112
-	}
113
-	if !reflect.DeepEqual(e1Entries, e2Entries) {
114
-		return fmt.Errorf("entries differ")
115
-	}
116
-	return nil
117
-}
118
-
119
-// ListTar lists the entries of a tar.
120
-func ListTar(f io.Reader) ([]string, error) {
121
-	tr := tar.NewReader(f)
122
-	var entries []string
123
-
124
-	for {
125
-		th, err := tr.Next()
126
-		if err == io.EOF {
127
-			// end of tar archive
128
-			return entries, nil
129
-		}
130
-		if err != nil {
131
-			return entries, err
132
-		}
133
-		entries = append(entries, th.Name)
134
-	}
135
-}
136
-
137
-// RandomTmpDirPath provides a temporary path with rand string appended.
138
-// does not create or checks if it exists.
139
-func RandomTmpDirPath(s string, platform string) string {
140
-	tmp := "/tmp"
141
-	if platform == "windows" {
142
-		tmp = os.Getenv("TEMP")
143
-	}
144
-	path := filepath.Join(tmp, fmt.Sprintf("%s.%s", s, stringutils.GenerateRandomAlphaOnlyString(10)))
145
-	if platform == "windows" {
146
-		return filepath.FromSlash(path) // Using \
147
-	}
148
-	return filepath.ToSlash(path) // Using /
149
-}
150
-
151
-// ConsumeWithSpeed reads chunkSize bytes from reader before sleeping
152
-// for interval duration. Returns total read bytes. Send true to the
153
-// stop channel to return before reading to EOF on the reader.
154
-func ConsumeWithSpeed(reader io.Reader, chunkSize int, interval time.Duration, stop chan bool) (n int, err error) {
155
-	buffer := make([]byte, chunkSize)
156
-	for {
157
-		var readBytes int
158
-		readBytes, err = reader.Read(buffer)
159
-		n += readBytes
160
-		if err != nil {
161
-			if err == io.EOF {
162
-				err = nil
163
-			}
164
-			return
165
-		}
166
-		select {
167
-		case <-stop:
168
-			return
169
-		case <-time.After(interval):
170
-		}
171
-	}
172
-}
173
-
174
-// ParseCgroupPaths parses 'procCgroupData', which is output of '/proc/<pid>/cgroup', and returns
175
-// a map which cgroup name as key and path as value.
176
-func ParseCgroupPaths(procCgroupData string) map[string]string {
177
-	cgroupPaths := map[string]string{}
178
-	for _, line := range strings.Split(procCgroupData, "\n") {
179
-		parts := strings.Split(line, ":")
180
-		if len(parts) != 3 {
181
-			continue
182
-		}
183
-		cgroupPaths[parts[1]] = parts[2]
184
-	}
185
-	return cgroupPaths
186
-}
187
-
188
-// ChannelBuffer holds a chan of byte array that can be populate in a goroutine.
189
-type ChannelBuffer struct {
190
-	C chan []byte
191
-}
192
-
193
-// Write implements Writer.
194
-func (c *ChannelBuffer) Write(b []byte) (int, error) {
195
-	c.C <- b
196
-	return len(b), nil
197
-}
198
-
199
-// Close closes the go channel.
200
-func (c *ChannelBuffer) Close() error {
201
-	close(c.C)
202
-	return nil
203
-}
204
-
205
-// ReadTimeout reads the content of the channel in the specified byte array with
206
-// the specified duration as timeout.
207
-func (c *ChannelBuffer) ReadTimeout(p []byte, n time.Duration) (int, error) {
208
-	select {
209
-	case b := <-c.C:
210
-		return copy(p[0:], b), nil
211
-	case <-time.After(n):
212
-		return -1, fmt.Errorf("timeout reading from channel")
213
-	}
214
-}
215
-
216
-// RunAtDifferentDate runs the specified function with the given time.
217
-// It changes the date of the system, which can led to weird behaviors.
218
-func RunAtDifferentDate(date time.Time, block func()) {
219
-	// Layout for date. MMDDhhmmYYYY
220
-	const timeLayout = "010203042006"
221
-	// Ensure we bring time back to now
222
-	now := time.Now().Format(timeLayout)
223
-	defer icmd.RunCommand("date", now)
224
-
225
-	icmd.RunCommand("date", date.Format(timeLayout))
226
-	block()
227
-	return
228
-}
229
-
230
-// ReadBody read the specified ReadCloser content and returns it
231
-func ReadBody(b io.ReadCloser) ([]byte, error) {
232
-	defer b.Close()
233
-	return ioutil.ReadAll(b)
234
-}
235 1
deleted file mode 100644
... ...
@@ -1,363 +0,0 @@
1
-package integration
2
-
3
-import (
4
-	"io"
5
-	"io/ioutil"
6
-	"os"
7
-	"os/exec"
8
-	"path/filepath"
9
-	"runtime"
10
-	"strings"
11
-	"testing"
12
-	"time"
13
-)
14
-
15
-func TestIsKilledFalseWithNonKilledProcess(t *testing.T) {
16
-	var lsCmd *exec.Cmd
17
-	if runtime.GOOS != "windows" {
18
-		lsCmd = exec.Command("ls")
19
-	} else {
20
-		lsCmd = exec.Command("cmd", "/c", "dir")
21
-	}
22
-
23
-	err := lsCmd.Run()
24
-	if IsKilled(err) {
25
-		t.Fatalf("Expected the ls command to not be killed, was.")
26
-	}
27
-}
28
-
29
-func TestIsKilledTrueWithKilledProcess(t *testing.T) {
30
-	var longCmd *exec.Cmd
31
-	if runtime.GOOS != "windows" {
32
-		longCmd = exec.Command("top")
33
-	} else {
34
-		longCmd = exec.Command("powershell", "while ($true) { sleep 1 }")
35
-	}
36
-
37
-	// Start a command
38
-	err := longCmd.Start()
39
-	if err != nil {
40
-		t.Fatal(err)
41
-	}
42
-	// Capture the error when *dying*
43
-	done := make(chan error, 1)
44
-	go func() {
45
-		done <- longCmd.Wait()
46
-	}()
47
-	// Then kill it
48
-	longCmd.Process.Kill()
49
-	// Get the error
50
-	err = <-done
51
-	if !IsKilled(err) {
52
-		t.Fatalf("Expected the command to be killed, was not.")
53
-	}
54
-}
55
-
56
-func TestRunCommandPipelineWithOutputWithNotEnoughCmds(t *testing.T) {
57
-	_, _, err := RunCommandPipelineWithOutput(exec.Command("ls"))
58
-	expectedError := "pipeline does not have multiple cmds"
59
-	if err == nil || err.Error() != expectedError {
60
-		t.Fatalf("Expected an error with %s, got err:%s", expectedError, err)
61
-	}
62
-}
63
-
64
-func TestRunCommandPipelineWithOutputErrors(t *testing.T) {
65
-	p := "$PATH"
66
-	if runtime.GOOS == "windows" {
67
-		p = "%PATH%"
68
-	}
69
-	cmd1 := exec.Command("ls")
70
-	cmd1.Stdout = os.Stdout
71
-	cmd2 := exec.Command("anything really")
72
-	_, _, err := RunCommandPipelineWithOutput(cmd1, cmd2)
73
-	if err == nil || err.Error() != "cannot set stdout pipe for anything really: exec: Stdout already set" {
74
-		t.Fatalf("Expected an error, got %v", err)
75
-	}
76
-
77
-	cmdWithError := exec.Command("doesnotexists")
78
-	cmdCat := exec.Command("cat")
79
-	_, _, err = RunCommandPipelineWithOutput(cmdWithError, cmdCat)
80
-	if err == nil || err.Error() != `starting doesnotexists failed with error: exec: "doesnotexists": executable file not found in `+p {
81
-		t.Fatalf("Expected an error, got %v", err)
82
-	}
83
-}
84
-
85
-func TestRunCommandPipelineWithOutput(t *testing.T) {
86
-	//TODO: Should run on Solaris
87
-	if runtime.GOOS == "solaris" {
88
-		t.Skip()
89
-	}
90
-	cmds := []*exec.Cmd{
91
-		// Print 2 characters
92
-		exec.Command("echo", "-n", "11"),
93
-		// Count the number or char from stdin (previous command)
94
-		exec.Command("wc", "-m"),
95
-	}
96
-	out, exitCode, err := RunCommandPipelineWithOutput(cmds...)
97
-	expectedOutput := "2\n"
98
-	if out != expectedOutput || exitCode != 0 || err != nil {
99
-		t.Fatalf("Expected %s for commands %v, got out:%s, exitCode:%d, err:%v", expectedOutput, cmds, out, exitCode, err)
100
-	}
101
-}
102
-
103
-func TestConvertSliceOfStringsToMap(t *testing.T) {
104
-	input := []string{"a", "b"}
105
-	actual := ConvertSliceOfStringsToMap(input)
106
-	for _, key := range input {
107
-		if _, ok := actual[key]; !ok {
108
-			t.Fatalf("Expected output to contains key %s, did not: %v", key, actual)
109
-		}
110
-	}
111
-}
112
-
113
-func TestCompareDirectoryEntries(t *testing.T) {
114
-	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-compare-directories")
115
-	if err != nil {
116
-		t.Fatal(err)
117
-	}
118
-	defer os.RemoveAll(tmpFolder)
119
-
120
-	file1 := filepath.Join(tmpFolder, "file1")
121
-	file2 := filepath.Join(tmpFolder, "file2")
122
-	os.Create(file1)
123
-	os.Create(file2)
124
-
125
-	fi1, err := os.Stat(file1)
126
-	if err != nil {
127
-		t.Fatal(err)
128
-	}
129
-	fi1bis, err := os.Stat(file1)
130
-	if err != nil {
131
-		t.Fatal(err)
132
-	}
133
-	fi2, err := os.Stat(file2)
134
-	if err != nil {
135
-		t.Fatal(err)
136
-	}
137
-
138
-	cases := []struct {
139
-		e1          []os.FileInfo
140
-		e2          []os.FileInfo
141
-		shouldError bool
142
-	}{
143
-		// Empty directories
144
-		{
145
-			[]os.FileInfo{},
146
-			[]os.FileInfo{},
147
-			false,
148
-		},
149
-		// Same FileInfos
150
-		{
151
-			[]os.FileInfo{fi1},
152
-			[]os.FileInfo{fi1},
153
-			false,
154
-		},
155
-		// Different FileInfos but same names
156
-		{
157
-			[]os.FileInfo{fi1},
158
-			[]os.FileInfo{fi1bis},
159
-			false,
160
-		},
161
-		// Different FileInfos, different names
162
-		{
163
-			[]os.FileInfo{fi1},
164
-			[]os.FileInfo{fi2},
165
-			true,
166
-		},
167
-	}
168
-	for _, elt := range cases {
169
-		err := CompareDirectoryEntries(elt.e1, elt.e2)
170
-		if elt.shouldError && err == nil {
171
-			t.Fatalf("Should have return an error, did not with %v and %v", elt.e1, elt.e2)
172
-		}
173
-		if !elt.shouldError && err != nil {
174
-			t.Fatalf("Should have not returned an error, but did : %v with %v and %v", err, elt.e1, elt.e2)
175
-		}
176
-	}
177
-}
178
-
179
-// FIXME make an "unhappy path" test for ListTar without "panicking" :-)
180
-func TestListTar(t *testing.T) {
181
-	// TODO Windows: Figure out why this fails. Should be portable.
182
-	if runtime.GOOS == "windows" {
183
-		t.Skip("Failing on Windows - needs further investigation")
184
-	}
185
-	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-list-tar")
186
-	if err != nil {
187
-		t.Fatal(err)
188
-	}
189
-	defer os.RemoveAll(tmpFolder)
190
-
191
-	// Let's create a Tar file
192
-	srcFile := filepath.Join(tmpFolder, "src")
193
-	tarFile := filepath.Join(tmpFolder, "src.tar")
194
-	os.Create(srcFile)
195
-	cmd := exec.Command("sh", "-c", "tar cf "+tarFile+" "+srcFile)
196
-	_, err = cmd.CombinedOutput()
197
-	if err != nil {
198
-		t.Fatal(err)
199
-	}
200
-
201
-	reader, err := os.Open(tarFile)
202
-	if err != nil {
203
-		t.Fatal(err)
204
-	}
205
-	defer reader.Close()
206
-
207
-	entries, err := ListTar(reader)
208
-	if err != nil {
209
-		t.Fatal(err)
210
-	}
211
-	if len(entries) != 1 && entries[0] != "src" {
212
-		t.Fatalf("Expected a tar file with 1 entry (%s), got %v", srcFile, entries)
213
-	}
214
-}
215
-
216
-func TestRandomTmpDirPath(t *testing.T) {
217
-	path := RandomTmpDirPath("something", runtime.GOOS)
218
-
219
-	prefix := "/tmp/something"
220
-	if runtime.GOOS == "windows" {
221
-		prefix = os.Getenv("TEMP") + `\something`
222
-	}
223
-	expectedSize := len(prefix) + 11
224
-
225
-	if !strings.HasPrefix(path, prefix) {
226
-		t.Fatalf("Expected generated path to have '%s' as prefix, got %s'", prefix, path)
227
-	}
228
-	if len(path) != expectedSize {
229
-		t.Fatalf("Expected generated path to be %d, got %d", expectedSize, len(path))
230
-	}
231
-}
232
-
233
-func TestConsumeWithSpeed(t *testing.T) {
234
-	reader := strings.NewReader("1234567890")
235
-	chunksize := 2
236
-
237
-	bytes1, err := ConsumeWithSpeed(reader, chunksize, 10*time.Millisecond, nil)
238
-	if err != nil {
239
-		t.Fatal(err)
240
-	}
241
-
242
-	if bytes1 != 10 {
243
-		t.Fatalf("Expected to have read 10 bytes, got %d", bytes1)
244
-	}
245
-
246
-}
247
-
248
-func TestConsumeWithSpeedWithStop(t *testing.T) {
249
-	reader := strings.NewReader("1234567890")
250
-	chunksize := 2
251
-
252
-	stopIt := make(chan bool)
253
-
254
-	go func() {
255
-		time.Sleep(1 * time.Millisecond)
256
-		stopIt <- true
257
-	}()
258
-
259
-	bytes1, err := ConsumeWithSpeed(reader, chunksize, 20*time.Millisecond, stopIt)
260
-	if err != nil {
261
-		t.Fatal(err)
262
-	}
263
-
264
-	if bytes1 != 2 {
265
-		t.Fatalf("Expected to have read 2 bytes, got %d", bytes1)
266
-	}
267
-
268
-}
269
-
270
-func TestParseCgroupPathsEmpty(t *testing.T) {
271
-	cgroupMap := ParseCgroupPaths("")
272
-	if len(cgroupMap) != 0 {
273
-		t.Fatalf("Expected an empty map, got %v", cgroupMap)
274
-	}
275
-	cgroupMap = ParseCgroupPaths("\n")
276
-	if len(cgroupMap) != 0 {
277
-		t.Fatalf("Expected an empty map, got %v", cgroupMap)
278
-	}
279
-	cgroupMap = ParseCgroupPaths("something:else\nagain:here")
280
-	if len(cgroupMap) != 0 {
281
-		t.Fatalf("Expected an empty map, got %v", cgroupMap)
282
-	}
283
-}
284
-
285
-func TestParseCgroupPaths(t *testing.T) {
286
-	cgroupMap := ParseCgroupPaths("2:memory:/a\n1:cpuset:/b")
287
-	if len(cgroupMap) != 2 {
288
-		t.Fatalf("Expected a map with 2 entries, got %v", cgroupMap)
289
-	}
290
-	if value, ok := cgroupMap["memory"]; !ok || value != "/a" {
291
-		t.Fatalf("Expected cgroupMap to contains an entry for 'memory' with value '/a', got %v", cgroupMap)
292
-	}
293
-	if value, ok := cgroupMap["cpuset"]; !ok || value != "/b" {
294
-		t.Fatalf("Expected cgroupMap to contains an entry for 'cpuset' with value '/b', got %v", cgroupMap)
295
-	}
296
-}
297
-
298
-func TestChannelBufferTimeout(t *testing.T) {
299
-	expected := "11"
300
-
301
-	buf := &ChannelBuffer{make(chan []byte, 1)}
302
-	defer buf.Close()
303
-
304
-	done := make(chan struct{}, 1)
305
-	go func() {
306
-		time.Sleep(100 * time.Millisecond)
307
-		io.Copy(buf, strings.NewReader(expected))
308
-		done <- struct{}{}
309
-	}()
310
-
311
-	// Wait long enough
312
-	b := make([]byte, 2)
313
-	_, err := buf.ReadTimeout(b, 50*time.Millisecond)
314
-	if err == nil && err.Error() != "timeout reading from channel" {
315
-		t.Fatalf("Expected an error, got %s", err)
316
-	}
317
-	<-done
318
-}
319
-
320
-func TestChannelBuffer(t *testing.T) {
321
-	expected := "11"
322
-
323
-	buf := &ChannelBuffer{make(chan []byte, 1)}
324
-	defer buf.Close()
325
-
326
-	go func() {
327
-		time.Sleep(100 * time.Millisecond)
328
-		io.Copy(buf, strings.NewReader(expected))
329
-	}()
330
-
331
-	// Wait long enough
332
-	b := make([]byte, 2)
333
-	_, err := buf.ReadTimeout(b, 200*time.Millisecond)
334
-	if err != nil {
335
-		t.Fatal(err)
336
-	}
337
-
338
-	if string(b) != expected {
339
-		t.Fatalf("Expected '%s', got '%s'", expected, string(b))
340
-	}
341
-}
342
-
343
-// FIXME doesn't work
344
-// func TestRunAtDifferentDate(t *testing.T) {
345
-// 	var date string
346
-
347
-// 	// Layout for date. MMDDhhmmYYYY
348
-// 	const timeLayout = "20060102"
349
-// 	expectedDate := "20100201"
350
-// 	theDate, err := time.Parse(timeLayout, expectedDate)
351
-// 	if err != nil {
352
-// 		t.Fatal(err)
353
-// 	}
354
-
355
-// 	RunAtDifferentDate(theDate, func() {
356
-// 		cmd := exec.Command("date", "+%Y%M%d")
357
-// 		out, err := cmd.Output()
358
-// 		if err != nil {
359
-// 			t.Fatal(err)
360
-// 		}
361
-// 		date = string(out)
362
-// 	})
363
-// }
364 1
new file mode 100644
... ...
@@ -0,0 +1,294 @@
0
+package cmd
1
+
2
+import (
3
+	"bytes"
4
+	"fmt"
5
+	"io"
6
+	"os/exec"
7
+	"path/filepath"
8
+	"runtime"
9
+	"strings"
10
+	"sync"
11
+	"time"
12
+
13
+	"github.com/docker/docker/pkg/system"
14
+	"github.com/go-check/check"
15
+)
16
+
17
+type testingT interface {
18
+	Fatalf(string, ...interface{})
19
+}
20
+
21
+const (
22
+	// None is a token to inform Result.Assert that the output should be empty
23
+	None string = "<NOTHING>"
24
+)
25
+
26
+type lockedBuffer struct {
27
+	m   sync.RWMutex
28
+	buf bytes.Buffer
29
+}
30
+
31
+func (buf *lockedBuffer) Write(b []byte) (int, error) {
32
+	buf.m.Lock()
33
+	defer buf.m.Unlock()
34
+	return buf.buf.Write(b)
35
+}
36
+
37
+func (buf *lockedBuffer) String() string {
38
+	buf.m.RLock()
39
+	defer buf.m.RUnlock()
40
+	return buf.buf.String()
41
+}
42
+
43
+// Result stores the result of running a command
44
+type Result struct {
45
+	Cmd      *exec.Cmd
46
+	ExitCode int
47
+	Error    error
48
+	// Timeout is true if the command was killed because it ran for too long
49
+	Timeout   bool
50
+	outBuffer *lockedBuffer
51
+	errBuffer *lockedBuffer
52
+}
53
+
54
+// Assert compares the Result against the Expected struct, and fails the test if
55
+// any of the expcetations are not met.
56
+func (r *Result) Assert(t testingT, exp Expected) {
57
+	err := r.Compare(exp)
58
+	if err == nil {
59
+		return
60
+	}
61
+
62
+	_, file, line, _ := runtime.Caller(1)
63
+	t.Fatalf("at %s:%d\n%s", filepath.Base(file), line, err.Error())
64
+}
65
+
66
+// Compare returns a formatted error with the command, stdout, stderr, exit
67
+// code, and any failed expectations
68
+func (r *Result) Compare(exp Expected) error {
69
+	errors := []string{}
70
+	add := func(format string, args ...interface{}) {
71
+		errors = append(errors, fmt.Sprintf(format, args...))
72
+	}
73
+
74
+	if exp.ExitCode != r.ExitCode {
75
+		add("ExitCode was %d expected %d", r.ExitCode, exp.ExitCode)
76
+	}
77
+	if exp.Timeout != r.Timeout {
78
+		if exp.Timeout {
79
+			add("Expected command to timeout")
80
+		} else {
81
+			add("Expected command to finish, but it hit the timeout")
82
+		}
83
+	}
84
+	if !matchOutput(exp.Out, r.Stdout()) {
85
+		add("Expected stdout to contain %q", exp.Out)
86
+	}
87
+	if !matchOutput(exp.Err, r.Stderr()) {
88
+		add("Expected stderr to contain %q", exp.Err)
89
+	}
90
+	switch {
91
+	// If a non-zero exit code is expected there is going to be an error.
92
+	// Don't require an error message as well as an exit code because the
93
+	// error message is going to be "exit status <code> which is not useful
94
+	case exp.Error == "" && exp.ExitCode != 0:
95
+	case exp.Error == "" && r.Error != nil:
96
+		add("Expected no error")
97
+	case exp.Error != "" && r.Error == nil:
98
+		add("Expected error to contain %q, but there was no error", exp.Error)
99
+	case exp.Error != "" && !strings.Contains(r.Error.Error(), exp.Error):
100
+		add("Expected error to contain %q", exp.Error)
101
+	}
102
+
103
+	if len(errors) == 0 {
104
+		return nil
105
+	}
106
+	return fmt.Errorf("%s\nFailures:\n%s\n", r, strings.Join(errors, "\n"))
107
+}
108
+
109
+func matchOutput(expected string, actual string) bool {
110
+	switch expected {
111
+	case None:
112
+		return actual == ""
113
+	default:
114
+		return strings.Contains(actual, expected)
115
+	}
116
+}
117
+
118
+func (r *Result) String() string {
119
+	var timeout string
120
+	if r.Timeout {
121
+		timeout = " (timeout)"
122
+	}
123
+
124
+	return fmt.Sprintf(`
125
+Command: %s
126
+ExitCode: %d%s, Error: %s
127
+Stdout: %v
128
+Stderr: %v
129
+`,
130
+		strings.Join(r.Cmd.Args, " "),
131
+		r.ExitCode,
132
+		timeout,
133
+		r.Error,
134
+		r.Stdout(),
135
+		r.Stderr())
136
+}
137
+
138
+// Expected is the expected output from a Command. This struct is compared to a
139
+// Result struct by Result.Assert().
140
+type Expected struct {
141
+	ExitCode int
142
+	Timeout  bool
143
+	Error    string
144
+	Out      string
145
+	Err      string
146
+}
147
+
148
+// Success is the default expected result
149
+var Success = Expected{}
150
+
151
+// Stdout returns the stdout of the process as a string
152
+func (r *Result) Stdout() string {
153
+	return r.outBuffer.String()
154
+}
155
+
156
+// Stderr returns the stderr of the process as a string
157
+func (r *Result) Stderr() string {
158
+	return r.errBuffer.String()
159
+}
160
+
161
+// Combined returns the stdout and stderr combined into a single string
162
+func (r *Result) Combined() string {
163
+	return r.outBuffer.String() + r.errBuffer.String()
164
+}
165
+
166
+// SetExitError sets Error and ExitCode based on Error
167
+func (r *Result) SetExitError(err error) {
168
+	if err == nil {
169
+		return
170
+	}
171
+	r.Error = err
172
+	r.ExitCode = system.ProcessExitCode(err)
173
+}
174
+
175
+type matches struct{}
176
+
177
+// Info returns the CheckerInfo
178
+func (m *matches) Info() *check.CheckerInfo {
179
+	return &check.CheckerInfo{
180
+		Name:   "CommandMatches",
181
+		Params: []string{"result", "expected"},
182
+	}
183
+}
184
+
185
+// Check compares a result against the expected
186
+func (m *matches) Check(params []interface{}, names []string) (bool, string) {
187
+	result, ok := params[0].(*Result)
188
+	if !ok {
189
+		return false, fmt.Sprintf("result must be a *Result, not %T", params[0])
190
+	}
191
+	expected, ok := params[1].(Expected)
192
+	if !ok {
193
+		return false, fmt.Sprintf("expected must be an Expected, not %T", params[1])
194
+	}
195
+
196
+	err := result.Compare(expected)
197
+	if err == nil {
198
+		return true, ""
199
+	}
200
+	return false, err.Error()
201
+}
202
+
203
+// Matches is a gocheck.Checker for comparing a Result against an Expected
204
+var Matches = &matches{}
205
+
206
+// Cmd contains the arguments and options for a process to run as part of a test
207
+// suite.
208
+type Cmd struct {
209
+	Command []string
210
+	Timeout time.Duration
211
+	Stdin   io.Reader
212
+	Stdout  io.Writer
213
+	Dir     string
214
+	Env     []string
215
+}
216
+
217
+// RunCmd runs a command and returns a Result
218
+func RunCmd(cmd Cmd) *Result {
219
+	result := StartCmd(cmd)
220
+	if result.Error != nil {
221
+		return result
222
+	}
223
+	return WaitOnCmd(cmd.Timeout, result)
224
+}
225
+
226
+// RunCommand parses a command line and runs it, returning a result
227
+func RunCommand(command string, args ...string) *Result {
228
+	return RunCmd(Cmd{Command: append([]string{command}, args...)})
229
+}
230
+
231
+// StartCmd starts a command, but doesn't wait for it to finish
232
+func StartCmd(cmd Cmd) *Result {
233
+	result := buildCmd(cmd)
234
+	if result.Error != nil {
235
+		return result
236
+	}
237
+	result.SetExitError(result.Cmd.Start())
238
+	return result
239
+}
240
+
241
+func buildCmd(cmd Cmd) *Result {
242
+	var execCmd *exec.Cmd
243
+	switch len(cmd.Command) {
244
+	case 1:
245
+		execCmd = exec.Command(cmd.Command[0])
246
+	default:
247
+		execCmd = exec.Command(cmd.Command[0], cmd.Command[1:]...)
248
+	}
249
+	outBuffer := new(lockedBuffer)
250
+	errBuffer := new(lockedBuffer)
251
+
252
+	execCmd.Stdin = cmd.Stdin
253
+	execCmd.Dir = cmd.Dir
254
+	execCmd.Env = cmd.Env
255
+	if cmd.Stdout != nil {
256
+		execCmd.Stdout = io.MultiWriter(outBuffer, cmd.Stdout)
257
+	} else {
258
+		execCmd.Stdout = outBuffer
259
+	}
260
+	execCmd.Stderr = errBuffer
261
+	return &Result{
262
+		Cmd:       execCmd,
263
+		outBuffer: outBuffer,
264
+		errBuffer: errBuffer,
265
+	}
266
+}
267
+
268
+// WaitOnCmd waits for a command to complete. If timeout is non-nil then
269
+// only wait until the timeout.
270
+func WaitOnCmd(timeout time.Duration, result *Result) *Result {
271
+	if timeout == time.Duration(0) {
272
+		result.SetExitError(result.Cmd.Wait())
273
+		return result
274
+	}
275
+
276
+	done := make(chan error, 1)
277
+	// Wait for command to exit in a goroutine
278
+	go func() {
279
+		done <- result.Cmd.Wait()
280
+	}()
281
+
282
+	select {
283
+	case <-time.After(timeout):
284
+		killErr := result.Cmd.Process.Kill()
285
+		if killErr != nil {
286
+			fmt.Printf("failed to kill (pid=%d): %v\n", result.Cmd.Process.Pid, killErr)
287
+		}
288
+		result.Timeout = true
289
+	case err := <-done:
290
+		result.SetExitError(err)
291
+	}
292
+	return result
293
+}
0 294
new file mode 100644
... ...
@@ -0,0 +1,118 @@
0
+package cmd
1
+
2
+import (
3
+	"runtime"
4
+	"strings"
5
+	"testing"
6
+	"time"
7
+
8
+	"github.com/docker/docker/pkg/testutil/assert"
9
+)
10
+
11
+func TestRunCommand(t *testing.T) {
12
+	// TODO Windows: Port this test
13
+	if runtime.GOOS == "windows" {
14
+		t.Skip("Needs porting to Windows")
15
+	}
16
+
17
+	var cmd string
18
+	if runtime.GOOS == "solaris" {
19
+		cmd = "gls"
20
+	} else {
21
+		cmd = "ls"
22
+	}
23
+	result := RunCommand(cmd)
24
+	result.Assert(t, Expected{})
25
+
26
+	result = RunCommand("doesnotexists")
27
+	expectedError := `exec: "doesnotexists": executable file not found`
28
+	result.Assert(t, Expected{ExitCode: 127, Error: expectedError})
29
+
30
+	result = RunCommand(cmd, "-z")
31
+	result.Assert(t, Expected{
32
+		ExitCode: 2,
33
+		Error:    "exit status 2",
34
+		Err:      "invalid option",
35
+	})
36
+	assert.Contains(t, result.Combined(), "invalid option")
37
+}
38
+
39
+func TestRunCommandWithCombined(t *testing.T) {
40
+	// TODO Windows: Port this test
41
+	if runtime.GOOS == "windows" {
42
+		t.Skip("Needs porting to Windows")
43
+	}
44
+
45
+	result := RunCommand("ls", "-a")
46
+	result.Assert(t, Expected{})
47
+
48
+	assert.Contains(t, result.Combined(), "..")
49
+	assert.Contains(t, result.Stdout(), "..")
50
+}
51
+
52
+func TestRunCommandWithTimeoutFinished(t *testing.T) {
53
+	// TODO Windows: Port this test
54
+	if runtime.GOOS == "windows" {
55
+		t.Skip("Needs porting to Windows")
56
+	}
57
+
58
+	result := RunCmd(Cmd{
59
+		Command: []string{"ls", "-a"},
60
+		Timeout: 50 * time.Millisecond,
61
+	})
62
+	result.Assert(t, Expected{Out: ".."})
63
+}
64
+
65
+func TestRunCommandWithTimeoutKilled(t *testing.T) {
66
+	// TODO Windows: Port this test
67
+	if runtime.GOOS == "windows" {
68
+		t.Skip("Needs porting to Windows")
69
+	}
70
+
71
+	command := []string{"sh", "-c", "while true ; do echo 1 ; sleep .5 ; done"}
72
+	result := RunCmd(Cmd{Command: command, Timeout: 1250 * time.Millisecond})
73
+	result.Assert(t, Expected{Timeout: true})
74
+
75
+	ones := strings.Split(result.Stdout(), "\n")
76
+	assert.Equal(t, len(ones), 4)
77
+}
78
+
79
+func TestRunCommandWithErrors(t *testing.T) {
80
+	result := RunCommand("/foobar")
81
+	result.Assert(t, Expected{Error: "foobar", ExitCode: 127})
82
+}
83
+
84
+func TestRunCommandWithStdoutStderr(t *testing.T) {
85
+	result := RunCommand("echo", "hello", "world")
86
+	result.Assert(t, Expected{Out: "hello world\n", Err: None})
87
+}
88
+
89
+func TestRunCommandWithStdoutStderrError(t *testing.T) {
90
+	result := RunCommand("doesnotexists")
91
+
92
+	expected := `exec: "doesnotexists": executable file not found`
93
+	result.Assert(t, Expected{Out: None, Err: None, ExitCode: 127, Error: expected})
94
+
95
+	switch runtime.GOOS {
96
+	case "windows":
97
+		expected = "ls: unknown option"
98
+	case "solaris":
99
+		expected = "gls: invalid option"
100
+	default:
101
+		expected = "ls: invalid option"
102
+	}
103
+
104
+	var cmd string
105
+	if runtime.GOOS == "solaris" {
106
+		cmd = "gls"
107
+	} else {
108
+		cmd = "ls"
109
+	}
110
+	result = RunCommand(cmd, "-z")
111
+	result.Assert(t, Expected{
112
+		Out:      None,
113
+		Err:      expected,
114
+		ExitCode: 2,
115
+		Error:    "exit status 2",
116
+	})
117
+}
0 118
new file mode 100644
... ...
@@ -0,0 +1,234 @@
0
+package testutil
1
+
2
+import (
3
+	"archive/tar"
4
+	"errors"
5
+	"fmt"
6
+	"io"
7
+	"io/ioutil"
8
+	"os"
9
+	"os/exec"
10
+	"path/filepath"
11
+	"reflect"
12
+	"strings"
13
+	"syscall"
14
+	"time"
15
+
16
+	"github.com/docker/docker/pkg/stringutils"
17
+	"github.com/docker/docker/pkg/system"
18
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
19
+)
20
+
21
+// IsKilled process the specified error and returns whether the process was killed or not.
22
+func IsKilled(err error) bool {
23
+	if exitErr, ok := err.(*exec.ExitError); ok {
24
+		status, ok := exitErr.Sys().(syscall.WaitStatus)
25
+		if !ok {
26
+			return false
27
+		}
28
+		// status.ExitStatus() is required on Windows because it does not
29
+		// implement Signal() nor Signaled(). Just check it had a bad exit
30
+		// status could mean it was killed (and in tests we do kill)
31
+		return (status.Signaled() && status.Signal() == os.Kill) || status.ExitStatus() != 0
32
+	}
33
+	return false
34
+}
35
+
36
+func runCommandWithOutput(cmd *exec.Cmd) (output string, exitCode int, err error) {
37
+	exitCode = 0
38
+	out, err := cmd.CombinedOutput()
39
+	exitCode = system.ProcessExitCode(err)
40
+	output = string(out)
41
+	return
42
+}
43
+
44
+// RunCommandPipelineWithOutput runs the array of commands with the output
45
+// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
46
+// It returns the final output, the exitCode different from 0 and the error
47
+// if something bad happened.
48
+func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, exitCode int, err error) {
49
+	if len(cmds) < 2 {
50
+		return "", 0, errors.New("pipeline does not have multiple cmds")
51
+	}
52
+
53
+	// connect stdin of each cmd to stdout pipe of previous cmd
54
+	for i, cmd := range cmds {
55
+		if i > 0 {
56
+			prevCmd := cmds[i-1]
57
+			cmd.Stdin, err = prevCmd.StdoutPipe()
58
+
59
+			if err != nil {
60
+				return "", 0, fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
61
+			}
62
+		}
63
+	}
64
+
65
+	// start all cmds except the last
66
+	for _, cmd := range cmds[:len(cmds)-1] {
67
+		if err = cmd.Start(); err != nil {
68
+			return "", 0, fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
69
+		}
70
+	}
71
+
72
+	defer func() {
73
+		var pipeErrMsgs []string
74
+		// wait all cmds except the last to release their resources
75
+		for _, cmd := range cmds[:len(cmds)-1] {
76
+			if pipeErr := cmd.Wait(); pipeErr != nil {
77
+				pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
78
+			}
79
+		}
80
+		if len(pipeErrMsgs) > 0 && err == nil {
81
+			err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
82
+		}
83
+	}()
84
+
85
+	// wait on last cmd
86
+	return runCommandWithOutput(cmds[len(cmds)-1])
87
+}
88
+
89
+// ConvertSliceOfStringsToMap converts a slices of string in a map
90
+// with the strings as key and an empty string as values.
91
+func ConvertSliceOfStringsToMap(input []string) map[string]struct{} {
92
+	output := make(map[string]struct{})
93
+	for _, v := range input {
94
+		output[v] = struct{}{}
95
+	}
96
+	return output
97
+}
98
+
99
+// CompareDirectoryEntries compares two sets of FileInfo (usually taken from a directory)
100
+// and returns an error if different.
101
+func CompareDirectoryEntries(e1 []os.FileInfo, e2 []os.FileInfo) error {
102
+	var (
103
+		e1Entries = make(map[string]struct{})
104
+		e2Entries = make(map[string]struct{})
105
+	)
106
+	for _, e := range e1 {
107
+		e1Entries[e.Name()] = struct{}{}
108
+	}
109
+	for _, e := range e2 {
110
+		e2Entries[e.Name()] = struct{}{}
111
+	}
112
+	if !reflect.DeepEqual(e1Entries, e2Entries) {
113
+		return fmt.Errorf("entries differ")
114
+	}
115
+	return nil
116
+}
117
+
118
+// ListTar lists the entries of a tar.
119
+func ListTar(f io.Reader) ([]string, error) {
120
+	tr := tar.NewReader(f)
121
+	var entries []string
122
+
123
+	for {
124
+		th, err := tr.Next()
125
+		if err == io.EOF {
126
+			// end of tar archive
127
+			return entries, nil
128
+		}
129
+		if err != nil {
130
+			return entries, err
131
+		}
132
+		entries = append(entries, th.Name)
133
+	}
134
+}
135
+
136
+// RandomTmpDirPath provides a temporary path with rand string appended.
137
+// does not create or checks if it exists.
138
+func RandomTmpDirPath(s string, platform string) string {
139
+	tmp := "/tmp"
140
+	if platform == "windows" {
141
+		tmp = os.Getenv("TEMP")
142
+	}
143
+	path := filepath.Join(tmp, fmt.Sprintf("%s.%s", s, stringutils.GenerateRandomAlphaOnlyString(10)))
144
+	if platform == "windows" {
145
+		return filepath.FromSlash(path) // Using \
146
+	}
147
+	return filepath.ToSlash(path) // Using /
148
+}
149
+
150
+// ConsumeWithSpeed reads chunkSize bytes from reader before sleeping
151
+// for interval duration. Returns total read bytes. Send true to the
152
+// stop channel to return before reading to EOF on the reader.
153
+func ConsumeWithSpeed(reader io.Reader, chunkSize int, interval time.Duration, stop chan bool) (n int, err error) {
154
+	buffer := make([]byte, chunkSize)
155
+	for {
156
+		var readBytes int
157
+		readBytes, err = reader.Read(buffer)
158
+		n += readBytes
159
+		if err != nil {
160
+			if err == io.EOF {
161
+				err = nil
162
+			}
163
+			return
164
+		}
165
+		select {
166
+		case <-stop:
167
+			return
168
+		case <-time.After(interval):
169
+		}
170
+	}
171
+}
172
+
173
+// ParseCgroupPaths parses 'procCgroupData', which is output of '/proc/<pid>/cgroup', and returns
174
+// a map which cgroup name as key and path as value.
175
+func ParseCgroupPaths(procCgroupData string) map[string]string {
176
+	cgroupPaths := map[string]string{}
177
+	for _, line := range strings.Split(procCgroupData, "\n") {
178
+		parts := strings.Split(line, ":")
179
+		if len(parts) != 3 {
180
+			continue
181
+		}
182
+		cgroupPaths[parts[1]] = parts[2]
183
+	}
184
+	return cgroupPaths
185
+}
186
+
187
+// ChannelBuffer holds a chan of byte array that can be populate in a goroutine.
188
+type ChannelBuffer struct {
189
+	C chan []byte
190
+}
191
+
192
+// Write implements Writer.
193
+func (c *ChannelBuffer) Write(b []byte) (int, error) {
194
+	c.C <- b
195
+	return len(b), nil
196
+}
197
+
198
+// Close closes the go channel.
199
+func (c *ChannelBuffer) Close() error {
200
+	close(c.C)
201
+	return nil
202
+}
203
+
204
+// ReadTimeout reads the content of the channel in the specified byte array with
205
+// the specified duration as timeout.
206
+func (c *ChannelBuffer) ReadTimeout(p []byte, n time.Duration) (int, error) {
207
+	select {
208
+	case b := <-c.C:
209
+		return copy(p[0:], b), nil
210
+	case <-time.After(n):
211
+		return -1, fmt.Errorf("timeout reading from channel")
212
+	}
213
+}
214
+
215
+// RunAtDifferentDate runs the specified function with the given time.
216
+// It changes the date of the system, which can led to weird behaviors.
217
+func RunAtDifferentDate(date time.Time, block func()) {
218
+	// Layout for date. MMDDhhmmYYYY
219
+	const timeLayout = "010203042006"
220
+	// Ensure we bring time back to now
221
+	now := time.Now().Format(timeLayout)
222
+	defer icmd.RunCommand("date", now)
223
+
224
+	icmd.RunCommand("date", date.Format(timeLayout))
225
+	block()
226
+	return
227
+}
228
+
229
+// ReadBody read the specified ReadCloser content and returns it
230
+func ReadBody(b io.ReadCloser) ([]byte, error) {
231
+	defer b.Close()
232
+	return ioutil.ReadAll(b)
233
+}
0 234
new file mode 100644
... ...
@@ -0,0 +1,363 @@
0
+package testutil
1
+
2
+import (
3
+	"io"
4
+	"io/ioutil"
5
+	"os"
6
+	"os/exec"
7
+	"path/filepath"
8
+	"runtime"
9
+	"strings"
10
+	"testing"
11
+	"time"
12
+)
13
+
14
+func TestIsKilledFalseWithNonKilledProcess(t *testing.T) {
15
+	var lsCmd *exec.Cmd
16
+	if runtime.GOOS != "windows" {
17
+		lsCmd = exec.Command("ls")
18
+	} else {
19
+		lsCmd = exec.Command("cmd", "/c", "dir")
20
+	}
21
+
22
+	err := lsCmd.Run()
23
+	if IsKilled(err) {
24
+		t.Fatalf("Expected the ls command to not be killed, was.")
25
+	}
26
+}
27
+
28
+func TestIsKilledTrueWithKilledProcess(t *testing.T) {
29
+	var longCmd *exec.Cmd
30
+	if runtime.GOOS != "windows" {
31
+		longCmd = exec.Command("top")
32
+	} else {
33
+		longCmd = exec.Command("powershell", "while ($true) { sleep 1 }")
34
+	}
35
+
36
+	// Start a command
37
+	err := longCmd.Start()
38
+	if err != nil {
39
+		t.Fatal(err)
40
+	}
41
+	// Capture the error when *dying*
42
+	done := make(chan error, 1)
43
+	go func() {
44
+		done <- longCmd.Wait()
45
+	}()
46
+	// Then kill it
47
+	longCmd.Process.Kill()
48
+	// Get the error
49
+	err = <-done
50
+	if !IsKilled(err) {
51
+		t.Fatalf("Expected the command to be killed, was not.")
52
+	}
53
+}
54
+
55
+func TestRunCommandPipelineWithOutputWithNotEnoughCmds(t *testing.T) {
56
+	_, _, err := RunCommandPipelineWithOutput(exec.Command("ls"))
57
+	expectedError := "pipeline does not have multiple cmds"
58
+	if err == nil || err.Error() != expectedError {
59
+		t.Fatalf("Expected an error with %s, got err:%s", expectedError, err)
60
+	}
61
+}
62
+
63
+func TestRunCommandPipelineWithOutputErrors(t *testing.T) {
64
+	p := "$PATH"
65
+	if runtime.GOOS == "windows" {
66
+		p = "%PATH%"
67
+	}
68
+	cmd1 := exec.Command("ls")
69
+	cmd1.Stdout = os.Stdout
70
+	cmd2 := exec.Command("anything really")
71
+	_, _, err := RunCommandPipelineWithOutput(cmd1, cmd2)
72
+	if err == nil || err.Error() != "cannot set stdout pipe for anything really: exec: Stdout already set" {
73
+		t.Fatalf("Expected an error, got %v", err)
74
+	}
75
+
76
+	cmdWithError := exec.Command("doesnotexists")
77
+	cmdCat := exec.Command("cat")
78
+	_, _, err = RunCommandPipelineWithOutput(cmdWithError, cmdCat)
79
+	if err == nil || err.Error() != `starting doesnotexists failed with error: exec: "doesnotexists": executable file not found in `+p {
80
+		t.Fatalf("Expected an error, got %v", err)
81
+	}
82
+}
83
+
84
+func TestRunCommandPipelineWithOutput(t *testing.T) {
85
+	//TODO: Should run on Solaris
86
+	if runtime.GOOS == "solaris" {
87
+		t.Skip()
88
+	}
89
+	cmds := []*exec.Cmd{
90
+		// Print 2 characters
91
+		exec.Command("echo", "-n", "11"),
92
+		// Count the number or char from stdin (previous command)
93
+		exec.Command("wc", "-m"),
94
+	}
95
+	out, exitCode, err := RunCommandPipelineWithOutput(cmds...)
96
+	expectedOutput := "2\n"
97
+	if out != expectedOutput || exitCode != 0 || err != nil {
98
+		t.Fatalf("Expected %s for commands %v, got out:%s, exitCode:%d, err:%v", expectedOutput, cmds, out, exitCode, err)
99
+	}
100
+}
101
+
102
+func TestConvertSliceOfStringsToMap(t *testing.T) {
103
+	input := []string{"a", "b"}
104
+	actual := ConvertSliceOfStringsToMap(input)
105
+	for _, key := range input {
106
+		if _, ok := actual[key]; !ok {
107
+			t.Fatalf("Expected output to contains key %s, did not: %v", key, actual)
108
+		}
109
+	}
110
+}
111
+
112
+func TestCompareDirectoryEntries(t *testing.T) {
113
+	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-compare-directories")
114
+	if err != nil {
115
+		t.Fatal(err)
116
+	}
117
+	defer os.RemoveAll(tmpFolder)
118
+
119
+	file1 := filepath.Join(tmpFolder, "file1")
120
+	file2 := filepath.Join(tmpFolder, "file2")
121
+	os.Create(file1)
122
+	os.Create(file2)
123
+
124
+	fi1, err := os.Stat(file1)
125
+	if err != nil {
126
+		t.Fatal(err)
127
+	}
128
+	fi1bis, err := os.Stat(file1)
129
+	if err != nil {
130
+		t.Fatal(err)
131
+	}
132
+	fi2, err := os.Stat(file2)
133
+	if err != nil {
134
+		t.Fatal(err)
135
+	}
136
+
137
+	cases := []struct {
138
+		e1          []os.FileInfo
139
+		e2          []os.FileInfo
140
+		shouldError bool
141
+	}{
142
+		// Empty directories
143
+		{
144
+			[]os.FileInfo{},
145
+			[]os.FileInfo{},
146
+			false,
147
+		},
148
+		// Same FileInfos
149
+		{
150
+			[]os.FileInfo{fi1},
151
+			[]os.FileInfo{fi1},
152
+			false,
153
+		},
154
+		// Different FileInfos but same names
155
+		{
156
+			[]os.FileInfo{fi1},
157
+			[]os.FileInfo{fi1bis},
158
+			false,
159
+		},
160
+		// Different FileInfos, different names
161
+		{
162
+			[]os.FileInfo{fi1},
163
+			[]os.FileInfo{fi2},
164
+			true,
165
+		},
166
+	}
167
+	for _, elt := range cases {
168
+		err := CompareDirectoryEntries(elt.e1, elt.e2)
169
+		if elt.shouldError && err == nil {
170
+			t.Fatalf("Should have return an error, did not with %v and %v", elt.e1, elt.e2)
171
+		}
172
+		if !elt.shouldError && err != nil {
173
+			t.Fatalf("Should have not returned an error, but did : %v with %v and %v", err, elt.e1, elt.e2)
174
+		}
175
+	}
176
+}
177
+
178
+// FIXME make an "unhappy path" test for ListTar without "panicking" :-)
179
+func TestListTar(t *testing.T) {
180
+	// TODO Windows: Figure out why this fails. Should be portable.
181
+	if runtime.GOOS == "windows" {
182
+		t.Skip("Failing on Windows - needs further investigation")
183
+	}
184
+	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-list-tar")
185
+	if err != nil {
186
+		t.Fatal(err)
187
+	}
188
+	defer os.RemoveAll(tmpFolder)
189
+
190
+	// Let's create a Tar file
191
+	srcFile := filepath.Join(tmpFolder, "src")
192
+	tarFile := filepath.Join(tmpFolder, "src.tar")
193
+	os.Create(srcFile)
194
+	cmd := exec.Command("sh", "-c", "tar cf "+tarFile+" "+srcFile)
195
+	_, err = cmd.CombinedOutput()
196
+	if err != nil {
197
+		t.Fatal(err)
198
+	}
199
+
200
+	reader, err := os.Open(tarFile)
201
+	if err != nil {
202
+		t.Fatal(err)
203
+	}
204
+	defer reader.Close()
205
+
206
+	entries, err := ListTar(reader)
207
+	if err != nil {
208
+		t.Fatal(err)
209
+	}
210
+	if len(entries) != 1 && entries[0] != "src" {
211
+		t.Fatalf("Expected a tar file with 1 entry (%s), got %v", srcFile, entries)
212
+	}
213
+}
214
+
215
+func TestRandomTmpDirPath(t *testing.T) {
216
+	path := RandomTmpDirPath("something", runtime.GOOS)
217
+
218
+	prefix := "/tmp/something"
219
+	if runtime.GOOS == "windows" {
220
+		prefix = os.Getenv("TEMP") + `\something`
221
+	}
222
+	expectedSize := len(prefix) + 11
223
+
224
+	if !strings.HasPrefix(path, prefix) {
225
+		t.Fatalf("Expected generated path to have '%s' as prefix, got %s'", prefix, path)
226
+	}
227
+	if len(path) != expectedSize {
228
+		t.Fatalf("Expected generated path to be %d, got %d", expectedSize, len(path))
229
+	}
230
+}
231
+
232
+func TestConsumeWithSpeed(t *testing.T) {
233
+	reader := strings.NewReader("1234567890")
234
+	chunksize := 2
235
+
236
+	bytes1, err := ConsumeWithSpeed(reader, chunksize, 10*time.Millisecond, nil)
237
+	if err != nil {
238
+		t.Fatal(err)
239
+	}
240
+
241
+	if bytes1 != 10 {
242
+		t.Fatalf("Expected to have read 10 bytes, got %d", bytes1)
243
+	}
244
+
245
+}
246
+
247
+func TestConsumeWithSpeedWithStop(t *testing.T) {
248
+	reader := strings.NewReader("1234567890")
249
+	chunksize := 2
250
+
251
+	stopIt := make(chan bool)
252
+
253
+	go func() {
254
+		time.Sleep(1 * time.Millisecond)
255
+		stopIt <- true
256
+	}()
257
+
258
+	bytes1, err := ConsumeWithSpeed(reader, chunksize, 20*time.Millisecond, stopIt)
259
+	if err != nil {
260
+		t.Fatal(err)
261
+	}
262
+
263
+	if bytes1 != 2 {
264
+		t.Fatalf("Expected to have read 2 bytes, got %d", bytes1)
265
+	}
266
+
267
+}
268
+
269
+func TestParseCgroupPathsEmpty(t *testing.T) {
270
+	cgroupMap := ParseCgroupPaths("")
271
+	if len(cgroupMap) != 0 {
272
+		t.Fatalf("Expected an empty map, got %v", cgroupMap)
273
+	}
274
+	cgroupMap = ParseCgroupPaths("\n")
275
+	if len(cgroupMap) != 0 {
276
+		t.Fatalf("Expected an empty map, got %v", cgroupMap)
277
+	}
278
+	cgroupMap = ParseCgroupPaths("something:else\nagain:here")
279
+	if len(cgroupMap) != 0 {
280
+		t.Fatalf("Expected an empty map, got %v", cgroupMap)
281
+	}
282
+}
283
+
284
+func TestParseCgroupPaths(t *testing.T) {
285
+	cgroupMap := ParseCgroupPaths("2:memory:/a\n1:cpuset:/b")
286
+	if len(cgroupMap) != 2 {
287
+		t.Fatalf("Expected a map with 2 entries, got %v", cgroupMap)
288
+	}
289
+	if value, ok := cgroupMap["memory"]; !ok || value != "/a" {
290
+		t.Fatalf("Expected cgroupMap to contains an entry for 'memory' with value '/a', got %v", cgroupMap)
291
+	}
292
+	if value, ok := cgroupMap["cpuset"]; !ok || value != "/b" {
293
+		t.Fatalf("Expected cgroupMap to contains an entry for 'cpuset' with value '/b', got %v", cgroupMap)
294
+	}
295
+}
296
+
297
+func TestChannelBufferTimeout(t *testing.T) {
298
+	expected := "11"
299
+
300
+	buf := &ChannelBuffer{make(chan []byte, 1)}
301
+	defer buf.Close()
302
+
303
+	done := make(chan struct{}, 1)
304
+	go func() {
305
+		time.Sleep(100 * time.Millisecond)
306
+		io.Copy(buf, strings.NewReader(expected))
307
+		done <- struct{}{}
308
+	}()
309
+
310
+	// Wait long enough
311
+	b := make([]byte, 2)
312
+	_, err := buf.ReadTimeout(b, 50*time.Millisecond)
313
+	if err == nil && err.Error() != "timeout reading from channel" {
314
+		t.Fatalf("Expected an error, got %s", err)
315
+	}
316
+	<-done
317
+}
318
+
319
+func TestChannelBuffer(t *testing.T) {
320
+	expected := "11"
321
+
322
+	buf := &ChannelBuffer{make(chan []byte, 1)}
323
+	defer buf.Close()
324
+
325
+	go func() {
326
+		time.Sleep(100 * time.Millisecond)
327
+		io.Copy(buf, strings.NewReader(expected))
328
+	}()
329
+
330
+	// Wait long enough
331
+	b := make([]byte, 2)
332
+	_, err := buf.ReadTimeout(b, 200*time.Millisecond)
333
+	if err != nil {
334
+		t.Fatal(err)
335
+	}
336
+
337
+	if string(b) != expected {
338
+		t.Fatalf("Expected '%s', got '%s'", expected, string(b))
339
+	}
340
+}
341
+
342
+// FIXME doesn't work
343
+// func TestRunAtDifferentDate(t *testing.T) {
344
+// 	var date string
345
+
346
+// 	// Layout for date. MMDDhhmmYYYY
347
+// 	const timeLayout = "20060102"
348
+// 	expectedDate := "20100201"
349
+// 	theDate, err := time.Parse(timeLayout, expectedDate)
350
+// 	if err != nil {
351
+// 		t.Fatal(err)
352
+// 	}
353
+
354
+// 	RunAtDifferentDate(theDate, func() {
355
+// 		cmd := exec.Command("date", "+%Y%M%d")
356
+// 		out, err := cmd.Output()
357
+// 		if err != nil {
358
+// 			t.Fatal(err)
359
+// 		}
360
+// 		date = string(out)
361
+// 	})
362
+// }