diff options
-rw-r--r-- | docs/how-to-use/IntegrationTests.rst | 3 | ||||
-rw-r--r-- | docs/how-to-use/UnitTests.rst | 6 | ||||
-rw-r--r-- | snaps/domain/network.py | 40 | ||||
-rw-r--r-- | snaps/domain/stack.py | 14 | ||||
-rw-r--r-- | snaps/domain/test/network_tests.py | 73 | ||||
-rw-r--r-- | snaps/domain/test/stack_tests.py | 20 | ||||
-rw-r--r-- | snaps/openstack/create_stack.py | 76 | ||||
-rw-r--r-- | snaps/openstack/tests/create_project_tests.py | 6 | ||||
-rw-r--r-- | snaps/openstack/tests/create_stack_tests.py | 53 | ||||
-rw-r--r-- | snaps/openstack/tests/heat/test_heat_template.yaml | 13 | ||||
-rw-r--r-- | snaps/openstack/utils/heat_utils.py | 52 | ||||
-rw-r--r-- | snaps/openstack/utils/neutron_utils.py | 29 | ||||
-rw-r--r-- | snaps/openstack/utils/tests/heat_utils_tests.py | 30 | ||||
-rw-r--r-- | snaps/openstack/utils/tests/neutron_utils_tests.py | 60 | ||||
-rw-r--r-- | snaps/test_suite_builder.py | 5 |
15 files changed, 426 insertions, 54 deletions
diff --git a/docs/how-to-use/IntegrationTests.rst b/docs/how-to-use/IntegrationTests.rst index e5c9901..8ef54ec 100644 --- a/docs/how-to-use/IntegrationTests.rst +++ b/docs/how-to-use/IntegrationTests.rst @@ -247,6 +247,9 @@ create_stack_tests.py - CreateStackSuccessTests | test_create_same_stack | 2 | Ensures that a Heat stack with the same name cannot be | | | | created 2x | +---------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_same_stack | 2 | Ensures that a Heat stack with the same name cannot be | +| | | created 2x | ++---------------------------------------+---------------+-----------------------------------------------------------+ create_stack_tests.py - CreateStackNegativeTests ------------------------------------------------ diff --git a/docs/how-to-use/UnitTests.rst b/docs/how-to-use/UnitTests.rst index cdf466e..6f4dd6c 100644 --- a/docs/how-to-use/UnitTests.rst +++ b/docs/how-to-use/UnitTests.rst @@ -210,6 +210,12 @@ StackDomainObjectTests Ensures that all required members are included when constructing a Stack domain object +ResourceDomainObjectTests +------------------------- + +Ensures that all required members are included when constructing a +Resource domain object + FloatingIpSettingsUnitTests --------------------------- diff --git a/snaps/domain/network.py b/snaps/domain/network.py index 2c71db8..0b56c43 100644 --- a/snaps/domain/network.py +++ b/snaps/domain/network.py @@ -25,11 +25,16 @@ class Network: """ self.name = kwargs.get('name') self.id = kwargs.get('id') - self.type = kwargs.get('provider:network_type') + self.admin_state_up = kwargs.get('admin_state_up') + self.shared = kwargs.get('shared') + self.external = kwargs.get('router:external', kwargs.get('external')) + self.type = kwargs.get('provider:network_type', kwargs.get('type')) def __eq__(self, other): return (self.name == other.name and self.id == other.id and - self.type == other.type) + self.admin_state_up == other.admin_state_up and + self.shared == other.shared and + self.external == other.external and self.type == other.type) class Subnet: @@ -44,10 +49,37 @@ class Subnet: self.name = kwargs.get('name') self.id = kwargs.get('id') self.cidr = kwargs.get('cidr') + self.ip_version = kwargs.get('ip_version') + self.gateway_ip = kwargs.get('gateway_ip') + self.enable_dhcp = kwargs.get('enable_dhcp') + self.dns_nameservers = kwargs.get('dns_nameservers') + self.host_routes = kwargs.get('host_routes') + self.ipv6_ra_mode = kwargs.get('ipv6_ra_mode') + self.ipv6_address_mode = kwargs.get('ipv6_address_mode') + + self.start = None + self.end = None + if ('allocation_pools' in kwargs and + len(kwargs['allocation_pools']) > 0): + # Will need to ultimately support a list of pools + pools = kwargs['allocation_pools'][0] + if 'start' in pools: + self.start = pools['start'] + if 'end' in pools: + self.end = pools['end'] def __eq__(self, other): - return (self.name == other.name and self.id == other.id and - self.cidr == other.cidr) + return (self.name == other.name and + self.id == other.id and + self.cidr == other.cidr and + self.ip_version == other.ip_version and + self.gateway_ip == other.gateway_ip and + self.enable_dhcp == other.enable_dhcp and + self.dns_nameservers == other.dns_nameservers and + self.host_routes == other.host_routes and + self.ipv6_ra_mode == other.ipv6_ra_mode and + self.ipv6_address_mode == other.ipv6_address_mode and + self.start == other.start and self.end == other.end) class Port: diff --git a/snaps/domain/stack.py b/snaps/domain/stack.py index 0302184..df4d4e4 100644 --- a/snaps/domain/stack.py +++ b/snaps/domain/stack.py @@ -31,3 +31,17 @@ class Stack: def __eq__(self, other): return (self.name == other.name and self.id == other.id) + + +class Resource: + """ + SNAPS domain object for resources created by a heat template + """ + def __init__(self, resource_type, resource_id): + """ + Constructor + :param resource_type: the type + :param resource_id: the ID attached to the resource of the given type + """ + self.type = resource_type + self.id = resource_id diff --git a/snaps/domain/test/network_tests.py b/snaps/domain/test/network_tests.py index 4fd20d4..0534b49 100644 --- a/snaps/domain/test/network_tests.py +++ b/snaps/domain/test/network_tests.py @@ -24,18 +24,40 @@ class NetworkObjectTests(unittest.TestCase): Tests the construction of the snaps.domain.network.Network class """ - def test_construction_kwargs(self): + def test_construction_kwargs_1(self): + network = Network( + **{'name': 'foo', 'id': 'bar', 'provider:network_type': 'flat', + 'admin_state_up': False, 'shared': True, + 'router:external': False}) + self.assertEqual('foo', network.name) + self.assertEqual('bar', network.id) + self.assertEqual('flat', network.type) + self.assertFalse(network.admin_state_up) + self.assertFalse(network.external) + self.assertTrue(network.shared) + + def test_construction_kwargs_2(self): network = Network( - **{'name': 'name', 'id': 'id', 'provider:network_type': 'flat'}) - self.assertEqual('name', network.name) - self.assertEqual('id', network.id) + **{'name': 'foo', 'id': 'bar', 'type': 'flat', + 'admin_state_up': False, 'shared': True, + 'external': False}) + self.assertEqual('foo', network.name) + self.assertEqual('bar', network.id) self.assertEqual('flat', network.type) + self.assertFalse(network.admin_state_up) + self.assertFalse(network.external) + self.assertTrue(network.shared) def test_construction_named(self): - network = Network(id='id', name='name') - self.assertEqual('name', network.name) - self.assertEqual('id', network.id) - self.assertIsNone(network.type) + network = Network( + name='foo', id='bar', type='flat', admin_state_up=False, + shared=True, external=False) + self.assertEqual('foo', network.name) + self.assertEqual('bar', network.id) + self.assertEqual('flat', network.type) + self.assertFalse(network.admin_state_up) + self.assertFalse(network.external) + self.assertTrue(network.shared) class SubnetObjectTests(unittest.TestCase): @@ -45,16 +67,39 @@ class SubnetObjectTests(unittest.TestCase): def test_construction_kwargs(self): subnet = Subnet( - **{'name': 'name', 'id': 'id', 'cidr': '10.0.0.0/24'}) - self.assertEqual('name', subnet.name) - self.assertEqual('id', subnet.id) + **{'name': 'foo', 'id': 'bar', 'cidr': '10.0.0.0/24', + 'ip_version': 4, 'gateway_ip': '10.0.0.1', 'enable_dhcp': True, + 'dns_nameservers': ['8.8.8.8'], 'host_routes': list(), + 'ipv6_ra_mode': 'hello', 'ipv6_address_mode': 'world'}) + self.assertEqual('foo', subnet.name) + self.assertEqual('bar', subnet.id) self.assertEqual('10.0.0.0/24', subnet.cidr) + self.assertEqual(4, subnet.ip_version) + self.assertEqual('10.0.0.1', subnet.gateway_ip) + self.assertTrue(subnet.enable_dhcp) + self.assertEqual(1, len(subnet.dns_nameservers)) + self.assertEqual('8.8.8.8', subnet.dns_nameservers[0]) + self.assertEqual(list(), subnet.host_routes) + self.assertEqual('hello', subnet.ipv6_ra_mode) + self.assertEqual('world', subnet.ipv6_address_mode) def test_construction_named(self): - subnet = Subnet(cidr='10.0.0.0/24', id='id', name='name') - self.assertEqual('name', subnet.name) - self.assertEqual('id', subnet.id) + subnet = Subnet( + name='foo', id='bar', cidr='10.0.0.0/24', + ip_version=4, gateway_ip='10.0.0.1', enable_dhcp=True, + dns_nameservers=['8.8.8.8'], host_routes=list(), + ipv6_ra_mode='hello', ipv6_address_mode='world') + self.assertEqual('foo', subnet.name) + self.assertEqual('bar', subnet.id) self.assertEqual('10.0.0.0/24', subnet.cidr) + self.assertEqual(4, subnet.ip_version) + self.assertEqual('10.0.0.1', subnet.gateway_ip) + self.assertTrue(subnet.enable_dhcp) + self.assertEqual(1, len(subnet.dns_nameservers)) + self.assertEqual('8.8.8.8', subnet.dns_nameservers[0]) + self.assertEqual(list(), subnet.host_routes) + self.assertEqual('hello', subnet.ipv6_ra_mode) + self.assertEqual('world', subnet.ipv6_address_mode) class PortDomainObjectTests(unittest.TestCase): diff --git a/snaps/domain/test/stack_tests.py b/snaps/domain/test/stack_tests.py index a6fd8a3..e0e1ae7 100644 --- a/snaps/domain/test/stack_tests.py +++ b/snaps/domain/test/stack_tests.py @@ -14,12 +14,12 @@ # limitations under the License. import unittest -from snaps.domain.stack import Stack +from snaps.domain.stack import Stack, Resource class StackDomainObjectTests(unittest.TestCase): """ - Tests the construction of the snaps.domain.test.Stack class + Tests the construction of the snaps.domain.Stack class """ def test_construction_positional(self): @@ -31,3 +31,19 @@ class StackDomainObjectTests(unittest.TestCase): stack = Stack(stack_id='id', name='name') self.assertEqual('name', stack.name) self.assertEqual('id', stack.id) + + +class ResourceDomainObjectTests(unittest.TestCase): + """ + Tests the construction of the snaps.domain.Resource class + """ + + def test_construction_positional(self): + resource = Resource('foo', 'bar') + self.assertEqual('foo', resource.type) + self.assertEqual('bar', resource.id) + + def test_construction_named(self): + resource = Resource(resource_id='bar', resource_type='foo') + self.assertEqual('foo', resource.type) + self.assertEqual('bar', resource.id) diff --git a/snaps/openstack/create_stack.py b/snaps/openstack/create_stack.py index 41cc725..454cb18 100644 --- a/snaps/openstack/create_stack.py +++ b/snaps/openstack/create_stack.py @@ -17,7 +17,10 @@ import logging import time from heatclient.exc import HTTPNotFound -from snaps.openstack.utils import heat_utils + +from snaps.openstack.create_network import ( + OpenStackNetwork, NetworkSettings, SubnetSettings) +from snaps.openstack.utils import heat_utils, neutron_utils __author__ = 'spisarski' @@ -51,7 +54,11 @@ class OpenStackHeatStack: """ Creates the heat stack in OpenStack if it does not already exist and returns the domain Stack object - :param cleanup: Denotes whether or not this is being called for cleanup + :param cleanup: When true, this object is initialized only via queries, + else objects will be created when the queries return + None. The name of this parameter should be changed to + something like 'readonly' as the same goes with all of + the other creator classes. :return: The OpenStack Stack object """ self.__heat_cli = heat_utils.heat_client(self.__os_creds) @@ -132,6 +139,65 @@ class OpenStackHeatStack: return self._stack_status_check(STATUS_CREATE_COMPLETE, block, timeout, poll_interval) + def get_network_creators(self): + """ + Returns a list of network creator objects as configured by the heat + template + :return: list() of OpenStackNetwork objects + """ + + neutron = neutron_utils.neutron_client(self.__os_creds) + + out = list() + stack_networks = heat_utils.get_stack_networks( + self.__heat_cli, neutron, self.__stack) + + for stack_network in stack_networks: + net_settings = self.__create_network_settings( + neutron, stack_network) + net_creator = OpenStackNetwork(self.__os_creds, net_settings) + out.append(net_creator) + net_creator.create(cleanup=True) + + return out + + def __create_network_settings(self, neutron, network): + """ + Returns a NetworkSettings object + :param neutron: the neutron client + :param network: a SNAPS-OO Network domain object + :return: + """ + return NetworkSettings( + name=network.name, network_type=network.type, + subnet_settings=self.__create_subnet_settings(neutron, network)) + + def __create_subnet_settings(self, neutron, network): + """ + Returns a list of SubnetSettings objects for a given network + :param neutron: the OpenStack neutron client + :param network: the SNAPS-OO Network domain object + :return: a list + """ + out = list() + + subnets = neutron_utils.get_subnets_by_network(neutron, network) + for subnet in subnets: + kwargs = dict() + kwargs['cidr'] = subnet.cidr + kwargs['ip_version'] = subnet.ip_version + kwargs['name'] = subnet.name + kwargs['start'] = subnet.start + kwargs['end'] = subnet.end + kwargs['gateway_ip'] = subnet.gateway_ip + kwargs['enable_dhcp'] = subnet.enable_dhcp + kwargs['dns_nameservers'] = subnet.dns_nameservers + kwargs['host_routes'] = subnet.host_routes + kwargs['ipv6_ra_mode'] = subnet.ipv6_ra_mode + kwargs['ipv6_address_mode'] = subnet.ipv6_address_mode + out.append(SubnetSettings(**kwargs)) + return out + def _stack_status_check(self, expected_status_code, block, timeout, poll_interval): """ @@ -228,14 +294,8 @@ class StackSettingsError(Exception): Exception to be thrown when an stack settings are incorrect """ - def __init__(self, message): - Exception.__init__(self, message) - class StackCreationError(Exception): """ Exception to be thrown when an stack cannot be created """ - - def __init__(self, message): - Exception.__init__(self, message) diff --git a/snaps/openstack/tests/create_project_tests.py b/snaps/openstack/tests/create_project_tests.py index dfbb0d6..0e1d0ae 100644 --- a/snaps/openstack/tests/create_project_tests.py +++ b/snaps/openstack/tests/create_project_tests.py @@ -267,7 +267,7 @@ class CreateProjectUserTests(OSComponentTestCase): user_creator = OpenStackUser( self.os_creds, UserSettings( name=self.guid + '-user', - password=self.guid, roles={'admin': 'admin'}, + password=self.guid, roles={'admin': self.project_settings.name}, domain_name=self.os_creds.user_domain_name)) self.project_creator.assoc_user(user_creator.create()) self.user_creators.append(user_creator) @@ -297,7 +297,7 @@ class CreateProjectUserTests(OSComponentTestCase): user_creator_1 = OpenStackUser( self.os_creds, UserSettings( name=self.guid + '-user1', password=self.guid, - roles={'admin': 'admin'}, + roles={'admin': self.project_settings.name}, domain_name=self.os_creds.user_domain_name)) self.project_creator.assoc_user(user_creator_1.create()) self.user_creators.append(user_creator_1) @@ -305,7 +305,7 @@ class CreateProjectUserTests(OSComponentTestCase): user_creator_2 = OpenStackUser( self.os_creds, UserSettings( name=self.guid + '-user2', password=self.guid, - roles={'admin': 'admin'}, + roles={'admin': self.project_settings.name}, domain_name=self.os_creds.user_domain_name)) self.project_creator.assoc_user(user_creator_2.create()) self.user_creators.append(user_creator_2) diff --git a/snaps/openstack/tests/create_stack_tests.py b/snaps/openstack/tests/create_stack_tests.py index fe33cd2..967e803 100644 --- a/snaps/openstack/tests/create_stack_tests.py +++ b/snaps/openstack/tests/create_stack_tests.py @@ -33,7 +33,7 @@ from snaps.openstack import create_stack from snaps.openstack.create_stack import StackSettings, StackSettingsError from snaps.openstack.tests import openstack_tests from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase -from snaps.openstack.utils import heat_utils +from snaps.openstack.utils import heat_utils, neutron_utils __author__ = 'spisarski' @@ -132,7 +132,7 @@ class CreateStackSuccessTests(OSIntegrationTestCase): """ super(self.__class__, self).__start__() - self.guid = str(uuid.uuid4()) + self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) self.heat_creds = self.admin_os_creds self.heat_creds.project_name = self.admin_os_creds.project_name @@ -142,7 +142,7 @@ class CreateStackSuccessTests(OSIntegrationTestCase): self.image_creator = OpenStackImage( self.heat_creds, openstack_tests.cirros_image_settings( - name=self.__class__.__name__ + '-' + str(self.guid) + '-image', + name=self.guid + '-image', image_metadata=self.image_metadata)) self.image_creator.create() @@ -153,9 +153,13 @@ class CreateStackSuccessTests(OSIntegrationTestCase): vcpus=1)) self.flavor_creator.create() + self.network_name = self.guid + '-net' + self.subnet_name = self.guid + '-subnet' self.env_values = { 'image_name': self.image_creator.image_settings.name, - 'flavor_name': self.flavor_creator.flavor_settings.name} + 'flavor_name': self.flavor_creator.flavor_settings.name, + 'net_name': self.network_name, + 'subnet_name': self.subnet_name} self.heat_tmplt_path = pkg_resources.resource_filename( 'snaps.openstack.tests.heat', 'test_heat_template.yaml') @@ -208,6 +212,11 @@ class CreateStackSuccessTests(OSIntegrationTestCase): self.assertIsNotNone(self.stack_creator.get_outputs()) self.assertEquals(0, len(self.stack_creator.get_outputs())) + resources = heat_utils.get_resources( + self.heat_cli, self.stack_creator.get_stack()) + self.assertIsNotNone(resources) + self.assertEqual(4, len(resources)) + def test_create_stack_template_dict(self): """ Tests the creation of an OpenStack stack from a heat dict() object. @@ -309,6 +318,42 @@ class CreateStackSuccessTests(OSIntegrationTestCase): stack2 = stack_creator2.create() self.assertEqual(created_stack1.id, stack2.id) + def test_retrieve_network_creators(self): + """ + Tests the creation of an OpenStack stack from Heat template file and + the retrieval of the network creator. + """ + stack_settings = StackSettings( + name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', + template_path=self.heat_tmplt_path, + env_values=self.env_values) + self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds, + stack_settings) + created_stack = self.stack_creator.create() + self.assertIsNotNone(created_stack) + + net_creators = self.stack_creator.get_network_creators() + self.assertIsNotNone(net_creators) + self.assertEqual(1, len(net_creators)) + self.assertEqual(self.network_name, net_creators[0].get_network().name) + + neutron = neutron_utils.neutron_client(self.os_creds) + net_by_name = neutron_utils.get_network( + neutron, network_name=net_creators[0].get_network().name) + self.assertEqual(net_creators[0].get_network(), net_by_name) + self.assertIsNotNone(neutron_utils.get_network_by_id( + neutron, net_creators[0].get_network().id)) + + self.assertEqual(1, len(net_creators[0].get_subnets())) + subnet = net_creators[0].get_subnets()[0] + subnet_by_name = neutron_utils.get_subnet( + neutron, subnet_name=subnet.name) + self.assertEqual(subnet, subnet_by_name) + + subnet_by_id = neutron_utils.get_subnet_by_id(neutron, subnet.id) + self.assertIsNotNone(subnet_by_id) + self.assertEqual(subnet_by_name, subnet_by_id) + class CreateStackNegativeTests(OSIntegrationTestCase): """ diff --git a/snaps/openstack/tests/heat/test_heat_template.yaml b/snaps/openstack/tests/heat/test_heat_template.yaml index d81a71c..ffb82d6 100644 --- a/snaps/openstack/tests/heat/test_heat_template.yaml +++ b/snaps/openstack/tests/heat/test_heat_template.yaml @@ -13,16 +13,27 @@ parameters: label: Instance Type description: Type of instance (flavor) to be used default: m1.small + net_name: + type: string + label: Test network name + description: The name of the stack's network + default: test_net + subnet_name: + type: string + label: Test subnet name + description: The name of the stack's subnet + default: test_subnet resources: private_net: type: OS::Neutron::Net properties: - name: test_net + name: { get_param: net_name } private_subnet: type: OS::Neutron::Subnet properties: + name: { get_param: subnet_name } network_id: { get_resource: private_net } cidr: 10.0.0.0/24 diff --git a/snaps/openstack/utils/heat_utils.py b/snaps/openstack/utils/heat_utils.py index a91a21c..c2919cb 100644 --- a/snaps/openstack/utils/heat_utils.py +++ b/snaps/openstack/utils/heat_utils.py @@ -20,9 +20,9 @@ from heatclient.common.template_format import yaml_loader from oslo_serialization import jsonutils from snaps import file_utils -from snaps.domain.stack import Stack +from snaps.domain.stack import Stack, Resource -from snaps.openstack.utils import keystone_utils +from snaps.openstack.utils import keystone_utils, neutron_utils __author__ = 'spisarski' @@ -130,6 +130,54 @@ def delete_stack(heat_cli, stack): heat_cli.stacks.delete(stack.id) +def __get_os_resources(heat_cli, stack): + """ + Returns all of the OpenStack resource objects for a given stack + :param heat_cli: the OpenStack heat client + :param stack: the SNAPS-OO Stack domain object + :return: a list + """ + return heat_cli.resources.list(stack.id) + + +def get_resources(heat_cli, stack): + """ + Returns all of the OpenStack resource objects for a given stack + :param heat_cli: the OpenStack heat client + :param stack: the SNAPS-OO Stack domain object + :return: a list + """ + os_resources = __get_os_resources(heat_cli, stack) + + if os_resources: + out = list() + for os_resource in os_resources: + out.append(Resource(resource_type=os_resource.resource_type, + resource_id=os_resource.physical_resource_id)) + return out + + +def get_stack_networks(heat_cli, neutron, stack): + """ + Returns an instance of NetworkSettings for each network owned by this stack + :param heat_cli: the OpenStack heat client object + :param neutron: the OpenStack neutron client object + :param stack: the SNAPS-OO Stack domain object + :return: a list of NetworkSettings + """ + + out = list() + resources = get_resources(heat_cli, stack) + for resource in resources: + if resource.type == 'OS::Neutron::Net': + network = neutron_utils.get_network_by_id( + neutron, resource.id) + if network: + out.append(network) + + return out + + def parse_heat_template_str(tmpl_str): """ Takes a heat template string, performs some simple validation and returns a diff --git a/snaps/openstack/utils/neutron_utils.py b/snaps/openstack/utils/neutron_utils.py index c615bd5..e21c905 100644 --- a/snaps/openstack/utils/neutron_utils.py +++ b/snaps/openstack/utils/neutron_utils.py @@ -188,6 +188,35 @@ def get_subnet(neutron, subnet_settings=None, subnet_name=None): return Subnet(**subnet) +def get_subnet_by_id(neutron, subnet_id): + """ + Returns a SNAPS-OO Subnet domain object for a given ID + :param neutron: the OpenStack neutron client + :param subnet_id: the subnet ID + :return: a Subnet object + """ + os_subnet = neutron.show_subnet(subnet_id) + if os_subnet and 'subnet' in os_subnet: + return Subnet(**os_subnet['subnet']) + + +def get_subnets_by_network(neutron, network): + """ + Returns a list of SNAPS-OO Subnet domain objects + :param neutron: the OpenStack neutron client + :param network: the SNAPS-OO Network domain object + :return: a list of Subnet objects + """ + out = list() + + os_subnets = neutron.list_subnets(network_id=network.id) + + for os_subnet in os_subnets['subnets']: + out.append(Subnet(**os_subnet)) + + return out + + def create_router(neutron, os_creds, router_settings): """ Creates a router for OpenStack diff --git a/snaps/openstack/utils/tests/heat_utils_tests.py b/snaps/openstack/utils/tests/heat_utils_tests.py index 16ce9fb..92432f6 100644 --- a/snaps/openstack/utils/tests/heat_utils_tests.py +++ b/snaps/openstack/utils/tests/heat_utils_tests.py @@ -25,7 +25,7 @@ from snaps.openstack.create_image import OpenStackImage from snaps.openstack.create_stack import StackSettings from snaps.openstack.tests import openstack_tests from snaps.openstack.tests.os_source_file_test import OSComponentTestCase -from snaps.openstack.utils import heat_utils +from snaps.openstack.utils import heat_utils, neutron_utils __author__ = 'spisarski' @@ -77,13 +77,14 @@ class HeatUtilsCreateStackTests(OSComponentTestCase): Instantiates OpenStack instances that cannot be spawned by Heat """ guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) - stack_name1 = self.__class__.__name__ + '-' + str(guid) + '-stack1' - stack_name2 = self.__class__.__name__ + '-' + str(guid) + '-stack2' + stack_name1 = guid + '-stack1' + stack_name2 = guid + '-stack2' + self.network_name = guid + '-net' + self.subnet_name = guid + '-subnet' self.image_creator = OpenStackImage( self.os_creds, openstack_tests.cirros_image_settings( - name=self.__class__.__name__ + '-' + str(guid) + '-image', - image_metadata=self.image_metadata)) + name=guid + '-image', image_metadata=self.image_metadata)) self.image_creator.create() # Create Flavor @@ -93,7 +94,9 @@ class HeatUtilsCreateStackTests(OSComponentTestCase): self.flavor_creator.create() env_values = {'image_name': self.image_creator.image_settings.name, - 'flavor_name': self.flavor_creator.flavor_settings.name} + 'flavor_name': self.flavor_creator.flavor_settings.name, + 'net_name': self.network_name, + 'subnet_name': self.subnet_name} heat_tmplt_path = pkg_resources.resource_filename( 'snaps.openstack.tests.heat', 'test_heat_template.yaml') self.stack_settings1 = StackSettings( @@ -175,6 +178,21 @@ class HeatUtilsCreateStackTests(OSComponentTestCase): self.assertTrue(is_active) + resources = heat_utils.get_resources(self.heat_client, self.stack1) + self.assertIsNotNone(resources) + self.assertEqual(4, len(resources)) + + neutron = neutron_utils.neutron_client(self.os_creds) + networks = heat_utils.get_stack_networks( + self.heat_client, neutron, self.stack1) + self.assertIsNotNone(networks) + self.assertEqual(1, len(networks)) + self.assertEqual(self.network_name, networks[0].name) + + subnets = neutron_utils.get_subnets_by_network(neutron, networks[0]) + self.assertEqual(1, len(subnets)) + self.assertEqual(self.subnet_name, subnets[0].name) + def test_create_stack_x2(self): """ Tests the creation of an OpenStack keypair that does not exist. diff --git a/snaps/openstack/utils/tests/neutron_utils_tests.py b/snaps/openstack/utils/tests/neutron_utils_tests.py index f6fc2bb..5493f5b 100644 --- a/snaps/openstack/utils/tests/neutron_utils_tests.py +++ b/snaps/openstack/utils/tests/neutron_utils_tests.py @@ -152,9 +152,15 @@ class NeutronUtilsSubnetTests(OSComponentTestCase): Cleans the remote OpenStack objects """ if self.subnet: - neutron_utils.delete_subnet(self.neutron, self.subnet) + try: + neutron_utils.delete_subnet(self.neutron, self.subnet) + except: + pass if self.network: - neutron_utils.delete_network(self.neutron, self.network) + try: + neutron_utils.delete_network(self.neutron, self.network) + except: + pass def test_create_subnet(self): """ @@ -173,6 +179,16 @@ class NeutronUtilsSubnetTests(OSComponentTestCase): self.assertTrue(validate_subnet( self.neutron, subnet_setting.name, subnet_setting.cidr, True)) + subnet_query1 = neutron_utils.get_subnet( + self.neutron, subnet_name=subnet_setting.name) + self.assertEqual(self.subnet, subnet_query1) + + subnet_query2 = neutron_utils.get_subnets_by_network(self.neutron, + self.network) + self.assertIsNotNone(subnet_query2) + self.assertEqual(1, len(subnet_query2)) + self.assertEqual(self.subnet, subnet_query2[0]) + def test_create_subnet_null_name(self): """ Tests the neutron_utils.create_neutron_subnet() function for an @@ -201,13 +217,23 @@ class NeutronUtilsSubnetTests(OSComponentTestCase): self.neutron, self.net_config.network_settings.name, True)) subnet_setting = self.net_config.network_settings.subnet_settings[0] - neutron_utils.create_subnet( + self.subnet = neutron_utils.create_subnet( self.neutron, subnet_setting, self.os_creds, network=self.network) self.assertTrue(validate_subnet( self.neutron, subnet_setting.name, subnet_setting.cidr, True)) self.assertFalse(validate_subnet( self.neutron, '', subnet_setting.cidr, True)) + subnet_query1 = neutron_utils.get_subnet( + self.neutron, subnet_name=subnet_setting.name) + self.assertEqual(self.subnet, subnet_query1) + + subnet_query2 = neutron_utils.get_subnets_by_network(self.neutron, + self.network) + self.assertIsNotNone(subnet_query2) + self.assertEqual(1, len(subnet_query2)) + self.assertEqual(self.subnet, subnet_query2[0]) + def test_create_subnet_null_cidr(self): """ Tests the neutron_utils.create_neutron_subnet() function for an @@ -272,17 +298,29 @@ class NeutronUtilsRouterTests(OSComponentTestCase): self.subnet) if self.router: - neutron_utils.delete_router(self.neutron, self.router) - validate_router(self.neutron, self.router.name, False) + try: + neutron_utils.delete_router(self.neutron, self.router) + validate_router(self.neutron, self.router.name, False) + except: + pass if self.port: - neutron_utils.delete_port(self.neutron, self.port) + try: + neutron_utils.delete_port(self.neutron, self.port) + except: + pass if self.subnet: - neutron_utils.delete_subnet(self.neutron, self.subnet) + try: + neutron_utils.delete_subnet(self.neutron, self.subnet) + except: + pass if self.network: - neutron_utils.delete_network(self.neutron, self.network) + try: + neutron_utils.delete_network(self.neutron, self.network) + except: + pass def test_create_router_simple(self): """ @@ -757,7 +795,11 @@ class NeutronUtilsFloatingIpTests(OSComponentTestCase): Cleans the image and downloaded image file """ if self.floating_ip: - neutron_utils.delete_floating_ip(self.neutron, self.floating_ip) + try: + neutron_utils.delete_floating_ip( + self.neutron, self.floating_ip) + except: + pass def test_floating_ips(self): """ diff --git a/snaps/test_suite_builder.py b/snaps/test_suite_builder.py index f0bae6e..e264b59 100644 --- a/snaps/test_suite_builder.py +++ b/snaps/test_suite_builder.py @@ -27,7 +27,8 @@ from snaps.domain.test.project_tests import ( ProjectDomainObjectTests, DomainDomainObjectTests, ComputeQuotasDomainObjectTests, NetworkQuotasDomainObjectTests) from snaps.domain.test.role_tests import RoleDomainObjectTests -from snaps.domain.test.stack_tests import StackDomainObjectTests +from snaps.domain.test.stack_tests import ( + StackDomainObjectTests, ResourceDomainObjectTests) from snaps.domain.test.user_tests import UserDomainObjectTests from snaps.domain.test.vm_inst_tests import ( VmInstDomainObjectTests, FloatingIpDomainObjectTests) @@ -157,6 +158,8 @@ def add_unit_tests(suite): suite.addTest(unittest.TestLoader().loadTestsFromTestCase( StackDomainObjectTests)) suite.addTest(unittest.TestLoader().loadTestsFromTestCase( + ResourceDomainObjectTests)) + suite.addTest(unittest.TestLoader().loadTestsFromTestCase( StackSettingsUnitTests)) suite.addTest(unittest.TestLoader().loadTestsFromTestCase( VmInstDomainObjectTests)) |