Merge pull request #6471 from LK4D4/more_buildfile_tests_to_cli
Move more buildfile tests to integration-cli Upstream-commit: c7fdd51eb6407fba41200e7a14f652519b179b71 Component: engine
This commit is contained in:
@@ -1133,3 +1133,251 @@ func TestBuildWithVolumeOwnership(t *testing.T) {
|
||||
|
||||
logDone("build - volume ownership")
|
||||
}
|
||||
|
||||
// testing #1405 - config.Cmd does not get cleaned up if
|
||||
// utilizing cache
|
||||
func TestBuildEntrypointRunCleanup(t *testing.T) {
|
||||
name := "testbuildcmdcleanup"
|
||||
defer deleteImages(name)
|
||||
if _, err := buildImage(name,
|
||||
`FROM busybox
|
||||
RUN echo "hello"`,
|
||||
true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx, err := fakeContext(`FROM busybox
|
||||
RUN echo "hello"
|
||||
ADD foo /foo
|
||||
ENTRYPOINT ["/bin/echo"]`,
|
||||
map[string]string{
|
||||
"foo": "hello",
|
||||
})
|
||||
defer ctx.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := inspectField(name, "Config.Cmd")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Cmd inherited from busybox, maybe will be fixed in #5147
|
||||
if expected := "[/bin/sh]"; res != expected {
|
||||
t.Fatalf("Cmd %s, expected %s", res, expected)
|
||||
}
|
||||
logDone("build - cleanup cmd after RUN")
|
||||
}
|
||||
|
||||
func TestBuldForbiddenContextPath(t *testing.T) {
|
||||
name := "testbuildforbidpath"
|
||||
defer deleteImages(name)
|
||||
ctx, err := fakeContext(`FROM scratch
|
||||
ADD ../../ test/
|
||||
`,
|
||||
map[string]string{
|
||||
"test.txt": "test1",
|
||||
"other.txt": "other",
|
||||
})
|
||||
|
||||
defer ctx.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
||||
if !strings.Contains(err.Error(), "Forbidden path outside the build context: ../../ (/)") {
|
||||
t.Fatal("Wrong error, must be about forbidden ../../ path")
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Error must not be nil")
|
||||
}
|
||||
logDone("build - forbidden context path")
|
||||
}
|
||||
|
||||
func TestBuildADDFileNotFound(t *testing.T) {
|
||||
name := "testbuildaddnotfound"
|
||||
defer deleteImages(name)
|
||||
ctx, err := fakeContext(`FROM scratch
|
||||
ADD foo /usr/local/bar`,
|
||||
map[string]string{"bar": "hello"})
|
||||
defer ctx.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
||||
if !strings.Contains(err.Error(), "foo: no such file or directory") {
|
||||
t.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Error must not be nil")
|
||||
}
|
||||
logDone("build - add file not found")
|
||||
}
|
||||
|
||||
func TestBuildInheritance(t *testing.T) {
|
||||
name := "testbuildinheritance"
|
||||
defer deleteImages(name)
|
||||
|
||||
_, err := buildImage(name,
|
||||
`FROM scratch
|
||||
EXPOSE 2375`,
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ports1, err := inspectField(name, "Config.ExposedPorts")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = buildImage(name,
|
||||
fmt.Sprintf(`FROM %s
|
||||
ENTRYPOINT ["/bin/echo"]`, name),
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
res, err := inspectField(name, "Config.Entrypoint")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if expected := "[/bin/echo]"; res != expected {
|
||||
t.Fatalf("Entrypoint %s, expected %s", res, expected)
|
||||
}
|
||||
ports2, err := inspectField(name, "Config.ExposedPorts")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ports1 != ports2 {
|
||||
t.Fatalf("Ports must be same: %s != %s", ports1, ports2)
|
||||
}
|
||||
logDone("build - inheritance")
|
||||
}
|
||||
|
||||
func TestBuildFails(t *testing.T) {
|
||||
name := "testbuildfails"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name,
|
||||
`FROM busybox
|
||||
RUN sh -c "exit 23"`,
|
||||
true)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
|
||||
t.Fatalf("Wrong error %v, must be about non-zero code 23", err)
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Error must not be nil")
|
||||
}
|
||||
logDone("build - fails")
|
||||
}
|
||||
|
||||
func TestBuildFailsDockerfileEmpty(t *testing.T) {
|
||||
name := "testbuildfails"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name, ``, true)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "Dockerfile cannot be empty") {
|
||||
t.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Error must not be nil")
|
||||
}
|
||||
logDone("build - fails with empty dockerfile")
|
||||
}
|
||||
|
||||
func TestBuildOnBuild(t *testing.T) {
|
||||
name := "testbuildonbuild"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name,
|
||||
`FROM busybox
|
||||
ONBUILD RUN touch foobar`,
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = buildImage(name,
|
||||
fmt.Sprintf(`FROM %s
|
||||
RUN [ -f foobar ]`, name),
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
logDone("build - onbuild")
|
||||
}
|
||||
|
||||
func TestBuildOnBuildForbiddenChained(t *testing.T) {
|
||||
name := "testbuildonbuildforbiddenchained"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name,
|
||||
`FROM busybox
|
||||
ONBUILD ONBUILD RUN touch foobar`,
|
||||
true)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
|
||||
t.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Error must not be nil")
|
||||
}
|
||||
logDone("build - onbuild forbidden chained")
|
||||
}
|
||||
|
||||
func TestBuildOnBuildForbiddenFrom(t *testing.T) {
|
||||
name := "testbuildonbuildforbiddenfrom"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name,
|
||||
`FROM busybox
|
||||
ONBUILD FROM scratch`,
|
||||
true)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
|
||||
t.Fatalf("Wrong error %v, must be about FROM forbidden", err)
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Error must not be nil")
|
||||
}
|
||||
logDone("build - onbuild forbidden from")
|
||||
}
|
||||
|
||||
func TestBuildOnBuildForbiddenMaintainer(t *testing.T) {
|
||||
name := "testbuildonbuildforbiddenmaintainer"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name,
|
||||
`FROM busybox
|
||||
ONBUILD MAINTAINER docker.io`,
|
||||
true)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
|
||||
t.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Error must not be nil")
|
||||
}
|
||||
logDone("build - onbuild forbidden maintainer")
|
||||
}
|
||||
|
||||
// gh #2446
|
||||
func TestBuildAddToSymlinkDest(t *testing.T) {
|
||||
name := "testbuildaddtosymlinkdest"
|
||||
defer deleteImages(name)
|
||||
ctx, err := fakeContext(`FROM busybox
|
||||
RUN mkdir /foo
|
||||
RUN ln -s /foo /bar
|
||||
ADD foo /bar/
|
||||
RUN [ -f /bar/foo ]
|
||||
RUN [ -f /foo/foo ]`,
|
||||
map[string]string{
|
||||
"foo": "hello",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ctx.Close()
|
||||
if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
logDone("build - add to symlink destination")
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/dotcloud/docker/archive"
|
||||
"github.com/dotcloud/docker/engine"
|
||||
"github.com/dotcloud/docker/image"
|
||||
"github.com/dotcloud/docker/nat"
|
||||
"github.com/dotcloud/docker/server"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
)
|
||||
@@ -413,267 +412,3 @@ func buildImage(context testContextTemplate, t *testing.T, eng *engine.Engine, u
|
||||
err = json.NewDecoder(buffer).Decode(image)
|
||||
return image, err
|
||||
}
|
||||
|
||||
// testing #1405 - config.Cmd does not get cleaned up if
|
||||
// utilizing cache
|
||||
func TestBuildEntrypointRunCleanup(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
defer nuke(mkDaemonFromEngine(eng, t))
|
||||
|
||||
img, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
run echo "hello"
|
||||
`,
|
||||
nil, nil}, t, eng, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
img, err = buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
run echo "hello"
|
||||
add foo /foo
|
||||
entrypoint ["/bin/echo"]
|
||||
`,
|
||||
[][2]string{{"foo", "HEYO"}}, nil}, t, eng, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(img.Config.Cmd) != 0 {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestForbiddenContextPath(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
defer nuke(mkDaemonFromEngine(eng, t))
|
||||
srv := mkServerFromEngine(eng, t)
|
||||
|
||||
context := testContextTemplate{`
|
||||
from {IMAGE}
|
||||
maintainer dockerio
|
||||
add ../../ test/
|
||||
`,
|
||||
[][2]string{{"test.txt", "test1"}, {"other.txt", "other"}}, nil}
|
||||
|
||||
httpServer, err := mkTestingFileServer(context.remoteFiles)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer httpServer.Close()
|
||||
|
||||
idx := strings.LastIndex(httpServer.URL, ":")
|
||||
if idx < 0 {
|
||||
t.Fatalf("could not get port from test http server address %s", httpServer.URL)
|
||||
}
|
||||
port := httpServer.URL[idx+1:]
|
||||
|
||||
iIP := eng.Hack_GetGlobalVar("httpapi.bridgeIP")
|
||||
if iIP == nil {
|
||||
t.Fatal("Legacy bridgeIP field not set in engine")
|
||||
}
|
||||
ip, ok := iIP.(net.IP)
|
||||
if !ok {
|
||||
panic("Legacy bridgeIP field in engine does not cast to net.IP")
|
||||
}
|
||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||
|
||||
buildfile := server.NewBuildFile(srv, ioutil.Discard, ioutil.Discard, false, true, false, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
||||
_, err = buildfile.Build(context.Archive(dockerfile, t))
|
||||
|
||||
if err == nil {
|
||||
t.Log("Error should not be nil")
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if err.Error() != "Forbidden path outside the build context: ../../ (/)" {
|
||||
t.Logf("Error message is not expected: %s", err.Error())
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildADDFileNotFound(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
defer nuke(mkDaemonFromEngine(eng, t))
|
||||
|
||||
context := testContextTemplate{`
|
||||
from {IMAGE}
|
||||
add foo /usr/local/bar
|
||||
`,
|
||||
nil, nil}
|
||||
|
||||
httpServer, err := mkTestingFileServer(context.remoteFiles)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer httpServer.Close()
|
||||
|
||||
idx := strings.LastIndex(httpServer.URL, ":")
|
||||
if idx < 0 {
|
||||
t.Fatalf("could not get port from test http server address %s", httpServer.URL)
|
||||
}
|
||||
port := httpServer.URL[idx+1:]
|
||||
|
||||
iIP := eng.Hack_GetGlobalVar("httpapi.bridgeIP")
|
||||
if iIP == nil {
|
||||
t.Fatal("Legacy bridgeIP field not set in engine")
|
||||
}
|
||||
ip, ok := iIP.(net.IP)
|
||||
if !ok {
|
||||
panic("Legacy bridgeIP field in engine does not cast to net.IP")
|
||||
}
|
||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||
|
||||
buildfile := server.NewBuildFile(mkServerFromEngine(eng, t), ioutil.Discard, ioutil.Discard, false, true, false, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
||||
_, err = buildfile.Build(context.Archive(dockerfile, t))
|
||||
|
||||
if err == nil {
|
||||
t.Log("Error should not be nil")
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if err.Error() != "foo: no such file or directory" {
|
||||
t.Logf("Error message is not expected: %s", err.Error())
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildInheritance(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
defer nuke(mkDaemonFromEngine(eng, t))
|
||||
|
||||
img, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
expose 2375
|
||||
`,
|
||||
nil, nil}, t, eng, true)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
img2, _ := buildImage(testContextTemplate{fmt.Sprintf(`
|
||||
from %s
|
||||
entrypoint ["/bin/echo"]
|
||||
`, img.ID),
|
||||
nil, nil}, t, eng, true)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// from child
|
||||
if img2.Config.Entrypoint[0] != "/bin/echo" {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// from parent
|
||||
if _, exists := img.Config.ExposedPorts[nat.NewPort("tcp", "2375")]; !exists {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildFails(t *testing.T) {
|
||||
_, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
run sh -c "exit 23"
|
||||
`,
|
||||
nil, nil}, t, nil, true)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Error should not be nil")
|
||||
}
|
||||
|
||||
sterr, ok := err.(*utils.JSONError)
|
||||
if !ok {
|
||||
t.Fatalf("Error should be utils.JSONError")
|
||||
}
|
||||
if sterr.Code != 23 {
|
||||
t.Fatalf("StatusCode %d unexpected, should be 23", sterr.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildFailsDockerfileEmpty(t *testing.T) {
|
||||
_, err := buildImage(testContextTemplate{``, nil, nil}, t, nil, true)
|
||||
|
||||
if err != server.ErrDockerfileEmpty {
|
||||
t.Fatal("Expected: %v, got: %v", server.ErrDockerfileEmpty, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOnBuildTrigger(t *testing.T) {
|
||||
_, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
onbuild run echo here is the trigger
|
||||
onbuild run touch foobar
|
||||
`,
|
||||
nil, nil,
|
||||
},
|
||||
t, nil, true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// FIXME: test that the 'foobar' file was created in the final build.
|
||||
}
|
||||
|
||||
func TestBuildOnBuildForbiddenChainedTrigger(t *testing.T) {
|
||||
_, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
onbuild onbuild run echo test
|
||||
`,
|
||||
nil, nil,
|
||||
},
|
||||
t, nil, true,
|
||||
)
|
||||
if err == nil {
|
||||
t.Fatal("Error should not be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOnBuildForbiddenFromTrigger(t *testing.T) {
|
||||
_, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
onbuild from {IMAGE}
|
||||
`,
|
||||
nil, nil,
|
||||
},
|
||||
t, nil, true,
|
||||
)
|
||||
if err == nil {
|
||||
t.Fatal("Error should not be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOnBuildForbiddenMaintainerTrigger(t *testing.T) {
|
||||
_, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
onbuild maintainer test
|
||||
`,
|
||||
nil, nil,
|
||||
},
|
||||
t, nil, true,
|
||||
)
|
||||
if err == nil {
|
||||
t.Fatal("Error should not be nil")
|
||||
}
|
||||
}
|
||||
|
||||
// gh #2446
|
||||
func TestBuildAddToSymlinkDest(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
defer nuke(mkDaemonFromEngine(eng, t))
|
||||
|
||||
_, err := buildImage(testContextTemplate{`
|
||||
from {IMAGE}
|
||||
run mkdir /foo
|
||||
run ln -s /foo /bar
|
||||
add foo /bar/
|
||||
run stat /bar/foo
|
||||
`,
|
||||
[][2]string{{"foo", "HEYO"}}, nil}, t, eng, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user