Skip to content

Commit e3fd64e

Browse files
authored
Merge pull request #365 from noamran/359-ilb
Add unit tests for internalloadbalancers
2 parents 6135007 + 95eefb3 commit e3fd64e

File tree

1 file changed

+316
-0
lines changed

1 file changed

+316
-0
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
/*
2+
Copyright 2019 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 internalloadbalancers
18+
19+
import (
20+
"context"
21+
"net/http"
22+
"testing"
23+
24+
"github.com/Azure/go-autorest/autorest/to"
25+
26+
"sigs.k8s.io/cluster-api-provider-azure/cloud/services/internalloadbalancers/mock_internalloadbalancers"
27+
"sigs.k8s.io/cluster-api-provider-azure/cloud/services/subnets/mock_subnets"
28+
"sigs.k8s.io/cluster-api-provider-azure/cloud/services/virtualnetworks/mock_virtualnetworks"
29+
30+
"github.com/Azure/go-autorest/autorest"
31+
"github.com/golang/mock/gomock"
32+
33+
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network"
34+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35+
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1alpha2"
36+
"sigs.k8s.io/cluster-api-provider-azure/cloud/scope"
37+
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha2"
38+
"sigs.k8s.io/controller-runtime/pkg/client/fake"
39+
)
40+
41+
func TestReconcileInternalLoadBalancer(t *testing.T) {
42+
testcases := []struct {
43+
name string
44+
internalLBSpec Spec
45+
expectedError string
46+
expect func(m *mock_internalloadbalancers.MockClientMockRecorder,
47+
mVnet *mock_virtualnetworks.MockClientMockRecorder,
48+
mSubnet *mock_subnets.MockClientMockRecorder)
49+
}{
50+
{
51+
name: "internal load balancer does not exist",
52+
internalLBSpec: Spec{
53+
Name: "my-lb",
54+
SubnetCidr: "10.0.0.0/16",
55+
SubnetName: "my-subnet",
56+
VnetName: "my-vnet",
57+
IPAddress: "10.0.0.10",
58+
},
59+
expectedError: "",
60+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder,
61+
mVnet *mock_virtualnetworks.MockClientMockRecorder,
62+
mSubnet *mock_subnets.MockClientMockRecorder) {
63+
m.Get(context.TODO(), "my-rg", "my-lb").Return(network.LoadBalancer{}, autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 404}, "Not found"))
64+
mVnet.CheckIPAddressAvailability(context.TODO(), "my-rg", "my-vnet", "10.0.0.10").Return(network.IPAddressAvailabilityResult{Available: to.BoolPtr(true)}, nil)
65+
mSubnet.Get(context.TODO(), "my-rg", "my-vnet", "my-subnet").Return(network.Subnet{}, nil)
66+
m.CreateOrUpdate(context.TODO(), "my-rg", "my-lb", gomock.AssignableToTypeOf(network.LoadBalancer{}))
67+
},
68+
},
69+
{
70+
name: "internal load balancer retrieval fails",
71+
internalLBSpec: Spec{
72+
Name: "my-lb",
73+
SubnetCidr: "10.0.0.0/16",
74+
SubnetName: "my-subnet",
75+
VnetName: "my-vnet",
76+
IPAddress: "10.0.0.10",
77+
},
78+
expectedError: "failed to look for existing internal LB: #: Internal Server Error: StatusCode=500",
79+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder,
80+
mVnet *mock_virtualnetworks.MockClientMockRecorder,
81+
mSubnet *mock_subnets.MockClientMockRecorder) {
82+
m.Get(context.TODO(), "my-rg", "my-lb").Return(network.LoadBalancer{}, autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 500}, "Internal Server Error"))
83+
},
84+
},
85+
{
86+
name: "internal load balancer exists",
87+
internalLBSpec: Spec{
88+
Name: "my-lb",
89+
SubnetCidr: "10.0.0.0/16",
90+
SubnetName: "my-subnet",
91+
VnetName: "my-vnet",
92+
IPAddress: "10.0.0.10",
93+
},
94+
expectedError: "",
95+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder,
96+
mVnet *mock_virtualnetworks.MockClientMockRecorder,
97+
mSubnet *mock_subnets.MockClientMockRecorder) {
98+
m.Get(context.TODO(), "my-rg", "my-lb").Return(network.LoadBalancer{
99+
LoadBalancerPropertiesFormat: &network.LoadBalancerPropertiesFormat{
100+
FrontendIPConfigurations: &[]network.FrontendIPConfiguration{
101+
{
102+
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{},
103+
},
104+
}}}, nil)
105+
mVnet.CheckIPAddressAvailability(context.TODO(), "my-rg", "my-vnet", "10.0.0.10").Return(network.IPAddressAvailabilityResult{Available: to.BoolPtr(true)}, nil)
106+
mSubnet.Get(context.TODO(), "my-rg", "my-vnet", "my-subnet").Return(network.Subnet{}, nil)
107+
m.CreateOrUpdate(context.TODO(), "my-rg", "my-lb", gomock.AssignableToTypeOf(network.LoadBalancer{}))
108+
},
109+
},
110+
{
111+
name: "internal load balancer does not exist and IP is not available",
112+
internalLBSpec: Spec{
113+
Name: "my-lb",
114+
SubnetCidr: "10.0.0.0/16",
115+
SubnetName: "my-subnet",
116+
VnetName: "my-vnet",
117+
IPAddress: "10.0.0.10",
118+
},
119+
expectedError: "IP 10.0.0.10 is not available in vnet my-vnet and there were no other available IPs found",
120+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder,
121+
mVnet *mock_virtualnetworks.MockClientMockRecorder,
122+
mSubnet *mock_subnets.MockClientMockRecorder) {
123+
m.Get(context.TODO(), "my-rg", "my-lb").Return(network.LoadBalancer{}, autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 404}, "Not found"))
124+
mVnet.CheckIPAddressAvailability(context.TODO(), "my-rg", "my-vnet", "10.0.0.10").Return(network.IPAddressAvailabilityResult{Available: to.BoolPtr(false)}, nil)
125+
},
126+
},
127+
{
128+
name: "internal load balancer does not exist and subnet does not exist",
129+
internalLBSpec: Spec{
130+
Name: "my-lb",
131+
SubnetCidr: "10.0.0.0/16",
132+
SubnetName: "my-subnet",
133+
VnetName: "my-vnet",
134+
IPAddress: "10.0.0.10",
135+
},
136+
expectedError: "failed to get subnet: #: Not found: StatusCode=404",
137+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder,
138+
mVnet *mock_virtualnetworks.MockClientMockRecorder,
139+
mSubnet *mock_subnets.MockClientMockRecorder) {
140+
m.Get(context.TODO(), "my-rg", "my-lb").Return(network.LoadBalancer{}, autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 404}, "Not found"))
141+
mVnet.CheckIPAddressAvailability(context.TODO(), "my-rg", "my-vnet", "10.0.0.10").Return(network.IPAddressAvailabilityResult{Available: to.BoolPtr(true)}, nil)
142+
mSubnet.Get(context.TODO(), "my-rg", "my-vnet", "my-subnet").Return(network.Subnet{}, autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 404}, "Not found"))
143+
},
144+
},
145+
}
146+
147+
for _, tc := range testcases {
148+
t.Run(tc.name, func(t *testing.T) {
149+
mockCtrl := gomock.NewController(t)
150+
internalLBMock := mock_internalloadbalancers.NewMockClient(mockCtrl)
151+
subnetMock := mock_subnets.NewMockClient(mockCtrl)
152+
vnetMock := mock_virtualnetworks.NewMockClient(mockCtrl)
153+
154+
cluster := &clusterv1.Cluster{
155+
ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"},
156+
}
157+
158+
client := fake.NewFakeClient(cluster)
159+
160+
tc.expect(internalLBMock.EXPECT(), vnetMock.EXPECT(), subnetMock.EXPECT())
161+
162+
clusterScope, err := scope.NewClusterScope(scope.ClusterScopeParams{
163+
AzureClients: scope.AzureClients{
164+
SubscriptionID: "123",
165+
Authorizer: autorest.NullAuthorizer{},
166+
},
167+
Client: client,
168+
Cluster: cluster,
169+
AzureCluster: &infrav1.AzureCluster{
170+
Spec: infrav1.AzureClusterSpec{
171+
Location: "test-location",
172+
ResourceGroup: "my-rg",
173+
NetworkSpec: infrav1.NetworkSpec{
174+
Vnet: infrav1.VnetSpec{Name: "my-vnet", ResourceGroup: "my-rg"},
175+
Subnets: []*infrav1.SubnetSpec{{
176+
Name: "my-subnet",
177+
Role: infrav1.SubnetNode,
178+
}},
179+
},
180+
},
181+
},
182+
})
183+
if err != nil {
184+
t.Fatalf("Failed to create test context: %v", err)
185+
}
186+
187+
s := &Service{
188+
Scope: clusterScope,
189+
Client: internalLBMock,
190+
SubnetsClient: subnetMock,
191+
VirtualNetworksClient: vnetMock,
192+
}
193+
194+
if err := s.Reconcile(context.TODO(), &tc.internalLBSpec); err != nil {
195+
if tc.expectedError == "" || err.Error() != tc.expectedError {
196+
t.Fatalf("got an unexpected error: %v", err)
197+
}
198+
} else {
199+
if tc.expectedError != "" {
200+
t.Fatalf("expected an error: %v", tc.expectedError)
201+
202+
}
203+
}
204+
})
205+
}
206+
}
207+
208+
func TestDeleteInternalLB(t *testing.T) {
209+
testcases := []struct {
210+
name string
211+
internalLBSpec Spec
212+
expectedError string
213+
expect func(m *mock_internalloadbalancers.MockClientMockRecorder)
214+
}{
215+
{
216+
name: "internal load balancer exists",
217+
internalLBSpec: Spec{
218+
Name: "my-lb",
219+
SubnetCidr: "10.0.0.0/16",
220+
SubnetName: "my-subnet",
221+
VnetName: "my-vnet",
222+
IPAddress: "10.0.0.10",
223+
},
224+
expectedError: "",
225+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder) {
226+
m.Delete(context.TODO(), "my-rg", "my-lb")
227+
},
228+
},
229+
{
230+
name: "internal load balancer already deleted",
231+
internalLBSpec: Spec{
232+
Name: "my-lb",
233+
SubnetCidr: "10.0.0.0/16",
234+
SubnetName: "my-subnet",
235+
VnetName: "my-vnet",
236+
IPAddress: "10.0.0.10",
237+
},
238+
expectedError: "",
239+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder) {
240+
m.Delete(context.TODO(), "my-rg", "my-lb").
241+
Return(autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 404}, "Not found"))
242+
},
243+
},
244+
{
245+
name: "internal load balancer deletion fails",
246+
internalLBSpec: Spec{
247+
Name: "my-lb",
248+
SubnetCidr: "10.0.0.0/16",
249+
SubnetName: "my-subnet",
250+
VnetName: "my-vnet",
251+
IPAddress: "10.0.0.10",
252+
},
253+
expectedError: "failed to delete internal load balancer my-lb in resource group my-rg: #: Internal Server Error: StatusCode=500",
254+
expect: func(m *mock_internalloadbalancers.MockClientMockRecorder) {
255+
m.Delete(context.TODO(), "my-rg", "my-lb").
256+
Return(autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 500}, "Internal Server Error"))
257+
},
258+
},
259+
}
260+
261+
for _, tc := range testcases {
262+
t.Run(tc.name, func(t *testing.T) {
263+
mockCtrl := gomock.NewController(t)
264+
internalLBMock := mock_internalloadbalancers.NewMockClient(mockCtrl)
265+
266+
cluster := &clusterv1.Cluster{
267+
ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"},
268+
}
269+
270+
client := fake.NewFakeClient(cluster)
271+
272+
tc.expect(internalLBMock.EXPECT())
273+
274+
clusterScope, err := scope.NewClusterScope(scope.ClusterScopeParams{
275+
AzureClients: scope.AzureClients{
276+
SubscriptionID: "123",
277+
Authorizer: autorest.NullAuthorizer{},
278+
},
279+
Client: client,
280+
Cluster: cluster,
281+
AzureCluster: &infrav1.AzureCluster{
282+
Spec: infrav1.AzureClusterSpec{
283+
Location: "test-location",
284+
ResourceGroup: "my-rg",
285+
NetworkSpec: infrav1.NetworkSpec{
286+
Vnet: infrav1.VnetSpec{Name: "my-vnet", ResourceGroup: "my-rg"},
287+
Subnets: []*infrav1.SubnetSpec{{
288+
Name: "my-subnet",
289+
Role: infrav1.SubnetNode,
290+
}},
291+
},
292+
},
293+
},
294+
})
295+
if err != nil {
296+
t.Fatalf("Failed to create test context: %v", err)
297+
}
298+
299+
s := &Service{
300+
Scope: clusterScope,
301+
Client: internalLBMock,
302+
}
303+
304+
if err := s.Delete(context.TODO(), &tc.internalLBSpec); err != nil {
305+
if tc.expectedError == "" || err.Error() != tc.expectedError {
306+
t.Fatalf("got an unexpected error: %v", err)
307+
}
308+
} else {
309+
if tc.expectedError != "" {
310+
t.Fatalf("expected an error: %v", tc.expectedError)
311+
312+
}
313+
}
314+
})
315+
}
316+
}

0 commit comments

Comments
 (0)