Add new Murano scenarios
- added four new Murano scenarios which check performance of commands which work with packages, like 'import-package', 'list-packages', 'delete-package'. - added appropriate methods into the murano/utils.py - added unit tests Change-Id: I655bb0c8a0980c59cd4ab576f97ee94c2c3cd0f7
This commit is contained in:
parent
79f8809245
commit
a04841e71f
@ -5,6 +5,6 @@ Name: HelloReporter
|
||||
Description: |
|
||||
HelloReporter test app.
|
||||
Author: 'Mirantis, Inc'
|
||||
Tags: [App, Test, HelloWorld]
|
||||
Tags: []
|
||||
Classes:
|
||||
io.murano.apps.HelloReporter: HelloReporter.yaml
|
||||
|
@ -61,6 +61,84 @@
|
||||
app_package: "/home/jenkins/.rally/extra/murano/applications/HelloReporter/io.murano.apps.HelloReporter/"
|
||||
roles:
|
||||
- "admin"
|
||||
|
||||
MuranoPackages.import_and_list_packages:
|
||||
-
|
||||
args:
|
||||
package: "/home/jenkins/.rally/extra/murano/applications/HelloReporter/io.murano.apps.HelloReporter/"
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 2
|
||||
context:
|
||||
users:
|
||||
tenants: 2
|
||||
users_per_tenant: 2
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
-
|
||||
args:
|
||||
package: "/home/jenkins/.rally/extra/murano/applications/HelloReporter/io.murano.apps.HelloReporter.zip"
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 1
|
||||
concurrency: 1
|
||||
context:
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
MuranoPackages.import_and_delete_package:
|
||||
-
|
||||
args:
|
||||
package: "/home/jenkins/.rally/extra/murano/applications/HelloReporter/io.murano.apps.HelloReporter/"
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 2
|
||||
context:
|
||||
users:
|
||||
tenants: 2
|
||||
users_per_tenant: 2
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
MuranoPackages.import_and_filter_applications:
|
||||
-
|
||||
args:
|
||||
package: "/home/jenkins/.rally/extra/murano/applications/HelloReporter/io.murano.apps.HelloReporter/"
|
||||
filter_query: {"category" : "Web"}
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 2
|
||||
context:
|
||||
users:
|
||||
tenants: 2
|
||||
users_per_tenant: 2
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
MuranoPackages.package_lifecycle:
|
||||
-
|
||||
args:
|
||||
package: "/home/jenkins/.rally/extra/murano/applications/HelloReporter/io.murano.apps.HelloReporter/"
|
||||
body: {"categories": ["Web"]}
|
||||
operation: "add"
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 2
|
||||
context:
|
||||
users:
|
||||
tenants: 2
|
||||
users_per_tenant: 2
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
142
rally/plugins/openstack/scenarios/murano/packages.py
Normal file
142
rally/plugins/openstack/scenarios/murano/packages.py
Normal file
@ -0,0 +1,142 @@
|
||||
# Copyright 2015: 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 os
|
||||
|
||||
from rally import consts
|
||||
from rally.plugins.openstack.scenarios.murano import utils
|
||||
from rally.task import scenario
|
||||
from rally.task import validation
|
||||
|
||||
|
||||
class MuranoPackages(utils.MuranoScenario):
|
||||
"""Benchmark scenarios for Murano packages."""
|
||||
|
||||
@validation.required_parameters("package")
|
||||
@validation.file_exists(param_name="package", mode=os.F_OK)
|
||||
@validation.required_clients("murano")
|
||||
@validation.required_services(consts.Service.MURANO)
|
||||
@validation.required_openstack(users=True)
|
||||
@scenario.configure(context={"cleanup": ["murano.packages"]})
|
||||
def import_and_list_packages(self, package, include_disabled=False):
|
||||
"""Import Murano package and get list of packages.
|
||||
|
||||
Measure the "murano import-package" and "murano package-list" commands
|
||||
performance.
|
||||
It imports Murano package from "package" (if it is not a zip archive
|
||||
then zip archive will be prepared) and gets list of imported packages.
|
||||
|
||||
:param package: path to zip archive that represents Murano
|
||||
application package or absolute path to folder with
|
||||
package components
|
||||
:param include_disabled: specifies whether the disabled packages will
|
||||
be included in a the result or not.
|
||||
Default value is False.
|
||||
"""
|
||||
package_path = self._zip_package(package)
|
||||
try:
|
||||
self._import_package(package_path)
|
||||
self._list_packages(include_disabled=include_disabled)
|
||||
finally:
|
||||
os.remove(package_path)
|
||||
|
||||
@validation.required_parameters("package")
|
||||
@validation.file_exists(param_name="package", mode=os.F_OK)
|
||||
@validation.required_clients("murano")
|
||||
@validation.required_services(consts.Service.MURANO)
|
||||
@validation.required_openstack(users=True)
|
||||
@scenario.configure(context={"cleanup": ["murano.packages"]})
|
||||
def import_and_delete_package(self, package):
|
||||
"""Import Murano package and then delete it.
|
||||
|
||||
Measure the "murano import-package" and "murano package-delete"
|
||||
commands performance.
|
||||
It imports Murano package from "package" (if it is not a zip archive
|
||||
then zip archive will be prepared) and deletes it.
|
||||
|
||||
:param package: path to zip archive that represents Murano
|
||||
application package or absolute path to folder with
|
||||
package components
|
||||
"""
|
||||
package_path = self._zip_package(package)
|
||||
try:
|
||||
package = self._import_package(package_path)
|
||||
self._delete_package(package)
|
||||
finally:
|
||||
os.remove(package_path)
|
||||
|
||||
@validation.required_parameters("package", "body")
|
||||
@validation.file_exists(param_name="package", mode=os.F_OK)
|
||||
@validation.required_clients("murano")
|
||||
@validation.required_services(consts.Service.MURANO)
|
||||
@validation.required_openstack(users=True)
|
||||
@scenario.configure(context={"cleanup": ["murano.packages"]})
|
||||
def package_lifecycle(self, package, body, operation="replace"):
|
||||
"""Import Murano package, modify it and then delete it.
|
||||
|
||||
Measure the Murano import, update and delete package
|
||||
commands performance.
|
||||
It imports Murano package from "package" (if it is not a zip archive
|
||||
then zip archive will be prepared), modifies it (using data from
|
||||
"body") and deletes.
|
||||
|
||||
:param package: path to zip archive that represents Murano
|
||||
application package or absolute path to folder with
|
||||
package components
|
||||
:param body: dict object that defines what package property will be
|
||||
updated, e.g {"tags": ["tag"]} or {"enabled": "true"}
|
||||
:param operation: string object that defines the way of how package
|
||||
property will be updated, allowed operations are
|
||||
"add", "replace" or "delete".
|
||||
Default value is "replace".
|
||||
|
||||
"""
|
||||
package_path = self._zip_package(package)
|
||||
try:
|
||||
package = self._import_package(package_path)
|
||||
self._update_package(package, body, operation)
|
||||
self._delete_package(package)
|
||||
finally:
|
||||
os.remove(package_path)
|
||||
|
||||
@validation.required_parameters("package", "filter_query")
|
||||
@validation.file_exists(param_name="package", mode=os.F_OK)
|
||||
@validation.required_clients("murano")
|
||||
@validation.required_services(consts.Service.MURANO)
|
||||
@validation.required_openstack(users=True)
|
||||
@scenario.configure(context={"cleanup": ["murano.packages"]})
|
||||
def import_and_filter_applications(self, package, filter_query):
|
||||
"""Import Murano package and then filter packages by some criteria.
|
||||
|
||||
Measure the performance of package import and package
|
||||
filtering commands.
|
||||
It imports Murano package from "package" (if it is not a zip archive
|
||||
then zip archive will be prepared) and filters packages by some
|
||||
criteria.
|
||||
|
||||
:param package: path to zip archive that represents Murano
|
||||
application package or absolute path to folder with
|
||||
package components
|
||||
:param filter_query: dict that contains filter criteria, lately it
|
||||
will be passed as **kwargs to filter method
|
||||
e.g. {"category": "Web"}
|
||||
"""
|
||||
package_path = self._zip_package(package)
|
||||
try:
|
||||
self._import_package(package_path)
|
||||
self._filter_applications(filter_query)
|
||||
finally:
|
||||
os.remove(package_path)
|
@ -13,10 +13,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import uuid
|
||||
import zipfile
|
||||
|
||||
from oslo_config import cfg
|
||||
import yaml
|
||||
|
||||
from rally.common import fileutils
|
||||
from rally.common import utils as common_utils
|
||||
from rally.plugins.openstack import scenario
|
||||
from rally.task import atomic
|
||||
from rally.task import utils
|
||||
@ -31,7 +38,7 @@ MURANO_TIMEOUT_OPTS = [
|
||||
cfg.IntOpt("delete_environment_check_interval", default=2,
|
||||
help="Delete environment check interval in seconds"),
|
||||
cfg.IntOpt("deploy_environment_check_interval", default=5,
|
||||
help="Deploy environment check interval in seconds")
|
||||
help="Deploy environment check interval in seconds"),
|
||||
]
|
||||
|
||||
benchmark_group = cfg.OptGroup(name="benchmark", title="benchmark options")
|
||||
@ -125,3 +132,149 @@ class MuranoScenario(scenario.OpenStackScenario):
|
||||
timeout=CONF.benchmark.deploy_environment_timeout,
|
||||
check_interval=CONF.benchmark.deploy_environment_check_interval
|
||||
)
|
||||
|
||||
@atomic.action_timer("murano.list_packages")
|
||||
def _list_packages(self, include_disabled=False):
|
||||
"""Returns packages list.
|
||||
|
||||
:param include_disabled: if "True" then disabled packages will be
|
||||
included in a the result.
|
||||
Default value is False.
|
||||
:returns: list of imported packages
|
||||
"""
|
||||
return self.clients("murano").packages.list(
|
||||
include_disabled=include_disabled)
|
||||
|
||||
@atomic.action_timer("murano.import_package")
|
||||
def _import_package(self, package):
|
||||
"""Import package to the Murano.
|
||||
|
||||
:param package: path to zip archive with Murano application
|
||||
:returns: imported package
|
||||
"""
|
||||
|
||||
package = self.clients("murano").packages.create(
|
||||
{}, {"file": open(package)}
|
||||
)
|
||||
|
||||
return package
|
||||
|
||||
@atomic.action_timer("murano.delete_package")
|
||||
def _delete_package(self, package):
|
||||
"""Delete specified package.
|
||||
|
||||
:param package: package that will be deleted
|
||||
"""
|
||||
|
||||
self.clients("murano").packages.delete(package.id)
|
||||
|
||||
@atomic.action_timer("murano.update_package")
|
||||
def _update_package(self, package, body, operation="replace"):
|
||||
"""Update specified package.
|
||||
|
||||
:param package: package that will be updated
|
||||
:param body: dict object that defines what package property will be
|
||||
updated, e.g {"tags": ["tag"]} or {"enabled": "true"}
|
||||
:param operation: string object that defines the way of how package
|
||||
property will be updated, allowed operations are
|
||||
"add", "replace" or "delete".
|
||||
Default value is "replace".
|
||||
:returns: updated package
|
||||
"""
|
||||
|
||||
return self.clients("murano").packages.update(
|
||||
package.id, body, operation)
|
||||
|
||||
@atomic.action_timer("murano.filter_applications")
|
||||
def _filter_applications(self, filter_query):
|
||||
"""Filter list of uploaded application by specified criteria.
|
||||
|
||||
:param filter_query: dict that contains filter criteria, it
|
||||
will be passed as **kwargs to filter method
|
||||
e.g. {"category": "Web"}
|
||||
:returns: filtered list of packages
|
||||
"""
|
||||
|
||||
return self.clients("murano").packages.filter(**filter_query)
|
||||
|
||||
def _zip_package(self, package_path):
|
||||
"""Call _prepare_package method that returns path to zip archive."""
|
||||
return MuranoPackageManager()._prepare_package(package_path)
|
||||
|
||||
|
||||
class MuranoPackageManager(object):
|
||||
|
||||
@staticmethod
|
||||
def _read_from_file(filename):
|
||||
with open(filename, "r") as f:
|
||||
read_data = f.read()
|
||||
return yaml.safe_load(read_data)
|
||||
|
||||
@staticmethod
|
||||
def _write_to_file(data, filename):
|
||||
with open(filename, "w") as f:
|
||||
yaml.safe_dump(data, f)
|
||||
|
||||
def _change_app_fullname(self, app_dir):
|
||||
"""Change application full name.
|
||||
|
||||
To avoid name conflict error during package import (when user
|
||||
tries to import a few packages into the same tenant) need to change the
|
||||
application name. For doing this need to replace following parts
|
||||
in manifest.yaml
|
||||
from
|
||||
...
|
||||
FullName: app.name
|
||||
...
|
||||
Classes:
|
||||
app.name: app_class.yaml
|
||||
to:
|
||||
...
|
||||
FullName: <new_name>
|
||||
...
|
||||
Classes:
|
||||
<new_name>: app_class.yaml
|
||||
|
||||
:param app_dir: path to directory with Murano application context
|
||||
"""
|
||||
|
||||
new_fullname = common_utils.generate_random_name("app.")
|
||||
|
||||
manifest_file = os.path.join(app_dir, "manifest.yaml")
|
||||
manifest = self._read_from_file(manifest_file)
|
||||
|
||||
class_file_name = manifest["Classes"][manifest["FullName"]]
|
||||
|
||||
# update manifest.yaml file
|
||||
del manifest["Classes"][manifest["FullName"]]
|
||||
manifest["FullName"] = new_fullname
|
||||
manifest["Classes"][new_fullname] = class_file_name
|
||||
self._write_to_file(manifest, manifest_file)
|
||||
|
||||
def _prepare_package(self, package_path):
|
||||
"""Check whether the package path is path to zip archive or not.
|
||||
|
||||
If package_path is not a path to zip archive but path to Murano
|
||||
application folder, than method prepares zip archive with Murano
|
||||
application. It copies directory with Murano app files to temporary
|
||||
folder, changes manifest.yaml and class file (to avoid '409 Conflict'
|
||||
errors in Murano) and prepares zip package.
|
||||
|
||||
:param package_path: path to zip archive or directory with package
|
||||
components
|
||||
:returns: path to zip archive with Murano application
|
||||
"""
|
||||
|
||||
if not zipfile.is_zipfile(package_path):
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
pkg_dir = os.path.join(tmp_dir, "package/")
|
||||
try:
|
||||
shutil.copytree(package_path, pkg_dir)
|
||||
|
||||
self._change_app_fullname(pkg_dir)
|
||||
package_path = fileutils.pack_dir(pkg_dir)
|
||||
|
||||
finally:
|
||||
shutil.rmtree(tmp_dir)
|
||||
|
||||
return package_path
|
||||
|
@ -0,0 +1,79 @@
|
||||
# Copyright 2015: 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 mock
|
||||
|
||||
from rally.plugins.openstack.scenarios.murano import packages
|
||||
from tests.unit import test
|
||||
|
||||
MURANO_SCENARIO = ("rally.plugins.openstack.scenarios.murano."
|
||||
"packages.MuranoPackages")
|
||||
|
||||
|
||||
class MuranoPackagesTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(MuranoPackagesTestCase, self).setUp()
|
||||
self.scenario = packages.MuranoPackages()
|
||||
self.scenario._import_package = mock.Mock()
|
||||
self.scenario._zip_package = mock.Mock()
|
||||
self.scenario._list_packages = mock.Mock()
|
||||
self.scenario._delete_package = mock.Mock()
|
||||
self.scenario._update_package = mock.Mock()
|
||||
self.scenario._filter_applications = mock.Mock()
|
||||
self.mock_remove = mock.patch("os.remove")
|
||||
self.mock_remove.start()
|
||||
|
||||
def tearDown(self):
|
||||
super(MuranoPackagesTestCase, self).tearDown()
|
||||
self.mock_remove.stop()
|
||||
|
||||
def test_make_zip_import_and_list_packages(self):
|
||||
self.scenario.import_and_list_packages("foo_package.zip")
|
||||
self.scenario._import_package.assert_called_once_with(
|
||||
self.scenario._zip_package.return_value)
|
||||
self.scenario._zip_package.assert_called_once_with("foo_package.zip")
|
||||
self.scenario._list_packages.assert_called_once_with(
|
||||
include_disabled=False)
|
||||
|
||||
def test_import_and_delete_package(self):
|
||||
fake_package = mock.Mock()
|
||||
self.scenario._import_package.return_value = fake_package
|
||||
self.scenario.import_and_delete_package("foo_package.zip")
|
||||
self.scenario._import_package.assert_called_once_with(
|
||||
self.scenario._zip_package.return_value)
|
||||
self.scenario._delete_package.assert_called_once_with(fake_package)
|
||||
|
||||
def test_package_lifecycle(self):
|
||||
fake_package = mock.Mock()
|
||||
self.scenario._import_package.return_value = fake_package
|
||||
self.scenario.package_lifecycle(
|
||||
"foo_package.zip", {"category": "Web"}, "add")
|
||||
self.scenario._import_package.assert_called_once_with(
|
||||
self.scenario._zip_package.return_value)
|
||||
self.scenario._update_package.assert_called_once_with(
|
||||
fake_package, {"category": "Web"}, "add")
|
||||
self.scenario._delete_package.assert_called_once_with(fake_package)
|
||||
|
||||
def test_import_and_filter_applications(self):
|
||||
fake_package = mock.Mock()
|
||||
self.scenario._import_package.return_value = fake_package
|
||||
self.scenario.import_and_filter_applications(
|
||||
"foo_package.zip", {"category": "Web"})
|
||||
self.scenario._import_package.assert_called_once_with(
|
||||
self.scenario._zip_package.return_value)
|
||||
self.scenario._filter_applications.assert_called_once_with(
|
||||
{"category": "Web"}
|
||||
)
|
@ -105,3 +105,129 @@ class MuranoScenarioTestCase(test.ScenarioTestCase):
|
||||
self.mock_resource_is.mock.assert_called_once_with("READY")
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"murano.deploy_environment")
|
||||
|
||||
@mock.patch(MRN_UTILS + ".open",
|
||||
side_effect=mock.mock_open(read_data="Key: value"),
|
||||
create=True)
|
||||
def test_read_from_file(self, mock_open):
|
||||
utility = utils.MuranoPackageManager()
|
||||
data = utility._read_from_file("filename")
|
||||
expected_data = {"Key": "value"}
|
||||
self.assertEqual(expected_data, data)
|
||||
|
||||
@mock.patch(MRN_UTILS + ".MuranoPackageManager._read_from_file")
|
||||
@mock.patch(MRN_UTILS + ".MuranoPackageManager._write_to_file")
|
||||
def test_change_app_fullname(
|
||||
self, mock_murano_package_manager__write_to_file,
|
||||
mock_murano_package_manager__read_from_file):
|
||||
manifest = {"FullName": "app.name_abc",
|
||||
"Classes": {"app.name_abc": "app_class.yaml"}}
|
||||
mock_murano_package_manager__read_from_file.side_effect = (
|
||||
[manifest])
|
||||
utility = utils.MuranoPackageManager()
|
||||
utility._change_app_fullname("tmp/tmpfile/")
|
||||
mock_murano_package_manager__read_from_file.assert_has_calls(
|
||||
[mock.call("tmp/tmpfile/manifest.yaml")]
|
||||
)
|
||||
mock_murano_package_manager__write_to_file.assert_has_calls(
|
||||
[mock.call(manifest, "tmp/tmpfile/manifest.yaml")]
|
||||
)
|
||||
|
||||
@mock.patch("zipfile.is_zipfile")
|
||||
@mock.patch("tempfile.mkdtemp")
|
||||
@mock.patch("shutil.copytree")
|
||||
@mock.patch(MRN_UTILS + ".MuranoPackageManager._change_app_fullname")
|
||||
@mock.patch("rally.common.fileutils.pack_dir")
|
||||
@mock.patch("shutil.rmtree")
|
||||
def test_prepare_zip_if_not_zip(
|
||||
self, mock_shutil_rmtree, mock_pack_dir,
|
||||
mock_murano_package_manager__change_app_fullname,
|
||||
mock_shutil_copytree, mock_tempfile_mkdtemp,
|
||||
mock_zipfile_is_zipfile):
|
||||
utility = utils.MuranoPackageManager()
|
||||
package_path = "tmp/tmpfile"
|
||||
|
||||
mock_zipfile_is_zipfile.return_value = False
|
||||
mock_tempfile_mkdtemp.return_value = "tmp/tmpfile"
|
||||
mock_pack_dir.return_value = "tmp/tmpzipfile"
|
||||
|
||||
zip_file = utility._prepare_package(package_path)
|
||||
|
||||
self.assertEqual("tmp/tmpzipfile", zip_file)
|
||||
mock_tempfile_mkdtemp.assert_called_once_with()
|
||||
mock_shutil_copytree.assert_called_once_with(
|
||||
"tmp/tmpfile",
|
||||
"tmp/tmpfile/package/"
|
||||
)
|
||||
(mock_murano_package_manager__change_app_fullname.
|
||||
assert_called_once_with("tmp/tmpfile/package/"))
|
||||
mock_shutil_rmtree.assert_called_once_with("tmp/tmpfile")
|
||||
|
||||
@mock.patch("zipfile.is_zipfile")
|
||||
def test_prepare_zip_if_zip(self, mock_zipfile_is_zipfile):
|
||||
utility = utils.MuranoPackageManager()
|
||||
package_path = "tmp/tmpfile.zip"
|
||||
mock_zipfile_is_zipfile.return_value = True
|
||||
zip_file = utility._prepare_package(package_path)
|
||||
self.assertEqual("tmp/tmpfile.zip", zip_file)
|
||||
|
||||
def test_list_packages(self):
|
||||
scenario = utils.MuranoScenario()
|
||||
self.assertEqual(self.clients("murano").packages.list.return_value,
|
||||
scenario._list_packages())
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"murano.list_packages")
|
||||
|
||||
@mock.patch(MRN_UTILS + ".open", create=True)
|
||||
def test_import_package(self, mock_open):
|
||||
self.clients("murano").packages.create.return_value = (
|
||||
"created_foo_package"
|
||||
)
|
||||
scenario = utils.MuranoScenario()
|
||||
mock_open.return_value = "opened_foo_package.zip"
|
||||
imp_package = scenario._import_package("foo_package.zip")
|
||||
self.assertEqual("created_foo_package", imp_package)
|
||||
self.clients("murano").packages.create.assert_called_once_with(
|
||||
{}, {"file": "opened_foo_package.zip"})
|
||||
mock_open.assert_called_once_with("foo_package.zip")
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"murano.import_package")
|
||||
|
||||
def test_delete_package(self):
|
||||
package = mock.Mock(id="package_id")
|
||||
scenario = utils.MuranoScenario()
|
||||
scenario._delete_package(package)
|
||||
self.clients("murano").packages.delete.assert_called_once_with(
|
||||
"package_id"
|
||||
)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"murano.delete_package")
|
||||
|
||||
def test_update_package(self):
|
||||
package = mock.Mock(id="package_id")
|
||||
self.clients("murano").packages.update.return_value = "updated_package"
|
||||
scenario = utils.MuranoScenario()
|
||||
upd_package = scenario._update_package(
|
||||
package, {"tags": ["tag"]}, "add"
|
||||
)
|
||||
self.assertEqual("updated_package", upd_package)
|
||||
self.clients("murano").packages.update.assert_called_once_with(
|
||||
"package_id",
|
||||
{"tags": ["tag"]},
|
||||
"add"
|
||||
)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"murano.update_package")
|
||||
|
||||
def test_filter_packages(self):
|
||||
self.clients("murano").packages.filter.return_value = []
|
||||
scenario = utils.MuranoScenario()
|
||||
return_apps_list = scenario._filter_applications(
|
||||
{"category": "Web"}
|
||||
)
|
||||
self.assertEqual([], return_apps_list)
|
||||
self.clients("murano").packages.filter.assert_called_once_with(
|
||||
category="Web"
|
||||
)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"murano.filter_applications")
|
||||
|
Loading…
Reference in New Issue
Block a user