murano/murano_tempest_tests/tests/scenario/application_catalog/base.py

407 lines
16 KiB
Python

# Copyright (c) 2016 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 requests
import socket
import time
from tempest.clients import Manager as services_manager
from tempest.common import credentials_factory as common_creds
from tempest.common import waiters
from tempest import config
from tempest.lib import exceptions
from tempest.services import orchestration
from tempest import test
from murano_tempest_tests import clients
from murano_tempest_tests import utils
CONF = config.CONF
class BaseApplicationCatalogScenarioTest(test.BaseTestCase):
"""Base test class for Murano Application Catalog Scenario tests."""
@classmethod
def skip_checks(cls):
super(BaseApplicationCatalogScenarioTest, cls).skip_checks()
if not CONF.service_available.murano:
skip_msg = "Murano is disabled"
raise cls.skipException(skip_msg)
@classmethod
def setup_clients(cls):
super(BaseApplicationCatalogScenarioTest, cls).setup_clients()
if not hasattr(cls, "os_primary"):
creds = cls.get_configured_isolated_creds(type_of_creds='primary')
cls.os_primary = clients.Manager(credentials=creds)
cls.services_manager = services_manager(creds)
cls.application_catalog_client = \
cls.os_primary.application_catalog_client
cls.artifacts_client = cls.os_primary.artifacts_client
cls.servers_client = cls.services_manager.servers_client
# NOTE(andreaf) The orchestration client is not initialised in Tempest
# by default anymore.
params = config.service_client_config('orchestration')
cls.orchestration_client = orchestration.OrchestrationClient(
cls.services_manager.auth_provider, **params)
cls.images_client = cls.services_manager.image_client_v2
@classmethod
def resource_setup(cls):
super(BaseApplicationCatalogScenarioTest, cls).resource_setup()
cls.linux_image = CONF.application_catalog.linux_image
cls.cirros_image = cls.get_required_image_name()
@classmethod
def get_client_with_isolated_creds(cls, type_of_creds="admin"):
creds = cls.get_configured_isolated_creds(type_of_creds=type_of_creds)
os = clients.Manager(credentials=creds)
client = os.application_catalog_client
return client
@classmethod
def get_configured_isolated_creds(cls, type_of_creds='admin'):
identity_version = CONF.identity.auth_version
if identity_version == 'v3':
cls.admin_role = CONF.identity.admin_role
else:
cls.admin_role = 'admin'
cls.credentials = common_creds.get_credentials_provider(
name=cls.__name__,
force_tenant_isolation=CONF.auth.use_dynamic_credentials,
identity_version=CONF.identity.auth_version)
if type_of_creds == 'primary':
creds = cls.credentials.get_primary_creds()
elif type_of_creds == 'admin':
creds = cls.credentials.get_admin_creds()
elif type_of_creds == 'alt':
creds = cls.credentials.get_alt_creds()
else:
creds = cls.credentials.get_credentials(type_of_creds)
cls.credentials.type_of_creds = type_of_creds
return creds.credentials
@classmethod
def get_required_image_name(cls):
image = cls.images_client.show_image(CONF.compute.image_ref)
return image['name']
def environment_delete(self, environment_id, timeout=180):
self.application_catalog_client.delete_environment(environment_id)
start_time = time.time()
while time.time() - start_time > timeout:
try:
self.application_catalog_client.get_environment(environment_id)
except exceptions.NotFound:
return
@classmethod
def purge_stacks(cls):
stacks = cls.orchestration_client.list_stacks()['stacks']
for stack in stacks:
cls.orchestration_client.delete_stack(stack['id'])
cls.orchestration_client.wait_for_stack_status(stack['id'],
'DELETE_COMPLETE')
def get_service(self, environment, session, service_name):
for service in self.application_catalog_client.get_services_list(
environment, session):
if service['name'] == service_name:
return service
def get_stack_id(self, environment_id):
stacks = self.orchestration_client.list_stacks()['stacks']
for stack in stacks:
if environment_id in self.orchestration_client.show_stack(
stack['id'])['stack']['description']:
return stack['id']
def get_stack_template(self, stack):
return self.orchestration_client.show_template(stack)
def get_instance_id(self, name):
instance_list = self.servers_client.list_servers()['servers']
for instance in instance_list:
if name in instance['name']:
return instance['id']
def apache(
self, attributes=None, userName=None, flavor='m1.tiny'):
post_body = {
"instance": {
"flavor": flavor,
"image": self.linux_image,
"assignFloatingIp": True,
"availabilityZone": "nova",
"volumes": attributes,
"?": {
"type": "io.murano.resources.LinuxMuranoInstance",
"id": utils.generate_uuid()
},
"name": utils.generate_name("testMurano")
},
"name": utils.generate_name("ApacheHTTPServer"),
"userName": userName,
"?": {
"_{id}".format(id=utils.generate_uuid()): {
"name": "ApacheHTTPServer"
},
"type": "io.murano.apps.test.ApacheHttpServerCustom",
"id": utils.generate_uuid()
}
}
return post_body
def vm_cinder(
self, attributes=None, userName=None, flavor='m1.tiny'):
post_body = {
"instance": {
"flavor": flavor,
"image": self.cirros_image,
"assignFloatingIp": True,
"availabilityZone": "nova",
"volumes": attributes,
"?": {
"type": "io.murano.resources.LinuxMuranoInstance",
"id": utils.generate_uuid()
},
"name": utils.generate_name("testMurano")
},
"name": utils.generate_name("VM"),
"userName": userName,
"?": {
"_{id}".format(id=utils.generate_uuid()): {
"name": "VM"
},
"type": "io.murano.apps.test.VM",
"id": utils.generate_uuid()
}
}
return post_body
def vm_test(self, **kwargs):
instance = {
"flavor": "m1.tiny",
"image": self.cirros_image,
"assignFloatingIp": True,
"availabilityZone": "nova",
"?": {
"type": "io.murano.resources.LinuxMuranoInstance",
"id": utils.generate_uuid()
},
"name": utils.generate_name("testMurano")
}
if kwargs.get('securityGroups'):
instance['securityGroups'] = kwargs.get('securityGroups')
return {
"instance": instance,
"name": utils.generate_name("VM"),
"?": {
"_{id}".format(id=utils.generate_uuid()): {
"name": "VM"
},
"type": "io.murano.apps.test.VM",
"id": utils.generate_uuid()
}
}
def update_executor(self, flavor='m1.tiny'):
post_body = {
"instance": {
"flavor": flavor,
"image": self.linux_image,
"assignFloatingIp": True,
"?": {
"type": "io.murano.resources.LinuxMuranoInstance",
"id": utils.generate_uuid()
},
"name": utils.generate_name('testMurano')
},
"name": utils.generate_name('dummy'),
"?": {
"type": "io.murano.apps.test.UpdateExecutor",
"id": utils.generate_uuid()
}
}
return post_body
def deploy_environment(self, environment, session):
self.application_catalog_client.deploy_session(environment['id'],
session['id'])
timeout = 1800
deployed_env = utils.wait_for_environment_deploy(
self.application_catalog_client, environment['id'],
timeout=timeout)
if deployed_env['status'] == 'ready':
return deployed_env
elif deployed_env['status'] == 'deploying':
self.fail('Environment deployment is not finished in {} seconds'.
format(timeout))
else:
self.fail('Environment has status {}'.format(
deployed_env['status']))
def status_check(self, environment_id, configurations):
for configuration in configurations:
inst_name = configuration[0]
ports = configuration[1:]
ip = self.get_ip_by_instance_name(environment_id, inst_name)
if ip and ports:
for port in ports:
self.check_port_access(ip, port)
else:
self.fail('Instance does not have floating IP')
def check_path(self, environment_id, path, inst_name=None):
environment = self.application_catalog_client.\
get_environment(environment_id)
if inst_name:
ip = self.get_ip_by_instance_name(environment_id, inst_name)
else:
ip = environment.services[0]['instance']['floatingIpAddress']
resp = requests.get('http://{0}/{1}'.format(ip, path))
if resp.status_code == 200:
return resp
else:
self.fail("Service path unavailable")
def get_ip_by_instance_name(self, environment_id, inst_name):
for service in self.application_catalog_client.\
get_services_list(environment_id):
if inst_name in service['instance']['name']:
return service['instance']['floatingIpAddress']
def check_port_access(self, ip, port):
result = 1
start_time = time.time()
while time.time() - start_time < 600:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((str(ip), port))
sock.close()
if result == 0:
break
time.sleep(5)
self.assertEqual(0, result, '%s port is closed on instance' % port)
@classmethod
def create_volume(cls, **kwargs):
volume = cls.volumes_client.create_volume(**kwargs)['volume']
waiters.wait_for_volume_resource_status(cls.volumes_client,
volume['id'], 'available')
return volume
@classmethod
def delete_volume(cls, volume_id):
cls.volumes_client.delete_volume(volume_id)
is_volume_deleted = False
while not is_volume_deleted:
is_volume_deleted = cls.volumes_client.\
is_resource_deleted(volume_id)
time.sleep(1)
def create_snapshot(self, volume_id):
snapshot = self.snapshots_client.\
create_snapshot(volume_id=volume_id)['snapshot']
waiters.wait_for_volume_resource_status(self.snapshots_client,
snapshot['id'], 'available')
return snapshot
def delete_snapshot(self, snapshot_id):
self.snapshots_client.delete_snapshot(snapshot_id)
is_snapshot_deleted = False
while not is_snapshot_deleted:
is_snapshot_deleted = self.snapshots_client.\
is_resource_deleted(snapshot_id)
time.sleep(1)
def create_backup(self, volume_id):
backup = self.backups_client.create_backup(
volume_id=volume_id,
force=True)['backup']
waiters.wait_for_volume_resource_status(self.backups_client,
backup['id'], 'available')
return backup
def delete_backup(self, backup_id):
self.backups_client.delete_backup(backup_id)
return self.backups_client.wait_for_resource_deletion(backup_id)
def get_volume(self, environment_id):
stack = self.get_stack_id(environment_id)
stack_outputs = self.orchestration_client.\
show_stack(stack)['stack']['outputs']
for output in stack_outputs:
if (output['output_key'].startswith('vol-') and
output['output_key'].endswith('-id')):
volume_id = output['output_value']
return self.volumes_client.show_volume(volume_id)['volume']
def get_volume_attachments(self, environment_id):
stack = self.get_stack_id(environment_id)
stack_outputs = self.orchestration_client.\
show_stack(stack)['stack']['outputs']
for output in stack_outputs:
if (output['output_key'].startswith('vol-') and
output['output_key'].endswith('-attachments')):
return output['output_value']
def check_volume_attachments(self, environment_id):
volume_attachments = self.get_volume_attachments(environment_id)
self.assertIsInstance(volume_attachments, list)
self.assertGreater(len(volume_attachments), 0)
instance_id = self.get_instance_id('testMurano')
for attachment in volume_attachments:
self.assertEqual(attachment.get('server_id'), instance_id)
self.assertTrue(attachment.get('device').startswith('/dev/'))
def check_volume_attached(self, name, volume_id):
instance_id = self.get_instance_id(name)
attached_volumes = self.servers_client.\
list_volume_attachments(instance_id)['volumeAttachments']
self.assertEqual(attached_volumes[0]['id'], volume_id)
class BaseApplicationCatalogScenarioIsolatedAdminTest(
BaseApplicationCatalogScenarioTest):
@classmethod
def setup_clients(cls):
super(BaseApplicationCatalogScenarioIsolatedAdminTest,
cls).setup_clients()
if not hasattr(cls, "os_admin"):
creds = cls.get_configured_isolated_creds(type_of_creds='admin')
cls.os_admin = clients.Manager(credentials=creds)
cls.services_manager = services_manager(creds)
cls.application_catalog_client = \
cls.os_admin.application_catalog_client
cls.artifacts_client = cls.os_admin.artifacts_client
cls.servers_client = cls.services_manager.servers_client
# NOTE(andreaf) The orchestration client is not initialised in Tempest
# by default anymore.
params = config.service_client_config('orchestration')
cls.orchestration_client = orchestration.OrchestrationClient(
cls.services_manager.auth_provider, **params)
cls.snapshots_client = cls.services_manager.snapshots_v2_client
cls.volumes_client = cls.services_manager.volumes_v2_client
cls.backups_client = cls.services_manager.backups_v2_client
cls.images_client = cls.services_manager.image_client_v2