github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/docker_compose_test.go (about) 1 package tiltfile 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 9 "github.com/tilt-dev/tilt/internal/dockercompose" 10 "github.com/tilt-dev/tilt/internal/testutils" 11 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 12 ) 13 14 // ParseConfig must return services topologically sorted wrt dependencies. 15 16 func TestParseConfigPreservesServiceOrder(t *testing.T) { 17 f := newDCFixture(t) 18 19 var output = `version: '3' 20 services: 21 a: 22 image: imga 23 depends_on: [b] 24 b: 25 image: imgb 26 depends_on: [c] 27 c: 28 image: imgc 29 depends_on: [d, e, f] 30 d: 31 image: imgd 32 depends_on: [f, e] 33 e: 34 image: imge 35 depends_on: [f] 36 f: 37 image: imgf 38 ` 39 40 services := f.parse(output) 41 if assert.Len(t, services, 6) { 42 serviceOrder := []string{"f", "e", "d", "c", "b", "a"} 43 for i, name := range serviceOrder { 44 assert.Equal(t, name, services[i].Name) 45 } 46 depOrder := [][]string{ 47 []string{}, 48 []string{"f"}, 49 []string{"e", "f"}, 50 []string{"d", "e", "f"}, 51 []string{"c"}, 52 []string{"b"}, 53 } 54 for i, deps := range depOrder { 55 assert.Equal(t, deps, services[i].Options.resourceDeps) 56 } 57 } 58 } 59 60 func TestPortStruct(t *testing.T) { 61 f := newDCFixture(t) 62 63 output := `services: 64 app: 65 command: sh -c 'node server.js' 66 image: tilt.dev/express-redis-app 67 ports: 68 - published: 3000 69 target: 30 70 version: '3.2' 71 ` 72 services := f.parse(output) 73 if assert.Len(t, services, 1) { 74 assert.Equal(t, []int{3000}, services[0].PublishedPorts) 75 } 76 77 } 78 79 func TestPortMapRandomized(t *testing.T) { 80 f := newDCFixture(t) 81 82 output := `services: 83 app: 84 command: sh -c 'node server.js' 85 image: tilt.dev/express-redis-app 86 ports: 87 - 3000/tcp 88 version: '3.0' 89 ` 90 services := f.parse(output) 91 if assert.Len(t, services, 1) { 92 assert.Empty(t, services[0].PublishedPorts) 93 } 94 } 95 96 func TestPortMapDifferent(t *testing.T) { 97 f := newDCFixture(t) 98 99 output := `services: 100 app: 101 command: sh -c 'node server.js' 102 image: tilt.dev/express-redis-app 103 ports: 104 - 3000:30/tcp 105 version: '3.0' 106 ` 107 108 services := f.parse(output) 109 if assert.Len(t, services, 1) { 110 assert.Equal(t, []int{3000}, services[0].PublishedPorts) 111 } 112 } 113 114 func TestPortMapIP(t *testing.T) { 115 f := newDCFixture(t) 116 117 output := `services: 118 app: 119 command: sh -c 'node server.js' 120 image: tilt.dev/express-redis-app 121 ports: 122 - 127.0.0.1:3000:30/tcp 123 version: '3.0' 124 ` 125 126 services := f.parse(output) 127 if assert.Len(t, services, 1) { 128 assert.Equal(t, []int{3000}, services[0].PublishedPorts) 129 } 130 } 131 132 func TestMarshalOverflow(t *testing.T) { 133 f := newDCFixture(t) 134 135 // certain Compose types cause a stack overflow panic if marshaled with gopkg.in/yaml.v3 136 // https://github.com/tilt-dev/tilt/issues/4797 137 output := `services: 138 foo: 139 image: myimage 140 ulimits: 141 nproc: 65535 142 nofile: 143 soft: 20000 144 hard: 40000 145 ` 146 147 services := f.parse(output) 148 assert.NotEmpty(t, services) 149 } 150 151 type dcFixture struct { 152 t *testing.T 153 ctx context.Context 154 dcCli *dockercompose.FakeDCClient 155 } 156 157 func newDCFixture(t *testing.T) dcFixture { 158 ctx, _, _ := testutils.CtxAndAnalyticsForTest() 159 dcCli := dockercompose.NewFakeDockerComposeClient(t, ctx) 160 return dcFixture{ 161 t: t, 162 ctx: ctx, 163 dcCli: dcCli, 164 } 165 } 166 167 func (f dcFixture) parse(configOutput string) []*dcService { 168 f.t.Helper() 169 170 f.dcCli.ConfigOutput = configOutput 171 172 dc := &dcResourceSet{ 173 Project: v1alpha1.DockerComposeProject{ConfigPaths: []string{"doesn't-matter.yml"}}, 174 services: make(map[string]*dcService), 175 resOptions: make(map[string]*dcResourceOptions), 176 } 177 178 services, err := parseDCConfig(f.ctx, f.dcCli, dc) 179 if err != nil { 180 f.t.Fatalf("dcFixture.Parse: %v", err) 181 } 182 return services 183 }