Tizen_4.0 base
[platform/upstream/docker-engine.git] / builder / dockerfile / internals_test.go
1 package dockerfile
2
3 import (
4         "fmt"
5         "runtime"
6         "testing"
7
8         "github.com/docker/docker/api/types"
9         "github.com/docker/docker/api/types/backend"
10         "github.com/docker/docker/api/types/container"
11         "github.com/docker/docker/builder"
12         "github.com/docker/docker/builder/remotecontext"
13         "github.com/docker/docker/pkg/archive"
14         "github.com/stretchr/testify/assert"
15         "github.com/stretchr/testify/require"
16 )
17
18 func TestEmptyDockerfile(t *testing.T) {
19         contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
20         defer cleanup()
21
22         createTestTempFile(t, contextDir, builder.DefaultDockerfileName, "", 0777)
23
24         readAndCheckDockerfile(t, "emptyDockerfile", contextDir, "", "the Dockerfile (Dockerfile) cannot be empty")
25 }
26
27 func TestSymlinkDockerfile(t *testing.T) {
28         contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
29         defer cleanup()
30
31         createTestSymlink(t, contextDir, builder.DefaultDockerfileName, "/etc/passwd")
32
33         // The reason the error is "Cannot locate specified Dockerfile" is because
34         // in the builder, the symlink is resolved within the context, therefore
35         // Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
36         // a nonexistent file.
37         expectedError := fmt.Sprintf("Cannot locate specified Dockerfile: %s", builder.DefaultDockerfileName)
38
39         readAndCheckDockerfile(t, "symlinkDockerfile", contextDir, builder.DefaultDockerfileName, expectedError)
40 }
41
42 func TestDockerfileOutsideTheBuildContext(t *testing.T) {
43         contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
44         defer cleanup()
45
46         expectedError := "Forbidden path outside the build context: ../../Dockerfile ()"
47
48         readAndCheckDockerfile(t, "DockerfileOutsideTheBuildContext", contextDir, "../../Dockerfile", expectedError)
49 }
50
51 func TestNonExistingDockerfile(t *testing.T) {
52         contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
53         defer cleanup()
54
55         expectedError := "Cannot locate specified Dockerfile: Dockerfile"
56
57         readAndCheckDockerfile(t, "NonExistingDockerfile", contextDir, "Dockerfile", expectedError)
58 }
59
60 func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, expectedError string) {
61         tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
62         require.NoError(t, err)
63
64         defer func() {
65                 if err = tarStream.Close(); err != nil {
66                         t.Fatalf("Error when closing tar stream: %s", err)
67                 }
68         }()
69
70         if dockerfilePath == "" { // handled in BuildWithContext
71                 dockerfilePath = builder.DefaultDockerfileName
72         }
73
74         config := backend.BuildConfig{
75                 Options: &types.ImageBuildOptions{Dockerfile: dockerfilePath},
76                 Source:  tarStream,
77         }
78         _, _, err = remotecontext.Detect(config)
79         assert.EqualError(t, err, expectedError)
80 }
81
82 func TestCopyRunConfig(t *testing.T) {
83         defaultEnv := []string{"foo=1"}
84         defaultCmd := []string{"old"}
85
86         var testcases = []struct {
87                 doc       string
88                 modifiers []runConfigModifier
89                 expected  *container.Config
90         }{
91                 {
92                         doc:       "Set the command",
93                         modifiers: []runConfigModifier{withCmd([]string{"new"})},
94                         expected: &container.Config{
95                                 Cmd: []string{"new"},
96                                 Env: defaultEnv,
97                         },
98                 },
99                 {
100                         doc:       "Set the command to a comment",
101                         modifiers: []runConfigModifier{withCmdComment("comment", runtime.GOOS)},
102                         expected: &container.Config{
103                                 Cmd: append(defaultShellForPlatform(runtime.GOOS), "#(nop) ", "comment"),
104                                 Env: defaultEnv,
105                         },
106                 },
107                 {
108                         doc: "Set the command and env",
109                         modifiers: []runConfigModifier{
110                                 withCmd([]string{"new"}),
111                                 withEnv([]string{"one", "two"}),
112                         },
113                         expected: &container.Config{
114                                 Cmd: []string{"new"},
115                                 Env: []string{"one", "two"},
116                         },
117                 },
118         }
119
120         for _, testcase := range testcases {
121                 runConfig := &container.Config{
122                         Cmd: defaultCmd,
123                         Env: defaultEnv,
124                 }
125                 runConfigCopy := copyRunConfig(runConfig, testcase.modifiers...)
126                 assert.Equal(t, testcase.expected, runConfigCopy, testcase.doc)
127                 // Assert the original was not modified
128                 assert.NotEqual(t, runConfig, runConfigCopy, testcase.doc)
129         }
130
131 }