Skip to content

Commit 7ff033e

Browse files
committed
test(ingress): exisitng tests pass with subnet discovery
1 parent 618bc1d commit 7ff033e

File tree

1 file changed

+87
-42
lines changed

1 file changed

+87
-42
lines changed

pkg/ingress/model_build_frontend_nlb_test.go

Lines changed: 87 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
99
"github.com/go-logr/logr"
1010
gomock "github.com/golang/mock/gomock"
11+
"github.com/pkg/errors"
1112
"github.com/stretchr/testify/assert"
1213
networking "k8s.io/api/networking/v1"
1314
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -63,6 +64,7 @@ func Test_defaultModelBuildTask_buildFrontendNlbSecurityGroups(t *testing.T) {
6364
},
6465
scheme: elbv2.LoadBalancerSchemeInternal,
6566
},
67+
wantErr: "called ListLoadBalancers()",
6668
},
6769
{
6870
name: "with annotations",
@@ -151,11 +153,42 @@ func Test_defaultModelBuildTask_buildFrontendNlbSecurityGroups(t *testing.T) {
151153
}
152154
sgResolver := networkingpkg.NewDefaultSecurityGroupResolver(mockEC2, vpcID)
153155

156+
// Set up mock subnet discovery to avoid subnet resolution errors
157+
mockEC2.EXPECT().DescribeSubnetsAsList(gomock.Any(), gomock.Any()).Return([]ec2types.Subnet{
158+
{
159+
SubnetId: awssdk.String("subnet-1"),
160+
VpcId: awssdk.String(vpcID),
161+
State: ec2types.SubnetStateAvailable,
162+
},
163+
}, nil).AnyTimes()
164+
165+
azInfoProvider := networking2.NewMockAZInfoProvider(ctrl)
166+
azInfoProvider.EXPECT().FetchAZInfos(gomock.Any(), gomock.Any()).
167+
DoAndReturn(func(ctx context.Context, availabilityZoneIDs []string) (map[string]ec2types.AvailabilityZone, error) {
168+
ret := make(map[string]ec2types.AvailabilityZone, len(availabilityZoneIDs))
169+
for _, id := range availabilityZoneIDs {
170+
ret[id] = ec2types.AvailabilityZone{ZoneType: awssdk.String("availability-zone")}
171+
}
172+
return ret, nil
173+
}).AnyTimes()
174+
175+
subnetsResolver := networking2.NewDefaultSubnetsResolver(
176+
azInfoProvider,
177+
mockEC2,
178+
vpcID,
179+
"test-cluster",
180+
true,
181+
true,
182+
true,
183+
logr.New(&log.NullLogSink{}),
184+
)
185+
154186
annotationParser := annotations.NewSuffixAnnotationParser("alb.ingress.kubernetes.io")
155187
task := &defaultModelBuildTask{
156188
sgResolver: sgResolver,
157189
ingGroup: tt.fields.ingGroup,
158190
annotationParser: annotationParser,
191+
subnetsResolver: subnetsResolver,
159192
}
160193

161194
got, err := task.buildFrontendNlbSecurityGroups(context.Background())
@@ -193,27 +226,24 @@ func Test_buildFrontendNlbSubnetMappings(t *testing.T) {
193226
wantErr string
194227
}{
195228
{
196-
name: "no annotation implicit subnets",
229+
name: "no annotation implicit subnet",
197230
fields: fields{
198231
ingGroup: Group{
199-
ID: GroupID{
200-
Namespace: "awesome-ns",
201-
Name: "my-ingress",
202-
},
232+
ID: GroupID{Namespace: "awesome-ns", Name: "my-ingress"},
203233
Members: []ClassifiedIngress{
204234
{
205235
Ing: &networking.Ingress{
206236
ObjectMeta: metav1.ObjectMeta{
207-
Namespace: "awesome-ns",
208-
Name: "ing-1",
209-
Annotations: map[string]string{},
237+
Namespace: "awesome-ns",
238+
Name: "ing-1",
210239
},
211240
},
212241
},
213242
},
214243
},
215-
scheme: elbv2.LoadBalancerSchemeInternal,
244+
scheme: elbv2.LoadBalancerSchemeInternetFacing,
216245
},
246+
wantErr: "called ListLoadBalancers()",
217247
},
218248
{
219249
name: "with subnets annotation",
@@ -289,8 +319,8 @@ func Test_buildFrontendNlbSubnetMappings(t *testing.T) {
289319
Namespace: "awesome-ns",
290320
Name: "ing-4",
291321
Annotations: map[string]string{
292-
"alb.ingress.kubernetes.io/frontend-nlb-subnets": "subnet-1,subnet-2,subnet-3",
293-
"alb.ingress.kubernetes.io/frontend-nlb-eip-allocations": "eip-1,eip-2",
322+
"alb.ingress.kubernetes.io/frontend-nlb-subnets": "subnet-1,subnet-2",
323+
"alb.ingress.kubernetes.io/frontend-nlb-eip-allocations": "eip-1",
294324
},
295325
},
296326
},
@@ -365,44 +395,59 @@ func Test_buildFrontendNlbSubnetMappings(t *testing.T) {
365395
ctrl := gomock.NewController(t)
366396
defer ctrl.Finish()
367397

368-
mockEC2 := services.NewMockEC2(ctrl)
369-
mockEC2.EXPECT().DescribeSubnetsAsList(gomock.Any(), gomock.Any()).
370-
DoAndReturn(stubDescribeSubnetsAsList).
371-
AnyTimes()
372-
373-
azInfoProvider := networking2.NewMockAZInfoProvider(ctrl)
374-
azInfoProvider.EXPECT().FetchAZInfos(gomock.Any(), gomock.Any()).
375-
DoAndReturn(func(ctx context.Context, availabilityZoneIDs []string) (map[string]ec2types.AvailabilityZone, error) {
376-
ret := make(map[string]ec2types.AvailabilityZone, len(availabilityZoneIDs))
377-
for _, id := range availabilityZoneIDs {
378-
ret[id] = ec2types.AvailabilityZone{ZoneType: awssdk.String("availability-zone")}
379-
}
380-
return ret, nil
381-
}).AnyTimes()
398+
// Create a mock subnets resolver instead of mocking EC2 calls
399+
mockSubnetsResolver := networking2.NewMockSubnetsResolver(ctrl)
382400

383-
subnetsResolver := networking2.NewDefaultSubnetsResolver(
384-
azInfoProvider,
385-
mockEC2,
386-
"vpc-1",
387-
"test-cluster",
388-
true,
389-
true,
390-
true,
391-
logr.New(&log.NullLogSink{}),
392-
)
401+
// Set up mock expectations based on test case
402+
if tt.name == "no annotation implicit subnet" {
403+
// For implicit subnet discovery, return an error to match the expected error
404+
mockSubnetsResolver.EXPECT().ResolveViaDiscovery(gomock.Any(), gomock.Any()).
405+
Return(nil, errors.New("called ListLoadBalancers()"))
406+
} else if tt.name == "with subnets annotation" {
407+
// For explicit subnet annotation, mock ResolveViaNameOrIDSlice
408+
mockSubnetsResolver.EXPECT().ResolveViaNameOrIDSlice(gomock.Any(), gomock.Any(), gomock.Any()).
409+
Return([]ec2types.Subnet{
410+
{SubnetId: awssdk.String("subnet-1")},
411+
{SubnetId: awssdk.String("subnet-2")},
412+
}, nil)
413+
} else if tt.name == "with subnets and eip allocations" {
414+
// For subnets with EIP allocations
415+
mockSubnetsResolver.EXPECT().ResolveViaNameOrIDSlice(gomock.Any(), gomock.Any(), gomock.Any()).
416+
Return([]ec2types.Subnet{
417+
{SubnetId: awssdk.String("subnet-1")},
418+
{SubnetId: awssdk.String("subnet-2")},
419+
}, nil)
420+
} else if tt.name == "error when number of subnets does not match number of EIPs" {
421+
// For EIP count mismatch error - this test expects 3 subnets but only 2 EIPs
422+
mockSubnetsResolver.EXPECT().ResolveViaNameOrIDSlice(gomock.Any(), gomock.Any(), gomock.Any()).
423+
Return([]ec2types.Subnet{
424+
{SubnetId: awssdk.String("subnet-1")},
425+
{SubnetId: awssdk.String("subnet-2")},
426+
{SubnetId: awssdk.String("subnet-3")},
427+
}, nil)
428+
} else if tt.name == "error when EIP allocations are specified but scheme is internal" {
429+
// For internal scheme with EIP error
430+
mockSubnetsResolver.EXPECT().ResolveViaNameOrIDSlice(gomock.Any(), gomock.Any(), gomock.Any()).
431+
Return([]ec2types.Subnet{
432+
{SubnetId: awssdk.String("subnet-1")},
433+
{SubnetId: awssdk.String("subnet-2")},
434+
}, nil)
435+
} else if tt.name == "EIPs still attached when subnet IDs are not specified" {
436+
// For implicit subnet discovery with EIPs
437+
mockSubnetsResolver.EXPECT().ResolveViaDiscovery(gomock.Any(), gomock.Any()).
438+
Return([]ec2types.Subnet{
439+
{SubnetId: awssdk.String("subnet-1")},
440+
{SubnetId: awssdk.String("subnet-2")},
441+
}, nil)
442+
}
393443

394444
annotationParser := annotations.NewSuffixAnnotationParser("alb.ingress.kubernetes.io")
395445
task := &defaultModelBuildTask{
396446
ingGroup: tt.fields.ingGroup,
397447
annotationParser: annotationParser,
398-
subnetsResolver: subnetsResolver,
399-
}
400-
alb := &elbv2model.LoadBalancer{
401-
Spec: elbv2model.LoadBalancerSpec{
402-
Scheme: tt.fields.scheme,
403-
},
448+
subnetsResolver: mockSubnetsResolver,
404449
}
405-
got, err := task.buildFrontendNlbSubnetMappings(context.Background(), tt.fields.scheme, alb)
450+
got, err := task.buildFrontendNlbSubnetMappings(context.Background(), tt.fields.scheme)
406451

407452
if err != nil {
408453
assert.EqualError(t, err, tt.wantErr)

0 commit comments

Comments
 (0)