|
@@ -0,0 +1,134 @@
|
|
|
+package dockerfile
|
|
|
+
|
|
|
+import (
|
|
|
+ "io/ioutil"
|
|
|
+ "os"
|
|
|
+ "strings"
|
|
|
+ "testing"
|
|
|
+
|
|
|
+ "github.com/docker/docker/builder"
|
|
|
+ "github.com/docker/docker/builder/dockerfile/parser"
|
|
|
+ "github.com/docker/docker/pkg/archive"
|
|
|
+ "github.com/docker/docker/pkg/reexec"
|
|
|
+ "github.com/docker/engine-api/types"
|
|
|
+ "github.com/docker/engine-api/types/container"
|
|
|
+)
|
|
|
+
|
|
|
+type dispatchTestCase struct {
|
|
|
+ name, dockerfile, expectedError string
|
|
|
+}
|
|
|
+
|
|
|
+func init() {
|
|
|
+ reexec.Init()
|
|
|
+}
|
|
|
+
|
|
|
+func initDispatchTestCases() []dispatchTestCase {
|
|
|
+ dispatchTestCases := []dispatchTestCase{{
|
|
|
+ name: "copyEmptyWhitespace",
|
|
|
+ dockerfile: `COPY
|
|
|
+ quux \
|
|
|
+ bar`,
|
|
|
+ expectedError: "COPY requires at least one argument",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "ONBUILD forbidden FROM",
|
|
|
+ dockerfile: "ONBUILD FROM scratch",
|
|
|
+ expectedError: "FROM isn't allowed as an ONBUILD trigger",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "ONBUILD forbidden MAINTAINER",
|
|
|
+ dockerfile: "ONBUILD MAINTAINER docker.io",
|
|
|
+ expectedError: "MAINTAINER isn't allowed as an ONBUILD trigger",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "ARG two arguments",
|
|
|
+ dockerfile: "ARG foo bar",
|
|
|
+ expectedError: "ARG requires exactly one argument definition",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "MAINTAINER unknown flag",
|
|
|
+ dockerfile: "MAINTAINER --boo joe@example.com",
|
|
|
+ expectedError: "Unknown flag: boo",
|
|
|
+ }}
|
|
|
+
|
|
|
+ return dispatchTestCases
|
|
|
+}
|
|
|
+
|
|
|
+func TestDispatch(t *testing.T) {
|
|
|
+ testCases := initDispatchTestCases()
|
|
|
+
|
|
|
+ for _, testCase := range testCases {
|
|
|
+ executeTestCase(t, testCase)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func executeTestCase(t *testing.T, testCase dispatchTestCase) {
|
|
|
+ contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
|
|
|
+ defer cleanup()
|
|
|
+
|
|
|
+ tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("Error when creating tar stream: %s", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ defer func() {
|
|
|
+ if err = tarStream.Close(); err != nil {
|
|
|
+ t.Fatalf("Error when closing tar stream: %s", err)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ context, err := builder.MakeTarSumContext(tarStream)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("Error when creating tar context: %s", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ defer func() {
|
|
|
+ if err = context.Close(); err != nil {
|
|
|
+ t.Fatalf("Error when closing tar context: %s", err)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ r := strings.NewReader(testCase.dockerfile)
|
|
|
+ n, err := parser.Parse(r)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("Error when parsing Dockerfile: %s", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ config := &container.Config{}
|
|
|
+ options := &types.ImageBuildOptions{}
|
|
|
+
|
|
|
+ b := &Builder{runConfig: config, options: options, Stdout: ioutil.Discard, context: context}
|
|
|
+
|
|
|
+ err = b.dispatch(0, n.Children[0])
|
|
|
+
|
|
|
+ if err == nil {
|
|
|
+ t.Fatalf("No error when executing test %s", testCase.name)
|
|
|
+ }
|
|
|
+
|
|
|
+ if !strings.Contains(err.Error(), testCase.expectedError) {
|
|
|
+ t.Fatalf("Wrong error message. Should be \"%s\". Got \"%s\"", testCase.expectedError, err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// createTestTempDir creates a temporary directory for testing.
|
|
|
+// It returns the created path and a cleanup function which is meant to be used as deferred call.
|
|
|
+// When an error occurs, it terminates the test.
|
|
|
+func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) {
|
|
|
+ path, err := ioutil.TempDir(dir, prefix)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("Error when creating directory %s with prefix %s: %s", dir, prefix, err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return path, func() {
|
|
|
+ err = os.RemoveAll(path)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("Error when removing directory %s: %s", path, err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|