Merge "Support murano plugin installation in OSTF tests"

This commit is contained in:
Jenkins 2016-06-10 15:35:53 +00:00 committed by Gerrit Code Review
commit de2d8fa1ea
7 changed files with 442 additions and 48 deletions

View File

@ -401,61 +401,65 @@ class MuranoTest(fuel_health.nmanager.PlatformServicesBaseClass):
if inst_name in service['instance']['name']: if inst_name in service['instance']['name']:
return service['instance']['floatingIpAddress'] return service['instance']['floatingIpAddress']
def get_list_packages(self): def get_list_packages(self, artifacts=False):
try: try:
packages = self.murano_client.packages.list() if artifacts:
packages_list = self.murano_art_client.packages.list()
packages = []
for package in packages_list:
packages.append(package)
else:
packages_list = self.murano_client.packages.list()
packages = list(packages_list)
except exceptions.ClientException: except exceptions.ClientException:
self.fail("Can not get list of packages") self.fail("Can not get list of packages")
packages_list = list(packages) LOG.debug('Packages List: {0}'.format(packages))
LOG.debug('Packages List: {0}'.format(packages_list)) self.assertIsInstance(packages, list)
self.assertIsInstance(packages_list, list) return packages
return packages_list
def generate_fqn_list(self): def generate_fqn_list(self, artifacts=False):
fqn_list = [] fqn_list = []
packages = self.get_list_packages() packages = self.get_list_packages(artifacts)
for package in packages: for package in packages:
fqn_list.append(package.to_dict()['fully_qualified_name']) fqn_list.append(package.to_dict()['fully_qualified_name'])
LOG.debug('FQN List: {0}'.format(fqn_list)) LOG.debug('FQN List: {0}'.format(fqn_list))
return fqn_list return fqn_list
def upload_package(self, package_name, body, app): def upload_package(self, package_name, body, app, artifacts=False):
files = {'%s' % package_name: open(app, 'rb')} files = {'%s' % package_name: open(app, 'rb')}
package = self.murano_client.packages.create(body, files) if artifacts:
package = self.murano_art_client.packages.create(body, files)
else:
package = self.murano_client.packages.create(body, files)
self.packages.append(package) self.packages.append(package)
return package return package
def package_exists(self, *packages): def package_exists(self, artifacts=False, *packages):
fqn_list = self.generate_fqn_list() fqn_list = self.generate_fqn_list(artifacts)
LOG.debug("Response for packages is {0}".format(fqn_list)) LOG.debug("Response for packages is {0}".format(fqn_list))
for package in packages: for package in packages:
if package not in fqn_list: if package not in fqn_list:
return False return False
return True return True
def get_package(self, package_id): def get_package(self, package_id, artifacts=False):
resp = requests.get(self.endpoint + 'catalog/packages/{0}'. if artifacts:
format(package_id), headers=self.headers, package = self.murano_art_client.packages.get(package_id)
verify=False) else:
self.assertEqual(200, resp.status_code) package = self.murano_client.packages.get(package_id)
return resp.json() return package
def get_package_by_fqdn(self, package_name): def get_package_by_fqdn(self, package_name, artifacts=False):
resp = requests.get(self.endpoint + 'catalog/packages', package_list = self.get_list_packages(artifacts)
headers=self.headers, verify=False) for package in package_list:
for package in resp.json()["packages"]: if package.to_dict()["fully_qualified_name"] == package_name:
if package["fully_qualified_name"] == package_name:
return package return package
def delete_package(self, package_id): def delete_package(self, package_id, artifacts=False):
resp = requests.delete(self.endpoint + 'catalog/packages/{0}'. if artifacts:
format(package_id), headers=self.headers, self.murano_art_client.packages.delete(package_id)
verify=False) else:
try: self.murano_client.packages.delete(package_id)
self.assertEqual(200, resp.status_code)
except Exception:
self.assertEqual(404, resp.status_code)
LOG.debug("Package not exists.")
def get_list_categories(self): def get_list_categories(self):
resp = requests.get(self.endpoint + 'catalog/packages/categories', resp = requests.get(self.endpoint + 'catalog/packages/categories',

View File

@ -58,6 +58,11 @@ try:
except Exception: except Exception:
LOG.exception() LOG.exception()
LOG.warning('Ironic client could not be imported') LOG.warning('Ironic client could not be imported')
try:
import muranoclient.glance.client as art_client
except Exception:
LOG.exception()
LOG.warning('Artifacts client could not be imported')
import aodhclient.client import aodhclient.client
import cinderclient.client import cinderclient.client
@ -116,6 +121,8 @@ class OfficialClientManager(fuel_health.manager.Manager):
self.glance_client_v1 = self._get_glance_client(version=1) self.glance_client_v1 = self._get_glance_client(version=1)
self.ironic_client = self._get_ironic_client() self.ironic_client = self._get_ironic_client()
self.aodh_client = self._get_aodh_client() self.aodh_client = self._get_aodh_client()
self.artifacts_client = self._get_artifacts_client()
self.murano_art_client = self._get_murano_client(artifacts=True)
self.client_attr_names = [ self.client_attr_names = [
'compute_client', 'compute_client',
'identity_client', 'identity_client',
@ -129,7 +136,9 @@ class OfficialClientManager(fuel_health.manager.Manager):
'ceilometer_client', 'ceilometer_client',
'neutron_client', 'neutron_client',
'ironic_client', 'ironic_client',
'aodh_client' 'aodh_client',
'artifacts_client',
'murano_art_client'
] ]
def _get_compute_client(self, username=None, password=None, def _get_compute_client(self, username=None, password=None,
@ -264,7 +273,7 @@ class OfficialClientManager(fuel_health.manager.Manager):
token=token, token=token,
insecure=True) insecure=True)
def _get_murano_client(self): def _get_murano_client(self, artifacts=False):
"""This method returns Murano API client """This method returns Murano API client
""" """
keystone = self._get_identity_client( keystone = self._get_identity_client(
@ -283,10 +292,16 @@ class OfficialClientManager(fuel_health.manager.Manager):
'not found. Murano client cannot be initialized.') 'not found. Murano client cannot be initialized.')
return return
return muranoclient.v1.client.Client( if artifacts:
endpoint, return muranoclient.v1.client.Client(
token=self.token_id, endpoint,
insecure=True) token=self.token_id,
insecure=True, artifacts_client=self.artifacts_client)
else:
return muranoclient.v1.client.Client(
endpoint,
token=self.token_id,
insecure=True)
def _get_sahara_client(self): def _get_sahara_client(self):
sahara_api_version = self.config.sahara.api_version sahara_api_version = self.config.sahara.api_version
@ -351,6 +366,21 @@ class OfficialClientManager(fuel_health.manager.Manager):
os_auth_token=keystone.auth_token, os_auth_token=keystone.auth_token,
ironic_url=endpoint, insecure=True) ironic_url=endpoint, insecure=True)
def _get_artifacts_client(self, version='1'):
keystone = self._get_identity_client()
try:
endpoint = keystone.service_catalog.url_for(
service_type='artifact',
endpoint_type='publicURL')
except keystoneclient.exceptions.EndpointNotFound:
LOG.warning('Can not initialize artifacts client')
return None
return art_client.Client(endpoint=endpoint,
type_name='murano',
type_version=version,
token=keystone.auth_token,
insecure=True)
def _get_aodh_client(self, version='2'): def _get_aodh_client(self, version='2'):
username = self.config.identity.admin_username username = self.config.identity.admin_username
password = self.config.identity.admin_password password = self.config.identity.admin_password

View File

@ -33,7 +33,7 @@ class MuranoSanityTests(muranomanager.MuranoTest):
Duration: 10 s. Duration: 10 s.
Deployment tags: Murano Deployment tags: Murano | murano_plugin
""" """
fail_msg = "Can't create environment. Murano API isn't available. " fail_msg = "Can't create environment. Murano API isn't available. "
@ -55,7 +55,7 @@ class MuranoSanityTests(muranomanager.MuranoTest):
Duration: 10 s. Duration: 10 s.
Deployment tags: Murano Deployment tags: Murano | murano_plugin
""" """
fail_msg = "Can't get list of categories. Murano API isn't available. " fail_msg = "Can't get list of categories. Murano API isn't available. "
self.verify(10, self.get_list_categories, 1, fail_msg, self.verify(10, self.get_list_categories, 1, fail_msg,
@ -70,8 +70,23 @@ class MuranoSanityTests(muranomanager.MuranoTest):
Duration: 10 s. Duration: 10 s.
Deployment tags: Murano Deployment tags: Murano | murano_plugin, murano_without_glare
""" """
fail_msg = "Can't get list of packages. Murano API isn't available. " fail_msg = "Can't get list of packages. Murano API isn't available. "
self.verify(10, self.get_list_packages, 1, fail_msg, self.verify(10, self.get_list_packages, 1, fail_msg,
"getting list of packages") "getting list of packages")
def test_get_list_artifacts_packages(self):
"""Get list of Murano Artifact applications packages
Target component: Murano
Scenario:
1. Send request to get list of artifact packages
Duration: 10 s.
Deployment tags: Murano | murano_plugin, murano_use_glare
"""
fail_msg = "Can't get list of packages. Murano API isn't available. "
self.verify(10, self.get_list_packages, 1, fail_msg,
"getting list of packages", artifacts=True)

View File

@ -43,7 +43,7 @@ class MuranoDeployLinuxServicesTests(muranomanager.MuranoTest):
self.dummy_fqdn = 'io.murano.apps.Simple' self.dummy_fqdn = 'io.murano.apps.Simple'
# Flavor with 2 vCPU and 40Gb HDD will allow to sucessfully # Flavor with 2 vCPU and 40Gb HDD will allow to successfully
# deploy all Murano applications. # deploy all Murano applications.
self.flavor_name = rand_name("ostf_test_Murano_flavor") self.flavor_name = rand_name("ostf_test_Murano_flavor")
flavor = self.compute_client.flavors.create( flavor = self.compute_client.flavors.create(
@ -70,7 +70,7 @@ class MuranoDeployLinuxServicesTests(muranomanager.MuranoTest):
10. Send request to delete package. 10. Send request to delete package.
Duration: 1200 s. Duration: 1200 s.
Deployment tags: Murano, Heat Deployment tags: Murano | murano_plugin, murano_without_glare
Available since release: 2014.2-6.1 Available since release: 2014.2-6.1
""" """
@ -163,6 +163,116 @@ class MuranoDeployLinuxServicesTests(muranomanager.MuranoTest):
self.verify(5, self.delete_package, 10, fail_msg, "deleting_package", self.verify(5, self.delete_package, 10, fail_msg, "deleting_package",
self.package.id) self.package.id)
def test_deploy_dummy_app_with_glare(self):
"""Check application deployment in Murano environment with GLARE
Target component: Murano
Scenario:
1. Prepare test app.
2. Upload test app.
3. Send request to create environment.
4. Send request to create session for environment.
5. Send request to create test service.
6. Send request to deploy session.
7. Checking environment status.
8. Checking deployment status.
9. Send request to delete environment.
10. Send request to delete package.
Duration: 1200 s.
Deployment tags: Murano | murano_plugin, murano_use_glare
Available since release: 2014.2-6.1
"""
artifacts = True
vms_count = self.get_info_about_available_resources(
self.min_required_ram_mb, 40, 2)
if vms_count < 1:
msg = ('This test requires more hardware resources of your '
'OpenStack cluster: your cloud should allow to create '
'at least 1 VM with {0} MB of RAM, {1} HDD and {2} vCPUs. '
'You need to remove some resources or add compute nodes '
'to have an ability to run this OSTF test.'
.format(self.min_required_ram_mb, 40, 2))
LOG.debug(msg)
self.skipTest(msg)
if self.package_exists(artifacts, self.dummy_fqdn):
package = self.get_package_by_fqdn(self.dummy_fqdn, artifacts)
self.delete_package(package.to_dict()["id"], artifacts)
fail_msg = ("Package preparation failed. Please refer to "
"OSTF logs for more information")
zip_path = self.verify(10, self.zip_dir, 1, fail_msg,
'prepare package',
os.path.dirname(__file__), self.dummy_fqdn)
fail_msg = ("Package uploading failed. "
"Please refer to Openstack and OSTF logs")
self.package = self.verify(10, self.upload_package, 2, fail_msg,
'uploading package', 'SimpleApp',
{"categories": ["Web"], "tags": ["tag"]},
zip_path, artifacts)
fail_msg = "Can't create environment. Murano API is not available. "
self.environment = self.verify(15, self.create_environment,
3, fail_msg, 'creating environment',
self.env_name)
fail_msg = "User can't create session for environment. "
session = self.verify(5, self.create_session,
4, fail_msg, "session creating",
self.environment.id)
post_body = {
"instance": {
"flavor": self.flavor_name,
"image": "TestVM",
"assignFloatingIp": True,
"?": {
"type": "io.murano.resources.LinuxMuranoInstance",
"id": str(uuid.uuid4())
},
"name": rand_name("testMurano")
},
"name": rand_name("teMurano"),
"?": {
"_{id}".format(id=uuid.uuid4().hex): {
"name": "SimpleApp"
},
"type": self.dummy_fqdn,
"id": str(uuid.uuid4())
}
}
fail_msg = "User can't create service. "
self.verify(5, self.create_service,
5, fail_msg, "service creating",
self.environment.id, session.id, post_body)
fail_msg = "User can't deploy session. "
self.verify(5, self.deploy_session,
6, fail_msg,
"sending session on deployment",
self.environment.id, session.id)
fail_msg = "Deployment was not completed correctly. "
self.verify(860, self.deploy_check,
7, fail_msg, 'deployment is going',
self.environment)
self.verify(5, self.deployments_status_check, 8, fail_msg,
'Check deployments status',
self.environment.id)
fail_msg = "Can't delete environment. "
self.verify(60, self.environment_delete_check,
9, fail_msg, "deleting environment",
self.environment.id)
fail_msg = "Can't delete package"
self.verify(5, self.delete_package, 10, fail_msg, "deleting_package",
self.package.id, artifacts)
def test_deploy_apache_service(self): def test_deploy_apache_service(self):
"""Check that user can deploy Apache service in Murano environment """Check that user can deploy Apache service in Murano environment
Target component: Murano Target component: Murano
@ -178,7 +288,7 @@ class MuranoDeployLinuxServicesTests(muranomanager.MuranoTest):
8. Send request to delete environment. 8. Send request to delete environment.
Duration: 2140 s. Duration: 2140 s.
Deployment tags: Murano, Heat Deployment tags: Murano | murano_plugin, murano_without_artifacts
Available since release: 2014.2-6.0 Available since release: 2014.2-6.0
""" """
@ -287,7 +397,7 @@ class MuranoDeployLinuxServicesTests(muranomanager.MuranoTest):
11. Send request to delete environment. 11. Send request to delete environment.
Duration: 2140 s. Duration: 2140 s.
Deployment tags: Murano, Heat Deployment tags: Murano | murano_plugin, murano_without_artifacts
Available since release: 2014.2-6.1 Available since release: 2014.2-6.1
""" """

View File

@ -30,10 +30,8 @@ from sqlalchemy.orm import joinedload
from fuel_plugin.ostf_adapter.nose_plugin import nose_utils from fuel_plugin.ostf_adapter.nose_plugin import nose_utils
from fuel_plugin.ostf_adapter.storage import models from fuel_plugin.ostf_adapter.storage import models
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
TEST_REPOSITORY = [] TEST_REPOSITORY = []
# TODO(ikutukov): remove hardcoded Nailgun API urls here and below # TODO(ikutukov): remove hardcoded Nailgun API urls here and below
NAILGUN_VERSION_API_URL = 'http://{0}:{1}/api/v1/version' NAILGUN_VERSION_API_URL = 'http://{0}:{1}/api/v1/version'
@ -242,6 +240,33 @@ def _get_cluster_attrs(cluster_id, token=None):
for comp in comp_names: for comp in comp_names:
processor(comp) processor(comp)
# TODO(freerunner): Rework murano part after removal murano from the box
murano_settings = response['editable'].get('murano_settings', None)
# NOTE(freerunner): Murano settings appears only if murano enabled
murano_artifacts = None
if murano_settings:
murano_artifacts = (murano_settings
['murano_glance_artifacts_plugin']['value'])
detach_murano = response['editable'].get('detach-murano', None)
murano_plugin_enabled = None
if detach_murano:
murano_plugin_enabled = detach_murano['metadata'].get('enabled', None)
if murano_plugin_enabled:
additional_depl_tags.add('murano_plugin')
# TODO(freerunner): Rework GLARE discover mechanism after
# TODO(freerunner): removal murano from the box
if murano_artifacts:
additional_depl_tags.add('murano_use_glare')
# NOTE(freerunner): Murano plugin will always support only one version
elif detach_murano and murano_plugin_enabled and (
detach_murano['metadata']['versions'][0]
['murano_glance_artifacts'].get('value', None)):
additional_depl_tags.add('murano_use_glare')
# NOTE(freerunner): Set this tag only if murano is present
elif murano_plugin_enabled or murano_settings:
additional_depl_tags.add('murano_without_glare')
storage_components = response['editable'].get('storage', dict()) storage_components = response['editable'].get('storage', dict())
storage_comp = ['volumes_ceph', 'images_ceph', 'ephemeral_ceph', storage_comp = ['volumes_ceph', 'images_ceph', 'ephemeral_ceph',

View File

@ -236,7 +236,121 @@ CLUSTERS = {
'common': {} 'common': {}
} }
} }
} },
9: {
'cluster_meta': {
'release_id': 9,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'detach-murano': {
'metadata': {
'enabled': True,
'versions': [
{
'murano_glance_artifacts': {
"value": True
}
}
]
}
},
'additional_components': {},
'common': {}
}
}
},
10: {
'cluster_meta': {
'release_id': 10,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'detach-murano': {
'metadata': {
'enabled': True,
'versions': [
{
'murano_glance_artifacts': {
"value": False
}
}
]
}
},
'additional_components': {},
'common': {}
}
}
},
11: {
'cluster_meta': {
'release_id': 11,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {
'murano': {
'value': True
}
},
'murano_settings': {
'murano_glance_artifacts_plugin': {
'value': True
}
},
'common': {}
}
}
},
12: {
'cluster_meta': {
'release_id': 12,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {
'murano': {
'value': True
}
},
'murano_settings': {
'murano_glance_artifacts_plugin': {
'value': False
}
},
'common': {}
}
}
},
} }

View File

@ -108,3 +108,99 @@ class TestDeplTagsGetter(base.BaseUnitTest):
res = mixins._get_cluster_attrs(expected['cluster_id']) res = mixins._get_cluster_attrs(expected['cluster_id'])
self.assertEqual(res, expected['attrs']) self.assertEqual(res, expected['attrs'])
class TestDeplMuranoTags(base.BaseUnitTest):
def setUp(self):
config.init_config([])
self.expected = {
'attrs': {
'deployment_tags': set(
['multinode', 'ubuntu', 'additional_components',
'nova_network', 'public_on_all_nodes',
'enable_without_ceph', 'computes_without_dpdk']),
'release_version': '2016.1-9.0'
}
}
def test_get_murano_plugin_tags_with_artifacts(self):
expected = self.expected
expected['cluster_id'] = 9
expected['attrs']['deployment_tags'].add('murano_plugin')
expected['attrs']['deployment_tags'].add('murano_use_glare')
with requests_mock.Mocker() as m:
cluster = base.CLUSTERS[expected['cluster_id']]
m.register_uri('GET', '/api/clusters/9',
json=cluster['cluster_meta'])
m.register_uri('GET', '/api/clusters/9/attributes',
json=cluster['cluster_attributes'])
m.register_uri('GET', '/api/releases/9',
json=cluster['release_data'])
m.register_uri('GET', '/api/nodes?cluster_id=9',
json=cluster['cluster_node'])
res = mixins._get_cluster_attrs(expected['cluster_id'])
self.assertEqual(res, expected['attrs'])
def test_get_murano_plugin_tags_without_artifacts(self):
expected = self.expected
expected['cluster_id'] = 10
expected['attrs']['deployment_tags'].add('murano_plugin')
expected['attrs']['deployment_tags'].add('murano_without_glare')
with requests_mock.Mocker() as m:
cluster = base.CLUSTERS[expected['cluster_id']]
m.register_uri('GET', '/api/clusters/10',
json=cluster['cluster_meta'])
m.register_uri('GET', '/api/clusters/10/attributes',
json=cluster['cluster_attributes'])
m.register_uri('GET', '/api/releases/10',
json=cluster['release_data'])
m.register_uri('GET', '/api/nodes?cluster_id=10',
json=cluster['cluster_node'])
res = mixins._get_cluster_attrs(expected['cluster_id'])
self.assertEqual(res, expected['attrs'])
def test_get_murano_tags_with_artifacts(self):
expected = self.expected
expected['cluster_id'] = 11
expected['attrs']['deployment_tags'].add('murano')
expected['attrs']['deployment_tags'].add('murano_use_glare')
with requests_mock.Mocker() as m:
cluster = base.CLUSTERS[expected['cluster_id']]
m.register_uri('GET', '/api/clusters/11',
json=cluster['cluster_meta'])
m.register_uri('GET', '/api/clusters/11/attributes',
json=cluster['cluster_attributes'])
m.register_uri('GET', '/api/releases/11',
json=cluster['release_data'])
m.register_uri('GET', '/api/nodes?cluster_id=11',
json=cluster['cluster_node'])
res = mixins._get_cluster_attrs(expected['cluster_id'])
self.assertEqual(res, expected['attrs'])
def test_get_murano_tags_without_artifacts(self):
expected = self.expected
expected['cluster_id'] = 12
expected['attrs']['deployment_tags'].add('murano')
expected['attrs']['deployment_tags'].add('murano_without_glare')
with requests_mock.Mocker() as m:
cluster = base.CLUSTERS[expected['cluster_id']]
m.register_uri('GET', '/api/clusters/12',
json=cluster['cluster_meta'])
m.register_uri('GET', '/api/clusters/12/attributes',
json=cluster['cluster_attributes'])
m.register_uri('GET', '/api/releases/12',
json=cluster['release_data'])
m.register_uri('GET', '/api/nodes?cluster_id=12',
json=cluster['cluster_node'])
res = mixins._get_cluster_attrs(expected['cluster_id'])
self.assertEqual(res, expected['attrs'])