github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/actor/pushaction/application_config_test.go (about)

     1  package pushaction_test
     2  
     3  import (
     4  	"errors"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"github.com/liamawhite/cli-with-i18n/actor/actionerror"
    10  	. "github.com/liamawhite/cli-with-i18n/actor/pushaction"
    11  	"github.com/liamawhite/cli-with-i18n/actor/pushaction/pushactionfakes"
    12  	"github.com/liamawhite/cli-with-i18n/actor/sharedaction"
    13  	"github.com/liamawhite/cli-with-i18n/actor/v2action"
    14  	"github.com/liamawhite/cli-with-i18n/api/cloudcontroller/ccv2"
    15  	"github.com/liamawhite/cli-with-i18n/types"
    16  	"github.com/liamawhite/cli-with-i18n/util/manifest"
    17  
    18  	. "github.com/onsi/ginkgo"
    19  	. "github.com/onsi/gomega"
    20  )
    21  
    22  var _ = Describe("Application Config", func() {
    23  	var (
    24  		actor           *Actor
    25  		fakeV2Actor     *pushactionfakes.FakeV2Actor
    26  		fakeSharedActor *pushactionfakes.FakeSharedActor
    27  	)
    28  
    29  	BeforeEach(func() {
    30  		fakeV2Actor = new(pushactionfakes.FakeV2Actor)
    31  		fakeSharedActor = new(pushactionfakes.FakeSharedActor)
    32  		actor = NewActor(fakeV2Actor, fakeSharedActor)
    33  	})
    34  
    35  	Describe("ApplicationConfig", func() {
    36  		Describe("CreatingApplication", func() {
    37  			Context("when the app did not exist", func() {
    38  				It("returns true", func() {
    39  					config := ApplicationConfig{}
    40  					Expect(config.CreatingApplication()).To(BeTrue())
    41  				})
    42  			})
    43  
    44  			Context("when the app exists", func() {
    45  				It("returns false", func() {
    46  					config := ApplicationConfig{CurrentApplication: Application{Application: v2action.Application{GUID: "some-app-guid"}}}
    47  					Expect(config.CreatingApplication()).To(BeFalse())
    48  				})
    49  			})
    50  		})
    51  
    52  		Describe("UpdatedApplication", func() {
    53  			Context("when the app did not exist", func() {
    54  				It("returns false", func() {
    55  					config := ApplicationConfig{}
    56  					Expect(config.UpdatingApplication()).To(BeFalse())
    57  				})
    58  			})
    59  
    60  			Context("when the app exists", func() {
    61  				It("returns true", func() {
    62  					config := ApplicationConfig{CurrentApplication: Application{Application: v2action.Application{GUID: "some-app-guid"}}}
    63  					Expect(config.UpdatingApplication()).To(BeTrue())
    64  				})
    65  			})
    66  		})
    67  	})
    68  
    69  	Describe("ConvertToApplicationConfigs", func() {
    70  		var (
    71  			appName   string
    72  			domain    v2action.Domain
    73  			filesPath string
    74  
    75  			orgGUID      string
    76  			spaceGUID    string
    77  			noStart      bool
    78  			manifestApps []manifest.Application
    79  
    80  			configs    []ApplicationConfig
    81  			warnings   Warnings
    82  			executeErr error
    83  
    84  			firstConfig ApplicationConfig
    85  		)
    86  
    87  		BeforeEach(func() {
    88  			appName = "some-app"
    89  			orgGUID = "some-org-guid"
    90  			spaceGUID = "some-space-guid"
    91  			noStart = false
    92  
    93  			var err error
    94  			filesPath, err = ioutil.TempDir("", "convert-to-application-configs")
    95  			Expect(err).ToNot(HaveOccurred())
    96  
    97  			// The temp directory created on OSX contains a symlink and needs to be evaluated.
    98  			filesPath, err = filepath.EvalSymlinks(filesPath)
    99  			Expect(err).ToNot(HaveOccurred())
   100  
   101  			manifestApps = []manifest.Application{{
   102  				Name: appName,
   103  				Path: filesPath,
   104  			}}
   105  
   106  			domain = v2action.Domain{
   107  				Name: "private-domain.com",
   108  				GUID: "some-private-domain-guid",
   109  			}
   110  			// Prevents NoDomainsFoundError
   111  			fakeV2Actor.GetOrganizationDomainsReturns(
   112  				[]v2action.Domain{domain},
   113  				v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"},
   114  				nil,
   115  			)
   116  		})
   117  
   118  		JustBeforeEach(func() {
   119  			configs, warnings, executeErr = actor.ConvertToApplicationConfigs(orgGUID, spaceGUID, noStart, manifestApps)
   120  			if len(configs) > 0 {
   121  				firstConfig = configs[0]
   122  			}
   123  		})
   124  
   125  		AfterEach(func() {
   126  			Expect(os.RemoveAll(filesPath)).ToNot(HaveOccurred())
   127  		})
   128  
   129  		Context("when the path is a symlink", func() {
   130  			var target string
   131  
   132  			BeforeEach(func() {
   133  				parentDir := filepath.Dir(filesPath)
   134  				target = filepath.Join(parentDir, "i-r-symlink")
   135  				Expect(os.Symlink(filesPath, target)).ToNot(HaveOccurred())
   136  				manifestApps[0].Path = target
   137  			})
   138  
   139  			AfterEach(func() {
   140  				Expect(os.RemoveAll(target)).ToNot(HaveOccurred())
   141  			})
   142  
   143  			It("evaluates the symlink into an absolute path", func() {
   144  				Expect(executeErr).ToNot(HaveOccurred())
   145  
   146  				Expect(firstConfig.Path).To(Equal(filesPath))
   147  			})
   148  
   149  			Context("given a path that does not exist", func() {
   150  				BeforeEach(func() {
   151  					manifestApps[0].Path = "/i/will/fight/you/if/this/exists"
   152  				})
   153  
   154  				It("returns errors and warnings", func() {
   155  					Expect(os.IsNotExist(executeErr)).To(BeTrue())
   156  
   157  					Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(0))
   158  					Expect(fakeSharedActor.GatherArchiveResourcesCallCount()).To(Equal(0))
   159  				})
   160  			})
   161  		})
   162  
   163  		Context("when the application exists", func() {
   164  			var app Application
   165  			var route v2action.Route
   166  
   167  			BeforeEach(func() {
   168  				app = Application{
   169  					Application: v2action.Application{
   170  						Name:      appName,
   171  						GUID:      "some-app-guid",
   172  						SpaceGUID: spaceGUID,
   173  					}}
   174  
   175  				route = v2action.Route{
   176  					Domain: v2action.Domain{
   177  						Name: "some-domain.com",
   178  						GUID: "some-domain-guid",
   179  					},
   180  					Host:      app.Name,
   181  					GUID:      "route-guid",
   182  					SpaceGUID: spaceGUID,
   183  				}
   184  
   185  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(app.Application, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, nil)
   186  			})
   187  
   188  			Context("when retrieving the application's routes is successful", func() {
   189  				BeforeEach(func() {
   190  					fakeV2Actor.GetApplicationRoutesReturns([]v2action.Route{route}, v2action.Warnings{"app-route-warnings"}, nil)
   191  				})
   192  
   193  				Context("when retrieving the application's services is successful", func() {
   194  					var services []v2action.ServiceInstance
   195  
   196  					BeforeEach(func() {
   197  						services = []v2action.ServiceInstance{
   198  							{Name: "service-1", GUID: "service-instance-1"},
   199  							{Name: "service-2", GUID: "service-instance-2"},
   200  						}
   201  
   202  						fakeV2Actor.GetServiceInstancesByApplicationReturns(services, v2action.Warnings{"service-instance-warning-1", "service-instance-warning-2"}, nil)
   203  					})
   204  
   205  					It("return warnings", func() {
   206  						Expect(executeErr).ToNot(HaveOccurred())
   207  						Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "app-route-warnings", "private-domain-warnings", "shared-domain-warnings", "service-instance-warning-1", "service-instance-warning-2"))
   208  					})
   209  
   210  					It("sets the current application to the existing application", func() {
   211  						Expect(firstConfig.CurrentApplication).To(Equal(app))
   212  						Expect(firstConfig.TargetedSpaceGUID).To(Equal(spaceGUID))
   213  
   214  						Expect(fakeV2Actor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1))
   215  						passedName, passedSpaceGUID := fakeV2Actor.GetApplicationByNameAndSpaceArgsForCall(0)
   216  						Expect(passedName).To(Equal(app.Name))
   217  						Expect(passedSpaceGUID).To(Equal(spaceGUID))
   218  					})
   219  
   220  					It("sets the current routes", func() {
   221  						Expect(firstConfig.CurrentRoutes).To(ConsistOf(route))
   222  
   223  						Expect(fakeV2Actor.GetApplicationRoutesCallCount()).To(Equal(1))
   224  						Expect(fakeV2Actor.GetApplicationRoutesArgsForCall(0)).To(Equal(app.GUID))
   225  					})
   226  
   227  					It("sets the bound services", func() {
   228  						Expect(firstConfig.CurrentServices).To(Equal(map[string]v2action.ServiceInstance{
   229  							"service-1": v2action.ServiceInstance{Name: "service-1", GUID: "service-instance-1"},
   230  							"service-2": v2action.ServiceInstance{Name: "service-2", GUID: "service-instance-2"},
   231  						}))
   232  
   233  						Expect(fakeV2Actor.GetServiceInstancesByApplicationCallCount()).To(Equal(1))
   234  						Expect(fakeV2Actor.GetServiceInstancesByApplicationArgsForCall(0)).To(Equal("some-app-guid"))
   235  					})
   236  				})
   237  
   238  				Context("when retrieving the application's services errors", func() {
   239  					var expectedErr error
   240  
   241  					BeforeEach(func() {
   242  						expectedErr = errors.New("dios mio")
   243  						fakeV2Actor.GetServiceInstancesByApplicationReturns(nil, v2action.Warnings{"service-instance-warning-1", "service-instance-warning-2"}, expectedErr)
   244  					})
   245  
   246  					It("returns the error and warnings", func() {
   247  						Expect(executeErr).To(MatchError(expectedErr))
   248  						Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "app-route-warnings", "service-instance-warning-1", "service-instance-warning-2"))
   249  					})
   250  				})
   251  			})
   252  
   253  			Context("when retrieving the application's routes errors", func() {
   254  				var expectedErr error
   255  
   256  				BeforeEach(func() {
   257  					expectedErr = errors.New("dios mio")
   258  					fakeV2Actor.GetApplicationRoutesReturns(nil, v2action.Warnings{"app-route-warnings"}, expectedErr)
   259  				})
   260  
   261  				It("returns the error and warnings", func() {
   262  					Expect(executeErr).To(MatchError(expectedErr))
   263  					Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "app-route-warnings"))
   264  				})
   265  			})
   266  		})
   267  
   268  		Context("when the application does not exist", func() {
   269  			BeforeEach(func() {
   270  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, actionerror.ApplicationNotFoundError{})
   271  			})
   272  
   273  			It("creates a new application and sets it to the desired application", func() {
   274  				Expect(executeErr).ToNot(HaveOccurred())
   275  				Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2", "private-domain-warnings", "shared-domain-warnings"))
   276  				Expect(firstConfig.CurrentApplication).To(Equal(Application{Application: v2action.Application{}}))
   277  				Expect(firstConfig.DesiredApplication).To(Equal(Application{
   278  					Application: v2action.Application{
   279  						Name:      appName,
   280  						SpaceGUID: spaceGUID,
   281  					}}))
   282  				Expect(firstConfig.TargetedSpaceGUID).To(Equal(spaceGUID))
   283  			})
   284  		})
   285  
   286  		Context("when retrieving the application errors", func() {
   287  			var expectedErr error
   288  
   289  			BeforeEach(func() {
   290  				expectedErr = errors.New("dios mio")
   291  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, expectedErr)
   292  			})
   293  
   294  			It("returns the error and warnings", func() {
   295  				Expect(executeErr).To(MatchError(expectedErr))
   296  				Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2"))
   297  			})
   298  		})
   299  
   300  		Context("when overriding application properties", func() {
   301  			var stack v2action.Stack
   302  
   303  			Context("when the manifest contains all the properties", func() {
   304  				BeforeEach(func() {
   305  					manifestApps[0].Buildpack = types.FilteredString{IsSet: true, Value: "some-buildpack"}
   306  					manifestApps[0].Command = types.FilteredString{IsSet: true, Value: "some-command"}
   307  					manifestApps[0].DockerImage = "some-docker-image"
   308  					manifestApps[0].DockerUsername = "some-docker-username"
   309  					manifestApps[0].DockerPassword = "some-docker-password"
   310  					manifestApps[0].HealthCheckHTTPEndpoint = "some-buildpack"
   311  					manifestApps[0].HealthCheckTimeout = 5
   312  					manifestApps[0].HealthCheckType = "port"
   313  					manifestApps[0].Instances = types.NullInt{Value: 1, IsSet: true}
   314  					manifestApps[0].DiskQuota = types.NullByteSizeInMb{Value: 2, IsSet: true}
   315  					manifestApps[0].Memory = types.NullByteSizeInMb{Value: 3, IsSet: true}
   316  					manifestApps[0].StackName = "some-stack"
   317  					manifestApps[0].EnvironmentVariables = map[string]string{
   318  						"env1": "1",
   319  						"env3": "3",
   320  					}
   321  
   322  					stack = v2action.Stack{
   323  						Name: "some-stack",
   324  						GUID: "some-stack-guid",
   325  					}
   326  
   327  					fakeV2Actor.GetStackByNameReturns(stack, v2action.Warnings{"some-stack-warning"}, nil)
   328  				})
   329  
   330  				It("overrides the current application properties", func() {
   331  					Expect(warnings).To(ConsistOf("some-stack-warning", "private-domain-warnings", "shared-domain-warnings"))
   332  
   333  					Expect(firstConfig.DesiredApplication.Buildpack).To(Equal(types.FilteredString{IsSet: true, Value: "some-buildpack"}))
   334  					Expect(firstConfig.DesiredApplication.Command).To(Equal(types.FilteredString{IsSet: true, Value: "some-command"}))
   335  					Expect(firstConfig.DesiredApplication.DockerImage).To(Equal("some-docker-image"))
   336  					Expect(firstConfig.DesiredApplication.DockerCredentials.Username).To(Equal("some-docker-username"))
   337  					Expect(firstConfig.DesiredApplication.DockerCredentials.Password).To(Equal("some-docker-password"))
   338  					Expect(firstConfig.DesiredApplication.EnvironmentVariables).To(Equal(map[string]string{
   339  						"env1": "1",
   340  						"env3": "3",
   341  					}))
   342  					Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(Equal("some-buildpack"))
   343  					Expect(firstConfig.DesiredApplication.HealthCheckTimeout).To(Equal(5))
   344  					Expect(firstConfig.DesiredApplication.HealthCheckType).To(Equal(ccv2.ApplicationHealthCheckPort))
   345  					Expect(firstConfig.DesiredApplication.Instances).To(Equal(types.NullInt{Value: 1, IsSet: true}))
   346  					Expect(firstConfig.DesiredApplication.DiskQuota).To(BeNumerically("==", 2))
   347  					Expect(firstConfig.DesiredApplication.Memory).To(BeNumerically("==", 3))
   348  					Expect(firstConfig.DesiredApplication.StackGUID).To(Equal("some-stack-guid"))
   349  					Expect(firstConfig.DesiredApplication.Stack).To(Equal(stack))
   350  
   351  					Expect(fakeV2Actor.GetStackByNameCallCount()).To(Equal(1))
   352  					Expect(fakeV2Actor.GetStackByNameArgsForCall(0)).To(Equal("some-stack"))
   353  				})
   354  			})
   355  
   356  			Context("when the manifest does not contain any properties", func() {
   357  				BeforeEach(func() {
   358  					stack = v2action.Stack{
   359  						Name: "some-stack",
   360  						GUID: "some-stack-guid",
   361  					}
   362  					fakeV2Actor.GetStackReturns(stack, nil, nil)
   363  
   364  					app := v2action.Application{
   365  						Buildpack: types.FilteredString{IsSet: true, Value: "some-buildpack"},
   366  						Command:   types.FilteredString{IsSet: true, Value: "some-command"},
   367  						DockerCredentials: ccv2.DockerCredentials{
   368  							Username: "some-docker-username",
   369  							Password: "some-docker-password",
   370  						},
   371  						DockerImage: "some-docker-image",
   372  						DiskQuota:   2,
   373  						EnvironmentVariables: map[string]string{
   374  							"env2": "2",
   375  							"env3": "9",
   376  						},
   377  						GUID: "some-app-guid",
   378  						HealthCheckHTTPEndpoint: "/some-endpoint",
   379  						HealthCheckTimeout:      5,
   380  						HealthCheckType:         "port",
   381  						Instances:               types.NullInt{Value: 3, IsSet: true},
   382  						Memory:                  3,
   383  						Name:                    appName,
   384  						StackGUID:               stack.GUID,
   385  					}
   386  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(app, nil, nil)
   387  				})
   388  
   389  				It("keeps the original app properties", func() {
   390  					Expect(firstConfig.DesiredApplication.Buildpack).To(Equal(types.FilteredString{IsSet: true, Value: "some-buildpack"}))
   391  					Expect(firstConfig.DesiredApplication.Command).To(Equal(types.FilteredString{IsSet: true, Value: "some-command"}))
   392  					Expect(firstConfig.DesiredApplication.DockerImage).To(Equal("some-docker-image"))
   393  					Expect(firstConfig.DesiredApplication.DockerCredentials.Username).To(Equal("some-docker-username"))
   394  					Expect(firstConfig.DesiredApplication.DockerCredentials.Password).To(Equal("some-docker-password"))
   395  					Expect(firstConfig.DesiredApplication.EnvironmentVariables).To(Equal(map[string]string{
   396  						"env2": "2",
   397  						"env3": "9",
   398  					}))
   399  					Expect(firstConfig.DesiredApplication.HealthCheckHTTPEndpoint).To(Equal("/some-endpoint"))
   400  					Expect(firstConfig.DesiredApplication.HealthCheckTimeout).To(Equal(5))
   401  					Expect(firstConfig.DesiredApplication.HealthCheckType).To(Equal(ccv2.ApplicationHealthCheckPort))
   402  					Expect(firstConfig.DesiredApplication.Instances).To(Equal(types.NullInt{Value: 3, IsSet: true}))
   403  					Expect(firstConfig.DesiredApplication.DiskQuota).To(BeNumerically("==", 2))
   404  					Expect(firstConfig.DesiredApplication.Memory).To(BeNumerically("==", 3))
   405  					Expect(firstConfig.DesiredApplication.StackGUID).To(Equal("some-stack-guid"))
   406  					Expect(firstConfig.DesiredApplication.Stack).To(Equal(stack))
   407  				})
   408  			})
   409  
   410  			Context("when retrieving the stack errors", func() {
   411  				var expectedErr error
   412  
   413  				BeforeEach(func() {
   414  					manifestApps[0].StackName = "some-stack"
   415  
   416  					expectedErr = errors.New("potattototototototootot")
   417  					fakeV2Actor.GetStackByNameReturns(v2action.Stack{}, v2action.Warnings{"some-stack-warning"}, expectedErr)
   418  				})
   419  
   420  				It("returns the error and warnings", func() {
   421  					Expect(executeErr).To(MatchError(expectedErr))
   422  					Expect(warnings).To(ConsistOf("some-stack-warning"))
   423  				})
   424  			})
   425  
   426  			Context("when both the manifest and application contains environment variables", func() {
   427  				BeforeEach(func() {
   428  					manifestApps[0].EnvironmentVariables = map[string]string{
   429  						"env1": "1",
   430  						"env3": "3",
   431  					}
   432  
   433  					app := v2action.Application{
   434  						EnvironmentVariables: map[string]string{
   435  							"env2": "2",
   436  							"env3": "9",
   437  						},
   438  					}
   439  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(app, nil, nil)
   440  				})
   441  
   442  				It("adds/overrides the existing environment variables", func() {
   443  					Expect(firstConfig.DesiredApplication.EnvironmentVariables).To(Equal(map[string]string{
   444  						"env1": "1",
   445  						"env2": "2",
   446  						"env3": "3",
   447  					}))
   448  
   449  					// Does not modify original set of env vars
   450  					Expect(firstConfig.CurrentApplication.EnvironmentVariables).To(Equal(map[string]string{
   451  						"env2": "2",
   452  						"env3": "9",
   453  					}))
   454  				})
   455  			})
   456  
   457  			Context("when neither the manifest or the application contains environment variables", func() {
   458  				It("leaves the EnvironmentVariables as nil", func() {
   459  					Expect(firstConfig.DesiredApplication.EnvironmentVariables).To(BeNil())
   460  				})
   461  			})
   462  
   463  			Context("when no-start is set to true", func() {
   464  				BeforeEach(func() {
   465  					noStart = true
   466  				})
   467  
   468  				It("sets the desired app state to stopped", func() {
   469  					Expect(executeErr).ToNot(HaveOccurred())
   470  					Expect(firstConfig.DesiredApplication.Stopped()).To(BeTrue())
   471  				})
   472  			})
   473  		})
   474  
   475  		Context("when the manifest contains services", func() {
   476  			BeforeEach(func() {
   477  				manifestApps[0].Services = []string{"service_1", "service_2"}
   478  				fakeV2Actor.GetServiceInstancesByApplicationReturns([]v2action.ServiceInstance{
   479  					{Name: "service_1", SpaceGUID: spaceGUID},
   480  					{Name: "service_3", SpaceGUID: spaceGUID},
   481  				}, v2action.Warnings{"some-service-warning-1"}, nil)
   482  			})
   483  
   484  			Context("when retrieving services is successful", func() {
   485  				BeforeEach(func() {
   486  					fakeV2Actor.GetServiceInstanceByNameAndSpaceReturns(v2action.ServiceInstance{Name: "service_2", SpaceGUID: spaceGUID}, v2action.Warnings{"some-service-warning-2"}, nil)
   487  				})
   488  
   489  				It("sets DesiredServices", func() {
   490  					Expect(executeErr).ToNot(HaveOccurred())
   491  					Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "some-service-warning-1", "some-service-warning-2"))
   492  					Expect(firstConfig.DesiredServices).To(Equal(map[string]v2action.ServiceInstance{
   493  						"service_1": v2action.ServiceInstance{Name: "service_1", SpaceGUID: spaceGUID},
   494  						"service_2": v2action.ServiceInstance{Name: "service_2", SpaceGUID: spaceGUID},
   495  						"service_3": v2action.ServiceInstance{Name: "service_3", SpaceGUID: spaceGUID},
   496  					}))
   497  
   498  					Expect(fakeV2Actor.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1))
   499  
   500  					inputServiceName, inputSpaceGUID := fakeV2Actor.GetServiceInstanceByNameAndSpaceArgsForCall(0)
   501  					Expect(inputServiceName).To(Equal("service_2"))
   502  					Expect(inputSpaceGUID).To(Equal(spaceGUID))
   503  				})
   504  			})
   505  
   506  			Context("when retrieving services fails", func() {
   507  				var expectedErr error
   508  
   509  				BeforeEach(func() {
   510  					expectedErr = errors.New("po-tat-toe")
   511  					fakeV2Actor.GetServiceInstanceByNameAndSpaceReturns(v2action.ServiceInstance{}, v2action.Warnings{"some-service-warning-2"}, expectedErr)
   512  				})
   513  
   514  				It("returns the error and warnings", func() {
   515  					Expect(executeErr).To(MatchError(expectedErr))
   516  					Expect(warnings).To(ConsistOf("some-service-warning-1", "some-service-warning-2"))
   517  				})
   518  			})
   519  		})
   520  
   521  		Context("when routes are defined", func() {
   522  			BeforeEach(func() {
   523  				manifestApps[0].Routes = []string{"route-1.private-domain.com", "route-2.private-domain.com"}
   524  			})
   525  
   526  			Context("when retrieving the routes are successful", func() {
   527  				BeforeEach(func() {
   528  					// Assumes new routes
   529  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, nil, actionerror.ApplicationNotFoundError{})
   530  					fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{domain}, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil)
   531  					fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, v2action.RouteNotFoundError{})
   532  				})
   533  
   534  				It("adds the new routes to the desired routes", func() {
   535  					Expect(executeErr).ToNot(HaveOccurred())
   536  					Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "get-route-warnings", "get-route-warnings"))
   537  					Expect(firstConfig.DesiredRoutes).To(ConsistOf(v2action.Route{
   538  						Domain:    domain,
   539  						Host:      "route-1",
   540  						SpaceGUID: spaceGUID,
   541  					}, v2action.Route{
   542  						Domain:    domain,
   543  						Host:      "route-2",
   544  						SpaceGUID: spaceGUID,
   545  					}))
   546  				})
   547  			})
   548  
   549  			Context("when retrieving the routes fails", func() {
   550  				var expectedErr error
   551  				BeforeEach(func() {
   552  					expectedErr = errors.New("dios mio")
   553  					// Assumes new routes
   554  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, nil, actionerror.ApplicationNotFoundError{})
   555  					fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{domain}, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, expectedErr)
   556  				})
   557  
   558  				It("returns errors and warnings", func() {
   559  					Expect(executeErr).To(MatchError(expectedErr))
   560  					Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2"))
   561  				})
   562  			})
   563  		})
   564  
   565  		Context("when routes are not defined", func() {
   566  			Context("when retrieving the default route is successful", func() {
   567  				var existingRoute v2action.Route
   568  
   569  				BeforeEach(func() {
   570  					app := v2action.Application{
   571  						GUID: "some-app-guid",
   572  						Name: appName,
   573  					}
   574  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(app, nil, nil)
   575  
   576  					existingRoute = v2action.Route{
   577  						Domain: v2action.Domain{
   578  							Name: "some-domain.com",
   579  							GUID: "some-domain-guid",
   580  						},
   581  						Host:      app.Name,
   582  						GUID:      "route-guid",
   583  						SpaceGUID: spaceGUID,
   584  					}
   585  					fakeV2Actor.GetApplicationRoutesReturns([]v2action.Route{existingRoute}, v2action.Warnings{"app-route-warnings"}, nil)
   586  
   587  					// Assumes new route
   588  					fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, v2action.RouteNotFoundError{})
   589  				})
   590  
   591  				It("adds the default route to desired routes", func() {
   592  					Expect(executeErr).ToNot(HaveOccurred())
   593  					Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "app-route-warnings", "get-route-warnings"))
   594  					Expect(firstConfig.DesiredRoutes).To(ConsistOf(
   595  						existingRoute,
   596  						v2action.Route{
   597  							Domain:    domain,
   598  							Host:      appName,
   599  							SpaceGUID: spaceGUID,
   600  						}))
   601  				})
   602  			})
   603  
   604  			Context("when retrieving the default route errors", func() {
   605  				var expectedErr error
   606  
   607  				BeforeEach(func() {
   608  					expectedErr = errors.New("dios mio")
   609  					fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, expectedErr)
   610  				})
   611  
   612  				It("returns the error and warnings", func() {
   613  					Expect(executeErr).To(MatchError(expectedErr))
   614  					Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "get-route-warnings"))
   615  				})
   616  			})
   617  		})
   618  
   619  		Context("when scanning for files", func() {
   620  			Context("given a directory", func() {
   621  				Context("when scanning is successful", func() {
   622  					var resources []sharedaction.Resource
   623  
   624  					BeforeEach(func() {
   625  						resources = []sharedaction.Resource{
   626  							{Filename: "I am a file!"},
   627  							{Filename: "I am not a file"},
   628  						}
   629  						fakeSharedActor.GatherDirectoryResourcesReturns(resources, nil)
   630  					})
   631  
   632  					It("sets the full resource list on the config", func() {
   633  						Expect(executeErr).ToNot(HaveOccurred())
   634  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
   635  						Expect(firstConfig.AllResources).To(Equal(actor.ConvertSharedResourcesToV2Resources(resources)))
   636  						Expect(firstConfig.Path).To(Equal(filesPath))
   637  						Expect(firstConfig.Archive).To(BeFalse())
   638  
   639  						Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(1))
   640  						Expect(fakeSharedActor.GatherDirectoryResourcesArgsForCall(0)).To(Equal(filesPath))
   641  					})
   642  				})
   643  
   644  				Context("when scanning errors", func() {
   645  					var expectedErr error
   646  
   647  					BeforeEach(func() {
   648  						expectedErr = errors.New("dios mio")
   649  						fakeSharedActor.GatherDirectoryResourcesReturns(nil, expectedErr)
   650  					})
   651  
   652  					It("returns the error and warnings", func() {
   653  						Expect(executeErr).To(MatchError(expectedErr))
   654  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
   655  					})
   656  				})
   657  			})
   658  
   659  			Context("given an archive", func() {
   660  				var archive string
   661  
   662  				BeforeEach(func() {
   663  					f, err := ioutil.TempFile("", "convert-to-application-configs-archive")
   664  					Expect(err).ToNot(HaveOccurred())
   665  					archive = f.Name()
   666  					Expect(f.Close()).ToNot(HaveOccurred())
   667  
   668  					// The temp file created on OSX contains a symlink and needs to be evaluated.
   669  					archive, err = filepath.EvalSymlinks(archive)
   670  					Expect(err).ToNot(HaveOccurred())
   671  
   672  					manifestApps[0].Path = archive
   673  				})
   674  
   675  				AfterEach(func() {
   676  					Expect(os.RemoveAll(archive)).ToNot(HaveOccurred())
   677  				})
   678  
   679  				Context("when scanning is successful", func() {
   680  					var resources []sharedaction.Resource
   681  
   682  					BeforeEach(func() {
   683  						resources = []sharedaction.Resource{
   684  							{Filename: "I am a file!"},
   685  							{Filename: "I am not a file"},
   686  						}
   687  						fakeSharedActor.GatherArchiveResourcesReturns(resources, nil)
   688  					})
   689  
   690  					It("sets the full resource list on the config", func() {
   691  						Expect(executeErr).ToNot(HaveOccurred())
   692  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
   693  						Expect(firstConfig.AllResources).To(Equal(actor.ConvertSharedResourcesToV2Resources(resources)))
   694  						Expect(firstConfig.Path).To(Equal(archive))
   695  						Expect(firstConfig.Archive).To(BeTrue())
   696  
   697  						Expect(fakeSharedActor.GatherArchiveResourcesCallCount()).To(Equal(1))
   698  						Expect(fakeSharedActor.GatherArchiveResourcesArgsForCall(0)).To(Equal(archive))
   699  					})
   700  				})
   701  
   702  				Context("when scanning errors", func() {
   703  					var expectedErr error
   704  
   705  					BeforeEach(func() {
   706  						expectedErr = errors.New("dios mio")
   707  						fakeSharedActor.GatherArchiveResourcesReturns(nil, expectedErr)
   708  					})
   709  
   710  					It("returns the error and warnings", func() {
   711  						Expect(executeErr).To(MatchError(expectedErr))
   712  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
   713  					})
   714  				})
   715  			})
   716  		})
   717  
   718  		Context("when a docker image is configured", func() {
   719  			BeforeEach(func() {
   720  				manifestApps[0].DockerImage = "some-docker-image-path"
   721  			})
   722  
   723  			It("sets the docker image on DesiredApplication and does not gather resources", func() {
   724  				Expect(executeErr).ToNot(HaveOccurred())
   725  				Expect(firstConfig.DesiredApplication.DockerImage).To(Equal("some-docker-image-path"))
   726  
   727  				Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(0))
   728  			})
   729  		})
   730  	})
   731  })