@@ -915,11 +915,17 @@ var _ = Describe("CloudProvider", func() {
915
915
InstanceMatchCriteria : string (ec2types .InstanceMatchCriteriaTargeted ),
916
916
InstanceType : "m5.large" ,
917
917
OwnerID : "012345678901" ,
918
+ State : v1 .CapacityReservationStateActive ,
919
+ ReservationType : v1 .CapacityReservationTypeDefault ,
918
920
},
919
921
}
920
922
setReservationID := func (id string ) {
921
923
out := awsEnv .EC2API .DescribeInstancesBehavior .Output .Clone ()
924
+ out .Reservations [0 ].Instances [0 ].SpotInstanceRequestId = nil
922
925
out .Reservations [0 ].Instances [0 ].CapacityReservationId = lo .ToPtr (id )
926
+ out .Reservations [0 ].Instances [0 ].CapacityReservationSpecification = & ec2types.CapacityReservationSpecificationResponse {
927
+ CapacityReservationPreference : ec2types .CapacityReservationPreferenceCapacityReservationsOnly ,
928
+ }
923
929
awsEnv .EC2API .DescribeInstancesBehavior .Output .Set (out )
924
930
}
925
931
setReservationID ("cr-foo" )
@@ -1414,25 +1420,30 @@ var _ = Describe("CloudProvider", func() {
1414
1420
})
1415
1421
})
1416
1422
Context ("Capacity Reservations" , func () {
1417
- var reservationID string
1423
+ const reservationCapacity = 10
1424
+ var crs []ec2types.CapacityReservation
1418
1425
BeforeEach (func () {
1419
- reservationID = "cr-m5.large-1a-1"
1420
- cr := ec2types.CapacityReservation {
1421
- AvailabilityZone : lo .ToPtr ("test-zone-1a" ),
1422
- InstanceType : lo .ToPtr ("m5.large" ),
1423
- OwnerId : lo .ToPtr ("012345678901" ),
1424
- InstanceMatchCriteria : ec2types .InstanceMatchCriteriaTargeted ,
1425
- CapacityReservationId : lo .ToPtr (reservationID ),
1426
- AvailableInstanceCount : lo.ToPtr [int32 ](10 ),
1427
- State : ec2types .CapacityReservationStateActive ,
1426
+ crs = lo .Map (v1 .CapacityReservationType ("" ).Values (), func (crt v1.CapacityReservationType , _ int ) ec2types.CapacityReservation {
1427
+ return ec2types.CapacityReservation {
1428
+ AvailabilityZone : lo .ToPtr ("test-zone-1a" ),
1429
+ InstanceType : lo .ToPtr ("m5.large" ),
1430
+ OwnerId : lo .ToPtr ("012345678901" ),
1431
+ InstanceMatchCriteria : ec2types .InstanceMatchCriteriaTargeted ,
1432
+ CapacityReservationId : lo .ToPtr (fmt .Sprintf ("cr-m5.large-1a-%s" , string (crt ))),
1433
+ AvailableInstanceCount : lo.ToPtr [int32 ](reservationCapacity ),
1434
+ State : ec2types .CapacityReservationStateActive ,
1435
+ ReservationType : ec2types .CapacityReservationType (crt ),
1436
+ }
1437
+ })
1438
+ for _ , cr := range crs {
1439
+ awsEnv .CapacityReservationProvider .SetAvailableInstanceCount (* cr .CapacityReservationId , 10 )
1428
1440
}
1429
- awsEnv .CapacityReservationProvider .SetAvailableInstanceCount (reservationID , 10 )
1430
1441
awsEnv .EC2API .DescribeCapacityReservationsOutput .Set (& ec2.DescribeCapacityReservationsOutput {
1431
- CapacityReservations : []ec2types.CapacityReservation {cr },
1442
+ CapacityReservations : crs ,
1443
+ })
1444
+ nodeClass .Status .CapacityReservations = lo .Map (crs , func (cr ec2types.CapacityReservation , _ int ) v1.CapacityReservation {
1445
+ return lo .Must (v1 .CapacityReservationFromEC2 (awsEnv .Clock , & cr ))
1432
1446
})
1433
- nodeClass .Status .CapacityReservations = []v1.CapacityReservation {
1434
- lo .Must (v1 .CapacityReservationFromEC2 (fakeClock , & cr )),
1435
- }
1436
1447
nodePool .Spec .Template .Spec .Requirements = []karpv1.NodeSelectorRequirementWithMinValues {{NodeSelectorRequirement : corev1.NodeSelectorRequirement {
1437
1448
Key : karpv1 .CapacityTypeLabelKey ,
1438
1449
Operator : corev1 .NodeSelectorOpIn ,
@@ -1444,7 +1455,9 @@ var _ = Describe("CloudProvider", func() {
1444
1455
ExpectApplied (ctx , env .Client , nodePool , nodeClass , pod )
1445
1456
ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pod )
1446
1457
ExpectScheduled (ctx , env .Client , pod )
1447
- Expect (awsEnv .CapacityReservationProvider .GetAvailableInstanceCount (reservationID )).To (Equal (9 ))
1458
+ ncs := ExpectNodeClaims (ctx , env .Client )
1459
+ Expect (ncs ).To (HaveLen (1 ))
1460
+ Expect (awsEnv .CapacityReservationProvider .GetAvailableInstanceCount (ncs [0 ].Labels [corecloudprovider .ReservationIDLabel ])).To (Equal (9 ))
1448
1461
})
1449
1462
It ("should mark capacity reservations as terminated" , func () {
1450
1463
pod := coretest .UnschedulablePod ()
@@ -1457,24 +1470,38 @@ var _ = Describe("CloudProvider", func() {
1457
1470
// Attempt the first delete - since the instance still exists we shouldn't increment the availability count
1458
1471
err := cloudProvider .Delete (ctx , ncs [0 ])
1459
1472
Expect (corecloudprovider .IsNodeClaimNotFoundError (err )).To (BeFalse ())
1460
- Expect (awsEnv .CapacityReservationProvider .GetAvailableInstanceCount (reservationID )).To (Equal (9 ))
1473
+ Expect (awsEnv .CapacityReservationProvider .GetAvailableInstanceCount (ncs [ 0 ]. Labels [ corecloudprovider . ReservationIDLabel ] )).To (Equal (9 ))
1461
1474
1462
1475
// Attempt again after clearing the instance from the EC2 output. Now that we get a NotFound error, expect
1463
1476
// availability to be incremented.
1464
1477
awsEnv .EC2API .DescribeInstancesBehavior .Output .Set (& ec2.DescribeInstancesOutput {})
1465
1478
err = cloudProvider .Delete (ctx , ncs [0 ])
1466
1479
Expect (corecloudprovider .IsNodeClaimNotFoundError (err )).To (BeTrue ())
1467
- Expect (awsEnv .CapacityReservationProvider .GetAvailableInstanceCount (reservationID )).To (Equal (10 ))
1468
- })
1469
- It ("should include capacity reservation labels" , func () {
1470
- pod := coretest .UnschedulablePod ()
1471
- ExpectApplied (ctx , env .Client , nodePool , nodeClass , pod )
1472
- ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pod )
1473
- ExpectScheduled (ctx , env .Client , pod )
1474
- ncs := ExpectNodeClaims (ctx , env .Client )
1475
- Expect (ncs ).To (HaveLen (1 ))
1476
- Expect (ncs [0 ].Labels ).To (HaveKeyWithValue (karpv1 .CapacityTypeLabelKey , karpv1 .CapacityTypeReserved ))
1477
- Expect (ncs [0 ].Labels ).To (HaveKeyWithValue (corecloudprovider .ReservationIDLabel , reservationID ))
1480
+ Expect (awsEnv .CapacityReservationProvider .GetAvailableInstanceCount (ncs [0 ].Labels [corecloudprovider .ReservationIDLabel ])).To (Equal (10 ))
1478
1481
})
1482
+ DescribeTable (
1483
+ "should include capacity reservation labels" ,
1484
+ func (crt v1.CapacityReservationType ) {
1485
+ pod := coretest .UnschedulablePod (coretest.PodOptions {
1486
+ NodeSelector : map [string ]string {
1487
+ v1 .LabelCapacityReservationType : string (crt ),
1488
+ },
1489
+ })
1490
+ ExpectApplied (ctx , env .Client , nodePool , nodeClass , pod )
1491
+ ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pod )
1492
+ ExpectScheduled (ctx , env .Client , pod )
1493
+ ncs := ExpectNodeClaims (ctx , env .Client )
1494
+ Expect (ncs ).To (HaveLen (1 ))
1495
+ Expect (ncs [0 ].Labels ).To (HaveKeyWithValue (karpv1 .CapacityTypeLabelKey , karpv1 .CapacityTypeReserved ))
1496
+ Expect (ncs [0 ].Labels ).To (HaveKeyWithValue (corecloudprovider .ReservationIDLabel , * lo .Must (lo .Find (crs , func (cr ec2types.CapacityReservation ) bool {
1497
+ return string (cr .ReservationType ) == string (crt )
1498
+
1499
+ })).CapacityReservationId ))
1500
+ Expect (ncs [0 ].Labels ).To (HaveKeyWithValue (v1 .LabelCapacityReservationType , string (crt )))
1501
+ },
1502
+ lo .Map (v1 .CapacityReservationType ("" ).Values (), func (crt v1.CapacityReservationType , _ int ) TableEntry {
1503
+ return Entry (fmt .Sprintf ("when the capacity reservation type is %q" , string (crt )), crt )
1504
+ }),
1505
+ )
1479
1506
})
1480
1507
})
0 commit comments