moto/tests/test_ec2/test_spot_instances.py
2019-10-31 10:36:05 -07:00

257 lines
8.7 KiB
Python

from __future__ import unicode_literals
from nose.tools import assert_raises
import datetime
import boto
import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import pytz
import sure # noqa
from moto import mock_ec2, mock_ec2_deprecated
from moto.backends import get_model
from moto.core.utils import iso_8601_datetime_with_milliseconds
@mock_ec2
def test_request_spot_instances():
conn = boto3.client("ec2", "us-east-1")
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
subnet = conn.create_subnet(
VpcId=vpc["VpcId"], CidrBlock="10.0.0.0/16", AvailabilityZone="us-east-1a"
)["Subnet"]
subnet_id = subnet["SubnetId"]
conn.create_security_group(GroupName="group1", Description="description")
conn.create_security_group(GroupName="group2", Description="description")
start_dt = datetime.datetime(2013, 1, 1).replace(tzinfo=pytz.utc)
end_dt = datetime.datetime(2013, 1, 2).replace(tzinfo=pytz.utc)
start = iso_8601_datetime_with_milliseconds(start_dt)
end = iso_8601_datetime_with_milliseconds(end_dt)
with assert_raises(ClientError) as ex:
request = conn.request_spot_instances(
SpotPrice="0.5",
InstanceCount=1,
Type="one-time",
ValidFrom=start,
ValidUntil=end,
LaunchGroup="the-group",
AvailabilityZoneGroup="my-group",
LaunchSpecification={
"ImageId": "ami-abcd1234",
"KeyName": "test",
"SecurityGroups": ["group1", "group2"],
"UserData": "some test data",
"InstanceType": "m1.small",
"Placement": {"AvailabilityZone": "us-east-1c"},
"KernelId": "test-kernel",
"RamdiskId": "test-ramdisk",
"Monitoring": {"Enabled": True},
"SubnetId": subnet_id,
},
DryRun=True,
)
ex.exception.response["Error"]["Code"].should.equal("DryRunOperation")
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.exception.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the RequestSpotInstance operation: Request would have succeeded, but DryRun flag is set"
)
request = conn.request_spot_instances(
SpotPrice="0.5",
InstanceCount=1,
Type="one-time",
ValidFrom=start,
ValidUntil=end,
LaunchGroup="the-group",
AvailabilityZoneGroup="my-group",
LaunchSpecification={
"ImageId": "ami-abcd1234",
"KeyName": "test",
"SecurityGroups": ["group1", "group2"],
"UserData": "some test data",
"InstanceType": "m1.small",
"Placement": {"AvailabilityZone": "us-east-1c"},
"KernelId": "test-kernel",
"RamdiskId": "test-ramdisk",
"Monitoring": {"Enabled": True},
"SubnetId": subnet_id,
},
)
requests = conn.describe_spot_instance_requests()["SpotInstanceRequests"]
requests.should.have.length_of(1)
request = requests[0]
request["State"].should.equal("open")
request["SpotPrice"].should.equal("0.5")
request["Type"].should.equal("one-time")
request["ValidFrom"].should.equal(start_dt)
request["ValidUntil"].should.equal(end_dt)
request["LaunchGroup"].should.equal("the-group")
request["AvailabilityZoneGroup"].should.equal("my-group")
launch_spec = request["LaunchSpecification"]
security_group_names = [
group["GroupName"] for group in launch_spec["SecurityGroups"]
]
set(security_group_names).should.equal(set(["group1", "group2"]))
launch_spec["ImageId"].should.equal("ami-abcd1234")
launch_spec["KeyName"].should.equal("test")
launch_spec["InstanceType"].should.equal("m1.small")
launch_spec["KernelId"].should.equal("test-kernel")
launch_spec["RamdiskId"].should.equal("test-ramdisk")
launch_spec["SubnetId"].should.equal(subnet_id)
@mock_ec2
def test_request_spot_instances_default_arguments():
"""
Test that moto set the correct default arguments
"""
conn = boto3.client("ec2", "us-east-1")
request = conn.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": "ami-abcd1234"}
)
requests = conn.describe_spot_instance_requests()["SpotInstanceRequests"]
requests.should.have.length_of(1)
request = requests[0]
request["State"].should.equal("open")
request["SpotPrice"].should.equal("0.5")
request["Type"].should.equal("one-time")
request.shouldnt.contain("ValidFrom")
request.shouldnt.contain("ValidUntil")
request.shouldnt.contain("LaunchGroup")
request.shouldnt.contain("AvailabilityZoneGroup")
launch_spec = request["LaunchSpecification"]
security_group_names = [
group["GroupName"] for group in launch_spec["SecurityGroups"]
]
security_group_names.should.equal(["default"])
launch_spec["ImageId"].should.equal("ami-abcd1234")
request.shouldnt.contain("KeyName")
launch_spec["InstanceType"].should.equal("m1.small")
request.shouldnt.contain("KernelId")
request.shouldnt.contain("RamdiskId")
request.shouldnt.contain("SubnetId")
@mock_ec2_deprecated
def test_cancel_spot_instance_request():
conn = boto.connect_ec2()
conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
with assert_raises(EC2ResponseError) as ex:
conn.cancel_spot_instance_requests([requests[0].id], dry_run=True)
ex.exception.error_code.should.equal("DryRunOperation")
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
"An error occurred (DryRunOperation) when calling the CancelSpotInstance operation: Request would have succeeded, but DryRun flag is set"
)
conn.cancel_spot_instance_requests([requests[0].id])
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(0)
@mock_ec2_deprecated
def test_request_spot_instances_fulfilled():
"""
Test that moto correctly fullfills a spot instance request
"""
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("open")
get_model("SpotInstanceRequest", "us-east-1")[0].state = "active"
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("active")
@mock_ec2_deprecated
def test_tag_spot_instance_request():
"""
Test that moto correctly tags a spot instance request
"""
conn = boto.connect_ec2()
request = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
request[0].add_tag("tag1", "value1")
request[0].add_tag("tag2", "value2")
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
tag_dict = dict(request.tags)
tag_dict.should.equal({"tag1": "value1", "tag2": "value2"})
@mock_ec2_deprecated
def test_get_all_spot_instance_requests_filtering():
"""
Test that moto correctly filters spot instance requests
"""
conn = boto.connect_ec2()
request1 = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
request2 = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
request1[0].add_tag("tag1", "value1")
request1[0].add_tag("tag2", "value2")
request2[0].add_tag("tag1", "value1")
request2[0].add_tag("tag2", "wrong")
requests = conn.get_all_spot_instance_requests(filters={"state": "active"})
requests.should.have.length_of(0)
requests = conn.get_all_spot_instance_requests(filters={"state": "open"})
requests.should.have.length_of(3)
requests = conn.get_all_spot_instance_requests(filters={"tag:tag1": "value1"})
requests.should.have.length_of(2)
requests = conn.get_all_spot_instance_requests(
filters={"tag:tag1": "value1", "tag:tag2": "value2"}
)
requests.should.have.length_of(1)
@mock_ec2_deprecated
def test_request_spot_instances_setting_instance_id():
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(price=0.5, image_id="ami-abcd1234")
req = get_model("SpotInstanceRequest", "us-east-1")[0]
req.state = "active"
req.instance_id = "i-12345678"
request = conn.get_all_spot_instance_requests()[0]
assert request.state == "active"
assert request.instance_id == "i-12345678"