mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Migrate some copy tests to integration
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
		
							parent
							
								
									600475715e
								
							
						
					
					
						commit
						00d409f03e
					
				
					 4 changed files with 66 additions and 195 deletions
				
			
		| 
						 | 
				
			
			@ -8,8 +8,6 @@ import (
 | 
			
		|||
	"github.com/go-check/check"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// docker cp CONTAINER:PATH LOCALPATH
 | 
			
		||||
 | 
			
		||||
// Try all of the test cases from the archive package which implements the
 | 
			
		||||
// internals of `docker cp` and ensure that the behavior matches when actually
 | 
			
		||||
// copying to and from containers.
 | 
			
		||||
| 
						 | 
				
			
			@ -20,67 +18,9 @@ import (
 | 
			
		|||
// 3. DST parent directory must exist.
 | 
			
		||||
// 4. If DST exists as a file, it must not end with a trailing separator.
 | 
			
		||||
 | 
			
		||||
// First get these easy error cases out of the way.
 | 
			
		||||
 | 
			
		||||
// Test for error when SRC does not exist.
 | 
			
		||||
func (s *DockerSuite) TestCpFromErrSrcNotExists(c *check.C) {
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{})
 | 
			
		||||
 | 
			
		||||
	tmpDir := getTestDir(c, "test-cp-from-err-src-not-exists")
 | 
			
		||||
	defer os.RemoveAll(tmpDir)
 | 
			
		||||
 | 
			
		||||
	err := runDockerCp(c, containerCpPath(containerID, "file1"), tmpDir, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test for error when SRC ends in a trailing
 | 
			
		||||
// path separator but it exists as a file.
 | 
			
		||||
func (s *DockerSuite) TestCpFromErrSrcNotDir(c *check.C) {
 | 
			
		||||
	testRequires(c, DaemonIsLinux)
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
 | 
			
		||||
 | 
			
		||||
	tmpDir := getTestDir(c, "test-cp-from-err-src-not-dir")
 | 
			
		||||
	defer os.RemoveAll(tmpDir)
 | 
			
		||||
 | 
			
		||||
	err := runDockerCp(c, containerCpPathTrailingSep(containerID, "file1"), tmpDir, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test for error when DST ends in a trailing
 | 
			
		||||
// path separator but exists as a file.
 | 
			
		||||
func (s *DockerSuite) TestCpFromErrDstNotDir(c *check.C) {
 | 
			
		||||
	testRequires(c, DaemonIsLinux)
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
 | 
			
		||||
 | 
			
		||||
	tmpDir := getTestDir(c, "test-cp-from-err-dst-not-dir")
 | 
			
		||||
	defer os.RemoveAll(tmpDir)
 | 
			
		||||
 | 
			
		||||
	makeTestContentInDir(c, tmpDir)
 | 
			
		||||
 | 
			
		||||
	// Try with a file source.
 | 
			
		||||
	srcPath := containerCpPath(containerID, "/file1")
 | 
			
		||||
	dstPath := cpPathTrailingSep(tmpDir, "file1")
 | 
			
		||||
 | 
			
		||||
	err := runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
 | 
			
		||||
 | 
			
		||||
	// Try with a directory source.
 | 
			
		||||
	srcPath = containerCpPath(containerID, "/dir1")
 | 
			
		||||
 | 
			
		||||
	err = runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check that copying from a container to a local symlink copies to the symlink
 | 
			
		||||
// target and does not overwrite the local symlink itself.
 | 
			
		||||
// TODO: move to docker/cli and/or integration/container/copy_test.go
 | 
			
		||||
func (s *DockerSuite) TestCpFromSymlinkDestination(c *check.C) {
 | 
			
		||||
	testRequires(c, DaemonIsLinux)
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,15 +2,11 @@ package main
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/integration-cli/checker"
 | 
			
		||||
	"github.com/go-check/check"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// docker cp LOCALPATH CONTAINER:PATH
 | 
			
		||||
 | 
			
		||||
// Try all of the test cases from the archive package which implements the
 | 
			
		||||
// internals of `docker cp` and ensure that the behavior matches when actually
 | 
			
		||||
// copying to and from containers.
 | 
			
		||||
| 
						 | 
				
			
			@ -21,124 +17,6 @@ import (
 | 
			
		|||
// 3. DST parent directory must exist.
 | 
			
		||||
// 4. If DST exists as a file, it must not end with a trailing separator.
 | 
			
		||||
 | 
			
		||||
// First get these easy error cases out of the way.
 | 
			
		||||
 | 
			
		||||
// Test for error when SRC does not exist.
 | 
			
		||||
func (s *DockerSuite) TestCpToErrSrcNotExists(c *check.C) {
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{})
 | 
			
		||||
 | 
			
		||||
	tmpDir := getTestDir(c, "test-cp-to-err-src-not-exists")
 | 
			
		||||
	defer os.RemoveAll(tmpDir)
 | 
			
		||||
 | 
			
		||||
	srcPath := cpPath(tmpDir, "file1")
 | 
			
		||||
	dstPath := containerCpPath(containerID, "file1")
 | 
			
		||||
	_, srcStatErr := os.Stat(srcPath)
 | 
			
		||||
	c.Assert(os.IsNotExist(srcStatErr), checker.True)
 | 
			
		||||
 | 
			
		||||
	err := runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	if runtime.GOOS == "windows" {
 | 
			
		||||
		// Go 1.9+ on Windows returns a different error for `os.Stat()`, see
 | 
			
		||||
		// https://github.com/golang/go/commit/6144c7270e5812d9de8fb97456ee4e5ae657fcbb#diff-f63e1a4b4377b2fe0b05011db3df9599
 | 
			
		||||
		//
 | 
			
		||||
		// Go 1.8: CreateFile C:\not-exist: The system cannot find the file specified.
 | 
			
		||||
		// Go 1.9: GetFileAttributesEx C:\not-exist: The system cannot find the file specified.
 | 
			
		||||
		//
 | 
			
		||||
		// Due to the CLI using a different version than the daemon, comparing the
 | 
			
		||||
		// error message won't work, so just hard-code the common part here.
 | 
			
		||||
		//
 | 
			
		||||
		// TODO this should probably be a test in the CLI repository instead
 | 
			
		||||
		c.Assert(strings.ToLower(err.Error()), checker.Contains, "cannot find the file specified")
 | 
			
		||||
		c.Assert(strings.ToLower(err.Error()), checker.Contains, strings.ToLower(tmpDir))
 | 
			
		||||
	} else {
 | 
			
		||||
		c.Assert(strings.ToLower(err.Error()), checker.Contains, strings.ToLower(srcStatErr.Error()))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test for error when SRC ends in a trailing
 | 
			
		||||
// path separator but it exists as a file.
 | 
			
		||||
func (s *DockerSuite) TestCpToErrSrcNotDir(c *check.C) {
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{})
 | 
			
		||||
 | 
			
		||||
	tmpDir := getTestDir(c, "test-cp-to-err-src-not-dir")
 | 
			
		||||
	defer os.RemoveAll(tmpDir)
 | 
			
		||||
 | 
			
		||||
	makeTestContentInDir(c, tmpDir)
 | 
			
		||||
 | 
			
		||||
	srcPath := cpPathTrailingSep(tmpDir, "file1")
 | 
			
		||||
	dstPath := containerCpPath(containerID, "testDir")
 | 
			
		||||
 | 
			
		||||
	err := runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test for error when SRC is a valid file or directory,
 | 
			
		||||
// but the DST parent directory does not exist.
 | 
			
		||||
func (s *DockerSuite) TestCpToErrDstParentNotExists(c *check.C) {
 | 
			
		||||
	testRequires(c, DaemonIsLinux)
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
 | 
			
		||||
 | 
			
		||||
	tmpDir := getTestDir(c, "test-cp-to-err-dst-parent-not-exists")
 | 
			
		||||
	defer os.RemoveAll(tmpDir)
 | 
			
		||||
 | 
			
		||||
	makeTestContentInDir(c, tmpDir)
 | 
			
		||||
 | 
			
		||||
	// Try with a file source.
 | 
			
		||||
	srcPath := cpPath(tmpDir, "file1")
 | 
			
		||||
	dstPath := containerCpPath(containerID, "/notExists", "file1")
 | 
			
		||||
 | 
			
		||||
	err := runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
 | 
			
		||||
 | 
			
		||||
	// Try with a directory source.
 | 
			
		||||
	srcPath = cpPath(tmpDir, "dir1")
 | 
			
		||||
 | 
			
		||||
	err = runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test for error when DST ends in a trailing path separator but exists as a
 | 
			
		||||
// file. Also test that we cannot overwrite an existing directory with a
 | 
			
		||||
// non-directory and cannot overwrite an existing
 | 
			
		||||
func (s *DockerSuite) TestCpToErrDstNotDir(c *check.C) {
 | 
			
		||||
	testRequires(c, DaemonIsLinux)
 | 
			
		||||
	containerID := makeTestContainer(c, testContainerOptions{addContent: true})
 | 
			
		||||
 | 
			
		||||
	tmpDir := getTestDir(c, "test-cp-to-err-dst-not-dir")
 | 
			
		||||
	defer os.RemoveAll(tmpDir)
 | 
			
		||||
 | 
			
		||||
	makeTestContentInDir(c, tmpDir)
 | 
			
		||||
 | 
			
		||||
	// Try with a file source.
 | 
			
		||||
	srcPath := cpPath(tmpDir, "dir1/file1-1")
 | 
			
		||||
	dstPath := containerCpPathTrailingSep(containerID, "file1")
 | 
			
		||||
 | 
			
		||||
	// The client should encounter an error trying to stat the destination
 | 
			
		||||
	// and then be unable to copy since the destination is asserted to be a
 | 
			
		||||
	// directory but does not exist.
 | 
			
		||||
	err := runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCpDirNotExist(err), checker.True, check.Commentf("expected DirNotExist error, but got %T: %s", err, err))
 | 
			
		||||
 | 
			
		||||
	// Try with a directory source.
 | 
			
		||||
	srcPath = cpPath(tmpDir, "dir1")
 | 
			
		||||
 | 
			
		||||
	// The client should encounter an error trying to stat the destination and
 | 
			
		||||
	// then decide to extract to the parent directory instead with a rebased
 | 
			
		||||
	// name in the source archive, but this directory would overwrite the
 | 
			
		||||
	// existing file with the same name.
 | 
			
		||||
	err = runDockerCp(c, srcPath, dstPath, nil)
 | 
			
		||||
	c.Assert(err, checker.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(isCannotOverwriteNonDirWithDir(err), checker.True, check.Commentf("expected CannotOverwriteNonDirWithDir error, but got %T: %s", err, err))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check that copying from a local path to a symlink in a container copies to
 | 
			
		||||
// the symlink target and does not overwrite the container symlink itself.
 | 
			
		||||
func (s *DockerSuite) TestCpToSymlinkDestination(c *check.C) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -228,18 +228,10 @@ func getTestDir(c *check.C, label string) (tmpDir string) {
 | 
			
		|||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isCpNotExist(err error) bool {
 | 
			
		||||
	return strings.Contains(strings.ToLower(err.Error()), "could not find the file")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isCpDirNotExist(err error) bool {
 | 
			
		||||
	return strings.Contains(err.Error(), archive.ErrDirNotExists.Error())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isCpNotDir(err error) bool {
 | 
			
		||||
	return strings.Contains(err.Error(), archive.ErrNotDirectory.Error()) || strings.Contains(err.Error(), "filename, directory name, or volume label syntax is incorrect")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isCpCannotCopyDir(err error) bool {
 | 
			
		||||
	return strings.Contains(err.Error(), archive.ErrCannotCopyDir.Error())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -248,10 +240,6 @@ func isCpCannotCopyReadOnly(err error) bool {
 | 
			
		|||
	return strings.Contains(err.Error(), "marked read-only")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isCannotOverwriteNonDirWithDir(err error) bool {
 | 
			
		||||
	return strings.Contains(err.Error(), "cannot overwrite non-directory")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fileContentEquals(c *check.C, filename, contents string) (err error) {
 | 
			
		||||
	c.Logf("checking that file %q contains %q\n", filename, contents)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										65
									
								
								integration/container/copy_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								integration/container/copy_test.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
package container // import "github.com/docker/docker/integration/container"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	"github.com/docker/docker/client"
 | 
			
		||||
	"github.com/docker/docker/integration/internal/container"
 | 
			
		||||
	"github.com/docker/docker/internal/testutil"
 | 
			
		||||
	"github.com/gotestyourself/gotestyourself/skip"
 | 
			
		||||
	"github.com/stretchr/testify/require"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestCopyFromContainerPathDoesNotExist(t *testing.T) {
 | 
			
		||||
	defer setupTest(t)()
 | 
			
		||||
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	apiclient := testEnv.APIClient()
 | 
			
		||||
	cid := container.Create(t, ctx, apiclient)
 | 
			
		||||
 | 
			
		||||
	_, _, err := apiclient.CopyFromContainer(ctx, cid, "/dne")
 | 
			
		||||
	require.True(t, client.IsErrNotFound(err))
 | 
			
		||||
	expected := fmt.Sprintf("No such container:path: %s:%s", cid, "/dne")
 | 
			
		||||
	testutil.ErrorContains(t, err, expected)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCopyFromContainerPathIsNotDir(t *testing.T) {
 | 
			
		||||
	defer setupTest(t)()
 | 
			
		||||
	skip.If(t, testEnv.OSType == "windows")
 | 
			
		||||
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	apiclient := testEnv.APIClient()
 | 
			
		||||
	cid := container.Create(t, ctx, apiclient)
 | 
			
		||||
 | 
			
		||||
	_, _, err := apiclient.CopyFromContainer(ctx, cid, "/etc/passwd/")
 | 
			
		||||
	require.Contains(t, err.Error(), "not a directory")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCopyToContainerPathDoesNotExist(t *testing.T) {
 | 
			
		||||
	defer setupTest(t)()
 | 
			
		||||
	skip.If(t, testEnv.OSType == "windows")
 | 
			
		||||
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	apiclient := testEnv.APIClient()
 | 
			
		||||
	cid := container.Create(t, ctx, apiclient)
 | 
			
		||||
 | 
			
		||||
	err := apiclient.CopyToContainer(ctx, cid, "/dne", nil, types.CopyToContainerOptions{})
 | 
			
		||||
	require.True(t, client.IsErrNotFound(err))
 | 
			
		||||
	expected := fmt.Sprintf("No such container:path: %s:%s", cid, "/dne")
 | 
			
		||||
	testutil.ErrorContains(t, err, expected)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCopyToContainerPathIsNotDir(t *testing.T) {
 | 
			
		||||
	defer setupTest(t)()
 | 
			
		||||
	skip.If(t, testEnv.OSType == "windows")
 | 
			
		||||
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	apiclient := testEnv.APIClient()
 | 
			
		||||
	cid := container.Create(t, ctx, apiclient)
 | 
			
		||||
 | 
			
		||||
	err := apiclient.CopyToContainer(ctx, cid, "/etc/passwd/", nil, types.CopyToContainerOptions{})
 | 
			
		||||
	require.Contains(t, err.Error(), "not a directory")
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue