ec2api-tempest-plugin/api/test_instances_vpc.py

283 lines
12 KiB
Python

# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
from tempest.lib import decorators
import testtools
from ec2api.tests.functional import base
from ec2api.tests.functional import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class InstanceInVPCTest(base.EC2TestCase):
VPC_CIDR = '10.16.0.0/20'
vpc_id = None
SUBNET_CIDR = '10.16.0.0/24'
subnet_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(InstanceInVPCTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
cls.get_vpc_waiter().wait_available(cls.vpc_id)
aws_zone = CONF.aws.aws_zone
data = cls.client.create_subnet(VpcId=cls.vpc_id,
CidrBlock=cls.SUBNET_CIDR,
AvailabilityZone=aws_zone)
cls.subnet_id = data['Subnet']['SubnetId']
cls.addResourceCleanUpStatic(cls.client.delete_subnet,
SubnetId=cls.subnet_id)
cls.get_subnet_waiter().wait_available(cls.subnet_id)
@decorators.idempotent_id('af8bd493-4a68-49e7-a3d1-326251b8d16e')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_delete_instance(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
data = self.client.describe_instances(InstanceIds=[instance_id])
reservations = data.get('Reservations', [])
self.assertNotEmpty(reservations)
instances = reservations[0].get('Instances', [])
self.assertNotEmpty(instances)
instance = instances[0]
self.assertEqual(self.vpc_id, instance['VpcId'])
self.assertEqual(self.subnet_id, instance['SubnetId'])
self.assertTrue(instance['SourceDestCheck'])
self.assertEqual(1, len(instance['NetworkInterfaces']))
ni = instance['NetworkInterfaces'][0]
self.assertEqual(1, len(ni['Groups']))
self.assertIsNotNone(ni['MacAddress'])
self.assertIsNotNone(ni['PrivateIpAddress'])
self.assertTrue(ni['SourceDestCheck'])
self.assertEqual('in-use', ni['Status'])
self.assertEqual(self.vpc_id, ni['VpcId'])
self.assertEqual(self.subnet_id, ni['SubnetId'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
# NOTE(andrey-mp): There is difference between Openstack and Amazon.
# Amazon returns instance in 'terminated' state some time after
# instance deletion. But Openstack doesn't return such instance.
@decorators.idempotent_id('17ba6206-3044-4e51-9e9b-f5d5728cc047')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_describe_instances_filter(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
data = self.client.describe_instances(InstanceIds=[instance_id])
self.assert_instance(data, instance_id)
instances = data['Reservations'][0]['Instances']
private_dns = instances[0]['PrivateDnsName']
private_ip = instances[0]['PrivateIpAddress']
# NOTE(andrey-mp): by private ip
data = self.client.describe_instances(
Filters=[{'Name': 'private-ip-address', 'Values': ['1.2.3.4']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'private-ip-address', 'Values': [private_ip]}])
self.assert_instance(data, instance_id)
# NOTE(andrey-mp): by private dns
data = self.client.describe_instances(
Filters=[{'Name': 'private-dns-name', 'Values': ['fake.com']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'private-dns-name', 'Values': [private_dns]}])
self.assert_instance(data, instance_id)
# NOTE(andrey-mp): by subnet id
data = self.client.describe_instances(
Filters=[{'Name': 'subnet-id', 'Values': ['subnet-0']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'subnet-id', 'Values': [self.subnet_id]}])
self.assert_instance(data, instance_id)
# NOTE(andrey-mp): by vpc id
data = self.client.describe_instances(
Filters=[{'Name': 'vpc-id', 'Values': ['vpc-0']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'vpc-id', 'Values': [self.vpc_id]}])
self.assert_instance(data, instance_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
def assert_instance(self, data, instance_id):
reservations = data.get('Reservations', [])
self.assertNotEmpty(reservations)
instances = reservations[0].get('Instances', [])
self.assertNotEmpty(instances)
self.assertEqual(instance_id, instances[0]['InstanceId'])
@decorators.idempotent_id('60ceda8b-85ae-47a7-807b-c4a4dd05a13b')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_instance_with_two_interfaces(self):
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id1 = data['NetworkInterface']['NetworkInterfaceId']
clean_ni1 = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id1)
self.get_network_interface_waiter().wait_available(ni_id1)
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
clean_ni2 = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
instance_id = self.run_instance(
NetworkInterfaces=[{'NetworkInterfaceId': ni_id1,
'DeviceIndex': 0},
{'NetworkInterfaceId': ni_id2,
'DeviceIndex': 2}])
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(2, len(nis))
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.get_network_interface_waiter().wait_available(ni_id1)
self.get_network_interface_waiter().wait_available(ni_id2)
self.client.delete_network_interface(
NetworkInterfaceId=ni_id2)
self.cancelResourceCleanUp(clean_ni2)
self.get_network_interface_waiter().wait_delete(ni_id2)
self.client.delete_network_interface(
NetworkInterfaceId=ni_id1)
self.cancelResourceCleanUp(clean_ni1)
self.get_network_interface_waiter().wait_delete(ni_id1)
@decorators.idempotent_id('a7dc520a-e828-4347-91e1-385c4e0e6070')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_instance_with_private_ip(self):
ip = '10.16.0.12'
instance_id = self.run_instance(SubnetId=self.subnet_id,
PrivateIpAddress=ip)
instance = self.get_instance(instance_id)
self.assertEqual(ip, instance['PrivateIpAddress'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('582ac8ed-58e7-4f27-bd65-35b999241c63')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_instance_with_invalid_params(self):
def _rollback(fn_data):
self.client.terminate_instances(
InstanceIds=[fn_data['Instances'][0]['InstanceId']])
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'PrivateIpAddress': '10.16.1.2'
}
ex_str = ('InvalidParameterCombination'
if base.TesterStateHolder().get_ec2_enabled() else
'InvalidParameterValue')
self.assertRaises(ex_str,
self.client.run_instances, rollback_fn=_rollback,
**kwargs)
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'SubnetId': self.subnet_id,
'PrivateIpAddress': '10.16.1.12'
}
self.assertRaises('InvalidParameterValue',
self.client.run_instances, rollback_fn=_rollback,
**kwargs)
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id1 = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id1)
self.get_network_interface_waiter().wait_available(ni_id1)
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
# NOTE(andrey-mp): A network interface may not specify a network
# interface ID and delete on termination as true
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'NetworkInterfaces': [{'NetworkInterfaceId': ni_id1,
'DeviceIndex': 0,
'DeleteOnTermination': True}]
}
self.assertRaises('InvalidParameterCombination',
self.client.run_instances, rollback_fn=_rollback,
**kwargs)
if CONF.aws.run_incompatible_tests:
# NOTE(andrey-mp): Each network interface requires a device index.
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'NetworkInterfaces': [{'NetworkInterfaceId': ni_id1},
{'NetworkInterfaceId': ni_id2}]
}
self.assertRaises('InvalidParameterValue',
self.client.run_instances, rollback_fn=_rollback,
**kwargs)