github.com/cpuid/libcompose@v0.4.0/integration/create_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "strings" 8 9 "path/filepath" 10 11 . "gopkg.in/check.v1" 12 ) 13 14 func (s *CliSuite) TestFields(c *C) { 15 p := s.CreateProjectFromText(c, ` 16 hello: 17 image: tianon/true 18 cpuset: 0,1 19 mem_limit: 4194304 20 `) 21 22 name := fmt.Sprintf("%s_%s_1", p, "hello") 23 cn := s.GetContainerByName(c, name) 24 c.Assert(cn, NotNil) 25 26 c.Assert(cn.Config.Image, Equals, "tianon/true") 27 c.Assert(cn.HostConfig.CpusetCpus, Equals, "0,1") 28 c.Assert(cn.HostConfig.Memory, Equals, int64(4194304)) 29 } 30 31 func (s *CliSuite) TestEmptyEntrypoint(c *C) { 32 p := s.CreateProjectFromText(c, ` 33 nil-cmd: 34 image: busybox 35 entrypoint: [] 36 `) 37 38 name := fmt.Sprintf("%s_%s_1", p, "nil-cmd") 39 cn := s.GetContainerByName(c, name) 40 c.Assert(cn, NotNil) 41 42 c.Assert(cn.Config.Entrypoint, IsNil) 43 } 44 45 func (s *CliSuite) TestHelloWorld(c *C) { 46 p := s.CreateProjectFromText(c, ` 47 hello: 48 image: tianon/true 49 `) 50 51 name := fmt.Sprintf("%s_%s_1", p, "hello") 52 cn := s.GetContainerByName(c, name) 53 c.Assert(cn, NotNil) 54 55 c.Assert(cn.Name, Equals, "/"+name) 56 } 57 58 func (s *CliSuite) TestContainerName(c *C) { 59 containerName := "containerName" 60 template := fmt.Sprintf(`hello: 61 image: busybox 62 command: top 63 container_name: %s`, containerName) 64 s.CreateProjectFromText(c, template) 65 66 cn := s.GetContainerByName(c, containerName) 67 c.Assert(cn, NotNil) 68 69 c.Assert(cn.Name, Equals, "/"+containerName) 70 } 71 72 func (s *CliSuite) TestContainerNameWithScale(c *C) { 73 containerName := "containerName" 74 template := fmt.Sprintf(`hello: 75 image: busybox 76 command: top 77 container_name: %s`, containerName) 78 p := s.CreateProjectFromText(c, template) 79 80 s.FromText(c, p, "scale", "hello=2", template) 81 containers := s.GetContainersByProject(c, p) 82 c.Assert(len(containers), Equals, 1) 83 84 } 85 86 func (s *CliSuite) TestInterpolation(c *C) { 87 os.Setenv("IMAGE", "tianon/true") 88 89 p := s.CreateProjectFromText(c, ` 90 test: 91 image: $IMAGE 92 `) 93 94 name := fmt.Sprintf("%s_%s_1", p, "test") 95 testContainer := s.GetContainerByName(c, name) 96 97 p = s.CreateProjectFromText(c, ` 98 reference: 99 image: tianon/true 100 `) 101 102 name = fmt.Sprintf("%s_%s_1", p, "reference") 103 referenceContainer := s.GetContainerByName(c, name) 104 105 c.Assert(testContainer, NotNil) 106 107 c.Assert(referenceContainer.Image, Equals, testContainer.Image) 108 109 os.Unsetenv("IMAGE") 110 } 111 112 func (s *CliSuite) TestInterpolationWithExtends(c *C) { 113 os.Setenv("IMAGE", "tianon/true") 114 os.Setenv("TEST_PORT", "8000") 115 116 p := s.CreateProjectFromText(c, ` 117 test: 118 extends: 119 file: ./assets/interpolation/docker-compose.yml 120 service: base 121 ports: 122 - ${TEST_PORT} 123 `) 124 125 name := fmt.Sprintf("%s_%s_1", p, "test") 126 testContainer := s.GetContainerByName(c, name) 127 128 p = s.CreateProjectFromText(c, ` 129 reference: 130 image: tianon/true 131 ports: 132 - 8000 133 `) 134 135 name = fmt.Sprintf("%s_%s_1", p, "reference") 136 referenceContainer := s.GetContainerByName(c, name) 137 138 c.Assert(testContainer, NotNil) 139 140 c.Assert(referenceContainer.Image, Equals, testContainer.Image) 141 142 os.Unsetenv("TEST_PORT") 143 os.Unsetenv("IMAGE") 144 } 145 146 func (s *CliSuite) TestFieldTypeConversions(c *C) { 147 os.Setenv("LIMIT", "40000000") 148 149 p := s.CreateProjectFromText(c, ` 150 test: 151 image: tianon/true 152 mem_limit: $LIMIT 153 memswap_limit: "40000000" 154 `) 155 156 name := fmt.Sprintf("%s_%s_1", p, "test") 157 testContainer := s.GetContainerByName(c, name) 158 159 p = s.CreateProjectFromText(c, ` 160 reference: 161 image: tianon/true 162 mem_limit: 40000000 163 memswap_limit: 40000000 164 `) 165 166 name = fmt.Sprintf("%s_%s_1", p, "reference") 167 referenceContainer := s.GetContainerByName(c, name) 168 169 c.Assert(testContainer, NotNil) 170 171 c.Assert(referenceContainer.Image, Equals, testContainer.Image) 172 173 os.Unsetenv("LIMIT") 174 } 175 176 func (s *CliSuite) TestMultipleComposeFilesOneTwo(c *C) { 177 p := "multiple" 178 cmd := exec.Command(s.command, "-f", "./assets/multiple/one.yml", "-f", "./assets/multiple/two.yml", "create") 179 cmd.Stdout = os.Stdout 180 cmd.Stderr = os.Stderr 181 cmd.Stdin = os.Stdin 182 err := cmd.Run() 183 184 c.Assert(err, IsNil) 185 186 containerNames := []string{"multiple", "simple", "another", "yetanother"} 187 188 for _, containerName := range containerNames { 189 name := fmt.Sprintf("%s_%s_1", p, containerName) 190 container := s.GetContainerByName(c, name) 191 192 c.Assert(container, NotNil) 193 } 194 195 name := fmt.Sprintf("%s_%s_1", p, "multiple") 196 container := s.GetContainerByName(c, name) 197 198 c.Assert(container.Config.Image, Equals, "busybox") 199 c.Assert([]string(container.Config.Cmd), DeepEquals, []string{"echo", "two"}) 200 c.Assert(contains(container.Config.Env, "KEY2=VAL2"), Equals, true) 201 c.Assert(contains(container.Config.Env, "KEY1=VAL1"), Equals, true) 202 } 203 204 func (s *CliSuite) TestMultipleComposeFilesTwoOne(c *C) { 205 p := "multiple" 206 cmd := exec.Command(s.command, "-f", "./assets/multiple/two.yml", "-f", "./assets/multiple/one.yml", "create") 207 cmd.Stdout = os.Stdout 208 cmd.Stderr = os.Stderr 209 cmd.Stdin = os.Stdin 210 err := cmd.Run() 211 212 c.Assert(err, IsNil) 213 214 containerNames := []string{"multiple", "simple", "another", "yetanother"} 215 216 for _, containerName := range containerNames { 217 name := fmt.Sprintf("%s_%s_1", p, containerName) 218 container := s.GetContainerByName(c, name) 219 220 c.Assert(container, NotNil) 221 } 222 223 name := fmt.Sprintf("%s_%s_1", p, "multiple") 224 container := s.GetContainerByName(c, name) 225 226 c.Assert(container.Config.Image, Equals, "tianon/true") 227 c.Assert([]string(container.Config.Cmd), DeepEquals, []string{"echo", "two"}) 228 c.Assert(contains(container.Config.Env, "KEY2=VAL2"), Equals, true) 229 c.Assert(contains(container.Config.Env, "KEY1=VAL1"), Equals, true) 230 } 231 232 func contains(s []string, e string) bool { 233 for _, a := range s { 234 if a == e { 235 return true 236 } 237 } 238 return false 239 } 240 241 func (s *CliSuite) TestDefaultMultipleComposeFiles(c *C) { 242 p := s.RandomProject() 243 cmd := exec.Command(filepath.Join("../../", s.command), "-p", p, "create") 244 cmd.Stdout = os.Stdout 245 cmd.Stderr = os.Stderr 246 cmd.Stdin = os.Stdin 247 cmd.Dir = "./assets/multiple-composefiles-default/" 248 err := cmd.Run() 249 250 c.Assert(err, IsNil) 251 252 containerNames := []string{"simple", "another", "yetanother"} 253 254 for _, containerName := range containerNames { 255 name := fmt.Sprintf("%s_%s_1", p, containerName) 256 container := s.GetContainerByName(c, name) 257 258 c.Assert(container, NotNil) 259 } 260 } 261 262 func (s *CliSuite) TestValidation(c *C) { 263 template := ` 264 test: 265 image: busybox 266 ports: invalid_type 267 ` 268 _, output := s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 269 270 c.Assert(strings.Contains(output, "Service 'test' configuration key 'ports' contains an invalid type, it should be an array."), Equals, true) 271 272 template = ` 273 test: 274 image: busybox 275 build: . 276 ` 277 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 278 279 c.Assert(strings.Contains(output, "Service 'test' has both an image and build path specified. A service can either be built to image or use an existing image, not both."), Equals, true) 280 281 template = ` 282 test: 283 image: busybox 284 ports: invalid_type 285 links: invalid_type 286 devices: 287 - /dev/foo:/dev/foo 288 - /dev/foo:/dev/foo 289 ` 290 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 291 292 c.Assert(strings.Contains(output, "Service 'test' configuration key 'ports' contains an invalid type, it should be an array."), Equals, true) 293 c.Assert(strings.Contains(output, "Service 'test' configuration key 'links' contains an invalid type, it should be an array"), Equals, true) 294 c.Assert(strings.Contains(output, "Service 'test' configuration key 'devices' value [/dev/foo:/dev/foo /dev/foo:/dev/foo] has non-unique elements"), Equals, true) 295 } 296 297 func (s *CliSuite) TestValidationV2(c *C) { 298 template := ` 299 version: '2' 300 services: 301 test: 302 image: busybox 303 ports: invalid_type 304 ` 305 _, output := s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 306 307 c.Assert(strings.Contains(output, "Service 'test' configuration key 'ports' contains an invalid type, it should be an array."), Equals, true) 308 309 template = ` 310 version: '2' 311 services: 312 test: 313 image: busybox 314 ports: invalid_type 315 links: invalid_type 316 devices: 317 - /dev/foo:/dev/foo 318 - /dev/foo:/dev/foo 319 ` 320 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 321 322 c.Assert(strings.Contains(output, "Service 'test' configuration key 'ports' contains an invalid type, it should be an array."), Equals, true) 323 c.Assert(strings.Contains(output, "Service 'test' configuration key 'links' contains an invalid type, it should be an array"), Equals, true) 324 c.Assert(strings.Contains(output, "Service 'test' configuration key 'devices' value [/dev/foo:/dev/foo /dev/foo:/dev/foo] has non-unique elements"), Equals, true) 325 } 326 327 func (s *CliSuite) TestValidationWithExtends(c *C) { 328 template := ` 329 base: 330 image: busybox 331 privilege: "something" 332 test: 333 extends: 334 service: base 335 ` 336 337 _, output := s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 338 339 c.Assert(strings.Contains(output, "Unsupported config option for base service: 'privilege' (did you mean 'privileged'?)"), Equals, true) 340 341 template = ` 342 base: 343 image: busybox 344 test: 345 extends: 346 service: base 347 links: invalid_type 348 ` 349 350 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 351 352 c.Assert(strings.Contains(output, "Service 'test' configuration key 'links' contains an invalid type, it should be an array"), Equals, true) 353 354 template = ` 355 test: 356 extends: 357 file: ./assets/validation/valid/docker-compose.v1.yml 358 service: base 359 devices: 360 - /dev/foo:/dev/foo 361 - /dev/foo:/dev/foo 362 ` 363 364 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 365 366 c.Assert(strings.Contains(output, "Service 'test' configuration key 'devices' value [/dev/foo:/dev/foo /dev/foo:/dev/foo] has non-unique elements"), Equals, true) 367 368 template = ` 369 test: 370 extends: 371 file: ./assets/validation/invalid/docker-compose.v1.yml 372 service: base 373 ` 374 375 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 376 377 c.Assert(strings.Contains(output, "Service 'base' configuration key 'ports' contains an invalid type, it should be an array."), Equals, true) 378 } 379 380 func (s *CliSuite) TestValidationWithExtendsV2(c *C) { 381 template := ` 382 version: '2' 383 services: 384 base: 385 image: busybox 386 privilege: "something" 387 test: 388 extends: 389 service: base 390 ` 391 392 _, output := s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 393 394 c.Assert(strings.Contains(output, "Unsupported config option for base service: 'privilege' (did you mean 'privileged'?)"), Equals, true) 395 396 template = ` 397 version: '2' 398 services: 399 base: 400 image: busybox 401 test: 402 extends: 403 service: base 404 links: invalid_type 405 ` 406 407 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 408 409 c.Assert(strings.Contains(output, "Service 'test' configuration key 'links' contains an invalid type, it should be an array"), Equals, true) 410 411 template = ` 412 version: '2' 413 services: 414 test: 415 extends: 416 file: ./assets/validation/valid/docker-compose.v2.yml 417 service: base 418 devices: 419 - /dev/foo:/dev/foo 420 - /dev/foo:/dev/foo 421 ` 422 423 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 424 425 c.Assert(strings.Contains(output, "Service 'test' configuration key 'devices' value [/dev/foo:/dev/foo /dev/foo:/dev/foo] has non-unique elements"), Equals, true) 426 427 template = ` 428 version: '2' 429 services: 430 test: 431 extends: 432 file: ./assets/validation/invalid/docker-compose.v2.yml 433 service: base 434 ` 435 436 _, output = s.FromTextCaptureOutput(c, s.RandomProject(), "create", template) 437 438 c.Assert(strings.Contains(output, "Service 'base' configuration key 'ports' contains an invalid type, it should be an array."), Equals, true) 439 }