gopkg.in/docker/libcompose.v0@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  }