github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/actor/v7pushaction/create_droplet_for_application_test.go (about)

     1  package v7pushaction_test
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  
     7  	"code.cloudfoundry.org/cli/actor/actionerror"
     8  	"code.cloudfoundry.org/cli/actor/v7action"
     9  	. "code.cloudfoundry.org/cli/actor/v7pushaction"
    10  	"code.cloudfoundry.org/cli/actor/v7pushaction/v7pushactionfakes"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    12  	"code.cloudfoundry.org/cli/resources"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("CreateDropletForApplication", func() {
    18  	var (
    19  		actor           *Actor
    20  		fakeV7Actor     *v7pushactionfakes.FakeV7Actor
    21  		fakeSharedActor *v7pushactionfakes.FakeSharedActor
    22  
    23  		returnedPushPlan PushPlan
    24  		paramPlan        PushPlan
    25  		fakeProgressBar  *v7pushactionfakes.FakeProgressBar
    26  
    27  		warnings   Warnings
    28  		executeErr error
    29  
    30  		events []Event
    31  	)
    32  
    33  	BeforeEach(func() {
    34  		actor, fakeV7Actor, fakeSharedActor = getTestPushActor()
    35  
    36  		fakeProgressBar = new(v7pushactionfakes.FakeProgressBar)
    37  
    38  		fakeSharedActor.ReadArchiveReturns(new(v7pushactionfakes.FakeReadCloser), 0, nil)
    39  
    40  		paramPlan = PushPlan{
    41  			Application: resources.Application{
    42  				GUID: "some-app-guid",
    43  			},
    44  		}
    45  	})
    46  
    47  	JustBeforeEach(func() {
    48  		events = EventFollower(func(eventStream chan<- *PushEvent) {
    49  			returnedPushPlan, warnings, executeErr = actor.CreateDropletForApplication(paramPlan, eventStream, fakeProgressBar)
    50  		})
    51  	})
    52  
    53  	When("the plan has a droplet path specified", func() {
    54  		BeforeEach(func() {
    55  			paramPlan.DropletPath = "path/to/some-droplet.tgz"
    56  		})
    57  
    58  		When("creating the droplet for app fails", func() {
    59  			var createError = errors.New("create droplet failed")
    60  
    61  			BeforeEach(func() {
    62  				fakeV7Actor.CreateApplicationDropletReturns(
    63  					resources.Droplet{},
    64  					v7action.Warnings{"create-droplet-warning"},
    65  					createError,
    66  				)
    67  			})
    68  
    69  			It("only records an event for creating droplet", func() {
    70  				Expect(events).To(Equal([]Event{
    71  					CreatingDroplet,
    72  				}))
    73  			})
    74  
    75  			It("returns the unmodified plan, warnings, and error", func() {
    76  				Expect(returnedPushPlan).To(Equal(paramPlan))
    77  				Expect(warnings).To(ConsistOf("create-droplet-warning"))
    78  				Expect(executeErr).To(Equal(createError))
    79  			})
    80  		})
    81  
    82  		When("reading droplet file fails", func() {
    83  			var readError = errors.New("reading file failed")
    84  
    85  			BeforeEach(func() {
    86  				fakeV7Actor.CreateApplicationDropletReturns(
    87  					resources.Droplet{},
    88  					v7action.Warnings{"create-droplet-warning"},
    89  					nil,
    90  				)
    91  
    92  				fakeSharedActor.ReadArchiveReturns(
    93  					nil,
    94  					0,
    95  					readError,
    96  				)
    97  			})
    98  
    99  			It("records events for creating droplet, reading archive", func() {
   100  				Expect(events).To(Equal([]Event{
   101  					CreatingDroplet,
   102  					ReadingArchive,
   103  				}))
   104  			})
   105  
   106  			It("returns the unmodified plan, warnings, and error", func() {
   107  				Expect(returnedPushPlan).To(Equal(paramPlan))
   108  				Expect(warnings).To(ConsistOf("create-droplet-warning"))
   109  				Expect(executeErr).To(Equal(readError))
   110  			})
   111  		})
   112  
   113  		When("uploading droplet fails", func() {
   114  			var createdDroplet = resources.Droplet{GUID: "created-droplet-guid"}
   115  			var progressReader = strings.NewReader("123456")
   116  			var uploadError = errors.New("uploading droplet failed")
   117  
   118  			BeforeEach(func() {
   119  				fakeV7Actor.CreateApplicationDropletReturns(
   120  					createdDroplet,
   121  					v7action.Warnings{"create-droplet-warning"},
   122  					nil,
   123  				)
   124  
   125  				fakeSharedActor.ReadArchiveReturns(
   126  					new(v7pushactionfakes.FakeReadCloser),
   127  					int64(128),
   128  					nil,
   129  				)
   130  
   131  				fakeProgressBar.NewProgressBarWrapperReturns(progressReader)
   132  
   133  				fakeV7Actor.UploadDropletReturns(
   134  					v7action.Warnings{"upload-droplet-warning"},
   135  					uploadError,
   136  				)
   137  			})
   138  
   139  			It("tries to upload the droplet with given path", func() {
   140  				Expect(fakeV7Actor.UploadDropletCallCount()).To(Equal(1))
   141  				givenDropletGUID, givenDropletPath, givenProgressReader, givenSize := fakeV7Actor.UploadDropletArgsForCall(0)
   142  				Expect(givenDropletGUID).To(Equal(createdDroplet.GUID))
   143  				Expect(givenDropletPath).To(Equal(paramPlan.DropletPath))
   144  				Expect(givenProgressReader).To(Equal(progressReader))
   145  				Expect(givenSize).To(Equal(int64(128)))
   146  			})
   147  
   148  			It("records events for creating droplet, reading archive, uploading droplet", func() {
   149  				Expect(events).To(Equal([]Event{
   150  					CreatingDroplet,
   151  					ReadingArchive,
   152  					UploadingDroplet,
   153  					UploadDropletComplete,
   154  				}))
   155  			})
   156  
   157  			It("returns the unmodified plan, warnings, and error", func() {
   158  				Expect(returnedPushPlan).To(Equal(paramPlan))
   159  				Expect(warnings).To(ConsistOf("create-droplet-warning", "upload-droplet-warning"))
   160  				Expect(executeErr).To(Equal(uploadError))
   161  			})
   162  		})
   163  
   164  		When("a retryable failure occurs", func() {
   165  			var createdDroplet = resources.Droplet{GUID: "created-droplet-guid"}
   166  			var progressReader = strings.NewReader("123456")
   167  			var retryableError = ccerror.PipeSeekError{
   168  				Err: errors.New("network error"),
   169  			}
   170  
   171  			BeforeEach(func() {
   172  				fakeV7Actor.CreateApplicationDropletReturns(
   173  					createdDroplet,
   174  					v7action.Warnings{"create-droplet-warning"},
   175  					nil,
   176  				)
   177  
   178  				fakeSharedActor.ReadArchiveReturns(
   179  					new(v7pushactionfakes.FakeReadCloser),
   180  					int64(128),
   181  					nil,
   182  				)
   183  
   184  				fakeProgressBar.NewProgressBarWrapperReturns(progressReader)
   185  			})
   186  
   187  			When("all upload attempts fail", func() {
   188  				BeforeEach(func() {
   189  					fakeV7Actor.UploadDropletReturns(
   190  						v7action.Warnings{"upload-droplet-warning"},
   191  						retryableError,
   192  					)
   193  				})
   194  
   195  				It("records events for creating droplet, reading archive, uploading droplet, retrying", func() {
   196  					Expect(events).To(Equal([]Event{
   197  						CreatingDroplet,
   198  						ReadingArchive,
   199  						UploadingDroplet,
   200  						RetryUpload,
   201  						ReadingArchive,
   202  						UploadingDroplet,
   203  						RetryUpload,
   204  						ReadingArchive,
   205  						UploadingDroplet,
   206  						RetryUpload,
   207  					}))
   208  				})
   209  
   210  				It("returns the unmodified plan, all warnings, and wrapped error", func() {
   211  					Expect(returnedPushPlan).To(Equal(paramPlan))
   212  					Expect(warnings).To(ConsistOf(
   213  						"create-droplet-warning",
   214  						"upload-droplet-warning",
   215  						"upload-droplet-warning",
   216  						"upload-droplet-warning",
   217  					))
   218  					Expect(executeErr).To(Equal(actionerror.UploadFailedError{
   219  						Err: retryableError.Err,
   220  					}))
   221  				})
   222  			})
   223  
   224  			When("the upload eventually succeeds", func() {
   225  				BeforeEach(func() {
   226  					fakeV7Actor.UploadDropletReturnsOnCall(0,
   227  						v7action.Warnings{"upload-droplet-warning"},
   228  						retryableError,
   229  					)
   230  
   231  					fakeV7Actor.UploadDropletReturnsOnCall(1,
   232  						v7action.Warnings{"upload-droplet-warning"},
   233  						retryableError,
   234  					)
   235  
   236  					fakeV7Actor.UploadDropletReturnsOnCall(2,
   237  						v7action.Warnings{"upload-droplet-warning"},
   238  						nil,
   239  					)
   240  				})
   241  
   242  				It("records events for creating droplet, reading archive, uploading droplet, retrying, completing", func() {
   243  					Expect(events).To(Equal([]Event{
   244  						CreatingDroplet,
   245  						ReadingArchive,
   246  						UploadingDroplet,
   247  						RetryUpload,
   248  						ReadingArchive,
   249  						UploadingDroplet,
   250  						RetryUpload,
   251  						ReadingArchive,
   252  						UploadingDroplet,
   253  						UploadDropletComplete,
   254  					}))
   255  				})
   256  
   257  				It("returns the modified plan, all warnings, and no error", func() {
   258  					Expect(returnedPushPlan.DropletGUID).To(Equal(createdDroplet.GUID))
   259  					Expect(warnings).To(ConsistOf(
   260  						"create-droplet-warning",
   261  						"upload-droplet-warning",
   262  						"upload-droplet-warning",
   263  						"upload-droplet-warning",
   264  					))
   265  					Expect(executeErr).NotTo(HaveOccurred())
   266  				})
   267  			})
   268  		})
   269  
   270  		When("upload completes successfully", func() {
   271  			var createdDroplet = resources.Droplet{GUID: "created-droplet-guid"}
   272  			var progressReader = strings.NewReader("123456")
   273  
   274  			BeforeEach(func() {
   275  				fakeV7Actor.CreateApplicationDropletReturns(
   276  					createdDroplet,
   277  					v7action.Warnings{"create-droplet-warning"},
   278  					nil,
   279  				)
   280  
   281  				fakeSharedActor.ReadArchiveReturns(
   282  					new(v7pushactionfakes.FakeReadCloser),
   283  					int64(128),
   284  					nil,
   285  				)
   286  
   287  				fakeProgressBar.NewProgressBarWrapperReturns(progressReader)
   288  
   289  				fakeV7Actor.UploadDropletReturns(
   290  					v7action.Warnings{"upload-droplet-warning"},
   291  					nil,
   292  				)
   293  			})
   294  
   295  			It("records events for creating droplet, reading archive, uploading droplet, retrying, completing", func() {
   296  				Expect(events).To(Equal([]Event{
   297  					CreatingDroplet,
   298  					ReadingArchive,
   299  					UploadingDroplet,
   300  					UploadDropletComplete,
   301  				}))
   302  			})
   303  
   304  			It("returns the modified plan, all warnings, and no error", func() {
   305  				Expect(returnedPushPlan.DropletGUID).To(Equal(createdDroplet.GUID))
   306  				Expect(warnings).To(ConsistOf(
   307  					"create-droplet-warning",
   308  					"upload-droplet-warning",
   309  				))
   310  				Expect(executeErr).NotTo(HaveOccurred())
   311  			})
   312  		})
   313  	})
   314  })