github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/actor/v7action/package_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/resources"
     5  	"errors"
     6  	"io"
     7  	"strings"
     8  
     9  	"code.cloudfoundry.org/cli/actor/actionerror"
    10  	"code.cloudfoundry.org/cli/actor/sharedaction"
    11  	. "code.cloudfoundry.org/cli/actor/v7action"
    12  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
    13  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    14  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    15  
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/ginkgo/extensions/table"
    18  	. "github.com/onsi/gomega"
    19  	. "github.com/onsi/gomega/gstruct"
    20  )
    21  
    22  var _ = Describe("Package Actions", func() {
    23  	var (
    24  		actor                     *Actor
    25  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    26  		fakeSharedActor           *v7actionfakes.FakeSharedActor
    27  		fakeConfig                *v7actionfakes.FakeConfig
    28  	)
    29  
    30  	BeforeEach(func() {
    31  		fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
    32  		fakeConfig = new(v7actionfakes.FakeConfig)
    33  		fakeSharedActor = new(v7actionfakes.FakeSharedActor)
    34  		actor = NewActor(fakeCloudControllerClient, fakeConfig, fakeSharedActor, nil)
    35  	})
    36  
    37  	Describe("GetApplicationPackages", func() {
    38  		When("there are no client errors", func() {
    39  			BeforeEach(func() {
    40  				fakeCloudControllerClient.GetApplicationsReturns(
    41  					[]resources.Application{
    42  						{GUID: "some-app-guid"},
    43  					},
    44  					ccv3.Warnings{"get-applications-warning"},
    45  					nil,
    46  				)
    47  
    48  				fakeCloudControllerClient.GetPackagesReturns(
    49  					[]resources.Package{
    50  						{
    51  							GUID:      "some-package-guid-1",
    52  							State:     constant.PackageReady,
    53  							CreatedAt: "2017-08-14T21:16:42Z",
    54  						},
    55  						{
    56  							GUID:      "some-package-guid-2",
    57  							State:     constant.PackageFailed,
    58  							CreatedAt: "2017-08-16T00:18:24Z",
    59  						},
    60  					},
    61  					ccv3.Warnings{"get-application-packages-warning"},
    62  					nil,
    63  				)
    64  			})
    65  
    66  			It("gets the app's packages", func() {
    67  				packages, warnings, err := actor.GetApplicationPackages("some-app-name", "some-space-guid")
    68  
    69  				Expect(err).ToNot(HaveOccurred())
    70  				Expect(warnings).To(ConsistOf("get-applications-warning", "get-application-packages-warning"))
    71  				Expect(packages).To(Equal([]Package{
    72  					{
    73  						GUID:      "some-package-guid-1",
    74  						State:     constant.PackageReady,
    75  						CreatedAt: "2017-08-14T21:16:42Z",
    76  					},
    77  					{
    78  						GUID:      "some-package-guid-2",
    79  						State:     constant.PackageFailed,
    80  						CreatedAt: "2017-08-16T00:18:24Z",
    81  					},
    82  				}))
    83  
    84  				Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
    85  				Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
    86  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app-name"}},
    87  					ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}},
    88  				))
    89  
    90  				Expect(fakeCloudControllerClient.GetPackagesCallCount()).To(Equal(1))
    91  				Expect(fakeCloudControllerClient.GetPackagesArgsForCall(0)).To(ConsistOf(
    92  					ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{"some-app-guid"}},
    93  				))
    94  			})
    95  		})
    96  
    97  		When("getting the application fails", func() {
    98  			var expectedErr error
    99  
   100  			BeforeEach(func() {
   101  				expectedErr = errors.New("some get application error")
   102  
   103  				fakeCloudControllerClient.GetApplicationsReturns(
   104  					[]resources.Application{},
   105  					ccv3.Warnings{"get-applications-warning"},
   106  					expectedErr,
   107  				)
   108  			})
   109  
   110  			It("returns the error", func() {
   111  				_, warnings, err := actor.GetApplicationPackages("some-app-name", "some-space-guid")
   112  
   113  				Expect(err).To(Equal(expectedErr))
   114  				Expect(warnings).To(ConsistOf("get-applications-warning"))
   115  			})
   116  		})
   117  
   118  		When("getting the application packages fails", func() {
   119  			var expectedErr error
   120  
   121  			BeforeEach(func() {
   122  				expectedErr = errors.New("some get application error")
   123  
   124  				fakeCloudControllerClient.GetApplicationsReturns(
   125  					[]resources.Application{
   126  						{GUID: "some-app-guid"},
   127  					},
   128  					ccv3.Warnings{"get-applications-warning"},
   129  					nil,
   130  				)
   131  
   132  				fakeCloudControllerClient.GetPackagesReturns(
   133  					[]resources.Package{},
   134  					ccv3.Warnings{"get-application-packages-warning"},
   135  					expectedErr,
   136  				)
   137  			})
   138  
   139  			It("returns the error", func() {
   140  				_, warnings, err := actor.GetApplicationPackages("some-app-name", "some-space-guid")
   141  
   142  				Expect(err).To(Equal(expectedErr))
   143  				Expect(warnings).To(ConsistOf("get-applications-warning", "get-application-packages-warning"))
   144  			})
   145  		})
   146  	})
   147  
   148  	Describe("CreateDockerPackageByApplicationNameAndSpace", func() {
   149  		var (
   150  			dockerPackage Package
   151  			warnings      Warnings
   152  			executeErr    error
   153  		)
   154  
   155  		JustBeforeEach(func() {
   156  			dockerPackage, warnings, executeErr = actor.CreateDockerPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", DockerImageCredentials{Path: "some-docker-image", Password: "some-password", Username: "some-username"})
   157  		})
   158  
   159  		When("the application can't be retrieved", func() {
   160  			BeforeEach(func() {
   161  				fakeCloudControllerClient.GetApplicationsReturns(
   162  					[]resources.Application{},
   163  					ccv3.Warnings{"some-app-warning"},
   164  					errors.New("some-app-error"),
   165  				)
   166  			})
   167  
   168  			It("returns the error and all warnings", func() {
   169  				Expect(executeErr).To(MatchError("some-app-error"))
   170  				Expect(warnings).To(ConsistOf("some-app-warning"))
   171  			})
   172  		})
   173  
   174  		When("the application can be retrieved", func() {
   175  			BeforeEach(func() {
   176  				fakeCloudControllerClient.GetApplicationsReturns(
   177  					[]resources.Application{
   178  						{
   179  							Name: "some-app-name",
   180  							GUID: "some-app-guid",
   181  						},
   182  					},
   183  					ccv3.Warnings{"some-app-warning"},
   184  					nil,
   185  				)
   186  			})
   187  
   188  			When("creating the package fails", func() {
   189  				BeforeEach(func() {
   190  					fakeCloudControllerClient.CreatePackageReturns(
   191  						resources.Package{},
   192  						ccv3.Warnings{"some-create-package-warning"},
   193  						errors.New("some-create-package-error"),
   194  					)
   195  				})
   196  				It("fails to create the package", func() {
   197  					Expect(executeErr).To(MatchError("some-create-package-error"))
   198  					Expect(warnings).To(ConsistOf("some-app-warning", "some-create-package-warning"))
   199  				})
   200  			})
   201  
   202  			When("creating the package succeeds", func() {
   203  				BeforeEach(func() {
   204  					createdPackage := resources.Package{
   205  						DockerImage:    "some-docker-image",
   206  						DockerUsername: "some-username",
   207  						DockerPassword: "some-password",
   208  						GUID:           "some-pkg-guid",
   209  						State:          constant.PackageReady,
   210  						Relationships: resources.Relationships{
   211  							constant.RelationshipTypeApplication: resources.Relationship{
   212  								GUID: "some-app-guid",
   213  							},
   214  						},
   215  					}
   216  
   217  					fakeCloudControllerClient.CreatePackageReturns(
   218  						createdPackage,
   219  						ccv3.Warnings{"some-create-package-warning"},
   220  						nil,
   221  					)
   222  				})
   223  
   224  				It("calls CC to create the package and returns the package", func() {
   225  					Expect(executeErr).ToNot(HaveOccurred())
   226  					Expect(warnings).To(ConsistOf("some-app-warning", "some-create-package-warning"))
   227  
   228  					expectedPackage := resources.Package{
   229  						DockerImage:    "some-docker-image",
   230  						DockerUsername: "some-username",
   231  						DockerPassword: "some-password",
   232  						GUID:           "some-pkg-guid",
   233  						State:          constant.PackageReady,
   234  						Relationships: resources.Relationships{
   235  							constant.RelationshipTypeApplication: resources.Relationship{
   236  								GUID: "some-app-guid",
   237  							},
   238  						},
   239  					}
   240  					Expect(dockerPackage).To(Equal(Package(expectedPackage)))
   241  
   242  					Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
   243  					Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
   244  						ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app-name"}},
   245  						ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}},
   246  					))
   247  
   248  					Expect(fakeCloudControllerClient.CreatePackageCallCount()).To(Equal(1))
   249  					Expect(fakeCloudControllerClient.CreatePackageArgsForCall(0)).To(Equal(resources.Package{
   250  						Type:           constant.PackageTypeDocker,
   251  						DockerImage:    "some-docker-image",
   252  						DockerUsername: "some-username",
   253  						DockerPassword: "some-password",
   254  						Relationships: resources.Relationships{
   255  							constant.RelationshipTypeApplication: resources.Relationship{GUID: "some-app-guid"},
   256  						},
   257  					}))
   258  				})
   259  			})
   260  		})
   261  	})
   262  
   263  	Describe("CreateBitsPackageByApplication", func() {
   264  		var (
   265  			appGUID string
   266  
   267  			pkg        Package
   268  			executeErr error
   269  			warnings   Warnings
   270  		)
   271  
   272  		JustBeforeEach(func() {
   273  			pkg, warnings, executeErr = actor.CreateBitsPackageByApplication(appGUID)
   274  		})
   275  
   276  		When("creating the package fails", func() {
   277  			BeforeEach(func() {
   278  				fakeCloudControllerClient.CreatePackageReturns(
   279  					resources.Package{},
   280  					ccv3.Warnings{"create-package-warning"},
   281  					errors.New("some-create-error"),
   282  				)
   283  			})
   284  
   285  			It("returns the error", func() {
   286  				Expect(executeErr).To(MatchError("some-create-error"))
   287  				Expect(warnings).To(ConsistOf("create-package-warning"))
   288  			})
   289  		})
   290  
   291  		When("creating the package succeeds", func() {
   292  			var createdPackage resources.Package
   293  
   294  			BeforeEach(func() {
   295  				createdPackage = resources.Package{GUID: "some-pkg-guid"}
   296  				fakeCloudControllerClient.CreatePackageReturns(
   297  					createdPackage,
   298  					ccv3.Warnings{"create-package-warning"},
   299  					nil,
   300  				)
   301  			})
   302  
   303  			It("returns all warnings and the package", func() {
   304  				Expect(executeErr).ToNot(HaveOccurred())
   305  
   306  				Expect(fakeCloudControllerClient.CreatePackageCallCount()).To(Equal(1))
   307  				Expect(fakeCloudControllerClient.CreatePackageArgsForCall(0)).To(Equal(resources.Package{
   308  					Type: constant.PackageTypeBits,
   309  					Relationships: resources.Relationships{
   310  						constant.RelationshipTypeApplication: resources.Relationship{GUID: appGUID},
   311  					},
   312  				}))
   313  
   314  				Expect(warnings).To(ConsistOf("create-package-warning"))
   315  				Expect(pkg).To(MatchFields(IgnoreExtras, Fields{
   316  					"GUID": Equal("some-pkg-guid"),
   317  				}))
   318  			})
   319  		})
   320  	})
   321  
   322  	Describe("UploadBitsPackage", func() {
   323  		var (
   324  			pkg              Package
   325  			matchedResources []sharedaction.V3Resource
   326  			reader           io.Reader
   327  			readerLength     int64
   328  
   329  			appPkg     Package
   330  			warnings   Warnings
   331  			executeErr error
   332  		)
   333  
   334  		BeforeEach(func() {
   335  			pkg = Package{GUID: "some-package-guid"}
   336  
   337  			matchedResources = []sharedaction.V3Resource{{FilePath: "some-resource"}, {FilePath: "another-resource"}}
   338  			someString := "who reads these days"
   339  			reader = strings.NewReader(someString)
   340  			readerLength = int64(len([]byte(someString)))
   341  		})
   342  
   343  		JustBeforeEach(func() {
   344  			appPkg, warnings, executeErr = actor.UploadBitsPackage(pkg, matchedResources, reader, readerLength)
   345  		})
   346  
   347  		When("the upload is successful", func() {
   348  			BeforeEach(func() {
   349  				fakeCloudControllerClient.UploadBitsPackageReturns(resources.Package{GUID: "some-package-guid"}, ccv3.Warnings{"upload-warning-1", "upload-warning-2"}, nil)
   350  			})
   351  
   352  			It("returns all warnings", func() {
   353  				Expect(executeErr).ToNot(HaveOccurred())
   354  				Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2"))
   355  				Expect(appPkg).To(Equal(Package{GUID: "some-package-guid"}))
   356  
   357  				Expect(fakeCloudControllerClient.UploadBitsPackageCallCount()).To(Equal(1))
   358  				passedPackage, passedExistingResources, passedReader, passedReaderLength := fakeCloudControllerClient.UploadBitsPackageArgsForCall(0)
   359  				Expect(passedPackage).To(Equal(resources.Package(appPkg)))
   360  				Expect(passedExistingResources).To(ConsistOf(ccv3.Resource{FilePath: "some-resource"}, ccv3.Resource{FilePath: "another-resource"}))
   361  				Expect(passedReader).To(Equal(reader))
   362  				Expect(passedReaderLength).To(Equal(readerLength))
   363  			})
   364  		})
   365  
   366  		When("the upload returns an error", func() {
   367  			var err error
   368  
   369  			BeforeEach(func() {
   370  				err = errors.New("some-error")
   371  				fakeCloudControllerClient.UploadBitsPackageReturns(resources.Package{}, ccv3.Warnings{"upload-warning-1", "upload-warning-2"}, err)
   372  			})
   373  
   374  			It("returns the error", func() {
   375  				Expect(executeErr).To(MatchError(err))
   376  				Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2"))
   377  			})
   378  		})
   379  	})
   380  
   381  	Describe("PollPackage", func() {
   382  		Context("Polling Behavior", func() {
   383  			var (
   384  				pkg Package
   385  
   386  				appPkg     Package
   387  				warnings   Warnings
   388  				executeErr error
   389  			)
   390  
   391  			BeforeEach(func() {
   392  				pkg = Package{
   393  					GUID: "some-pkg-guid",
   394  				}
   395  
   396  				warnings = nil
   397  				executeErr = nil
   398  
   399  				// putting this here so the tests don't hang on polling
   400  				fakeCloudControllerClient.GetPackageReturns(
   401  					resources.Package{
   402  						GUID:  "some-pkg-guid",
   403  						State: constant.PackageReady,
   404  					},
   405  					ccv3.Warnings{},
   406  					nil,
   407  				)
   408  			})
   409  
   410  			JustBeforeEach(func() {
   411  				appPkg, warnings, executeErr = actor.PollPackage(pkg)
   412  			})
   413  
   414  			When("the polling errors", func() {
   415  				var expectedErr error
   416  
   417  				BeforeEach(func() {
   418  					expectedErr = errors.New("Fake error during polling")
   419  					fakeCloudControllerClient.GetPackageReturns(
   420  						resources.Package{},
   421  						ccv3.Warnings{"some-get-pkg-warning"},
   422  						expectedErr,
   423  					)
   424  				})
   425  
   426  				It("returns the error and warnings", func() {
   427  					Expect(executeErr).To(MatchError(expectedErr))
   428  					Expect(warnings).To(ConsistOf("some-get-pkg-warning"))
   429  				})
   430  			})
   431  
   432  			When("the polling is successful", func() {
   433  				It("returns the package", func() {
   434  					Expect(executeErr).ToNot(HaveOccurred())
   435  
   436  					expectedPackage := resources.Package{
   437  						GUID:  "some-pkg-guid",
   438  						State: constant.PackageReady,
   439  					}
   440  
   441  					Expect(appPkg).To(Equal(Package(expectedPackage)))
   442  					Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(1))
   443  					Expect(fakeCloudControllerClient.GetPackageArgsForCall(0)).To(Equal("some-pkg-guid"))
   444  				})
   445  			})
   446  		})
   447  
   448  		DescribeTable("Polling states",
   449  			func(finalState constant.PackageState, expectedErr error) {
   450  				fakeCloudControllerClient.GetPackageReturns(
   451  					resources.Package{GUID: "some-pkg-guid", State: constant.PackageAwaitingUpload},
   452  					ccv3.Warnings{"poll-package-warning"},
   453  					nil,
   454  				)
   455  
   456  				fakeCloudControllerClient.GetPackageReturnsOnCall(
   457  					1,
   458  					resources.Package{State: finalState},
   459  					ccv3.Warnings{"poll-package-warning"},
   460  					nil,
   461  				)
   462  
   463  				_, tableWarnings, err := actor.PollPackage(Package{
   464  					GUID: "some-pkg-guid",
   465  				})
   466  
   467  				if expectedErr == nil {
   468  					Expect(err).ToNot(HaveOccurred())
   469  				} else {
   470  					Expect(err).To(MatchError(expectedErr))
   471  				}
   472  
   473  				Expect(tableWarnings).To(ConsistOf("poll-package-warning", "poll-package-warning"))
   474  
   475  				Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(2))
   476  				Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(2))
   477  			},
   478  
   479  			Entry("READY", constant.PackageReady, nil),
   480  			Entry("FAILED", constant.PackageFailed, actionerror.PackageProcessingFailedError{}),
   481  			Entry("EXPIRED", constant.PackageExpired, actionerror.PackageProcessingExpiredError{}),
   482  		)
   483  	})
   484  })