diff --git a/fuel_health/ceilometermanager.py b/fuel_health/ceilometermanager.py index faa54f42..e71615f8 100644 --- a/fuel_health/ceilometermanager.py +++ b/fuel_health/ceilometermanager.py @@ -34,7 +34,6 @@ class CeilometerBaseTest(fuel_health.nmanager.PlatformServicesBaseClass): if cls.manager.clients_initialized: cls.wait_interval = cls.config.compute.build_interval cls.wait_timeout = cls.config.compute.build_timeout - cls.private_net = 'net04' cls.objects_for_delete = [] cls.nova_notifications = ['memory', 'vcpus', 'disk.root.size', 'disk.ephemeral.size'] @@ -102,6 +101,15 @@ class CeilometerBaseTest(fuel_health.nmanager.PlatformServicesBaseClass): not self.config.compute.use_vcenter): self.skipTest('There are no compute nodes') + def create_server(self, name, **kwargs): + server = self._create_server(self.compute_client, name, **kwargs) + self.addCleanup(fuel_health.test.call_until_true, + self.is_resource_deleted, 300, 3, + self.compute_client.servers, server.id) + self.addCleanup(self.compute_client.servers.delete, server.id) + + return server + def create_alarm(self, **kwargs): """This method provides creation of alarm.""" if 'name' in kwargs: @@ -274,12 +282,7 @@ class CeilometerBaseTest(fuel_health.nmanager.PlatformServicesBaseClass): router["id"], {"router": {"name": rand_name("ceilo-router-update")}}) - external_network = None - for network in self.neutron_client.list_networks()["networks"]: - if network.get("router:external"): - external_network = network - if not external_network: - self.fail('Can not find external network') + external_network = self.find_external_network() try: body = { "floatingip": { @@ -308,15 +311,17 @@ class CeilometerBaseTest(fuel_health.nmanager.PlatformServicesBaseClass): flavor.id for flavor in self.compute_client.flavors.list() if flavor.name == 'm1.small') - # Create json for node grou + private_net_id, floating_ip_pool = self.create_network_resources() + # Create json for node group node_group = {'name': 'all-in-one', 'flavor_id': flavor_id, 'node_processes': ['nodemanager', 'datanode', 'resourcemanager', 'namenode', 'historyserver'], 'count': 1, - 'floating_ip_pool': self.floating_ip_pool, 'auto_security_group': True} + if floating_ip_pool: + node_group['floating_ip_pool'] = floating_ip_pool # Create json for Sahara cluster cluster_json = {'name': rand_name("ceilo-cluster"), @@ -325,10 +330,15 @@ class CeilometerBaseTest(fuel_health.nmanager.PlatformServicesBaseClass): 'default_image_id': image_id, 'cluster_configs': {'HDFS': {'dfs.replication': 1}}, 'node_groups': [node_group], - 'net_id': self.neutron_private_net_id} + 'net_id': private_net_id} # Create Sahara cluster cluster = self.sahara_client.clusters.create(**cluster_json) + self.objects_for_delete.append( + (self.sahara_client.clusters.delete, cluster.id)) + self.addCleanup(fuel_health.test.call_until_true, + self.is_resource_deleted, 300, 3, + self.sahara_client.clusters, cluster.id) # Wait for change cluster state for metric: cluster.update def check_status(): @@ -336,9 +346,9 @@ class CeilometerBaseTest(fuel_health.nmanager.PlatformServicesBaseClass): return cluster_state in ['Waiting', 'Active', 'Error'] fuel_health.test.call_until_true(check_status, 300, 1) - self.objects_for_delete.append((self.sahara_client.clusters.delete, - cluster.id)) + # Delete cluster self.sahara_client.clusters.delete(cluster.id) + return cluster def glance_helper(self): diff --git a/fuel_health/heatmanager.py b/fuel_health/heatmanager.py index 2dc368ba..c0fab8e1 100644 --- a/fuel_health/heatmanager.py +++ b/fuel_health/heatmanager.py @@ -26,23 +26,26 @@ import fuel_health.test LOG = logging.getLogger(__name__) -class HeatBaseTest(fuel_health.nmanager.NovaNetworkScenarioTest): - """Base class for Heat openstack sanity and smoke tests.""" +class HeatBaseTest(fuel_health.nmanager.PlatformServicesBaseClass): + """Base class for Heat sanity and platform tests.""" @classmethod def setUpClass(cls): super(HeatBaseTest, cls).setUpClass() - if cls.manager.clients_initialized: - if cls.heat_client is None: - cls.fail('Heat is unavailable.') - cls.wait_interval = cls.config.compute.build_interval - cls.wait_timeout = cls.config.compute.build_timeout + cls.wait_interval = cls.config.compute.build_interval + cls.wait_timeout = cls.config.compute.build_timeout def setUp(self): super(HeatBaseTest, self).setUp() + self.check_clients_state() + if self.heat_client is None: + self.fail('Heat is unavailable.') + if not self.find_micro_flavor(): + self.fail('m1.micro flavor was not created.') + def create_flavor(self, ram=256, vcpus=1, disk=2): """This method creates a flavor for Heat tests.""" diff --git a/fuel_health/neutronmanager.py b/fuel_health/neutronmanager.py index 927587f9..f652a61c 100644 --- a/fuel_health/neutronmanager.py +++ b/fuel_health/neutronmanager.py @@ -46,7 +46,7 @@ class NeutronBaseTest(fuel_health.nmanager.NovaNetworkScenarioTest): external_network = network if not external_network: - self.fail('Can not find external network') + self.fail('Cannot find the external network.') gw_info = { "network_id": external_network["id"], diff --git a/fuel_health/nmanager.py b/fuel_health/nmanager.py index 7b74821f..a3dfd1b8 100644 --- a/fuel_health/nmanager.py +++ b/fuel_health/nmanager.py @@ -20,6 +20,8 @@ import socket import time import traceback +import fuel_health.common.utils.data_utils as data_utils + LOG = logging.getLogger(__name__) # Default client libs @@ -651,7 +653,7 @@ class NovaNetworkScenarioTest(OfficialClientTest): create_kwargs = {'nics': [{'net-id': network[0]}], 'security_groups': security_groups} else: - self.fail("Default private network '{0}' isn't present." + self.fail("Default private network '{0}' isn't present. " "Please verify it is properly created.". format(self.private_net)) else: @@ -867,46 +869,6 @@ class NovaNetworkScenarioTest(OfficialClientTest): class PlatformServicesBaseClass(NovaNetworkScenarioTest): - def setUp(self): - super(PlatformServicesBaseClass, self).setUp() - - self.neutron_private_net_id = None - self.floating_ip_pool = None - - if self.config.network.network_provider == 'neutron': - self.neutron_private_net_id = ( - self.compute_client.networks.find(label=self.private_net)).id - self.floating_ip_pool = ( - self.compute_client.networks.find( - label=self.private_net + '_ext')).id - else: - if not self.config.compute.auto_assign_floating_ip: - flip_list = self.compute_client.floating_ip_pools.list() - self.floating_ip_pool = next( - flip.name for flip in flip_list if flip.is_loaded()) - - def _try_port(self, host, port): - start_time = time.time() - delta = time.time() - start_time - - while delta < 600: - cmd = ("timeout 60 bash -c 'echo >/dev/" - "tcp/{0}/{1}'; echo $?".format(host, port)) - - output, output_err = self._run_ssh_cmd(cmd) - print('NC output after %s seconds is "%s"' % (delta, output)) - LOG.debug('NC output after %s seconds is "%s"', - delta, output) - - if output or str(output_err).find(' succeeded!') > 0: - return True - - time.sleep(10) - delta = time.time() - start_time - - self.fail('On host %s port %s is not opened ' - 'more then 10 minutes' % (host, port)) - def get_max_free_compute_node_ram(self, min_required_ram_mb): max_free_ram_mb = 0 for hypervisor in self.compute_client.hypervisors.list(): @@ -918,6 +880,117 @@ class PlatformServicesBaseClass(NovaNetworkScenarioTest): return max_free_ram_mb + # Methods for creating network resources. + def create_network_resources(self): + """This method creates network resources. + + It creates a network, an internal subnet on the network, a router and + links the network to the router. All resources created by this method + will be automatically deleted. + """ + + private_net_id = None + floating_ip_pool = None + + if self.config.network.network_provider == 'neutron': + ext_net = self.find_external_network() + net_name = data_utils.rand_name('ostf-platform-service-net-') + net = self._create_net(net_name) + subnet = self._create_internal_subnet(net) + router_name = data_utils.rand_name('ostf-platform-service-router-') + router = self._create_router(router_name, ext_net) + self.neutron_client.add_interface_router( + router['id'], {'subnet_id': subnet['id']}) + self.addCleanup(self.neutron_client.remove_interface_router, + router['id'], {'subnet_id': subnet['id']}) + self.addCleanup( + self.neutron_client.remove_gateway_router, router['id']) + + private_net_id = net['id'] + floating_ip_pool = ext_net['id'] + else: + if not self.config.compute.auto_assign_floating_ip: + fl_ip_pools = self.compute_client.floating_ip_pools.list() + floating_ip_pool = next(fl_ip_pool.name + for fl_ip_pool in fl_ip_pools + if fl_ip_pool.is_loaded()) + + return private_net_id, floating_ip_pool + + def find_external_network(self): + """This method finds the external network.""" + + LOG.debug('Finding external network...') + for net in self.neutron_client.list_networks()['networks']: + if net['router:external']: + LOG.debug('External network found. Ext net: {0}'.format(net)) + return net + + self.fail('Cannot find the external network.') + + def _create_net(self, name): + """This method creates a network. + + All resources created by this method will be automatically deleted. + """ + + LOG.debug('Creating network with name "{0}"...'.format(name)) + net_body = { + 'network': { + 'name': name, + 'tenant_id': self.tenant_id + } + } + net = self.neutron_client.create_network(net_body)['network'] + self.addCleanup(self.neutron_client.delete_network, net['id']) + LOG.debug('Network "{0}" has been created. Net: {1}'.format(name, net)) + + return net + + def _create_internal_subnet(self, net): + """This method creates an internal subnet on the network. + + All resources created by this method will be automatically deleted. + """ + + LOG.debug('Creating subnet...') + subnet_body = { + 'subnet': { + 'network_id': net['id'], + 'ip_version': 4, + 'cidr': '10.1.7.0/24', + 'tenant_id': self.tenant_id + } + } + subnet = self.neutron_client.create_subnet(subnet_body)['subnet'] + self.addCleanup(self.neutron_client.delete_subnet, subnet['id']) + LOG.debug('Subnet has been created. Subnet: {0}'.format(subnet)) + + return subnet + + def _create_router(self, name, ext_net): + """This method creates a router. + + All resources created by this method will be automatically deleted. + """ + + LOG.debug('Creating router with name "{0}"...'.format(name)) + router_body = { + 'router': { + 'name': name, + 'external_gateway_info': { + 'network_id': ext_net['id'] + }, + 'tenant_id': self.tenant_id + } + } + router = self.neutron_client.create_router(router_body)['router'] + self.addCleanup(self.neutron_client.delete_router, router['id']) + LOG.debug('Router "{0}" has been created. ' + 'Router: {1}'.format(name, router)) + + return router + def get_info_about_available_resources(self, min_ram, min_hdd, min_vcpus): """This function allows to get the information about resources. @@ -943,8 +1016,7 @@ class PlatformServicesBaseClass(NovaNetworkScenarioTest): # Methods for finding and checking Sahara images. def find_and_check_image(self, tag_plugin, tag_version): - """This method finds a correctly registered image for Sahara platform - tests. + """This method finds a correctly registered Sahara image. It finds a Sahara image by specific tags and checks whether the image is correctly registered or not. @@ -978,6 +1050,27 @@ class PlatformServicesBaseClass(NovaNetworkScenarioTest): LOG.debug('Image with tags "{0}" and "{1}" ' 'not found.'.format(tag_plugin, tag_version)) + # Method for checking whether or not resource is deleted. + def is_resource_deleted(self, resource_client, resource_id): + """This method checks whether or not the resource is deleted. + + The API request is wrapped in the try/except block to correctly handle + the "404 Not Found" exception. If the resource doesn't exist, this + method will return True. Otherwise it will return False. + """ + + try: + resource_client.get(resource_id) + except Exception as exc: + exc_msg = exc.message.lower() + if ('not found' in exc_msg) or ('could not be found' in exc_msg): + LOG.debug('Resource "{0}" is deleted.'.format(resource_id)) + return True + + self.fail(exc.message) + + return False + class SanityChecksTest(OfficialClientTest): """Base class for openstack sanity tests.""" @@ -1145,7 +1238,7 @@ class SmokeChecksTest(OfficialClientTest): create_kwargs = {'block_device_mapping': bd_map, 'nics': [{'net-id': network[0]}]} else: - self.fail("Default private network '{0}' isn't present." + self.fail("Default private network '{0}' isn't present. " "Please verify it is properly created.". format(self.private_net)) server = client.servers.create( @@ -1182,7 +1275,7 @@ class SmokeChecksTest(OfficialClientTest): if network: create_kwargs = {'nics': [{'net-id': network[0]}]} else: - self.fail("Default private network '{0}' isn't present." + self.fail("Default private network '{0}' isn't present. " "Please verify it is properly created.". format(self.private_net)) server = client.servers.create( diff --git a/fuel_health/saharamanager.py b/fuel_health/saharamanager.py index 23980c4a..be891dea 100644 --- a/fuel_health/saharamanager.py +++ b/fuel_health/saharamanager.py @@ -15,8 +15,6 @@ import logging import time -from saharaclient.api import base as sab - from fuel_health.common.utils.data_utils import rand_name from fuel_health import nmanager @@ -226,7 +224,7 @@ class SaharaTestsManager(nmanager.PlatformServicesBaseClass): """ LOG.debug('Deleting resource "{0}"...'.format(resource_id)) - if self._is_resource_deleted(resource_client, resource_id): + if self.is_resource_deleted(resource_client, resource_id): return resource_client.delete(resource_id) self._wait_for_deletion(resource_client, resource_id) @@ -237,28 +235,10 @@ class SaharaTestsManager(nmanager.PlatformServicesBaseClass): start = time.time() while time.time() - start < self.delete_timeout: - if self._is_resource_deleted(resource_client, resource_id): + if self.is_resource_deleted(resource_client, resource_id): return time.sleep(self.request_timeout) self.fail('Request timed out. ' 'Timed out while waiting for one of the test resources ' 'to delete within {0} seconds.'.format(self.delete_timeout)) - - def _is_resource_deleted(self, resource_client, resource_id): - """This method checks whether the resource is deleted or not. - - The API request is wrapped in try/except block to correctly handle - "404 Not Found" exception. If the resource doesn't exist, this method - will return True. Otherwise it will return False. - """ - - try: - resource_client.get(resource_id) - except sab.APIException as sahara_api_exc: - if sahara_api_exc.error_code == 404: - LOG.debug('Resource "{0}" not found.'.format(resource_id)) - return True - self.fail(sahara_api_exc.message) - - return False diff --git a/fuel_health/test.py b/fuel_health/test.py index 3c7fb0f7..77a77451 100644 --- a/fuel_health/test.py +++ b/fuel_health/test.py @@ -43,7 +43,7 @@ class BaseTestCase(unittest2.TestCase, cls.config = config.FuelConfig() -def call_until_true(func, duration, sleep_for, arg=None): +def call_until_true(func, duration, sleep_for, *args): """Call the given function until it returns True (and return True) or until the specified duration (in seconds) elapses (and return False). @@ -57,8 +57,8 @@ def call_until_true(func, duration, sleep_for, arg=None): now = time.time() timeout = now + duration while now < timeout: - if arg: - if func(arg): + if args: + if func(*args): return True elif func(): return True diff --git a/fuel_health/tests/smoke/test_nova_image_actions.py b/fuel_health/tests/smoke/test_nova_image_actions.py index 791a044c..3577b953 100644 --- a/fuel_health/tests/smoke/test_nova_image_actions.py +++ b/fuel_health/tests/smoke/test_nova_image_actions.py @@ -97,7 +97,7 @@ class TestImageAction(nmanager.SmokeChecksTest): ], } else: - self.fail("Default private network '{0}' isn't present." + self.fail("Default private network '{0}' isn't present. " "Please verify it is properly created.". format(self.private_net)) server = client.servers.create(name=name, diff --git a/fuel_health/tests/smoke/test_vcenter.py b/fuel_health/tests/smoke/test_vcenter.py index b6c5ed61..01eb6cf1 100644 --- a/fuel_health/tests/smoke/test_vcenter.py +++ b/fuel_health/tests/smoke/test_vcenter.py @@ -304,7 +304,7 @@ class TestVcenterImageAction(nmanager.SmokeChecksTest): ], } else: - self.fail("Default private network '{0}' isn't present." + self.fail("Default private network '{0}' isn't present. " "Please verify it is properly created.". format(self.private_net)) server = client.servers.create(name=name, diff --git a/fuel_health/tests/tests_platform/test_ceilometer.py b/fuel_health/tests/tests_platform/test_ceilometer.py index 340b4f87..837bce48 100644 --- a/fuel_health/tests/tests_platform/test_ceilometer.py +++ b/fuel_health/tests/tests_platform/test_ceilometer.py @@ -122,14 +122,15 @@ class CeilometerApiPlatformTests(ceilometermanager.CeilometerBaseTest): """ self.check_image_exists() + private_net_id, _ = self.create_network_resources() fail_msg = 'Failed to create instance.' msg = 'creating instance' name = rand_name('ostf-ceilo-instance-') vcenter = self.config.compute.use_vcenter image_name = 'TestVM-VMDK' if vcenter else None - instance = self.verify(600, self._create_server, 1, fail_msg, msg, - self.compute_client, name, img_name=image_name) + instance = self.verify(600, self.create_server, 1, fail_msg, msg, name, + net_id=private_net_id, img_name=image_name) fail_msg = 'Failed while waiting for "ACTIVE" status of instance.' msg = 'waiting for "ACTIVE" status of instance' diff --git a/fuel_health/tests/tests_platform/test_heat.py b/fuel_health/tests/tests_platform/test_heat.py index 8bf11c49..77588158 100644 --- a/fuel_health/tests/tests_platform/test_heat.py +++ b/fuel_health/tests/tests_platform/test_heat.py @@ -71,7 +71,7 @@ class HeatSmokeTests(heatmanager.HeatBaseTest): 'ImageId': self.config.compute.image_name } if 'neutron' in self.config.network.network_provider: - parameters['network'] = self.private_net + parameters['network'], _ = self.create_network_resources() template = self.load_template( 'heat_create_neutron_stack_template.yaml') else: @@ -231,7 +231,7 @@ class HeatSmokeTests(heatmanager.HeatBaseTest): 'ImageId': self.config.compute.image_name } if 'neutron' in self.config.network.network_provider: - parameters['network'] = self.private_net + parameters['network'], _ = self.create_network_resources() template = self.load_template( 'heat_create_neutron_stack_template.yaml') else: @@ -418,7 +418,7 @@ class HeatSmokeTests(heatmanager.HeatBaseTest): 'ImageId': self.config.compute.image_name } if 'neutron' in self.config.network.network_provider: - parameters['network'] = self.private_net + parameters['network'], _ = self.create_network_resources() template = self.load_template( 'heat_create_neutron_stack_template.yaml') else: @@ -519,7 +519,7 @@ class HeatSmokeTests(heatmanager.HeatBaseTest): 'ImageId': self.config.compute.image_name } if 'neutron' in self.config.network.network_provider: - parameters['network'] = self.private_net + parameters['network'], _ = self.create_network_resources() template = self.load_template( 'heat_update_neutron_stack_template.yaml') else: @@ -640,7 +640,7 @@ class HeatSmokeTests(heatmanager.HeatBaseTest): } if 'neutron' in self.config.network.network_provider: - parameters['Subnet'] = self.private_net + parameters['Subnet'], _ = self.create_network_resources() template = self.load_template('heat_autoscaling_neutron.yaml') else: template = self.load_template('heat_autoscaling_nova.yaml') @@ -780,7 +780,7 @@ class HeatSmokeTests(heatmanager.HeatBaseTest): 'ImageId': self.config.compute.image_name } if 'neutron' in self.config.network.network_provider: - parameters['network'] = self.private_net + parameters['network'], _ = self.create_network_resources() template = self.load_template( 'heat_create_neutron_stack_template.yaml') else: diff --git a/fuel_health/tests/tests_platform/test_sahara.py b/fuel_health/tests/tests_platform/test_sahara.py index 2b19dbb6..2b1fd366 100644 --- a/fuel_health/tests/tests_platform/test_sahara.py +++ b/fuel_health/tests/tests_platform/test_sahara.py @@ -55,6 +55,7 @@ class SaharaClusterTest(saharamanager.SaharaTestsManager): self.skipTest(msg) flavor_id = self.create_flavor() + private_net_id, floating_ip_pool = self.create_network_resources() self.cl_template = { 'name': rand_name('sahara-cluster-template-'), 'plugin': self._plugin_name, @@ -64,7 +65,7 @@ class SaharaClusterTest(saharamanager.SaharaTestsManager): 'name': 'master', 'flavor_id': flavor_id, 'node_processes': self._master_processes, - 'floating_ip_pool': self.floating_ip_pool, + 'floating_ip_pool': floating_ip_pool, 'auto_security_group': True, 'count': 1 }, @@ -72,12 +73,12 @@ class SaharaClusterTest(saharamanager.SaharaTestsManager): 'name': 'worker', 'flavor_id': flavor_id, 'node_processes': self._worker_processes, - 'floating_ip_pool': self.floating_ip_pool, + 'floating_ip_pool': floating_ip_pool, 'auto_security_group': True, 'count': 1 } ], - 'net_id': self.neutron_private_net_id, + 'net_id': private_net_id, 'cluster_configs': {'HDFS': {'dfs.replication': 1}}, 'description': 'Test cluster template' }