Add tempest GLARE sanity check tests
This commit adds very basic api tests for glare artifact type for murano Also adds initial implementation of upload/delete package methods to tempest artifact client. Change-Id: Idc6c06570f4674d5d998fc4fb1ec72208662ff2e Targets: bp murano-glare-devstack-testing
This commit is contained in:
parent
a1387135e8
commit
0e1647bc09
|
@ -19,6 +19,7 @@ from tempest.lib import auth
|
|||
|
||||
from murano_tempest_tests.services.application_catalog \
|
||||
import application_catalog_client
|
||||
from murano_tempest_tests.services.artifacts import artifacts_client
|
||||
from murano_tempest_tests.services.service_broker import service_broker_client
|
||||
|
||||
CONF = config.CONF
|
||||
|
@ -31,6 +32,11 @@ class Manager(object):
|
|||
self.auth_provider = get_auth_provider(credentials)
|
||||
self.service_broker_client = service_broker_client.ServiceBrokerClient(
|
||||
self.auth_provider)
|
||||
if CONF.application_catalog.glare_backend:
|
||||
self.artifacts_client = artifacts_client.ArtifactsClient(
|
||||
self.auth_provider)
|
||||
else:
|
||||
self.artifacts_client = None
|
||||
self.application_catalog_client = \
|
||||
application_catalog_client.ApplicationCatalogClient(
|
||||
self.auth_provider)
|
||||
|
|
|
@ -14,10 +14,14 @@
|
|||
# under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
from tempest import config
|
||||
from tempest.lib.common import rest_client
|
||||
|
||||
from murano_tempest_tests import utils
|
||||
import six
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
|
@ -39,7 +43,8 @@ class ArtifactsClient(rest_client.RestClient):
|
|||
uri = 'v0.1/artifacts/murano/v1'
|
||||
resp, body = self.get(uri)
|
||||
self.expected_success(200, resp.status)
|
||||
return self._parse_resp(body)
|
||||
parsed = self._parse_resp(body)
|
||||
return parsed['artifacts']
|
||||
|
||||
def list_drafts(self):
|
||||
uri = 'v0.1/artifacts/murano/v1/creating'
|
||||
|
@ -54,7 +59,7 @@ class ArtifactsClient(rest_client.RestClient):
|
|||
return self._parse_resp(body)
|
||||
|
||||
def create_artifact_draft(self, name, version, **kwargs):
|
||||
uri = 'v0.1/artifacts/murano/v1/creating'
|
||||
uri = 'v0.1/artifacts/murano/v1/drafts'
|
||||
kwargs.update({'name': name, 'version': version})
|
||||
resp, body = self.post(uri, body=json.dumps(kwargs))
|
||||
self.expected_success(201, resp.status)
|
||||
|
@ -62,7 +67,7 @@ class ArtifactsClient(rest_client.RestClient):
|
|||
|
||||
def publish_artifact(self, artifact_id):
|
||||
uri = 'v0.1/artifacts/murano/v1/{0}/publish'.format(artifact_id)
|
||||
resp, body = self.post(uri)
|
||||
resp, body = self.post(uri, body='')
|
||||
self.expected_success(200, resp.status)
|
||||
return self._parse_resp(body)
|
||||
|
||||
|
@ -83,7 +88,7 @@ class ArtifactsClient(rest_client.RestClient):
|
|||
def delete_artifact(self, artifact_id):
|
||||
uri = 'v0.1/artifacts/murano/v1/{0}'.format(artifact_id)
|
||||
resp, body = self.delete(uri)
|
||||
self.expected_success(200, resp.status)
|
||||
self.expected_success(204, resp.status)
|
||||
return self._parse_resp(body)
|
||||
|
||||
def upload_blob(self, artifact_id, blob_type, data):
|
||||
|
@ -91,7 +96,7 @@ class ArtifactsClient(rest_client.RestClient):
|
|||
uri = 'v0.1/artifacts/murano/v1/{0}/{1}'.format(
|
||||
artifact_id, blob_type)
|
||||
resp, body = self.put(uri, data, headers=headers)
|
||||
self.expected_success(201, resp.status)
|
||||
self.expected_success(200, resp.status)
|
||||
return self._parse_resp(body)
|
||||
|
||||
def download_blob(self, artifact_id, blob_type):
|
||||
|
@ -100,3 +105,54 @@ class ArtifactsClient(rest_client.RestClient):
|
|||
resp, body = self.get(uri)
|
||||
self.expected_success(200, resp.status)
|
||||
return self._parse_resp(body)
|
||||
|
||||
# -----------------------------Packages methods-------------------------------
|
||||
|
||||
def get_list_packages(self):
|
||||
return self.list_artifacts()
|
||||
|
||||
def delete_package(self, package_id):
|
||||
return self.delete_artifact(package_id)
|
||||
|
||||
def upload_package(self, package_name, package_path, top_dir, body):
|
||||
files = {package_name: open(os.path.join(top_dir, package_path), 'rb')}
|
||||
is_public = body.pop('is_public', None)
|
||||
if is_public is not None:
|
||||
body['visibility'] = 'public' if is_public else 'private'
|
||||
fqn = list(files.keys())[0]
|
||||
package = utils.Package.from_file(files[fqn])
|
||||
manifest = package.manifest
|
||||
package_draft = {
|
||||
'name': manifest.get('FullName', fqn),
|
||||
'version': manifest.get('Version', '0.0.0'),
|
||||
'description': manifest.get('Description'),
|
||||
'display_name': manifest.get('Name', fqn),
|
||||
'type': manifest.get('Type', 'Application'),
|
||||
'author': manifest.get('Author'),
|
||||
'tags': manifest.get('Tags', []),
|
||||
'class_definitions': package.classes.keys()
|
||||
}
|
||||
for k, v in six.iteritems(body):
|
||||
package_draft[k] = v
|
||||
|
||||
inherits = utils.get_local_inheritance(package.classes)
|
||||
|
||||
# TODO(kzaitsev): add local and global inheritance information tests
|
||||
package_draft['inherits'] = inherits
|
||||
|
||||
keywords = package_draft['tags']
|
||||
package_draft['keywords'] = keywords
|
||||
|
||||
draft = self.create_artifact_draft(**package_draft)
|
||||
self.upload_blob(draft['id'], 'archive', package.file())
|
||||
|
||||
# TODO(kzaitsev): add logo upload code, currently it's failing for me
|
||||
# with io.UnsupportedOperation: fileno
|
||||
|
||||
# if package.logo is not None:
|
||||
# self.upload_blob(draft['id'], 'logo', package.logo)
|
||||
# if package.ui is not None:
|
||||
# self.client.artifacts.upload_blob(draft['id'], 'ui_definition',
|
||||
# package.ui)
|
||||
self.publish_artifact(draft['id'])
|
||||
return draft
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# 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.
|
||||
|
||||
from tempest.common import credentials_factory as common_creds
|
||||
from tempest.common import dynamic_creds
|
||||
from tempest import config
|
||||
from tempest.lib import base
|
||||
|
||||
from murano_tempest_tests import clients
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class BaseArtifactsTest(base.BaseTestCase):
|
||||
"""Base test class for Murano Glare tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(BaseArtifactsTest, cls).setUpClass()
|
||||
cls.resource_setup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.resource_cleanup()
|
||||
super(BaseArtifactsTest, cls).tearDownClass()
|
||||
|
||||
@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.artifacts_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.dynamic_cred = dynamic_creds.DynamicCredentialProvider(
|
||||
identity_version=CONF.identity.auth_version,
|
||||
name=cls.__name__, admin_role=cls.admin_role,
|
||||
admin_creds=common_creds.get_configured_admin_credentials(
|
||||
'identity_admin'))
|
||||
if type_of_creds == 'primary':
|
||||
creds = cls.dynamic_cred.get_primary_creds()
|
||||
elif type_of_creds == 'admin':
|
||||
creds = cls.dynamic_cred.get_admin_creds()
|
||||
elif type_of_creds == 'alt':
|
||||
creds = cls.dynamic_cred.get_alt_creds()
|
||||
else:
|
||||
creds = cls.dynamic_cred.get_credentials(type_of_creds)
|
||||
cls.dynamic_cred.type_of_creds = type_of_creds
|
||||
|
||||
return creds.credentials
|
||||
|
||||
@classmethod
|
||||
def verify_nonempty(cls, *args):
|
||||
if not all(args):
|
||||
msg = "Missing API credentials in configuration."
|
||||
raise cls.skipException(msg)
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
if not CONF.service_available.murano:
|
||||
skip_msg = "Murano is disabled"
|
||||
raise cls.skipException(skip_msg)
|
||||
if not hasattr(cls, "os"):
|
||||
creds = cls.get_configured_isolated_creds(type_of_creds='primary')
|
||||
cls.os = clients.Manager(credentials=creds)
|
||||
cls.artifacts_client = cls.os.artifacts_client
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
cls.clear_isolated_creds()
|
||||
|
||||
@classmethod
|
||||
def clear_isolated_creds(cls):
|
||||
if hasattr(cls, "dynamic_cred"):
|
||||
cls.dynamic_cred.clear_creds()
|
|
@ -0,0 +1,54 @@
|
|||
# Copyright (c) 2016 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.
|
||||
|
||||
import os
|
||||
import testtools
|
||||
|
||||
from tempest import config
|
||||
|
||||
from murano_tempest_tests.tests.api.application_catalog.artifacts import base
|
||||
from murano_tempest_tests import utils
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class TestRepositorySanity(base.BaseArtifactsTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
if not CONF.application_catalog.glare_backend:
|
||||
msg = ("Murano is not using GLARE backend. "
|
||||
"Skipping GLARE tests.")
|
||||
raise cls.skipException(msg)
|
||||
super(TestRepositorySanity, cls).resource_setup()
|
||||
|
||||
@testtools.testcase.attr('smoke')
|
||||
def test_get_list_packages(self):
|
||||
package_list = self.artifacts_client.get_list_packages()
|
||||
self.assertIsInstance(package_list, list)
|
||||
|
||||
@testtools.testcase.attr('smoke')
|
||||
def test_upload_and_delete_package(self):
|
||||
application_name = utils.generate_name('package_test_upload')
|
||||
abs_archive_path, dir_with_archive, archive_name = \
|
||||
utils.prepare_package(application_name)
|
||||
self.addCleanup(os.remove, abs_archive_path)
|
||||
package = self.artifacts_client.upload_package(
|
||||
application_name, archive_name, dir_with_archive,
|
||||
{"categories": [], "tags": [], 'is_public': False})
|
||||
package_list = self.artifacts_client.get_list_packages()
|
||||
self.assertIn(package['id'], {pkg['id'] for pkg in package_list})
|
||||
self.artifacts_client.delete_package(package['id'])
|
||||
package_list = self.artifacts_client.get_list_packages()
|
||||
self.assertNotIn(package['id'], {pkg['id'] for pkg in package_list})
|
|
@ -48,10 +48,10 @@ class TestRepositorySanity(base.BaseApplicationCatalogTest):
|
|||
application_name, archive_name, dir_with_archive,
|
||||
{"categories": [], "tags": [], 'is_public': False})
|
||||
package_list = self.application_catalog_client.get_list_packages()
|
||||
self.assertIn(package, package_list)
|
||||
self.assertIn(package['id'], {pkg['id'] for pkg in package_list})
|
||||
self.application_catalog_client.delete_package(package['id'])
|
||||
package_list = self.application_catalog_client.get_list_packages()
|
||||
self.assertNotIn(package, package_list)
|
||||
self.assertNotIn(package['id'], {pkg['id'] for pkg in package_list})
|
||||
|
||||
|
||||
class TestRepository(base.BaseApplicationCatalogIsolatedAdminTest):
|
||||
|
|
Loading…
Reference in New Issue