Files
docker-cli/components/engine/builder/dockerfile/internals_test.go
Sebastiaan van Stijn 2096535fce Fixes for libcontainer changes
Libcontainer no longer provides placeholders for
unsupported platforms, which cause the Windows
builds to fail.

This patch moves features that are not supported
to platform-specific files.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: d1c34831e930c1f6b3de28cab3f4a358845a79d5
Component: engine
2018-01-18 10:08:12 +01:00

171 lines
4.8 KiB
Go

package dockerfile
import (
"fmt"
"runtime"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder"
"github.com/docker/docker/builder/remotecontext"
"github.com/docker/docker/pkg/archive"
"github.com/docker/go-connections/nat"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestEmptyDockerfile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
defer cleanup()
createTestTempFile(t, contextDir, builder.DefaultDockerfileName, "", 0777)
readAndCheckDockerfile(t, "emptyDockerfile", contextDir, "", "the Dockerfile (Dockerfile) cannot be empty")
}
func TestSymlinkDockerfile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
defer cleanup()
createTestSymlink(t, contextDir, builder.DefaultDockerfileName, "/etc/passwd")
// The reason the error is "Cannot locate specified Dockerfile" is because
// in the builder, the symlink is resolved within the context, therefore
// Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
// a nonexistent file.
expectedError := fmt.Sprintf("Cannot locate specified Dockerfile: %s", builder.DefaultDockerfileName)
readAndCheckDockerfile(t, "symlinkDockerfile", contextDir, builder.DefaultDockerfileName, expectedError)
}
func TestDockerfileOutsideTheBuildContext(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
defer cleanup()
expectedError := "Forbidden path outside the build context: ../../Dockerfile ()"
readAndCheckDockerfile(t, "DockerfileOutsideTheBuildContext", contextDir, "../../Dockerfile", expectedError)
}
func TestNonExistingDockerfile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
defer cleanup()
expectedError := "Cannot locate specified Dockerfile: Dockerfile"
readAndCheckDockerfile(t, "NonExistingDockerfile", contextDir, "Dockerfile", expectedError)
}
func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, expectedError string) {
tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
require.NoError(t, err)
defer func() {
if err = tarStream.Close(); err != nil {
t.Fatalf("Error when closing tar stream: %s", err)
}
}()
if dockerfilePath == "" { // handled in BuildWithContext
dockerfilePath = builder.DefaultDockerfileName
}
config := backend.BuildConfig{
Options: &types.ImageBuildOptions{Dockerfile: dockerfilePath},
Source: tarStream,
}
_, _, err = remotecontext.Detect(config)
assert.EqualError(t, err, expectedError)
}
func TestCopyRunConfig(t *testing.T) {
defaultEnv := []string{"foo=1"}
defaultCmd := []string{"old"}
var testcases = []struct {
doc string
modifiers []runConfigModifier
expected *container.Config
}{
{
doc: "Set the command",
modifiers: []runConfigModifier{withCmd([]string{"new"})},
expected: &container.Config{
Cmd: []string{"new"},
Env: defaultEnv,
},
},
{
doc: "Set the command to a comment",
modifiers: []runConfigModifier{withCmdComment("comment", runtime.GOOS)},
expected: &container.Config{
Cmd: append(defaultShellForOS(runtime.GOOS), "#(nop) ", "comment"),
Env: defaultEnv,
},
},
{
doc: "Set the command and env",
modifiers: []runConfigModifier{
withCmd([]string{"new"}),
withEnv([]string{"one", "two"}),
},
expected: &container.Config{
Cmd: []string{"new"},
Env: []string{"one", "two"},
},
},
}
for _, testcase := range testcases {
runConfig := &container.Config{
Cmd: defaultCmd,
Env: defaultEnv,
}
runConfigCopy := copyRunConfig(runConfig, testcase.modifiers...)
assert.Equal(t, testcase.expected, runConfigCopy, testcase.doc)
// Assert the original was not modified
assert.NotEqual(t, runConfig, runConfigCopy, testcase.doc)
}
}
func fullMutableRunConfig() *container.Config {
return &container.Config{
Cmd: []string{"command", "arg1"},
Env: []string{"env1=foo", "env2=bar"},
ExposedPorts: nat.PortSet{
"1000/tcp": {},
"1001/tcp": {},
},
Volumes: map[string]struct{}{
"one": {},
"two": {},
},
Entrypoint: []string{"entry", "arg1"},
OnBuild: []string{"first", "next"},
Labels: map[string]string{
"label1": "value1",
"label2": "value2",
},
Shell: []string{"shell", "-c"},
}
}
func TestDeepCopyRunConfig(t *testing.T) {
runConfig := fullMutableRunConfig()
copy := copyRunConfig(runConfig)
assert.Equal(t, fullMutableRunConfig(), copy)
copy.Cmd[1] = "arg2"
copy.Env[1] = "env2=new"
copy.ExposedPorts["10002"] = struct{}{}
copy.Volumes["three"] = struct{}{}
copy.Entrypoint[1] = "arg2"
copy.OnBuild[0] = "start"
copy.Labels["label3"] = "value3"
copy.Shell[0] = "sh"
assert.Equal(t, fullMutableRunConfig(), runConfig)
}