diff --git a/murano/tests/functional/api/base.py b/murano/tests/functional/api/base.py index 7a9da1394..1838ea3e7 100644 --- a/murano/tests/functional/api/base.py +++ b/murano/tests/functional/api/base.py @@ -19,6 +19,7 @@ import time import uuid from tempest import clients +from tempest.common import isolated_creds from tempest.common import rest_client from tempest import config from tempest import exceptions @@ -100,6 +101,14 @@ class MuranoClient(rest_client.RestClient): return resp, json.loads(body) + def deploy_session(self, environment_id, session_id): + post_body = None + url = 'v1/environments/{0}/sessions/{1}/deploy' + resp, body = self.post(url.format(environment_id, session_id), + post_body) + + return resp, json.loads(body) + def create_service(self, environment_id, session_id, post_body): post_body = json.dumps(post_body) @@ -242,7 +251,9 @@ class TestCase(tempest.test.BaseTestCase): return environment - def create_demo_service(self, environment_id, session_id): + def create_demo_service(self, environment_id, session_id, client=None): + if not client: + client = self.client post_body = { "?": { "id": uuid.uuid4().hex, @@ -261,9 +272,9 @@ class TestCase(tempest.test.BaseTestCase): "configuration": "standalone" } - return self.client.create_service(environment_id, - session_id, - post_body) + return client.create_service(environment_id, + session_id, + post_body) class NegativeTestCase(TestCase): @@ -273,5 +284,6 @@ class NegativeTestCase(TestCase): # If no credentials are provided, the Manager will use those # in CONF.identity and generate an auth_provider from them - mgr = clients.Manager() + creds = isolated_creds.IsolatedCreds(cls.__name__).get_alt_creds() + mgr = clients.Manager(credentials=creds) cls.alt_client = MuranoClient(mgr.auth_provider) diff --git a/murano/tests/functional/api/v1/test_envs.py b/murano/tests/functional/api/v1/test_envs.py index 44f8606cd..d97841cd7 100644 --- a/murano/tests/functional/api/v1/test_envs.py +++ b/murano/tests/functional/api/v1/test_envs.py @@ -100,3 +100,27 @@ class TestEnvironments(base.TestCase): self.assertRaises(exceptions.NotFound, self.client.get_environment, env['id']) + + +class TestEnvironmentsTenantIsolation(base.NegativeTestCase): + + @attr(type='negative') + def test_get_environment_from_another_tenant(self): + env = self.create_environment('test') + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.get_environment, env['id']) + + @attr(type='negative') + def test_update_environment_from_another_tenant(self): + env = self.create_environment('test') + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.update_environment, env['id']) + + @attr(type='negative') + def test_delete_environment_from_another_tenant(self): + env = self.create_environment('test') + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.delete_environment, env['id']) diff --git a/murano/tests/functional/api/v1/test_repository.py b/murano/tests/functional/api/v1/test_repository.py index efb3dca12..8bad99706 100644 --- a/murano/tests/functional/api/v1/test_repository.py +++ b/murano/tests/functional/api/v1/test_repository.py @@ -13,7 +13,6 @@ # under the License. import os -import testtools import uuid import zipfile @@ -56,8 +55,6 @@ class TestCaseRepository(base.TestCase): try: self.client.delete_package(package['id']) except Exception: - #except exceptions.NotFound: Need to uncomment after fix the - #following bug https://bugs.launchpad.net/murano/+bug/1309413 pass @classmethod @@ -141,7 +138,6 @@ class TestRepositoryNegativeNotFound(base.NegativeTestCase): self.client.get_package, self.id) - @testtools.skip("https://bugs.launchpad.net/murano/+bug/1309413") @attr(type='negative') def test_delete_package_with_incorrect_id(self): self.assertRaises(exceptions.NotFound, @@ -173,9 +169,6 @@ class TestRepositoryNegativeForbidden(base.NegativeTestCase, def setUpClass(cls): super(TestRepositoryNegativeForbidden, cls).setUpClass() - raise cls.skipException( - "https://bugs.launchpad.net/murano/+bug/1312190") - cls.categorie = cls.client.list_categories()[1]['categories'][0] packages_list = cls.client.get_list_packages()[1] diff --git a/murano/tests/functional/api/v1/test_services.py b/murano/tests/functional/api/v1/test_services.py index fa2b0b4cb..b671ae1bb 100644 --- a/murano/tests/functional/api/v1/test_services.py +++ b/murano/tests/functional/api/v1/test_services.py @@ -206,3 +206,44 @@ class TestServices(base.TestCase): env['id'], "", service['?']['id']) + + +class TestServicesTenantIsolation(base.NegativeTestCase): + + @attr(type='negative') + def test_get_list_services_in_env_from_another_tenant(self): + env = self.create_environment('test') + sess = self.client.create_session(env['id'])[1] + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.get_services_list, env['id'], + sess['id']) + + @attr(type='negative') + def test_create_service_in_env_from_another_tenant(self): + env = self.create_environment('test') + sess = self.client.create_session(env['id'])[1] + + self.assertRaises(exceptions.Unauthorized, + self.create_demo_service, env['id'], + sess['id'], client=self.alt_client) + + @attr(type='negative') + def test_delete_service_in_env_from_another_tenant(self): + env = self.create_environment('test') + sess = self.client.create_session(env['id'])[1] + service = self.create_demo_service(env['id'], sess['id'])[1] + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.delete_service, env['id'], + sess['id'], service['?']['id']) + + @attr(type='negative') + def test_get_service_in_env_from_another_tenant(self): + env = self.create_environment('test') + sess = self.client.create_session(env['id'])[1] + service = self.create_demo_service(env['id'], sess['id'])[1] + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.get_service, env['id'], + sess['id'], service['?']['id']) diff --git a/murano/tests/functional/api/v1/test_sessions.py b/murano/tests/functional/api/v1/test_sessions.py index d2d5ef050..dce9e92cb 100644 --- a/murano/tests/functional/api/v1/test_sessions.py +++ b/murano/tests/functional/api/v1/test_sessions.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +import testtools + from tempest import exceptions from tempest.test import attr @@ -103,3 +105,41 @@ class TestSessions(base.TestCase): self.client.delete_session, env['id'], sess['id']) + + +class TestSessionsTenantIsolation(base.NegativeTestCase): + + @attr(type='negative') + def test_create_session_in_env_from_another_tenant(self): + env = self.create_environment('test') + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.create_session, env['id']) + + @attr(type='negative') + def test_delete_session_in_env_from_another_tenant(self): + env = self.create_environment('test') + sess = self.client.create_session(env['id'])[1] + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.delete_session, env['id'], + sess['id']) + + @attr(type='negative') + def test_get_session_in_env_from_another_tenant(self): + env = self.create_environment('test') + sess = self.client.create_session(env['id'])[1] + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.get_session, env['id'], + sess['id']) + + @testtools.skip("https://bugs.launchpad.net/murano/+bug/1382026") + @attr(type='negative') + def test_deploy_session_in_env_from_another_tenant(self): + env = self.create_environment('test') + sess = self.client.create_session(env['id'])[1] + + self.assertRaises(exceptions.Unauthorized, + self.alt_client.deploy_session, env['id'], + sess['id']) diff --git a/murano/tests/functional/cli/muranoclient.py b/murano/tests/functional/cli/muranoclient.py index 85a49e9a6..04ba4bf05 100644 --- a/murano/tests/functional/cli/muranoclient.py +++ b/murano/tests/functional/cli/muranoclient.py @@ -12,12 +12,34 @@ # License for the specific language governing permissions and limitations # under the License. -from tempest import cli +from tempest_lib.cli import base # noqa + +from tempest import config + +CONF = config.CONF -class ClientTestBase(cli.ClientTestBase): +class ClientTestBase(base.ClientTestBase): def murano(self, action, flags='', params='', admin=True, fail_ok=False): """Executes murano command for the given action.""" - return self.cmd_with_auth( + return self.clients.cmd_with_auth( 'murano', action, flags, params, admin, fail_ok) + + def _get_clients(self): + clients = base.CLIClient( + CONF.identity.admin_username, + CONF.identity.admin_password, + CONF.identity.admin_tenant_name, + CONF.identity.uri, + CONF.cli.cli_dir + ) + return clients + + def listing(self, command, params=""): + return self.parser.listing(self.murano(command, params=params)) + + def get_value(self, need_field, known_field, known_value, somelist): + for element in somelist: + if element[known_field] == known_value: + return element[need_field] diff --git a/murano/tests/functional/cli/simple_read_only/test_murano.py b/murano/tests/functional/cli/simple_read_only/test_murano.py index 61f8dd081..8d686b984 100644 --- a/murano/tests/functional/cli/simple_read_only/test_murano.py +++ b/murano/tests/functional/cli/simple_read_only/test_murano.py @@ -12,6 +12,9 @@ # License for the specific language governing permissions and limitations # under the License. +import time +import uuid + from murano.tests.functional.cli import muranoclient @@ -27,16 +30,100 @@ class SimpleReadOnlyMuranoClientTest(muranoclient.ClientTestBase): super(SimpleReadOnlyMuranoClientTest, cls).setUpClass() def test_environment_list(self): - environments = self.parser.listing(self.murano('environment-list')) + environments = self.listing('environment-list') self.assertTableStruct(environments, ['ID', 'Name', 'Created', 'Updated']) def test_package_list(self): - packages = self.parser.listing(self.murano('package-list')) + packages = self.listing('package-list') self.assertTableStruct(packages, ['ID', 'Name', 'FQN', 'Author', 'Is Public']) def test_category_list(self): self.murano('category-list') + + def test_table_struct_of_environment_create(self): + env_name = "gg" + uuid.uuid4().hex + environment = self.listing('environment-create', params=env_name) + + self.assertTableStruct(environment, + ['ID', 'Name', 'Created', 'Updated']) + + def test_table_struct_of_environment_delete(self): + env_name = "gg" + uuid.uuid4().hex + environment = self.listing('environment-create', params=env_name) + + ID = self.get_value('ID', 'Name', env_name, environment) + + delete_env = self.listing('environment-delete', params=ID) + + self.assertTableStruct(delete_env, + ['ID', 'Name', 'Created', 'Updated']) + + +class EnvironmentMuranoClientTest(muranoclient.ClientTestBase): + + @classmethod + def setUpClass(cls): + super(EnvironmentMuranoClientTest, cls).setUpClass() + + def test_environment_create(self): + env_name = "gg" + uuid.uuid4().hex + environment = self.listing('environment-create', params=env_name) + + environment_list = self.listing('environment-list') + + self.assertIn(env_name, [env['Name'] for env in environment]) + self.assertIn(env_name, [env['Name'] for env in environment_list]) + + def test_environment_delete(self): + env_name = "gg" + uuid.uuid4().hex + environments = self.listing('environment-create', params=env_name) + + ID = self.get_value('ID', 'Name', env_name, environments) + + self.listing('environment-delete', params=ID) + + start_time = time.time() + while env_name in [env['Name'] + for env in self.listing('environment-list')]: + if start_time - time.time() > 60: + self.fail("Environment is not deleted in 60 seconds") + + def test_environment_show(self): + env_name = "gg" + uuid.uuid4().hex + environment = self.listing('environment-create', params=env_name) + + ID = self.get_value('ID', 'Name', env_name, environment) + + created = self.get_value('Created', 'Name', env_name, environment) + updated = self.get_value('Updated', 'Name', env_name, environment) + + show_env = self.listing('environment-show', params=ID) + + self.assertEqual(env_name, self.get_value('Value', 'Property', 'name', + show_env)) + self.assertEqual(created, self.get_value('Value', 'Property', + 'created', show_env)) + self.assertEqual(updated, self.get_value('Value', 'Property', + 'updated', show_env)) + + def test_environment_rename(self): + env_name = "gg" + uuid.uuid4().hex + environment = self.listing('environment-create', params=env_name) + + ID = self.get_value('ID', 'Name', env_name, environment) + + new_name = "renamed" + uuid.uuid4().hex + rename_env = self.listing('environment-rename', + params='{id} {name}'.format(id=ID, + name=new_name)) + + show_env = self.listing('environment-show', params=ID) + + self.assertEqual(new_name, self.get_value('Name', 'ID', ID, + rename_env)) + self.assertEqual(new_name, self.get_value('Value', 'Property', 'name', + show_env)) diff --git a/murano/tests/functional/engine/base.py b/murano/tests/functional/engine/base.py index a1b3b047c..e9c8990f0 100644 --- a/murano/tests/functional/engine/base.py +++ b/murano/tests/functional/engine/base.py @@ -12,19 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -import json import os import socket import time -import urlparse import uuid -import requests import testresources import testtools from heatclient import client as heatclient from keystoneclient.v2_0 import client as ksclient +from muranoclient import client as mclient +import muranoclient.common.exceptions as exceptions import murano.tests.functional.engine.config as cfg @@ -32,106 +31,6 @@ import murano.tests.functional.engine.config as cfg CONF = cfg.cfg.CONF -class Client(object): - def __init__(self, user, password, tenant, auth_url, murano_url): - self.auth = ksclient.Client( - username=user, password=password, - tenant_name=tenant, auth_url=auth_url - ) - self.endpoint = urlparse.urljoin(murano_url, 'v1/') - self.headers = { - 'X-Auth-Token': self.auth.auth_token, - 'Content-type': 'application/json' - } - - def get_url(self, url_part=None): - return urlparse.urljoin(self.endpoint, url_part) - - def create_environment(self, name): - endpoint = self.get_url('environments') - body = json.dumps({'name': name}) - - return requests.post(endpoint, data=body, headers=self.headers).json() - - def delete_environment(self, environment_id, timeout=180): - endpoint = self.get_url('environments/%s' % environment_id) - - def _is_exist(): - resp = requests.get(endpoint, headers=self.headers) - return resp.status_code == requests.codes.ok - - env_deleted = not _is_exist() - requests.delete(endpoint, headers=self.headers) - - start_time = time.time() - while env_deleted is not True: - if timeout and time.time() - start_time > timeout: - raise Exception('Environment was not deleted') - time.sleep(5) - env_deleted = not _is_exist() - - def get_environment(self, environment_id): - endpoint = self.get_url('environments/%s' % environment_id) - return requests.get(endpoint, headers=self.headers).json() - - def create_session(self, environment_id): - endpoint = self.get_url('environments/%s/configure' % environment_id) - return requests.post(endpoint, headers=self.headers).json() - - def deploy_session(self, environment_id, session_id): - endpoint = self.get_url('environments/{0}/sessions/{1}/deploy'.format( - environment_id, session_id)) - return requests.post(endpoint, headers=self.headers) - - def create_service(self, environment_id, session_id, json_data): - endpoint = self.get_url('environments/%s/services' % environment_id) - body = json.dumps(json_data) - headers = self.headers.copy() - headers['x-configuration-session'] = session_id - - return requests.post(endpoint, data=body, headers=headers).json() - - def delete_service(self, environment_id, session_id, service_id): - endpoint = self.get_url('environments/{0}/services/{1}'.format( - environment_id, service_id - )) - headers = self.headers.copy() - headers['x-configuration-session'] = session_id - - requests.delete(endpoint, headers=headers) - - def wait_for_environment_deploy(self, environment_id): - environment = self.get_environment(environment_id) - - start_time = time.time() - while environment['status'] != 'ready': - if time.time() - start_time > 1200: - return - time.sleep(5) - environment = self.get_environment(environment_id) - - return environment - - def get_ip_list(self, environment): - return [service['instance']['ipAddresses'] - for service in environment['services']] - - def deployments_list(self, environment_id): - endpoint = self.get_url('environments/%s/deployments' % environment_id) - response = requests.get(endpoint, headers=self.headers) - return response.json()['deployments'] - - def upload_package(self, name, package, description): - endpoint = self.get_url('catalog/packages') - body = {'JsonString': json.dumps(description)} - files = {name: open(package, 'rb')} - headers = self.headers.copy() - del headers['Content-type'] - - resp = requests.post(endpoint, data=body, files=files, headers=headers) - return resp.json()['id'] - - class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, testresources.ResourcedTestCase): @@ -141,20 +40,26 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, cfg.load_config() - cls.client = Client(user=CONF.murano.user, - password=CONF.murano.password, - tenant=CONF.murano.tenant, - auth_url=CONF.murano.auth_url, - murano_url=CONF.murano.murano_url) + keystone_client = ksclient.Client(username=CONF.murano.user, + password=CONF.murano.password, + tenant_name=CONF.murano.tenant, + auth_url=CONF.murano.auth_url) - cls.linux = CONF.murano.linux_image - cls.windows = CONF.murano.windows_image - - heat_url = cls.client.auth.service_catalog.url_for( + heat_url = keystone_client.service_catalog.url_for( service_type='orchestration', endpoint_type='publicURL') cls.heat_client = heatclient.Client('1', endpoint=heat_url, - token=cls.client.auth.auth_token) + token=keystone_client.auth_token) + + url = CONF.murano.murano_url + murano_url = url if 'v1' not in url else "/".join( + url.split('/')[:url.split('/').index('v1')]) + + cls.muranoclient = mclient.Client('1', + endpoint=murano_url, + token=keystone_client.auth_token) + + cls.linux = CONF.murano.linux_image cls.pkgs_path = os.path.abspath(os.path.join( os.path.dirname(__file__), @@ -162,48 +67,77 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, 'murano-app-incubator' )) - cls.postgre_id = cls.client.upload_package( + def upload_package(package_name, body, app): + + files = {'%s' % package_name: open(app, 'rb')} + + return cls.muranoclient.packages.create(body, files) + + upload_package( 'PostgreSQL', - os.path.join(cls.pkgs_path, 'io.murano.apps.PostgreSql.zip'), - {'categories': ['Databases'], 'tags': ['tag']} + {"categories": ["Databases"], "tags": ["tag"]}, + os.path.join(cls.pkgs_path, 'io.murano.databases.PostgreSql.zip') ) - cls.apache_id = cls.client.upload_package( + upload_package( + 'SqlDatabase', + {"categories": ["Databases"], "tags": ["tag"]}, + os.path.join(cls.pkgs_path, 'io.murano.databases.SqlDatabase.zip') + ) + upload_package( 'Apache', - os.path.join(cls.pkgs_path, 'io.murano.apps.apache.Apache.zip'), - {'categories': ['Application Servers'], 'tags': ['tag']} - ) - cls.tomcat_id = cls.client.upload_package( - 'Tomcat', - os.path.join(cls.pkgs_path, 'io.murano.apps.apache.Tomcat.zip'), - {'categories': ['Application Servers'], 'tags': ['tag']} - ) - cls.telnet_id = cls.client.upload_package( - 'Telnet', - os.path.join(cls.pkgs_path, 'io.murano.apps.linux.Telnet.zip'), - {'categories': ['Web'], 'tags': ['tag']} - ) - cls.ad_id = cls.client.upload_package( - 'Active Directory', + {"categories": ["Application Servers"], "tags": ["tag"]}, os.path.join(cls.pkgs_path, - 'io.murano.windows.ActiveDirectory.zip'), - {'categories': ['Microsoft Services'], 'tags': ['tag']} + 'io.murano.apps.apache.ApacheHttpServer.zip') + ) + upload_package( + 'Tomcat', + {"categories": ["Application Servers"], "tags": ["tag"]}, + os.path.join(cls.pkgs_path, 'io.murano.apps.apache.Tomcat.zip') + ) + upload_package( + 'Telnet', + {"categories": ["Web"], "tags": ["tag"]}, + os.path.join(cls.pkgs_path, 'io.murano.apps.linux.Telnet.zip') ) def setUp(self): super(MuranoBase, self).setUp() self.environments = [] - self.stack_names = [] def tearDown(self): super(MuranoBase, self).tearDown() for env in self.environments: try: - self.client.delete_environment(env) + self.environment_delete(env) except Exception: pass + def environment_delete(self, environment_id, timeout=180): + self.muranoclient.environments.delete(environment_id) + + start_time = time.time() + while time.time() - start_time < timeout: + try: + self.muranoclient.environments.get(environment_id) + except exceptions.HTTPNotFound: + return + raise Exception( + 'Environment {0} was not deleted in {1} seconds'.format( + environment_id, timeout)) + + def wait_for_environment_deploy(self, environment): + start_time = time.time() + + while environment.manager.get(environment.id).status != 'ready': + if time.time() - start_time > 1200: + self.fail( + 'Environment deployment is not finished in 1200 seconds') + time.sleep(5) + + return environment.manager.get(environment.id) + def check_port_access(self, ip, port): result = 1 start_time = time.time() @@ -219,15 +153,17 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, self.assertEqual(0, result, '%s port is closed on instance' % port) def deployment_success_check(self, environment, port): - deployments = self.client.deployments_list(environment['id']) + deployment = self.muranoclient.deployments.list(environment.id)[-1] - for deployment in deployments: - msg = 'Deployment status is %s' % deployment['state'] - self.assertEqual('success', deployment['state'], msg) + self.assertEqual('success', deployment.state, + 'Deployment status is {0}'.format(deployment.state)) - instance = environment['services'][0]['instance'] - self.assertTrue(instance['floatingIpAddress']) - self.check_port_access(instance['floatingIpAddress'], port) + ip = environment.services[-1]['instance']['floatingIpAddress'] + + if ip: + self.check_port_access(ip, port) + else: + self.fail('Instance does not have floating IP') def test_deploy_telnet(self): post_body = { @@ -250,16 +186,7 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, environment_name = 'Telnetenv' + uuid.uuid4().hex[:5] - environment = self.client.create_environment(environment_name) - self.environments.append(environment['id']) - - session = self.client.create_session(environment['id']) - - self.client.create_service(environment['id'], session['id'], post_body) - self.client.deploy_session(environment['id'], session['id']) - - env = self.client.wait_for_environment_deploy(environment['id']) - self.assertIsNotNone(env) + env = self._quick_deploy(environment_name, post_body) self.deployment_success_check(env, 23) @@ -277,24 +204,14 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, }, "name": "teMurano", "?": { - "type": "io.murano.apps.apache.Apache", + "type": "io.murano.apps.apache.ApacheHttpServer", "id": str(uuid.uuid4()) } } environment_name = 'Apacheenv' + uuid.uuid4().hex[:5] - environment = self.client.create_environment(environment_name) - self.environments.append(environment['id']) - self.stack_names.append(environment_name) - - session = self.client.create_session(environment['id']) - - self.client.create_service(environment['id'], session['id'], post_body) - self.client.deploy_session(environment['id'], session['id']) - - env = self.client.wait_for_environment_deploy(environment['id']) - self.assertIsNotNone(env) + env = self._quick_deploy(environment_name, post_body) self.deployment_success_check(env, 80) @@ -311,25 +228,18 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, "name": "testMurano" }, "name": "teMurano", + "database": "test_db", + "username": "test_usr", + "password": "test_pass", "?": { - "type": "io.murano.apps.PostgreSql", + "type": "io.murano.databases.PostgreSql", "id": str(uuid.uuid4()) } } environment_name = 'Postgreenv' + uuid.uuid4().hex[:5] - environment = self.client.create_environment(environment_name) - self.environments.append(environment['id']) - self.stack_names.append(environment_name) - - session = self.client.create_session(environment['id']) - - self.client.create_service(environment['id'], session['id'], post_body) - self.client.deploy_session(environment['id'], session['id']) - - env = self.client.wait_for_environment_deploy(environment['id']) - self.assertIsNotNone(env) + env = self._quick_deploy(environment_name, post_body) self.deployment_success_check(env, 5432) @@ -354,16 +264,7 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, environment_name = 'Tomcatenv' + uuid.uuid4().hex[:5] - environment = self.client.create_environment(environment_name) - self.environments.append(environment['id']) - - session = self.client.create_session(environment['id']) - - self.client.create_service(environment['id'], session['id'], post_body) - self.client.deploy_session(environment['id'], session['id']) - - env = self.client.wait_for_environment_deploy(environment['id']) - self.assertIsNotNone(env) + env = self._quick_deploy(environment_name, post_body) self.deployment_success_check(env, 8080) @@ -386,14 +287,20 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, } def _quick_deploy(self, name, *apps): - environment = self.client.create_environment(name) - session = self.client.create_session(environment['id']) - environment_id, session_id = environment['id'], session['id'] + environment = self.muranoclient.environments.create({'name': name}) + self.environments.append(environment.id) + + session = self.muranoclient.sessions.configure(environment.id) for app in apps: - self.client.create_service(environment_id, session_id, app) - self.client.deploy_session(environment_id, session_id) - return self.client.wait_for_environment_deploy(environment_id) + self.muranoclient.services.post(environment.id, + path='/', + data=app, + session_id=session.id) + + self.muranoclient.sessions.deploy(environment.id, session.id) + + return self.wait_for_environment_deploy(environment) def _get_stack(self, environment_id): @@ -413,17 +320,17 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, application_id = application1['?']['id'] instance_name = application1['instance']['name'] apps = [application1, application2] - environment_id = self._quick_deploy(name, *apps)['id'] - # add environment to the list for tear-down clean-up - self.environments.append(environment_id) + environment = self._quick_deploy(name, *apps) # delete telnet application - session_id = self.client.create_session(environment_id)['id'] - self.client.delete_service(environment_id, session_id, application_id) - self.client.deploy_session(environment_id, session_id) - self.client.wait_for_environment_deploy(environment_id) + session = self.muranoclient.sessions.configure(environment.id) + self.muranoclient.services.delete(environment.id, + '/' + application_id, + session.id) + self.muranoclient.sessions.deploy(environment.id, session.id) + self.wait_for_environment_deploy(environment) - stack_name = self._get_stack(environment_id).stack_name + stack_name = self._get_stack(environment.id).stack_name template = self.heat_client.stacks.template(stack_name) ip_addresses = '{0}-assigned-ip'.format(instance_name) floating_ip = '{0}-FloatingIPaddress'.format(instance_name) @@ -437,17 +344,16 @@ class MuranoBase(testtools.TestCase, testtools.testcase.WithAttributes, application = self._get_telnet_app() environment = self._quick_deploy(name, application) - self.assertIsNotNone(environment) - stack = self._get_stack(environment['id']) + stack = self._get_stack(environment.id) self.assertIsNotNone(stack) - self.client.delete_environment(environment['id']) + self.muranoclient.environments.delete(environment.id) start_time = time.time() while stack is not None: if time.time() - start_time > 300: break time.sleep(5) - stack = self._get_stack(environment['id']) + stack = self._get_stack(environment.id) self.assertIsNone(stack, 'stack is not deleted') diff --git a/murano/tests/unit/db/migration/test_migrations_base.py b/murano/tests/unit/db/migration/test_migrations_base.py index 22eadbc5f..1d9b4b2d8 100644 --- a/murano/tests/unit/db/migration/test_migrations_base.py +++ b/murano/tests/unit/db/migration/test_migrations_base.py @@ -29,6 +29,7 @@ import os from alembic import command from alembic import config as alembic_config from alembic import migration +from alembic import script as alembic_script from oslo.config import cfg import six.moves.urllib.parse as urlparse import sqlalchemy @@ -459,29 +460,20 @@ class BaseWalkMigrationTestCase(BaseMigrationTestCase): #session.cleanup() return res - def _get_alembic_versions(self, engine): - """For support of full testing of migrations - we should have an opportunity to run command step by step for each - version in repo. This method returns list of alembic_versions by - historical order. - """ - full_history = self._alembic_command('history', - engine, self.ALEMBIC_CONFIG) - # The piece of output data with version can looked as: - # 'Rev: 17738166b91 (head)' or 'Rev: 43b1a023dfaa' - alembic_history = [r.split(' ')[1] for r in full_history.split("\n") - if r.startswith("Rev")] - alembic_history.reverse() - return alembic_history - - def _up_and_down_versions(self, engine): + def _up_and_down_versions(self): """Since alembic version has a random algorithm of generation (SA-migrate has an ordered autoincrement naming) we should store a tuple of versions (version for upgrade and version for downgrade) for successful testing of migrations in up>down>up mode. """ - versions = self._get_alembic_versions(engine) - return zip(versions, ['-1'] + versions) + + env = alembic_script.ScriptDirectory.from_config(self.ALEMBIC_CONFIG) + versions = [] + for rev in env.walk_revisions(): + versions.append((rev.revision, rev.down_revision or '-1')) + + versions.reverse() + return versions def _walk_versions(self, engine=None, snake_walk=False, downgrade=True): @@ -491,7 +483,7 @@ class BaseWalkMigrationTestCase(BaseMigrationTestCase): # upgrades successfully. self._configure(engine) - up_and_down_versions = self._up_and_down_versions(engine) + up_and_down_versions = self._up_and_down_versions() for ver_up, ver_down in up_and_down_versions: # upgrade -> downgrade -> upgrade self._migrate_up(engine, ver_up, with_data=True)