sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/vnetpeerings/vnetpeerings_test.go (about) 1 /* 2 Copyright 2021 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package vnetpeerings 18 19 import ( 20 "context" 21 "fmt" 22 "io" 23 "net/http" 24 "strings" 25 "testing" 26 27 "github.com/Azure/azure-sdk-for-go/sdk/azcore" 28 . "github.com/onsi/gomega" 29 "go.uber.org/mock/gomock" 30 "k8s.io/utils/ptr" 31 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 32 "sigs.k8s.io/cluster-api-provider-azure/azure" 33 "sigs.k8s.io/cluster-api-provider-azure/azure/services/async/mock_async" 34 "sigs.k8s.io/cluster-api-provider-azure/azure/services/vnetpeerings/mock_vnetpeerings" 35 gomockinternal "sigs.k8s.io/cluster-api-provider-azure/internal/test/matchers/gomock" 36 "sigs.k8s.io/cluster-api-provider-azure/util/reconciler" 37 ) 38 39 var ( 40 fakePeering1To2 = VnetPeeringSpec{ 41 PeeringName: "vnet1-to-vnet2", 42 SourceVnetName: "vnet1", 43 SourceResourceGroup: "group1", 44 RemoteVnetName: "vnet2", 45 RemoteResourceGroup: "group2", 46 SubscriptionID: "sub1", 47 } 48 fakePeering2To1 = VnetPeeringSpec{ 49 PeeringName: "vnet2-to-vnet1", 50 SourceVnetName: "vnet2", 51 SourceResourceGroup: "group2", 52 RemoteVnetName: "vnet1", 53 RemoteResourceGroup: "group1", 54 SubscriptionID: "sub1", 55 } 56 fakePeering1To3 = VnetPeeringSpec{ 57 PeeringName: "vnet1-to-vnet3", 58 SourceVnetName: "vnet1", 59 SourceResourceGroup: "group1", 60 RemoteVnetName: "vnet3", 61 RemoteResourceGroup: "group3", 62 SubscriptionID: "sub1", 63 } 64 fakePeering3To1 = VnetPeeringSpec{ 65 PeeringName: "vnet3-to-vnet1", 66 SourceVnetName: "vnet3", 67 SourceResourceGroup: "group3", 68 RemoteVnetName: "vnet1", 69 RemoteResourceGroup: "group1", 70 SubscriptionID: "sub1", 71 } 72 fakePeeringHubToSpoke = VnetPeeringSpec{ 73 PeeringName: "hub-to-spoke", 74 SourceVnetName: "hub-vnet", 75 SourceResourceGroup: "hub-group", 76 RemoteVnetName: "spoke-vnet", 77 RemoteResourceGroup: "spoke-group", 78 SubscriptionID: "sub1", 79 AllowForwardedTraffic: ptr.To(true), 80 AllowGatewayTransit: ptr.To(true), 81 AllowVirtualNetworkAccess: ptr.To(true), 82 UseRemoteGateways: ptr.To(false), 83 } 84 fakePeeringSpokeToHub = VnetPeeringSpec{ 85 PeeringName: "spoke-to-hub", 86 SourceVnetName: "spoke-vnet", 87 SourceResourceGroup: "spoke-group", 88 RemoteVnetName: "hub-vnet", 89 RemoteResourceGroup: "hub-group", 90 SubscriptionID: "sub1", 91 AllowForwardedTraffic: ptr.To(true), 92 AllowGatewayTransit: ptr.To(false), 93 AllowVirtualNetworkAccess: ptr.To(true), 94 UseRemoteGateways: ptr.To(true), 95 } 96 fakePeeringExtra = VnetPeeringSpec{ 97 PeeringName: "extra-peering", 98 SourceVnetName: "vnet3", 99 SourceResourceGroup: "group3", 100 RemoteVnetName: "vnet4", 101 RemoteResourceGroup: "group4", 102 SubscriptionID: "sub1", 103 } 104 fakePeeringSpecs = []azure.ResourceSpecGetter{&fakePeering1To2, &fakePeering2To1, &fakePeering1To3, &fakePeering3To1, &fakePeeringHubToSpoke, &fakePeeringSpokeToHub} 105 fakePeeringExtraSpecs = []azure.ResourceSpecGetter{&fakePeering1To2, &fakePeering2To1, &fakePeeringExtra} 106 notDoneError = azure.NewOperationNotDoneError(&infrav1.Future{}) 107 ) 108 109 func internalError() *azcore.ResponseError { 110 return &azcore.ResponseError{ 111 RawResponse: &http.Response{ 112 Body: io.NopCloser(strings.NewReader("#: Internal Server Error: StatusCode=500")), 113 StatusCode: http.StatusInternalServerError, 114 }, 115 } 116 } 117 118 func TestReconcileVnetPeerings(t *testing.T) { 119 testcases := []struct { 120 name string 121 expectedError string 122 expect func(s *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) 123 }{ 124 { 125 name: "create one peering", 126 expectedError: "", 127 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 128 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 129 p.VnetPeeringSpecs().Return(fakePeeringSpecs[:1]) 130 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 131 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 132 }, 133 }, 134 { 135 name: "noop if no peering specs are found", 136 expectedError: "", 137 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 138 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 139 p.VnetPeeringSpecs().Return([]azure.ResourceSpecGetter{}) 140 }, 141 }, 142 { 143 name: "create even number of peerings", 144 expectedError: "", 145 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 146 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 147 p.VnetPeeringSpecs().Return(fakePeeringSpecs[:2]) 148 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 149 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(&fakePeering2To1, nil) 150 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 151 }, 152 }, 153 { 154 name: "create odd number of peerings", 155 expectedError: "", 156 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 157 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 158 p.VnetPeeringSpecs().Return(fakePeeringExtraSpecs) 159 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 160 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(&fakePeering2To1, nil) 161 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringExtra, ServiceName).Return(&fakePeeringExtra, nil) 162 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 163 }, 164 }, 165 { 166 name: "create multiple peerings on one vnet", 167 expectedError: "", 168 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 169 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 170 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 171 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 172 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(&fakePeering2To1, nil) 173 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(&fakePeering1To3, nil) 174 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(&fakePeering3To1, nil) 175 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(&fakePeeringHubToSpoke, nil) 176 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(&fakePeeringSpokeToHub, nil) 177 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 178 }, 179 }, 180 { 181 name: "error in creating peering", 182 expectedError: "#: Internal Server Error: StatusCode=500", 183 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 184 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 185 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 186 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 187 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(&fakePeering2To1, nil) 188 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(nil, internalError()) 189 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(&fakePeering3To1, nil) 190 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(&fakePeeringHubToSpoke, nil) 191 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(&fakePeeringSpokeToHub, nil) 192 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, internalError()) 193 }, 194 }, 195 { 196 name: "not done error in creating is ignored", 197 expectedError: "#: Internal Server Error: StatusCode=500", 198 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 199 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 200 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 201 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 202 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(nil, internalError()) 203 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(nil, notDoneError) 204 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(&fakePeering3To1, nil) 205 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(&fakePeeringHubToSpoke, nil) 206 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(&fakePeeringSpokeToHub, nil) 207 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, internalError()) 208 }, 209 }, 210 { 211 name: "not done error in creating is overwritten", 212 expectedError: "#: Internal Server Error: StatusCode=500", 213 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 214 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 215 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 216 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 217 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(&fakePeering2To1, nil) 218 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(nil, notDoneError) 219 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(nil, internalError()) 220 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(&fakePeeringHubToSpoke, nil) 221 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(&fakePeeringSpokeToHub, nil) 222 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, internalError()) 223 }, 224 }, 225 { 226 name: "not done error in creating remains", 227 expectedError: "operation type on Azure resource / is not done", 228 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 229 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 230 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 231 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(&fakePeering1To2, nil) 232 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(&fakePeering2To1, nil) 233 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(nil, notDoneError) 234 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(&fakePeering3To1, nil) 235 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(&fakePeeringHubToSpoke, nil) 236 r.CreateOrUpdateResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(&fakePeeringSpokeToHub, nil) 237 p.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, notDoneError) 238 }, 239 }, 240 } 241 242 for _, tc := range testcases { 243 tc := tc 244 t.Run(tc.name, func(t *testing.T) { 245 g := NewWithT(t) 246 247 t.Parallel() 248 mockCtrl := gomock.NewController(t) 249 defer mockCtrl.Finish() 250 scopeMock := mock_vnetpeerings.NewMockVnetPeeringScope(mockCtrl) 251 asyncMock := mock_async.NewMockReconciler(mockCtrl) 252 253 tc.expect(scopeMock.EXPECT(), asyncMock.EXPECT()) 254 255 s := &Service{ 256 Scope: scopeMock, 257 Reconciler: asyncMock, 258 } 259 260 err := s.Reconcile(context.TODO()) 261 if tc.expectedError != "" { 262 g.Expect(err).To(HaveOccurred()) 263 g.Expect(err.Error()).To(ContainSubstring(tc.expectedError)) 264 } else { 265 g.Expect(err).NotTo(HaveOccurred()) 266 } 267 }) 268 } 269 } 270 271 func TestDeleteVnetPeerings(t *testing.T) { 272 testcases := []struct { 273 name string 274 expectedError string 275 expect func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) 276 }{ 277 { 278 name: "delete one peering", 279 expectedError: "", 280 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 281 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 282 p.VnetPeeringSpecs().Return(fakePeeringSpecs[:1]) 283 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 284 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 285 }, 286 }, 287 { 288 name: "noop if no peering specs are found", 289 expectedError: "", 290 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 291 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 292 p.VnetPeeringSpecs().Return([]azure.ResourceSpecGetter{}) 293 }, 294 }, 295 { 296 name: "delete even number of peerings", 297 expectedError: "", 298 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 299 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 300 p.VnetPeeringSpecs().Return(fakePeeringSpecs[:2]) 301 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 302 r.DeleteResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(nil) 303 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 304 }, 305 }, 306 { 307 name: "delete odd number of peerings", 308 expectedError: "", 309 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 310 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 311 p.VnetPeeringSpecs().Return(fakePeeringExtraSpecs) 312 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 313 r.DeleteResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(nil) 314 r.DeleteResource(gomockinternal.AContext(), &fakePeeringExtra, ServiceName).Return(nil) 315 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 316 }, 317 }, 318 { 319 name: "delete multiple peerings on one vnet", 320 expectedError: "", 321 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 322 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 323 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 324 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 325 r.DeleteResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(nil) 326 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(nil) 327 r.DeleteResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(nil) 328 r.DeleteResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(nil) 329 r.DeleteResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(nil) 330 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, nil) 331 }, 332 }, 333 { 334 name: "error in deleting peering", 335 expectedError: "#: Internal Server Error: StatusCode=500", 336 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 337 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 338 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 339 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 340 r.DeleteResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(nil) 341 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(internalError()) 342 r.DeleteResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(nil) 343 r.DeleteResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(nil) 344 r.DeleteResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(nil) 345 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, internalError()) 346 }, 347 }, 348 { 349 name: "not done error in deleting is ignored", 350 expectedError: "#: Internal Server Error: StatusCode=500", 351 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 352 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 353 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 354 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 355 r.DeleteResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(internalError()) 356 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(notDoneError) 357 r.DeleteResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(nil) 358 r.DeleteResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(nil) 359 r.DeleteResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(nil) 360 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, internalError()) 361 }, 362 }, 363 { 364 name: "not done error in deleting is overwritten", 365 expectedError: "#: Internal Server Error: StatusCode=500", 366 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 367 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 368 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 369 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 370 r.DeleteResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(nil) 371 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(notDoneError) 372 r.DeleteResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(internalError()) 373 r.DeleteResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(nil) 374 r.DeleteResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(nil) 375 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, internalError()) 376 }, 377 }, 378 { 379 name: "not done error in deleting remains", 380 expectedError: "operation type on Azure resource / is not done", 381 expect: func(p *mock_vnetpeerings.MockVnetPeeringScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) { 382 p.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout) 383 p.VnetPeeringSpecs().Return(fakePeeringSpecs) 384 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To2, ServiceName).Return(nil) 385 r.DeleteResource(gomockinternal.AContext(), &fakePeering2To1, ServiceName).Return(nil) 386 r.DeleteResource(gomockinternal.AContext(), &fakePeering1To3, ServiceName).Return(notDoneError) 387 r.DeleteResource(gomockinternal.AContext(), &fakePeering3To1, ServiceName).Return(nil) 388 r.DeleteResource(gomockinternal.AContext(), &fakePeeringHubToSpoke, ServiceName).Return(nil) 389 r.DeleteResource(gomockinternal.AContext(), &fakePeeringSpokeToHub, ServiceName).Return(nil) 390 p.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, notDoneError) 391 }, 392 }, 393 } 394 395 for _, tc := range testcases { 396 tc := tc 397 t.Run(tc.name, func(t *testing.T) { 398 g := NewWithT(t) 399 400 t.Parallel() 401 mockCtrl := gomock.NewController(t) 402 defer mockCtrl.Finish() 403 scopeMock := mock_vnetpeerings.NewMockVnetPeeringScope(mockCtrl) 404 asyncMock := mock_async.NewMockReconciler(mockCtrl) 405 406 tc.expect(scopeMock.EXPECT(), asyncMock.EXPECT()) 407 408 s := &Service{ 409 Scope: scopeMock, 410 Reconciler: asyncMock, 411 } 412 413 err := s.Delete(context.TODO()) 414 if tc.expectedError != "" { 415 fmt.Printf("\nExpected error:\t%s\n", tc.expectedError) 416 fmt.Printf("\nActual error:\t%s\n", err.Error()) 417 g.Expect(err).To(HaveOccurred()) 418 g.Expect(err.Error()).To(ContainSubstring(tc.expectedError)) 419 } else { 420 g.Expect(err).NotTo(HaveOccurred()) 421 } 422 }) 423 } 424 }