Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frontend: add some dockerfile integration tests #183

Merged
merged 4 commits into from
Dec 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions cmd/buildctl/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/containerd/containerd"
"github.com/containerd/containerd/fs/fstest"
"github.com/containerd/containerd/namespaces"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/util/testutil/integration"
"github.com/stretchr/testify/require"
)

func testBuildWithLocalFiles(t *testing.T, sb integration.Sandbox) {
t.Parallel()
dir, err := tmpdir(
fstest.CreateFile("foo", []byte("bar"), 0600),
)
require.NoError(t, err)
defer os.RemoveAll(dir)

st := llb.Image("busybox").
Run(llb.Shlex("sh -c 'echo -n bar > foo2'")).
Run(llb.Shlex("cmp -s /mnt/foo foo2"))

st.AddMount("/mnt", llb.Local("src"), llb.Readonly)

rdr, err := marshal(st.Root())
require.NoError(t, err)

cmd := sb.Cmd(fmt.Sprintf("build --no-progress --local src=%s", dir))
cmd.Stdin = rdr

err = cmd.Run()
require.NoError(t, err)
}

func testBuildLocalExporter(t *testing.T, sb integration.Sandbox) {
t.Parallel()
st := llb.Image("busybox").
Run(llb.Shlex("sh -c 'echo -n bar > /out/foo'"))

out := st.AddMount("/out", llb.Scratch())

rdr, err := marshal(out)
require.NoError(t, err)

tmpdir, err := ioutil.TempDir("", "buildkit-buildctl")
require.NoError(t, err)
defer os.RemoveAll(tmpdir)

cmd := sb.Cmd(fmt.Sprintf("build --no-progress --exporter=local --exporter-opt output=%s", tmpdir))
cmd.Stdin = rdr
err = cmd.Run()

require.NoError(t, err)

dt, err := ioutil.ReadFile(filepath.Join(tmpdir, "foo"))
require.NoError(t, err)
require.Equal(t, string(dt), "bar")
}

func testBuildContainerdExporter(t *testing.T, sb integration.Sandbox) {
t.Parallel()

var cdAddress string
if cd, ok := sb.(interface {
ContainerdAddress() string
}); !ok {
t.Skip("only for containerd worker")
} else {
cdAddress = cd.ContainerdAddress()
}

st := llb.Image("busybox").
Run(llb.Shlex("sh -c 'echo -n bar > /foo'"))

rdr, err := marshal(st.Root())
require.NoError(t, err)

cmd := sb.Cmd("build --no-progress --exporter=image --exporter-opt name=example.com/moby/imageexporter:test")
cmd.Stdin = rdr
err = cmd.Run()
require.NoError(t, err)

client, err := containerd.New(cdAddress)
require.NoError(t, err)
defer client.Close()

ctx := namespaces.WithNamespace(context.Background(), "buildkit")

_, err = client.ImageService().Get(ctx, "example.com/moby/imageexporter:test")
require.NoError(t, err)
}

func marshal(st llb.State) (io.Reader, error) {
def, err := st.Marshal()
if err != nil {
return nil, err
}
dt, err := def.ToPB().Marshal()
if err != nil {
return nil, err
}
return bytes.NewBuffer(dt), nil
}

func tmpdir(appliers ...fstest.Applier) (string, error) {
tmpdir, err := ioutil.TempDir("", "buildkit-buildctl")
if err != nil {
return "", err
}
if err := fstest.Apply(appliers...).Apply(tmpdir); err != nil {
return "", err
}
return tmpdir, nil
}
3 changes: 3 additions & 0 deletions cmd/buildctl/buildctl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ import (
func TestCLIIntegration(t *testing.T) {
integration.Run(t, []integration.Test{
testDiskUsage,
testBuildWithLocalFiles,
testBuildLocalExporter,
testBuildContainerdExporter,
})
}
129 changes: 129 additions & 0 deletions frontend/dockerfile/dockerfile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package dockerfile

import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/containerd/containerd/fs/fstest"
"github.com/moby/buildkit/identity"
"github.com/moby/buildkit/util/testutil/integration"
"github.com/stretchr/testify/require"
)

func TestIntegration(t *testing.T) {
integration.Run(t, []integration.Test{
testDockerfileDirs,
testDockerfileInvalidCommand,
})
}

func testDockerfileDirs(t *testing.T, sb integration.Sandbox) {
t.Parallel()
dockerfile := []byte(`
FROM busybox
COPY foo /foo2
COPY foo /
RUN echo -n bar > foo3
RUN test -f foo
RUN cmp -s foo foo2
RUN cmp -s foo foo3
`)

dir, err := tmpdir(
fstest.CreateFile("Dockerfile", dockerfile, 0600),
fstest.CreateFile("foo", []byte("bar"), 0600),
)
require.NoError(t, err)
defer os.RemoveAll(dir)

args, trace := dfCmdArgs(dir, dir)
defer os.RemoveAll(trace)

cmd := sb.Cmd(args)
require.NoError(t, cmd.Run())

_, err = os.Stat(trace)
require.NoError(t, err)

// relative urls
args, trace = dfCmdArgs(".", ".")
defer os.RemoveAll(trace)

cmd = sb.Cmd(args)
cmd.Dir = dir
require.NoError(t, cmd.Run())

_, err = os.Stat(trace)
require.NoError(t, err)

// different context and dockerfile directories
dir1, err := tmpdir(
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)
require.NoError(t, err)
defer os.RemoveAll(dir1)

dir2, err := tmpdir(
fstest.CreateFile("foo", []byte("bar"), 0600),
)
require.NoError(t, err)
defer os.RemoveAll(dir2)

args, trace = dfCmdArgs(dir2, dir1)
defer os.RemoveAll(trace)

cmd = sb.Cmd(args)
cmd.Dir = dir
require.NoError(t, cmd.Run())

_, err = os.Stat(trace)
require.NoError(t, err)

// TODO: test trace file output, cache hits, logs etc.
// TODO: output metadata about original dockerfile command in trace
}

func testDockerfileInvalidCommand(t *testing.T, sb integration.Sandbox) {
t.Parallel()
dockerfile := []byte(`
FROM busybox
RUN invalidcmd
`)

dir, err := tmpdir(
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)
require.NoError(t, err)
defer os.RemoveAll(dir)

args, trace := dfCmdArgs(dir, dir)
defer os.RemoveAll(trace)

cmd := sb.Cmd(args)
stdout := new(bytes.Buffer)
cmd.Stderr = stdout
err = cmd.Run()
require.Error(t, err)
require.Contains(t, stdout.String(), "/bin/sh -c invalidcmd")
require.Contains(t, stdout.String(), "worker failed running")
}

func tmpdir(appliers ...fstest.Applier) (string, error) {
tmpdir, err := ioutil.TempDir("", "buildkit-dockerfile")
if err != nil {
return "", err
}
if err := fstest.Apply(appliers...).Apply(tmpdir); err != nil {
return "", err
}
return tmpdir, nil
}

func dfCmdArgs(ctx, dockerfile string) (string, string) {
traceFile := filepath.Join(os.TempDir(), "trace"+identity.NewID())
return fmt.Sprintf("build --no-progress --frontend dockerfile.v0 --local context=%s --local dockerfile=%s --trace=%s", ctx, dockerfile, traceFile), traceFile
}
11 changes: 10 additions & 1 deletion util/testutil/integration/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,14 @@ func (c *containerd) New() (sb Sandbox, cl func() error, err error) {
}
deferF.append(stop)

return &sandbox{address: builddSock, logs: logs}, cl, nil
return &cdsandbox{address: address, sandbox: sandbox{address: builddSock, logs: logs}}, cl, nil
}

type cdsandbox struct {
sandbox
address string
}

func (s *cdsandbox) ContainerdAddress() string {
return s.address
}
7 changes: 7 additions & 0 deletions util/testutil/integration/standalone.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"runtime"
"testing"
"time"

"github.com/google/shlex"
)

func init() {
Expand Down Expand Up @@ -59,6 +61,11 @@ func (sb *sandbox) PrintLogs(t *testing.T) {
}

func (sb *sandbox) Cmd(args ...string) *exec.Cmd {
if len(args) == 1 {
if split, err := shlex.Split(args[0]); err == nil {
args = split
}
}
cmd := exec.Command("buildctl", args...)
cmd.Env = append(cmd.Env, os.Environ()...)
cmd.Env = append(cmd.Env, "BUILDKIT_HOST="+sb.Address())
Expand Down
53 changes: 53 additions & 0 deletions vendor/github.com/containerd/containerd/fs/fstest/compare.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading