208 lines
7.3 KiB
Python
208 lines
7.3 KiB
Python
# Copyright (c) 2015 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 json
|
|
import multiprocessing
|
|
import os
|
|
import shutil
|
|
import SocketServer
|
|
import tempfile
|
|
import time
|
|
import uuid
|
|
|
|
from six.moves import SimpleHTTPServer
|
|
from tempest_lib.cli import output_parser
|
|
from tempest_lib import exceptions
|
|
|
|
from muranoclient.tests.functional.cli import utils
|
|
from muranoclient.tests.functional import muranoclient
|
|
|
|
|
|
class CLIUtilsTestBase(muranoclient.ClientTestBase):
|
|
"""Basic methods for Murano CLI client."""
|
|
|
|
def delete_murano_object(self, murano_object, obj_to_del):
|
|
"""Delete Murano object like environment, category
|
|
or environment-template.
|
|
"""
|
|
if obj_to_del not in self.listing('{0}-list'.format(murano_object)):
|
|
return
|
|
object_list = self.listing('{0}-delete'.format(murano_object),
|
|
params=obj_to_del['ID'])
|
|
start_time = time.time()
|
|
while obj_to_del in self.listing('{0}-list'.format(murano_object)):
|
|
if start_time - time.time() > 60:
|
|
self.fail("{0} is not deleted in 60 seconds".
|
|
format(murano_object))
|
|
return object_list
|
|
|
|
def create_murano_object(self, murano_object, prefix_object_name):
|
|
"""Create Murano object like environment, category
|
|
or environment-template.
|
|
"""
|
|
object_name = self.generate_name(prefix_object_name)
|
|
mrn_objects = self.listing('{0}-create'.format(murano_object),
|
|
params=object_name)
|
|
mrn_object = None
|
|
for obj in mrn_objects:
|
|
if object_name == obj['Name']:
|
|
mrn_object = obj
|
|
break
|
|
if mrn_object is None:
|
|
self.fail("Murano {0} has not been created!".format(murano_object))
|
|
|
|
self.addCleanup(self.delete_murano_object, murano_object, mrn_object)
|
|
return mrn_object
|
|
|
|
@staticmethod
|
|
def generate_uuid():
|
|
"""Generate uuid for objects."""
|
|
return uuid.uuid4().hex
|
|
|
|
@staticmethod
|
|
def generate_name(prefix):
|
|
"""Generate name for objects."""
|
|
suffix = CLIUtilsTestBase.generate_uuid()[:8]
|
|
return "{0}_{1}".format(prefix, suffix)
|
|
|
|
def get_table_struct(self, command, params=""):
|
|
"""Get table structure i.e. header of table."""
|
|
return output_parser.table(self.murano(command,
|
|
params=params))['headers']
|
|
|
|
def get_object(self, object_list, object_value):
|
|
""""Get Murano object by value from list of Murano objects."""
|
|
for obj in object_list:
|
|
if object_value in obj.values():
|
|
return obj
|
|
|
|
def get_property_value(self, obj, prop):
|
|
return [o['Value'] for o in obj
|
|
if o['Property'] == '{0}'.format(prop)][0]
|
|
|
|
|
|
class TestSuiteRepository(CLIUtilsTestBase):
|
|
|
|
def setUp(self):
|
|
super(TestSuiteRepository, self).setUp()
|
|
self.serve_dir = tempfile.mkdtemp(suffix="repo")
|
|
self.app_name = self.generate_name("dummy_app")
|
|
self.dummy_app_path = self._compose_app(name=self.app_name)
|
|
|
|
def tearDown(self):
|
|
super(TestSuiteRepository, self).tearDown()
|
|
shutil.rmtree(self.serve_dir)
|
|
|
|
def run_server(self):
|
|
def serve_function():
|
|
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
|
pass
|
|
os.chdir(self.serve_dir)
|
|
httpd = SocketServer.TCPServer(
|
|
("0.0.0.0", 8089),
|
|
Handler, bind_and_activate=False)
|
|
httpd.allow_reuse_address = True
|
|
httpd.server_bind()
|
|
httpd.server_activate()
|
|
httpd.serve_forever()
|
|
self.p = multiprocessing.Process(target=serve_function)
|
|
self.p.start()
|
|
|
|
def stop_server(self):
|
|
self.p.terminate()
|
|
|
|
def _compose_app(self, name, require=None):
|
|
package_dir = os.path.join(self.serve_dir, 'apps/', name)
|
|
shutil.copytree(os.path.join(os.path.dirname(
|
|
os.path.realpath(__file__)), 'MockApp'), package_dir)
|
|
|
|
app_name = utils.compose_package(
|
|
name,
|
|
os.path.join(package_dir, 'manifest.yaml'),
|
|
package_dir,
|
|
require=require,
|
|
archive_dir=os.path.join(self.serve_dir, 'apps/'),
|
|
)
|
|
|
|
return app_name
|
|
|
|
|
|
class CLIUtilsTestPackagesBase(TestSuiteRepository):
|
|
"""Basic methods for Murano Packages CLI client."""
|
|
|
|
def import_package(self, pkg_name, pkg_path, *args):
|
|
"""Create Murano dummy package and import it by url."""
|
|
|
|
actions = ' '.join(args)
|
|
params = '{0} {1}'.format(pkg_path, actions)
|
|
package = self.listing('package-import', params=params)
|
|
package = self.get_object(package, pkg_name)
|
|
self.addCleanup(self.delete_murano_object, 'package', package)
|
|
|
|
return package
|
|
|
|
def prepare_file_with_obj_model(self, obj_model):
|
|
temp_file = tempfile.NamedTemporaryFile(prefix="murano-obj-model",
|
|
delete=False)
|
|
self.addCleanup(os.remove, temp_file.name)
|
|
|
|
with open(temp_file.name, 'w') as tf:
|
|
tf.write(json.dumps([obj_model]))
|
|
|
|
return temp_file.name
|
|
|
|
def wait_deployment_result(self, env_id, timeout=180):
|
|
start_time = time.time()
|
|
|
|
env = self.listing('environment-show', params=env_id)
|
|
env_status = self.get_property_value(env, 'status')
|
|
|
|
expected_statuses = ['ready', 'deploying']
|
|
|
|
while env_status != 'ready':
|
|
if time.time() - start_time > timeout:
|
|
msg = ("Environment exceeds timeout {0} to change state "
|
|
"to Ready. Environment: {1}".format(timeout, env))
|
|
raise exceptions.TimeoutException(msg)
|
|
|
|
env = self.listing('environment-show', params=env_id)
|
|
env_status = self.get_property_value(env, 'status')
|
|
|
|
if env_status not in expected_statuses:
|
|
msg = ("Environment status %s is not in expected "
|
|
"statuses: %s" % (env_status, expected_statuses))
|
|
raise exceptions.TempestException(msg)
|
|
|
|
time.sleep(2)
|
|
|
|
return True
|
|
|
|
def deploy_environment(self, env_id, obj_model):
|
|
session = self.listing('environment-session-create',
|
|
params=env_id)
|
|
session_id = self.get_property_value(session, 'id')
|
|
|
|
temp_file = self.prepare_file_with_obj_model(obj_model)
|
|
|
|
self.listing('environment-apps-edit',
|
|
params='--session-id {0} {1} {2}'.
|
|
format(session_id, env_id, temp_file))
|
|
|
|
self.listing('environment-deploy',
|
|
params='{0} --session-id {1}'.
|
|
format(env_id, session_id))
|
|
|
|
result = self.wait_deployment_result(env_id)
|
|
self.assertTrue(result)
|