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