7e1cf628e7
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
159 lines
6.0 KiB
Python
159 lines
6.0 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 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
|
|
|
|
|
|
class ArtifactsClient(rest_client.RestClient):
|
|
"""Tempest REST client for Glance Artifacts"""
|
|
|
|
def __init__(self, auth_provider):
|
|
super(ArtifactsClient, self).__init__(
|
|
auth_provider,
|
|
CONF.artifacts.catalog_type,
|
|
CONF.identity.region,
|
|
endpoint_type=CONF.artifacts.endpoint_type)
|
|
self.build_interval = CONF.artifacts.build_interval
|
|
self.build_timeout = CONF.artifacts.build_timeout
|
|
|
|
# -----------------------------Artifacts methods-------------------------------
|
|
|
|
def list_artifacts(self):
|
|
uri = 'v0.1/artifacts/murano/v1'
|
|
resp, body = self.get(uri)
|
|
self.expected_success(200, resp.status)
|
|
parsed = self._parse_resp(body)
|
|
return parsed['artifacts']
|
|
|
|
def list_drafts(self):
|
|
uri = 'v0.1/artifacts/murano/v1/creating'
|
|
resp, body = self.get(uri)
|
|
self.expected_success(200, resp.status)
|
|
return self._parse_resp(body)
|
|
|
|
def list_deactivated_drafts(self):
|
|
uri = 'v0.1/artifacts/murano/v1/deactivated'
|
|
resp, body = self.get(uri)
|
|
self.expected_success(200, resp.status)
|
|
return self._parse_resp(body)
|
|
|
|
def create_artifact_draft(self, name, version, **kwargs):
|
|
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)
|
|
return self._parse_resp(body)
|
|
|
|
def publish_artifact(self, artifact_id):
|
|
uri = 'v0.1/artifacts/murano/v1/{0}/publish'.format(artifact_id)
|
|
resp, body = self.post(uri, body='')
|
|
self.expected_success(200, resp.status)
|
|
return self._parse_resp(body)
|
|
|
|
def get_artifact(self, artifact_id):
|
|
uri = 'v0.1/artifacts/murano/v1/{0}'.format(artifact_id)
|
|
resp, body = self.get(uri)
|
|
self.expected_success(200, resp.status)
|
|
return self._parse_resp(body)
|
|
|
|
def update_artifact(self, artifact_id, body):
|
|
headers = {
|
|
'Content-Type': 'application/openstack-images-v2.1-json-patch'}
|
|
uri = 'v0.1/artifacts/murano/v1/{0}'.format(artifact_id)
|
|
resp, body = self.patch(uri, json.dumps(body), headers=headers)
|
|
self.expected_success(200, resp.status)
|
|
return self._parse_resp(body)
|
|
|
|
def delete_artifact(self, artifact_id):
|
|
uri = 'v0.1/artifacts/murano/v1/{0}'.format(artifact_id)
|
|
resp, body = self.delete(uri)
|
|
self.expected_success(204, resp.status)
|
|
return self._parse_resp(body)
|
|
|
|
def upload_blob(self, artifact_id, blob_type, data):
|
|
headers = {'Content-Type': 'application/octet-stream'}
|
|
uri = 'v0.1/artifacts/murano/v1/{0}/{1}'.format(
|
|
artifact_id, blob_type)
|
|
resp, body = self.put(uri, data, headers=headers)
|
|
self.expected_success(200, resp.status)
|
|
return self._parse_resp(body)
|
|
|
|
def download_blob(self, artifact_id, blob_type):
|
|
uri = 'v0.1/artifacts/murano/v1/{0}/{1}/download'.format(
|
|
artifact_id, blob_type)
|
|
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
|