github.com/grahambrereton-form3/tilt@v0.10.18/internal/engine/docker_compose_build_and_deployer_test.go (about)

     1  package engine
     2  
     3  import (
     4  	"archive/tar"
     5  	"context"
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/windmilleng/wmclient/pkg/dirs"
    12  
    13  	"github.com/windmilleng/tilt/internal/container"
    14  	"github.com/windmilleng/tilt/internal/docker"
    15  	"github.com/windmilleng/tilt/internal/dockercompose"
    16  	"github.com/windmilleng/tilt/internal/store"
    17  	"github.com/windmilleng/tilt/internal/testutils"
    18  	"github.com/windmilleng/tilt/internal/testutils/manifestbuilder"
    19  	"github.com/windmilleng/tilt/internal/testutils/tempdir"
    20  	"github.com/windmilleng/tilt/pkg/model"
    21  )
    22  
    23  func TestDockerComposeTargetBuilt(t *testing.T) {
    24  	f := newDCBDFixture(t)
    25  	defer f.TearDown()
    26  
    27  	expectedContainerID := "fake-container-id"
    28  	f.dcCli.ContainerIdOutput = container.ID(expectedContainerID)
    29  
    30  	manifest := manifestbuilder.New(f, "fe").WithDockerCompose().Build()
    31  	dcTarg := manifest.DockerComposeTarget()
    32  
    33  	res, err := f.dcbad.BuildAndDeploy(f.ctx, f.st, buildTargets(manifest), store.BuildStateSet{})
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	if assert.Len(t, f.dcCli.UpCalls, 1, "expect one call to `docker-compose up`") {
    38  		call := f.dcCli.UpCalls[0]
    39  		assert.Equal(t, dcTarg.ConfigPaths, call.PathToConfig)
    40  		assert.Equal(t, "fe", call.ServiceName.String())
    41  		assert.True(t, call.ShouldBuild)
    42  	}
    43  
    44  	dRes := res[dcTarg.ID()].(store.DockerComposeBuildResult)
    45  	assert.Equal(t, expectedContainerID, dRes.DockerComposeContainerID.String())
    46  }
    47  
    48  func TestTiltBuildsImage(t *testing.T) {
    49  	f := newDCBDFixture(t)
    50  	defer f.TearDown()
    51  
    52  	iTarget := NewSanchoDockerBuildImageTarget(f)
    53  	manifest := manifestbuilder.New(f, "fe").
    54  		WithDockerCompose().
    55  		WithImageTarget(iTarget).
    56  		Build()
    57  	dcTarg := manifest.DockerComposeTarget()
    58  
    59  	res, err := f.dcbad.BuildAndDeploy(f.ctx, f.st, buildTargets(manifest), store.BuildStateSet{})
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  
    64  	assert.Equal(t, 1, f.dCli.BuildCount, "expect one docker build")
    65  
    66  	expectedTag := fmt.Sprintf("%s:%s", iTarget.DeploymentRef, docker.TagLatest)
    67  	assert.Equal(t, expectedTag, f.dCli.TagTarget)
    68  
    69  	if assert.Len(t, f.dcCli.UpCalls, 1, "expect one call to `docker-compose up`") {
    70  		call := f.dcCli.UpCalls[0]
    71  		assert.Equal(t, dcTarg.ConfigPaths, call.PathToConfig)
    72  		assert.Equal(t, "fe", call.ServiceName.String())
    73  		assert.False(t, call.ShouldBuild, "should call `up` without `--build` b/c Tilt is doing the building")
    74  	}
    75  
    76  	assert.Len(t, res, 2, "expect two results (one for each spec)")
    77  }
    78  
    79  func TestTiltBuildsImageWithTag(t *testing.T) {
    80  	f := newDCBDFixture(t)
    81  	defer f.TearDown()
    82  
    83  	refWithTag := "gcr.io/foo:bar"
    84  	iTarget := model.NewImageTarget(container.MustParseSelector(refWithTag)).
    85  		WithBuildDetails(model.DockerBuild{})
    86  	manifest := manifestbuilder.New(f, "fe").
    87  		WithDockerCompose().
    88  		WithImageTarget(iTarget).
    89  		Build()
    90  
    91  	_, err := f.dcbad.BuildAndDeploy(f.ctx, f.st, buildTargets(manifest), store.BuildStateSet{})
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  
    96  	assert.Equal(t, refWithTag, f.dCli.TagTarget)
    97  }
    98  
    99  func TestDCBADRejectsAllSpecsIfOneUnsupported(t *testing.T) {
   100  	f := newDCBDFixture(t)
   101  	defer f.TearDown()
   102  
   103  	specs := []model.TargetSpec{model.DockerComposeTarget{}, model.ImageTarget{}, model.K8sTarget{}}
   104  
   105  	iTarg, dcTarg := f.dcbad.extract(specs)
   106  	assert.Empty(t, iTarg)
   107  	assert.Empty(t, dcTarg)
   108  }
   109  
   110  func TestMultiStageDockerCompose(t *testing.T) {
   111  	f := newDCBDFixture(t)
   112  	defer f.TearDown()
   113  
   114  	manifest := NewSanchoDockerBuildMultiStageManifest(f).
   115  		WithDeployTarget(defaultDockerComposeTarget(f, "sancho"))
   116  
   117  	stateSet := store.BuildStateSet{}
   118  	_, err := f.dcbad.BuildAndDeploy(f.ctx, f.st, buildTargets(manifest), stateSet)
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	assert.Equal(t, 2, f.dCli.BuildCount)
   124  	assert.Equal(t, 0, f.dCli.PushCount)
   125  
   126  	expected := expectedFile{
   127  		Path: "Dockerfile",
   128  		Contents: `
   129  FROM sancho-base:latest
   130  ADD . .
   131  RUN go install github.com/windmilleng/sancho
   132  ENTRYPOINT /go/bin/sancho
   133  `,
   134  	}
   135  	testutils.AssertFileInTar(t, tar.NewReader(f.dCli.BuildOptions.Context), expected)
   136  }
   137  
   138  func TestMultiStageDockerComposeWithOnlyOneDirtyImage(t *testing.T) {
   139  	f := newDCBDFixture(t)
   140  	defer f.TearDown()
   141  
   142  	manifest := NewSanchoDockerBuildMultiStageManifest(f).
   143  		WithDeployTarget(defaultDockerComposeTarget(f, "sancho"))
   144  
   145  	iTargetID := manifest.ImageTargets[0].ID()
   146  	result := store.NewImageBuildResult(iTargetID, container.MustParseNamedTagged("sancho-base:tilt-prebuilt"))
   147  	state := store.NewBuildState(result, nil)
   148  	stateSet := store.BuildStateSet{iTargetID: state}
   149  	f.dCli.ImageListCount = 1
   150  	_, err := f.dcbad.BuildAndDeploy(f.ctx, f.st, buildTargets(manifest), stateSet)
   151  	if err != nil {
   152  		t.Fatal(err)
   153  	}
   154  
   155  	assert.Equal(t, 1, f.dCli.BuildCount)
   156  	assert.Equal(t, 0, f.dCli.PushCount)
   157  
   158  	expected := expectedFile{
   159  		Path: "Dockerfile",
   160  		Contents: `
   161  FROM sancho-base:tilt-prebuilt
   162  ADD . .
   163  RUN go install github.com/windmilleng/sancho
   164  ENTRYPOINT /go/bin/sancho
   165  `,
   166  	}
   167  	testutils.AssertFileInTar(t, tar.NewReader(f.dCli.BuildOptions.Context), expected)
   168  }
   169  
   170  type dcbdFixture struct {
   171  	*tempdir.TempDirFixture
   172  	ctx   context.Context
   173  	dcCli *dockercompose.FakeDCClient
   174  	dCli  *docker.FakeClient
   175  	dcbad *DockerComposeBuildAndDeployer
   176  	st    *store.Store
   177  }
   178  
   179  func newDCBDFixture(t *testing.T) *dcbdFixture {
   180  	ctx, _, _ := testutils.CtxAndAnalyticsForTest()
   181  
   182  	f := tempdir.NewTempDirFixture(t)
   183  
   184  	dir := dirs.NewWindmillDirAt(f.Path())
   185  	dcCli := dockercompose.NewFakeDockerComposeClient(t, ctx)
   186  	dCli := docker.NewFakeClient()
   187  	dcbad, err := provideDockerComposeBuildAndDeployer(ctx, dcCli, dCli, dir)
   188  	if err != nil {
   189  		t.Fatal(err)
   190  	}
   191  	st, _ := store.NewStoreForTesting()
   192  	return &dcbdFixture{
   193  		TempDirFixture: f,
   194  		ctx:            ctx,
   195  		dcCli:          dcCli,
   196  		dCli:           dCli,
   197  		dcbad:          dcbad,
   198  		st:             st,
   199  	}
   200  }
   201  
   202  func defaultDockerComposeTarget(f Fixture, name string) model.DockerComposeTarget {
   203  	return model.DockerComposeTarget{
   204  		Name:        model.TargetName(name),
   205  		ConfigPaths: []string{f.JoinPath("docker-compose.yml")},
   206  	}
   207  }