diff --git a/fuel_health/cleanup.py b/fuel_health/cleanup.py index 20262058..426c3b87 100755 --- a/fuel_health/cleanup.py +++ b/fuel_health/cleanup.py @@ -23,13 +23,13 @@ sys.path.append(path) import logging from fuel_health import exceptions -import fuel_health.heatmanager +import fuel_health.nmanager LOG = logging.getLogger(__name__) -class CleanUpClientManager(fuel_health.heatmanager.HeatManager): +class CleanUpClientManager(fuel_health.nmanager.OfficialClientManager): """ Manager that provides access to the official python clients for calling various OpenStack APIs. @@ -57,6 +57,18 @@ class CleanUpClientManager(fuel_health.heatmanager.HeatManager): def cleanup(): manager = CleanUpClientManager() + murano_client = manager._get_murano_client() + if murano_client is not None: + environments = murano_client.list_environments() + for e in environments: + if e.name.startswith('ost1_test-'): + try: + LOG.info('Start environment deletion.') + murano_client.stacks.delete(e.id) + except Exception as exc: + LOG.debug(exc) + pass + heat_client = manager._get_heat_client() if heat_client is not None: stacks = heat_client.stacks.list() diff --git a/fuel_health/config.py b/fuel_health/config.py index 9ee40fbe..aedb6d14 100644 --- a/fuel_health/config.py +++ b/fuel_health/config.py @@ -303,6 +303,31 @@ def register_savanna_opts(conf): conf.register_opt(opt, group='savanna') +murano_group = cfg.OptGroup(name='murano', + title='Murano API Service Options') + +MuranoConfig = [ + cfg.StrOpt('api_url', + default=None, + help="Murano API Service URL."), + cfg.BoolOpt('insecure', + default=False, + help="This parameter allow to enable SSL encription"), + cfg.StrOpt('agListnerIP', + default='10.100.0.155', + help="Murano SQL Cluster AG IP."), + cfg.StrOpt('clusterIP', + default='10.100.0.150', + help="Murano SQL Cluster IP."), +] + + +def register_murano_opts(conf): + conf.register_group(murano_group) + for opt in MuranoConfig: + conf.register_opt(opt, group='murano') + + def process_singleton(cls): """Wrapper for classes... To be instantiated only one time per process""" instances = {} @@ -363,10 +388,12 @@ class FileConfig(object): register_identity_opts(cfg.CONF) register_network_opts(cfg.CONF) register_volume_opts(cfg.CONF) + register_murano_opts(cfg.CONF) self.compute = cfg.CONF.compute self.identity = cfg.CONF.identity self.network = cfg.CONF.network self.volume = cfg.CONF.volume + self.murano = cfg.CONF.murano class ConfigGroup(object): @@ -404,6 +431,7 @@ class NailgunConfig(object): network = ConfigGroup(NetworkGroup) volume = ConfigGroup(VolumeGroup) object_storage = ConfigGroup(ObjectStoreConfig) + murano = ConfigGroup(MuranoConfig) def __init__(self, parse=True): LOG.info('INITIALIZING NAILGUN CONFIG') @@ -425,10 +453,17 @@ class NailgunConfig(object): self._parse_networks_configuration() self.set_endpoints() self.set_proxy() + self._parse_murano_configuration() except Exception, e: LOG.warning('Nailgun config creation failed. ' 'Something wrong with endpoints') + def _parse_murano_configuration(self): + murano_api_url = self.network.raw_data.get('public_vip', None) + if not murano_api_url: + murano_api_url = self.compute.controller_nodes[0] + self.murano.api_url = 'http://{0}:8082'.format(murano_api_url) + def _parse_cluster_attributes(self): api_url = '/api/clusters/%s/attributes' % self.cluster_id response = self.req_session.get(self.nailgun_url + api_url) diff --git a/fuel_health/heatmanager.py b/fuel_health/heatmanager.py index 71ace529..788cc4a5 100644 --- a/fuel_health/heatmanager.py +++ b/fuel_health/heatmanager.py @@ -18,48 +18,13 @@ import logging -LOG = logging.getLogger(__name__) - - -try: - import heatclient.v1.client -except: - LOG.warning('Heatclient could not be imported.') from fuel_health.common.utils.data_utils import rand_name from fuel_health import config import fuel_health.nmanager import fuel_health.test -class HeatManager(fuel_health.nmanager.OfficialClientManager): - """ - HeatManager provides access to the official python client of Heat. - """ - - def __init__(self): - super(HeatManager, self).__init__() - self.heat_client = self._get_heat_client() - self.client_attr_names.append('heat_client') - - def _get_heat_client(self, username=None, password=None): - keystone = self._get_identity_client() - token = keystone.auth_token - auth_url = self.config.identity.uri - - if 'orchestration' not in [s.type for s in keystone.services.list()]: - return None - - endpoint = keystone.service_catalog.url_for( - service_type='orchestration', endpoint_type='publicURL') - if not username: - username = self.config.identity.admin_username - if not password: - password = self.config.identity.admin_password - - return heatclient.v1.client.Client(endpoint, - auth_url=auth_url, token=token, - username=username, - password=password) +LOG = logging.getLogger(__name__) class HeatBaseTest(fuel_health.nmanager.OfficialClientTest): @@ -67,8 +32,6 @@ class HeatBaseTest(fuel_health.nmanager.OfficialClientTest): Base class for Heat openstack sanity and smoke tests. """ - manager_class = HeatManager - simple_template = """ { "AWSTemplateFormatVersion": "2010-09-09", diff --git a/fuel_health/murano.py b/fuel_health/murano.py new file mode 100644 index 00000000..ede9e51a --- /dev/null +++ b/fuel_health/murano.py @@ -0,0 +1,263 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 Mirantis, Inc. +# 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. + +import time + +import fuel_health.nmanager + + +class MuranoTest(fuel_health.nmanager.OfficialClientTest): + """ + Manager that provides access to the Murano python client for + calling Murano API. + """ + + def setUp(self): + """ + This method allows to initialize authentication before + each test case and define parameters of Murano API Service + This method also create environment for all tests + """ + + super(MuranoTest, self).setUp() + + if self.murano_client is None: + self.fail('Murano is unavailable.') + + def verify_elements_list(self, elements, attrs, msg='', failed_step=''): + """ + Method provides human readable message for the verification of + list of elements with specific parameters + :param elements: the list of elements from response + :param attrs: required attributes for each element + :param msg: message to be used instead the default one + :param failed_step: step with failed action + """ + if failed_step: + msg = ('Step %s failed: ' % str(failed_step)) + msg + + if not elements: + self.fail(msg) + + for element in elements: + for attribute in attrs: + if not hasattr(element, attribute): + self.fail(msg) + + def is_keypair_available(self, keyname): + return keyname in [k.id for k in self.compute_client.keypairs.list()] + + def list_environments(self): + """ + This method allows to get the list of environments. + + Returns the list of environments. + """ + + return self.murano_client.environments.list() + + def create_environment(self, name): + """ + This method allows to create environment. + + Input parameters: + name - Name of new environment + + Returns new environment. + """ + + return self.murano_client.environments.create(name) + + def get_environment(self, environment_id, session_id=None): + """ + This method allows to get specific environment by ID. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment (optional) + + Returns specific environment. + """ + + return self.murano_client.environments.get(environment_id, session_id) + + def update_environment(self, environment_id, new_name): + """ + This method allows to update specific environment by ID. + + Input parameters: + environment_id - ID of environment + new_name - New name for environment + + Returns new environment. + """ + + return self.murano_client.environments.update(environment_id, new_name) + + def delete_environment(self, environment_id): + """ + This method allows to delete specific environment by ID. + + Input parameters: + environment_id - ID of environment + + Returns None. + """ + + return self.murano_client.environments.delete(environment_id) + + def create_session(self, environment_id): + """ + This method allows to create session for environment. + + Input parameters: + environment_id - ID of environment + + Returns new session. + """ + + return self.murano_client.sessions.configure(environment_id) + + def get_session(self, environment_id, session_id): + """ + This method allows to get specific session. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment + + Returns specific session. + """ + + return self.murano_client.sessions.get(environment_id, session_id) + + def delete_session(self, environment_id, session_id): + """ + This method allows to delete session for environment. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment + + Returns None. + """ + + return self.murano_client.sessions.delete(environment_id, session_id) + + def deploy_session(self, environment_id, session_id): + """ + This method allows to deploy session for environment. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment + + Returns specific session. + """ + + return self.murano_client.sessions.deploy(environment_id, session_id) + + def create_service(self, environment_id, session_id, json_data): + """ + This method allows to create service. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment + json_data - JSON with service description + + Returns specific service. + """ + + return self.murano_client.services.post(environment_id, path='/', + data=json_data, session_id=session_id) + + def list_services(self, environment_id, session_id=None): + """ + This method allows to get list of services. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment (optional) + + Returns list of services. + """ + + return self.murano_client.services.get(environment_id, '/', session_id) + + def get_service(self, environment_id, session_id, service_id): + """ + This method allows to get service by ID. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment + service_id - ID of service in this environment + + Returns specific service. + """ + + return self.murano_client.services.get(environment_id, + '/{0}'.format(service_id), + session_id) + + def delete_service(self, environment_id, session_id, service_id): + """ + This method allows to delete specific service. + + Input parameters: + environment_id - ID of environment + session_id - ID of session for this environment + service_id - ID of service in this environment + + Returns None. + """ + + return self.murano_client.services.delete(environment_id, + '/{0}'.format(service_id), + session_id) + + def deploy_check(self, environment_id): + """ + This method allows to wait for deployment of Murano evironments. + + Input parameters: + environment_id - ID of environment + + Returns 'OK'. + """ + + infa = self.get_environment(environment_id) + while infa.status != 'ready': + time.sleep(15) + infa = self.get_environment(environment_id) + return 'OK' + + def deployments_status_check(self, environment_id): + """ + This method allows to check that deployment status is 'success'. + + Input parameters: + environment_id - ID of environment + + Returns 'OK'. + """ + + deployments = self.murano_client.deployments.list(environment_id) + for depl in deployments: + assert depl.state == 'success' + return 'OK' diff --git a/fuel_health/nmanager.py b/fuel_health/nmanager.py index 019800dd..10ce1fb5 100644 --- a/fuel_health/nmanager.py +++ b/fuel_health/nmanager.py @@ -17,15 +17,24 @@ # under the License. import logging +import time + +LOG = logging.getLogger(__name__) # Default client libs +try: + import heatclient.v1.client +except: + LOG.warning('Heatclient could not be imported.') +try: + import muranoclient.v1.client +except: + LOG.warning('Muranoclient could not be imported.') import cinderclient.client import glanceclient.client import keystoneclient.v2_0.client import novaclient.client -import time - from fuel_health.common.ssh import Client as SSHClient from fuel_health.exceptions import SSHExecCommandFailed from fuel_health.common.utils.data_utils import rand_name @@ -36,9 +45,6 @@ import fuel_health.test from fuel_health import config -LOG = logging.getLogger(__name__) - - class OfficialClientManager(fuel_health.manager.Manager): """ Manager that provides access to the official python clients for @@ -55,12 +61,17 @@ class OfficialClientManager(fuel_health.manager.Manager): self.identity_client = self._get_identity_client() self.network_client = self._get_network_client() self.volume_client = self._get_volume_client() + self.heat_client = self._get_heat_client() + self.murano_client = self._get_murano_client() + self.client_attr_names = [ 'compute_client', 'image_client', 'identity_client', 'network_client', - 'volume_client' + 'volume_client', + 'heat_client', + 'murano_client' ] def _get_compute_client(self, username=None, password=None, @@ -156,6 +167,50 @@ class OfficialClientManager(fuel_health.manager.Manager): return + def _get_heat_client(self, username=None, password=None): + keystone = self._get_identity_client() + token = keystone.auth_token + auth_url = self.config.identity.uri + + if 'orchestration' not in [s.type for s in + keystone.services.list()]: + return None + + endpoint = keystone.service_catalog.url_for( + service_type='orchestration', endpoint_type='publicURL') + if not username: + username = self.config.identity.admin_username + if not password: + password = self.config.identity.admin_password + + return heatclient.v1.client.Client(endpoint, + auth_url=auth_url, token=token, + username=username, + password=password) + + def _get_murano_client(self): + """ + This method returns Murano API client + or None if needed configuration parameters are unavailable. + """ + # Get xAuth token from Keystone + self.token_id = self._get_identity_client( + self.config.identity.admin_username, + self.config.identity.admin_password, + self.config.identity.admin_tenant_name).auth_token + + # Get Murano API parameters + self.api_host = None + self.insecure = False + if hasattr(self.config.murano, 'api_url'): + self.api_host = self.config.murano.api_url + if hasattr(self.config.murano, 'insecure'): + self.insecure = self.config.murano.insecure + + return muranoclient.v1.client.Client(endpoint=self.api_host, + token=self.token_id, + insecure=self.insecure) + class OfficialClientTest(fuel_health.test.TestCase): manager_class = OfficialClientManager diff --git a/fuel_health/tests/heat/__init__.py b/fuel_health/tests/heat/__init__.py deleted file mode 100644 index 30a94d00..00000000 --- a/fuel_health/tests/heat/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Mirantis, Inc. -# -# 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. diff --git a/fuel_health/tests/heat/test_heat_actions.py b/fuel_health/tests/platform_smoke_tests/test_smoke_heat.py similarity index 100% rename from fuel_health/tests/heat/test_heat_actions.py rename to fuel_health/tests/platform_smoke_tests/test_smoke_heat.py diff --git a/fuel_health/tests/platform_smoke_tests/test_smoke_murano.py b/fuel_health/tests/platform_smoke_tests/test_smoke_murano.py new file mode 100644 index 00000000..c7b5155c --- /dev/null +++ b/fuel_health/tests/platform_smoke_tests/test_smoke_murano.py @@ -0,0 +1,582 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 Mirantis, Inc. +# +# 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 fuel_health import murano + + +class MuranoDeploymentSmokeTests(murano.MuranoTest): + """ + TestClass contains verifications of full Murano functionality. + Special requirements: + 1. Murano component should be installed. + 2. Key Pair 'murano-lb-key' + 3. Internet access for virtual machines in OpenStack + 4. Windows image with metadata should be imported. + Correct Metadata for Windows image in Glance: + murano_image_info = {"type":"ws-2012-std", + "title":"Windows Server 2012"} + """ + + def test_check_default_key_pair(self): + """Check Default Key Pair 'murano-lb-key' For Server Farms + Test checks that user has Key Pair 'murano-lb-key'. + Please, see more detailed information in Murano Administrator Guide. + Target component: Murano + + Scenario: + 1. Check that Key Pair 'murano-lb-key' exists. + Duration: 5 s. + """ + + keyname = 'murano-lb-key' + fail_msg = "Key Pair %s does not exist. " % keyname + + self.verify(5, self.is_keypair_available, 1, fail_msg, + "checking if %s keypair is available" % keyname, + keyname) + + def test_check_windows_image_with_murano_tag(self): + """Check Windows Image With Murano Tag + Test checks that user has windows image with murano tag. + Please, see more detailed information in Murano Administrator Guide. + Target component: Murano + + Scenario: + 1. Check that Windows image with Murano tag imported in Glance. + Duration: 5 s. + """ + + exp_key = 'murano_image_info' + exp_value = '{"type":"ws-2012-std","title":"Windows Server 2012"}' + + fail_msg = "Windows image with Murano tag wasn't imported into Glance" + + find_image = lambda k, v: len( + [i for i in self.compute_client.images.list() + if k in i.metadata and v == i.metadata[k]]) > 0 + + self.verify(5, find_image, 1, fail_msg, + "checking if Windows image with Murano tag is available", + exp_key, exp_value) + + def test_deploy_ad(self): + """Check deploy of AD service + Test checks that user can deploy AD. + Target component: Murano + + Scenario: + 1. Send request to create environment. + 2. Send request to create session for environment. + 3. Send request to create service AD. + 4. Request to deploy session. + 5. Checking environment status. + 6. Checking deployments status + 7. Send request to delete environment. + Duration: 120 - 1830 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 2, fail_msg, "session creating", + self.environment.id) + + post_body = {"type": "activeDirectory","name": "ad.local", + "adminPassword": "P@ssw0rd", "domain": "ad.local", + "availabilityZone": "nova", "unitNamingPattern": "", + "flavor": "m1.medium", "osImage": + {"type": "ws-2012-std", "name": "ws-2012-std", "title": + "Windows Server 2012 Standard"},"configuration": + "standalone", "units": [{"isMaster": True, + "recoveryPassword": "P@ssw0rd", + "location": "west-dc"}]} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 3, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 4, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly' + status_env = self.verify(1800, self.deploy_check, + 5, fail_msg, 'deploy is going', + self.environment.id) + + step = '6. Checking deployments status' + deployment_status = self.verify(40, self.deployments_status_check, + step, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 7, fail_msg, "deleting environment", + self.environment.id) + + def test_deploy_iis(self): + """Check deploy of IIS service + Test checks that user can deploy IIS. + Target component: Murano + + Scenario: + 1. Send request to create environment. + 2. Send request to create session for environment. + 3. Send request to create service IIS. + 4. Request to deploy session. + 5. Checking environment status. + 6. Checking deployments status + 7. Send request to delete environment. + Duration: 120 - 1830 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 2, fail_msg, "session creating", + self.environment.id) + + creds = {'username': 'Administrator', + 'password': 'P@ssw0rd'} + post_body = {"type": "webServer", "domain": "", + "availabilityZone": "nova", "name": "someIIS", + "adminPassword": "P@ssw0rd", "unitNamingPattern": "", + "osImage": {"type": "ws-2012-std", + "name": "ws-2012-std", + "title": "Windows Server 2012 Standard"}, + "units": [{}], "credentials": creds, + "flavor": "m1.medium"} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 3, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 4, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly' + status_env = self.verify(1800, self.deploy_check, + 5, fail_msg, 'deploy is going', + self.environment.id) + + step = '6. Checking deployments status' + deployment_status = self.verify(40, self.deployments_status_check, + step, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 7, fail_msg, "deleting environment", + self.environment.id) + + def test_deploy_aspnet(self): + """Check deploy of ASP.NET application service + Test checks that user can deploy ASPNet. + Target component: Murano + + Special requirements: + 1. Internet access for virtual machines in OpenStack + + Scenario: + 1. Send request to create environment. + 2. Send request to create session for environment. + 3. Send request to create service ASPNet. + 4. Request to deploy session. + 5. Checking environment status. + 6. Checking deployments status + 7. Send request to delete environment. + Duration: 120 - 1830 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 2, fail_msg, "session creating", + self.environment.id) + + creds = {'username': 'Administrator', + 'password': 'P@ssw0rd'} + asp_repository = "git://github.com/Mirantis/murano-mvc-demo.git" + post_body = {"type": "aspNetApp", "domain": "", + "availabilityZone": "nova", "name": "someasp", + "repository": asp_repository, + "adminPassword": "P@ssw0rd", "unitNamingPattern": "", + "osImage": {"type": "ws-2012-std", "name": "ws-2012-std", + "title": "Windows Server 2012 Standard"}, + "units": [{}], "credentials": creds, + "flavor": "m1.medium"} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 3, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 4, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly, ' + fail_msg += 'please check that virtual machines have Internet access' + status_env = self.verify(1800, self.deploy_check, + 5, fail_msg, 'deploy is going', + self.environment.id) + + step = '6. Checking deployments status' + deployment_status = self.verify(40, self.deployments_status_check, + step, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 7, fail_msg, "deleting environment", + self.environment.id) + + def test_deploy_iis_farm(self): + """Check deploy of IIS Servers Farm service + Test checks that user can deploy IIS farm. + Target component: Murano + + Special requirements: + 1. Key Pair 'murano-lb-key' + + Scenario: + 1. Send request to create environment. + 2. Send request to create session for environment. + 3. Send request to create service IIS farm. + 4. Request to deploy session. + 5. Checking environment status. + 6. Checking deployments status + 7. Send request to delete environment. + Duration: 120 - 1830 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 2, fail_msg, "session creating", + self.environment.id) + + creds = {'username': 'Administrator', + 'password': 'P@ssw0rd'} + post_body = {"type": "webServerFarm", "domain": "", + "availabilityZone": "nova", "name": "someIISFARM", + "adminPassword": "P@ssw0rd", "loadBalancerPort": 80, + "unitNamingPattern": "", + "osImage": {"type": "ws-2012-std", "name": "ws-2012-std", + "title": "Windows Server 2012 Standard"}, + "units": [{}, {}], + "credentials": creds, "flavor": "m1.medium"} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 3, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 4, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly, ' + fail_msg += 'please check that Key Pair "murano-lb-key" exists' + status_env = self.verify(1800, self.deploy_check, + 5, fail_msg, 'deploy is going', + self.environment.id) + + step = '6. Checking deployments status' + deployment_status = self.verify(40, self.deployments_status_check, + step, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 7, fail_msg, "deleting environment", + self.environment.id) + + def test_deploy_aspnet_farm(self): + """Check deploy of ASP.NET application servers farm service + Test checks that user can deploy ASPNet farm. + Target component: Murano + + Special requirements: + 1. Key Pair 'murano-lb-key' + 2. Internet access for virtual machines in OpenStack + + Scenario: + 1. Send request to create environment. + 2. Send request to create session for environment. + 3. Send request to create service ASPNet farm. + 4. Request to deploy session. + 5. Checking environment status. + 6. Checking deployments status + 7. Send request to delete environment. + Duration: 120 - 1830 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 2, fail_msg, "session creating", + self.environment.id) + + creds = {'username': 'Administrator', + 'password': 'P@ssw0rd'} + asp_repository = "git://github.com/Mirantis/murano-mvc-demo.git" + post_body = {"type": "aspNetAppFarm", "domain": "", + "availabilityZone": "nova", "name": "SomeApsFarm", + "repository": asp_repository, + "adminPassword": "P@ssw0rd", "loadBalancerPort": 80, + "unitNamingPattern": "", + "osImage": {"type": "ws-2012-std", "name": "ws-2012-std", + "title": "Windows Server 2012 Standard"}, + "units": [{}, {}], + "credentials": creds, "flavor": "m1.medium"} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 3, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 4, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly, ' + fail_msg += 'please check, that Key Pair "murano-lb-key" exists ' + fail_msg += 'and virtual machines have Internet access' + status_env = self.verify(1800, self.deploy_check, + 5, fail_msg, 'deploy is going', + self.environment.id) + + step = '6. Checking deployments status' + deployment_status = self.verify(40, self.deployments_status_check, + step, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 7, fail_msg, "deleting environment", + self.environment.id) + + def test_deploy_sql(self): + """Check deploy of SQL service + Test checks that user can deploy SQL. + Target component: Murano + + Scenario: + 1. Send request to create environment. + 2. Send request to create session for environment. + 3. Send request to create service SQL. + 4. Request to deploy session. + 5. Checking environment status. + 6. Checking deployments status + 7. Send request to delete environment. + Duration: 120 - 1830 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 2, fail_msg, "session creating", + self.environment.id) + + post_body = {"type": "msSqlServer", "domain": "", + "availabilityZone": "nova", "name": "SQLSERVER", + "adminPassword": "P@ssw0rd", "unitNamingPattern": "", + "saPassword": "P@ssw0rd", "mixedModeAuth": "true", + "osImage": {"type": "ws-2012-std", "name": "ws-2012-std", + "title": "Windows Server 2012 Standard"},"units": [{}], + "credentials": {"username": "Administrator", + "password": "P@ssw0rd"}, "flavor": "m1.medium"} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 3, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 4, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly' + status_env = self.verify(1800, self.deploy_check, + 5, fail_msg, 'deploy is going', + self.environment.id) + + step = '6. Checking deployments status' + deployment_status = self.verify(40, self.deployments_status_check, + step, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 7, fail_msg, "deleting environment", + self.environment.id) + + def test_deploy_sql_cluster(self): + """Check deploy of SQL Cluster service + Test checks that user can deploy SQL Cluster. + Target component: Murano + + Scenario: + 1. Send request to create environment. + 2. Send request to create session for environment. + 3. Send request to create service AD. + 4. Request to deploy session. + 5. Checking environment status. + 6. Checking deployments status. + 7. Send request to create session for environment. + 8. Send request to create service SQL cluster. + 9. Request to deploy session.. + 10. Checking environment status. + 11. Checking deployments status. + 12. Send request to delete environment. + Duration: 200 - 2200 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 2, fail_msg, "session creating", + self.environment.id) + + post_body = {"type": "activeDirectory","name": "ad.local", + "adminPassword": "P@ssw0rd", "domain": "ad.local", + "availabilityZone": "nova", "unitNamingPattern": "", + "flavor": "m1.medium", "osImage": + {"type": "ws-2012-std", "name": "ws-2012-std", "title": + "Windows Server 2012 Standard"},"configuration": + "standalone", "units": [{"isMaster": True, + "recoveryPassword": "P@ssw0rd", + "location": "west-dc"}]} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 3, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 4, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly' + status_env = self.verify(1800, self.deploy_check, + 5, fail_msg, 'deploy is going', + self.environment.id) + + deployment_status = self.verify(40, self.deployments_status_check, + 6, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'User can not create session for environment.' + session = self.verify(5, self.create_session, + 7, fail_msg, "session creating", + self.environment.id) + + # it is just 'any unused IP addresses' + AG = self.config.murano.agListnerIP + clIP = self.config.murano.clusterIP + + post_body = {"domain": "ad.local", "domainAdminPassword": "P@ssw0rd", + "externalAD": False, + "sqlServiceUserName": "Administrator", + "sqlServicePassword": "P@ssw0rd", + "osImage": {"type": "ws-2012-std", "name": "ws-2012-std", + "title": "Windows Server 2012 Standard"}, + "agListenerName": "SomeSQL_AGListner", + "flavor": "m1.medium", + "agGroupName": "SomeSQL_AG", + "domainAdminUserName": "Administrator", + "agListenerIP": AG, + "clusterIP": clIP, + "type": "msSqlClusterServer", "availabilityZone": "nova", + "adminPassword": "P@ssw0rd", + "clusterName": "SomeSQL", "mixedModeAuth": True, + "unitNamingPattern": "", "units": [{"isMaster": True, + "name": "node1", "isSync": True}, {"isMaster": False, + "name": "node2", "isSync": True}], + "name": "Sqlname", "saPassword": "P@ssw0rd", + "databases": ['murano', 'test']} + + fail_msg = 'User can not create service.' + service = self.verify(5, self.create_service, + 8, fail_msg, "service creating", + self.environment.id, session.id, post_body) + + fail_msg = 'User can not deploy session' + deploy_sess = self.verify(10, self.deploy_session, + 9, fail_msg, "session send on deploy", + self.environment.id, session.id) + + fail_msg = 'Deploy did not complete correctly' + status_env = self.verify(1800, self.deploy_check, + 10, fail_msg, 'deploy is going', + self.environment.id) + + step = '11. Checking deployments status' + deployment_status = self.verify(40, self.deployments_status_check, + step, fail_msg, + 'Check deployments status', + self.environment.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 12, fail_msg, "deleting environment", + self.environment.id) diff --git a/fuel_health/tests/sanity/test_sanity_murano.py b/fuel_health/tests/sanity/test_sanity_murano.py new file mode 100644 index 00000000..8e589327 --- /dev/null +++ b/fuel_health/tests/sanity/test_sanity_murano.py @@ -0,0 +1,85 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 Mirantis, Inc. +# +# 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 fuel_health import murano + + +class MuranoSanityTests(murano.MuranoTest): + """ + TestClass contains verifications of basic Murano functionality. + Special requirements: + 1. Murano component should be installed. + """ + + def test_create_and_delete_service(self): + """Murano environment and service creation, listing and deletion + Test checks if it's possible to create and delete service. + Target component: Murano + + Scenario: + 1. Send request to create environment. + 2. Request the list of environments. + 3. Send request to create session for environment. + 4. Send request to create service. + 5. Request the list of services. + 6. Send request to delete service. + 7. Send request to delete environment. + Duration: 35 s. + """ + + fail_msg = 'Cannot create environment.' + self.environment = self.verify(5, self.create_environment, + 1, fail_msg, 'creating environment', + "ost1_test-Murano_env01") + + fail_msg = 'Environments list is unavailable.' + environments = self.verify(5, self.list_environments, + 2, fail_msg, "listing environments") + + step = '2. Request the list of environments.' + self.verify_elements_list(environments, ['id', 'name'], + msg=fail_msg, failed_step=step) + + fail_msg = 'Cannot create session for environment.' + session = self.verify(5, self.create_session, + 3, fail_msg, "creating session", + self.environment.id) + + srv = {"name": "new_service", "type": "test", "units": [{},]} + fail_msg = 'Cannot create service.' + service = self.verify(5, self.create_service, + 4, fail_msg, "creating service", + self.environment.id, session.id, srv) + + step = '4. Request the list of services.' + fail_msg = 'Cannot get list of services.' + services = self.verify(5, self.list_services, + 5, fail_msg, "listing services", + self.environment.id, session.id) + + self.verify_elements_list(services, ['id', 'name'], + msg='Cannot get list of services', + failed_step=step) + + fail_msg = 'Cannot delete service.' + self.verify(5, self.delete_service, + 6, fail_msg, "deleting service", + self.environment.id, session.id, service.id) + + fail_msg = 'Cannot delete environment.' + self.verify(5, self.delete_environment, + 7, fail_msg, "deleting environment", + self.environment.id) diff --git a/setup.py b/setup.py index b3bf9003..1a26498e 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,7 @@ fuel_health_reqs = [ 'python-keystoneclient==0.3.1', 'python-novaclient==2.13.0', 'python-heatclient==0.2.4', + 'python-muranoclient==0.2', 'python-savannaclient>=0.2.2', 'paramiko>=1.10.1', 'requests>=1.1,<1.2.3',