github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/integration/isolated/manifest_inheritance_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  	"strings"
     8  	"time"
     9  
    10  	"code.cloudfoundry.org/cli/integration/helpers"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/gbytes"
    14  	. "github.com/onsi/gomega/gexec"
    15  )
    16  
    17  // pushes app with multiple manifests, children being passed in first in the
    18  // array
    19  func pushHelloWorldAppWithManifests(manifests []string) {
    20  	helpers.WithHelloWorldApp(func(appDir string) {
    21  		pushPath := filepath.Join(appDir, "manifest-0.yml")
    22  		for i, manifest := range manifests {
    23  			manifestPath := filepath.Join(appDir, fmt.Sprintf("manifest-%d.yml", i))
    24  			manifest = strings.Replace(manifest, "inherit: {some-parent}", fmt.Sprintf("inherit: manifest-%d.yml", i+1), 1)
    25  			manifest = strings.Replace(manifest, "path: {some-dir}", fmt.Sprintf("path: %s", appDir), -1)
    26  			err := ioutil.WriteFile(manifestPath, []byte(manifest), 0666)
    27  			Expect(err).ToNot(HaveOccurred())
    28  		}
    29  		Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", "-f", pushPath)).Should(Exit(0))
    30  	})
    31  }
    32  
    33  func pushDockerWithManifests(manifests []string) {
    34  	helpers.WithHelloWorldApp(func(appDir string) {
    35  		pushPath := filepath.Join(appDir, "manifest-0.yml")
    36  		for i, manifest := range manifests {
    37  			manifestPath := filepath.Join(appDir, fmt.Sprintf("manifest-%d.yml", i))
    38  			manifest = strings.Replace(manifest, "inherit: {some-parent}", fmt.Sprintf("inherit: manifest-%d.yml", i+1), 1)
    39  			manifest = strings.Replace(manifest, "path: {some-dir}", fmt.Sprintf("path: %s", appDir), -1)
    40  			err := ioutil.WriteFile(manifestPath, []byte(manifest), 0666)
    41  			Expect(err).ToNot(HaveOccurred())
    42  		}
    43  		Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", "-f", pushPath)).Should(Exit())
    44  	})
    45  }
    46  
    47  // CASE 1: child manifest (no inheritance)
    48  //
    49  // APPLICATION params:
    50  // values (memory, disk), list (routes), map (env vars)
    51  //
    52  // GLOBAL params:
    53  // value, list, map types
    54  //
    55  // APPLICATION and GLOBAL params:
    56  // value: application values override global values
    57  // list: application lists append to global lists
    58  // map: application maps merge & override global maps
    59  //
    60  //
    61  // CASE 2: child + parent manifests (1 level inheritance)
    62  //
    63  // Parent Application & Child Application
    64  // Parent Global & Child Application
    65  // Parent Application & Child Global
    66  // Parent Global & Child Global
    67  //
    68  // Parent Global & Child Global & Child Application
    69  // Parent Application & Child Global & Child Application
    70  // Parent Global & Parent Application & Child Application
    71  // Parent Global & Parent Application & Child Global
    72  //
    73  // Parent Global & Parent Application & Child Global & Child Application
    74  //
    75  // CASE 3: child + parent + super-parent manifests (n+ inheritance)
    76  // Super-parent Global & Parent Global & Parent Application & Child Global
    77  // Super-parent Global & Parent Global & Child Global & Child Application
    78  
    79  var _ = Describe("manifest inheritance in push command", func() {
    80  	var (
    81  		orgName     string
    82  		spaceName   string
    83  		domainName  string
    84  		app1Name    string
    85  		app2Name    string
    86  		app1MemSize int
    87  		app2MemSize int
    88  	)
    89  
    90  	BeforeEach(func() {
    91  		orgName = helpers.NewOrgName()
    92  		spaceName = helpers.NewSpaceName()
    93  		app1Name = helpers.PrefixedRandomName("app")
    94  		app2Name = helpers.PrefixedRandomName("app")
    95  		app1MemSize = 32
    96  		app2MemSize = 32
    97  
    98  		setupCF(orgName, spaceName)
    99  
   100  		domainName = fmt.Sprintf("%s.com", helpers.PrefixedRandomName("DOMAIN"))
   101  		helpers.NewDomain(orgName, domainName).Create()
   102  	})
   103  
   104  	AfterEach(func() {
   105  		helpers.QuickDeleteOrg(orgName)
   106  	})
   107  
   108  	Context("when there is only one manifest", func() {
   109  		Context("when the manifest contains only applications properties", func() {
   110  			BeforeEach(func() {
   111  				pushHelloWorldAppWithManifests([]string{fmt.Sprintf(`
   112  ---
   113  applications:
   114  - name: %s
   115    memory: %dM
   116    disk_quota: 128M
   117    buildpack: staticfile_buildpack
   118    path: {some-dir}
   119    routes:
   120    - route: hello.%s
   121    - route: hi.%s
   122    env:
   123      BAR: bar
   124      FOO: foo
   125  - name: %s
   126    memory: %dM
   127    disk_quota: 128M
   128    buildpack: staticfile_buildpack
   129    path: {some-dir}
   130    routes:
   131    - route: hello.%s
   132    - route: hi.%s
   133    env:
   134      BAR: bar
   135      FOO: foo
   136  `, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName)})
   137  			})
   138  
   139  			It("pushes the same applications properties", func() {
   140  				session := helpers.CF("env", app1Name)
   141  				Eventually(session.Out).Should(Say("OK"))
   142  				Eventually(session.Out).Should(Say(`"application_uris": \[
   143     "hello\.%s"\,
   144     "hi\.%s"
   145    \]`, domainName, domainName))
   146  				Eventually(session.Out).Should(Say(`"disk": 128`))
   147  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   148  				Eventually(session.Out).Should(Say(`User-Provided:
   149  BAR: bar
   150  FOO: foo
   151  
   152  `))
   153  				Eventually(session).Should(Exit(0))
   154  
   155  				session = helpers.CF("env", app2Name)
   156  				Eventually(session.Out).Should(Say("OK"))
   157  				Eventually(session.Out).Should(Say(`"application_uris": \[
   158     "hello\.%s"\,
   159     "hi\.%s"
   160    \]`, domainName, domainName))
   161  				Eventually(session.Out).Should(Say(`"disk": 128`))
   162  				Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
   163  				Eventually(session.Out).Should(Say(`User-Provided:
   164  BAR: bar
   165  FOO: foo
   166  
   167  `))
   168  				Eventually(session).Should(Exit(0))
   169  			})
   170  		})
   171  
   172  		Context("when the manifest contains mainly global properties", func() {
   173  			BeforeEach(func() {
   174  				pushHelloWorldAppWithManifests([]string{fmt.Sprintf(`
   175  ---
   176  memory: %dM
   177  disk_quota: 128M
   178  buildpack: staticfile_buildpack
   179  path: {some-dir}
   180  routes:
   181  - route: hello.%s
   182  - route: hi.%s
   183  env:
   184    BAR: bar
   185    FOO: foo
   186  applications:
   187  - name: %s
   188  - name: %s
   189  `, app1MemSize, domainName, domainName, app1Name, app2Name)})
   190  			})
   191  
   192  			It("pushes the same global properties", func() {
   193  				session := helpers.CF("env", app1Name)
   194  				Eventually(session.Out).Should(Say("OK"))
   195  				Eventually(session.Out).Should(Say(`"application_uris": \[
   196     "hello\.%s"\,
   197     "hi\.%s"
   198    \]`, domainName, domainName))
   199  				Eventually(session.Out).Should(Say(`"disk": 128`))
   200  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   201  				Eventually(session.Out).Should(Say(`User-Provided:
   202  BAR: bar
   203  FOO: foo
   204  
   205  `))
   206  				Eventually(session).Should(Exit(0))
   207  
   208  				session = helpers.CF("env", app2Name)
   209  				Eventually(session.Out).Should(Say("OK"))
   210  				Eventually(session.Out).Should(Say(`"application_uris": \[
   211     "hello\.%s"\,
   212     "hi\.%s"
   213    \]`, domainName, domainName))
   214  				Eventually(session.Out).Should(Say(`"disk": 128`))
   215  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   216  				Eventually(session.Out).Should(Say(`User-Provided:
   217  BAR: bar
   218  FOO: foo
   219  
   220  `))
   221  				Eventually(session).Should(Exit(0))
   222  			})
   223  		})
   224  
   225  		Context("when the manifest contains both applications and global properties", func() {
   226  			BeforeEach(func() {
   227  				pushHelloWorldAppWithManifests([]string{fmt.Sprintf(`
   228  ---
   229  buildpack: staticfile_buildpack
   230  memory: 64M
   231  disk_quota: 256M
   232  routes:
   233  - route: global-1.%s
   234  - route: global-2.%s
   235  env:
   236    BAR: global
   237    FOO: global
   238  applications:
   239  - name: %s
   240    memory: %dM
   241    disk_quota: 128M
   242    path: {some-dir}
   243    routes:
   244    - route: app-1.%s
   245    - route: app-2.%s
   246    env:
   247      BAR: app
   248      BAZ: app
   249  - name: %s
   250    memory: %dM
   251    disk_quota: 128M
   252    path: {some-dir}
   253    routes:
   254    - route: app-1.%s
   255    - route: app-2.%s
   256    env:
   257      BAR: app
   258      BAZ: app
   259  `, domainName, domainName, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName)})
   260  			})
   261  
   262  			It("pushes with application properties taking precedence; values are overwritten, lists are appended, and maps are merged", func() {
   263  				session := helpers.CF("env", app1Name)
   264  				Eventually(session.Out).Should(Say("OK"))
   265  				Eventually(session.Out).Should(Say(`"application_uris": \[
   266     "global-1\.%s"\,
   267     "global-2\.%s",
   268     "app-1\.%s",
   269     "app-2\.%s"
   270    \]`, domainName, domainName, domainName, domainName))
   271  				Eventually(session.Out).Should(Say(`"disk": 128`))
   272  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   273  				Eventually(session.Out).Should(Say(`User-Provided:
   274  BAR: app
   275  BAZ: app
   276  FOO: global
   277  
   278  `))
   279  				Eventually(session).Should(Exit(0))
   280  
   281  				session = helpers.CF("env", app2Name)
   282  				Eventually(session.Out).Should(Say("OK"))
   283  				Eventually(session.Out).Should(Say(`"application_uris": \[
   284     "global-1\.%s"\,
   285     "global-2\.%s",
   286     "app-1\.%s",
   287     "app-2\.%s"
   288    \]`, domainName, domainName, domainName, domainName))
   289  				Eventually(session.Out).Should(Say(`"disk": 128`))
   290  				Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
   291  				Eventually(session.Out).Should(Say(`User-Provided:
   292  BAR: app
   293  BAZ: app
   294  FOO: global
   295  
   296  `))
   297  				Eventually(session).Should(Exit(0))
   298  			})
   299  		})
   300  	})
   301  
   302  	Context("when there are two manifests", func() {
   303  		Context("when the child has applications properties; and the parent has applications properties", func() {
   304  			Context("when the app is a buildpack app", func() {
   305  				BeforeEach(func() {
   306  					pushHelloWorldAppWithManifests([]string{
   307  						fmt.Sprintf(`
   308  ---
   309  inherit: {some-parent}
   310  applications:
   311  - name: %s
   312    memory: %dM
   313    disk_quota: 128M
   314    path: {some-dir}
   315    routes:
   316    - route: child-app-1.%s
   317    - route: child-app-2.%s
   318    env:
   319      BAR: child-app
   320      BAZ: child-app
   321  - name: %s
   322    memory: %dM
   323    disk_quota: 128M
   324    path: {some-dir}
   325    routes:
   326    - route: child-app-1.%s
   327    - route: child-app-2.%s
   328    env:
   329      BAR: child-app
   330      BAZ: child-app
   331  `, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
   332  						fmt.Sprintf(`
   333  ---
   334  applications:
   335  - name: %s
   336    buildpack: staticfile_buildpack
   337    memory: %dM
   338    disk_quota: 256M
   339    path: {some-dir}
   340    routes:
   341    - route: parent-app-1.%s
   342    - route: parent-app-2.%s
   343    env:
   344      BAR: parent-app
   345      BAZ: parent-app
   346      FOO: parent-app
   347  - name: %s
   348    buildpack: staticfile_buildpack
   349    memory: %dM
   350    disk_quota: 256M
   351    path: {some-dir}
   352    routes:
   353    - route: parent-app-1.%s
   354    - route: parent-app-2.%s
   355    env:
   356      BAR: parent-app
   357      BAZ: parent-app
   358      FOO: parent-app
   359  `, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
   360  					})
   361  				})
   362  
   363  				It("pushes with child application properties taking precedence; values are overwritten, lists are appended, and maps are merged", func() {
   364  					session := helpers.CF("env", app1Name)
   365  					Eventually(session.Out).Should(Say("OK"))
   366  					Eventually(session.Out).Should(Say(`"application_uris": \[
   367     "parent-app-1\.%s",
   368     "parent-app-2\.%s",
   369     "child-app-1\.%s"\,
   370     "child-app-2\.%s"
   371    \]`, domainName, domainName, domainName, domainName))
   372  					Eventually(session.Out).Should(Say(`"disk": 128`))
   373  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   374  					Eventually(session.Out).Should(Say(`User-Provided:
   375  BAR: child-app
   376  BAZ: child-app
   377  FOO: parent-app
   378  
   379  `))
   380  					Eventually(session).Should(Exit(0))
   381  
   382  					session = helpers.CF("env", app2Name)
   383  					Eventually(session.Out).Should(Say("OK"))
   384  					Eventually(session.Out).Should(Say(`"application_uris": \[
   385     "parent-app-1\.%s",
   386     "parent-app-2\.%s",
   387     "child-app-1\.%s"\,
   388     "child-app-2\.%s"
   389    \]`, domainName, domainName, domainName, domainName))
   390  					Eventually(session.Out).Should(Say(`"disk": 128`))
   391  					Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
   392  					Eventually(session.Out).Should(Say(`User-Provided:
   393  BAR: child-app
   394  BAZ: child-app
   395  FOO: parent-app
   396  
   397  `))
   398  					Eventually(session).Should(Exit(0))
   399  				})
   400  			})
   401  
   402  			Context("when the app is a Docker app", func() {
   403  				BeforeEach(func() {
   404  					pushDockerWithManifests([]string{
   405  						fmt.Sprintf(`
   406  ---
   407  inherit: {some-parent}
   408  applications:
   409  - name: %s
   410    docker:
   411      image: child-application-image
   412  `, app1Name),
   413  						fmt.Sprintf(`
   414  ---
   415  applications:
   416  - name: %s
   417    docker:
   418      image: %s
   419  `, app1Name, DockerImage),
   420  					})
   421  				})
   422  
   423  				It("pushes with child application docker image properties taking precedence", func() {
   424  					session := helpers.CF("app", app1Name)
   425  					Eventually(session.Out).Should(Say(`docker image:\s*child-application-image`))
   426  					Eventually(session).Should(Exit(0))
   427  				})
   428  			})
   429  		})
   430  
   431  		Context("when the child has applications properties; and the parent has global properties", func() {
   432  			Context("when the app is a buildpack app", func() {
   433  				BeforeEach(func() {
   434  					pushHelloWorldAppWithManifests([]string{
   435  						fmt.Sprintf(`
   436  ---
   437  inherit: {some-parent}
   438  applications:
   439  - name: %s
   440    memory: %dM
   441    disk_quota: 128M
   442    path: {some-dir}
   443    routes:
   444    - route: child-app-1.%s
   445    - route: child-app-2.%s
   446    env:
   447      BAR: child-app
   448      BAZ: child-app
   449  - name: %s
   450    memory: %dM
   451    disk_quota: 128M
   452    path: {some-dir}
   453    routes:
   454    - route: child-app-1.%s
   455    - route: child-app-2.%s
   456    env:
   457      BAR: child-app
   458      BAZ: child-app
   459  `, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
   460  						fmt.Sprintf(`
   461  ---
   462  buildpack: staticfile_buildpack
   463  memory: 64M
   464  disk_quota: 256M
   465  path: {some-dir}
   466  routes:
   467  - route: parent-global-1.%s
   468  - route: parent-global-2.%s
   469  env:
   470    BAR: parent-global
   471    BAZ: parent-global
   472    FOO: parent-global
   473  `, domainName, domainName),
   474  					})
   475  					SetDefaultEventuallyTimeout(300 * time.Second)
   476  				})
   477  
   478  				It("pushes with child application properties taking precedence", func() {
   479  					session := helpers.CF("env", app1Name)
   480  					Eventually(session.Out).Should(Say("OK"))
   481  					Eventually(session.Out).Should(Say(`"application_uris": \[
   482     "parent-global-1\.%s",
   483     "parent-global-2\.%s",
   484     "child-app-1\.%s"\,
   485     "child-app-2\.%s"
   486    \]`, domainName, domainName, domainName, domainName))
   487  					Eventually(session.Out).Should(Say(`"disk": 128`))
   488  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   489  					Eventually(session.Out).Should(Say(`User-Provided:
   490  BAR: child-app
   491  BAZ: child-app
   492  FOO: parent-global
   493  
   494  `))
   495  					Eventually(session).Should(Exit(0))
   496  
   497  					session = helpers.CF("env", app2Name)
   498  					Eventually(session.Out).Should(Say("OK"))
   499  					Eventually(session.Out).Should(Say(`"application_uris": \[
   500     "parent-global-1\.%s",
   501     "parent-global-2\.%s",
   502     "child-app-1\.%s"\,
   503     "child-app-2\.%s"
   504    \]`, domainName, domainName, domainName, domainName))
   505  					Eventually(session.Out).Should(Say(`"disk": 128`))
   506  					Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
   507  					Eventually(session.Out).Should(Say(`User-Provided:
   508  BAR: child-app
   509  BAZ: child-app
   510  FOO: parent-global
   511  
   512  `))
   513  					Eventually(session).Should(Exit(0))
   514  				})
   515  			})
   516  
   517  			Context("when the app is a Docker app", func() {
   518  				BeforeEach(func() {
   519  					pushDockerWithManifests([]string{
   520  						fmt.Sprintf(`
   521  ---
   522  inherit: {some-parent}
   523  applications:
   524  - name: %s
   525    docker:
   526      image: child-application-image
   527  `, app1Name),
   528  						fmt.Sprintf(`
   529  ---
   530  docker:
   531    image: parent-global-image
   532  `),
   533  					})
   534  				})
   535  
   536  				It("pushes with child application docker image properties taking precedence", func() {
   537  					session := helpers.CF("app", app1Name)
   538  					Eventually(session.Out).Should(Say(`docker image:\s*child-application-image`))
   539  					Eventually(session).Should(Exit(0))
   540  				})
   541  			})
   542  		})
   543  
   544  		Context("when the child has global properties; and the parent has applications properties", func() {
   545  			Context("when the app is a buildpack app", func() {
   546  				BeforeEach(func() {
   547  					pushHelloWorldAppWithManifests([]string{
   548  						fmt.Sprintf(`
   549  ---
   550  inherit: {some-parent}
   551  buildpack: staticfile_buildpack
   552  memory: 64M
   553  disk_quota: 256M
   554  path: {some-dir}
   555  routes:
   556  - route: child-global-1.%s
   557  - route: child-global-2.%s
   558  env:
   559    BAR: child-global
   560    BAZ: child-global
   561  `, domainName, domainName),
   562  						fmt.Sprintf(`
   563  ---
   564  applications:
   565  - name: %s
   566    memory: %dM
   567    disk_quota: 128M
   568    path: {some-dir}
   569    routes:
   570    - route: parent-app-1.%s
   571    - route: parent-app-2.%s
   572    env:
   573      BAR: parent-app
   574      BAZ: parent-app
   575      FOO: parent-app
   576  - name: %s
   577    memory: %dM
   578    disk_quota: 128M
   579    path: {some-dir}
   580    routes:
   581    - route: parent-app-1.%s
   582    - route: parent-app-2.%s
   583    env:
   584      BAR: parent-app
   585      BAZ: parent-app
   586      FOO: parent-app
   587  `, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
   588  					})
   589  					SetDefaultEventuallyTimeout(300 * time.Second)
   590  				})
   591  
   592  				It("pushes with parent application properties taking precedence", func() {
   593  					session := helpers.CF("env", app1Name)
   594  					Eventually(session.Out).Should(Say("OK"))
   595  					Eventually(session.Out).Should(Say(`"application_uris": \[
   596     "child-global-1\.%s"\,
   597     "child-global-2\.%s",
   598     "parent-app-1\.%s",
   599     "parent-app-2\.%s"
   600    \]`, domainName, domainName, domainName, domainName))
   601  					Eventually(session.Out).Should(Say(`"disk": 128`))
   602  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   603  					Eventually(session.Out).Should(Say(`User-Provided:
   604  BAR: parent-app
   605  BAZ: parent-app
   606  FOO: parent-app
   607  `))
   608  					Eventually(session).Should(Exit(0))
   609  
   610  					session = helpers.CF("env", app2Name)
   611  					Eventually(session.Out).Should(Say("OK"))
   612  					Eventually(session.Out).Should(Say(`"application_uris": \[
   613     "child-global-1\.%s"\,
   614     "child-global-2\.%s",
   615     "parent-app-1\.%s",
   616     "parent-app-2\.%s"
   617    \]`, domainName, domainName, domainName, domainName))
   618  					Eventually(session.Out).Should(Say(`"disk": 128`))
   619  					Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
   620  					Eventually(session.Out).Should(Say(`User-Provided:
   621  BAR: parent-app
   622  BAZ: parent-app
   623  FOO: parent-app
   624  `))
   625  					Eventually(session).Should(Exit(0))
   626  				})
   627  			})
   628  
   629  			Context("when the app is a Docker app", func() {
   630  				BeforeEach(func() {
   631  					pushDockerWithManifests([]string{
   632  						fmt.Sprintf(`
   633  ---
   634  inherit: {some-parent}
   635  docker:
   636    image: child-global-image
   637  `),
   638  						fmt.Sprintf(`
   639  ---
   640  applications:
   641  - name: %s
   642    docker:
   643      image: parent-application-image
   644  `, app1Name),
   645  					})
   646  				})
   647  
   648  				It("pushes with parent application docker image properties taking precedence", func() {
   649  					session := helpers.CF("app", app1Name)
   650  					Eventually(session.Out).Should(Say(`docker image:\s*parent-application-image`))
   651  					Eventually(session).Should(Exit(0))
   652  				})
   653  			})
   654  		})
   655  
   656  		Context("when the child has global properties; and the parent has global properties", func() {
   657  			Context("when the app is a buildpack app", func() {
   658  				BeforeEach(func() {
   659  					pushHelloWorldAppWithManifests([]string{
   660  						fmt.Sprintf(`
   661  ---
   662  inherit: {some-parent}
   663  memory: %dM
   664  disk_quota: 128M
   665  path: {some-dir}
   666  routes:
   667  - route: child-global-1.%s
   668  - route: child-global-2.%s
   669  env:
   670    BAR: child-global
   671    FOO: child-global
   672  `, app1MemSize, domainName, domainName),
   673  						fmt.Sprintf(`
   674  ---
   675  buildpack: staticfile_buildpack
   676  memory: 64M
   677  disk_quota: 256M
   678  path: {some-dir}
   679  routes:
   680  - route: parent-global-1.%s
   681  - route: parent-global-2.%s
   682  env:
   683    BAR: parent-global
   684    FOO: parent-global
   685    BAZ: parent-global
   686  applications:
   687  - name: %s
   688  - name: %s
   689  `, domainName, domainName, app1Name, app2Name),
   690  					})
   691  				})
   692  
   693  				It("pushes with child global properties taking precedence;", func() {
   694  					session := helpers.CF("env", app1Name)
   695  					Eventually(session.Out).Should(Say("OK"))
   696  					Eventually(session.Out).Should(Say(`"application_uris": \[
   697     "parent-global-1\.%s"\,
   698     "parent-global-2\.%s",
   699     "child-global-1\.%s",
   700     "child-global-2\.%s"
   701    \]`, domainName, domainName, domainName, domainName))
   702  					Eventually(session.Out).Should(Say(`"disk": 128`))
   703  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   704  					Eventually(session.Out).Should(Say(`User-Provided:
   705  BAR: child-global
   706  BAZ: parent-global
   707  FOO: child-global
   708  
   709  `))
   710  					Eventually(session).Should(Exit(0))
   711  
   712  					session = helpers.CF("env", app2Name)
   713  					Eventually(session.Out).Should(Say("OK"))
   714  					Eventually(session.Out).Should(Say(`"application_uris": \[
   715     "parent-global-1\.%s"\,
   716     "parent-global-2\.%s",
   717     "child-global-1\.%s",
   718     "child-global-2\.%s"
   719    \]`, domainName, domainName, domainName, domainName))
   720  					Eventually(session.Out).Should(Say(`"disk": 128`))
   721  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   722  					Eventually(session.Out).Should(Say(`User-Provided:
   723  BAR: child-global
   724  BAZ: parent-global
   725  FOO: child-global
   726  
   727  `))
   728  					Eventually(session).Should(Exit(0))
   729  				})
   730  			})
   731  
   732  			Context("when the app is a Docker app", func() {
   733  				BeforeEach(func() {
   734  					pushDockerWithManifests([]string{
   735  						fmt.Sprintf(`
   736  ---
   737  inherit: {some-parent}
   738  docker:
   739    image: child-global-image
   740  `),
   741  						fmt.Sprintf(`
   742  ---
   743  docker:
   744    image: %s
   745  applications:
   746  - name: %s
   747  `, DockerImage, app1Name),
   748  					})
   749  				})
   750  
   751  				It("pushes with child global docker image properties taking precedence", func() {
   752  					session := helpers.CF("app", app1Name)
   753  					Eventually(session.Out).Should(Say(`docker image:\s*child-global-image`))
   754  					Eventually(session).Should(Exit(0))
   755  				})
   756  			})
   757  		})
   758  
   759  		Context("when the child has applications and global properties; and the parent has global properties", func() {
   760  			Context("when the app is a buildpack app", func() {
   761  				BeforeEach(func() {
   762  					pushHelloWorldAppWithManifests([]string{
   763  						fmt.Sprintf(`
   764  ---
   765  inherit: {some-parent}
   766  memory: 128M
   767  disk_quota: 128M
   768  path: {some-dir}
   769  routes:
   770  - route: child-global-1.%s
   771  - route: child-global-2.%s
   772  env:
   773    FOO: child-global
   774    FIZ: child-global
   775  applications:
   776  - name: %s
   777    memory: %dM
   778    disk_quota: 64M
   779    path: {some-dir}
   780    routes:
   781    - route: child-app-1.%s
   782    - route: child-app-2.%s
   783    env:
   784      BAR: child-app
   785      FOO: child-app
   786  - name: %s
   787    memory: %dM
   788    disk_quota: 64M
   789    path: {some-dir}
   790    routes:
   791    - route: child-app-1.%s
   792    - route: child-app-2.%s
   793    env:
   794      BAR: child-app
   795      FOO: child-app
   796  `, domainName, domainName, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
   797  						fmt.Sprintf(`
   798  ---
   799  buildpack: staticfile_buildpack
   800  memory: 256M
   801  disk_quota: 256M
   802  path: {some-dir}
   803  routes:
   804  - route: parent-global-1.%s
   805  - route: parent-global-2.%s
   806  env:
   807    BAR: parent-global
   808    FOO: parent-global
   809    FIZ: parent-global
   810    BAZ: parent-global
   811  applications:
   812  - name: %s
   813  - name: %s
   814  `, domainName, domainName, app1Name, app2Name),
   815  					})
   816  				})
   817  
   818  				It("pushes with child application taking precedence over child global over parent global", func() {
   819  					session := helpers.CF("env", app1Name)
   820  					Eventually(session.Out).Should(Say("OK"))
   821  					Eventually(session.Out).Should(Say(`"application_uris": \[
   822     "parent-global-1\.%s"\,
   823     "parent-global-2\.%s",
   824     "child-global-1\.%s",
   825     "child-global-2\.%s",
   826     "child-app-1\.%s",
   827     "child-app-2\.%s"
   828    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
   829  					Eventually(session.Out).Should(Say(`"disk": 64`))
   830  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   831  					Eventually(session.Out).Should(Say(`User-Provided:
   832  BAR: child-app
   833  BAZ: parent-global
   834  FIZ: child-global
   835  FOO: child-app
   836  
   837  `))
   838  					Eventually(session).Should(Exit(0))
   839  
   840  					session = helpers.CF("env", app2Name)
   841  					Eventually(session.Out).Should(Say("OK"))
   842  					Eventually(session.Out).Should(Say(`"application_uris": \[
   843     "parent-global-1\.%s"\,
   844     "parent-global-2\.%s",
   845     "child-global-1\.%s",
   846     "child-global-2\.%s",
   847     "child-app-1\.%s",
   848     "child-app-2\.%s"
   849    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
   850  					Eventually(session.Out).Should(Say(`"disk": 64`))
   851  					Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
   852  					Eventually(session.Out).Should(Say(`User-Provided:
   853  BAR: child-app
   854  BAZ: parent-global
   855  FIZ: child-global
   856  FOO: child-app
   857  
   858  `))
   859  					Eventually(session).Should(Exit(0))
   860  				})
   861  			})
   862  
   863  			Context("when the app is a Docker app", func() {
   864  				BeforeEach(func() {
   865  					pushDockerWithManifests([]string{
   866  						fmt.Sprintf(`
   867  ---
   868  inherit: {some-parent}
   869  applications:
   870  - name: %s
   871    docker:
   872      image: child-application-image
   873  docker:
   874    image: child-global-image
   875  `, app1Name),
   876  						fmt.Sprintf(`
   877  ---
   878  docker:
   879    image: parent-image
   880  `),
   881  					})
   882  				})
   883  
   884  				It("pushes with child application docker image properties taking precedence", func() {
   885  					session := helpers.CF("app", app1Name)
   886  					Eventually(session.Out).Should(Say(`docker image:\s*child-application-image`))
   887  					Eventually(session).Should(Exit(0))
   888  				})
   889  			})
   890  		})
   891  
   892  		Context("when the child has applications and global properties; and the parent has applications properties", func() {
   893  			Context("when the app is a buildpack app", func() {
   894  				BeforeEach(func() {
   895  					pushHelloWorldAppWithManifests([]string{
   896  						fmt.Sprintf(`
   897  ---
   898  inherit: {some-parent}
   899  memory: %dM
   900  disk_quota: 128M
   901  path: {some-dir}
   902  routes:
   903  - route: child-global-1.%s
   904  - route: child-global-2.%s
   905  env:
   906    FOO: child-global
   907    FIZ: child-global
   908  applications:
   909  - name: %s
   910    disk_quota: 64M
   911    path: {some-dir}
   912    routes:
   913    - route: child-app-1.%s
   914    - route: child-app-2.%s
   915    env:
   916      BAR: child-app
   917      FOO: child-app
   918  - name: %s
   919    disk_quota: 64M
   920    path: {some-dir}
   921    routes:
   922    - route: child-app-1.%s
   923    - route: child-app-2.%s
   924    env:
   925      BAR: child-app
   926      FOO: child-app
   927  `, app1MemSize, domainName, domainName, app1Name, domainName, domainName, app2Name, domainName, domainName),
   928  						fmt.Sprintf(`
   929  ---
   930  buildpack: staticfile_buildpack
   931  applications:
   932  - name: %s
   933    memory: 256M
   934    disk_quota: 256M
   935    path: {some-dir}
   936    routes:
   937    - route: parent-app-1.%s
   938    - route: parent-app-2.%s
   939    env:
   940      BAR: parent-app
   941      FOO: parent-app
   942      FIZ: parent-app
   943      BAZ: parent-app
   944  - name: %s
   945    memory: 256M
   946    disk_quota: 256M
   947    path: {some-dir}
   948    routes:
   949    - route: parent-app-1.%s
   950    - route: parent-app-2.%s
   951    env:
   952      BAR: parent-app
   953      FOO: parent-app
   954      FIZ: parent-app
   955      BAZ: parent-app
   956  `, app1Name, domainName, domainName, app2Name, domainName, domainName),
   957  					})
   958  				})
   959  
   960  				It("pushes with child application taking precedence over child global over parent application", func() {
   961  					session := helpers.CF("env", app1Name)
   962  					Eventually(session.Out).Should(Say("OK"))
   963  					Eventually(session.Out).Should(Say(`"application_uris": \[
   964     "child-global-1\.%s",
   965     "child-global-2\.%s",
   966     "parent-app-1\.%s"\,
   967     "parent-app-2\.%s",
   968     "child-app-1\.%s",
   969     "child-app-2\.%s"
   970    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
   971  					Eventually(session.Out).Should(Say(`"disk": 64`))
   972  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   973  					Eventually(session.Out).Should(Say(`User-Provided:
   974  BAR: child-app
   975  BAZ: parent-app
   976  FIZ: child-global
   977  FOO: child-app
   978  
   979  `))
   980  					Eventually(session).Should(Exit(0))
   981  
   982  					session = helpers.CF("env", app2Name)
   983  					Eventually(session.Out).Should(Say("OK"))
   984  					Eventually(session.Out).Should(Say(`"application_uris": \[
   985     "child-global-1\.%s",
   986     "child-global-2\.%s",
   987     "parent-app-1\.%s"\,
   988     "parent-app-2\.%s",
   989     "child-app-1\.%s",
   990     "child-app-2\.%s"
   991    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
   992  					Eventually(session.Out).Should(Say(`"disk": 64`))
   993  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
   994  					Eventually(session.Out).Should(Say(`User-Provided:
   995  BAR: child-app
   996  BAZ: parent-app
   997  FIZ: child-global
   998  FOO: child-app
   999  
  1000  `))
  1001  					Eventually(session).Should(Exit(0))
  1002  				})
  1003  			})
  1004  
  1005  			Context("when the app is a Docker app", func() {
  1006  				BeforeEach(func() {
  1007  					pushDockerWithManifests([]string{
  1008  						fmt.Sprintf(`
  1009  ---
  1010  inherit: {some-parent}
  1011  applications:
  1012  - name: %s
  1013    docker:
  1014      image: child-application-image
  1015  docker:
  1016    image: child-global-image
  1017  `, app1Name),
  1018  						fmt.Sprintf(`
  1019  ---
  1020  applications:
  1021  - name: %s
  1022    docker:
  1023      image: %s
  1024  `, app1Name, DockerImage),
  1025  					})
  1026  				})
  1027  
  1028  				It("pushes with child application docker image properties taking precedence", func() {
  1029  					session := helpers.CF("app", app1Name)
  1030  					Eventually(session.Out).Should(Say(`docker image:\s*child-application-image`))
  1031  					Eventually(session).Should(Exit(0))
  1032  				})
  1033  			})
  1034  		})
  1035  
  1036  		Context("when the child has applications properties; and the parent has applications and global properties", func() {
  1037  			Context("when the app is a buildpack app", func() {
  1038  				BeforeEach(func() {
  1039  					pushHelloWorldAppWithManifests([]string{
  1040  						fmt.Sprintf(`
  1041  ---
  1042  inherit: {some-parent}
  1043  applications:
  1044  - name: %s
  1045    memory: %dM
  1046    disk_quota: 64M
  1047    path: {some-dir}
  1048    routes:
  1049    - route: child-app-1.%s
  1050    - route: child-app-2.%s
  1051    env:
  1052      BAR: child-app
  1053      FOO: child-app
  1054  - name: %s
  1055    memory: %dM
  1056    disk_quota: 64M
  1057    path: {some-dir}
  1058    routes:
  1059    - route: child-app-1.%s
  1060    - route: child-app-2.%s
  1061    env:
  1062      BAR: child-app
  1063      FOO: child-app
  1064  `, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
  1065  						fmt.Sprintf(`
  1066  ---
  1067  buildpack: staticfile_buildpack
  1068  memory: 128M
  1069  disk_quota: 128M
  1070  path: {some-dir}
  1071  routes:
  1072  - route: parent-global-1.%s
  1073  - route: parent-global-2.%s
  1074  env:
  1075    FOO: parent-global
  1076    FIZ: parent-global
  1077  applications:
  1078  - name: %s
  1079    memory: 256M
  1080    disk_quota: 256M
  1081    path: {some-dir}
  1082    routes:
  1083    - route: parent-app-1.%s
  1084    - route: parent-app-2.%s
  1085    env:
  1086      BAR: parent-app
  1087      FOO: parent-app
  1088      FIZ: parent-app
  1089      BAZ: parent-app
  1090  - name: %s
  1091    memory: 256M
  1092    disk_quota: 256M
  1093    path: {some-dir}
  1094    routes:
  1095    - route: parent-app-1.%s
  1096    - route: parent-app-2.%s
  1097    env:
  1098      BAR: parent-app
  1099      FOO: parent-app
  1100      FIZ: parent-app
  1101      BAZ: parent-app
  1102  `, domainName, domainName, app1Name, domainName, domainName, app2Name, domainName, domainName),
  1103  					})
  1104  				})
  1105  
  1106  				It("pushes with child application taking precedence over parent application over child global", func() {
  1107  					session := helpers.CF("env", app1Name)
  1108  					Eventually(session.Out).Should(Say("OK"))
  1109  					Eventually(session.Out).Should(Say(`"application_uris": \[
  1110     "parent-global-1\.%s",
  1111     "parent-global-2\.%s",
  1112     "parent-app-1\.%s"\,
  1113     "parent-app-2\.%s",
  1114     "child-app-1\.%s",
  1115     "child-app-2\.%s"
  1116    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
  1117  					Eventually(session.Out).Should(Say(`"disk": 64`))
  1118  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
  1119  					Eventually(session.Out).Should(Say(`User-Provided:
  1120  BAR: child-app
  1121  BAZ: parent-app
  1122  FIZ: parent-global
  1123  FOO: child-app
  1124  
  1125  `))
  1126  					Eventually(session).Should(Exit(0))
  1127  
  1128  					session = helpers.CF("env", app2Name)
  1129  					Eventually(session.Out).Should(Say("OK"))
  1130  					Eventually(session.Out).Should(Say(`"application_uris": \[
  1131     "parent-global-1\.%s",
  1132     "parent-global-2\.%s",
  1133     "parent-app-1\.%s"\,
  1134     "parent-app-2\.%s",
  1135     "child-app-1\.%s",
  1136     "child-app-2\.%s"
  1137    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
  1138  					Eventually(session.Out).Should(Say(`"disk": 64`))
  1139  					Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
  1140  					Eventually(session.Out).Should(Say(`User-Provided:
  1141  BAR: child-app
  1142  BAZ: parent-app
  1143  FIZ: parent-global
  1144  FOO: child-app
  1145  
  1146  `))
  1147  					Eventually(session).Should(Exit(0))
  1148  				})
  1149  			})
  1150  
  1151  			Context("when the app is a Docker app", func() {
  1152  				BeforeEach(func() {
  1153  					pushDockerWithManifests([]string{
  1154  						fmt.Sprintf(`
  1155  ---
  1156  inherit: {some-parent}
  1157  applications:
  1158  - name: %s
  1159    docker:
  1160      image: child-application-image
  1161  `, app1Name),
  1162  						fmt.Sprintf(`
  1163  ---
  1164  applications:
  1165  - name: %s
  1166    docker:
  1167      image: %s
  1168  docker:
  1169    image: %s
  1170  `, app1Name, DockerImage, DockerImage),
  1171  					})
  1172  				})
  1173  
  1174  				It("pushes with child application docker image properties taking precedence", func() {
  1175  					session := helpers.CF("app", app1Name)
  1176  					Eventually(session.Out).Should(Say(`docker image:\s*child-application-image`))
  1177  					Eventually(session).Should(Exit(0))
  1178  				})
  1179  			})
  1180  		})
  1181  
  1182  		Context("when the child has global properties; and the parent has applications and global properties", func() {
  1183  			Context("when the app is a buildpack app", func() {
  1184  				BeforeEach(func() {
  1185  					pushHelloWorldAppWithManifests([]string{
  1186  						fmt.Sprintf(`
  1187  ---
  1188  inherit: {some-parent}
  1189  memory: 128M
  1190  disk_quota: 128M
  1191  path: {some-dir}
  1192  routes:
  1193  - route: child-global-1.%s
  1194  - route: child-global-2.%s
  1195  env:
  1196    FOO: child-global
  1197    FIZ: child-global
  1198  `, domainName, domainName),
  1199  						fmt.Sprintf(`
  1200  ---
  1201  buildpack: staticfile_buildpack
  1202  routes:
  1203  - route: parent-global-1.%s
  1204  - route: parent-global-2.%s
  1205  env:
  1206    FIZ: parent-global
  1207    ZOOM: parent-global
  1208  applications:
  1209  - name: %s
  1210    memory: %dM
  1211    disk_quota: 256M
  1212    path: {some-dir}
  1213    routes:
  1214    - route: parent-app-1.%s
  1215    - route: parent-app-2.%s
  1216    env:
  1217      FOO: parent-app
  1218      BAZ: parent-app
  1219  - name: %s
  1220    memory: %dM
  1221    disk_quota: 256M
  1222    path: {some-dir}
  1223    routes:
  1224    - route: parent-app-1.%s
  1225    - route: parent-app-2.%s
  1226    env:
  1227      FOO: parent-app
  1228      BAZ: parent-app
  1229  `, domainName, domainName, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
  1230  					})
  1231  				})
  1232  
  1233  				It("pushes with parent application taking precedence over child global over parent global", func() {
  1234  					session := helpers.CF("env", app1Name)
  1235  					Eventually(session.Out).Should(Say("OK"))
  1236  					Eventually(session.Out).Should(Say(`"application_uris": \[
  1237     "parent-global-1\.%s",
  1238     "parent-global-2\.%s",
  1239     "child-global-1\.%s",
  1240     "child-global-2\.%s",
  1241     "parent-app-1\.%s"\,
  1242     "parent-app-2\.%s"
  1243    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
  1244  					Eventually(session.Out).Should(Say(`"disk": 256`))
  1245  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
  1246  					Eventually(session.Out).Should(Say(`User-Provided:
  1247  BAZ: parent-app
  1248  FIZ: child-global
  1249  FOO: parent-app
  1250  ZOOM: parent-global
  1251  
  1252  `))
  1253  					Eventually(session).Should(Exit(0))
  1254  
  1255  					session = helpers.CF("env", app2Name)
  1256  					Eventually(session.Out).Should(Say("OK"))
  1257  					Eventually(session.Out).Should(Say(`"application_uris": \[
  1258     "parent-global-1\.%s",
  1259     "parent-global-2\.%s",
  1260     "child-global-1\.%s",
  1261     "child-global-2\.%s",
  1262     "parent-app-1\.%s"\,
  1263     "parent-app-2\.%s"
  1264    \]`, domainName, domainName, domainName, domainName, domainName, domainName))
  1265  					Eventually(session.Out).Should(Say(`"disk": 256`))
  1266  					Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
  1267  					Eventually(session.Out).Should(Say(`User-Provided:
  1268  BAZ: parent-app
  1269  FIZ: child-global
  1270  FOO: parent-app
  1271  ZOOM: parent-global
  1272  
  1273  `))
  1274  					Eventually(session).Should(Exit(0))
  1275  				})
  1276  			})
  1277  
  1278  			Context("when the app is a Docker app", func() {
  1279  				BeforeEach(func() {
  1280  					pushDockerWithManifests([]string{
  1281  						fmt.Sprintf(`
  1282  ---
  1283  inherit: {some-parent}
  1284  docker:
  1285    image: child-global-image
  1286  `),
  1287  						fmt.Sprintf(`
  1288  ---
  1289  applications:
  1290  - name: %s
  1291    docker:
  1292      image: parent-application-image
  1293  docker:
  1294    image: parent-global-image
  1295  `, app1Name),
  1296  					})
  1297  				})
  1298  
  1299  				It("pushes with parent application docker image properties taking precedence", func() {
  1300  					session := helpers.CF("app", app1Name)
  1301  					Eventually(session.Out).Should(Say(`docker image:\s*parent-application-image`))
  1302  					Eventually(session).Should(Exit(0))
  1303  				})
  1304  			})
  1305  		})
  1306  
  1307  		Context("when the child has applications and global properties; and the parent has applications and global properties", func() {
  1308  			Context("when the app is a buildpack app", func() {
  1309  				BeforeEach(func() {
  1310  					pushHelloWorldAppWithManifests([]string{
  1311  						fmt.Sprintf(`
  1312  ---
  1313  inherit: {some-parent}
  1314  instances: 2
  1315  memory: 128M
  1316  path: {some-dir}
  1317  routes:
  1318  - route: child-global-1.%s
  1319  - route: child-global-2.%s
  1320  env:
  1321    FOO: child-global
  1322    FIZ: child-global
  1323  applications:
  1324  - name: %s
  1325    memory: %dM
  1326    disk_quota: 64M
  1327    path: {some-dir}
  1328    routes:
  1329    - route: child-app-1.%s
  1330    - route: child-app-2.%s
  1331    env:
  1332      FOO: child-app
  1333      BAR: child-app
  1334  - name: %s
  1335    memory: %dM
  1336    disk_quota: 64M
  1337    path: {some-dir}
  1338    routes:
  1339    - route: child-app-1.%s
  1340    - route: child-app-2.%s
  1341    env:
  1342      FOO: child-app
  1343      BAR: child-app
  1344  `, domainName, domainName, app1Name, app1MemSize, domainName, domainName, app2Name, app2MemSize, domainName, domainName),
  1345  						fmt.Sprintf(`
  1346  ---
  1347  buildpack: staticfile_buildpack
  1348  memory: 256M
  1349  disk_quota: 256M
  1350  path: {some-dir}
  1351  routes:
  1352  - route: parent-global-1.%s
  1353  - route: parent-global-2.%s
  1354  env:
  1355    FIZ: parent-global
  1356    ZOOM: parent-global
  1357  applications:
  1358  - name: %s
  1359    memory: 256M
  1360    disk_quota: 256M
  1361    path: {some-dir}
  1362    routes:
  1363    - route: parent-app-1.%s
  1364    - route: parent-app-2.%s
  1365    env:
  1366      FIZ: parent-app
  1367      BAZ: parent-app
  1368  - name: %s
  1369    memory: 256M
  1370    disk_quota: 256M
  1371    path: {some-dir}
  1372    routes:
  1373    - route: parent-app-1.%s
  1374    - route: parent-app-2.%s
  1375    env:
  1376      FIZ: parent-app
  1377      BAZ: parent-app
  1378  `, domainName, domainName, app1Name, domainName, domainName, app2Name, domainName, domainName),
  1379  					})
  1380  				})
  1381  
  1382  				It("pushes with parent application taking precedence over child global", func() {
  1383  					session := helpers.CF("app", app1Name)
  1384  					Eventually(session.Out).Should(Say("instances.*2"))
  1385  					Eventually(session).Should(Exit(0))
  1386  
  1387  					session = helpers.CF("env", app1Name)
  1388  					Eventually(session.Out).Should(Say("OK"))
  1389  					Eventually(session.Out).Should(Say(`"application_uris": \[
  1390     "parent-global-1\.%s",
  1391     "parent-global-2\.%s",
  1392     "child-global-1\.%s",
  1393     "child-global-2\.%s",
  1394     "parent-app-1\.%s"\,
  1395     "parent-app-2\.%s",
  1396     "child-app-1\.%s"\,
  1397     "child-app-2\.%s"
  1398    \]`, domainName, domainName, domainName, domainName, domainName, domainName, domainName, domainName))
  1399  					Eventually(session.Out).Should(Say(`"disk": 64`))
  1400  					Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
  1401  					Eventually(session.Out).Should(Say(`User-Provided:
  1402  BAR: child-app
  1403  BAZ: parent-app
  1404  FIZ: child-global
  1405  FOO: child-app
  1406  ZOOM: parent-global
  1407  
  1408  `))
  1409  					Eventually(session).Should(Exit(0))
  1410  
  1411  					session = helpers.CF("app", app2Name)
  1412  					Eventually(session.Out).Should(Say("instances.*2"))
  1413  					Eventually(session).Should(Exit(0))
  1414  
  1415  					session = helpers.CF("env", app2Name)
  1416  					Eventually(session.Out).Should(Say("OK"))
  1417  					Eventually(session.Out).Should(Say(`"application_uris": \[
  1418     "parent-global-1\.%s",
  1419     "parent-global-2\.%s",
  1420     "child-global-1\.%s",
  1421     "child-global-2\.%s",
  1422     "parent-app-1\.%s"\,
  1423     "parent-app-2\.%s",
  1424     "child-app-1\.%s"\,
  1425     "child-app-2\.%s"
  1426    \]`, domainName, domainName, domainName, domainName, domainName, domainName, domainName, domainName))
  1427  					Eventually(session.Out).Should(Say(`"disk": 64`))
  1428  					Eventually(session.Out).Should(Say(`"mem": %d`, app2MemSize))
  1429  					Eventually(session.Out).Should(Say(`User-Provided:
  1430  BAR: child-app
  1431  BAZ: parent-app
  1432  FIZ: child-global
  1433  FOO: child-app
  1434  ZOOM: parent-global
  1435  
  1436  `))
  1437  					Eventually(session).Should(Exit(0))
  1438  				})
  1439  			})
  1440  
  1441  			Context("when the app is a Docker app", func() {
  1442  				BeforeEach(func() {
  1443  					pushDockerWithManifests([]string{
  1444  						fmt.Sprintf(`
  1445  ---
  1446  inherit: {some-parent}
  1447  applications:
  1448  - name: %s
  1449    docker:
  1450      image: child-application-image
  1451  docker:
  1452    image: child-global-image
  1453  `, app1Name),
  1454  						fmt.Sprintf(`
  1455  ---
  1456  applications:
  1457  - name: %s
  1458    docker:
  1459      image: %s
  1460  docker:
  1461    image: %s
  1462  `, app1Name, DockerImage, DockerImage),
  1463  					})
  1464  				})
  1465  
  1466  				It("pushes with child application docker image properties taking precedence", func() {
  1467  					session := helpers.CF("app", app1Name)
  1468  					Eventually(session.Out).Should(Say(`docker image:\s*child-application-image`))
  1469  					Eventually(session).Should(Exit(0))
  1470  				})
  1471  			})
  1472  		})
  1473  	})
  1474  
  1475  	Context("when there are 3 manifests", func() {
  1476  		Context("when super-parent has globals, parent has globals, and child has app and globals", func() {
  1477  			BeforeEach(func() {
  1478  				pushHelloWorldAppWithManifests([]string{
  1479  					fmt.Sprintf(`
  1480  ---
  1481  inherit: {some-parent}
  1482  memory: %dM
  1483  path: {some-dir}
  1484  routes:
  1485  - route: child-global-1.%s
  1486  - route: child-global-2.%s
  1487  env:
  1488    FOO: child-global
  1489    FIZ: child-global
  1490  applications:
  1491  - name: %s
  1492    disk_quota: 64M
  1493    path: {some-dir}
  1494    routes:
  1495    - route: child-app-1.%s
  1496    - route: child-app-2.%s
  1497    env:
  1498      FOO: child-app
  1499      BAR: child-app
  1500  - name: %s
  1501    disk_quota: 64M
  1502    path: {some-dir}
  1503    routes:
  1504    - route: child-app-1.%s
  1505    - route: child-app-2.%s
  1506    env:
  1507      FOO: child-app
  1508      BAR: child-app
  1509  `, app1MemSize, domainName, domainName, app1Name, domainName, domainName, app2Name, domainName, domainName),
  1510  					fmt.Sprintf(`
  1511  ---
  1512  inherit: {some-parent}
  1513  instances: 2
  1514  memory: 256M
  1515  disk_quota: 256M
  1516  path: {some-dir}
  1517  routes:
  1518  - route: parent-global-1.%s
  1519  - route: parent-global-2.%s
  1520  env:
  1521    ZOOM: parent-global
  1522    FIZ: parent-global
  1523  `, domainName, domainName),
  1524  					fmt.Sprintf(`
  1525  ---
  1526  buildpack: staticfile_buildpack
  1527  memory: 512M
  1528  disk_quota: 512M
  1529  path: {some-dir}
  1530  routes:
  1531  - route: super-parent-global-1.%s
  1532  - route: super-parent-global-2.%s
  1533  env:
  1534    MOON: super-parent-global
  1535    ZOOM: super-parent-global
  1536  `, domainName, domainName),
  1537  				})
  1538  			})
  1539  
  1540  			It("pushes with child application taking precedence over child global over parent global over super-parent global", func() {
  1541  				session := helpers.CF("app", app1Name)
  1542  				Eventually(session.Out).Should(Say("instances.*2"))
  1543  				Eventually(session).Should(Exit(0))
  1544  
  1545  				session = helpers.CF("env", app1Name)
  1546  				Eventually(session.Out).Should(Say("OK"))
  1547  				Eventually(session.Out).Should(Say(`"application_uris": \[
  1548     "super-parent-global-1\.%s",
  1549     "super-parent-global-2\.%s",
  1550     "parent-global-1\.%s",
  1551     "parent-global-2\.%s",
  1552     "child-global-1\.%s",
  1553     "child-global-2\.%s",
  1554     "child-app-1\.%s"\,
  1555     "child-app-2\.%s"
  1556    \]`, domainName, domainName, domainName, domainName, domainName, domainName, domainName, domainName))
  1557  				Eventually(session.Out).Should(Say(`"disk": 64`))
  1558  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
  1559  				Eventually(session.Out).Should(Say(`User-Provided:
  1560  BAR: child-app
  1561  FIZ: child-global
  1562  FOO: child-app
  1563  MOON: super-parent-global
  1564  ZOOM: parent-global
  1565  
  1566  `))
  1567  				Eventually(session).Should(Exit(0))
  1568  
  1569  				session = helpers.CF("app", app2Name)
  1570  				Eventually(session.Out).Should(Say("instances.*2"))
  1571  
  1572  				session = helpers.CF("env", app2Name)
  1573  				Eventually(session.Out).Should(Say("OK"))
  1574  				Eventually(session.Out).Should(Say(`"application_uris": \[
  1575     "super-parent-global-1\.%s",
  1576     "super-parent-global-2\.%s",
  1577     "parent-global-1\.%s",
  1578     "parent-global-2\.%s",
  1579     "child-global-1\.%s",
  1580     "child-global-2\.%s",
  1581     "child-app-1\.%s"\,
  1582     "child-app-2\.%s"
  1583    \]`, domainName, domainName, domainName, domainName, domainName, domainName, domainName, domainName))
  1584  				Eventually(session.Out).Should(Say(`"disk": 64`))
  1585  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
  1586  				Eventually(session.Out).Should(Say(`User-Provided:
  1587  BAR: child-app
  1588  FIZ: child-global
  1589  FOO: child-app
  1590  MOON: super-parent-global
  1591  ZOOM: parent-global
  1592  
  1593  `))
  1594  				Eventually(session).Should(Exit(0))
  1595  			})
  1596  		})
  1597  
  1598  		Context("when super-parent has globals, parent has app and globals, and child has globals", func() {
  1599  			BeforeEach(func() {
  1600  				pushHelloWorldAppWithManifests([]string{
  1601  					fmt.Sprintf(`
  1602  ---
  1603  inherit: {some-parent}
  1604  memory: %dM
  1605  path: {some-dir}
  1606  routes:
  1607  - route: child-global-1.%s
  1608  - route: child-global-2.%s
  1609  env:
  1610    FOO: child-global
  1611    FIZ: child-global
  1612    JUNE: child-global
  1613  `, app1MemSize, domainName, domainName),
  1614  					fmt.Sprintf(`
  1615  ---
  1616  inherit: {some-parent}
  1617  instances: 2
  1618  memory: 256M
  1619  disk_quota: 256M
  1620  path: {some-dir}
  1621  routes:
  1622  - route: parent-global-1.%s
  1623  - route: parent-global-2.%s
  1624  env:
  1625    ZOOM: parent-global
  1626    FIZ: parent-global
  1627  applications:
  1628  - name: %s
  1629    disk_quota: 64M
  1630    path: {some-dir}
  1631    routes:
  1632    - route: parent-app-1.%s
  1633    - route: parent-app-2.%s
  1634    env:
  1635      FOO: parent-app
  1636      BAR: parent-app
  1637  - name: %s
  1638    disk_quota: 64M
  1639    path: {some-dir}
  1640    routes:
  1641    - route: parent-app-1.%s
  1642    - route: parent-app-2.%s
  1643    env:
  1644      FOO: parent-app
  1645      BAR: parent-app
  1646  `, domainName, domainName, app1Name, domainName, domainName, app2Name, domainName, domainName),
  1647  					fmt.Sprintf(`
  1648  ---
  1649  buildpack: staticfile_buildpack
  1650  memory: 512M
  1651  disk_quota: 512M
  1652  path: {some-dir}
  1653  routes:
  1654  - route: super-parent-global-1.%s
  1655  - route: super-parent-global-2.%s
  1656  env:
  1657    MOON: super-parent-global
  1658    ZOOM: super-parent-global
  1659    JUNE: super-parent-global
  1660  `, domainName, domainName),
  1661  				})
  1662  			})
  1663  
  1664  			It("pushes with child application taking precedence over child global over parent global over super-parent global", func() {
  1665  				session := helpers.CF("app", app1Name)
  1666  				Eventually(session.Out).Should(Say("instances.*2"))
  1667  				Eventually(session).Should(Exit(0))
  1668  
  1669  				session = helpers.CF("env", app1Name)
  1670  				Eventually(session.Out).Should(Say("OK"))
  1671  				Eventually(session.Out).Should(Say(`"application_uris": \[
  1672     "super-parent-global-1\.%s",
  1673     "super-parent-global-2\.%s",
  1674     "parent-global-1\.%s",
  1675     "parent-global-2\.%s",
  1676     "child-global-1\.%s",
  1677     "child-global-2\.%s",
  1678     "parent-app-1\.%s"\,
  1679     "parent-app-2\.%s"
  1680    \]`, domainName, domainName, domainName, domainName, domainName, domainName, domainName, domainName))
  1681  				Eventually(session.Out).Should(Say(`"disk": 64`))
  1682  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
  1683  				Eventually(session.Out).Should(Say(`User-Provided:
  1684  BAR: parent-app
  1685  FIZ: child-global
  1686  FOO: parent-app
  1687  JUNE: child-global
  1688  MOON: super-parent-global
  1689  ZOOM: parent-global
  1690  
  1691  `))
  1692  				Eventually(session).Should(Exit(0))
  1693  
  1694  				session = helpers.CF("app", app1Name)
  1695  				Eventually(session.Out).Should(Say("instances.*2"))
  1696  				Eventually(session).Should(Exit(0))
  1697  
  1698  				session = helpers.CF("env", app2Name)
  1699  				Eventually(session.Out).Should(Say("OK"))
  1700  				Eventually(session.Out).Should(Say(`"application_uris": \[
  1701     "super-parent-global-1\.%s",
  1702     "super-parent-global-2\.%s",
  1703     "parent-global-1\.%s",
  1704     "parent-global-2\.%s",
  1705     "child-global-1\.%s",
  1706     "child-global-2\.%s",
  1707     "parent-app-1\.%s"\,
  1708     "parent-app-2\.%s"
  1709    \]`, domainName, domainName, domainName, domainName, domainName, domainName, domainName, domainName))
  1710  				Eventually(session.Out).Should(Say(`"disk": 64`))
  1711  				Eventually(session.Out).Should(Say(`"mem": %d`, app1MemSize))
  1712  				Eventually(session.Out).Should(Say(`User-Provided:
  1713  BAR: parent-app
  1714  FIZ: child-global
  1715  FOO: parent-app
  1716  JUNE: child-global
  1717  MOON: super-parent-global
  1718  ZOOM: parent-global
  1719  
  1720  `))
  1721  				Eventually(session).Should(Exit(0))
  1722  			})
  1723  		})
  1724  	})
  1725  })