Skip to content

Commit 4664864

Browse files
committed
minor
1 parent 08dfdb3 commit 4664864

File tree

1 file changed

+82
-79
lines changed

1 file changed

+82
-79
lines changed

packages/aws-library/tests/test_ec2_client.py

Lines changed: 82 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import random
77
from collections.abc import AsyncIterator, Awaitable, Callable
88
from dataclasses import fields
9-
from typing import cast, get_args
9+
from typing import Any, cast, get_args
1010

1111
import botocore.exceptions
1212
import pytest
@@ -592,10 +592,10 @@ async def test_launch_instances_insufficient_capacity_fallback(
592592
aws_ami_id: str,
593593
mocker: MockerFixture,
594594
):
595-
"""Test that launch_instances falls back to next subnet when InsufficientInstanceCapacity occurs."""
596595
await _assert_no_instances_in_ec2(ec2_client)
597596

598597
# Create additional valid subnets for testing
598+
subnet1_id = aws_subnet_id
599599
subnet2_id = await create_aws_subnet_id()
600600

601601
# Create a config with multiple valid subnet IDs
@@ -606,20 +606,21 @@ async def test_launch_instances_insufficient_capacity_fallback(
606606
ami_id=aws_ami_id,
607607
key_name=faker.pystr(),
608608
security_group_ids=[aws_security_group_id],
609-
subnet_ids=[aws_subnet_id, subnet2_id],
609+
subnet_ids=[subnet1_id, subnet2_id],
610610
iam_instance_profile="",
611611
)
612612

613613
# Mock the EC2 client to simulate InsufficientInstanceCapacity on first subnet
614614
original_run_instances = simcore_ec2_api.client.run_instances
615615
call_count = 0
616616

617-
async def mock_run_instances(*args, **kwargs):
617+
async def mock_run_instances(*args, **kwargs) -> Any:
618618
nonlocal call_count
619619
call_count += 1
620620
if call_count == 1:
621+
assert kwargs["NetworkInterfaces"][0]["SubnetId"] == subnet1_id
621622
# First call (first subnet) - simulate insufficient capacity
622-
error_response = {
623+
error_response: dict[str, Any] = {
623624
"Error": {
624625
"Code": "InsufficientInstanceCapacity",
625626
"Message": "Insufficient capacity.",
@@ -633,17 +634,18 @@ async def mock_run_instances(*args, **kwargs):
633634
}
634635
raise botocore.exceptions.ClientError(error_response, "RunInstances")
635636
# Second call (second subnet) - succeed normally
637+
assert kwargs["NetworkInterfaces"][0]["SubnetId"] == subnet2_id
636638
return await original_run_instances(*args, **kwargs)
637639

638640
# Apply the mock
639-
with mocker.patch.object(
641+
mocker.patch.object(
640642
simcore_ec2_api.client, "run_instances", side_effect=mock_run_instances
641-
):
642-
instances = await simcore_ec2_api.launch_instances(
643-
ec2_instance_config,
644-
min_number_of_instances=1,
645-
number_of_instances=1,
646-
)
643+
)
644+
instances = await simcore_ec2_api.launch_instances(
645+
ec2_instance_config,
646+
min_number_of_instances=1,
647+
number_of_instances=1,
648+
)
647649

648650
# Verify that run_instances was called twice (once for each subnet)
649651
assert call_count == 2
@@ -682,11 +684,12 @@ async def test_launch_instances_all_subnets_insufficient_capacity_raises_error(
682684
aws_ami_id: str,
683685
mocker: MockerFixture,
684686
):
685-
"""Test that launch_instances raises EC2InsufficientCapacityError when all subnets have insufficient capacity."""
686687
await _assert_no_instances_in_ec2(ec2_client)
687688

688689
# Create additional valid subnets for testing
690+
subnet1_id = aws_subnet_id
689691
subnet2_id = await create_aws_subnet_id()
692+
subnet3_id = await create_aws_subnet_id()
690693

691694
# Create a config with multiple valid subnet IDs
692695
ec2_instance_config = EC2InstanceConfig(
@@ -696,14 +699,14 @@ async def test_launch_instances_all_subnets_insufficient_capacity_raises_error(
696699
ami_id=aws_ami_id,
697700
key_name=faker.pystr(),
698701
security_group_ids=[aws_security_group_id],
699-
subnet_ids=[aws_subnet_id, subnet2_id],
702+
subnet_ids=[subnet1_id, subnet2_id, subnet3_id],
700703
iam_instance_profile="",
701704
)
702705

703706
# Mock the EC2 client to simulate InsufficientInstanceCapacity on ALL subnets
704707
call_count = 0
705708

706-
async def mock_run_instances(*args, **kwargs):
709+
async def mock_run_instances(*args, **kwargs) -> Any:
707710
nonlocal call_count
708711
call_count += 1
709712
# Always simulate insufficient capacity
@@ -722,20 +725,18 @@ async def mock_run_instances(*args, **kwargs):
722725
raise botocore.exceptions.ClientError(error_response, "RunInstances")
723726

724727
# Apply the mock and expect EC2InsufficientCapacityError
725-
with (
726-
mocker.patch.object(
727-
simcore_ec2_api.client, "run_instances", side_effect=mock_run_instances
728-
),
729-
pytest.raises(EC2InsufficientCapacityError) as exc_info,
730-
):
728+
mocker.patch.object(
729+
simcore_ec2_api.client, "run_instances", side_effect=mock_run_instances
730+
)
731+
with pytest.raises(EC2InsufficientCapacityError) as exc_info:
731732
await simcore_ec2_api.launch_instances(
732733
ec2_instance_config,
733734
min_number_of_instances=1,
734735
number_of_instances=1,
735736
)
736737

737738
# Verify that run_instances was called for both subnets
738-
assert call_count == 2
739+
assert call_count == 3
739740

740741
# Verify the error contains the expected information
741742
assert hasattr(exc_info.value, "instance_type")
@@ -785,72 +786,74 @@ async def mock_run_instances(*args, **kwargs):
785786
if call_count == 1:
786787
# First call: return only 2 instances when 3 were requested
787788
# Simulate that the subnet has capacity for only 2 machines
789+
required_instances = kwargs["MaxCount"]
788790
kwargs_copy = kwargs.copy()
789-
kwargs_copy["MinCount"] = 2
790-
kwargs_copy["MaxCount"] = 2
791+
kwargs_copy["MinCount"] = required_instances - 1
792+
kwargs_copy["MaxCount"] = required_instances - 1
791793
return await original_run_instances(*args, **kwargs_copy)
792-
else:
793-
# Second call: simulate insufficient capacity (subnet is full)
794-
error_response = {
795-
"Error": {
796-
"Code": "InsufficientInstanceCapacity",
797-
"Message": "Insufficient capacity.",
798-
},
799-
"ResponseMetadata": {
800-
"RequestId": "12345678-1234-1234-1234-123456789012",
801-
"HTTPStatusCode": 400,
802-
"HTTPHeaders": {},
803-
"RetryAttempts": 0,
804-
},
805-
}
806-
raise botocore.exceptions.ClientError(error_response, "RunInstances")
794+
795+
# Second call: simulate insufficient capacity (subnet is full)
796+
error_response = {
797+
"Error": {
798+
"Code": "InsufficientInstanceCapacity",
799+
"Message": "Insufficient capacity.",
800+
},
801+
"ResponseMetadata": {
802+
"RequestId": "12345678-1234-1234-1234-123456789012",
803+
"HTTPStatusCode": 400,
804+
"HTTPHeaders": {},
805+
"RetryAttempts": 0,
806+
},
807+
}
808+
raise botocore.exceptions.ClientError(error_response, "RunInstances")
807809

808810
# Apply the mock for the first call
809-
with mocker.patch.object(
811+
mocker.patch.object(
810812
simcore_ec2_api.client, "run_instances", side_effect=mock_run_instances
811-
):
812-
# First call: ask for 3 instances (min 1) -> should get 2, no error
813-
instances = await simcore_ec2_api.launch_instances(
813+
)
814+
# First call: ask for 3 instances (min 1) -> should get 2, no error
815+
instances = await simcore_ec2_api.launch_instances(
816+
ec2_instance_config,
817+
min_number_of_instances=1,
818+
number_of_instances=3,
819+
)
820+
821+
# Verify we got 2 instances (partial capacity)
822+
assert len(instances) == 2
823+
assert call_count == 1
824+
825+
# Verify instances were created
826+
await _assert_instances_in_ec2(
827+
ec2_client,
828+
expected_num_reservations=1,
829+
expected_num_instances=2,
830+
expected_instance_type=ec2_instance_config.type,
831+
expected_tags=ec2_instance_config.tags,
832+
expected_state="running",
833+
)
834+
835+
# Second call: ask for 3 instances (min 1) -> should raise EC2InsufficientCapacityError
836+
with pytest.raises(EC2InsufficientCapacityError) as exc_info:
837+
await simcore_ec2_api.launch_instances(
814838
ec2_instance_config,
815839
min_number_of_instances=1,
816840
number_of_instances=3,
817841
)
818842

819-
# Verify we got 2 instances (partial capacity)
820-
assert len(instances) == 2
821-
assert call_count == 1
822-
823-
# Verify instances were created
824-
await _assert_instances_in_ec2(
825-
ec2_client,
826-
expected_num_reservations=1,
827-
expected_num_instances=2,
828-
expected_instance_type=ec2_instance_config.type,
829-
expected_tags=ec2_instance_config.tags,
830-
expected_state="running",
831-
)
843+
# Verify that run_instances was called twice total
844+
assert call_count == 2
832845

833-
# Second call: ask for 3 instances (min 1) -> should raise EC2InsufficientCapacityError
834-
with pytest.raises(EC2InsufficientCapacityError) as exc_info:
835-
await simcore_ec2_api.launch_instances(
836-
ec2_instance_config,
837-
min_number_of_instances=1,
838-
number_of_instances=3,
839-
)
846+
# Verify the error contains the expected information
847+
assert hasattr(exc_info.value, "instance_type")
848+
assert exc_info.value.instance_type == fake_ec2_instance_type.name # type: ignore
849+
assert exc_info.value.subnet_id == aws_subnet_id # type: ignore
840850

841-
# Verify that run_instances was called twice total
842-
assert call_count == 2
843-
844-
# Verify the error contains the expected information
845-
assert hasattr(exc_info.value, "instance_type")
846-
assert exc_info.value.instance_type == fake_ec2_instance_type.name
847-
848-
# Verify still only 2 instances exist (no new ones were created)
849-
await _assert_instances_in_ec2(
850-
ec2_client,
851-
expected_num_reservations=1,
852-
expected_num_instances=2,
853-
expected_instance_type=ec2_instance_config.type,
854-
expected_tags=ec2_instance_config.tags,
855-
expected_state="running",
856-
)
851+
# Verify still only 2 instances exist (no new ones were created)
852+
await _assert_instances_in_ec2(
853+
ec2_client,
854+
expected_num_reservations=1,
855+
expected_num_instances=2,
856+
expected_instance_type=ec2_instance_config.type,
857+
expected_tags=ec2_instance_config.tags,
858+
expected_state="running",
859+
)

0 commit comments

Comments
 (0)