github.com/grahambrereton-form3/tilt@v0.10.18/internal/engine/local_target_build_and_deployer_test.go (about) 1 package engine 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 13 "github.com/windmilleng/tilt/internal/testutils/tempdir" 14 15 "github.com/windmilleng/tilt/internal/store" 16 "github.com/windmilleng/tilt/internal/testutils" 17 "github.com/windmilleng/tilt/pkg/model" 18 ) 19 20 func TestNoLocalTargets(t *testing.T) { 21 f := newLTFixture(t) 22 defer f.TearDown() 23 24 specs := []model.TargetSpec{ 25 model.ImageTarget{}, model.K8sTarget{}, model.DockerComposeTarget{}, 26 } 27 res, err := f.ltbad.BuildAndDeploy(f.ctx, f.st, specs, store.BuildStateSet{}) 28 assert.Empty(t, res, "expect empty result for failed BuildAndDeploy") 29 30 require.NotNil(t, err) 31 assert.Contains(t, err.Error(), 32 "LocalTargetBuildAndDeployer requires exactly one LocalTarget (got 0)") 33 } 34 35 func TestTooManyLocalTargets(t *testing.T) { 36 f := newLTFixture(t) 37 defer f.TearDown() 38 39 specs := []model.TargetSpec{ 40 model.LocalTarget{}, model.ImageTarget{}, model.K8sTarget{}, model.LocalTarget{}, 41 } 42 res, err := f.ltbad.BuildAndDeploy(f.ctx, f.st, specs, store.BuildStateSet{}) 43 assert.Empty(t, res, "expect empty result for failed BuildAndDeploy") 44 45 require.NotNil(t, err) 46 assert.Contains(t, err.Error(), 47 "LocalTargetBuildAndDeployer requires exactly one LocalTarget (got 2)") 48 } 49 50 func TestSuccessfulCommand(t *testing.T) { 51 f := newLTFixture(t) 52 defer f.TearDown() 53 54 targ := f.localTarget("echo hello world") 55 56 res, err := f.ltbad.BuildAndDeploy(f.ctx, f.st, []model.TargetSpec{targ}, store.BuildStateSet{}) 57 require.Nil(t, err) 58 59 assert.Equal(t, targ.ID(), res[targ.ID()].TargetID()) 60 61 assert.Contains(t, f.out.String(), "hello world", "expect cmd stdout in logs") 62 } 63 64 func TestWorkdir(t *testing.T) { 65 f := newLTFixture(t) 66 defer f.TearDown() 67 68 f.MkdirAll("some/internal/dir") 69 workdir := f.JoinPath("some/internal/dir") 70 targ := f.localTargetWithWorkdir("echo the directory is $(pwd)", workdir) 71 72 res, err := f.ltbad.BuildAndDeploy(f.ctx, f.st, []model.TargetSpec{targ}, store.BuildStateSet{}) 73 require.Nil(t, err) 74 75 assert.Equal(t, targ.ID(), res[targ.ID()].TargetID()) 76 77 expectedOut := fmt.Sprintf("the directory is %s", workdir) 78 assert.Contains(t, f.out.String(), expectedOut, "expect cmd stdout (with appropriate pwd) in logs") 79 } 80 81 func TestExtractOneLocalTarget(t *testing.T) { 82 f := newLTFixture(t) 83 defer f.TearDown() 84 85 targ := f.localTarget("echo hello world") 86 87 // Even if there are multiple other targets, should correctly extract and run the one LocalTarget 88 specs := []model.TargetSpec{ 89 targ, model.ImageTarget{}, model.K8sTarget{}, 90 } 91 92 res, err := f.ltbad.BuildAndDeploy(f.ctx, f.st, specs, store.BuildStateSet{}) 93 require.Nil(t, err) 94 95 assert.Equal(t, targ.ID(), res[targ.ID()].TargetID()) 96 97 assert.Contains(t, f.out.String(), "hello world", "expect cmd stdout in logs") 98 } 99 100 func TestFailedCommand(t *testing.T) { 101 f := newLTFixture(t) 102 defer f.TearDown() 103 104 targ := f.localTarget("echo oh no; false") 105 106 res, err := f.ltbad.BuildAndDeploy(f.ctx, f.st, []model.TargetSpec{targ}, store.BuildStateSet{}) 107 assert.Empty(t, res, "expect empty build result for failed cmd") 108 109 require.NotNil(t, err, "failed cmd should throw error") 110 assert.Contains(t, err.Error(), 111 "Command \"echo oh no; false\" failed: exit status 1") 112 assert.True(t, IsDontFallBackError(err), "expect DontFallBackError") 113 114 assert.Contains(t, f.out.String(), "oh no", "expect cmd stdout in logs") 115 } 116 117 type ltFixture struct { 118 *tempdir.TempDirFixture 119 120 ctx context.Context 121 out *bytes.Buffer 122 ltbad *LocalTargetBuildAndDeployer 123 st *store.Store 124 } 125 126 func newLTFixture(t *testing.T) *ltFixture { 127 f := tempdir.NewTempDirFixture(t) 128 129 out := new(bytes.Buffer) 130 ctx, _, _ := testutils.ForkedCtxAndAnalyticsForTest(out) 131 clock := fakeClock{time.Date(2019, 1, 1, 1, 1, 1, 1, time.UTC)} 132 133 ltbad := NewLocalTargetBuildAndDeployer(clock) 134 st, _ := store.NewStoreForTesting() 135 return <Fixture{ 136 TempDirFixture: f, 137 ctx: ctx, 138 out: out, 139 ltbad: ltbad, 140 st: st, 141 } 142 } 143 144 func (f *ltFixture) localTarget(cmd string) model.LocalTarget { 145 return f.localTargetWithWorkdir(cmd, f.Path()) 146 } 147 148 func (f *ltFixture) localTargetWithWorkdir(cmd string, workdir string) model.LocalTarget { 149 return model.LocalTarget{ 150 Cmd: model.ToShellCmd(cmd), 151 Workdir: workdir, 152 } 153 }