f4b81e69b8
* Address `boto` deprecation warnings This commit eliminates the following warning: ../boto/ec2/connection.py:582: PendingDeprecationWarning: The current get_all_instances implementation will be replaced with get_all_reservations. `boto` isn't likely to ever make good on this warning, but doing the replacement will declutter the `moto` test output. * Remove `invoke_lambda` tracebacks from unit test logging If an exception is encountered, the details are returned in the response payload. Printing the traceback was just adding noise to the pytest output. * Use known AMIs in unit tests This commit eliminates the following warning in the pytest output: `PendingDeprecationWarning: Could not find AMI with image-id:ami-123456, in the near future this will cause an error.` Known, pre-loaded AMI image ids are used instead of random ids that don't actually exist in the moto backend. The integrity of the tests is unaffected by this change. A test has been added to provide explicit coverage of the PendingDeprecationWarning raised when an invalid AMI image id is passed to moto.
215 lines
7.6 KiB
Python
215 lines
7.6 KiB
Python
from __future__ import unicode_literals
|
|
import boto3
|
|
import sure # noqa
|
|
|
|
from moto import mock_opsworks
|
|
from moto import mock_ec2
|
|
from tests import EXAMPLE_AMI_ID
|
|
|
|
|
|
@mock_opsworks
|
|
def test_create_instance():
|
|
client = boto3.client("opsworks", region_name="us-east-1")
|
|
stack_id = client.create_stack(
|
|
Name="test_stack_1",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
|
|
layer_id = client.create_layer(
|
|
StackId=stack_id,
|
|
Type="custom",
|
|
Name="TestLayer",
|
|
Shortname="TestLayerShortName",
|
|
)["LayerId"]
|
|
|
|
second_stack_id = client.create_stack(
|
|
Name="test_stack_2",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
|
|
second_layer_id = client.create_layer(
|
|
StackId=second_stack_id,
|
|
Type="custom",
|
|
Name="SecondTestLayer",
|
|
Shortname="SecondTestLayerShortName",
|
|
)["LayerId"]
|
|
|
|
response = client.create_instance(
|
|
StackId=stack_id, LayerIds=[layer_id], InstanceType="t2.micro"
|
|
)
|
|
|
|
response.should.contain("InstanceId")
|
|
|
|
client.create_instance.when.called_with(
|
|
StackId="nothere", LayerIds=[layer_id], InstanceType="t2.micro"
|
|
).should.throw(Exception, "Unable to find stack with ID nothere")
|
|
|
|
client.create_instance.when.called_with(
|
|
StackId=stack_id, LayerIds=["nothere"], InstanceType="t2.micro"
|
|
).should.throw(Exception, "nothere")
|
|
# ClientError
|
|
client.create_instance.when.called_with(
|
|
StackId=stack_id, LayerIds=[second_layer_id], InstanceType="t2.micro"
|
|
).should.throw(Exception, "Please only provide layer IDs from the same stack")
|
|
# ClientError
|
|
client.start_instance.when.called_with(InstanceId="nothere").should.throw(
|
|
Exception, "Unable to find instance with ID nothere"
|
|
)
|
|
|
|
|
|
@mock_opsworks
|
|
def test_describe_instances():
|
|
"""
|
|
create two stacks, with 1 layer and 2 layers (S1L1, S2L1, S2L2)
|
|
|
|
populate S1L1 with 2 instances (S1L1_i1, S1L1_i2)
|
|
populate S2L1 with 1 instance (S2L1_i1)
|
|
populate S2L2 with 3 instances (S2L2_i1..2)
|
|
"""
|
|
|
|
client = boto3.client("opsworks", region_name="us-east-1")
|
|
S1 = client.create_stack(
|
|
Name="S1",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
S1L1 = client.create_layer(
|
|
StackId=S1, Type="custom", Name="S1L1", Shortname="S1L1"
|
|
)["LayerId"]
|
|
S2 = client.create_stack(
|
|
Name="S2",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
S2L1 = client.create_layer(
|
|
StackId=S2, Type="custom", Name="S2L1", Shortname="S2L1"
|
|
)["LayerId"]
|
|
S2L2 = client.create_layer(
|
|
StackId=S2, Type="custom", Name="S2L2", Shortname="S2L2"
|
|
)["LayerId"]
|
|
|
|
S1L1_i1 = client.create_instance(
|
|
StackId=S1, LayerIds=[S1L1], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S1L1_i2 = client.create_instance(
|
|
StackId=S1, LayerIds=[S1L1], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S2L1_i1 = client.create_instance(
|
|
StackId=S2, LayerIds=[S2L1], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S2L2_i1 = client.create_instance(
|
|
StackId=S2, LayerIds=[S2L2], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S2L2_i2 = client.create_instance(
|
|
StackId=S2, LayerIds=[S2L2], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
|
|
# instances in Stack 1
|
|
response = client.describe_instances(StackId=S1)["Instances"]
|
|
response.should.have.length_of(2)
|
|
S1L1_i1.should.be.within([i["InstanceId"] for i in response])
|
|
S1L1_i2.should.be.within([i["InstanceId"] for i in response])
|
|
|
|
response2 = client.describe_instances(InstanceIds=[S1L1_i1, S1L1_i2])["Instances"]
|
|
sorted(response2, key=lambda d: d["InstanceId"]).should.equal(
|
|
sorted(response, key=lambda d: d["InstanceId"])
|
|
)
|
|
|
|
response3 = client.describe_instances(LayerId=S1L1)["Instances"]
|
|
sorted(response3, key=lambda d: d["InstanceId"]).should.equal(
|
|
sorted(response, key=lambda d: d["InstanceId"])
|
|
)
|
|
|
|
response = client.describe_instances(StackId=S1)["Instances"]
|
|
response.should.have.length_of(2)
|
|
S1L1_i1.should.be.within([i["InstanceId"] for i in response])
|
|
S1L1_i2.should.be.within([i["InstanceId"] for i in response])
|
|
|
|
# instances in Stack 2
|
|
response = client.describe_instances(StackId=S2)["Instances"]
|
|
response.should.have.length_of(3)
|
|
S2L1_i1.should.be.within([i["InstanceId"] for i in response])
|
|
S2L2_i1.should.be.within([i["InstanceId"] for i in response])
|
|
S2L2_i2.should.be.within([i["InstanceId"] for i in response])
|
|
|
|
response = client.describe_instances(LayerId=S2L1)["Instances"]
|
|
response.should.have.length_of(1)
|
|
S2L1_i1.should.be.within([i["InstanceId"] for i in response])
|
|
|
|
response = client.describe_instances(LayerId=S2L2)["Instances"]
|
|
response.should.have.length_of(2)
|
|
S2L1_i1.should_not.be.within([i["InstanceId"] for i in response])
|
|
|
|
# ClientError
|
|
client.describe_instances.when.called_with(StackId=S1, LayerId=S1L1).should.throw(
|
|
Exception, "Please provide either one or more"
|
|
)
|
|
# ClientError
|
|
client.describe_instances.when.called_with(StackId="nothere").should.throw(
|
|
Exception, "nothere"
|
|
)
|
|
# ClientError
|
|
client.describe_instances.when.called_with(LayerId="nothere").should.throw(
|
|
Exception, "nothere"
|
|
)
|
|
# ClientError
|
|
client.describe_instances.when.called_with(InstanceIds=["nothere"]).should.throw(
|
|
Exception, "nothere"
|
|
)
|
|
|
|
|
|
@mock_opsworks
|
|
@mock_ec2
|
|
def test_ec2_integration():
|
|
"""
|
|
instances created via OpsWorks should be discoverable via ec2
|
|
"""
|
|
|
|
opsworks = boto3.client("opsworks", region_name="us-east-1")
|
|
stack_id = opsworks.create_stack(
|
|
Name="S1",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
|
|
layer_id = opsworks.create_layer(
|
|
StackId=stack_id, Type="custom", Name="S1L1", Shortname="S1L1"
|
|
)["LayerId"]
|
|
|
|
instance_id = opsworks.create_instance(
|
|
AmiId=EXAMPLE_AMI_ID,
|
|
StackId=stack_id,
|
|
LayerIds=[layer_id],
|
|
InstanceType="t2.micro",
|
|
SshKeyName="testSSH",
|
|
)["InstanceId"]
|
|
|
|
ec2 = boto3.client("ec2", region_name="us-east-1")
|
|
|
|
# Before starting the instance, it shouldn't be discoverable via ec2
|
|
reservations = ec2.describe_instances()["Reservations"]
|
|
assert reservations.should.be.empty
|
|
|
|
# Before starting the instance, its status should be "stopped"
|
|
opsworks_instance = opsworks.describe_instances(StackId=stack_id)["Instances"][0]
|
|
opsworks_instance["Status"].should.equal("stopped")
|
|
|
|
# After starting the instance, it should be discoverable via ec2
|
|
opsworks.start_instance(InstanceId=instance_id)
|
|
reservations = ec2.describe_instances()["Reservations"]
|
|
reservations[0]["Instances"].should.have.length_of(1)
|
|
instance = reservations[0]["Instances"][0]
|
|
opsworks_instance = opsworks.describe_instances(StackId=stack_id)["Instances"][0]
|
|
|
|
instance["InstanceId"].should.equal(opsworks_instance["Ec2InstanceId"])
|
|
instance["PrivateIpAddress"].should.equal(opsworks_instance["PrivateIp"])
|
|
# After starting the instance, its status should be "online"
|
|
opsworks_instance["Status"].should.equal("online")
|