github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/suspension/handler_test.go (about) 1 package suspension 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/kyma-project/kyma-environment-broker/common/orchestration" 8 9 "github.com/kyma-project/kyma-environment-broker/internal/storage/dberr" 10 11 "github.com/kyma-project/kyma-environment-broker/internal" 12 "github.com/kyma-project/kyma-environment-broker/internal/broker" 13 "github.com/kyma-project/kyma-environment-broker/internal/fixture" 14 "github.com/kyma-project/kyma-environment-broker/internal/ptr" 15 "github.com/kyma-project/kyma-environment-broker/internal/storage" 16 "github.com/pivotal-cf/brokerapi/v8/domain" 17 "github.com/sirupsen/logrus" 18 "github.com/stretchr/testify/assert" 19 "github.com/stretchr/testify/require" 20 ) 21 22 func TestSuspension(t *testing.T) { 23 // given 24 provisioning := NewDummyQueue() 25 deprovisioning := NewDummyQueue() 26 st := storage.NewMemoryStorage() 27 28 svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New()) 29 instance := fixInstance(fixActiveErsContext()) 30 st.Instances().Insert(*instance) 31 32 // when 33 changed, err := svc.Handle(instance, fixInactiveErsContext()) 34 require.NoError(t, err) 35 assert.True(t, changed, "handler to change active flag") 36 37 // then 38 op, _ := st.Operations().GetDeprovisioningOperationByInstanceID("instance-id") 39 assertQueue(t, deprovisioning, op.ID) 40 assertQueue(t, provisioning) 41 42 assert.Equal(t, domain.LastOperationState("pending"), op.State) 43 assert.Equal(t, instance.InstanceID, op.InstanceID) 44 } 45 46 func TestSuspension_Retrigger(t *testing.T) { 47 t.Run("should skip suspension when temporary deprovisioning operation already succeeded", func(t *testing.T) { 48 // given 49 provisioning := NewDummyQueue() 50 deprovisioning := NewDummyQueue() 51 st := storage.NewMemoryStorage() 52 53 svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New()) 54 instance := fixInstance(fixInactiveErsContext()) 55 st.Instances().Insert(*instance) 56 st.Operations().InsertDeprovisioningOperation(internal.DeprovisioningOperation{ 57 Operation: internal.Operation{ 58 ID: "suspended-op-id", 59 Version: 0, 60 CreatedAt: time.Now(), 61 UpdatedAt: time.Now(), 62 InstanceID: instance.InstanceID, 63 State: domain.Succeeded, 64 Temporary: true, 65 Type: internal.OperationTypeDeprovision, 66 }, 67 }) 68 69 // when 70 changed, err := svc.Handle(instance, fixInactiveErsContext()) 71 require.NoError(t, err) 72 assert.False(t, changed, "handler to not change active flag") 73 74 // then 75 op, _ := st.Operations().GetDeprovisioningOperationByInstanceID("instance-id") 76 assertQueue(t, deprovisioning) 77 assertQueue(t, provisioning) 78 79 assert.Equal(t, domain.Succeeded, op.State) 80 assert.Equal(t, instance.InstanceID, op.InstanceID) 81 }) 82 83 t.Run("should retrigger deprovisioning when existing temporary deprovisioning operation failed", func(t *testing.T) { 84 // given 85 provisioning := NewDummyQueue() 86 deprovisioning := NewDummyQueue() 87 st := storage.NewMemoryStorage() 88 89 svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New()) 90 instance := fixInstance(fixInactiveErsContext()) 91 st.Instances().Insert(*instance) 92 st.Operations().InsertDeprovisioningOperation(internal.DeprovisioningOperation{ 93 Operation: internal.Operation{ 94 ID: "suspended-op-id", 95 Version: 0, 96 CreatedAt: time.Now(), 97 UpdatedAt: time.Now(), 98 InstanceID: instance.InstanceID, 99 State: domain.Failed, 100 Temporary: true, 101 Type: internal.OperationTypeDeprovision, 102 }, 103 }) 104 105 // when 106 changed, err := svc.Handle(instance, fixInactiveErsContext()) 107 require.NoError(t, err) 108 assert.True(t, changed, "handler to change active flag") 109 110 // then 111 op, _ := st.Operations().GetDeprovisioningOperationByInstanceID("instance-id") 112 assertQueue(t, deprovisioning, op.ID) 113 assertQueue(t, provisioning) 114 115 assert.Equal(t, domain.LastOperationState("pending"), op.State) 116 assert.Equal(t, instance.InstanceID, op.InstanceID) 117 }) 118 119 } 120 121 func assertQueue(t *testing.T, q *dummyQueue, id ...string) { 122 t.Helper() 123 if len(id) == 0 { 124 assert.Empty(t, q.IDs) 125 return 126 } 127 assert.Equal(t, q.IDs, id) 128 } 129 130 func TestUnsuspension(t *testing.T) { 131 // given 132 provisioning := NewDummyQueue() 133 deprovisioning := NewDummyQueue() 134 st := storage.NewMemoryStorage() 135 136 svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New()) 137 instance := fixInstance(fixInactiveErsContext()) 138 instance.InstanceDetails.ShootName = "c-012345" 139 instance.InstanceDetails.ShootDomain = "c-012345.sap.com" 140 141 st.Instances().Insert(*instance) 142 143 deprovisioningOperation := fixture.FixDeprovisioningOperation("d-op", "instance-id") 144 deprovisioningOperation.Temporary = true 145 st.Operations().InsertDeprovisioningOperation(deprovisioningOperation) 146 147 // when 148 changed, err := svc.Handle(instance, fixActiveErsContext()) 149 require.NoError(t, err) 150 assert.True(t, changed, "handler to change active flag") 151 152 // then 153 op, err := st.Operations().GetProvisioningOperationByInstanceID("instance-id") 154 require.NoError(t, err) 155 assertQueue(t, deprovisioning) 156 assertQueue(t, provisioning, op.ID) 157 158 assert.Equal(t, domain.LastOperationState(orchestration.Pending), op.State) 159 assert.Equal(t, instance.InstanceID, op.InstanceID) 160 assert.Equal(t, "c-012345", op.ShootName) 161 assert.Equal(t, "c-012345.sap.com", op.ShootDomain) 162 } 163 164 func TestUnsuspensionForDeprovisioningInstance(t *testing.T) { 165 // given 166 provisioning := NewDummyQueue() 167 deprovisioning := NewDummyQueue() 168 st := storage.NewMemoryStorage() 169 170 svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New()) 171 instance := fixInstance(fixInactiveErsContext()) 172 instance.InstanceDetails.ShootName = "c-012345" 173 instance.InstanceDetails.ShootDomain = "c-012345.sap.com" 174 175 st.Instances().Insert(*instance) 176 deprovisioningOperation := fixture.FixDeprovisioningOperation("d-op", "instance-id") 177 deprovisioningOperation.Temporary = false 178 st.Operations().InsertDeprovisioningOperation(deprovisioningOperation) 179 180 // when 181 changed, err := svc.Handle(instance, fixActiveErsContext()) 182 require.NoError(t, err) 183 assert.False(t, changed, "handler to not change active flag") 184 185 // then 186 _, err = st.Operations().GetProvisioningOperationByInstanceID("instance-id") 187 assert.True(t, dberr.IsNotFound(err)) 188 assertQueue(t, deprovisioning) 189 assertQueue(t, provisioning) 190 } 191 192 func TestUnsuspensionForExpiredInstance(t *testing.T) { 193 // given 194 provisioning := NewDummyQueue() 195 deprovisioning := NewDummyQueue() 196 st := storage.NewMemoryStorage() 197 198 svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New()) 199 instance := fixInstance(fixInactiveErsContext()) 200 instance.InstanceDetails.ShootName = "c-012345" 201 instance.InstanceDetails.ShootDomain = "c-012345.sap.com" 202 instance.ExpiredAt = ptr.Time(time.Now()) 203 204 st.Instances().Insert(*instance) 205 206 // when 207 changed, err := svc.Handle(instance, fixActiveErsContext()) 208 require.NoError(t, err) 209 assert.False(t, changed, "handler to not change active flag") 210 211 // then 212 _, err = st.Operations().GetProvisioningOperationByInstanceID("instance-id") 213 assert.True(t, dberr.IsNotFound(err)) 214 } 215 216 func fixInstance(ersContext internal.ERSContext) *internal.Instance { 217 instance := fixture.FixInstance("instance-id") 218 instance.ServicePlanID = broker.TrialPlanID 219 instance.Parameters.ErsContext = ersContext 220 221 return &instance 222 } 223 224 func fixActiveErsContext() internal.ERSContext { 225 return internal.ERSContext{ 226 Active: ptr.Bool(true), 227 } 228 } 229 230 func fixInactiveErsContext() internal.ERSContext { 231 return internal.ERSContext{ 232 Active: ptr.Bool(false), 233 } 234 } 235 236 type dummyQueue struct { 237 IDs []string 238 } 239 240 func NewDummyQueue() *dummyQueue { 241 return &dummyQueue{ 242 IDs: []string{}, 243 } 244 } 245 246 func (q *dummyQueue) Add(id string) { 247 q.IDs = append(q.IDs, id) 248 }