[Manila] Add scenarios for Manila share metadata
List of changes: - Added support for 'set' and 'delete' operations for share metadata. - Added benchmark for setting and deleting share metadata. Change-Id: I0ecb8c13218f23fd359045b05e0b596455b401b9
This commit is contained in:
parent
02435f13f7
commit
e63d7e7567
@ -58,3 +58,35 @@
|
||||
failure_rate:
|
||||
max: 0
|
||||
{% endfor %}
|
||||
|
||||
|
||||
ManilaShares.set_and_delete_metadata:
|
||||
-
|
||||
args:
|
||||
sets: 1
|
||||
set_size: 3
|
||||
delete_size: 3
|
||||
key_min_length: 1
|
||||
key_max_length: 256
|
||||
value_min_length: 1
|
||||
value_max_length: 1024
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 10
|
||||
context:
|
||||
quotas:
|
||||
manila:
|
||||
shares: -1
|
||||
gigabytes: -1
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
manila_shares:
|
||||
shares_per_tenant: 1
|
||||
share_proto: "NFS"
|
||||
size: 1
|
||||
share_type: "dhss_false"
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
@ -162,3 +162,37 @@
|
||||
failure_rate:
|
||||
max: 0
|
||||
{% endfor %}
|
||||
|
||||
ManilaShares.set_and_delete_metadata:
|
||||
-
|
||||
args:
|
||||
sets: 1
|
||||
set_size: 3
|
||||
delete_size: 3
|
||||
key_min_length: 1
|
||||
key_max_length: 256
|
||||
value_min_length: 1
|
||||
value_max_length: 1024
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 10
|
||||
context:
|
||||
quotas:
|
||||
manila:
|
||||
shares: -1
|
||||
gigabytes: -1
|
||||
share_networks: -1
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
manila_share_networks:
|
||||
use_share_networks: True
|
||||
manila_shares:
|
||||
shares_per_tenant: 1
|
||||
share_proto: "NFS"
|
||||
size: 1
|
||||
share_type: "dhss_true"
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
@ -13,5 +13,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
SHARES_CONTEXT_NAME = "manila_shares"
|
||||
SHARE_NETWORKS_CONTEXT_NAME = "manila_share_networks"
|
||||
SECURITY_SERVICES_CONTEXT_NAME = "manila_security_services"
|
||||
|
@ -33,7 +33,7 @@ CONTEXT_NAME = consts.SHARE_NETWORKS_CONTEXT_NAME
|
||||
|
||||
@context.configure(name=CONTEXT_NAME, order=450)
|
||||
class ShareNetworks(context.Context):
|
||||
"""This context creates resources specific for Manila project."""
|
||||
"""This context creates share networks for Manila project."""
|
||||
CONFIG_SCHEMA = {
|
||||
"type": "object",
|
||||
"$schema": rally_consts.JSON_SCHEMA,
|
||||
|
107
rally/plugins/openstack/context/manila/manila_shares.py
Normal file
107
rally/plugins/openstack/context/manila/manila_shares.py
Normal file
@ -0,0 +1,107 @@
|
||||
# Copyright 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from rally.common.i18n import _
|
||||
from rally.common import logging
|
||||
from rally.common import utils
|
||||
from rally import consts as rally_consts
|
||||
from rally.plugins.openstack.cleanup import manager as resource_manager
|
||||
from rally.plugins.openstack.context.manila import consts
|
||||
from rally.plugins.openstack.scenarios.manila import utils as manila_utils
|
||||
from rally.task import context
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CONTEXT_NAME = consts.SHARES_CONTEXT_NAME
|
||||
|
||||
|
||||
@context.configure(name=CONTEXT_NAME, order=455)
|
||||
class Shares(context.Context):
|
||||
"""This context creates shares for Manila project."""
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
"type": "object",
|
||||
"$schema": rally_consts.JSON_SCHEMA,
|
||||
"properties": {
|
||||
"shares_per_tenant": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"share_proto": {
|
||||
"type": "string",
|
||||
},
|
||||
"share_type": {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
"shares_per_tenant": 1,
|
||||
"size": 1,
|
||||
"share_proto": "NFS",
|
||||
"share_type": None,
|
||||
}
|
||||
|
||||
def _create_shares(self, manila_scenario, tenant_id, share_proto, size=1,
|
||||
share_type=None):
|
||||
tenant_ctxt = self.context["tenants"][tenant_id]
|
||||
tenant_ctxt.setdefault("shares", [])
|
||||
for i in range(self.config["shares_per_tenant"]):
|
||||
kwargs = {"share_proto": share_proto, "size": size}
|
||||
if share_type:
|
||||
kwargs["share_type"] = share_type
|
||||
share_networks = tenant_ctxt.get("manila_share_networks", {}).get(
|
||||
"share_networks", [])
|
||||
if share_networks:
|
||||
kwargs["share_network"] = share_networks[
|
||||
i % len(share_networks)]["id"]
|
||||
share = manila_scenario._create_share(**kwargs)
|
||||
tenant_ctxt["shares"].append(share.to_dict())
|
||||
|
||||
@logging.log_task_wrapper(
|
||||
LOG.info, _("Enter context: `%s`") % CONTEXT_NAME)
|
||||
def setup(self):
|
||||
for user, tenant_id in (
|
||||
utils.iterate_per_tenants(self.context.get("users", []))):
|
||||
manila_scenario = manila_utils.ManilaScenario({
|
||||
"task": self.task,
|
||||
"user": user,
|
||||
"config": {
|
||||
"api_versions": self.context["config"].get(
|
||||
"api_versions", [])}
|
||||
})
|
||||
self._create_shares(
|
||||
manila_scenario,
|
||||
tenant_id,
|
||||
self.config["share_proto"],
|
||||
self.config["size"],
|
||||
self.config["share_type"],
|
||||
)
|
||||
|
||||
@logging.log_task_wrapper(LOG.info, _("Exit context: `%s`") % CONTEXT_NAME)
|
||||
def cleanup(self):
|
||||
resource_manager.cleanup(
|
||||
names=["manila.shares"],
|
||||
users=self.context.get("users", []),
|
||||
)
|
@ -15,6 +15,7 @@
|
||||
|
||||
from rally.common import logging
|
||||
from rally import consts
|
||||
from rally.plugins.openstack.context.manila import consts as manila_consts
|
||||
from rally.plugins.openstack import scenario
|
||||
from rally.plugins.openstack.scenarios.manila import utils
|
||||
from rally.task import validation
|
||||
@ -228,3 +229,53 @@ class CreateAndListShare(utils.ManilaScenario):
|
||||
self._create_share(share_proto=share_proto, size=size, **kwargs)
|
||||
self.sleep_between(min_sleep, max_sleep)
|
||||
self._list_shares(detailed=detailed)
|
||||
|
||||
|
||||
@validation.number("sets", minval=1, integer_only=True)
|
||||
@validation.number("set_size", minval=1, integer_only=True)
|
||||
@validation.number("key_min_length", minval=1, maxval=256, integer_only=True)
|
||||
@validation.number("key_max_length", minval=1, maxval=256, integer_only=True)
|
||||
@validation.number(
|
||||
"value_min_length", minval=1, maxval=1024, integer_only=True)
|
||||
@validation.number(
|
||||
"value_max_length", minval=1, maxval=1024, integer_only=True)
|
||||
@validation.required_services(consts.Service.MANILA)
|
||||
@validation.required_openstack(users=True)
|
||||
@validation.required_contexts(manila_consts.SHARES_CONTEXT_NAME)
|
||||
@scenario.configure(
|
||||
context={"cleanup": ["manila"]},
|
||||
name="ManilaShares.set_and_delete_metadata")
|
||||
class SetAndDeleteMetadata(utils.ManilaScenario):
|
||||
|
||||
def run(self, sets=10, set_size=3, delete_size=3,
|
||||
key_min_length=1, key_max_length=256,
|
||||
value_min_length=1, value_max_length=1024):
|
||||
"""Sets and deletes share metadata.
|
||||
|
||||
This requires a share to be created with the shares
|
||||
context. Additionally, ``sets * set_size`` must be greater
|
||||
than or equal to ``deletes * delete_size``.
|
||||
|
||||
:param sets: how many set_metadata operations to perform
|
||||
:param set_size: number of metadata keys to set in each
|
||||
set_metadata operation
|
||||
:param delete_size: number of metadata keys to delete in each
|
||||
delete_metadata operation
|
||||
:param key_min_length: minimal size of metadata key to set
|
||||
:param key_max_length: maximum size of metadata key to set
|
||||
:param value_min_length: minimal size of metadata value to set
|
||||
:param value_max_length: maximum size of metadata value to set
|
||||
"""
|
||||
shares = self.context.get("tenant", {}).get("shares", [])
|
||||
share = shares[self.context["iteration"] % len(shares)]
|
||||
|
||||
keys = self._set_metadata(
|
||||
share=share,
|
||||
sets=sets,
|
||||
set_size=set_size,
|
||||
key_min_length=key_min_length,
|
||||
key_max_length=key_max_length,
|
||||
value_min_length=value_min_length,
|
||||
value_max_length=value_max_length)
|
||||
|
||||
self._delete_metadata(share=share, keys=keys, delete_size=delete_size)
|
||||
|
@ -13,9 +13,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import random
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from rally import exceptions
|
||||
from rally.plugins.openstack.context.manila import consts
|
||||
from rally.plugins.openstack import scenario
|
||||
from rally.task import atomic
|
||||
@ -244,3 +246,65 @@ class ManilaScenario(scenario.OpenStackScenario):
|
||||
"manila").share_networks.add_security_service(
|
||||
share_network, security_service)
|
||||
return share_network
|
||||
|
||||
@atomic.action_timer("manila.set_metadata")
|
||||
def _set_metadata(self, share, sets=1, set_size=1,
|
||||
key_min_length=1, key_max_length=256,
|
||||
value_min_length=1, value_max_length=1024):
|
||||
"""Sets share metadata.
|
||||
|
||||
:param share: the share to set metadata on
|
||||
:param sets: how many operations to perform
|
||||
:param set_size: number of metadata keys to set in each operation
|
||||
:param key_min_length: minimal size of metadata key to set
|
||||
:param key_max_length: maximum size of metadata key to set
|
||||
:param value_min_length: minimal size of metadata value to set
|
||||
:param value_max_length: maximum size of metadata value to set
|
||||
:returns: A list of keys that were set
|
||||
:raises exceptions.InvalidArgumentsException: if invalid arguments
|
||||
were provided.
|
||||
"""
|
||||
if not (key_min_length <= key_max_length and
|
||||
value_min_length <= value_max_length):
|
||||
raise exceptions.InvalidArgumentsException(
|
||||
"Min length for keys and values of metadata can not be bigger "
|
||||
"than maximum length.")
|
||||
|
||||
keys = []
|
||||
for i in range(sets):
|
||||
metadata = {}
|
||||
for j in range(set_size):
|
||||
if key_min_length == key_max_length:
|
||||
key_length = key_min_length
|
||||
else:
|
||||
key_length = random.choice(
|
||||
range(key_min_length, key_max_length))
|
||||
if value_min_length == value_max_length:
|
||||
value_length = value_min_length
|
||||
else:
|
||||
value_length = random.choice(
|
||||
range(value_min_length, value_max_length))
|
||||
key = self._generate_random_part(length=key_length)
|
||||
keys.append(key)
|
||||
metadata[key] = self._generate_random_part(length=value_length)
|
||||
self.clients("manila").shares.set_metadata(share["id"], metadata)
|
||||
|
||||
return keys
|
||||
|
||||
@atomic.action_timer("manila.delete_metadata")
|
||||
def _delete_metadata(self, share, keys, delete_size=3):
|
||||
"""Deletes share metadata.
|
||||
|
||||
:param share: The share to delete metadata from.
|
||||
:param delete_size: number of metadata keys to delete using one single
|
||||
call.
|
||||
:param keys: a list or tuple of keys to choose deletion candidates from
|
||||
:raises exceptions.InvalidArgumentsException: if invalid arguments
|
||||
were provided.
|
||||
"""
|
||||
if not (isinstance(keys, list) and keys):
|
||||
raise exceptions.InvalidArgumentsException(
|
||||
"Param 'keys' should be non-empty 'list'. keys = '%s'" % keys)
|
||||
for i in range(0, len(keys), delete_size):
|
||||
self.clients("manila").shares.delete_metadata(
|
||||
share["id"], keys[i:i + delete_size])
|
||||
|
@ -0,0 +1,51 @@
|
||||
{
|
||||
"ManilaShares.set_and_delete_metadata": [
|
||||
{
|
||||
"args": {
|
||||
"sets": 1,
|
||||
"set_size": 3,
|
||||
"delete_size": 3,
|
||||
"key_min_length": 1,
|
||||
"key_max_length": 256,
|
||||
"value_min_length": 1,
|
||||
"value_max_length": 1024
|
||||
},
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 1,
|
||||
"concurrency": 1
|
||||
},
|
||||
"context": {
|
||||
"quotas": {
|
||||
"manila": {
|
||||
"shares": -1,
|
||||
"gigabytes": -1,
|
||||
"share_networks": -1
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"tenants": 1,
|
||||
"users_per_tenant": 1,
|
||||
"user_choice_method": "round_robin"
|
||||
},
|
||||
"network": {
|
||||
"networks_per_tenant": 1,
|
||||
"start_cidr": "99.0.0.0/24"
|
||||
},
|
||||
"manila_share_networks": {
|
||||
"use_share_networks": true
|
||||
},
|
||||
"manila_shares": {
|
||||
"shares_per_tenant": 1,
|
||||
"share_proto": "NFS",
|
||||
"size": 1
|
||||
}
|
||||
},
|
||||
"sla": {
|
||||
"failure_rate": {
|
||||
"max": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
---
|
||||
ManilaShares.set_and_delete_metadata:
|
||||
-
|
||||
args:
|
||||
sets: 1
|
||||
set_size: 3
|
||||
delete_size: 3
|
||||
key_min_length: 1
|
||||
key_max_length: 256
|
||||
value_min_length: 1
|
||||
value_max_length: 1024
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 1
|
||||
concurrency: 1
|
||||
context:
|
||||
quotas:
|
||||
manila:
|
||||
shares: -1
|
||||
gigabytes: -1
|
||||
share_networks: -1
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
user_choice_method: "round_robin"
|
||||
network:
|
||||
networks_per_tenant: 1
|
||||
start_cidr: "99.0.0.0/24"
|
||||
manila_share_networks:
|
||||
use_share_networks: True
|
||||
manila_shares:
|
||||
shares_per_tenant: 1
|
||||
share_proto: "NFS"
|
||||
size: 1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
@ -0,0 +1,44 @@
|
||||
{
|
||||
"ManilaShares.set_and_delete_metadata": [
|
||||
{
|
||||
"args": {
|
||||
"sets": 1,
|
||||
"set_size": 3,
|
||||
"delete_size": 3,
|
||||
"key_min_length": 1,
|
||||
"key_max_length": 256,
|
||||
"value_min_length": 1,
|
||||
"value_max_length": 1024
|
||||
},
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 1,
|
||||
"concurrency": 1
|
||||
},
|
||||
"context": {
|
||||
"quotas": {
|
||||
"manila": {
|
||||
"shares": -1,
|
||||
"gigabytes": -1,
|
||||
"share_networks": -1
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"tenants": 1,
|
||||
"users_per_tenant": 1,
|
||||
"user_choice_method": "round_robin"
|
||||
},
|
||||
"manila_shares": {
|
||||
"shares_per_tenant": 1,
|
||||
"share_proto": "NFS",
|
||||
"size": 1
|
||||
}
|
||||
},
|
||||
"sla": {
|
||||
"failure_rate": {
|
||||
"max": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
---
|
||||
ManilaShares.set_and_delete_metadata:
|
||||
-
|
||||
args:
|
||||
sets: 1
|
||||
set_size: 3
|
||||
delete_size: 3
|
||||
key_min_length: 1
|
||||
key_max_length: 256
|
||||
value_min_length: 1
|
||||
value_max_length: 1024
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 1
|
||||
concurrency: 1
|
||||
context:
|
||||
quotas:
|
||||
manila:
|
||||
shares: -1
|
||||
gigabytes: -1
|
||||
share_networks: -1
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
user_choice_method: "round_robin"
|
||||
manila_shares:
|
||||
shares_per_tenant: 1
|
||||
share_proto: "NFS"
|
||||
size: 1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
@ -0,0 +1,202 @@
|
||||
# Copyright 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 copy
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
import six
|
||||
|
||||
from rally import consts as rally_consts
|
||||
from rally.plugins.openstack.context.manila import consts
|
||||
from rally.plugins.openstack.context.manila import manila_shares
|
||||
from tests.unit import test
|
||||
|
||||
MANILA_UTILS_PATH = (
|
||||
"rally.plugins.openstack.scenarios.manila.utils.ManilaScenario.")
|
||||
|
||||
|
||||
class Fake(object):
|
||||
def __init__(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
|
||||
def to_dict(self):
|
||||
return self.__dict__
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class SharesTestCase(test.TestCase):
|
||||
TENANTS_AMOUNT = 3
|
||||
USERS_PER_TENANT = 4
|
||||
SHARES_PER_TENANT = 7
|
||||
SHARE_NETWORKS = [{"id": "sn_%s_id" % d} for d in range(3)]
|
||||
|
||||
def _get_context(self, use_share_networks=False, shares_per_tenant=None,
|
||||
share_size=1, share_proto="fake_proto", share_type=None):
|
||||
tenants = {}
|
||||
for t_id in range(self.TENANTS_AMOUNT):
|
||||
tenants[six.text_type(t_id)] = {"name": six.text_type(t_id)}
|
||||
users = []
|
||||
for t_id in sorted(list(tenants.keys())):
|
||||
for i in range(self.USERS_PER_TENANT):
|
||||
users.append(
|
||||
{"id": i, "tenant_id": t_id, "credential": "fake"})
|
||||
context = {
|
||||
"config": {
|
||||
"users": {
|
||||
"tenants": self.TENANTS_AMOUNT,
|
||||
"users_per_tenant": self.USERS_PER_TENANT,
|
||||
"user_choice_method": "round_robin",
|
||||
},
|
||||
consts.SHARE_NETWORKS_CONTEXT_NAME: {
|
||||
"use_share_networks": use_share_networks,
|
||||
"share_networks": self.SHARE_NETWORKS,
|
||||
},
|
||||
consts.SHARES_CONTEXT_NAME: {
|
||||
"shares_per_tenant": (
|
||||
shares_per_tenant or self.SHARES_PER_TENANT),
|
||||
"size": share_size,
|
||||
"share_proto": share_proto,
|
||||
"share_type": share_type,
|
||||
},
|
||||
},
|
||||
"admin": {
|
||||
"credential": mock.MagicMock(),
|
||||
},
|
||||
"task": mock.MagicMock(),
|
||||
"users": users,
|
||||
"tenants": tenants,
|
||||
}
|
||||
if use_share_networks:
|
||||
for t in context["tenants"].keys():
|
||||
context["tenants"][t][consts.SHARE_NETWORKS_CONTEXT_NAME] = {
|
||||
"share_networks": self.SHARE_NETWORKS,
|
||||
}
|
||||
return context
|
||||
|
||||
def test_init(self):
|
||||
ctxt = {
|
||||
"task": mock.MagicMock(),
|
||||
"config": {
|
||||
consts.SHARES_CONTEXT_NAME: {"foo": "bar"},
|
||||
"fake": {"fake_key": "fake_value"},
|
||||
},
|
||||
}
|
||||
|
||||
inst = manila_shares.Shares(ctxt)
|
||||
|
||||
self.assertEqual(
|
||||
{"foo": "bar", "shares_per_tenant": 1, "size": 1,
|
||||
"share_proto": "NFS", "share_type": None},
|
||||
inst.config)
|
||||
self.assertIn(
|
||||
rally_consts.JSON_SCHEMA, inst.CONFIG_SCHEMA.get("$schema"))
|
||||
self.assertFalse(inst.CONFIG_SCHEMA.get("additionalProperties"))
|
||||
self.assertEqual("object", inst.CONFIG_SCHEMA.get("type"))
|
||||
props = inst.CONFIG_SCHEMA.get("properties", {})
|
||||
self.assertEqual(
|
||||
{"minimum": 1, "type": "integer"}, props.get("shares_per_tenant"))
|
||||
self.assertEqual({"minimum": 1, "type": "integer"}, props.get("size"))
|
||||
self.assertEqual({"type": "string"}, props.get("share_proto"))
|
||||
self.assertEqual({"type": "string"}, props.get("share_type"))
|
||||
self.assertEqual(455, inst.get_order())
|
||||
self.assertEqual(consts.SHARES_CONTEXT_NAME, inst.get_name())
|
||||
|
||||
@mock.patch(MANILA_UTILS_PATH + "_create_share")
|
||||
@ddt.data(True, False)
|
||||
def test_setup(
|
||||
self,
|
||||
use_share_networks,
|
||||
mock_manila_scenario__create_share):
|
||||
share_type = "fake_share_type"
|
||||
ctxt = self._get_context(
|
||||
use_share_networks=use_share_networks, share_type=share_type)
|
||||
inst = manila_shares.Shares(ctxt)
|
||||
shares = [
|
||||
Fake(id="fake_share_id_%d" % s_id)
|
||||
for s_id in range(self.TENANTS_AMOUNT * self.SHARES_PER_TENANT)
|
||||
]
|
||||
mock_manila_scenario__create_share.side_effect = shares
|
||||
expected_ctxt = copy.deepcopy(ctxt)
|
||||
|
||||
inst.setup()
|
||||
|
||||
self.assertEqual(
|
||||
self.TENANTS_AMOUNT * self.SHARES_PER_TENANT,
|
||||
mock_manila_scenario__create_share.call_count)
|
||||
for d in range(self.TENANTS_AMOUNT):
|
||||
self.assertEqual(
|
||||
[
|
||||
s.to_dict() for s in shares[
|
||||
(d * self.SHARES_PER_TENANT):(
|
||||
d * self.SHARES_PER_TENANT + self.SHARES_PER_TENANT
|
||||
)
|
||||
]
|
||||
],
|
||||
inst.context.get("tenants", {}).get("%s" % d, {}).get("shares")
|
||||
)
|
||||
self.assertEqual(expected_ctxt["task"], inst.context.get("task"))
|
||||
self.assertEqual(expected_ctxt["config"], inst.context.get("config"))
|
||||
self.assertEqual(expected_ctxt["users"], inst.context.get("users"))
|
||||
if use_share_networks:
|
||||
mock_calls = [
|
||||
mock.call(
|
||||
share_proto=ctxt["config"][consts.SHARES_CONTEXT_NAME][
|
||||
"share_proto"],
|
||||
size=ctxt["config"][consts.SHARES_CONTEXT_NAME]["size"],
|
||||
share_type=ctxt["config"][consts.SHARES_CONTEXT_NAME][
|
||||
"share_type"],
|
||||
share_network=self.SHARE_NETWORKS[
|
||||
int(t_id) % len(self.SHARE_NETWORKS)]["id"]
|
||||
) for t_id in expected_ctxt["tenants"].keys()
|
||||
]
|
||||
else:
|
||||
mock_calls = [
|
||||
mock.call(
|
||||
share_proto=ctxt["config"][consts.SHARES_CONTEXT_NAME][
|
||||
"share_proto"],
|
||||
size=ctxt["config"][consts.SHARES_CONTEXT_NAME]["size"],
|
||||
share_type=ctxt["config"][consts.SHARES_CONTEXT_NAME][
|
||||
"share_type"],
|
||||
) for t_id in expected_ctxt["tenants"].keys()
|
||||
]
|
||||
mock_manila_scenario__create_share.assert_has_calls(
|
||||
mock_calls, any_order=True)
|
||||
|
||||
@mock.patch(MANILA_UTILS_PATH + "_create_share")
|
||||
@mock.patch("rally.plugins.openstack.cleanup.manager.cleanup")
|
||||
def test_cleanup(
|
||||
self,
|
||||
mock_cleanup_manager_cleanup,
|
||||
mock_manila_scenario__create_share):
|
||||
ctxt = self._get_context()
|
||||
inst = manila_shares.Shares(ctxt)
|
||||
shares = [
|
||||
Fake(id="fake_share_id_%d" % s_id)
|
||||
for s_id in range(self.TENANTS_AMOUNT * self.SHARES_PER_TENANT)
|
||||
]
|
||||
mock_manila_scenario__create_share.side_effect = shares
|
||||
inst.setup()
|
||||
|
||||
inst.cleanup()
|
||||
|
||||
mock_cleanup_manager_cleanup.assert_called_once_with(
|
||||
names=["manila.shares"],
|
||||
users=inst.context.get("users", []),
|
||||
)
|
@ -209,3 +209,37 @@ class ManilaSharesTestCase(test.ScenarioTestCase):
|
||||
scenario._create_share.assert_called_once_with(**params)
|
||||
scenario.sleep_between.assert_called_once_with(3, 4)
|
||||
scenario._list_shares.assert_called_once_with(detailed=detailed)
|
||||
|
||||
@ddt.data(
|
||||
({}, 0, 0),
|
||||
({}, 1, 1),
|
||||
({}, 2, 2),
|
||||
({}, 3, 0),
|
||||
({"sets": 5, "set_size": 8, "delete_size": 10}, 1, 1),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_set_and_delete_metadata(self, params, iteration, share_number):
|
||||
scenario = shares.SetAndDeleteMetadata()
|
||||
share_list = [{"id": "fake_share_%s_id" % d} for d in range(3)]
|
||||
scenario.context = {"tenant": {"shares": share_list}}
|
||||
scenario.context["iteration"] = iteration
|
||||
scenario._set_metadata = mock.MagicMock()
|
||||
scenario._delete_metadata = mock.MagicMock()
|
||||
expected_set_params = {
|
||||
"share": share_list[share_number],
|
||||
"sets": params.get("sets", 10),
|
||||
"set_size": params.get("set_size", 3),
|
||||
"key_min_length": params.get("key_min_length", 1),
|
||||
"key_max_length": params.get("key_max_length", 256),
|
||||
"value_min_length": params.get("value_min_length", 1),
|
||||
"value_max_length": params.get("value_max_length", 1024),
|
||||
}
|
||||
|
||||
scenario.run(**params)
|
||||
|
||||
scenario._set_metadata.assert_called_once_with(**expected_set_params)
|
||||
scenario._delete_metadata.assert_called_once_with(
|
||||
share=share_list[share_number],
|
||||
keys=scenario._set_metadata.return_value,
|
||||
delete_size=params.get("delete_size", 3),
|
||||
)
|
||||
|
@ -16,6 +16,7 @@
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from rally import exceptions
|
||||
from rally.plugins.openstack.context.manila import consts
|
||||
from rally.plugins.openstack.scenarios.manila import utils
|
||||
from tests.unit import test
|
||||
@ -41,12 +42,14 @@ class ManilaScenarioTestCase(test.ScenarioTestCase):
|
||||
},
|
||||
"iteration": 0,
|
||||
}
|
||||
self.scenario.generate_random_name = mock.Mock()
|
||||
fake_random_name = "fake_random_name_value"
|
||||
self.scenario.generate_random_name = mock.Mock(
|
||||
return_value=fake_random_name)
|
||||
|
||||
self.scenario._create_share("nfs")
|
||||
|
||||
self.clients("manila").shares.create.assert_called_once_with(
|
||||
"nfs", 1, name=self.scenario.generate_random_name.return_value,
|
||||
"nfs", 1, name=fake_random_name,
|
||||
share_network=self.scenario.context["tenant"][
|
||||
consts.SHARE_NETWORKS_CONTEXT_NAME]["share_networks"][0]["id"])
|
||||
|
||||
@ -213,3 +216,87 @@ class ManilaScenarioTestCase(test.ScenarioTestCase):
|
||||
self.clients(
|
||||
"manila").share_networks.add_security_service.assert_has_calls([
|
||||
mock.call(fake_sn, fake_ss)])
|
||||
|
||||
@ddt.data(
|
||||
{"key_min_length": 5, "key_max_length": 4},
|
||||
{"value_min_length": 5, "value_max_length": 4},
|
||||
)
|
||||
def test__set_metadata_wrong_params(self, params):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidArgumentsException,
|
||||
self.scenario._set_metadata,
|
||||
{"id": "fake_share_id"}, **params)
|
||||
|
||||
@ddt.data(
|
||||
{},
|
||||
{"sets": 0, "set_size": 1},
|
||||
{"sets": 1, "set_size": 1},
|
||||
{"sets": 5, "set_size": 7},
|
||||
{"sets": 5, "set_size": 2},
|
||||
{"key_min_length": 1, "key_max_length": 1},
|
||||
{"key_min_length": 1, "key_max_length": 2},
|
||||
{"key_min_length": 256, "key_max_length": 256},
|
||||
{"value_min_length": 1, "value_max_length": 1},
|
||||
{"value_min_length": 1, "value_max_length": 2},
|
||||
{"value_min_length": 1024, "value_max_length": 1024},
|
||||
)
|
||||
def test__set_metadata(self, params):
|
||||
share = {"id": "fake_share_id"}
|
||||
sets = params.get("sets", 1)
|
||||
set_size = params.get("set_size", 1)
|
||||
gen_name_calls = sets * set_size * 2
|
||||
data = range(gen_name_calls)
|
||||
generator_data = iter(data)
|
||||
|
||||
def fake_random_name(prefix="fake", length="fake"):
|
||||
return next(generator_data)
|
||||
|
||||
scenario = self.scenario
|
||||
scenario.clients = mock.MagicMock()
|
||||
scenario._generate_random_part = mock.MagicMock(
|
||||
side_effect=fake_random_name)
|
||||
|
||||
keys = scenario._set_metadata(share, **params)
|
||||
|
||||
self.assertEqual(
|
||||
gen_name_calls,
|
||||
scenario._generate_random_part.call_count)
|
||||
self.assertEqual(
|
||||
params.get("sets", 1),
|
||||
scenario.clients.return_value.shares.set_metadata.call_count)
|
||||
scenario.clients.return_value.shares.set_metadata.assert_has_calls([
|
||||
mock.call(
|
||||
share["id"],
|
||||
dict([(j, j + 1) for j in data[
|
||||
i * set_size * 2: (i + 1) * set_size * 2: 2]])
|
||||
) for i in range(sets)
|
||||
])
|
||||
self.assertEqual([i for i in range(0, gen_name_calls, 2)], keys)
|
||||
|
||||
@ddt.data(None, [], {"fake_set"}, {"fake_key": "fake_value"})
|
||||
def test__delete_metadata_wrong_params(self, keys):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidArgumentsException,
|
||||
self.scenario._delete_metadata,
|
||||
"fake_share", keys=keys,
|
||||
)
|
||||
|
||||
@ddt.data(
|
||||
{"keys": [i for i in range(30)]},
|
||||
{"keys": list(range(7)), "delete_size": 2},
|
||||
{"keys": list(range(7)), "delete_size": 3},
|
||||
{"keys": list(range(7)), "delete_size": 4},
|
||||
)
|
||||
def test__delete_metadata(self, params):
|
||||
share = {"id": "fake_share_id"}
|
||||
delete_size = params.get("delete_size", 3)
|
||||
keys = params.get("keys", [])
|
||||
scenario = self.scenario
|
||||
scenario.clients = mock.MagicMock()
|
||||
|
||||
scenario._delete_metadata(share, **params)
|
||||
|
||||
scenario.clients.return_value.shares.delete_metadata.assert_has_calls([
|
||||
mock.call(share["id"], keys[i:i + delete_size])
|
||||
for i in range(0, len(keys), delete_size)
|
||||
])
|
||||
|
Loading…
Reference in New Issue
Block a user