Reimplement integration test for symlink Dockerfile as a unit test
| ... | ... |
@@ -2,8 +2,6 @@ package dockerfile |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"io/ioutil" |
| 5 |
- "os" |
|
| 6 |
- "path/filepath" |
|
| 7 | 5 |
"strings" |
| 8 | 6 |
"testing" |
| 9 | 7 |
|
| ... | ... |
@@ -195,35 +193,3 @@ func executeTestCase(t *testing.T, testCase dispatchTestCase) {
|
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 | 197 |
} |
| 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 |
-} |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package dockerfile |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "fmt" |
|
| 4 | 5 |
"strings" |
| 5 | 6 |
"testing" |
| 6 | 7 |
|
| ... | ... |
@@ -15,6 +16,25 @@ func TestEmptyDockerfile(t *testing.T) {
|
| 15 | 15 |
|
| 16 | 16 |
createTestTempFile(t, contextDir, builder.DefaultDockerfileName, "", 0777) |
| 17 | 17 |
|
| 18 |
+ readAndCheckDockerfile(t, "emptyDockefile", contextDir, "", "The Dockerfile (Dockerfile) cannot be empty") |
|
| 19 |
+} |
|
| 20 |
+ |
|
| 21 |
+func TestSymlinkDockerfile(t *testing.T) {
|
|
| 22 |
+ contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test") |
|
| 23 |
+ defer cleanup() |
|
| 24 |
+ |
|
| 25 |
+ createTestSymlink(t, contextDir, builder.DefaultDockerfileName, "/etc/passwd") |
|
| 26 |
+ |
|
| 27 |
+ // The reason the error is "Cannot locate specified Dockerfile" is because |
|
| 28 |
+ // in the builder, the symlink is resolved within the context, therefore |
|
| 29 |
+ // Dockerfile -> /etc/passwd becomes etc/passwd from the context which is |
|
| 30 |
+ // a nonexistent file. |
|
| 31 |
+ expectedError := fmt.Sprintf("Cannot locate specified Dockerfile: %s", builder.DefaultDockerfileName)
|
|
| 32 |
+ |
|
| 33 |
+ readAndCheckDockerfile(t, "symlinkDockerfile", contextDir, builder.DefaultDockerfileName, expectedError) |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 36 |
+func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, expectedError string) {
|
|
| 18 | 37 |
tarStream, err := archive.Tar(contextDir, archive.Uncompressed) |
| 19 | 38 |
|
| 20 | 39 |
if err != nil {
|
| ... | ... |
@@ -39,18 +59,20 @@ func TestEmptyDockerfile(t *testing.T) {
|
| 39 | 39 |
} |
| 40 | 40 |
}() |
| 41 | 41 |
|
| 42 |
- options := &types.ImageBuildOptions{}
|
|
| 42 |
+ options := &types.ImageBuildOptions{
|
|
| 43 |
+ Dockerfile: dockerfilePath, |
|
| 44 |
+ } |
|
| 43 | 45 |
|
| 44 | 46 |
b := &Builder{options: options, context: context}
|
| 45 | 47 |
|
| 46 | 48 |
err = b.readDockerfile() |
| 47 | 49 |
|
| 48 | 50 |
if err == nil {
|
| 49 |
- t.Fatalf("No error when executing test for empty Dockerfile")
|
|
| 51 |
+ t.Fatalf("No error when executing test: %s", testName)
|
|
| 50 | 52 |
} |
| 51 | 53 |
|
| 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())
|
|
| 54 |
+ if !strings.Contains(err.Error(), expectedError) {
|
|
| 55 |
+ t.Fatalf("Wrong error message. Should be \"%s\". Got \"%s\"", expectedError, err.Error())
|
|
| 54 | 56 |
} |
| 55 | 57 |
} |
| 56 | 58 |
|
| 57 | 59 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,50 @@ |
| 0 |
+package dockerfile |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "io/ioutil" |
|
| 4 |
+ "os" |
|
| 5 |
+ "path/filepath" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// createTestTempDir creates a temporary directory for testing. |
|
| 10 |
+// It returns the created path and a cleanup function which is meant to be used as deferred call. |
|
| 11 |
+// When an error occurs, it terminates the test. |
|
| 12 |
+func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) {
|
|
| 13 |
+ path, err := ioutil.TempDir(dir, prefix) |
|
| 14 |
+ |
|
| 15 |
+ if err != nil {
|
|
| 16 |
+ t.Fatalf("Error when creating directory %s with prefix %s: %s", dir, prefix, err)
|
|
| 17 |
+ } |
|
| 18 |
+ |
|
| 19 |
+ return path, func() {
|
|
| 20 |
+ err = os.RemoveAll(path) |
|
| 21 |
+ |
|
| 22 |
+ if err != nil {
|
|
| 23 |
+ t.Fatalf("Error when removing directory %s: %s", path, err)
|
|
| 24 |
+ } |
|
| 25 |
+ } |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+// createTestTempFile creates a temporary file within dir with specific contents and permissions. |
|
| 29 |
+// When an error occurs, it terminates the test |
|
| 30 |
+func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.FileMode) string {
|
|
| 31 |
+ filePath := filepath.Join(dir, filename) |
|
| 32 |
+ err := ioutil.WriteFile(filePath, []byte(contents), perm) |
|
| 33 |
+ |
|
| 34 |
+ if err != nil {
|
|
| 35 |
+ t.Fatalf("Error when creating %s file: %s", filename, err)
|
|
| 36 |
+ } |
|
| 37 |
+ |
|
| 38 |
+ return filePath |
|
| 39 |
+} |
|
| 40 |
+ |
|
| 41 |
+// createTestSymlink creates a symlink file within dir which points to oldname |
|
| 42 |
+func createTestSymlink(t *testing.T, dir, filename, oldname string) string {
|
|
| 43 |
+ filePath := filepath.Join(dir, filename) |
|
| 44 |
+ if err := os.Symlink(oldname, filePath); err != nil {
|
|
| 45 |
+ t.Fatalf("Error when creating %s symlink to %s: %s", filename, oldname, err)
|
|
| 46 |
+ } |
|
| 47 |
+ |
|
| 48 |
+ return filePath |
|
| 49 |
+} |
| ... | ... |
@@ -193,38 +193,6 @@ RUN echo from dockerfile`, |
| 193 | 193 |
c.Assert(out, checker.Contains, "from Dockerfile") |
| 194 | 194 |
} |
| 195 | 195 |
|
| 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 |
- |
|
| 228 | 196 |
func (s *DockerSuite) TestBuildApiUnnormalizedTarPaths(c *check.C) {
|
| 229 | 197 |
// Make sure that build context tars with entries of the form |
| 230 | 198 |
// x/./y don't cause caching false positives. |