dotcloud/docker

View on GitHub
testutil/fakecontext/context.go

Summary

Maintainability
A
0 mins
Test Coverage
package fakecontext // import "github.com/docker/docker/testutil/fakecontext"

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

    "github.com/docker/docker/pkg/archive"
)

// New creates a fake build context
func New(t testing.TB, dir string, modifiers ...func(*Fake) error) *Fake {
    t.Helper()
    fakeContext := &Fake{Dir: dir}
    if dir == "" {
        if err := newDir(fakeContext); err != nil {
            t.Fatal(err)
        }
    }

    for _, modifier := range modifiers {
        if err := modifier(fakeContext); err != nil {
            t.Fatal(err)
        }
    }

    return fakeContext
}

func newDir(fake *Fake) error {
    tmp, err := os.MkdirTemp("", "fake-context")
    if err != nil {
        return err
    }
    if err := os.Chmod(tmp, 0o755); err != nil {
        return err
    }
    fake.Dir = tmp
    return nil
}

// WithFile adds the specified file (with content) in the build context
func WithFile(name, content string) func(*Fake) error {
    return func(ctx *Fake) error {
        return ctx.Add(name, content)
    }
}

// WithDockerfile adds the specified content as Dockerfile in the build context
func WithDockerfile(content string) func(*Fake) error {
    return WithFile("Dockerfile", content)
}

// WithFiles adds the specified files in the build context, content is a string
func WithFiles(files map[string]string) func(*Fake) error {
    return func(fakeContext *Fake) error {
        for file, content := range files {
            if err := fakeContext.Add(file, content); err != nil {
                return err
            }
        }
        return nil
    }
}

// WithBinaryFiles adds the specified files in the build context, content is binary
func WithBinaryFiles(files map[string]*bytes.Buffer) func(*Fake) error {
    return func(fakeContext *Fake) error {
        for file, content := range files {
            if err := fakeContext.Add(file, content.String()); err != nil {
                return err
            }
        }
        return nil
    }
}

// Fake creates directories that can be used as a build context
type Fake struct {
    Dir string
}

// Add a file at a path, creating directories where necessary
func (f *Fake) Add(file, content string) error {
    return f.addFile(file, []byte(content))
}

func (f *Fake) addFile(file string, content []byte) error {
    fp := filepath.Join(f.Dir, filepath.FromSlash(file))
    dirpath := filepath.Dir(fp)
    if dirpath != "." {
        if err := os.MkdirAll(dirpath, 0o755); err != nil {
            return err
        }
    }
    return os.WriteFile(fp, content, 0o644)
}

// Delete a file at a path
func (f *Fake) Delete(file string) error {
    fp := filepath.Join(f.Dir, filepath.FromSlash(file))
    return os.RemoveAll(fp)
}

// Close deletes the context
func (f *Fake) Close() error {
    return os.RemoveAll(f.Dir)
}

// AsTarReader returns a ReadCloser with the contents of Dir as a tar archive.
func (f *Fake) AsTarReader(t testing.TB) io.ReadCloser {
    t.Helper()
    reader, err := archive.TarWithOptions(f.Dir, &archive.TarOptions{})
    if err != nil {
        t.Fatalf("Failed to create tar from %s: %s", f.Dir, err)
    }
    return reader
}