code.cloudfoundry.org/cli@v7.1.0+incompatible/actor/v2action/manifest_test.go (about)

     1  package v2action_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	. "code.cloudfoundry.org/cli/actor/v2action"
     7  	"code.cloudfoundry.org/cli/actor/v2action/v2actionfakes"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant"
    10  	"code.cloudfoundry.org/cli/types"
    11  	"code.cloudfoundry.org/cli/util/manifest"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  	. "github.com/onsi/gomega/gstruct"
    15  )
    16  
    17  var _ = Describe("Manifest Actions", func() {
    18  	var (
    19  		actor                     *Actor
    20  		fakeCloudControllerClient *v2actionfakes.FakeCloudControllerClient
    21  	)
    22  
    23  	BeforeEach(func() {
    24  		fakeCloudControllerClient = new(v2actionfakes.FakeCloudControllerClient)
    25  		actor = NewActor(fakeCloudControllerClient, nil, nil)
    26  	})
    27  
    28  	Describe("CreateApplicationManifestByNameAndSpace", func() {
    29  		var (
    30  			manifestApp manifest.Application
    31  			warnings    Warnings
    32  			createErr   error
    33  		)
    34  
    35  		JustBeforeEach(func() {
    36  			manifestApp, warnings, createErr = actor.CreateApplicationManifestByNameAndSpace("some-app", "some-space-guid")
    37  		})
    38  
    39  		When("getting the application summary errors", func() {
    40  			BeforeEach(func() {
    41  				fakeCloudControllerClient.GetApplicationsReturns([]ccv2.Application{}, ccv2.Warnings{"some-app-warning"}, errors.New("some-app-error"))
    42  			})
    43  
    44  			It("returns the error and all warnings", func() {
    45  				Expect(createErr).To(MatchError("some-app-error"))
    46  				Expect(warnings).To(ConsistOf("some-app-warning"))
    47  			})
    48  		})
    49  
    50  		When("getting the application summary succeeds", func() {
    51  			var app ccv2.Application
    52  
    53  			Describe("buildpacks", func() {
    54  				When("buildpack is not set", func() {
    55  					It("does not populate buildpacks field", func() {
    56  						Expect(manifestApp.Buildpacks).To(BeNil())
    57  					})
    58  				})
    59  
    60  				When("buildpack is set", func() {
    61  					BeforeEach(func() {
    62  						app = ccv2.Application{
    63  							GUID: "some-app-guid",
    64  							Name: "some-app",
    65  							Buildpack: types.FilteredString{
    66  								IsSet: true,
    67  								Value: "some-buildpack",
    68  							},
    69  						}
    70  
    71  						fakeCloudControllerClient.GetApplicationsReturns(
    72  							[]ccv2.Application{app},
    73  							ccv2.Warnings{"some-app-warning"},
    74  							nil)
    75  					})
    76  
    77  					It("populates buildpacks field", func() {
    78  						Expect(manifestApp.Buildpacks).To(ConsistOf("some-buildpack"))
    79  					})
    80  				})
    81  
    82  				When("buildpack and detected buildpack are set", func() {
    83  					BeforeEach(func() {
    84  						app = ccv2.Application{
    85  							GUID: "some-app-guid",
    86  							Name: "some-app",
    87  							Buildpack: types.FilteredString{
    88  								IsSet: true,
    89  								Value: "some-buildpack",
    90  							},
    91  							DetectedBuildpack: types.FilteredString{
    92  								IsSet: true,
    93  								Value: "some-detected-buildpack",
    94  							},
    95  						}
    96  
    97  						fakeCloudControllerClient.GetApplicationsReturns(
    98  							[]ccv2.Application{app},
    99  							ccv2.Warnings{"some-app-warning"},
   100  							nil)
   101  					})
   102  
   103  					It("populates buildpacks field with the buildpack", func() {
   104  						Expect(createErr).NotTo(HaveOccurred())
   105  						Expect(manifestApp.Buildpacks).To(ConsistOf("some-buildpack"))
   106  					})
   107  				})
   108  			})
   109  
   110  			Describe("docker images", func() {
   111  				When("docker image and username are provided", func() {
   112  					BeforeEach(func() {
   113  						app = ccv2.Application{
   114  							GUID:        "some-app-guid",
   115  							Name:        "some-app",
   116  							DockerImage: "some-docker-image",
   117  							DockerCredentials: ccv2.DockerCredentials{
   118  								Username: "some-docker-username",
   119  								Password: "some-docker-password", // CC currently always returns an empty string
   120  							},
   121  						}
   122  
   123  						fakeCloudControllerClient.GetApplicationsReturns(
   124  							[]ccv2.Application{app},
   125  							ccv2.Warnings{"some-app-warning"},
   126  							nil)
   127  					})
   128  
   129  					It("populates docker image and username", func() {
   130  						Expect(createErr).NotTo(HaveOccurred())
   131  						Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   132  							"DockerImage":    Equal("some-docker-image"),
   133  							"DockerUsername": Equal("some-docker-username"),
   134  						}))
   135  					})
   136  				})
   137  
   138  				When("docker image and username are not provided", func() {
   139  					BeforeEach(func() {
   140  						app = ccv2.Application{
   141  							GUID: "some-app-guid",
   142  							Name: "some-app",
   143  						}
   144  
   145  						fakeCloudControllerClient.GetApplicationsReturns(
   146  							[]ccv2.Application{app},
   147  							ccv2.Warnings{"some-app-warning"},
   148  							nil)
   149  					})
   150  					It("does not include it in manifest", func() {
   151  						Expect(createErr).NotTo(HaveOccurred())
   152  						Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   153  							"DockerImage":    BeEmpty(),
   154  							"DockerUsername": BeEmpty(),
   155  						}))
   156  					})
   157  				})
   158  			})
   159  
   160  			Describe("health check", func() {
   161  				When("the health check type is http", func() {
   162  					When("the health check endpoint path is '/'", func() {
   163  						BeforeEach(func() {
   164  							app = ccv2.Application{
   165  								GUID:                    "some-app-guid",
   166  								Name:                    "some-app",
   167  								HealthCheckType:         constant.ApplicationHealthCheckHTTP,
   168  								HealthCheckHTTPEndpoint: "/",
   169  							}
   170  							fakeCloudControllerClient.GetApplicationsReturns(
   171  								[]ccv2.Application{app},
   172  								ccv2.Warnings{"some-app-warning"},
   173  								nil)
   174  						})
   175  
   176  						It("does not include health check endpoint in manifest", func() {
   177  							Expect(createErr).NotTo(HaveOccurred())
   178  							Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   179  								"HealthCheckType":         Equal("http"),
   180  								"HealthCheckHTTPEndpoint": BeEmpty(),
   181  							}))
   182  						})
   183  					})
   184  
   185  					When("the health check endpoint path is not the default", func() {
   186  						BeforeEach(func() {
   187  							app = ccv2.Application{
   188  								GUID:                    "some-app-guid",
   189  								Name:                    "some-app",
   190  								HealthCheckType:         constant.ApplicationHealthCheckHTTP,
   191  								HealthCheckHTTPEndpoint: "/whatever",
   192  							}
   193  							fakeCloudControllerClient.GetApplicationsReturns(
   194  								[]ccv2.Application{app},
   195  								ccv2.Warnings{"some-app-warning"},
   196  								nil)
   197  						})
   198  
   199  						It("populates the health check endpoint in manifest", func() {
   200  							Expect(createErr).NotTo(HaveOccurred())
   201  							Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   202  								"HealthCheckType":         Equal("http"),
   203  								"HealthCheckHTTPEndpoint": Equal("/whatever"),
   204  							}))
   205  						})
   206  					})
   207  				})
   208  
   209  				When("the health check type is process", func() {
   210  					BeforeEach(func() {
   211  						app = ccv2.Application{
   212  							GUID:                    "some-app-guid",
   213  							Name:                    "some-app",
   214  							HealthCheckType:         constant.ApplicationHealthCheckProcess,
   215  							HealthCheckHTTPEndpoint: "/",
   216  						}
   217  						fakeCloudControllerClient.GetApplicationsReturns(
   218  							[]ccv2.Application{app},
   219  							ccv2.Warnings{"some-app-warning"},
   220  							nil)
   221  					})
   222  
   223  					It("only populates health check type", func() {
   224  						Expect(createErr).NotTo(HaveOccurred())
   225  						Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   226  							"HealthCheckType":         Equal("process"),
   227  							"HealthCheckHTTPEndpoint": BeEmpty(),
   228  						}))
   229  					})
   230  				})
   231  
   232  				When("the health check type is port", func() {
   233  					BeforeEach(func() {
   234  						app = ccv2.Application{
   235  							GUID:                    "some-app-guid",
   236  							Name:                    "some-app",
   237  							HealthCheckType:         constant.ApplicationHealthCheckPort,
   238  							HealthCheckHTTPEndpoint: "/",
   239  						}
   240  						fakeCloudControllerClient.GetApplicationsReturns(
   241  							[]ccv2.Application{app},
   242  							ccv2.Warnings{"some-app-warning"},
   243  							nil)
   244  					})
   245  
   246  					It("does not include health check type and endpoint", func() {
   247  						Expect(createErr).NotTo(HaveOccurred())
   248  						Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   249  							"HealthCheckType":         BeEmpty(),
   250  							"HealthCheckHTTPEndpoint": BeEmpty(),
   251  						}))
   252  					})
   253  				})
   254  			})
   255  
   256  			Describe("routes", func() {
   257  				BeforeEach(func() {
   258  					app = ccv2.Application{
   259  						GUID: "some-app-guid",
   260  						Name: "some-app",
   261  					}
   262  
   263  					fakeCloudControllerClient.GetApplicationsReturns(
   264  						[]ccv2.Application{app},
   265  						ccv2.Warnings{"some-app-warning"},
   266  						nil)
   267  				})
   268  
   269  				When("routes are set", func() {
   270  					BeforeEach(func() {
   271  						fakeCloudControllerClient.GetApplicationRoutesReturns(
   272  							[]ccv2.Route{
   273  								{
   274  									GUID:       "some-route-1-guid",
   275  									Host:       "host-1",
   276  									DomainGUID: "some-domain-guid",
   277  								},
   278  								{
   279  									GUID:       "some-route-2-guid",
   280  									Host:       "host-2",
   281  									DomainGUID: "some-domain-guid",
   282  								},
   283  							},
   284  							ccv2.Warnings{"some-routes-warning"},
   285  							nil)
   286  
   287  						fakeCloudControllerClient.GetSharedDomainReturns(
   288  							ccv2.Domain{GUID: "some-domain-guid", Name: "some-domain"},
   289  							ccv2.Warnings{"some-domain-warning"},
   290  							nil)
   291  					})
   292  					It("populates the routes", func() {
   293  						Expect(createErr).NotTo(HaveOccurred())
   294  						Expect(manifestApp.Routes).To(ConsistOf("host-1.some-domain", "host-2.some-domain"))
   295  					})
   296  				})
   297  
   298  				When("there are no routes", func() {
   299  					It("returns the app with no-route set to true", func() {
   300  						Expect(createErr).NotTo(HaveOccurred())
   301  						Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   302  							"Routes":  BeEmpty(),
   303  							"NoRoute": Equal(true),
   304  						}))
   305  					})
   306  				})
   307  			})
   308  
   309  			Describe("services", func() {
   310  				BeforeEach(func() {
   311  					app = ccv2.Application{
   312  						GUID: "some-app-guid",
   313  						Name: "some-app",
   314  					}
   315  
   316  					fakeCloudControllerClient.GetApplicationsReturns(
   317  						[]ccv2.Application{app},
   318  						ccv2.Warnings{"some-app-warning"},
   319  						nil)
   320  				})
   321  
   322  				When("getting services fails", func() {
   323  					BeforeEach(func() {
   324  						fakeCloudControllerClient.GetServiceBindingsReturns(
   325  							[]ccv2.ServiceBinding{},
   326  							ccv2.Warnings{"some-service-warning"},
   327  							errors.New("some-service-error"),
   328  						)
   329  					})
   330  
   331  					It("returns the error and all warnings", func() {
   332  						Expect(createErr).To(MatchError("some-service-error"))
   333  						Expect(warnings).To(ConsistOf("some-app-warning", "some-service-warning"))
   334  					})
   335  				})
   336  
   337  				When("getting services succeeds", func() {
   338  					BeforeEach(func() {
   339  						fakeCloudControllerClient.GetServiceBindingsReturns(
   340  							[]ccv2.ServiceBinding{
   341  								{ServiceInstanceGUID: "service-1-guid"},
   342  								{ServiceInstanceGUID: "service-2-guid"},
   343  							},
   344  							ccv2.Warnings{"some-service-warning"},
   345  							nil,
   346  						)
   347  						fakeCloudControllerClient.GetServiceInstanceStub = func(serviceInstanceGUID string) (ccv2.ServiceInstance, ccv2.Warnings, error) {
   348  							switch serviceInstanceGUID {
   349  							case "service-1-guid":
   350  								return ccv2.ServiceInstance{Name: "service-1"}, ccv2.Warnings{"some-service-1-warning"}, nil
   351  							case "service-2-guid":
   352  								return ccv2.ServiceInstance{Name: "service-2"}, ccv2.Warnings{"some-service-2-warning"}, nil
   353  							default:
   354  								panic("unknown service instance")
   355  							}
   356  						}
   357  					})
   358  
   359  					It("creates the corresponding manifest application", func() {
   360  						Expect(createErr).NotTo(HaveOccurred())
   361  						Expect(manifestApp.Services).To(ConsistOf("service-1", "service-2"))
   362  					})
   363  				})
   364  			})
   365  
   366  			Describe("everything else", func() {
   367  				BeforeEach(func() {
   368  					app = ccv2.Application{
   369  						GUID:      "some-app-guid",
   370  						Name:      "some-app",
   371  						DiskQuota: types.NullByteSizeInMb{IsSet: true, Value: 1024},
   372  						Command: types.FilteredString{
   373  							IsSet: true,
   374  							Value: "some-command",
   375  						},
   376  						DetectedStartCommand: types.FilteredString{
   377  							IsSet: true,
   378  							Value: "some-detected-command",
   379  						},
   380  						EnvironmentVariables: map[string]string{
   381  							"env_1": "foo",
   382  							"env_2": "182837403930483038",
   383  							"env_3": "true",
   384  							"env_4": "1.00001",
   385  						},
   386  						HealthCheckTimeout: 120,
   387  						Instances: types.NullInt{
   388  							Value: 10,
   389  							IsSet: true,
   390  						},
   391  						Memory:    types.NullByteSizeInMb{IsSet: true, Value: 200},
   392  						StackGUID: "some-stack-guid",
   393  					}
   394  
   395  					fakeCloudControllerClient.GetApplicationsReturns(
   396  						[]ccv2.Application{app},
   397  						ccv2.Warnings{"some-app-warning"},
   398  						nil)
   399  
   400  					fakeCloudControllerClient.GetStackReturns(
   401  						ccv2.Stack{Name: "some-stack"},
   402  						ccv2.Warnings{"some-stack-warning"},
   403  						nil)
   404  				})
   405  
   406  				It("creates the corresponding manifest application", func() {
   407  					Expect(warnings).To(ConsistOf("some-app-warning", "some-stack-warning"))
   408  					Expect(manifestApp).To(MatchFields(IgnoreExtras, Fields{
   409  						"Name":      Equal("some-app"),
   410  						"DiskQuota": Equal(types.NullByteSizeInMb{IsSet: true, Value: 1024}),
   411  						"Command": Equal(types.FilteredString{
   412  							IsSet: true,
   413  							Value: "some-command",
   414  						}),
   415  						"EnvironmentVariables": Equal(map[string]string{
   416  							"env_1": "foo",
   417  							"env_2": "182837403930483038",
   418  							"env_3": "true",
   419  							"env_4": "1.00001",
   420  						}),
   421  						"HealthCheckTimeout": BeEquivalentTo(120),
   422  						"Instances": Equal(types.NullInt{
   423  							Value: 10,
   424  							IsSet: true,
   425  						}),
   426  						"Memory":    Equal(types.NullByteSizeInMb{IsSet: true, Value: 200}),
   427  						"StackName": Equal("some-stack"),
   428  					}))
   429  				})
   430  			})
   431  		})
   432  	})
   433  })