Skip to content

Commit e08aed5

Browse files
authored
Merge pull request moby#23322 from tkopczynski/20784-builder-dockerfile-symlink
Reimplement integration test for symlink Dockerfile as a unit test
2 parents da15923 + 830584b commit e08aed5

File tree

4 files changed

+76
-70
lines changed

4 files changed

+76
-70
lines changed

builder/dockerfile/evaluator_test.go

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package dockerfile
22

33
import (
44
"io/ioutil"
5-
"os"
6-
"path/filepath"
75
"strings"
86
"testing"
97

@@ -195,35 +193,3 @@ func executeTestCase(t *testing.T, testCase dispatchTestCase) {
195193
}
196194

197195
}
198-
199-
// createTestTempDir creates a temporary directory for testing.
200-
// It returns the created path and a cleanup function which is meant to be used as deferred call.
201-
// When an error occurs, it terminates the test.
202-
func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) {
203-
path, err := ioutil.TempDir(dir, prefix)
204-
205-
if err != nil {
206-
t.Fatalf("Error when creating directory %s with prefix %s: %s", dir, prefix, err)
207-
}
208-
209-
return path, func() {
210-
err = os.RemoveAll(path)
211-
212-
if err != nil {
213-
t.Fatalf("Error when removing directory %s: %s", path, err)
214-
}
215-
}
216-
}
217-
218-
// createTestTempFile creates a temporary file within dir with specific contents and permissions.
219-
// When an error occurs, it terminates the test
220-
func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.FileMode) string {
221-
filePath := filepath.Join(dir, filename)
222-
err := ioutil.WriteFile(filePath, []byte(contents), perm)
223-
224-
if err != nil {
225-
t.Fatalf("Error when creating %s file: %s", filename, err)
226-
}
227-
228-
return filePath
229-
}

builder/dockerfile/internals_test.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dockerfile
22

33
import (
4+
"fmt"
45
"strings"
56
"testing"
67

@@ -15,6 +16,25 @@ func TestEmptyDockerfile(t *testing.T) {
1516

1617
createTestTempFile(t, contextDir, builder.DefaultDockerfileName, "", 0777)
1718

19+
readAndCheckDockerfile(t, "emptyDockefile", contextDir, "", "The Dockerfile (Dockerfile) cannot be empty")
20+
}
21+
22+
func TestSymlinkDockerfile(t *testing.T) {
23+
contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
24+
defer cleanup()
25+
26+
createTestSymlink(t, contextDir, builder.DefaultDockerfileName, "/etc/passwd")
27+
28+
// The reason the error is "Cannot locate specified Dockerfile" is because
29+
// in the builder, the symlink is resolved within the context, therefore
30+
// Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
31+
// a nonexistent file.
32+
expectedError := fmt.Sprintf("Cannot locate specified Dockerfile: %s", builder.DefaultDockerfileName)
33+
34+
readAndCheckDockerfile(t, "symlinkDockerfile", contextDir, builder.DefaultDockerfileName, expectedError)
35+
}
36+
37+
func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, expectedError string) {
1838
tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
1939

2040
if err != nil {
@@ -39,18 +59,20 @@ func TestEmptyDockerfile(t *testing.T) {
3959
}
4060
}()
4161

42-
options := &types.ImageBuildOptions{}
62+
options := &types.ImageBuildOptions{
63+
Dockerfile: dockerfilePath,
64+
}
4365

4466
b := &Builder{options: options, context: context}
4567

4668
err = b.readDockerfile()
4769

4870
if err == nil {
49-
t.Fatalf("No error when executing test for empty Dockerfile")
71+
t.Fatalf("No error when executing test: %s", testName)
5072
}
5173

52-
if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") {
53-
t.Fatalf("Wrong error message. Should be \"%s\". Got \"%s\"", "The Dockerfile (Dockerfile) cannot be empty", err.Error())
74+
if !strings.Contains(err.Error(), expectedError) {
75+
t.Fatalf("Wrong error message. Should be \"%s\". Got \"%s\"", expectedError, err.Error())
5476
}
5577
}
5678

builder/dockerfile/utils_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package dockerfile
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
)
9+
10+
// createTestTempDir creates a temporary directory for testing.
11+
// It returns the created path and a cleanup function which is meant to be used as deferred call.
12+
// When an error occurs, it terminates the test.
13+
func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) {
14+
path, err := ioutil.TempDir(dir, prefix)
15+
16+
if err != nil {
17+
t.Fatalf("Error when creating directory %s with prefix %s: %s", dir, prefix, err)
18+
}
19+
20+
return path, func() {
21+
err = os.RemoveAll(path)
22+
23+
if err != nil {
24+
t.Fatalf("Error when removing directory %s: %s", path, err)
25+
}
26+
}
27+
}
28+
29+
// createTestTempFile creates a temporary file within dir with specific contents and permissions.
30+
// When an error occurs, it terminates the test
31+
func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.FileMode) string {
32+
filePath := filepath.Join(dir, filename)
33+
err := ioutil.WriteFile(filePath, []byte(contents), perm)
34+
35+
if err != nil {
36+
t.Fatalf("Error when creating %s file: %s", filename, err)
37+
}
38+
39+
return filePath
40+
}
41+
42+
// createTestSymlink creates a symlink file within dir which points to oldname
43+
func createTestSymlink(t *testing.T, dir, filename, oldname string) string {
44+
filePath := filepath.Join(dir, filename)
45+
if err := os.Symlink(oldname, filePath); err != nil {
46+
t.Fatalf("Error when creating %s symlink to %s: %s", filename, oldname, err)
47+
}
48+
49+
return filePath
50+
}

integration-cli/docker_api_build_test.go

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -193,38 +193,6 @@ RUN echo from dockerfile`,
193193
c.Assert(out, checker.Contains, "from Dockerfile")
194194
}
195195

196-
func (s *DockerSuite) TestBuildApiDockerfileSymlink(c *check.C) {
197-
// Test to make sure we stop people from trying to leave the
198-
// build context when specifying a symlink as the path to the dockerfile
199-
buffer := new(bytes.Buffer)
200-
tw := tar.NewWriter(buffer)
201-
defer tw.Close()
202-
203-
err := tw.WriteHeader(&tar.Header{
204-
Name: "Dockerfile",
205-
Typeflag: tar.TypeSymlink,
206-
Linkname: "/etc/passwd",
207-
})
208-
// failed to write tar file header
209-
c.Assert(err, checker.IsNil)
210-
211-
// failed to close tar archive
212-
c.Assert(tw.Close(), checker.IsNil)
213-
214-
res, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
215-
c.Assert(err, checker.IsNil)
216-
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
217-
218-
out, err := readBody(body)
219-
c.Assert(err, checker.IsNil)
220-
221-
// The reason the error is "Cannot locate specified Dockerfile" is because
222-
// in the builder, the symlink is resolved within the context, therefore
223-
// Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
224-
// a nonexistent file.
225-
c.Assert(string(out), checker.Contains, "Cannot locate specified Dockerfile: Dockerfile", check.Commentf("Didn't complain about leaving build context"))
226-
}
227-
228196
func (s *DockerSuite) TestBuildApiUnnormalizedTarPaths(c *check.C) {
229197
// Make sure that build context tars with entries of the form
230198
// x/./y don't cause caching false positives.

0 commit comments

Comments
 (0)