github.com/bdwilliams/libcompose@v0.3.1-0.20160826154243-d81a9bdacff0/docker/builder/builder_test.go (about)

     1  package builder
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"testing"
    12  
    13  	"golang.org/x/net/context"
    14  
    15  	"github.com/docker/docker/pkg/archive"
    16  	"github.com/docker/docker/pkg/jsonmessage"
    17  	"github.com/docker/engine-api/types"
    18  	"github.com/docker/libcompose/test"
    19  )
    20  
    21  type DaemonClient struct {
    22  	test.NopClient
    23  	contextDir string
    24  	imageName  string
    25  	changes    int
    26  	message    jsonmessage.JSONMessage
    27  }
    28  
    29  func (c *DaemonClient) ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
    30  	if c.imageName != "" {
    31  		if len(options.Tags) != 1 || options.Tags[0] != c.imageName {
    32  			return types.ImageBuildResponse{}, fmt.Errorf("expected image %q, got %v", c.imageName, options.Tags)
    33  		}
    34  	}
    35  	if c.contextDir != "" {
    36  		tmp, err := ioutil.TempDir("", "image-build-test")
    37  		if err != nil {
    38  			return types.ImageBuildResponse{}, err
    39  		}
    40  		if err := archive.Untar(context, tmp, nil); err != nil {
    41  			return types.ImageBuildResponse{}, err
    42  		}
    43  		changes, err := archive.ChangesDirs(tmp, c.contextDir)
    44  		if err != nil {
    45  			return types.ImageBuildResponse{}, err
    46  		}
    47  		if len(changes) != c.changes {
    48  			return types.ImageBuildResponse{}, fmt.Errorf("expected %d changes, got %v", c.changes, changes)
    49  		}
    50  		b, err := json.Marshal(c.message)
    51  		if err != nil {
    52  			return types.ImageBuildResponse{}, err
    53  		}
    54  		return types.ImageBuildResponse{
    55  			Body: ioutil.NopCloser(bytes.NewReader(b)),
    56  		}, nil
    57  	}
    58  	return c.NopClient.ImageBuild(ctx, context, options)
    59  }
    60  
    61  func TestBuildInvalidContextDirectoryOrDockerfile(t *testing.T) {
    62  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
    63  	if err != nil {
    64  		t.Fatal(err)
    65  	}
    66  	testCases := []struct {
    67  		contextDirectory string
    68  		dockerfile       string
    69  		expected         string
    70  	}{
    71  		{
    72  			contextDirectory: "",
    73  			dockerfile:       "",
    74  			expected:         "Cannot locate Dockerfile: Dockerfile",
    75  		},
    76  		{
    77  			contextDirectory: "",
    78  			dockerfile:       "test.Dockerfile",
    79  			expected:         "Cannot locate Dockerfile: test.Dockerfile",
    80  		},
    81  		{
    82  			contextDirectory: "/I/DONT/EXISTS",
    83  			dockerfile:       "",
    84  			expected:         "Cannot locate Dockerfile: Dockerfile",
    85  		},
    86  		{
    87  			contextDirectory: "/I/DONT/EXISTS",
    88  			dockerfile:       "test.Dockerfile",
    89  			expected:         "Cannot locate Dockerfile: /I/DONT/EXISTS/test.Dockerfile",
    90  		},
    91  		{
    92  			contextDirectory: tmpDir,
    93  			dockerfile:       "test.Dockerfile",
    94  			expected:         "Cannot locate Dockerfile: " + filepath.Join(tmpDir, "test.Dockerfile"),
    95  		},
    96  	}
    97  	for _, c := range testCases {
    98  		builder := &DaemonBuilder{
    99  			ContextDirectory: c.contextDirectory,
   100  			Dockerfile:       c.dockerfile,
   101  		}
   102  		err := builder.Build(context.Background(), "image")
   103  		if err == nil || err.Error() != c.expected {
   104  			t.Fatalf("expected an error %q, got %s", c.expected, err)
   105  		}
   106  
   107  	}
   108  }
   109  
   110  func TestBuildWithClientBuildError(t *testing.T) {
   111  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   112  	if err != nil {
   113  		t.Fatal(err)
   114  	}
   115  	defer os.RemoveAll(tmpDir)
   116  	if err := ioutil.WriteFile(filepath.Join(tmpDir, DefaultDockerfileName), []byte("FROM busybox"), 0700); err != nil {
   117  		t.Fatal(err)
   118  	}
   119  
   120  	imageName := "image"
   121  	client := &DaemonClient{}
   122  	builder := &DaemonBuilder{
   123  		ContextDirectory: tmpDir,
   124  		Client:           client,
   125  	}
   126  
   127  	err = builder.Build(context.Background(), imageName)
   128  	if err == nil || err.Error() != "Engine no longer exists" {
   129  		t.Fatalf("expected an 'Engine no longer exists', got %s", err)
   130  	}
   131  }
   132  
   133  func TestBuildWithDefaultDockerfile(t *testing.T) {
   134  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   135  	if err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	defer os.RemoveAll(tmpDir)
   139  	if err := ioutil.WriteFile(filepath.Join(tmpDir, DefaultDockerfileName), []byte("FROM busybox"), 0700); err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil {
   143  		t.Fatal(err)
   144  	}
   145  
   146  	imageName := "image"
   147  	client := &DaemonClient{
   148  		contextDir: tmpDir,
   149  		imageName:  imageName,
   150  	}
   151  	builder := &DaemonBuilder{
   152  		ContextDirectory: tmpDir,
   153  		Client:           client,
   154  	}
   155  
   156  	err = builder.Build(context.Background(), imageName)
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  }
   161  
   162  func TestBuildWithDefaultLowercaseDockerfile(t *testing.T) {
   163  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	defer os.RemoveAll(tmpDir)
   168  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "dockerfile"), []byte("FROM busybox"), 0700); err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil {
   172  		t.Fatal(err)
   173  	}
   174  
   175  	imageName := "image"
   176  	client := &DaemonClient{
   177  		contextDir: tmpDir,
   178  		imageName:  imageName,
   179  	}
   180  	builder := &DaemonBuilder{
   181  		ContextDirectory: tmpDir,
   182  		Client:           client,
   183  	}
   184  
   185  	err = builder.Build(context.Background(), imageName)
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  }
   190  
   191  func TestBuildWithSpecificDockerfile(t *testing.T) {
   192  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   193  	if err != nil {
   194  		t.Fatal(err)
   195  	}
   196  	defer os.RemoveAll(tmpDir)
   197  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil {
   198  		t.Fatal(err)
   199  	}
   200  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil {
   201  		t.Fatal(err)
   202  	}
   203  
   204  	imageName := "image"
   205  	client := &DaemonClient{
   206  		contextDir: tmpDir,
   207  		imageName:  imageName,
   208  	}
   209  	builder := &DaemonBuilder{
   210  		ContextDirectory: tmpDir,
   211  		Dockerfile:       "test.Dockerfile",
   212  		Client:           client,
   213  	}
   214  
   215  	err = builder.Build(context.Background(), imageName)
   216  	if err != nil {
   217  		t.Fatal(err)
   218  	}
   219  }
   220  
   221  func TestBuildWithDockerignoreNothing(t *testing.T) {
   222  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   223  	if err != nil {
   224  		t.Fatal(err)
   225  	}
   226  	defer os.RemoveAll(tmpDir)
   227  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil {
   228  		t.Fatal(err)
   229  	}
   230  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil {
   231  		t.Fatal(err)
   232  	}
   233  	if err := ioutil.WriteFile(filepath.Join(tmpDir, ".dockerignore"), []byte(""), 0700); err != nil {
   234  		t.Fatal(err)
   235  	}
   236  
   237  	imageName := "image"
   238  	client := &DaemonClient{
   239  		contextDir: tmpDir,
   240  		imageName:  imageName,
   241  	}
   242  	builder := &DaemonBuilder{
   243  		ContextDirectory: tmpDir,
   244  		Dockerfile:       "test.Dockerfile",
   245  		Client:           client,
   246  	}
   247  
   248  	err = builder.Build(context.Background(), imageName)
   249  	if err != nil {
   250  		t.Fatal(err)
   251  	}
   252  }
   253  
   254  func TestBuildWithDockerignoreDockerfileAndItself(t *testing.T) {
   255  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   256  	if err != nil {
   257  		t.Fatal(err)
   258  	}
   259  	defer os.RemoveAll(tmpDir)
   260  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil {
   261  		t.Fatal(err)
   262  	}
   263  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil {
   264  		t.Fatal(err)
   265  	}
   266  	if err := ioutil.WriteFile(filepath.Join(tmpDir, ".dockerignore"), []byte("Dockerfile\n.dockerignore"), 0700); err != nil {
   267  		t.Fatal(err)
   268  	}
   269  
   270  	imageName := "image"
   271  	client := &DaemonClient{
   272  		contextDir: tmpDir,
   273  		imageName:  imageName,
   274  	}
   275  	builder := &DaemonBuilder{
   276  		ContextDirectory: tmpDir,
   277  		Dockerfile:       "test.Dockerfile",
   278  		Client:           client,
   279  	}
   280  
   281  	err = builder.Build(context.Background(), imageName)
   282  	if err != nil {
   283  		t.Fatal(err)
   284  	}
   285  }
   286  
   287  func TestBuildWithDockerignoreAfile(t *testing.T) {
   288  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   289  	if err != nil {
   290  		t.Fatal(err)
   291  	}
   292  	defer os.RemoveAll(tmpDir)
   293  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil {
   294  		t.Fatal(err)
   295  	}
   296  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil {
   297  		t.Fatal(err)
   298  	}
   299  	if err := ioutil.WriteFile(filepath.Join(tmpDir, ".dockerignore"), []byte("afile"), 0700); err != nil {
   300  		t.Fatal(err)
   301  	}
   302  
   303  	imageName := "image"
   304  	client := &DaemonClient{
   305  		contextDir: tmpDir,
   306  		imageName:  imageName,
   307  		changes:    1,
   308  	}
   309  	builder := &DaemonBuilder{
   310  		ContextDirectory: tmpDir,
   311  		Dockerfile:       "test.Dockerfile",
   312  		Client:           client,
   313  	}
   314  
   315  	err = builder.Build(context.Background(), imageName)
   316  	if err != nil {
   317  		t.Fatal(err)
   318  	}
   319  }
   320  
   321  func TestBuildWithErrorJSONMessage(t *testing.T) {
   322  	tmpDir, err := ioutil.TempDir("", "daemonbuilder-test")
   323  	if err != nil {
   324  		t.Fatal(err)
   325  	}
   326  	defer os.RemoveAll(tmpDir)
   327  	if err := ioutil.WriteFile(filepath.Join(tmpDir, DefaultDockerfileName), []byte("FROM busybox"), 0700); err != nil {
   328  		t.Fatal(err)
   329  	}
   330  	if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil {
   331  		t.Fatal(err)
   332  	}
   333  
   334  	imageName := "image"
   335  	client := &DaemonClient{
   336  		contextDir: tmpDir,
   337  		imageName:  imageName,
   338  		message: jsonmessage.JSONMessage{
   339  			Error: &jsonmessage.JSONError{
   340  				Code:    0,
   341  				Message: "error",
   342  			},
   343  		},
   344  	}
   345  	builder := &DaemonBuilder{
   346  		ContextDirectory: tmpDir,
   347  		Client:           client,
   348  	}
   349  
   350  	err = builder.Build(context.Background(), imageName)
   351  	expectedError := "Status: error, Code: 1"
   352  	if err == nil || err.Error() != expectedError {
   353  		t.Fatalf("expected an error about %q, got %s", expectedError, err)
   354  	}
   355  }