[Manila] Add scenario for creation and deletion of Manila shares

List of changes:
- Added support of 'create' and 'delete' operations for shares.
- Added benchmark for creating and deleting shares without usage
of share networks.

Change-Id: I48adb06140f70c5d18139726f5af6d7e1ab93a47
This commit is contained in:
Valeriy Ponomaryov 2015-06-11 17:36:25 +03:00
parent 966830eaaa
commit 51e61a5d6b
8 changed files with 256 additions and 6 deletions

View File

@ -207,6 +207,24 @@
# (floating point value) # (floating point value)
#heat_stack_resume_poll_interval = 1.0 #heat_stack_resume_poll_interval = 1.0
# Delay between creating Manila share and polling for its status.
# (floating point value)
#manila_share_create_prepoll_delay = 2.0
# Timeout for Manila share creation. (floating point value)
#manila_share_create_timeout = 300.0
# Interval between checks when waiting for Manila share creation.
# (floating point value)
#manila_share_create_poll_interval = 3.0
# Timeout for Manila share deletion. (floating point value)
#manila_share_delete_timeout = 180.0
# Interval between checks when waiting for Manila share deletion.
# (floating point value)
#manila_share_delete_poll_interval = 2.0
# Time to sleep after start before polling for status (floating point # Time to sleep after start before polling for status (floating point
# value) # value)
#nova_server_start_prepoll_delay = 0.0 #nova_server_start_prepoll_delay = 0.0

View File

@ -32,3 +32,26 @@
sla: sla:
failure_rate: failure_rate:
max: 0 max: 0
ManilaShares.create_and_delete_share:
-
args:
share_proto: "nfs"
size: 1
min_sleep: 1
max_sleep: 2
runner:
type: "constant"
times: 4
concurrency: 4
context:
quotas:
manila:
shares: -1
gigabytes: -1
users:
tenants: 2
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -22,6 +22,32 @@ from rally.plugins.openstack.scenarios.manila import utils
class ManilaShares(utils.ManilaScenario): class ManilaShares(utils.ManilaScenario):
"""Benchmark scenarios for Manila shares.""" """Benchmark scenarios for Manila shares."""
@validation.validate_share_proto()
@validation.required_services(consts.Service.MANILA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["manila"]})
def create_and_delete_share(self, share_proto, size=1, min_sleep=0,
max_sleep=0, **kwargs):
"""Create and delete a share.
Optional 'min_sleep' and 'max_sleep' parameters allow the scenario
to simulate a pause between share creation and deletion
(of random duration from [min_sleep, max_sleep]).
:param share_proto: share protocol, valid values are NFS, CIFS,
GlusterFS and HDFS
:param size: share size in GB, should be greater than 0
:param min_sleep: minimum sleep time in seconds (non-negative)
:param max_sleep: maximum sleep time in seconds (non-negative)
:param kwargs: optional args to create a share
"""
share = self._create_share(
share_proto=share_proto,
size=size,
**kwargs)
self.sleep_between(min_sleep, max_sleep)
self._delete_share(share)
@validation.required_services(consts.Service.MANILA) @validation.required_services(consts.Service.MANILA)
@validation.required_openstack(users=True) @validation.required_openstack(users=True)
@base.scenario() @base.scenario()

View File

@ -13,12 +13,93 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import time
from oslo_config import cfg
from rally.benchmark.scenarios import base from rally.benchmark.scenarios import base
from rally.benchmark import utils as bench_utils
MANILA_BENCHMARK_OPTS = [
cfg.FloatOpt(
"manila_share_create_prepoll_delay",
default=2.0,
help="Delay between creating Manila share and polling for its "
"status."),
cfg.FloatOpt(
"manila_share_create_timeout",
default=300.0,
help="Timeout for Manila share creation."),
cfg.FloatOpt(
"manila_share_create_poll_interval",
default=3.0,
help="Interval between checks when waiting for Manila share "
"creation."),
cfg.FloatOpt(
"manila_share_delete_timeout",
default=180.0,
help="Timeout for Manila share deletion."),
cfg.FloatOpt(
"manila_share_delete_poll_interval",
default=2.0,
help="Interval between checks when waiting for Manila share "
"deletion."),
]
CONF = cfg.CONF
benchmark_group = cfg.OptGroup(name="benchmark", title="benchmark options")
CONF.register_opts(MANILA_BENCHMARK_OPTS, group=benchmark_group)
class ManilaScenario(base.Scenario): class ManilaScenario(base.Scenario):
"""Base class for Manila scenarios with basic atomic actions.""" """Base class for Manila scenarios with basic atomic actions."""
@base.atomic_action_timer("manila.create_share")
def _create_share(self, share_proto, size=1, **kwargs):
"""Create a share.
:param share_proto: share protocol for new share,
available values are NFS, CIFS, GlusterFS and HDFS.
:param size: size of a share in GB
:param snapshot_id: ID of the snapshot
:param name: name of new share
:param description: description of a share
:param metadata: optional metadata to set on share creation
:param share_network: either instance of ShareNetwork or str with ID
:param share_type: either instance of ShareType or str with ID
:param is_public: defines whether to set share as public or not.
:returns: instance of :class:`Share`
"""
if not kwargs.get("name"):
kwargs["name"] = self._generate_random_name()
share = self.clients("manila").shares.create(
share_proto, size, **kwargs)
time.sleep(CONF.benchmark.manila_share_create_prepoll_delay)
share = bench_utils.wait_for(
share,
is_ready=bench_utils.resource_is("available"),
update_resource=bench_utils.get_from_manager(),
timeout=CONF.benchmark.manila_share_create_timeout,
check_interval=CONF.benchmark.manila_share_create_poll_interval,
)
return share
@base.atomic_action_timer("manila.delete_share")
def _delete_share(self, share):
"""Delete the given share.
:param share: :class:`Share`
"""
share.delete()
error_statuses = ("error_deleting", )
bench_utils.wait_for_delete(
share,
update_resource=bench_utils.get_from_manager(error_statuses),
timeout=CONF.benchmark.manila_share_delete_timeout,
check_interval=CONF.benchmark.manila_share_delete_poll_interval)
@base.atomic_action_timer("manila.list_shares") @base.atomic_action_timer("manila.list_shares")
def _list_shares(self, detailed=True, search_opts=None): def _list_shares(self, detailed=True, search_opts=None):
"""Returns user shares list. """Returns user shares list.

View File

@ -0,0 +1,29 @@
{
"ManilaShares.create_and_delete_share": [
{
"args": {
"share_proto": "nfs",
"size": 1,
"min_sleep": 1,
"max_sleep": 2
},
"runner": {
"type": "constant",
"times": 2,
"concurrency": 2
},
"context": {
"quotas": {
"manila": {
"shares": -1,
"gigabytes": -1
}
},
"users": {
"tenants": 2,
"users_per_tenant": 1
}
}
}
]
}

View File

@ -0,0 +1,20 @@
---
ManilaShares.create_and_delete_share:
-
args:
share_proto: "nfs"
size: 1
min_sleep: 1
max_sleep: 2
runner:
type: "constant"
times: 2
concurrency: 2
context:
quotas:
manila:
shares: -1
gigabytes: -1
users:
tenants: 2
users_per_tenant: 1

View File

@ -23,6 +23,24 @@ from tests.unit import test
@ddt.ddt @ddt.ddt
class ManilaSharesTestCase(test.TestCase): class ManilaSharesTestCase(test.TestCase):
@ddt.data(
{"share_proto": "nfs", "size": 3},
{"share_proto": "cifs", "size": 4,
"share_network": "foo", "share_type": "bar"},
)
def test_create_and_delete_share(self, params):
fake_share = mock.MagicMock()
scenario = shares.ManilaShares()
scenario._create_share = mock.MagicMock(return_value=fake_share)
scenario.sleep_between = mock.MagicMock()
scenario._delete_share = mock.MagicMock()
scenario.create_and_delete_share(min_sleep=3, max_sleep=4, **params)
scenario._create_share.assert_called_once_with(**params)
scenario.sleep_between.assert_called_once_with(3, 4)
scenario._delete_share.assert_called_once_with(fake_share)
@ddt.data( @ddt.data(
{}, {},
{"detailed": True}, {"detailed": True},

View File

@ -19,30 +19,65 @@ import mock
from rally.plugins.openstack.scenarios.manila import utils from rally.plugins.openstack.scenarios.manila import utils
from tests.unit import test from tests.unit import test
MANILA_UTILS = "rally.plugins.openstack.scenarios.manila.utils.ManilaScenario." BM_UTILS = "rally.benchmark.utils."
@ddt.ddt @ddt.ddt
class ManilaScenarioTestCase(test.TestCase): class ManilaScenarioTestCase(test.ClientsTestCase):
def setUp(self): def setUp(self):
super(ManilaScenarioTestCase, self).setUp() super(ManilaScenarioTestCase, self).setUp()
self.scenario = utils.ManilaScenario() self.scenario = utils.ManilaScenario()
@mock.patch("time.sleep")
@mock.patch(BM_UTILS + "wait_for")
@mock.patch(BM_UTILS + "get_from_manager")
@mock.patch(BM_UTILS + "resource_is")
def test__create_share(self, mock_resource_is, mock_get_from_manager,
mock_wait_for, mock_sleep):
fake_name = "fake_name"
fake_share = mock.Mock()
self.clients("manila").shares.create.return_value = fake_share
self.scenario._generate_random_name = mock.Mock(return_value=fake_name)
self.scenario._create_share("nfs")
self.clients("manila").shares.create.assert_called_once_with(
"nfs", 1, name=fake_name)
mock_wait_for.assert_called_once_with(
fake_share, is_ready=mock.ANY, update_resource=mock.ANY,
timeout=300, check_interval=3)
mock_resource_is.assert_called_once_with("available")
mock_get_from_manager.assert_called_once_with()
self.assertTrue(mock_sleep.called)
@mock.patch(BM_UTILS + "get_from_manager")
@mock.patch(BM_UTILS + "wait_for_delete")
def test__delete_share(self, mock_wait_for_delete, mock_get_from_manager):
fake_share = mock.MagicMock()
self.scenario._delete_share(fake_share)
fake_share.delete.assert_called_once_with()
mock_get_from_manager.assert_called_once_with(("error_deleting", ))
mock_wait_for_delete.assert_called_once_with(
fake_share, update_resource=mock.ANY, timeout=180,
check_interval=2)
@ddt.data( @ddt.data(
{}, {},
{"detailed": False, "search_opts": None}, {"detailed": False, "search_opts": None},
{"detailed": True, "search_opts": {"name": "foo_sn"}}, {"detailed": True, "search_opts": {"name": "foo_sn"}},
{"search_opts": {"project_id": "fake_project"}}, {"search_opts": {"project_id": "fake_project"}},
) )
@mock.patch(MANILA_UTILS + "clients") def test__list_shares(self, params):
def test__list_shares(self, params, mock_clients):
fake_shares = ["foo", "bar"] fake_shares = ["foo", "bar"]
mock_clients.return_value.shares.list.return_value = fake_shares self.clients("manila").shares.list.return_value = fake_shares
result = self.scenario._list_shares(**params) result = self.scenario._list_shares(**params)
self.assertEqual(fake_shares, result) self.assertEqual(fake_shares, result)
mock_clients.return_value.shares.list.assert_called_once_with( self.clients("manila").shares.list.assert_called_once_with(
detailed=params.get("detailed", True), detailed=params.get("detailed", True),
search_opts=params.get("search_opts", None)) search_opts=params.get("search_opts", None))