github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/actor/v7action/service_instance_list_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	. "code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    10  	"code.cloudfoundry.org/cli/resources"
    11  	"code.cloudfoundry.org/cli/types"
    12  	"code.cloudfoundry.org/cli/util/batcher"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("Service Instance List Action", func() {
    18  	var (
    19  		actor                     *Actor
    20  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    21  	)
    22  	const spaceGUID = "some-source-space-guid"
    23  
    24  	BeforeEach(func() {
    25  		fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
    26  		actor = NewActor(fakeCloudControllerClient, nil, nil, nil, nil, nil)
    27  		fakeCloudControllerClient.GetServiceInstancesReturns(
    28  			[]resources.ServiceInstance{
    29  				{
    30  					GUID:             "fake-guid-1",
    31  					Type:             resources.ManagedServiceInstance,
    32  					Name:             "msi1",
    33  					ServicePlanGUID:  "fake-plan-guid-1",
    34  					UpgradeAvailable: types.NewOptionalBoolean(true),
    35  					LastOperation: resources.LastOperation{
    36  						Type:  resources.CreateOperation,
    37  						State: resources.OperationSucceeded,
    38  					},
    39  				},
    40  				{
    41  					GUID:             "fake-guid-2",
    42  					Type:             resources.ManagedServiceInstance,
    43  					Name:             "msi2",
    44  					ServicePlanGUID:  "fake-plan-guid-2",
    45  					UpgradeAvailable: types.NewOptionalBoolean(false),
    46  					LastOperation: resources.LastOperation{
    47  						Type:  resources.UpdateOperation,
    48  						State: resources.OperationSucceeded,
    49  					},
    50  				},
    51  				{
    52  					GUID:            "fake-guid-3",
    53  					Type:            resources.ManagedServiceInstance,
    54  					Name:            "msi3",
    55  					ServicePlanGUID: "fake-plan-guid-3",
    56  					LastOperation: resources.LastOperation{
    57  						Type:  resources.CreateOperation,
    58  						State: resources.OperationInProgress,
    59  					},
    60  				},
    61  				{
    62  					GUID:             "fake-guid-4",
    63  					Type:             resources.ManagedServiceInstance,
    64  					Name:             "msi4",
    65  					ServicePlanGUID:  "fake-plan-guid-4",
    66  					UpgradeAvailable: types.NewOptionalBoolean(true),
    67  					LastOperation: resources.LastOperation{
    68  						Type:  resources.CreateOperation,
    69  						State: resources.OperationFailed,
    70  					},
    71  				},
    72  				{
    73  					GUID:             "fake-guid-5",
    74  					Type:             resources.ManagedServiceInstance,
    75  					Name:             "msi5",
    76  					ServicePlanGUID:  "fake-plan-guid-4",
    77  					UpgradeAvailable: types.NewOptionalBoolean(false),
    78  					LastOperation: resources.LastOperation{
    79  						Type:  resources.DeleteOperation,
    80  						State: resources.OperationInProgress,
    81  					},
    82  				},
    83  				{
    84  					GUID: "fake-guid-6",
    85  					Type: resources.UserProvidedServiceInstance,
    86  					Name: "upsi",
    87  				},
    88  			},
    89  			ccv3.IncludedResources{
    90  				ServicePlans: []resources.ServicePlan{
    91  					{
    92  						GUID:                "fake-plan-guid-1",
    93  						Name:                "fake-plan-1",
    94  						ServiceOfferingGUID: "fake-offering-guid-1",
    95  					},
    96  					{
    97  						GUID:                "fake-plan-guid-2",
    98  						Name:                "fake-plan-2",
    99  						ServiceOfferingGUID: "fake-offering-guid-2",
   100  					},
   101  					{
   102  						GUID:                "fake-plan-guid-3",
   103  						Name:                "fake-plan-3",
   104  						ServiceOfferingGUID: "fake-offering-guid-3",
   105  					},
   106  					{
   107  						GUID:                "fake-plan-guid-4",
   108  						Name:                "fake-plan-4",
   109  						ServiceOfferingGUID: "fake-offering-guid-3",
   110  					},
   111  				},
   112  				ServiceOfferings: []resources.ServiceOffering{
   113  					{
   114  						GUID:              "fake-offering-guid-1",
   115  						Name:              "fake-offering-1",
   116  						ServiceBrokerGUID: "fake-broker-guid-1",
   117  					},
   118  					{
   119  						GUID:              "fake-offering-guid-2",
   120  						Name:              "fake-offering-2",
   121  						ServiceBrokerGUID: "fake-broker-guid-2",
   122  					},
   123  					{
   124  						GUID:              "fake-offering-guid-3",
   125  						Name:              "fake-offering-3",
   126  						ServiceBrokerGUID: "fake-broker-guid-2",
   127  					},
   128  				},
   129  				ServiceBrokers: []resources.ServiceBroker{
   130  					{
   131  						GUID: "fake-broker-guid-1",
   132  						Name: "fake-broker-1",
   133  					},
   134  					{
   135  						GUID: "fake-broker-guid-2",
   136  						Name: "fake-broker-2",
   137  					},
   138  				},
   139  			},
   140  			ccv3.Warnings{"a warning"},
   141  			nil,
   142  		)
   143  		fakeCloudControllerClient.GetServiceCredentialBindingsReturns(
   144  			[]resources.ServiceCredentialBinding{
   145  				{Type: "app", ServiceInstanceGUID: "fake-guid-1", AppGUID: "app-1", AppName: "great-app-1", AppSpaceGUID: spaceGUID},
   146  				{Type: "app", ServiceInstanceGUID: "fake-guid-1", AppGUID: "app-2", AppName: "great-app-2", AppSpaceGUID: spaceGUID},
   147  				{Type: "app", ServiceInstanceGUID: "fake-guid-2", AppGUID: "app-3", AppName: "great-app-3", AppSpaceGUID: spaceGUID},
   148  				{Type: "app", ServiceInstanceGUID: "fake-guid-2", AppGUID: "app-4", AppName: "great-app-4", AppSpaceGUID: spaceGUID},
   149  				{Type: "app", ServiceInstanceGUID: "fake-guid-3", AppGUID: "app-5", AppName: "great-app-5", AppSpaceGUID: spaceGUID},
   150  				{Type: "app", ServiceInstanceGUID: "fake-guid-4", AppGUID: "app-6", AppName: "great-app-6", AppSpaceGUID: spaceGUID},
   151  				{Type: "app", ServiceInstanceGUID: "fake-guid-5", AppGUID: "app-6", AppName: "great-app-6", AppSpaceGUID: spaceGUID},
   152  				{Type: "key", ServiceInstanceGUID: "fake-guid-1", AppSpaceGUID: spaceGUID},
   153  				{Type: "key", ServiceInstanceGUID: "fake-guid-2", AppSpaceGUID: spaceGUID},
   154  			},
   155  			ccv3.Warnings{"bindings warning"},
   156  			nil,
   157  		)
   158  	})
   159  
   160  	Describe("GetServiceInstancesForSpace", func() {
   161  		var (
   162  			serviceInstances []ServiceInstance
   163  			warnings         Warnings
   164  			executionError   error
   165  			omitApps         bool
   166  		)
   167  
   168  		BeforeEach(func() {
   169  			omitApps = false
   170  		})
   171  
   172  		JustBeforeEach(func() {
   173  			serviceInstances, warnings, executionError = actor.GetServiceInstancesForSpace(spaceGUID, omitApps)
   174  		})
   175  
   176  		It("makes the correct call to get service instances", func() {
   177  			Expect(fakeCloudControllerClient.GetServiceInstancesCallCount()).To(Equal(1))
   178  			Expect(fakeCloudControllerClient.GetServiceInstancesArgsForCall(0)).To(ConsistOf(
   179  				ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}},
   180  				ccv3.Query{Key: ccv3.FieldsServicePlan, Values: []string{"guid", "name", "relationships.service_offering"}},
   181  				ccv3.Query{Key: ccv3.FieldsServicePlanServiceOffering, Values: []string{"guid", "name", "relationships.service_broker"}},
   182  				ccv3.Query{Key: ccv3.FieldsServicePlanServiceOfferingServiceBroker, Values: []string{"guid", "name"}},
   183  				ccv3.Query{Key: ccv3.OrderBy, Values: []string{ccv3.NameOrder}},
   184  				ccv3.Query{Key: ccv3.PerPage, Values: []string{ccv3.MaxPerPage}},
   185  			))
   186  		})
   187  
   188  		It("makes the correct call to get service credential bindings", func() {
   189  			Expect(fakeCloudControllerClient.GetServiceCredentialBindingsCallCount()).To(Equal(1))
   190  			Expect(fakeCloudControllerClient.GetServiceCredentialBindingsArgsForCall(0)).To(ConsistOf(
   191  				ccv3.Query{Key: ccv3.ServiceInstanceGUIDFilter, Values: []string{
   192  					"fake-guid-1",
   193  					"fake-guid-2",
   194  					"fake-guid-3",
   195  					"fake-guid-4",
   196  					"fake-guid-5",
   197  					"fake-guid-6",
   198  				}},
   199  				ccv3.Query{Key: ccv3.Include, Values: []string{"app"}},
   200  			))
   201  		})
   202  
   203  		When("omit apps is set to true", func() {
   204  			BeforeEach(func() {
   205  				omitApps = true
   206  			})
   207  
   208  			It("does not get service credential bindings", func() {
   209  				Expect(fakeCloudControllerClient.GetServiceCredentialBindingsCallCount()).To(Equal(0))
   210  			})
   211  		})
   212  
   213  		When("the list of service instances is long", func() {
   214  			BeforeEach(func() {
   215  				var longList []resources.ServiceInstance
   216  				for i := 0; i < batcher.BatchSize*10; i++ {
   217  					longList = append(longList, resources.ServiceInstance{GUID: fmt.Sprintf("fake-guid-%d", i)})
   218  				}
   219  				fakeCloudControllerClient.GetServiceInstancesReturns(
   220  					longList,
   221  					ccv3.IncludedResources{},
   222  					ccv3.Warnings{},
   223  					nil,
   224  				)
   225  			})
   226  
   227  			It("makes multiple different requests to get the service credential bindings", func() {
   228  				Expect(fakeCloudControllerClient.GetServiceCredentialBindingsCallCount()).To(Equal(10))
   229  				Expect(fakeCloudControllerClient.GetServiceCredentialBindingsArgsForCall(0)).
   230  					NotTo(Equal(fakeCloudControllerClient.GetServiceCredentialBindingsArgsForCall(1)))
   231  			})
   232  		})
   233  
   234  		When("the cloud controller request is successful", func() {
   235  			It("returns a list of service instances and warnings", func() {
   236  				Expect(executionError).NotTo(HaveOccurred())
   237  				Expect(warnings).To(ConsistOf("a warning", "bindings warning"))
   238  
   239  				Expect(serviceInstances).To(Equal([]ServiceInstance{
   240  					{
   241  						Name:                "msi1",
   242  						Type:                resources.ManagedServiceInstance,
   243  						ServicePlanName:     "fake-plan-1",
   244  						ServiceOfferingName: "fake-offering-1",
   245  						ServiceBrokerName:   "fake-broker-1",
   246  						UpgradeAvailable:    types.NewOptionalBoolean(true),
   247  						BoundApps:           []string{"great-app-1", "great-app-2"},
   248  						LastOperation:       "create succeeded",
   249  					},
   250  					{
   251  						Name:                "msi2",
   252  						Type:                resources.ManagedServiceInstance,
   253  						ServicePlanName:     "fake-plan-2",
   254  						ServiceOfferingName: "fake-offering-2",
   255  						ServiceBrokerName:   "fake-broker-2",
   256  						UpgradeAvailable:    types.NewOptionalBoolean(false),
   257  						BoundApps:           []string{"great-app-3", "great-app-4"},
   258  						LastOperation:       "update succeeded",
   259  					},
   260  					{
   261  						Name:                "msi3",
   262  						Type:                resources.ManagedServiceInstance,
   263  						ServicePlanName:     "fake-plan-3",
   264  						ServiceOfferingName: "fake-offering-3",
   265  						ServiceBrokerName:   "fake-broker-2",
   266  						BoundApps:           []string{"great-app-5"},
   267  						LastOperation:       "create in progress",
   268  					},
   269  					{
   270  						Name:                "msi4",
   271  						Type:                resources.ManagedServiceInstance,
   272  						ServicePlanName:     "fake-plan-4",
   273  						ServiceOfferingName: "fake-offering-3",
   274  						ServiceBrokerName:   "fake-broker-2",
   275  						UpgradeAvailable:    types.NewOptionalBoolean(true),
   276  						BoundApps:           []string{"great-app-6"},
   277  						LastOperation:       "create failed",
   278  					},
   279  					{
   280  						Name:                "msi5",
   281  						Type:                resources.ManagedServiceInstance,
   282  						ServicePlanName:     "fake-plan-4",
   283  						ServiceOfferingName: "fake-offering-3",
   284  						ServiceBrokerName:   "fake-broker-2",
   285  						UpgradeAvailable:    types.NewOptionalBoolean(false),
   286  						BoundApps:           []string{"great-app-6"},
   287  						LastOperation:       "delete in progress",
   288  					},
   289  					{
   290  						Name:      "upsi",
   291  						Type:      resources.UserProvidedServiceInstance,
   292  						BoundApps: nil,
   293  					},
   294  				}))
   295  			})
   296  		})
   297  
   298  		When("the getting the service instances returns an error", func() {
   299  			BeforeEach(func() {
   300  				fakeCloudControllerClient.GetServiceInstancesReturns(
   301  					[]resources.ServiceInstance{},
   302  					ccv3.IncludedResources{},
   303  					ccv3.Warnings{"some-service-instance-warning"},
   304  					errors.New("something really awful"),
   305  				)
   306  			})
   307  
   308  			It("returns an error and warnings", func() {
   309  				Expect(executionError).To(MatchError("something really awful"))
   310  				Expect(warnings).To(ConsistOf("some-service-instance-warning"))
   311  			})
   312  		})
   313  
   314  		When("the getting the service credential bindings returns an error", func() {
   315  			BeforeEach(func() {
   316  				fakeCloudControllerClient.GetServiceCredentialBindingsReturns(
   317  					[]resources.ServiceCredentialBinding{},
   318  					ccv3.Warnings{"some-service-credential-binding-warning"},
   319  					errors.New("something really REALLY awful"),
   320  				)
   321  			})
   322  
   323  			It("returns an error and warnings", func() {
   324  				Expect(executionError).To(MatchError("something really REALLY awful"))
   325  				Expect(warnings).To(ConsistOf("a warning", "some-service-credential-binding-warning"))
   326  			})
   327  		})
   328  
   329  		When("the service instance is shared", func() {
   330  			BeforeEach(func() {
   331  				fakeCloudControllerClient.GetServiceInstancesReturns(
   332  					[]resources.ServiceInstance{{
   333  						GUID:             "service-instance-guid",
   334  						Type:             resources.ManagedServiceInstance,
   335  						Name:             "msi1",
   336  						ServicePlanGUID:  "fake-plan-guid-1",
   337  						UpgradeAvailable: types.NewOptionalBoolean(true),
   338  						LastOperation: resources.LastOperation{
   339  							Type:  resources.CreateOperation,
   340  							State: resources.OperationSucceeded,
   341  						},
   342  					}},
   343  					ccv3.IncludedResources{
   344  						ServicePlans: []resources.ServicePlan{{
   345  							GUID:                "fake-plan-guid-1",
   346  							Name:                "fake-plan-1",
   347  							ServiceOfferingGUID: "fake-offering-guid-1",
   348  						}},
   349  						ServiceOfferings: []resources.ServiceOffering{{
   350  							GUID:              "fake-offering-guid-1",
   351  							Name:              "fake-offering-1",
   352  							ServiceBrokerGUID: "fake-broker-guid-1",
   353  						}},
   354  						ServiceBrokers: []resources.ServiceBroker{{
   355  							GUID: "fake-broker-guid-1", Name: "fake-broker-1",
   356  						}},
   357  					},
   358  					ccv3.Warnings{"a warning"},
   359  					nil,
   360  				)
   361  
   362  				fakeCloudControllerClient.GetServiceCredentialBindingsReturns(
   363  					[]resources.ServiceCredentialBinding{{
   364  						Type:                "app",
   365  						GUID:                "some-binding-guid",
   366  						ServiceInstanceGUID: "service-instance-guid",
   367  						AppGUID:             "app-guid",
   368  						AppName:             "app-on-space-1",
   369  						AppSpaceGUID:        spaceGUID,
   370  					}, {
   371  						Type:                "app",
   372  						GUID:                "some-binding-guid",
   373  						ServiceInstanceGUID: "service-instance-guid",
   374  						AppGUID:             "app-guid-2",
   375  						AppName:             "app-on-space-2",
   376  						AppSpaceGUID:        "another-space-guid",
   377  					}},
   378  					nil,
   379  					nil,
   380  				)
   381  			})
   382  
   383  			It("should only include bound apps in the provided space", func() {
   384  				Expect(serviceInstances).To(HaveLen(1))
   385  				serviceInstance := serviceInstances[0]
   386  				Expect(serviceInstance.BoundApps).To(ConsistOf("app-on-space-1"))
   387  			})
   388  		})
   389  	})
   390  })