github.com/bdwilliams/libcompose@v0.3.1-0.20160826154243-d81a9bdacff0/config/merge_test.go (about)

     1  package config
     2  
     3  import (
     4  	"io/ioutil"
     5  	"testing"
     6  )
     7  
     8  type NullLookup struct {
     9  }
    10  
    11  func (n *NullLookup) Lookup(file, relativeTo string) ([]byte, string, error) {
    12  	return nil, "", nil
    13  }
    14  
    15  func (n *NullLookup) ResolvePath(path, inFile string) string {
    16  	return ""
    17  }
    18  
    19  type FileLookup struct {
    20  }
    21  
    22  func (f *FileLookup) Lookup(file, relativeTo string) ([]byte, string, error) {
    23  	bytes, err := ioutil.ReadFile(file)
    24  	return bytes, file, err
    25  }
    26  
    27  func (f *FileLookup) ResolvePath(path, inFile string) string {
    28  	return ""
    29  }
    30  
    31  func TestExtendsInheritImage(t *testing.T) {
    32  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
    33  parent:
    34    image: foo
    35  child:
    36    extends:
    37      service: parent
    38  `), nil)
    39  	if err != nil {
    40  		t.Fatal(err)
    41  	}
    42  
    43  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
    44  version: '2'
    45  services:
    46    parent:
    47      image: foo
    48    child:
    49      extends:
    50        service: parent
    51  `), nil)
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
    57  		parent := config["parent"]
    58  		child := config["child"]
    59  
    60  		if parent.Image != "foo" {
    61  			t.Fatal("Invalid parent image", parent.Image)
    62  		}
    63  
    64  		t.Logf("%#v", config["child"])
    65  		if child.Build.Context != "" {
    66  			t.Fatalf("Invalid build %#v", child.Build)
    67  		}
    68  
    69  		if child.Image != "foo" {
    70  			t.Fatal("Invalid child image", child.Image)
    71  		}
    72  	}
    73  }
    74  
    75  func TestExtendsInheritBuild(t *testing.T) {
    76  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
    77  parent:
    78    build: .
    79  child:
    80    extends:
    81      service: parent
    82  `), nil)
    83  	if err != nil {
    84  		t.Fatal(err)
    85  	}
    86  
    87  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
    88  version: '2'
    89  services:
    90    parent:
    91      build:
    92        context: .
    93    child:
    94      extends:
    95        service: parent
    96  `), nil)
    97  	if err != nil {
    98  		t.Fatal(err)
    99  	}
   100  
   101  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
   102  		parent := config["parent"]
   103  		child := config["child"]
   104  
   105  		if parent.Build.Context != "." {
   106  			t.Fatal("Invalid build", parent.Build)
   107  		}
   108  
   109  		if child.Build.Context != "." {
   110  			t.Fatal("Invalid build", child.Build)
   111  		}
   112  
   113  		if child.Image != "" {
   114  			t.Fatal("Invalid image", child.Image)
   115  		}
   116  	}
   117  }
   118  
   119  func TestExtendBuildOverImage(t *testing.T) {
   120  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   121  parent:
   122    image: foo
   123  child:
   124    build: .
   125    extends:
   126      service: parent
   127  `), nil)
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  
   132  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   133  version: '2'
   134  services:
   135    parent:
   136      image: foo
   137    child:
   138      build:
   139        context: .
   140      extends:
   141        service: parent
   142  `), nil)
   143  	if err != nil {
   144  		t.Fatal(err)
   145  	}
   146  
   147  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
   148  		parent := config["parent"]
   149  		child := config["child"]
   150  
   151  		if parent.Image != "foo" {
   152  			t.Fatal("Invalid image", parent.Image)
   153  		}
   154  
   155  		if child.Build.Context != "." {
   156  			t.Fatal("Invalid build", child.Build)
   157  		}
   158  
   159  		if child.Image != "" {
   160  			t.Fatal("Invalid image", child.Image)
   161  		}
   162  	}
   163  }
   164  
   165  func TestExtendImageOverBuild(t *testing.T) {
   166  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   167  parent:
   168    build: .
   169  child:
   170    image: foo
   171    extends:
   172      service: parent
   173  `), nil)
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   179  version: '2'
   180  services:
   181    parent:
   182      build:
   183        context: .
   184    child:
   185      image: foo
   186      extends:
   187        service: parent
   188  `), nil)
   189  	if err != nil {
   190  		t.Fatal(err)
   191  	}
   192  
   193  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
   194  		parent := config["parent"]
   195  		child := config["child"]
   196  
   197  		if parent.Image != "" {
   198  			t.Fatal("Invalid image", parent.Image)
   199  		}
   200  
   201  		if parent.Build.Context != "." {
   202  			t.Fatal("Invalid build", parent.Build)
   203  		}
   204  
   205  		if child.Build.Context != "" {
   206  			t.Fatal("Invalid build", child.Build)
   207  		}
   208  
   209  		if child.Image != "foo" {
   210  			t.Fatal("Invalid image", child.Image)
   211  		}
   212  	}
   213  }
   214  
   215  func TestMergesEnvFile(t *testing.T) {
   216  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &FileLookup{}, "", []byte(`
   217  test:
   218    image: foo
   219    env_file:
   220      - testdata/.env
   221  `), nil)
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  
   226  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &FileLookup{}, "", []byte(`
   227  version: '2'
   228  services:
   229    test:
   230      image: foo
   231      env_file:
   232        - testdata/.env
   233  `), nil)
   234  	if err != nil {
   235  		t.Fatal(err)
   236  	}
   237  
   238  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
   239  		test := config["test"]
   240  
   241  		if len(test.Environment) != 2 {
   242  			t.Fatal("env_file is not merged", test.Environment)
   243  		}
   244  
   245  		for _, environment := range test.Environment {
   246  			if (environment != "FOO=foo") && (environment != "BAR=bar") {
   247  				t.Fatal("Empty line and comment should be excluded", environment)
   248  			}
   249  		}
   250  	}
   251  }
   252  
   253  func TestRestartNo(t *testing.T) {
   254  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   255  test:
   256    restart: "no"
   257    image: foo
   258  `), nil)
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  
   263  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   264  version: '2'
   265  services:
   266    test:
   267      restart: "no"
   268      image: foo
   269  `), nil)
   270  	if err != nil {
   271  		t.Fatal(err)
   272  	}
   273  
   274  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
   275  		test := config["test"]
   276  
   277  		if test.Restart != "no" {
   278  			t.Fatal("Invalid restart policy", test.Restart)
   279  		}
   280  	}
   281  }
   282  
   283  func TestRestartAlways(t *testing.T) {
   284  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   285  test:
   286    restart: always
   287    image: foo
   288  `), nil)
   289  	if err != nil {
   290  		t.Fatal(err)
   291  	}
   292  
   293  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   294  version: '2'
   295  services:
   296    test:
   297      restart: always
   298      image: foo
   299  `), nil)
   300  	if err != nil {
   301  		t.Fatal(err)
   302  	}
   303  
   304  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
   305  		test := config["test"]
   306  
   307  		if test.Restart != "always" {
   308  			t.Fatal("Invalid restart policy", test.Restart)
   309  		}
   310  	}
   311  }
   312  
   313  func TestIsValidRemote(t *testing.T) {
   314  	gitUrls := []string{
   315  		"git://github.com/docker/docker",
   316  		"git@github.com:docker/docker.git",
   317  		"git@bitbucket.org:atlassianlabs/atlassian-docker.git",
   318  		"https://github.com/docker/docker.git",
   319  		"http://github.com/docker/docker.git",
   320  		"http://github.com/docker/docker.git#branch",
   321  		"http://github.com/docker/docker.git#:dir",
   322  	}
   323  	incompleteGitUrls := []string{
   324  		"github.com/docker/docker",
   325  	}
   326  	invalidGitUrls := []string{
   327  		"http://github.com/docker/docker.git:#branch",
   328  	}
   329  	for _, url := range gitUrls {
   330  		if !IsValidRemote(url) {
   331  			t.Fatalf("%q should have been a valid remote", url)
   332  		}
   333  	}
   334  	for _, url := range incompleteGitUrls {
   335  		if !IsValidRemote(url) {
   336  			t.Fatalf("%q should have been a valid remote", url)
   337  		}
   338  	}
   339  	for _, url := range invalidGitUrls {
   340  		if !IsValidRemote(url) {
   341  			t.Fatalf("%q should have been a valid remote", url)
   342  		}
   343  	}
   344  }
   345  
   346  func preprocess(services RawServiceMap) (RawServiceMap, error) {
   347  	for name := range services {
   348  		services[name]["image"] = "foo2"
   349  	}
   350  	return services, nil
   351  }
   352  
   353  func postprocess(services map[string]*ServiceConfig) (map[string]*ServiceConfig, error) {
   354  	for name := range services {
   355  		services[name].ContainerName = "cname"
   356  	}
   357  	return services, nil
   358  }
   359  
   360  func TestParseOptions(t *testing.T) {
   361  	parseOptions := ParseOptions{
   362  		Interpolate: false,
   363  		Validate:    false,
   364  		Preprocess:  preprocess,
   365  		Postprocess: postprocess,
   366  	}
   367  
   368  	_, configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   369  test:
   370    image: foo
   371    labels:
   372      x: $X
   373  test2:
   374    invalid_key: true
   375  `), &parseOptions)
   376  	if err != nil {
   377  		t.Fatal(err)
   378  	}
   379  
   380  	_, configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
   381  version: '2'
   382  services:
   383    test:
   384      image: foo
   385      labels:
   386        x: $X
   387    test2:
   388      invalid_key: true
   389  `), &parseOptions)
   390  	if err != nil {
   391  		t.Fatal(err)
   392  	}
   393  
   394  	for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
   395  		test := config["test"]
   396  
   397  		if test.Image != "foo2" {
   398  			t.Fatal("Preprocess failed to change image", test.Image)
   399  		}
   400  		if test.ContainerName != "cname" {
   401  			t.Fatal("Postprocess failed to change container name", test.ContainerName)
   402  		}
   403  		if test.Labels["x"] != "$X" {
   404  			t.Fatal("Failed to disable interpolation")
   405  		}
   406  	}
   407  }
   408  
   409  func TestParseNetworks(t *testing.T) {
   410  	composeFile := []byte(`networks:
   411    public:`)
   412  
   413  	networkConfigs, err := ParseNetworks(composeFile)
   414  	if err != nil {
   415  		t.Fatal(err)
   416  	}
   417  	for key, networkConfig := range networkConfigs {
   418  		if networkConfig == nil {
   419  			t.Fatalf("networkConfig %s was nil, shouldn't be", key)
   420  		}
   421  	}
   422  }