@@ -1024,63 +1024,98 @@ func TestWarmENIInteractions(t *testing.T) {
1024
1024
_ = ds .AddENI ("eni-2" , 2 , false , false , false )
1025
1025
_ = ds .AddENI ("eni-3" , 3 , false , false , false )
1026
1026
1027
+ // Add an IP address to ENI 1 and assign it to a pod
1027
1028
ipv4Addr := net.IPNet {IP : net .ParseIP ("1.1.1.1" ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}
1028
1029
_ = ds .AddIPv4CidrToStore ("eni-1" , ipv4Addr , false )
1029
1030
key1 := IPAMKey {"net0" , "sandbox-1" , "eth0" }
1030
1031
_ , _ , err := ds .AssignPodIPv4Address (key1 , IPAMMetadata {K8SPodNamespace : "default" , K8SPodName : "sample-pod-1" })
1031
1032
assert .NoError (t , err )
1032
1033
1034
+ // Add another IP address to ENI 1 and assign a pod
1033
1035
ipv4Addr = net.IPNet {IP : net .ParseIP ("1.1.1.2" ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}
1034
1036
_ = ds .AddIPv4CidrToStore ("eni-1" , ipv4Addr , false )
1035
1037
key2 := IPAMKey {"net0" , "sandbox-2" , "eth0" }
1036
1038
_ , _ , err = ds .AssignPodIPv4Address (key2 , IPAMMetadata {K8SPodNamespace : "default" , K8SPodName : "sample-pod-2" })
1037
1039
assert .NoError (t , err )
1038
1040
1041
+ // Add two IP addresses to ENI 2 and one IP address to ENI 3
1039
1042
ipv4Addr = net.IPNet {IP : net .ParseIP ("1.1.2.1" ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}
1040
1043
_ = ds .AddIPv4CidrToStore ("eni-2" , ipv4Addr , false )
1041
1044
ipv4Addr = net.IPNet {IP : net .ParseIP ("1.1.2.2" ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}
1042
1045
_ = ds .AddIPv4CidrToStore ("eni-2" , ipv4Addr , false )
1043
1046
ipv4Addr = net.IPNet {IP : net .ParseIP ("1.1.3.1" ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}
1044
1047
_ = ds .AddIPv4CidrToStore ("eni-3" , ipv4Addr , false )
1045
1048
1046
- noWarmIPTarget := 0
1047
-
1048
1049
ds .eniPool ["eni-2" ].createTime = time.Time {}
1049
1050
ds .eniPool ["eni-3" ].createTime = time.Time {}
1050
1051
1051
- // We have three ENIs, 5 IPs and two pods on ENI 1. Each ENI can handle two pods.
1052
+ // We have 3 ENIs, 5 IPs and 2 pods on ENI 1.
1053
+ // ENI 1: 2 IPs allocated, 2 IPs in use
1054
+ // ENI 2: 2 IPs allocated, 0 IPs in use
1055
+ // ENI 3: 1 IP allocated, 0 IPs in use
1056
+ // => 3 free IPs
1052
1057
// We should not be able to remove any ENIs if either warmIPTarget >= 3 or minimumWarmIPTarget >= 5
1058
+
1059
+ // WARM IP TARGET=3, MINIMUM_IP_TARGET=1 => no ENI should be removed
1053
1060
eni := ds .RemoveUnusedENIFromStore (3 , 1 , 0 )
1054
1061
assert .Equal (t , "" , eni )
1055
- // Should not be able to free this ENI because we want at least 5 IPs, which requires at least three ENIs
1062
+
1063
+ // WARM IP TARGET=1, MINIMUM_IP_TARGET=5 => no ENI should be removed
1056
1064
eni = ds .RemoveUnusedENIFromStore (1 , 5 , 0 )
1057
1065
assert .Equal (t , "" , eni )
1058
- // Should be able to free an ENI because both warmIPTarget and minimumWarmIPTarget are both effectively 4
1066
+
1067
+ // WARM IP TARGET=2, MINIMUM_IP_TARGET=4 => ENI 3 should be removed as we only need 2 free IPs, which ENI 2 has
1059
1068
removedEni := ds .RemoveUnusedENIFromStore (2 , 4 , 0 )
1060
- assert .Contains (t , [] string { "eni-2" , "eni-3" } , removedEni )
1069
+ assert .Equal (t , "eni-3" , removedEni )
1061
1070
1062
- // Should not be able to free an ENI because minimumWarmIPTarget requires at least two ENIs and no warm IP target
1063
- eni = ds .RemoveUnusedENIFromStore (noWarmIPTarget , 3 , 0 )
1064
- assert .Equal (t , "" , eni )
1065
- // Should be able to free an ENI because one ENI can provide a minimum count of 2 IPs
1066
- secondRemovedEni := ds .RemoveUnusedENIFromStore (noWarmIPTarget , 2 , 0 )
1067
- assert .Contains (t , []string {"eni-2" , "eni-3" }, secondRemovedEni )
1071
+ // We have 2 ENIs, 4 IPs and 2 pods on ENI 1.
1072
+ // ENI 1: 2 IPs allocated, 2 IPs in use
1073
+ // ENI 2: 2 IPs allocated, 0 IPs in use
1074
+ // => 2 free IPs
1068
1075
1069
- assert .NotEqual (t , removedEni , secondRemovedEni , "The two removed ENIs should not be the same ENI." )
1076
+ // WARM IP TARGET=0, MINIMUM_IP_TARGET=3 => no ENI should be removed
1077
+ eni = ds .RemoveUnusedENIFromStore (0 , 3 , 0 )
1078
+ assert .Equal (t , "" , eni )
1070
1079
1071
- _ = ds .AddENI ("eni-4" , 3 , false , true , false )
1072
- _ = ds .AddENI ("eni-5" , 3 , false , false , true )
1080
+ // WARM IP TARGET=0, MINIMUM_IP_TARGET=2 => ENI 2 should be removed as ENI 1 covers the requirements
1081
+ removedEni = ds .RemoveUnusedENIFromStore (0 , 2 , 0 )
1082
+ assert .Contains (t , "eni-2" , removedEni )
1073
1083
1084
+ // Add 2 more ENIs to the datastore and add 1 IP address to each of them
1085
+ ds .AddENI ("eni-4" , 4 , false , true , false ) // trunk ENI
1086
+ ds .AddENI ("eni-5" , 5 , false , false , true ) // EFA ENI
1074
1087
ipv4Addr = net.IPNet {IP : net .ParseIP ("1.1.4.1" ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}
1075
- _ = ds .AddIPv4CidrToStore ("eni-4" , ipv4Addr , false )
1088
+ ds .AddIPv4CidrToStore ("eni-4" , ipv4Addr , false )
1076
1089
ipv4Addr = net.IPNet {IP : net .ParseIP ("1.1.5.1" ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}
1077
- _ = ds .AddIPv4CidrToStore ("eni-5" , ipv4Addr , false )
1078
-
1090
+ ds .AddIPv4CidrToStore ("eni-5" , ipv4Addr , false )
1079
1091
ds .eniPool ["eni-4" ].createTime = time.Time {}
1080
1092
ds .eniPool ["eni-5" ].createTime = time.Time {}
1081
- thirdRemovedEni := ds .RemoveUnusedENIFromStore (noWarmIPTarget , 2 , 0 )
1082
- // None of the others can be removed...
1083
- assert .Equal (t , "" , thirdRemovedEni )
1093
+
1094
+ // We have 3 ENIs, 4 IPs and 2 pods on ENI 1.
1095
+ // ENI 1: 2 IPs allocated, 2 IPs in use
1096
+ // ENI 4: 1 IPs allocated, 0 IPs in use
1097
+ // ENI 5: 1 IPs allocated, 0 IPs in use
1098
+ // => 2 free IPs
1099
+
1100
+ // WARM IP TARGET=0, MINIMUM_IP_TARGET=2 => no ENI can be removed because ENI 4 is a trunk ENI and ENI 5 is an EFA ENI
1101
+ removedEni = ds .RemoveUnusedENIFromStore (0 , 2 , 0 )
1102
+ assert .Equal (t , "" , removedEni )
1103
+ assert .Equal (t , 3 , ds .GetENIs ())
1104
+
1105
+ // Add 1 more normal ENI to the datastore
1106
+ ds .AddENI ("eni-6" , 6 , false , false , false ) // trunk ENI
1107
+ ds .eniPool ["eni-6" ].createTime = time.Time {}
1108
+
1109
+ // We have 4 ENIs, 4 IPs and 2 pods on ENI 1.
1110
+ // ENI 1: 2 IPs allocated, 2 IPs in use
1111
+ // ENI 4: 1 IPs allocated, 0 IPs in use
1112
+ // ENI 5: 1 IPs allocated, 0 IPs in use
1113
+ // ENI 6: 0 IPs allocated, 0 IPs in use
1114
+ // => 2 free IPs
1115
+
1116
+ // WARM IP TARGET=0, MINIMUM_IP_TARGET=2 => ENI 6 can be removed
1117
+ removedEni = ds .RemoveUnusedENIFromStore (0 , 2 , 0 )
1118
+ assert .Equal (t , "eni-6" , removedEni )
1084
1119
assert .Equal (t , 3 , ds .GetENIs ())
1085
1120
}
1086
1121
0 commit comments