Browse code

Migrate some copy tests to integration

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

Daniel Nephin authored on 2018/02/28 06:46:14
Showing 4 changed files
... ...
@@ -8,8 +8,6 @@ import (
8 8
 	"github.com/go-check/check"
9 9
 )
10 10
 
11
-// docker cp CONTAINER:PATH LOCALPATH
12
-
13 11
 // Try all of the test cases from the archive package which implements the
14 12
 // internals of `docker cp` and ensure that the behavior matches when actually
15 13
 // copying to and from containers.
... ...
@@ -20,67 +18,9 @@ import (
20 20
 // 3. DST parent directory must exist.
21 21
 // 4. If DST exists as a file, it must not end with a trailing separator.
22 22
 
23
-// First get these easy error cases out of the way.
24
-
25
-// Test for error when SRC does not exist.
26
-func (s *DockerSuite) TestCpFromErrSrcNotExists(c *check.C) {
27
-	containerID := makeTestContainer(c, testContainerOptions{})
28
-
29
-	tmpDir := getTestDir(c, "test-cp-from-err-src-not-exists")
30
-	defer os.RemoveAll(tmpDir)
31
-
32
-	err := runDockerCp(c, containerCpPath(containerID, "file1"), tmpDir, nil)
33
-	c.Assert(err, checker.NotNil)
34
-
35
-	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
36
-}
37
-
38
-// Test for error when SRC ends in a trailing
39
-// path separator but it exists as a file.
40
-func (s *DockerSuite) TestCpFromErrSrcNotDir(c *check.C) {
41
-	testRequires(c, DaemonIsLinux)
42
-	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
43
-
44
-	tmpDir := getTestDir(c, "test-cp-from-err-src-not-dir")
45
-	defer os.RemoveAll(tmpDir)
46
-
47
-	err := runDockerCp(c, containerCpPathTrailingSep(containerID, "file1"), tmpDir, nil)
48
-	c.Assert(err, checker.NotNil)
49
-
50
-	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
51
-}
52
-
53
-// Test for error when DST ends in a trailing
54
-// path separator but exists as a file.
55
-func (s *DockerSuite) TestCpFromErrDstNotDir(c *check.C) {
56
-	testRequires(c, DaemonIsLinux)
57
-	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
58
-
59
-	tmpDir := getTestDir(c, "test-cp-from-err-dst-not-dir")
60
-	defer os.RemoveAll(tmpDir)
61
-
62
-	makeTestContentInDir(c, tmpDir)
63
-
64
-	// Try with a file source.
65
-	srcPath := containerCpPath(containerID, "/file1")
66
-	dstPath := cpPathTrailingSep(tmpDir, "file1")
67
-
68
-	err := runDockerCp(c, srcPath, dstPath, nil)
69
-	c.Assert(err, checker.NotNil)
70
-
71
-	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
72
-
73
-	// Try with a directory source.
74
-	srcPath = containerCpPath(containerID, "/dir1")
75
-
76
-	err = runDockerCp(c, srcPath, dstPath, nil)
77
-	c.Assert(err, checker.NotNil)
78
-
79
-	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
80
-}
81
-
82 23
 // Check that copying from a container to a local symlink copies to the symlink
83 24
 // target and does not overwrite the local symlink itself.
25
+// TODO: move to docker/cli and/or integration/container/copy_test.go
84 26
 func (s *DockerSuite) TestCpFromSymlinkDestination(c *check.C) {
85 27
 	testRequires(c, DaemonIsLinux)
86 28
 	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
... ...
@@ -2,15 +2,11 @@ package main
2 2
 
3 3
 import (
4 4
 	"os"
5
-	"runtime"
6
-	"strings"
7 5
 
8 6
 	"github.com/docker/docker/integration-cli/checker"
9 7
 	"github.com/go-check/check"
10 8
 )
11 9
 
12
-// docker cp LOCALPATH CONTAINER:PATH
13
-
14 10
 // Try all of the test cases from the archive package which implements the
15 11
 // internals of `docker cp` and ensure that the behavior matches when actually
16 12
 // copying to and from containers.
... ...
@@ -21,124 +17,6 @@ import (
21 21
 // 3. DST parent directory must exist.
22 22
 // 4. If DST exists as a file, it must not end with a trailing separator.
23 23
 
24
-// First get these easy error cases out of the way.
25
-
26
-// Test for error when SRC does not exist.
27
-func (s *DockerSuite) TestCpToErrSrcNotExists(c *check.C) {
28
-	containerID := makeTestContainer(c, testContainerOptions{})
29
-
30
-	tmpDir := getTestDir(c, "test-cp-to-err-src-not-exists")
31
-	defer os.RemoveAll(tmpDir)
32
-
33
-	srcPath := cpPath(tmpDir, "file1")
34
-	dstPath := containerCpPath(containerID, "file1")
35
-	_, srcStatErr := os.Stat(srcPath)
36
-	c.Assert(os.IsNotExist(srcStatErr), checker.True)
37
-
38
-	err := runDockerCp(c, srcPath, dstPath, nil)
39
-	if runtime.GOOS == "windows" {
40
-		// Go 1.9+ on Windows returns a different error for `os.Stat()`, see
41
-		// https://github.com/golang/go/commit/6144c7270e5812d9de8fb97456ee4e5ae657fcbb#diff-f63e1a4b4377b2fe0b05011db3df9599
42
-		//
43
-		// Go 1.8: CreateFile C:\not-exist: The system cannot find the file specified.
44
-		// Go 1.9: GetFileAttributesEx C:\not-exist: The system cannot find the file specified.
45
-		//
46
-		// Due to the CLI using a different version than the daemon, comparing the
47
-		// error message won't work, so just hard-code the common part here.
48
-		//
49
-		// TODO this should probably be a test in the CLI repository instead
50
-		c.Assert(strings.ToLower(err.Error()), checker.Contains, "cannot find the file specified")
51
-		c.Assert(strings.ToLower(err.Error()), checker.Contains, strings.ToLower(tmpDir))
52
-	} else {
53
-		c.Assert(strings.ToLower(err.Error()), checker.Contains, strings.ToLower(srcStatErr.Error()))
54
-	}
55
-}
56
-
57
-// Test for error when SRC ends in a trailing
58
-// path separator but it exists as a file.
59
-func (s *DockerSuite) TestCpToErrSrcNotDir(c *check.C) {
60
-	containerID := makeTestContainer(c, testContainerOptions{})
61
-
62
-	tmpDir := getTestDir(c, "test-cp-to-err-src-not-dir")
63
-	defer os.RemoveAll(tmpDir)
64
-
65
-	makeTestContentInDir(c, tmpDir)
66
-
67
-	srcPath := cpPathTrailingSep(tmpDir, "file1")
68
-	dstPath := containerCpPath(containerID, "testDir")
69
-
70
-	err := runDockerCp(c, srcPath, dstPath, nil)
71
-	c.Assert(err, checker.NotNil)
72
-
73
-	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
74
-}
75
-
76
-// Test for error when SRC is a valid file or directory,
77
-// but the DST parent directory does not exist.
78
-func (s *DockerSuite) TestCpToErrDstParentNotExists(c *check.C) {
79
-	testRequires(c, DaemonIsLinux)
80
-	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
81
-
82
-	tmpDir := getTestDir(c, "test-cp-to-err-dst-parent-not-exists")
83
-	defer os.RemoveAll(tmpDir)
84
-
85
-	makeTestContentInDir(c, tmpDir)
86
-
87
-	// Try with a file source.
88
-	srcPath := cpPath(tmpDir, "file1")
89
-	dstPath := containerCpPath(containerID, "/notExists", "file1")
90
-
91
-	err := runDockerCp(c, srcPath, dstPath, nil)
92
-	c.Assert(err, checker.NotNil)
93
-
94
-	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
95
-
96
-	// Try with a directory source.
97
-	srcPath = cpPath(tmpDir, "dir1")
98
-
99
-	err = runDockerCp(c, srcPath, dstPath, nil)
100
-	c.Assert(err, checker.NotNil)
101
-
102
-	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
103
-}
104
-
105
-// Test for error when DST ends in a trailing path separator but exists as a
106
-// file. Also test that we cannot overwrite an existing directory with a
107
-// non-directory and cannot overwrite an existing
108
-func (s *DockerSuite) TestCpToErrDstNotDir(c *check.C) {
109
-	testRequires(c, DaemonIsLinux)
110
-	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
111
-
112
-	tmpDir := getTestDir(c, "test-cp-to-err-dst-not-dir")
113
-	defer os.RemoveAll(tmpDir)
114
-
115
-	makeTestContentInDir(c, tmpDir)
116
-
117
-	// Try with a file source.
118
-	srcPath := cpPath(tmpDir, "dir1/file1-1")
119
-	dstPath := containerCpPathTrailingSep(containerID, "file1")
120
-
121
-	// The client should encounter an error trying to stat the destination
122
-	// and then be unable to copy since the destination is asserted to be a
123
-	// directory but does not exist.
124
-	err := runDockerCp(c, srcPath, dstPath, nil)
125
-	c.Assert(err, checker.NotNil)
126
-
127
-	c.Assert(isCpDirNotExist(err), checker.True, check.Commentf("expected DirNotExist error, but got %T: %s", err, err))
128
-
129
-	// Try with a directory source.
130
-	srcPath = cpPath(tmpDir, "dir1")
131
-
132
-	// The client should encounter an error trying to stat the destination and
133
-	// then decide to extract to the parent directory instead with a rebased
134
-	// name in the source archive, but this directory would overwrite the
135
-	// existing file with the same name.
136
-	err = runDockerCp(c, srcPath, dstPath, nil)
137
-	c.Assert(err, checker.NotNil)
138
-
139
-	c.Assert(isCannotOverwriteNonDirWithDir(err), checker.True, check.Commentf("expected CannotOverwriteNonDirWithDir error, but got %T: %s", err, err))
140
-}
141
-
142 24
 // Check that copying from a local path to a symlink in a container copies to
143 25
 // the symlink target and does not overwrite the container symlink itself.
144 26
 func (s *DockerSuite) TestCpToSymlinkDestination(c *check.C) {
... ...
@@ -228,18 +228,10 @@ func getTestDir(c *check.C, label string) (tmpDir string) {
228 228
 	return
229 229
 }
230 230
 
231
-func isCpNotExist(err error) bool {
232
-	return strings.Contains(strings.ToLower(err.Error()), "could not find the file")
233
-}
234
-
235 231
 func isCpDirNotExist(err error) bool {
236 232
 	return strings.Contains(err.Error(), archive.ErrDirNotExists.Error())
237 233
 }
238 234
 
239
-func isCpNotDir(err error) bool {
240
-	return strings.Contains(err.Error(), archive.ErrNotDirectory.Error()) || strings.Contains(err.Error(), "filename, directory name, or volume label syntax is incorrect")
241
-}
242
-
243 235
 func isCpCannotCopyDir(err error) bool {
244 236
 	return strings.Contains(err.Error(), archive.ErrCannotCopyDir.Error())
245 237
 }
... ...
@@ -248,10 +240,6 @@ func isCpCannotCopyReadOnly(err error) bool {
248 248
 	return strings.Contains(err.Error(), "marked read-only")
249 249
 }
250 250
 
251
-func isCannotOverwriteNonDirWithDir(err error) bool {
252
-	return strings.Contains(err.Error(), "cannot overwrite non-directory")
253
-}
254
-
255 251
 func fileContentEquals(c *check.C, filename, contents string) (err error) {
256 252
 	c.Logf("checking that file %q contains %q\n", filename, contents)
257 253
 
258 254
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+package container // import "github.com/docker/docker/integration/container"
1
+
2
+import (
3
+	"context"
4
+	"fmt"
5
+	"testing"
6
+
7
+	"github.com/docker/docker/api/types"
8
+	"github.com/docker/docker/client"
9
+	"github.com/docker/docker/integration/internal/container"
10
+	"github.com/docker/docker/internal/testutil"
11
+	"github.com/gotestyourself/gotestyourself/skip"
12
+	"github.com/stretchr/testify/require"
13
+)
14
+
15
+func TestCopyFromContainerPathDoesNotExist(t *testing.T) {
16
+	defer setupTest(t)()
17
+
18
+	ctx := context.Background()
19
+	apiclient := testEnv.APIClient()
20
+	cid := container.Create(t, ctx, apiclient)
21
+
22
+	_, _, err := apiclient.CopyFromContainer(ctx, cid, "/dne")
23
+	require.True(t, client.IsErrNotFound(err))
24
+	expected := fmt.Sprintf("No such container:path: %s:%s", cid, "/dne")
25
+	testutil.ErrorContains(t, err, expected)
26
+}
27
+
28
+func TestCopyFromContainerPathIsNotDir(t *testing.T) {
29
+	defer setupTest(t)()
30
+	skip.If(t, testEnv.OSType == "windows")
31
+
32
+	ctx := context.Background()
33
+	apiclient := testEnv.APIClient()
34
+	cid := container.Create(t, ctx, apiclient)
35
+
36
+	_, _, err := apiclient.CopyFromContainer(ctx, cid, "/etc/passwd/")
37
+	require.Contains(t, err.Error(), "not a directory")
38
+}
39
+
40
+func TestCopyToContainerPathDoesNotExist(t *testing.T) {
41
+	defer setupTest(t)()
42
+	skip.If(t, testEnv.OSType == "windows")
43
+
44
+	ctx := context.Background()
45
+	apiclient := testEnv.APIClient()
46
+	cid := container.Create(t, ctx, apiclient)
47
+
48
+	err := apiclient.CopyToContainer(ctx, cid, "/dne", nil, types.CopyToContainerOptions{})
49
+	require.True(t, client.IsErrNotFound(err))
50
+	expected := fmt.Sprintf("No such container:path: %s:%s", cid, "/dne")
51
+	testutil.ErrorContains(t, err, expected)
52
+}
53
+
54
+func TestCopyToContainerPathIsNotDir(t *testing.T) {
55
+	defer setupTest(t)()
56
+	skip.If(t, testEnv.OSType == "windows")
57
+
58
+	ctx := context.Background()
59
+	apiclient := testEnv.APIClient()
60
+	cid := container.Create(t, ctx, apiclient)
61
+
62
+	err := apiclient.CopyToContainer(ctx, cid, "/etc/passwd/", nil, types.CopyToContainerOptions{})
63
+	require.Contains(t, err.Error(), "not a directory")
64
+}