github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/command/v7/upgrade_service_command_test.go (about)

     1  package v7_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	"code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/command/commandfakes"
     9  	"code.cloudfoundry.org/cli/command/translatableerror"
    10  	. "code.cloudfoundry.org/cli/command/v7"
    11  	"code.cloudfoundry.org/cli/command/v7/v7fakes"
    12  	"code.cloudfoundry.org/cli/util/configv3"
    13  	"code.cloudfoundry.org/cli/util/ui"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  	. "github.com/onsi/gomega/gbytes"
    17  )
    18  
    19  var _ = Describe("upgrade-service command", func() {
    20  	const (
    21  		serviceInstanceName = "fake-service-instance-name"
    22  		spaceName           = "fake-space-name"
    23  		spaceGUID           = "fake-space-guid"
    24  		orgName             = "fake-org-name"
    25  		username            = "fake-username"
    26  	)
    27  
    28  	var (
    29  		input           *Buffer
    30  		testUI          *ui.UI
    31  		fakeConfig      *commandfakes.FakeConfig
    32  		fakeSharedActor *commandfakes.FakeSharedActor
    33  		fakeActor       *v7fakes.FakeActor
    34  		cmd             UpgradeServiceCommand
    35  		executeErr      error
    36  	)
    37  
    38  	BeforeEach(func() {
    39  		input = NewBuffer()
    40  		testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer())
    41  		fakeConfig = new(commandfakes.FakeConfig)
    42  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    43  		fakeActor = new(v7fakes.FakeActor)
    44  
    45  		cmd = UpgradeServiceCommand{
    46  			BaseCommand: BaseCommand{
    47  				UI:          testUI,
    48  				Config:      fakeConfig,
    49  				SharedActor: fakeSharedActor,
    50  				Actor:       fakeActor,
    51  			},
    52  		}
    53  
    54  		setPositionalFlags(&cmd, serviceInstanceName)
    55  
    56  		fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: orgName})
    57  		fakeConfig.TargetedSpaceReturns(configv3.Space{
    58  			Name: spaceName,
    59  			GUID: spaceGUID,
    60  		})
    61  		fakeActor.GetCurrentUserReturns(configv3.User{Name: username}, nil)
    62  	})
    63  
    64  	JustBeforeEach(func() {
    65  		executeErr = cmd.Execute(nil)
    66  	})
    67  
    68  	testActorInteractions := func() {
    69  		It("delegates to the actor", func() {
    70  			Expect(fakeActor.UpgradeManagedServiceInstanceCallCount()).To(Equal(1))
    71  			actualName, actualSpaceGUID := fakeActor.UpgradeManagedServiceInstanceArgsForCall(0)
    72  			Expect(actualName).To(Equal(serviceInstanceName))
    73  			Expect(actualSpaceGUID).To(Equal(spaceGUID))
    74  		})
    75  
    76  		When("the service instance does not exist", func() {
    77  			BeforeEach(func() {
    78  				fakeActor.UpgradeManagedServiceInstanceReturns(
    79  					nil,
    80  					v7action.Warnings{"upgrade warning"},
    81  					actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName},
    82  				)
    83  			})
    84  
    85  			It("prints warnings and returns a translatable error", func() {
    86  				Expect(testUI.Err).To(Say("upgrade warning"))
    87  				Expect(executeErr).To(MatchError(translatableerror.ServiceInstanceNotFoundError{
    88  					Name: serviceInstanceName,
    89  				}))
    90  			})
    91  		})
    92  
    93  		When("the actor returns an unexpected error", func() {
    94  			BeforeEach(func() {
    95  				fakeActor.UpgradeManagedServiceInstanceReturns(
    96  					make(chan v7action.PollJobEvent),
    97  					v7action.Warnings{"upgrade warning"},
    98  					errors.New("bang"),
    99  				)
   100  			})
   101  
   102  			It("fails with warnings", func() {
   103  				Expect(executeErr).To(MatchError("bang"))
   104  				Expect(testUI.Err).To(Say("upgrade warning"))
   105  				Expect(testUI.Out).NotTo(Say("OK"))
   106  			})
   107  		})
   108  
   109  		When("stream goes to polling", func() {
   110  			BeforeEach(func() {
   111  				fakeStream := make(chan v7action.PollJobEvent)
   112  				fakeActor.UpgradeManagedServiceInstanceReturns(
   113  					fakeStream,
   114  					v7action.Warnings{"actor warning"},
   115  					nil,
   116  				)
   117  
   118  				go func() {
   119  					fakeStream <- v7action.PollJobEvent{
   120  						State:    v7action.JobPolling,
   121  						Warnings: v7action.Warnings{"poll warning"},
   122  					}
   123  				}()
   124  			})
   125  
   126  			It("prints messages and warnings", func() {
   127  				Expect(testUI.Out).To(SatisfyAll(
   128  					Say(`Upgrading service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username),
   129  					Say(`\n`),
   130  					Say(`Upgrade in progress. Use 'cf services' or 'cf service %s' to check operation status\.`, serviceInstanceName),
   131  					Say(`OK\n`),
   132  				))
   133  
   134  				Expect(testUI.Err).To(SatisfyAll(
   135  					Say("actor warning"),
   136  					Say("poll warning"),
   137  				))
   138  			})
   139  		})
   140  
   141  		When("error in event stream", func() {
   142  			BeforeEach(func() {
   143  				setFlag(&cmd, "--wait")
   144  
   145  				fakeStream := make(chan v7action.PollJobEvent)
   146  				fakeActor.UpgradeManagedServiceInstanceReturns(
   147  					fakeStream,
   148  					v7action.Warnings{"a warning"},
   149  					nil,
   150  				)
   151  
   152  				go func() {
   153  					fakeStream <- v7action.PollJobEvent{
   154  						State:    v7action.JobPolling,
   155  						Warnings: v7action.Warnings{"poll warning"},
   156  					}
   157  					fakeStream <- v7action.PollJobEvent{
   158  						State:    v7action.JobFailed,
   159  						Warnings: v7action.Warnings{"failed warning"},
   160  						Err:      errors.New("boom"),
   161  					}
   162  				}()
   163  			})
   164  
   165  			It("returns the error and prints warnings", func() {
   166  				Expect(executeErr).To(MatchError("boom"))
   167  				Expect(testUI.Err).To(SatisfyAll(
   168  					Say("poll warning"),
   169  					Say("failed warning"),
   170  				))
   171  			})
   172  		})
   173  
   174  		When("--wait flag specified", func() {
   175  			BeforeEach(func() {
   176  				setFlag(&cmd, "--wait")
   177  
   178  				fakeStream := make(chan v7action.PollJobEvent)
   179  				fakeActor.UpgradeManagedServiceInstanceReturns(
   180  					fakeStream,
   181  					v7action.Warnings{"a warning"},
   182  					nil,
   183  				)
   184  
   185  				go func() {
   186  					fakeStream <- v7action.PollJobEvent{
   187  						State:    v7action.JobPolling,
   188  						Warnings: v7action.Warnings{"poll warning"},
   189  					}
   190  					fakeStream <- v7action.PollJobEvent{
   191  						State:    v7action.JobComplete,
   192  						Warnings: v7action.Warnings{"failed warning"},
   193  					}
   194  					close(fakeStream)
   195  				}()
   196  			})
   197  
   198  			It("prints messages and warnings", func() {
   199  				Expect(testUI.Out).To(SatisfyAll(
   200  					Say(`Upgrading service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username),
   201  					Say(`\n`),
   202  					Say(`Waiting for the operation to complete\.\.\n`),
   203  					Say(`\n`),
   204  					Say(`Upgrade of service instance %s complete\.\n`, serviceInstanceName),
   205  					Say(`OK\n`),
   206  				))
   207  
   208  				Expect(testUI.Err).To(SatisfyAll(
   209  					Say("a warning"),
   210  					Say("poll warning"),
   211  					Say("failed warning"),
   212  				))
   213  			})
   214  		})
   215  	}
   216  
   217  	It("checks the user is logged in, and targeting an org and space", func() {
   218  		Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   219  		orgChecked, spaceChecked := fakeSharedActor.CheckTargetArgsForCall(0)
   220  		Expect(orgChecked).To(BeTrue())
   221  		Expect(spaceChecked).To(BeTrue())
   222  	})
   223  
   224  	It("prompts the user for confirmation", func() {
   225  		Expect(testUI.Out).To(SatisfyAll(
   226  			Say(`Warning: This operation may be long running and will block further operations on the service instance until it's completed`),
   227  			Say(`Do you really want to upgrade the service instance %s\? \[yN\]:`, serviceInstanceName),
   228  		))
   229  	})
   230  
   231  	When("the user confirms when prompted", func() {
   232  		BeforeEach(func() {
   233  			_, err := input.Write([]byte("y\n"))
   234  			Expect(err).NotTo(HaveOccurred())
   235  		})
   236  
   237  		It("outputs the attempted operation", func() {
   238  			Expect(testUI.Out).To(SatisfyAll(
   239  				Say(`Upgrading service instance %s in org %s / space %s as %s\.\.\.\n`, serviceInstanceName, orgName, spaceName, username),
   240  				Say(`\n`),
   241  			))
   242  		})
   243  
   244  		testActorInteractions()
   245  	})
   246  
   247  	When("the user cancels when prompted", func() {
   248  		BeforeEach(func() {
   249  			_, err := input.Write([]byte("n\n"))
   250  			Expect(err).NotTo(HaveOccurred())
   251  		})
   252  
   253  		It("does not call the actor", func() {
   254  			Expect(fakeActor.DeleteServiceInstanceCallCount()).To(BeZero())
   255  		})
   256  
   257  		It("outputs that the upgrade was cancelled", func() {
   258  			Expect(executeErr).NotTo(HaveOccurred())
   259  			Expect(testUI.Out).To(Say("Upgrade cancelled\n"))
   260  		})
   261  	})
   262  
   263  	When("the -f flags is passed", func() {
   264  		BeforeEach(func() {
   265  			setFlag(&cmd, "-f")
   266  		})
   267  
   268  		It("does not prompt the user", func() {
   269  			Expect(testUI.Out).NotTo(Say("Do you really want"))
   270  		})
   271  
   272  		testActorInteractions()
   273  	})
   274  
   275  	When("checking the target returns an error", func() {
   276  		It("returns the error", func() {
   277  			fakeSharedActor.CheckTargetReturns(errors.New("explode"))
   278  			executeErr := cmd.Execute(nil)
   279  			Expect(executeErr).To(MatchError("explode"))
   280  		})
   281  	})
   282  })