github.com/cloudfoundry/cli@v7.1.0+incompatible/actor/pushaction/application_config_test.go (about)

     1  package pushaction_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"code.cloudfoundry.org/cli/actor/actionerror"
    11  	. "code.cloudfoundry.org/cli/actor/pushaction"
    12  	"code.cloudfoundry.org/cli/actor/pushaction/pushactionfakes"
    13  	"code.cloudfoundry.org/cli/actor/sharedaction"
    14  	"code.cloudfoundry.org/cli/actor/v2action"
    15  	"code.cloudfoundry.org/cli/actor/v3action"
    16  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
    17  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant"
    18  	"code.cloudfoundry.org/cli/types"
    19  	"code.cloudfoundry.org/cli/util/manifest"
    20  	. "github.com/onsi/ginkgo"
    21  	. "github.com/onsi/gomega"
    22  	. "github.com/onsi/gomega/gstruct"
    23  )
    24  
    25  var _ = Describe("Application Config", func() {
    26  	var (
    27  		actor                   *Actor
    28  		fakeV2Actor             *pushactionfakes.FakeV2Actor
    29  		fakeV3Actor             *pushactionfakes.FakeV3Actor
    30  		fakeSharedActor         *pushactionfakes.FakeSharedActor
    31  		fakeRandomWordGenerator *pushactionfakes.FakeRandomWordGenerator
    32  	)
    33  
    34  	BeforeEach(func() {
    35  		actor, fakeV2Actor, fakeV3Actor, fakeSharedActor = getTestPushActor()
    36  
    37  		fakeRandomWordGenerator = new(pushactionfakes.FakeRandomWordGenerator)
    38  		actor.WordGenerator = fakeRandomWordGenerator
    39  	})
    40  
    41  	Describe("ApplicationConfig", func() {
    42  		Describe("CreatingApplication", func() {
    43  			When("the app did not exist", func() {
    44  				It("returns true", func() {
    45  					config := ApplicationConfig{}
    46  					Expect(config.CreatingApplication()).To(BeTrue())
    47  				})
    48  			})
    49  
    50  			When("the app exists", func() {
    51  				It("returns false", func() {
    52  					config := ApplicationConfig{CurrentApplication: Application{Application: v2action.Application{GUID: "some-app-guid"}}}
    53  					Expect(config.CreatingApplication()).To(BeFalse())
    54  				})
    55  			})
    56  		})
    57  
    58  		Describe("UpdatedApplication", func() {
    59  			When("the app did not exist", func() {
    60  				It("returns false", func() {
    61  					config := ApplicationConfig{}
    62  					Expect(config.UpdatingApplication()).To(BeFalse())
    63  				})
    64  			})
    65  
    66  			When("the app exists", func() {
    67  				It("returns true", func() {
    68  					config := ApplicationConfig{CurrentApplication: Application{Application: v2action.Application{GUID: "some-app-guid"}}}
    69  					Expect(config.UpdatingApplication()).To(BeTrue())
    70  				})
    71  			})
    72  		})
    73  	})
    74  
    75  	Describe("ConvertToApplicationConfigs", func() {
    76  		var (
    77  			appName   string
    78  			domain    v2action.Domain
    79  			filesPath string
    80  
    81  			orgGUID      string
    82  			spaceGUID    string
    83  			noStart      bool
    84  			manifestApps []manifest.Application
    85  
    86  			configs    []ApplicationConfig
    87  			warnings   Warnings
    88  			executeErr error
    89  
    90  			firstConfig ApplicationConfig
    91  		)
    92  
    93  		BeforeEach(func() {
    94  			appName = "some-app"
    95  			orgGUID = "some-org-guid"
    96  			spaceGUID = "some-space-guid"
    97  			noStart = false
    98  
    99  			var err error
   100  			filesPath, err = ioutil.TempDir("", "convert-to-application-configs")
   101  			Expect(err).ToNot(HaveOccurred())
   102  
   103  			// The temp directory created on OSX contains a symlink and needs to be evaluated.
   104  			filesPath, err = filepath.EvalSymlinks(filesPath)
   105  			Expect(err).ToNot(HaveOccurred())
   106  
   107  			manifestApps = []manifest.Application{{
   108  				Name: appName,
   109  				Path: filesPath,
   110  			}}
   111  
   112  			domain = v2action.Domain{
   113  				Name: "private-domain.com",
   114  				GUID: "some-private-domain-guid",
   115  			}
   116  
   117  			// Prevents NoDomainsFoundError
   118  			fakeV2Actor.GetOrganizationDomainsReturns(
   119  				[]v2action.Domain{domain},
   120  				v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"},
   121  				nil,
   122  			)
   123  		})
   124  
   125  		JustBeforeEach(func() {
   126  			configs, warnings, executeErr = actor.ConvertToApplicationConfigs(orgGUID, spaceGUID, noStart, manifestApps)
   127  			if len(configs) > 0 {
   128  				firstConfig = configs[0]
   129  			}
   130  		})
   131  
   132  		AfterEach(func() {
   133  			Expect(os.RemoveAll(filesPath)).ToNot(HaveOccurred())
   134  		})
   135  
   136  		When("the path is a symlink", func() {
   137  			var target string
   138  
   139  			BeforeEach(func() {
   140  				parentDir := filepath.Dir(filesPath)
   141  				target = filepath.Join(parentDir, fmt.Sprintf("i-r-symlink%d", GinkgoParallelNode()))
   142  				Expect(os.Symlink(filesPath, target)).To(Succeed())
   143  				manifestApps[0].Path = target
   144  			})
   145  
   146  			AfterEach(func() {
   147  				Expect(os.RemoveAll(target)).ToNot(HaveOccurred())
   148  			})
   149  
   150  			It("evaluates the symlink into an absolute path", func() {
   151  				Expect(executeErr).ToNot(HaveOccurred())
   152  
   153  				Expect(firstConfig.Path).To(Equal(filesPath))
   154  			})
   155  
   156  			Context("given a path that does not exist", func() {
   157  				BeforeEach(func() {
   158  					manifestApps[0].Path = "/i/will/fight/you/if/this/exists"
   159  				})
   160  
   161  				It("returns errors and warnings", func() {
   162  					Expect(os.IsNotExist(executeErr)).To(BeTrue())
   163  
   164  					Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(0))
   165  					Expect(fakeSharedActor.GatherArchiveResourcesCallCount()).To(Equal(0))
   166  				})
   167  			})
   168  		})
   169  
   170  		When("the application exists", func() {
   171  			var app Application
   172  			var route v2action.Route
   173  
   174  			BeforeEach(func() {
   175  				app = Application{
   176  					Application: v2action.Application{
   177  						Name:      appName,
   178  						GUID:      "some-app-guid",
   179  						SpaceGUID: spaceGUID,
   180  					}}
   181  
   182  				route = v2action.Route{
   183  					Domain: v2action.Domain{
   184  						Name: "some-domain.com",
   185  						GUID: "some-domain-guid",
   186  					},
   187  					Host:      app.Name,
   188  					GUID:      "route-guid",
   189  					SpaceGUID: spaceGUID,
   190  				}
   191  
   192  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(app.Application, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, nil)
   193  			})
   194  
   195  			When("there is an existing route and retrieving the route(s) is successful", func() {
   196  				BeforeEach(func() {
   197  					fakeV2Actor.GetApplicationRoutesReturns([]v2action.Route{route}, v2action.Warnings{"app-route-warnings"}, nil)
   198  				})
   199  
   200  				When("retrieving the application's services is successful", func() {
   201  					var services []v2action.ServiceInstance
   202  
   203  					BeforeEach(func() {
   204  						services = []v2action.ServiceInstance{
   205  							{Name: "service-1", GUID: "service-instance-1"},
   206  							{Name: "service-2", GUID: "service-instance-2"},
   207  						}
   208  
   209  						fakeV2Actor.GetServiceInstancesByApplicationReturns(services, v2action.Warnings{"service-instance-warning-1", "service-instance-warning-2"}, nil)
   210  					})
   211  
   212  					It("return warnings", func() {
   213  						Expect(executeErr).ToNot(HaveOccurred())
   214  						Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "app-route-warnings", "service-instance-warning-1", "service-instance-warning-2"))
   215  					})
   216  
   217  					It("sets the current application to the existing application", func() {
   218  						Expect(firstConfig.CurrentApplication).To(Equal(app))
   219  
   220  						Expect(fakeV2Actor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1))
   221  						passedName, passedSpaceGUID := fakeV2Actor.GetApplicationByNameAndSpaceArgsForCall(0)
   222  						Expect(passedName).To(Equal(app.Name))
   223  						Expect(passedSpaceGUID).To(Equal(spaceGUID))
   224  					})
   225  
   226  					It("sets the current routes", func() {
   227  						Expect(firstConfig.CurrentRoutes).To(ConsistOf(route))
   228  
   229  						Expect(fakeV2Actor.GetApplicationRoutesCallCount()).To(Equal(1))
   230  						Expect(fakeV2Actor.GetApplicationRoutesArgsForCall(0)).To(Equal(app.GUID))
   231  					})
   232  
   233  					It("sets the bound services", func() {
   234  						Expect(firstConfig.CurrentServices).To(Equal(map[string]v2action.ServiceInstance{
   235  							"service-1": v2action.ServiceInstance{Name: "service-1", GUID: "service-instance-1"},
   236  							"service-2": v2action.ServiceInstance{Name: "service-2", GUID: "service-instance-2"},
   237  						}))
   238  
   239  						Expect(fakeV2Actor.GetServiceInstancesByApplicationCallCount()).To(Equal(1))
   240  						Expect(fakeV2Actor.GetServiceInstancesByApplicationArgsForCall(0)).To(Equal("some-app-guid"))
   241  					})
   242  				})
   243  
   244  				When("retrieving the application's services errors", func() {
   245  					var expectedErr error
   246  
   247  					BeforeEach(func() {
   248  						expectedErr = errors.New("dios mio")
   249  						fakeV2Actor.GetServiceInstancesByApplicationReturns(nil, v2action.Warnings{"service-instance-warning-1", "service-instance-warning-2"}, expectedErr)
   250  					})
   251  
   252  					It("returns the error and warnings", func() {
   253  						Expect(executeErr).To(MatchError(expectedErr))
   254  						Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "app-route-warnings", "service-instance-warning-1", "service-instance-warning-2"))
   255  					})
   256  				})
   257  
   258  				When("the --random-route flag is provided", func() {
   259  					BeforeEach(func() {
   260  						manifestApps[0].RandomRoute = true
   261  					})
   262  
   263  					It("does not generate a random route", func() {
   264  						Expect(executeErr).ToNot(HaveOccurred())
   265  						Expect(warnings).To(ConsistOf(
   266  							"some-app-warning-1",
   267  							"some-app-warning-2",
   268  							"app-route-warnings",
   269  						))
   270  						Expect(firstConfig.DesiredRoutes).To(ConsistOf(route))
   271  
   272  						Expect(fakeV2Actor.GetOrganizationDomainsCallCount()).To(Equal(0))
   273  					})
   274  				})
   275  			})
   276  
   277  			When("there is not an existing route and no errors are encountered", func() {
   278  				BeforeEach(func() {
   279  					fakeV2Actor.GetApplicationRoutesReturns(nil, v2action.Warnings{"app-route-warnings"}, nil)
   280  				})
   281  
   282  				When("the --random-route flag is provided", func() {
   283  					BeforeEach(func() {
   284  						manifestApps[0].RandomRoute = true
   285  						fakeRandomWordGenerator.RandomAdjectiveReturns("striped")
   286  						fakeRandomWordGenerator.RandomNounReturns("apple")
   287  					})
   288  
   289  					It("appends a random route to the current route for desired routes", func() {
   290  						Expect(executeErr).ToNot(HaveOccurred())
   291  						Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "app-route-warnings", "private-domain-warnings", "shared-domain-warnings"))
   292  						Expect(firstConfig.DesiredRoutes).To(ConsistOf(
   293  							v2action.Route{
   294  								Domain:    domain,
   295  								SpaceGUID: spaceGUID,
   296  								Host:      "some-app-striped-apple",
   297  							},
   298  						))
   299  					})
   300  				})
   301  			})
   302  
   303  			When("retrieving the application's routes errors", func() {
   304  				var expectedErr error
   305  
   306  				BeforeEach(func() {
   307  					expectedErr = errors.New("dios mio")
   308  					fakeV2Actor.GetApplicationRoutesReturns(nil, v2action.Warnings{"app-route-warnings"}, expectedErr)
   309  				})
   310  
   311  				It("returns the error and warnings", func() {
   312  					Expect(executeErr).To(MatchError(expectedErr))
   313  					Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "app-route-warnings"))
   314  				})
   315  			})
   316  		})
   317  
   318  		When("the application does not exist", func() {
   319  			BeforeEach(func() {
   320  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, actionerror.ApplicationNotFoundError{})
   321  			})
   322  
   323  			It("creates a new application and sets it to the desired application", func() {
   324  				Expect(executeErr).ToNot(HaveOccurred())
   325  				Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "private-domain-warnings", "shared-domain-warnings"))
   326  				Expect(firstConfig.CurrentApplication).To(Equal(Application{Application: v2action.Application{}}))
   327  				Expect(firstConfig.DesiredApplication).To(Equal(Application{
   328  					Application: v2action.Application{
   329  						Name:      appName,
   330  						SpaceGUID: spaceGUID,
   331  					}}))
   332  			})
   333  
   334  			When("the --random-route flag is provided", func() {
   335  				BeforeEach(func() {
   336  					manifestApps[0].RandomRoute = true
   337  					fakeRandomWordGenerator.RandomAdjectiveReturns("striped")
   338  					fakeRandomWordGenerator.RandomNounReturns("apple")
   339  				})
   340  
   341  				It("appends a random route to the current route for desired routes", func() {
   342  					Expect(executeErr).ToNot(HaveOccurred())
   343  					Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "private-domain-warnings", "shared-domain-warnings"))
   344  					Expect(firstConfig.DesiredRoutes).To(ConsistOf(
   345  						v2action.Route{
   346  							Domain:    domain,
   347  							SpaceGUID: spaceGUID,
   348  							Host:      "some-app-striped-apple",
   349  						},
   350  					))
   351  				})
   352  
   353  				When("the -d flag is provided", func() {
   354  					When("the domain is an http domain", func() {
   355  						var httpDomain v2action.Domain
   356  
   357  						BeforeEach(func() {
   358  							httpDomain = v2action.Domain{
   359  								Name: "some-http-domain.com",
   360  							}
   361  
   362  							manifestApps[0].Domain = "some-http-domain.com"
   363  							fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{httpDomain}, v2action.Warnings{"domain-warnings-1", "domain-warnings-2"}, nil)
   364  							fakeRandomWordGenerator.RandomAdjectiveReturns("striped")
   365  							fakeRandomWordGenerator.RandomNounReturns("apple")
   366  						})
   367  
   368  						It("appends a random HTTP route to the desired routes", func() {
   369  							Expect(executeErr).ToNot(HaveOccurred())
   370  							Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "domain-warnings-1", "domain-warnings-2"))
   371  							Expect(firstConfig.DesiredRoutes).To(ConsistOf(
   372  								v2action.Route{
   373  									Host:      "some-app-striped-apple",
   374  									Domain:    httpDomain,
   375  									SpaceGUID: spaceGUID,
   376  								},
   377  							))
   378  						})
   379  					})
   380  
   381  					When("the domain is a tcp domain", func() {
   382  						var tcpDomain v2action.Domain
   383  						BeforeEach(func() {
   384  							tcpDomain = v2action.Domain{
   385  								Name:            "some-tcp-domain.com",
   386  								RouterGroupType: constant.TCPRouterGroup,
   387  							}
   388  
   389  							manifestApps[0].Domain = "some-tcp-domain.com"
   390  							fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{tcpDomain}, v2action.Warnings{"domain-warnings-1", "domain-warnings-2"}, nil)
   391  						})
   392  
   393  						It("appends a random TCP route to the desired routes", func() {
   394  							Expect(executeErr).ToNot(HaveOccurred())
   395  							Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "domain-warnings-1", "domain-warnings-2"))
   396  							Expect(firstConfig.DesiredRoutes).To(ConsistOf(
   397  								v2action.Route{
   398  									Domain:    tcpDomain,
   399  									SpaceGUID: spaceGUID,
   400  									Port:      types.NullInt{IsSet: false},
   401  								},
   402  							))
   403  						})
   404  					})
   405  				})
   406  			})
   407  		})
   408  
   409  		When("retrieving the application errors", func() {
   410  			var expectedErr error
   411  
   412  			BeforeEach(func() {
   413  				expectedErr = errors.New("dios mio")
   414  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, expectedErr)
   415  			})
   416  
   417  			It("returns the error and warnings", func() {
   418  				Expect(executeErr).To(MatchError(expectedErr))
   419  				Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2"))
   420  			})
   421  		})
   422  
   423  		When("overriding application properties", func() {
   424  			var stack v2action.Stack
   425  
   426  			When("the manifest contains all the properties", func() {
   427  				BeforeEach(func() {
   428  					manifestApps[0].Buildpack = types.FilteredString{IsSet: true, Value: "some-buildpack"}
   429  					manifestApps[0].Command = types.FilteredString{IsSet: true, Value: "some-command"}
   430  					manifestApps[0].DockerImage = "some-docker-image"
   431  					manifestApps[0].DockerUsername = "some-docker-username"
   432  					manifestApps[0].DockerPassword = "some-docker-password"
   433  					manifestApps[0].HealthCheckTimeout = 5
   434  					manifestApps[0].Instances = types.NullInt{Value: 1, IsSet: true}
   435  					manifestApps[0].DiskQuota = types.NullByteSizeInMb{Value: 2, IsSet: true}
   436  					manifestApps[0].Memory = types.NullByteSizeInMb{Value: 3, IsSet: true}
   437  					manifestApps[0].StackName = "some-stack"
   438  					manifestApps[0].EnvironmentVariables = map[string]string{
   439  						"env1": "1",
   440  						"env3": "3",
   441  					}
   442  
   443  					stack = v2action.Stack{
   444  						Name: "some-stack",
   445  						GUID: "some-stack-guid",
   446  					}
   447  
   448  					fakeV2Actor.GetStackByNameReturns(stack, v2action.Warnings{"some-stack-warning"}, nil)
   449  				})
   450  
   451  				It("overrides the current application properties", func() {
   452  					Expect(warnings).To(ConsistOf("some-stack-warning", "private-domain-warnings", "shared-domain-warnings"))
   453  
   454  					Expect(firstConfig.DesiredApplication).To(MatchFields(IgnoreExtras, Fields{
   455  						"Application": MatchFields(IgnoreExtras, Fields{
   456  							"Command":     Equal(types.FilteredString{IsSet: true, Value: "some-command"}),
   457  							"DockerImage": Equal("some-docker-image"),
   458  							"DockerCredentials": MatchFields(IgnoreExtras, Fields{
   459  								"Username": Equal("some-docker-username"),
   460  								"Password": Equal("some-docker-password"),
   461  							}),
   462  							"EnvironmentVariables": Equal(map[string]string{
   463  								"env1": "1",
   464  								"env3": "3",
   465  							}),
   466  							"HealthCheckTimeout": BeEquivalentTo(5),
   467  							"Instances":          Equal(types.NullInt{Value: 1, IsSet: true}),
   468  							"DiskQuota":          Equal(types.NullByteSizeInMb{IsSet: true, Value: 2}),
   469  							"Memory":             Equal(types.NullByteSizeInMb{IsSet: true, Value: 3}),
   470  							"StackGUID":          Equal("some-stack-guid"),
   471  						}),
   472  						"Buildpacks": ConsistOf("some-buildpack"),
   473  						"Stack":      Equal(stack),
   474  					}))
   475  
   476  					Expect(fakeV2Actor.GetStackByNameCallCount()).To(Equal(1))
   477  					Expect(fakeV2Actor.GetStackByNameArgsForCall(0)).To(Equal("some-stack"))
   478  				})
   479  			})
   480  
   481  			When("the manifest does not contain any properties", func() {
   482  				BeforeEach(func() {
   483  					stack = v2action.Stack{
   484  						Name: "some-stack",
   485  						GUID: "some-stack-guid",
   486  					}
   487  					fakeV2Actor.GetStackReturns(stack, nil, nil)
   488  
   489  					app := v2action.Application{
   490  						Buildpack: types.FilteredString{IsSet: true, Value: "some-buildpack"},
   491  						Command:   types.FilteredString{IsSet: true, Value: "some-command"},
   492  						DockerCredentials: ccv2.DockerCredentials{
   493  							Username: "some-docker-username",
   494  							Password: "some-docker-password",
   495  						},
   496  						DockerImage: "some-docker-image",
   497  						DiskQuota:   types.NullByteSizeInMb{IsSet: true, Value: 2},
   498  						EnvironmentVariables: map[string]string{
   499  							"env2": "2",
   500  							"env3": "9",
   501  						},
   502  						GUID:                    "some-app-guid",
   503  						HealthCheckHTTPEndpoint: "/some-endpoint",
   504  						HealthCheckTimeout:      5,
   505  						HealthCheckType:         constant.ApplicationHealthCheckPort,
   506  						Instances:               types.NullInt{Value: 3, IsSet: true},
   507  						Memory:                  types.NullByteSizeInMb{IsSet: true, Value: 3},
   508  						Name:                    appName,
   509  						StackGUID:               stack.GUID,
   510  					}
   511  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(app, nil, nil)
   512  				})
   513  
   514  				It("keeps the original app properties", func() {
   515  					Expect(firstConfig.DesiredApplication.Buildpack).To(Equal(types.FilteredString{IsSet: true, Value: "some-buildpack"}))
   516  					Expect(firstConfig.DesiredApplication.Command).To(Equal(types.FilteredString{IsSet: true, Value: "some-command"}))
   517  					Expect(firstConfig.DesiredApplication.DockerImage).To(Equal("some-docker-image"))
   518  					Expect(firstConfig.DesiredApplication.DockerCredentials.Username).To(Equal("some-docker-username"))
   519  					Expect(firstConfig.DesiredApplication.DockerCredentials.Password).To(Equal("some-docker-password"))
   520  					Expect(firstConfig.DesiredApplication.EnvironmentVariables).To(Equal(map[string]string{
   521  						"env2": "2",
   522  						"env3": "9",
   523  					}))
   524  					Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(Equal("/some-endpoint"))
   525  					Expect(firstConfig.DesiredApplication.HealthCheckTimeout).To(BeEquivalentTo(5))
   526  					Expect(firstConfig.DesiredApplication.HealthCheckType).To(Equal(constant.ApplicationHealthCheckPort))
   527  					Expect(firstConfig.DesiredApplication.Instances).To(Equal(types.NullInt{Value: 3, IsSet: true}))
   528  					Expect(firstConfig.DesiredApplication.DiskQuota).To(Equal(types.NullByteSizeInMb{IsSet: true, Value: 2}))
   529  					Expect(firstConfig.DesiredApplication.Memory).To(Equal(types.NullByteSizeInMb{IsSet: true, Value: 3}))
   530  					Expect(firstConfig.DesiredApplication.StackGUID).To(Equal("some-stack-guid"))
   531  					Expect(firstConfig.DesiredApplication.Stack).To(Equal(stack))
   532  				})
   533  			})
   534  
   535  			When("setting health check variables", func() {
   536  				When("setting the type to 'http'", func() {
   537  					BeforeEach(func() {
   538  						manifestApps[0].HealthCheckType = "http"
   539  					})
   540  
   541  					When("the http health check endpoint is set", func() {
   542  						BeforeEach(func() {
   543  							manifestApps[0].HealthCheckHTTPEndpoint = "/some/endpoint"
   544  						})
   545  
   546  						It("should overried the health check type and the endpoint should be set", func() {
   547  							Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(Equal("/some/endpoint"))
   548  							Expect(firstConfig.DesiredApplication.HealthCheckType).To(Equal(constant.ApplicationHealthCheckHTTP))
   549  						})
   550  					})
   551  
   552  					When("the http health check endpoint is not set", func() {
   553  						It("should override the health check type and the endpoint should be defaulted to \"/\"", func() {
   554  							Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(Equal("/"))
   555  							Expect(firstConfig.DesiredApplication.HealthCheckType).To(Equal(constant.ApplicationHealthCheckHTTP))
   556  						})
   557  					})
   558  				})
   559  
   560  				When("setting type to 'port'", func() {
   561  					BeforeEach(func() {
   562  						manifestApps[0].HealthCheckType = "port"
   563  					})
   564  
   565  					It("should override the health check type and the endpoint should not be set", func() {
   566  						Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(BeEmpty())
   567  						Expect(firstConfig.DesiredApplication.HealthCheckType).To(Equal(constant.ApplicationHealthCheckPort))
   568  					})
   569  				})
   570  
   571  				When("setting type to 'process'", func() {
   572  					BeforeEach(func() {
   573  						manifestApps[0].HealthCheckType = "process"
   574  					})
   575  
   576  					It("should override the health check type and the endpoint should not be set", func() {
   577  						Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(BeEmpty())
   578  						Expect(firstConfig.DesiredApplication.HealthCheckType).To(Equal(constant.ApplicationHealthCheckProcess))
   579  					})
   580  				})
   581  
   582  				When("type is unset", func() {
   583  					It("leaves the previously set values", func() {
   584  						Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(BeEmpty())
   585  						Expect(firstConfig.DesiredApplication.HealthCheckType).To(BeEmpty())
   586  					})
   587  				})
   588  			})
   589  
   590  			When("retrieving the stack errors", func() {
   591  				var expectedErr error
   592  
   593  				BeforeEach(func() {
   594  					manifestApps[0].StackName = "some-stack"
   595  
   596  					expectedErr = errors.New("potattototototototootot")
   597  					fakeV2Actor.GetStackByNameReturns(v2action.Stack{}, v2action.Warnings{"some-stack-warning"}, expectedErr)
   598  				})
   599  
   600  				It("returns the error and warnings", func() {
   601  					Expect(executeErr).To(MatchError(expectedErr))
   602  					Expect(warnings).To(ConsistOf("some-stack-warning"))
   603  				})
   604  			})
   605  
   606  			When("both the manifest and application contains environment variables", func() {
   607  				BeforeEach(func() {
   608  					manifestApps[0].EnvironmentVariables = map[string]string{
   609  						"env1": "1",
   610  						"env3": "3",
   611  					}
   612  
   613  					app := v2action.Application{
   614  						EnvironmentVariables: map[string]string{
   615  							"env2": "2",
   616  							"env3": "9",
   617  						},
   618  					}
   619  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(app, nil, nil)
   620  				})
   621  
   622  				It("adds/overrides the existing environment variables", func() {
   623  					Expect(firstConfig.DesiredApplication.EnvironmentVariables).To(Equal(map[string]string{
   624  						"env1": "1",
   625  						"env2": "2",
   626  						"env3": "3",
   627  					}))
   628  
   629  					// Does not modify original set of env vars
   630  					Expect(firstConfig.CurrentApplication.EnvironmentVariables).To(Equal(map[string]string{
   631  						"env2": "2",
   632  						"env3": "9",
   633  					}))
   634  				})
   635  			})
   636  
   637  			When("neither the manifest or the application contains environment variables", func() {
   638  				It("leaves the EnvironmentVariables as nil", func() {
   639  					Expect(firstConfig.DesiredApplication.EnvironmentVariables).To(BeNil())
   640  				})
   641  			})
   642  
   643  			When("no-start is set to true", func() {
   644  				BeforeEach(func() {
   645  					noStart = true
   646  				})
   647  
   648  				It("sets the desired app state to stopped", func() {
   649  					Expect(executeErr).ToNot(HaveOccurred())
   650  					Expect(firstConfig.DesiredApplication.Stopped()).To(BeTrue())
   651  				})
   652  			})
   653  
   654  			Describe("Buildpacks", func() {
   655  				When("the application is new", func() {
   656  					When("the 'buildpack' field is set", func() {
   657  						When("a buildpack name is provided", func() {
   658  							BeforeEach(func() {
   659  								manifestApps[0].Buildpack = types.FilteredString{
   660  									IsSet: true,
   661  									Value: "banana",
   662  								}
   663  							})
   664  
   665  							It("sets buildpacks to the provided buildpack name", func() {
   666  								Expect(firstConfig.DesiredApplication.Buildpacks).To(ConsistOf("banana"))
   667  							})
   668  						})
   669  
   670  						When("buildpack auto detection is set", func() {
   671  							BeforeEach(func() {
   672  								manifestApps[0].Buildpack = types.FilteredString{
   673  									IsSet: true,
   674  								}
   675  							})
   676  
   677  							It("sets buildpacks to the provided buildpack name", func() {
   678  								Expect(firstConfig.DesiredApplication.Buildpacks).To(Equal([]string{}))
   679  							})
   680  						})
   681  					})
   682  
   683  					When("the 'buildpacks' field is set", func() {
   684  						When("multiple buildpacks are provided", func() {
   685  							BeforeEach(func() {
   686  								manifestApps[0].Buildpacks = []string{"banana", "strawberry"}
   687  							})
   688  
   689  							It("sets buildpacks to the provided buildpack names", func() {
   690  								Expect(firstConfig.DesiredApplication.Buildpacks).To(ConsistOf("banana", "strawberry"))
   691  							})
   692  						})
   693  
   694  						When("a single buildpack is provided", func() {
   695  							BeforeEach(func() {
   696  								manifestApps[0].Buildpacks = []string{"banana"}
   697  							})
   698  
   699  							It("sets buildpacks to the provided buildpack names", func() {
   700  								Expect(firstConfig.DesiredApplication.Buildpacks).To(ConsistOf("banana"))
   701  							})
   702  						})
   703  
   704  						When("buildpack auto detection is set", func() {
   705  							BeforeEach(func() {
   706  								manifestApps[0].Buildpacks = []string{}
   707  							})
   708  
   709  							It("sets buildpacks to an empty slice", func() {
   710  								Expect(firstConfig.DesiredApplication.Buildpacks).To(Equal([]string{}))
   711  							})
   712  						})
   713  					})
   714  
   715  					When("nothing is set", func() {
   716  						It("leaves buildpack and buildpacks unset", func() {
   717  							Expect(firstConfig.DesiredApplication.Buildpack).To(Equal(types.FilteredString{}))
   718  							Expect(firstConfig.DesiredApplication.Buildpacks).To(BeNil())
   719  						})
   720  					})
   721  				})
   722  
   723  				When("the application exists", func() {
   724  					BeforeEach(func() {
   725  						fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{
   726  							Name:      appName,
   727  							GUID:      "some-app-guid",
   728  							SpaceGUID: spaceGUID,
   729  							Buildpack: types.FilteredString{IsSet: true, Value: "something-I-don't-care"},
   730  						},
   731  							nil, nil)
   732  
   733  						fakeV3Actor.GetApplicationByNameAndSpaceReturns(
   734  							v3action.Application{LifecycleBuildpacks: []string{"something-I-don't-care"}},
   735  							nil, nil)
   736  					})
   737  
   738  					When("the 'buildpack' field is set", func() {
   739  						When("a buildpack name is provided", func() {
   740  							BeforeEach(func() {
   741  								manifestApps[0].Buildpack = types.FilteredString{
   742  									IsSet: true,
   743  									Value: "banana",
   744  								}
   745  							})
   746  
   747  							It("sets buildpacks to the provided buildpack name", func() {
   748  								Expect(firstConfig.DesiredApplication.Buildpacks).To(ConsistOf("banana"))
   749  							})
   750  						})
   751  
   752  						When("buildpack auto detection is set", func() {
   753  							BeforeEach(func() {
   754  								manifestApps[0].Buildpack = types.FilteredString{
   755  									IsSet: true,
   756  								}
   757  							})
   758  
   759  							It("sets buildpacks to the provided buildpack name", func() {
   760  								Expect(firstConfig.DesiredApplication.Buildpacks).To(Equal([]string{}))
   761  							})
   762  						})
   763  					})
   764  
   765  					When("the 'buildpacks' field is set", func() {
   766  						When("multiple buildpacks are provided", func() {
   767  							BeforeEach(func() {
   768  								manifestApps[0].Buildpacks = []string{"banana", "strawberry"}
   769  							})
   770  
   771  							It("sets buildpacks to the provided buildpack names", func() {
   772  								Expect(firstConfig.DesiredApplication.Buildpacks).To(ConsistOf("banana", "strawberry"))
   773  							})
   774  						})
   775  
   776  						When("a single buildpack is provided", func() {
   777  							BeforeEach(func() {
   778  								manifestApps[0].Buildpacks = []string{"banana"}
   779  							})
   780  
   781  							It("sets buildpacks to the provided buildpack names", func() {
   782  								Expect(firstConfig.DesiredApplication.Buildpacks).To(ConsistOf("banana"))
   783  							})
   784  						})
   785  
   786  						When("buildpack auto detection is set", func() {
   787  							BeforeEach(func() {
   788  								manifestApps[0].Buildpacks = []string{}
   789  							})
   790  
   791  							It("sets buildpacks to an empty slice", func() {
   792  								Expect(firstConfig.DesiredApplication.Buildpacks).To(Equal([]string{}))
   793  							})
   794  						})
   795  					})
   796  
   797  					When("nothing is set", func() {
   798  						It("use the original values", func() {
   799  							Expect(firstConfig.DesiredApplication.Buildpack).To(Equal(types.FilteredString{IsSet: true, Value: "something-I-don't-care"}))
   800  							Expect(firstConfig.DesiredApplication.Buildpacks).To(ConsistOf("something-I-don't-care"))
   801  						})
   802  					})
   803  				})
   804  			})
   805  		})
   806  
   807  		When("the manifest contains services", func() {
   808  			BeforeEach(func() {
   809  				manifestApps[0].Services = []string{"service_1", "service_2"}
   810  				fakeV2Actor.GetServiceInstancesByApplicationReturns([]v2action.ServiceInstance{
   811  					{Name: "service_1", SpaceGUID: spaceGUID},
   812  					{Name: "service_3", SpaceGUID: spaceGUID},
   813  				}, v2action.Warnings{"some-service-warning-1"}, nil)
   814  			})
   815  
   816  			When("retrieving services is successful", func() {
   817  				BeforeEach(func() {
   818  					fakeV2Actor.GetServiceInstanceByNameAndSpaceReturns(v2action.ServiceInstance{Name: "service_2", SpaceGUID: spaceGUID}, v2action.Warnings{"some-service-warning-2"}, nil)
   819  				})
   820  
   821  				It("sets DesiredServices", func() {
   822  					Expect(executeErr).ToNot(HaveOccurred())
   823  					Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "some-service-warning-1", "some-service-warning-2"))
   824  					Expect(firstConfig.DesiredServices).To(Equal(map[string]v2action.ServiceInstance{
   825  						"service_1": v2action.ServiceInstance{Name: "service_1", SpaceGUID: spaceGUID},
   826  						"service_2": v2action.ServiceInstance{Name: "service_2", SpaceGUID: spaceGUID},
   827  						"service_3": v2action.ServiceInstance{Name: "service_3", SpaceGUID: spaceGUID},
   828  					}))
   829  
   830  					Expect(fakeV2Actor.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1))
   831  
   832  					inputServiceName, inputSpaceGUID := fakeV2Actor.GetServiceInstanceByNameAndSpaceArgsForCall(0)
   833  					Expect(inputServiceName).To(Equal("service_2"))
   834  					Expect(inputSpaceGUID).To(Equal(spaceGUID))
   835  				})
   836  			})
   837  
   838  			When("retrieving services fails", func() {
   839  				var expectedErr error
   840  
   841  				BeforeEach(func() {
   842  					expectedErr = errors.New("po-tat-toe")
   843  					fakeV2Actor.GetServiceInstanceByNameAndSpaceReturns(v2action.ServiceInstance{}, v2action.Warnings{"some-service-warning-2"}, expectedErr)
   844  				})
   845  
   846  				It("returns the error and warnings", func() {
   847  					Expect(executeErr).To(MatchError(expectedErr))
   848  					Expect(warnings).To(ConsistOf("some-service-warning-1", "some-service-warning-2"))
   849  				})
   850  			})
   851  		})
   852  
   853  		When("no-route is set", func() {
   854  			BeforeEach(func() {
   855  				manifestApps[0].NoRoute = true
   856  
   857  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, nil, actionerror.ApplicationNotFoundError{})
   858  			})
   859  
   860  			It("should set NoRoute to true", func() {
   861  				Expect(executeErr).ToNot(HaveOccurred())
   862  				Expect(warnings).To(BeEmpty())
   863  				Expect(firstConfig.NoRoute).To(BeTrue())
   864  				Expect(firstConfig.DesiredRoutes).To(BeEmpty())
   865  			})
   866  
   867  			It("should skip route generation", func() {
   868  				Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(0))
   869  				Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(0))
   870  			})
   871  		})
   872  
   873  		When("routes are defined", func() {
   874  			BeforeEach(func() {
   875  				manifestApps[0].Routes = []string{"route-1.private-domain.com", "route-2.private-domain.com"}
   876  			})
   877  
   878  			When("retrieving the routes are successful", func() {
   879  				BeforeEach(func() {
   880  					// Assumes new routes
   881  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, nil, actionerror.ApplicationNotFoundError{})
   882  					fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{domain}, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil)
   883  					fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{})
   884  				})
   885  
   886  				When("the --random-route flag is provided", func() {
   887  					BeforeEach(func() {
   888  						manifestApps[0].RandomRoute = true
   889  					})
   890  
   891  					It("adds the new routes to the desired routes, and does not generate a random route", func() {
   892  						Expect(executeErr).ToNot(HaveOccurred())
   893  						Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "get-route-warnings", "get-route-warnings"))
   894  						Expect(firstConfig.DesiredRoutes).To(ConsistOf(v2action.Route{
   895  							Domain:    domain,
   896  							Host:      "route-1",
   897  							SpaceGUID: spaceGUID,
   898  						}, v2action.Route{
   899  							Domain:    domain,
   900  							Host:      "route-2",
   901  							SpaceGUID: spaceGUID,
   902  						}))
   903  
   904  						Expect(fakeV2Actor.GetOrganizationDomainsCallCount()).To(Equal(0))
   905  					})
   906  				})
   907  
   908  				It("adds the new routes to the desired routes", func() {
   909  					Expect(executeErr).ToNot(HaveOccurred())
   910  					Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "get-route-warnings", "get-route-warnings"))
   911  					Expect(firstConfig.DesiredRoutes).To(ConsistOf(v2action.Route{
   912  						Domain:    domain,
   913  						Host:      "route-1",
   914  						SpaceGUID: spaceGUID,
   915  					}, v2action.Route{
   916  						Domain:    domain,
   917  						Host:      "route-2",
   918  						SpaceGUID: spaceGUID,
   919  					}))
   920  				})
   921  			})
   922  
   923  			When("retrieving the routes fails", func() {
   924  				var expectedErr error
   925  				BeforeEach(func() {
   926  					expectedErr = errors.New("dios mio")
   927  					// Assumes new routes
   928  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, nil, actionerror.ApplicationNotFoundError{})
   929  					fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{domain}, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, expectedErr)
   930  				})
   931  
   932  				It("returns errors and warnings", func() {
   933  					Expect(executeErr).To(MatchError(expectedErr))
   934  					Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2"))
   935  				})
   936  			})
   937  		})
   938  
   939  		When("routes are not defined", func() {
   940  			var app v2action.Application
   941  
   942  			BeforeEach(func() {
   943  				app = v2action.Application{
   944  					GUID: "some-app-guid",
   945  					Name: appName,
   946  				}
   947  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(app, nil, nil)
   948  			})
   949  
   950  			When("the default route is mapped", func() {
   951  				var existingRoute v2action.Route
   952  
   953  				BeforeEach(func() {
   954  					existingRoute = v2action.Route{
   955  						Domain: v2action.Domain{
   956  							Name: "some-domain.com",
   957  							GUID: "some-domain-guid",
   958  						},
   959  						Host:      app.Name,
   960  						GUID:      "route-guid",
   961  						SpaceGUID: spaceGUID,
   962  					}
   963  					fakeV2Actor.GetApplicationRoutesReturns([]v2action.Route{existingRoute}, v2action.Warnings{"app-route-warnings"}, nil)
   964  				})
   965  
   966  				When("only the -d flag is provided", func() {
   967  					BeforeEach(func() {
   968  						manifestApps[0].Domain = "some-private-domain"
   969  					})
   970  
   971  					When("the provided domain exists", func() {
   972  						BeforeEach(func() {
   973  							fakeV2Actor.GetDomainsByNameAndOrganizationReturns(
   974  								[]v2action.Domain{domain},
   975  								v2action.Warnings{"some-organization-domain-warning"},
   976  								nil,
   977  							)
   978  							fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{})
   979  						})
   980  
   981  						It("it uses the provided domain instead of the first shared domain", func() {
   982  							Expect(executeErr).ToNot(HaveOccurred())
   983  							Expect(warnings).To(ConsistOf("some-organization-domain-warning", "app-route-warnings", "get-route-warnings"))
   984  
   985  							Expect(firstConfig.DesiredRoutes).To(ConsistOf(
   986  								existingRoute,
   987  								v2action.Route{
   988  									Domain:    domain,
   989  									Host:      appName,
   990  									SpaceGUID: spaceGUID,
   991  								}),
   992  							)
   993  							Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1))
   994  							domainNamesArg, orgGUIDArg := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0)
   995  							Expect(domainNamesArg).To(Equal([]string{"some-private-domain"}))
   996  							Expect(orgGUIDArg).To(Equal(orgGUID))
   997  						})
   998  					})
   999  
  1000  					When("the provided domain does not exist", func() {
  1001  						BeforeEach(func() {
  1002  							fakeV2Actor.GetDomainsByNameAndOrganizationReturns(
  1003  								[]v2action.Domain{},
  1004  								v2action.Warnings{"some-organization-domain-warning"},
  1005  								nil,
  1006  							)
  1007  						})
  1008  
  1009  						It("returns an DomainNotFoundError", func() {
  1010  							Expect(executeErr).To(MatchError(actionerror.DomainNotFoundError{Name: "some-private-domain"}))
  1011  							Expect(warnings).To(ConsistOf("some-organization-domain-warning", "app-route-warnings"))
  1012  
  1013  							Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1))
  1014  							domainNamesArg, orgGUIDArg := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0)
  1015  							Expect(domainNamesArg).To(Equal([]string{"some-private-domain"}))
  1016  							Expect(orgGUIDArg).To(Equal(orgGUID))
  1017  						})
  1018  					})
  1019  				})
  1020  			})
  1021  
  1022  			When("the default route is not mapped to the app", func() {
  1023  				When("only the -d flag is provided", func() {
  1024  					BeforeEach(func() {
  1025  						manifestApps[0].Domain = "some-private-domain"
  1026  						fakeV2Actor.GetApplicationRoutesReturns(nil, v2action.Warnings{"app-route-warnings"}, nil)
  1027  					})
  1028  
  1029  					When("the provided domain exists", func() {
  1030  						BeforeEach(func() {
  1031  							fakeV2Actor.GetDomainsByNameAndOrganizationReturns(
  1032  								[]v2action.Domain{domain},
  1033  								v2action.Warnings{"some-organization-domain-warning"},
  1034  								nil,
  1035  							)
  1036  							fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{})
  1037  						})
  1038  
  1039  						It("it uses the provided domain instead of the first shared domain", func() {
  1040  							Expect(executeErr).ToNot(HaveOccurred())
  1041  							Expect(warnings).To(ConsistOf("some-organization-domain-warning", "app-route-warnings", "get-route-warnings"))
  1042  
  1043  							Expect(firstConfig.DesiredRoutes).To(ConsistOf(
  1044  								v2action.Route{
  1045  									Domain:    domain,
  1046  									Host:      appName,
  1047  									SpaceGUID: spaceGUID,
  1048  								}),
  1049  							)
  1050  							Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1))
  1051  							domainNamesArg, orgGUIDArg := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0)
  1052  							Expect(domainNamesArg).To(Equal([]string{"some-private-domain"}))
  1053  							Expect(orgGUIDArg).To(Equal(orgGUID))
  1054  						})
  1055  					})
  1056  
  1057  					When("the provided domain does not exist", func() {
  1058  						BeforeEach(func() {
  1059  							fakeV2Actor.GetDomainsByNameAndOrganizationReturns(
  1060  								[]v2action.Domain{},
  1061  								v2action.Warnings{"some-organization-domain-warning"},
  1062  								nil,
  1063  							)
  1064  						})
  1065  
  1066  						It("returns an DomainNotFoundError", func() {
  1067  							Expect(executeErr).To(MatchError(actionerror.DomainNotFoundError{Name: "some-private-domain"}))
  1068  							Expect(warnings).To(ConsistOf("some-organization-domain-warning", "app-route-warnings"))
  1069  
  1070  							Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1))
  1071  							domainNamesArg, orgGUIDArg := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0)
  1072  							Expect(domainNamesArg).To(Equal([]string{"some-private-domain"}))
  1073  							Expect(orgGUIDArg).To(Equal(orgGUID))
  1074  						})
  1075  					})
  1076  				})
  1077  
  1078  				When("there are routes bound to the application", func() {
  1079  					var existingRoute v2action.Route
  1080  
  1081  					BeforeEach(func() {
  1082  						existingRoute = v2action.Route{
  1083  							Domain: v2action.Domain{
  1084  								Name: "some-domain.com",
  1085  								GUID: "some-domain-guid",
  1086  							},
  1087  							Host:      app.Name,
  1088  							GUID:      "route-guid",
  1089  							SpaceGUID: spaceGUID,
  1090  						}
  1091  						fakeV2Actor.GetApplicationRoutesReturns([]v2action.Route{existingRoute}, v2action.Warnings{"app-route-warnings"}, nil)
  1092  					})
  1093  
  1094  					It("does not bind any addition routes", func() {
  1095  						Expect(executeErr).ToNot(HaveOccurred())
  1096  						Expect(warnings).To(ConsistOf("app-route-warnings"))
  1097  						Expect(firstConfig.DesiredRoutes).To(ConsistOf(existingRoute))
  1098  						Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(0))
  1099  					})
  1100  				})
  1101  
  1102  				When("there are no routes bound to the application", func() {
  1103  					BeforeEach(func() {
  1104  						fakeV2Actor.GetApplicationRoutesReturns(nil, v2action.Warnings{"app-route-warnings"}, nil)
  1105  
  1106  						// Assumes new route
  1107  						fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{})
  1108  					})
  1109  
  1110  					It("adds the default route to desired routes", func() {
  1111  						Expect(executeErr).ToNot(HaveOccurred())
  1112  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "app-route-warnings", "get-route-warnings"))
  1113  						Expect(firstConfig.DesiredRoutes).To(ConsistOf(
  1114  							v2action.Route{
  1115  								Domain:    domain,
  1116  								Host:      appName,
  1117  								SpaceGUID: spaceGUID,
  1118  							}))
  1119  					})
  1120  				})
  1121  			})
  1122  		})
  1123  
  1124  		When("scanning for files", func() {
  1125  			Context("given a directory", func() {
  1126  				When("scanning is successful", func() {
  1127  					var resources []sharedaction.Resource
  1128  
  1129  					BeforeEach(func() {
  1130  						resources = []sharedaction.Resource{
  1131  							{Filename: "I am a file!"},
  1132  							{Filename: "I am not a file"},
  1133  						}
  1134  						fakeSharedActor.GatherDirectoryResourcesReturns(resources, nil)
  1135  					})
  1136  
  1137  					It("sets the full resource list on the config", func() {
  1138  						Expect(executeErr).ToNot(HaveOccurred())
  1139  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
  1140  						Expect(firstConfig.AllResources).To(Equal(actor.ConvertSharedResourcesToV2Resources(resources)))
  1141  						Expect(firstConfig.Path).To(Equal(filesPath))
  1142  						Expect(firstConfig.Archive).To(BeFalse())
  1143  
  1144  						Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(1))
  1145  						Expect(fakeSharedActor.GatherDirectoryResourcesArgsForCall(0)).To(Equal(filesPath))
  1146  					})
  1147  				})
  1148  
  1149  				When("scanning errors", func() {
  1150  					var expectedErr error
  1151  
  1152  					BeforeEach(func() {
  1153  						expectedErr = errors.New("dios mio")
  1154  						fakeSharedActor.GatherDirectoryResourcesReturns(nil, expectedErr)
  1155  					})
  1156  
  1157  					It("returns the error and warnings", func() {
  1158  						Expect(executeErr).To(MatchError(expectedErr))
  1159  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
  1160  					})
  1161  				})
  1162  			})
  1163  
  1164  			Context("given an archive", func() {
  1165  				var archive string
  1166  
  1167  				BeforeEach(func() {
  1168  					f, err := ioutil.TempFile("", "convert-to-application-configs-archive")
  1169  					Expect(err).ToNot(HaveOccurred())
  1170  					archive = f.Name()
  1171  					Expect(f.Close()).ToNot(HaveOccurred())
  1172  
  1173  					// The temp file created on OSX contains a symlink and needs to be evaluated.
  1174  					archive, err = filepath.EvalSymlinks(archive)
  1175  					Expect(err).ToNot(HaveOccurred())
  1176  
  1177  					manifestApps[0].Path = archive
  1178  				})
  1179  
  1180  				AfterEach(func() {
  1181  					Expect(os.RemoveAll(archive)).ToNot(HaveOccurred())
  1182  				})
  1183  
  1184  				When("scanning is successful", func() {
  1185  					var resources []sharedaction.Resource
  1186  
  1187  					BeforeEach(func() {
  1188  						resources = []sharedaction.Resource{
  1189  							{Filename: "I am a file!"},
  1190  							{Filename: "I am not a file"},
  1191  						}
  1192  						fakeSharedActor.GatherArchiveResourcesReturns(resources, nil)
  1193  					})
  1194  
  1195  					It("sets the full resource list on the config", func() {
  1196  						Expect(executeErr).ToNot(HaveOccurred())
  1197  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
  1198  						Expect(firstConfig.AllResources).To(Equal(actor.ConvertSharedResourcesToV2Resources(resources)))
  1199  						Expect(firstConfig.Path).To(Equal(archive))
  1200  						Expect(firstConfig.Archive).To(BeTrue())
  1201  
  1202  						Expect(fakeSharedActor.GatherArchiveResourcesCallCount()).To(Equal(1))
  1203  						Expect(fakeSharedActor.GatherArchiveResourcesArgsForCall(0)).To(Equal(archive))
  1204  					})
  1205  				})
  1206  
  1207  				When("scanning errors", func() {
  1208  					var expectedErr error
  1209  
  1210  					BeforeEach(func() {
  1211  						expectedErr = errors.New("dios mio")
  1212  						fakeSharedActor.GatherArchiveResourcesReturns(nil, expectedErr)
  1213  					})
  1214  
  1215  					It("returns the error and warnings", func() {
  1216  						Expect(executeErr).To(MatchError(expectedErr))
  1217  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
  1218  					})
  1219  				})
  1220  			})
  1221  		})
  1222  
  1223  		When("a docker image is configured", func() {
  1224  			BeforeEach(func() {
  1225  				manifestApps[0].DockerImage = "some-docker-image-path"
  1226  			})
  1227  
  1228  			It("sets the docker image on DesiredApplication and does not gather resources", func() {
  1229  				Expect(executeErr).ToNot(HaveOccurred())
  1230  				Expect(firstConfig.DesiredApplication.DockerImage).To(Equal("some-docker-image-path"))
  1231  
  1232  				Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(0))
  1233  			})
  1234  		})
  1235  
  1236  		When("a droplet is provided", func() {
  1237  			BeforeEach(func() {
  1238  				manifestApps[0].DropletPath = filesPath
  1239  			})
  1240  
  1241  			It("sets the droplet on DesiredApplication and does not gather resources", func() {
  1242  				Expect(executeErr).ToNot(HaveOccurred())
  1243  				Expect(firstConfig.DropletPath).To(Equal(filesPath))
  1244  
  1245  				Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(0))
  1246  			})
  1247  		})
  1248  
  1249  		When("buildpacks (plural) are provided", func() {
  1250  			BeforeEach(func() {
  1251  				manifestApps[0].Buildpacks = []string{
  1252  					"some-buildpack-1",
  1253  					"some-buildpack-2",
  1254  				}
  1255  			})
  1256  
  1257  			It("sets the buildpacks on DesiredApplication", func() {
  1258  				Expect(executeErr).ToNot(HaveOccurred())
  1259  				Expect(len(firstConfig.DesiredApplication.Buildpacks)).To(Equal(2))
  1260  				Expect(firstConfig.DesiredApplication.Buildpacks[0]).To(Equal("some-buildpack-1"))
  1261  				Expect(firstConfig.DesiredApplication.Buildpacks[1]).To(Equal("some-buildpack-2"))
  1262  			})
  1263  
  1264  			When("the buildpacks are an empty array", func() {
  1265  				BeforeEach(func() {
  1266  					manifestApps[0].Buildpacks = []string{}
  1267  				})
  1268  
  1269  				It("set the buildpacks on DesiredApplication to empty array", func() {
  1270  					Expect(executeErr).ToNot(HaveOccurred())
  1271  					Expect(firstConfig.DesiredApplication.Buildpacks).To(Equal([]string{}))
  1272  				})
  1273  			})
  1274  		})
  1275  	})
  1276  })