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