github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/actor/pushaction/resource_test.go (about)

     1  package pushaction_test
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"strings"
     9  
    10  	. "code.cloudfoundry.org/cli/actor/pushaction"
    11  	"code.cloudfoundry.org/cli/actor/pushaction/pushactionfakes"
    12  	"code.cloudfoundry.org/cli/actor/v2action"
    13  
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  var _ = Describe("Resources", func() {
    19  	var (
    20  		actor           *Actor
    21  		fakeV2Actor     *pushactionfakes.FakeV2Actor
    22  		fakeSharedActor *pushactionfakes.FakeSharedActor
    23  	)
    24  
    25  	BeforeEach(func() {
    26  		fakeV2Actor = new(pushactionfakes.FakeV2Actor)
    27  		fakeSharedActor = new(pushactionfakes.FakeSharedActor)
    28  		actor = NewActor(fakeV2Actor, nil, fakeSharedActor)
    29  	})
    30  
    31  	Describe("CreateArchive", func() {
    32  		var (
    33  			config ApplicationConfig
    34  
    35  			archivePath string
    36  			executeErr  error
    37  
    38  			resourcesToArchive []v2action.Resource
    39  		)
    40  
    41  		BeforeEach(func() {
    42  			config = ApplicationConfig{
    43  				Path: "some-path",
    44  				DesiredApplication: Application{
    45  					Application: v2action.Application{
    46  						GUID: "some-app-guid",
    47  					}},
    48  			}
    49  
    50  			resourcesToArchive = []v2action.Resource{{Filename: "file1"}, {Filename: "file2"}}
    51  			config.UnmatchedResources = resourcesToArchive
    52  		})
    53  
    54  		JustBeforeEach(func() {
    55  			archivePath, executeErr = actor.CreateArchive(config)
    56  		})
    57  
    58  		Context("when the source is an archive", func() {
    59  			BeforeEach(func() {
    60  				config.Archive = true
    61  			})
    62  
    63  			Context("when the zipping is successful", func() {
    64  				var fakeArchivePath string
    65  
    66  				BeforeEach(func() {
    67  					fakeArchivePath = "some-archive-path"
    68  					fakeSharedActor.ZipArchiveResourcesReturns(fakeArchivePath, nil)
    69  				})
    70  
    71  				It("returns the path to the zip", func() {
    72  					Expect(executeErr).ToNot(HaveOccurred())
    73  					Expect(archivePath).To(Equal(fakeArchivePath))
    74  
    75  					Expect(fakeSharedActor.ZipArchiveResourcesCallCount()).To(Equal(1))
    76  					sourceDir, passedResources := fakeSharedActor.ZipArchiveResourcesArgsForCall(0)
    77  					Expect(sourceDir).To(Equal("some-path"))
    78  					sharedResourcesToArchive := actor.ConvertV2ResourcesToSharedResources(resourcesToArchive)
    79  					Expect(passedResources).To(Equal(sharedResourcesToArchive))
    80  
    81  				})
    82  			})
    83  
    84  			Context("when creating the archive errors", func() {
    85  				var expectedErr error
    86  
    87  				BeforeEach(func() {
    88  					expectedErr = errors.New("oh no")
    89  					fakeSharedActor.ZipArchiveResourcesReturns("", expectedErr)
    90  				})
    91  
    92  				It("sends errors and returns true", func() {
    93  					Expect(executeErr).To(MatchError(expectedErr))
    94  				})
    95  			})
    96  		})
    97  
    98  		Context("when the source is a directory", func() {
    99  			Context("when the zipping is successful", func() {
   100  				var fakeArchivePath string
   101  				BeforeEach(func() {
   102  					fakeArchivePath = "some-archive-path"
   103  					fakeSharedActor.ZipDirectoryResourcesReturns(fakeArchivePath, nil)
   104  				})
   105  
   106  				It("returns the path to the zip", func() {
   107  					Expect(executeErr).ToNot(HaveOccurred())
   108  					Expect(archivePath).To(Equal(fakeArchivePath))
   109  
   110  					Expect(fakeSharedActor.ZipDirectoryResourcesCallCount()).To(Equal(1))
   111  					sourceDir, passedResources := fakeSharedActor.ZipDirectoryResourcesArgsForCall(0)
   112  					Expect(sourceDir).To(Equal("some-path"))
   113  					sharedResourcesToArchive := actor.ConvertV2ResourcesToSharedResources(resourcesToArchive)
   114  					Expect(passedResources).To(Equal(sharedResourcesToArchive))
   115  				})
   116  			})
   117  
   118  			Context("when creating the archive errors", func() {
   119  				var expectedErr error
   120  
   121  				BeforeEach(func() {
   122  					expectedErr = errors.New("oh no")
   123  					fakeSharedActor.ZipDirectoryResourcesReturns("", expectedErr)
   124  				})
   125  
   126  				It("sends errors and returns true", func() {
   127  					Expect(executeErr).To(MatchError(expectedErr))
   128  				})
   129  			})
   130  		})
   131  	})
   132  
   133  	Describe("SetMatchedResources", func() {
   134  		var (
   135  			inputConfig  ApplicationConfig
   136  			outputConfig ApplicationConfig
   137  			warnings     Warnings
   138  		)
   139  		JustBeforeEach(func() {
   140  			outputConfig, warnings = actor.SetMatchedResources(inputConfig)
   141  		})
   142  
   143  		BeforeEach(func() {
   144  			inputConfig.AllResources = []v2action.Resource{
   145  				{Filename: "file-1"},
   146  				{Filename: "file-2"},
   147  			}
   148  		})
   149  
   150  		Context("when the resource matching is successful", func() {
   151  			BeforeEach(func() {
   152  				fakeV2Actor.ResourceMatchReturns(
   153  					[]v2action.Resource{{Filename: "file-1"}},
   154  					[]v2action.Resource{{Filename: "file-2"}},
   155  					v2action.Warnings{"warning-1"},
   156  					nil,
   157  				)
   158  			})
   159  
   160  			It("sets the matched and unmatched resources", func() {
   161  				Expect(outputConfig.MatchedResources).To(ConsistOf(v2action.Resource{Filename: "file-1"}))
   162  				Expect(outputConfig.UnmatchedResources).To(ConsistOf(v2action.Resource{Filename: "file-2"}))
   163  
   164  				Expect(warnings).To(ConsistOf("warning-1"))
   165  			})
   166  		})
   167  
   168  		Context("when resource matching returns an error", func() {
   169  			BeforeEach(func() {
   170  				fakeV2Actor.ResourceMatchReturns(nil, nil, v2action.Warnings{"warning-1"}, errors.New("some-error"))
   171  			})
   172  
   173  			It("sets the unmatched resources to AllResources", func() {
   174  				Expect(outputConfig.UnmatchedResources).To(Equal(inputConfig.AllResources))
   175  
   176  				Expect(warnings).To(ConsistOf("warning-1"))
   177  			})
   178  		})
   179  	})
   180  
   181  	Describe("UploadPackage", func() {
   182  		var (
   183  			config ApplicationConfig
   184  
   185  			warnings   Warnings
   186  			executeErr error
   187  
   188  			resources []v2action.Resource
   189  		)
   190  
   191  		BeforeEach(func() {
   192  			resources = []v2action.Resource{
   193  				{Filename: "file-1"},
   194  				{Filename: "file-2"},
   195  			}
   196  
   197  			config = ApplicationConfig{
   198  				DesiredApplication: Application{
   199  					Application: v2action.Application{
   200  						GUID: "some-app-guid",
   201  					}},
   202  				MatchedResources: resources,
   203  			}
   204  		})
   205  
   206  		JustBeforeEach(func() {
   207  			warnings, executeErr = actor.UploadPackage(config)
   208  		})
   209  
   210  		Context("when the upload is successful", func() {
   211  			var uploadJob v2action.Job
   212  
   213  			BeforeEach(func() {
   214  				uploadJob.GUID = "some-job-guid"
   215  				fakeV2Actor.UploadApplicationPackageReturns(uploadJob, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, nil)
   216  			})
   217  
   218  			Context("when polling is successful", func() {
   219  				BeforeEach(func() {
   220  					fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, nil)
   221  				})
   222  
   223  				It("uploads the existing resources", func() {
   224  					Expect(executeErr).ToNot(HaveOccurred())
   225  					Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2"))
   226  
   227  					Expect(fakeV2Actor.UploadApplicationPackageCallCount()).To(Equal(1))
   228  					appGUID, existingResources, reader, newResourcesLength := fakeV2Actor.UploadApplicationPackageArgsForCall(0)
   229  					Expect(appGUID).To(Equal("some-app-guid"))
   230  					Expect(existingResources).To(Equal(resources))
   231  					Expect(reader).To(BeNil())
   232  					Expect(newResourcesLength).To(BeNumerically("==", 0))
   233  
   234  					Expect(fakeV2Actor.PollJobCallCount()).To(Equal(1))
   235  					Expect(fakeV2Actor.PollJobArgsForCall(0)).To(Equal(uploadJob))
   236  				})
   237  			})
   238  
   239  			Context("when the polling fails", func() {
   240  				var expectedErr error
   241  
   242  				BeforeEach(func() {
   243  					expectedErr = errors.New("I can't let you do that starfox")
   244  					fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, expectedErr)
   245  				})
   246  
   247  				It("returns the warnings", func() {
   248  					Expect(executeErr).To(MatchError(expectedErr))
   249  					Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2"))
   250  				})
   251  			})
   252  		})
   253  
   254  		Context("when the upload errors", func() {
   255  			var expectedErr error
   256  
   257  			BeforeEach(func() {
   258  				expectedErr = errors.New("I can't let you do that starfox")
   259  				fakeV2Actor.UploadApplicationPackageReturns(v2action.Job{}, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, expectedErr)
   260  			})
   261  
   262  			It("returns the error and warnings", func() {
   263  				Expect(executeErr).To(MatchError(expectedErr))
   264  				Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2"))
   265  			})
   266  		})
   267  	})
   268  
   269  	Describe("UploadPackageWithArchive", func() {
   270  		var (
   271  			config          ApplicationConfig
   272  			archivePath     string
   273  			fakeProgressBar *pushactionfakes.FakeProgressBar
   274  			eventStream     chan Event
   275  
   276  			warnings   Warnings
   277  			executeErr error
   278  
   279  			resources []v2action.Resource
   280  		)
   281  
   282  		BeforeEach(func() {
   283  			resources = []v2action.Resource{
   284  				{Filename: "file-1"},
   285  				{Filename: "file-2"},
   286  			}
   287  
   288  			config = ApplicationConfig{
   289  				DesiredApplication: Application{
   290  					Application: v2action.Application{
   291  						GUID: "some-app-guid",
   292  					}},
   293  				MatchedResources: resources,
   294  			}
   295  			fakeProgressBar = new(pushactionfakes.FakeProgressBar)
   296  			eventStream = make(chan Event)
   297  		})
   298  
   299  		AfterEach(func() {
   300  			close(eventStream)
   301  		})
   302  
   303  		JustBeforeEach(func() {
   304  			warnings, executeErr = actor.UploadPackageWithArchive(config, archivePath, fakeProgressBar, eventStream)
   305  		})
   306  
   307  		Context("when the archive can be accessed properly", func() {
   308  			BeforeEach(func() {
   309  				tmpfile, err := ioutil.TempFile("", "fake-archive")
   310  				Expect(err).ToNot(HaveOccurred())
   311  				_, err = tmpfile.Write([]byte("123456"))
   312  				Expect(err).ToNot(HaveOccurred())
   313  				Expect(tmpfile.Close()).ToNot(HaveOccurred())
   314  
   315  				archivePath = tmpfile.Name()
   316  			})
   317  
   318  			AfterEach(func() {
   319  				Expect(os.Remove(archivePath)).ToNot(HaveOccurred())
   320  			})
   321  
   322  			Context("when the upload is successful", func() {
   323  				var (
   324  					progressBarReader io.Reader
   325  					uploadJob         v2action.Job
   326  				)
   327  
   328  				BeforeEach(func() {
   329  					uploadJob.GUID = "some-job-guid"
   330  					fakeV2Actor.UploadApplicationPackageReturns(uploadJob, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, nil)
   331  
   332  					progressBarReader = strings.NewReader("123456")
   333  					fakeProgressBar.NewProgressBarWrapperReturns(progressBarReader)
   334  
   335  					go func() {
   336  						defer GinkgoRecover()
   337  
   338  						Eventually(eventStream).Should(Receive(Equal(UploadingApplicationWithArchive)))
   339  						Eventually(eventStream).Should(Receive(Equal(UploadWithArchiveComplete)))
   340  					}()
   341  				})
   342  
   343  				Context("when the polling is successful", func() {
   344  					BeforeEach(func() {
   345  						fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, nil)
   346  					})
   347  
   348  					It("returns the warnings", func() {
   349  						Expect(executeErr).ToNot(HaveOccurred())
   350  						Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2"))
   351  
   352  						Expect(fakeV2Actor.UploadApplicationPackageCallCount()).To(Equal(1))
   353  						appGUID, existingResources, _, newResourcesLength := fakeV2Actor.UploadApplicationPackageArgsForCall(0)
   354  						Expect(appGUID).To(Equal("some-app-guid"))
   355  						Expect(existingResources).To(Equal(resources))
   356  						Expect(newResourcesLength).To(BeNumerically("==", 6))
   357  
   358  						Expect(fakeV2Actor.PollJobCallCount()).To(Equal(1))
   359  						Expect(fakeV2Actor.PollJobArgsForCall(0)).To(Equal(uploadJob))
   360  					})
   361  
   362  					It("passes the file reader to the progress bar", func() {
   363  						Expect(executeErr).ToNot(HaveOccurred())
   364  
   365  						Expect(fakeProgressBar.NewProgressBarWrapperCallCount()).To(Equal(1))
   366  						_, size := fakeProgressBar.NewProgressBarWrapperArgsForCall(0)
   367  						Expect(size).To(BeNumerically("==", 6))
   368  					})
   369  				})
   370  
   371  				Context("when the polling fails", func() {
   372  					var expectedErr error
   373  
   374  					BeforeEach(func() {
   375  						expectedErr = errors.New("I can't let you do that starfox")
   376  						fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, expectedErr)
   377  					})
   378  
   379  					It("returns the warnings", func() {
   380  						Expect(executeErr).To(MatchError(expectedErr))
   381  						Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2"))
   382  					})
   383  				})
   384  			})
   385  
   386  			Context("when the upload errors", func() {
   387  				var (
   388  					expectedErr error
   389  					done        chan bool
   390  				)
   391  
   392  				BeforeEach(func() {
   393  					expectedErr = errors.New("I can't let you do that starfox")
   394  					fakeV2Actor.UploadApplicationPackageReturns(v2action.Job{}, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, expectedErr)
   395  
   396  					done = make(chan bool)
   397  
   398  					go func() {
   399  						defer GinkgoRecover()
   400  
   401  						Eventually(eventStream).Should(Receive(Equal(UploadingApplicationWithArchive)))
   402  						Consistently(eventStream).ShouldNot(Receive())
   403  						done <- true
   404  					}()
   405  				})
   406  
   407  				AfterEach(func() {
   408  					close(done)
   409  				})
   410  
   411  				It("returns the error and warnings", func() {
   412  					Eventually(done).Should(Receive())
   413  					Expect(executeErr).To(MatchError(expectedErr))
   414  					Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2"))
   415  				})
   416  			})
   417  		})
   418  
   419  		Context("when the archive returns any access errors", func() {
   420  			It("returns the error", func() {
   421  				_, ok := executeErr.(*os.PathError)
   422  				Expect(ok).To(BeTrue())
   423  			})
   424  		})
   425  	})
   426  
   427  	Describe("UploadDroplet", func() {
   428  		var (
   429  			config          ApplicationConfig
   430  			dropletPath     string
   431  			fakeProgressBar *pushactionfakes.FakeProgressBar
   432  			eventStream     chan Event
   433  
   434  			warnings   Warnings
   435  			executeErr error
   436  		)
   437  
   438  		BeforeEach(func() {
   439  			config = ApplicationConfig{
   440  				DesiredApplication: Application{
   441  					Application: v2action.Application{
   442  						GUID: "some-app-guid",
   443  					}},
   444  			}
   445  			fakeProgressBar = new(pushactionfakes.FakeProgressBar)
   446  			eventStream = make(chan Event)
   447  		})
   448  
   449  		AfterEach(func() {
   450  			close(eventStream)
   451  		})
   452  
   453  		JustBeforeEach(func() {
   454  			warnings, executeErr = actor.UploadDroplet(config, dropletPath, fakeProgressBar, eventStream)
   455  		})
   456  
   457  		Context("when the droplet can be accessed properly", func() {
   458  			BeforeEach(func() {
   459  				tmpfile, err := ioutil.TempFile("", "fake-droplet")
   460  				Expect(err).ToNot(HaveOccurred())
   461  				_, err = tmpfile.Write([]byte("123456"))
   462  				Expect(err).ToNot(HaveOccurred())
   463  				Expect(tmpfile.Close()).ToNot(HaveOccurred())
   464  
   465  				dropletPath = tmpfile.Name()
   466  			})
   467  
   468  			AfterEach(func() {
   469  				Expect(os.RemoveAll(dropletPath)).ToNot(HaveOccurred())
   470  			})
   471  
   472  			Context("when the upload is successful", func() {
   473  				var (
   474  					progressBarReader io.Reader
   475  					uploadJob         v2action.Job
   476  				)
   477  
   478  				BeforeEach(func() {
   479  					uploadJob.GUID = "some-job-guid"
   480  					fakeV2Actor.UploadDropletReturns(uploadJob, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, nil)
   481  
   482  					progressBarReader = strings.NewReader("123456")
   483  					fakeProgressBar.NewProgressBarWrapperReturns(progressBarReader)
   484  
   485  					go func() {
   486  						defer GinkgoRecover()
   487  
   488  						Eventually(eventStream).Should(Receive(Equal(UploadDropletComplete)))
   489  					}()
   490  				})
   491  
   492  				Context("when the polling is successful", func() {
   493  					BeforeEach(func() {
   494  						fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, nil)
   495  					})
   496  
   497  					It("returns the warnings", func() {
   498  						Expect(executeErr).ToNot(HaveOccurred())
   499  						Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2"))
   500  
   501  						Expect(fakeV2Actor.UploadDropletCallCount()).To(Equal(1))
   502  						appGUID, _, dropletLength := fakeV2Actor.UploadDropletArgsForCall(0)
   503  						Expect(appGUID).To(Equal("some-app-guid"))
   504  						Expect(dropletLength).To(BeNumerically("==", 6))
   505  
   506  						Expect(fakeV2Actor.PollJobCallCount()).To(Equal(1))
   507  						Expect(fakeV2Actor.PollJobArgsForCall(0)).To(Equal(uploadJob))
   508  					})
   509  
   510  					It("passes the file reader to the progress bar", func() {
   511  						Expect(executeErr).ToNot(HaveOccurred())
   512  
   513  						Expect(fakeProgressBar.NewProgressBarWrapperCallCount()).To(Equal(1))
   514  						_, size := fakeProgressBar.NewProgressBarWrapperArgsForCall(0)
   515  						Expect(size).To(BeNumerically("==", 6))
   516  					})
   517  				})
   518  
   519  				Context("when the polling fails", func() {
   520  					var expectedErr error
   521  
   522  					BeforeEach(func() {
   523  						expectedErr = errors.New("I can't let you do that starfox")
   524  						fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, expectedErr)
   525  					})
   526  
   527  					It("returns the warnings", func() {
   528  						Expect(executeErr).To(MatchError(expectedErr))
   529  						Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2"))
   530  					})
   531  				})
   532  			})
   533  
   534  			Context("when the upload errors", func() {
   535  				var (
   536  					expectedErr error
   537  					done        chan bool
   538  				)
   539  
   540  				BeforeEach(func() {
   541  					expectedErr = errors.New("I can't let you do that starfox")
   542  					fakeV2Actor.UploadDropletReturns(v2action.Job{}, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, expectedErr)
   543  
   544  					done = make(chan bool)
   545  
   546  					go func() {
   547  						defer GinkgoRecover()
   548  
   549  						Consistently(eventStream).ShouldNot(Receive(Equal(UploadDropletComplete)))
   550  						done <- true
   551  					}()
   552  				})
   553  
   554  				AfterEach(func() {
   555  					close(done)
   556  				})
   557  
   558  				It("returns the error and warnings", func() {
   559  					Eventually(done).Should(Receive())
   560  					Expect(executeErr).To(MatchError(expectedErr))
   561  					Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2"))
   562  				})
   563  			})
   564  		})
   565  	})
   566  })