Merge "Add tempest versioning test suite"
This commit is contained in:
commit
f85313b368
|
@ -26,7 +26,7 @@ Methods:
|
|||
credentials:
|
||||
uri: localhost
|
||||
deploy:
|
||||
Body:
|
||||
Body:
|
||||
- $this.find(std:Environment).reporter.report($this, 'Follow the white rabbit')
|
||||
|
||||
staticAction:
|
||||
|
|
|
@ -19,4 +19,4 @@ Forms:
|
|||
type: string
|
||||
description: Apache License, Version 2.0
|
||||
hidden: false
|
||||
required: false
|
||||
required: false
|
||||
|
|
|
@ -19,6 +19,7 @@ from tempest import config
|
|||
from tempest.lib import base
|
||||
|
||||
from murano_tempest_tests import clients
|
||||
from murano_tempest_tests import utils
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
@ -85,6 +86,7 @@ class BaseArtifactsTest(base.BaseTestCase):
|
|||
creds = cls.get_configured_isolated_creds(type_of_creds='primary')
|
||||
cls.os = clients.Manager(credentials=creds)
|
||||
cls.artifacts_client = cls.os.artifacts_client
|
||||
cls.application_catalog_client = cls.os.application_catalog_client
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
|
@ -94,3 +96,24 @@ class BaseArtifactsTest(base.BaseTestCase):
|
|||
def clear_isolated_creds(cls):
|
||||
if hasattr(cls, "dynamic_cred"):
|
||||
cls.dynamic_cred.clear_creds()
|
||||
|
||||
@classmethod
|
||||
def upload_package(cls, application_name, version=None, require=None):
|
||||
abs_archive_path, dir_with_archive, archive_name = \
|
||||
utils.prepare_package(application_name, version=version,
|
||||
add_class_name=True, require=require)
|
||||
package = cls.artifacts_client.upload_package(
|
||||
application_name, archive_name, dir_with_archive,
|
||||
{"categories": [], "tags": [], 'is_public': False})
|
||||
return package, abs_archive_path
|
||||
|
||||
@staticmethod
|
||||
def create_obj_model(package):
|
||||
return {
|
||||
"name": package['display_name'],
|
||||
"?": {
|
||||
"type": package['name'],
|
||||
"id": utils.generate_uuid(),
|
||||
"classVersion": package['version']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
# 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 six
|
||||
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 TestVersioning(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(TestVersioning, cls).resource_setup()
|
||||
|
||||
application_name = utils.generate_name('package_test')
|
||||
# create first package
|
||||
version1 = '1.0.0'
|
||||
package1, _ = cls.upload_package(application_name,
|
||||
version=version1)
|
||||
|
||||
# create second package
|
||||
version2 = '2.0.0'
|
||||
package2, path1 = cls.upload_package(application_name,
|
||||
version=version2)
|
||||
|
||||
# create package with require >=2.0.0 for 2.0.0 package
|
||||
expected_version = '>=2.0.0'
|
||||
main_app_name = utils.generate_name('main_package_test')
|
||||
require = [(package2['name'], expected_version)]
|
||||
package3, path2 = cls.upload_package(main_app_name, require=require)
|
||||
|
||||
cls.packages = {
|
||||
'1.0.0': package1,
|
||||
'2.0.0': package2,
|
||||
'require_for_2.0.0': package3,
|
||||
}
|
||||
cls.abs_archive_paths = [path1, path2]
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
for pkg in six.itervalues(cls.packages):
|
||||
cls.artifacts_client.delete_package(pkg['id'])
|
||||
map(os.remove, cls.abs_archive_paths)
|
||||
super(TestVersioning, cls).resource_cleanup()
|
||||
|
||||
@testtools.testcase.attr('smoke')
|
||||
def test_availability_of_packages_with_different_versions(self):
|
||||
"""Test availability of packages with different versions.
|
||||
|
||||
1) Check two packages to have the same names.
|
||||
2) Check two packages to have different ids.
|
||||
3) Check two packages to be in repository.
|
||||
"""
|
||||
self.assertEqual(self.packages['1.0.0']['name'],
|
||||
self.packages['2.0.0']['name'])
|
||||
self.assertNotEqual(self.packages['1.0.0']['id'],
|
||||
self.packages['2.0.0']['id'])
|
||||
|
||||
# check packages availability
|
||||
artifact_packages = {pkg['id'] for pkg in
|
||||
self.artifacts_client.get_list_packages()}
|
||||
|
||||
self.assertIn(self.packages['1.0.0']['id'], artifact_packages)
|
||||
self.assertIn(self.packages['2.0.0']['id'], artifact_packages)
|
||||
|
||||
@testtools.testcase.attr('smoke')
|
||||
def test_deploy_packages_with_different_versions(self):
|
||||
"""Test deployment of packages with different versions.
|
||||
|
||||
1) Create environment.
|
||||
2) Add package with version 1.0.0 to the environment.
|
||||
3) Add package with version 2.0.0 to the environment.
|
||||
4) Deploy environment.
|
||||
5) Check if deployment status ok.
|
||||
"""
|
||||
|
||||
# create environment
|
||||
environment_name = utils.generate_name('create_environment')
|
||||
environment = self.application_catalog_client.create_environment(
|
||||
environment_name)
|
||||
self.addCleanup(self.application_catalog_client.delete_environment,
|
||||
environment['id'])
|
||||
|
||||
# create session
|
||||
session = self.application_catalog_client.create_session(
|
||||
environment['id'])
|
||||
|
||||
# add first application
|
||||
object_model = self.create_obj_model(self.packages['1.0.0'])
|
||||
|
||||
self.application_catalog_client.create_service(
|
||||
environment['id'], session['id'], object_model)
|
||||
|
||||
# add second application
|
||||
object_model = self.create_obj_model(self.packages['2.0.0'])
|
||||
|
||||
self.application_catalog_client.create_service(
|
||||
environment['id'], session['id'], object_model)
|
||||
|
||||
self.application_catalog_client.deploy_session(
|
||||
environment['id'], session['id'])
|
||||
|
||||
deploy_result = utils.wait_for_environment_deploy(
|
||||
self.application_catalog_client, environment['id'])['status']
|
||||
|
||||
self.assertEqual(deploy_result, 'ready')
|
||||
|
||||
@testtools.testcase.attr('smoke')
|
||||
def test_deploy_package_with_required_package_version(self):
|
||||
"""Test deployment of package which requires package with present version.
|
||||
|
||||
1) Create environment.
|
||||
2) Add to the environment package which requires version 2.0.0 of the
|
||||
package, which is present with versions 1.0.0 and 2.0.0 in repository.
|
||||
3) Deploy environment.
|
||||
4) Check if deployment status ok.
|
||||
"""
|
||||
|
||||
# create environment
|
||||
environment_name = utils.generate_name('create_environment')
|
||||
environment = self.application_catalog_client.create_environment(
|
||||
environment_name)
|
||||
self.addCleanup(self.application_catalog_client.delete_environment,
|
||||
environment['id'])
|
||||
|
||||
# create session
|
||||
session = self.application_catalog_client.create_session(
|
||||
environment['id'])
|
||||
|
||||
object_model = self.create_obj_model(
|
||||
self.packages['require_for_2.0.0'])
|
||||
|
||||
self.application_catalog_client.create_service(
|
||||
environment['id'], session['id'], object_model)
|
||||
|
||||
self.application_catalog_client.deploy_session(
|
||||
environment['id'], session['id'])
|
||||
|
||||
deploy_result = utils.wait_for_environment_deploy(
|
||||
self.application_catalog_client, environment['id'])['status']
|
||||
|
||||
self.assertEqual(deploy_result, 'ready')
|
|
@ -0,0 +1,97 @@
|
|||
# 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 six
|
||||
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 TestVersioningNegative(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(TestVersioningNegative, cls).resource_setup()
|
||||
|
||||
# create package with version 1.0.0
|
||||
application_name = utils.generate_name('package_test')
|
||||
provided_version = '1.0.0'
|
||||
package1, path1 = cls.upload_package(
|
||||
application_name, version=provided_version)
|
||||
|
||||
# main application
|
||||
expected_version = '2.0.0'
|
||||
main_app_name = utils.generate_name('main_package_test')
|
||||
require = [(package1['name'], expected_version)]
|
||||
package2, path2 = cls.upload_package(main_app_name, require=require)
|
||||
|
||||
cls.packages = {
|
||||
'1.0.0': package1,
|
||||
'require_for_1.0.0': package2
|
||||
}
|
||||
cls.abs_archive_paths = [path1, path2]
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
for pkg in six.itervalues(cls.packages):
|
||||
cls.artifacts_client.delete_package(pkg['id'])
|
||||
map(os.remove, cls.abs_archive_paths)
|
||||
super(TestVersioningNegative, cls).resource_cleanup()
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
@testtools.testcase.attr('smoke')
|
||||
def test_deploy_package_with_no_required_package_version(self):
|
||||
"""Test deployment of package which requires package with absent version.
|
||||
|
||||
1) Create environment.
|
||||
2) Add to the environment package which requires version 2.0.0 of the
|
||||
package, which is present with version 1.0.0 only in repository.
|
||||
3) Deploy environment.
|
||||
4) Check if deployment status failure.
|
||||
"""
|
||||
|
||||
# create environment
|
||||
environment_name = utils.generate_name('create_environment')
|
||||
environment = self.application_catalog_client.create_environment(
|
||||
environment_name)
|
||||
self.addCleanup(self.application_catalog_client.delete_environment,
|
||||
environment['id'])
|
||||
|
||||
# create session
|
||||
session = self.application_catalog_client.create_session(
|
||||
environment['id'])
|
||||
|
||||
object_model = self.create_obj_model(
|
||||
self.packages['require_for_1.0.0'])
|
||||
|
||||
self.application_catalog_client.create_service(
|
||||
environment['id'], session['id'], object_model)
|
||||
|
||||
self.application_catalog_client.deploy_session(
|
||||
environment['id'], session['id'])
|
||||
|
||||
deploy_result = utils.wait_for_environment_deploy(
|
||||
self.application_catalog_client, environment['id'])['status']
|
||||
|
||||
self.assertEqual(deploy_result, 'deploy failure')
|
|
@ -16,6 +16,7 @@ import collections
|
|||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
import yaml
|
||||
import zipfile
|
||||
|
@ -35,7 +36,7 @@ MANIFEST = {'Format': 'MuranoPL/1.0',
|
|||
|
||||
def compose_package(app_name, manifest, package_dir,
|
||||
require=None, archive_dir=None, add_class_name=False,
|
||||
manifest_required=True):
|
||||
manifest_required=True, version=None):
|
||||
"""Composes a murano package
|
||||
|
||||
Composes package `app_name` with `manifest` file as a template for the
|
||||
|
@ -44,6 +45,13 @@ def compose_package(app_name, manifest, package_dir,
|
|||
Puts the resulting .zip file into `acrhive_dir` if present or in the
|
||||
`package_dir`.
|
||||
"""
|
||||
class_file_changes = add_class_name or require
|
||||
# store class file before changes
|
||||
if class_file_changes:
|
||||
class_path = os.path.join(package_dir, 'Classes', 'mock_muranopl.yaml')
|
||||
with open(class_path, 'r') as f:
|
||||
class_store = f.read()
|
||||
|
||||
if manifest_required:
|
||||
with open(manifest, 'w') as f:
|
||||
fqn = 'io.murano.apps.' + app_name
|
||||
|
@ -52,7 +60,10 @@ def compose_package(app_name, manifest, package_dir,
|
|||
mfest_copy['Name'] = app_name
|
||||
mfest_copy['Classes'] = {fqn: 'mock_muranopl.yaml'}
|
||||
if require:
|
||||
mfest_copy['Require'] = require
|
||||
mfest_copy['Require'] = {str(name): version
|
||||
for name, version in require}
|
||||
if version:
|
||||
mfest_copy['Version'] = version
|
||||
f.write(yaml.dump(mfest_copy, default_flow_style=False))
|
||||
|
||||
if add_class_name:
|
||||
|
@ -66,6 +77,20 @@ def compose_package(app_name, manifest, package_dir,
|
|||
with open(class_file, 'w') as f:
|
||||
f.write(contents)
|
||||
|
||||
if require:
|
||||
class_file = os.path.join(package_dir, 'Classes', 'mock_muranopl.yaml')
|
||||
with open(class_file, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
index_string = 'deploy:\n Body:\n '
|
||||
index = content.index(index_string) + len(index_string)
|
||||
class_names = [req[0][req[0].rfind('.') + 1:] for req in require]
|
||||
addition = "".join(["- new({})\n".format(name) + ' ' * 6
|
||||
for name in class_names])
|
||||
content = content[:index] + addition + content[index:]
|
||||
with open(class_file, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
name = app_name + '.zip'
|
||||
|
||||
if not archive_dir:
|
||||
|
@ -80,11 +105,17 @@ def compose_package(app_name, manifest, package_dir,
|
|||
arcname=os.path.join(os.path.relpath(root, package_dir), f)
|
||||
)
|
||||
|
||||
# restore class file after changes
|
||||
if class_file_changes:
|
||||
with open(class_path, 'w') as f:
|
||||
f.write(class_store)
|
||||
|
||||
return archive_path, name
|
||||
|
||||
|
||||
def prepare_package(name, require=None, add_class_name=False,
|
||||
app='MockApp', manifest_required=True):
|
||||
app='MockApp', manifest_required=True,
|
||||
version=None):
|
||||
"""Prepare package.
|
||||
|
||||
:param name: Package name to compose
|
||||
|
@ -98,7 +129,8 @@ def prepare_package(name, require=None, add_class_name=False,
|
|||
arc_path, filename = compose_package(
|
||||
name, os.path.join(app_dir, 'manifest.yaml'),
|
||||
app_dir, require=require, archive_dir=target_arc_path,
|
||||
add_class_name=add_class_name, manifest_required=manifest_required)
|
||||
add_class_name=add_class_name, manifest_required=manifest_required,
|
||||
version=version)
|
||||
return arc_path, target_arc_path, filename
|
||||
|
||||
|
||||
|
@ -477,3 +509,13 @@ def get_local_inheritance(classes):
|
|||
base_fqn = base_class
|
||||
result.setdefault(base_fqn, []).append(class_name)
|
||||
return result
|
||||
|
||||
|
||||
def wait_for_environment_deploy(client, environment_id,
|
||||
timeout=1800, interval=10):
|
||||
start_time = time.time()
|
||||
while client.get_environment(environment_id)['status'] == 'deploying':
|
||||
if time.time() - start_time > timeout:
|
||||
break
|
||||
time.sleep(interval)
|
||||
return client.get_environment(environment_id)
|
||||
|
|
Loading…
Reference in New Issue