Merge "Add cinder.CreateAndListQos scenario"

This commit is contained in:
Jenkins 2017-04-19 13:53:25 +00:00 committed by Gerrit Code Review
commit ce2b44a2a8
10 changed files with 308 additions and 0 deletions

View File

@ -987,3 +987,22 @@
sla:
failure_rate:
max: 0
CinderQos.create_and_list_qos:
-
args:
specs:
consumer: "both"
write_iops_sec: "10"
read_iops_sec: "1000"
runner:
type: "constant"
times: 5
concurrency: 2
context:
users:
tenants: 2
users_per_tenant: 2
sla:
failure_rate:
max: 0

View File

@ -547,6 +547,11 @@ class CinderQuotas(QuotaMixin, base.ResourceManager):
pass
@base.resource("cinder", "qos_specs", order=next(_cinder_order),
admin_required=True, perform_for_admin_only=True)
class CinderQos(base.ResourceManager):
pass
# MANILA
_manila_order = get_order(450)

View File

@ -0,0 +1,41 @@
# 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 rally import consts
from rally.plugins.openstack import scenario
from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils
from rally.task import validation
"""Scenarios for Cinder QoS."""
@validation.restricted_parameters("name")
@validation.required_services(consts.Service.CINDER)
@validation.add("required_platform", platform="openstack", admin=True)
@scenario.configure(context={"admin_cleanup": ["cinder"]},
name="CinderQos.create_and_list_qos")
class CreateAndListQos(cinder_utils.CinderBasic):
def run(self, specs):
"""create a qos, then list all qos.
:param specs: A dict of key/value pairs to create qos
"""
qos = self.admin_cinder.create_qos(specs)
pool_list = self.admin_cinder.list_qos()
msg = ("Qos not included into list of available qos\n"
"created qos:{}\n"
"Pool of qos:{}").format(qos, pool_list)
self.assertIn(qos, pool_list, err_msg=msg)

View File

@ -189,6 +189,24 @@ class BlockStorage(service.UnifiedOpenStackService):
volume, force=force, container_format=container_format,
disk_format=disk_format)
@service.should_be_overridden
def create_qos(self, specs):
"""Create a qos specs.
:param specs: A dict of key/value pairs to be set
:rtype: :class:'QoSSpecs'
"""
return self._impl.create_qos(specs)
@service.should_be_overridden
def list_qos(self, search_opts=None):
"""Get a list of all qos specs.
:param search_opts: search options
:rtype: list of :class: 'QoSpecs'
"""
return self._impl.list_qos(search_opts)
@service.should_be_overridden
def create_snapshot(self, volume_id, force=False,
name=None, description=None, metadata=None):

View File

@ -203,6 +203,28 @@ class CinderMixin(object):
return image_inst
def create_qos(self, specs):
"""Create a qos specs.
:param specs: A dict of key/value pairs to be set
:rtype: :class:'QoSSpecs'
"""
aname = "cinder_v%s.create_qos" % self.version
name = self.generate_random_name()
with atomic.ActionTimer(self, aname):
return self._get_client().qos_specs.create(name, specs)
def list_qos(self, search_opts=None):
"""Get a list of all qos specs.
:param search_opts: search options
:rtype: list of :class: 'QoSpecs'
"""
aname = "cinder_v%s.list_qos" % self.version
with atomic.ActionTimer(self, aname):
return self._get_client().qos_specs.list(search_opts)
def delete_snapshot(self, snapshot):
"""Delete the given snapshot.
@ -449,6 +471,22 @@ class UnifiedCinderMixin(object):
volume, force=force, container_format=container_format,
disk_format=disk_format)
def create_qos(self, specs):
"""Create a qos specs.
:param specs: A dict of key/value pairs to be set
:rtype: :class:'QoSSpecs'
"""
return self._impl.create_qos(specs)
def list_qos(self, search_opts=None):
"""Get a list of all qos specs.
:param search_opts: search options
:rtype: list of :class: 'QoSpecs'
"""
return self._impl.list_qos(search_opts)
def delete_snapshot(self, snapshot):
"""Delete the given backup.

View File

@ -0,0 +1,29 @@
{
"CinderQos.create_and_list_qos": [
{
"args": {
"specs": {
"consumer": "both",
"write_iops_sec": "10",
"read_iops_sec": "1000"
}
},
"runner": {
"type": "constant",
"times": 5,
"concurrency": 2
},
"context": {
"users": {
"tenants": 2,
"users_per_tenant": 2
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,19 @@
---
CinderQos.create_and_list_qos:
-
args:
specs:
consumer: "both"
write_iops_sec: "10"
read_iops_sec: "1000"
runner:
type: "constant"
times: 5
concurrency: 2
context:
users:
tenants: 2
users_per_tenant: 2
sla:
failure_rate:
max: 0

View File

@ -0,0 +1,80 @@
# 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 import exceptions as rally_exceptions
from rally.plugins.openstack.scenarios.cinder import qos_specs
from tests.unit import test
class CinderQosTestCase(test.ScenarioTestCase):
def setUp(self):
super(CinderQosTestCase, self).setUp()
patch = mock.patch(
"rally.plugins.openstack.services.storage.block.BlockStorage")
self.addCleanup(patch.stop)
self.mock_cinder = patch.start()
def _get_context(self):
context = test.get_test_context()
context.update({
"admin": {
"id": "fake_user_id",
"credential": mock.MagicMock()
},
"user": {"id": "fake_user_id",
"credential": mock.MagicMock()},
"tenant": {"id": "fake", "name": "fake"}})
return context
def test_create_and_list_qos(self):
mock_service = self.mock_cinder.return_value
qos = mock.MagicMock()
qos = mock.MagicMock()
list_qos = [mock.MagicMock(),
mock.MagicMock(),
qos]
specs = {"consumer": "both",
"write_iops_sec": "10",
"read_iops_sec": "1000"}
scenario = qos_specs.CreateAndListQos(self._get_context())
mock_service.create_qos.return_value = qos
mock_service.list_qos.return_value = list_qos
scenario.run(specs)
mock_service.create_qos.assert_called_once_with(specs)
mock_service.list_qos.assert_called_once_with()
def test_create_and_list_qos_with_fails(self):
mock_service = self.mock_cinder.return_value
qos = mock.MagicMock()
list_qos = [mock.MagicMock(),
mock.MagicMock(),
mock.MagicMock()]
specs = {"consumer": "both",
"write_iops_sec": "10",
"read_iops_sec": "1000"}
scenario = qos_specs.CreateAndListQos(self._get_context())
mock_service.create_qos.return_value = qos
mock_service.list_qos.return_value = list_qos
self.assertRaises(rally_exceptions.RallyAssertionError,
scenario.run, specs)
mock_service.create_qos.assert_called_once_with(specs)
mock_service.list_qos.assert_called_once_with()

View File

@ -113,6 +113,24 @@ class BlockTestCase(test.TestCase):
self.service._impl.upload_volume_to_image.assert_called_once_with(
"volume", container_format="bare", disk_format="raw", force=False)
def test_create_qos(self):
spaces = {"consumer": "both",
"write_iops_sec": "10",
"read_iops_sec": "1000"}
self.assertEqual(
self.service._impl.create_qos.return_value,
self.service.create_qos(spaces)
)
self.service._impl.create_qos.assert_called_once_with(spaces)
def test_list_qos(self):
self.assertEqual(
self.service._impl.list_qos.return_value,
self.service.list_qos(True)
)
self.service._impl.list_qos.assert_called_once_with(True)
def test_create_snapshot(self):
self.assertEqual(
self.service._impl.create_snapshot.return_value,

View File

@ -227,6 +227,30 @@ class CinderMixinTestCase(test.ScenarioTestCase):
])
glance.get_image.assert_called_once_with(1)
def test_create_qos(self):
specs = {"consumer": "both",
"write_iops_sec": "10",
"read_iops_sec": "1000"}
random_name = "random_name"
self.service.generate_random_name = mock.MagicMock(
return_value=random_name)
result = self.service.create_qos(specs)
self.assertEqual(
self.cinder.qos_specs.create.return_value,
result
)
self.cinder.qos_specs.create.assert_called_once_with(random_name,
specs)
def test_list_qos(self):
result = self.service.list_qos(True)
self.assertEqual(
self.cinder.qos_specs.list.return_value,
result
)
self.cinder.qos_specs.list.assert_called_once_with(True)
def test_delete_snapshot(self):
snapshot = mock.Mock()
self.service.delete_snapshot(snapshot)
@ -452,6 +476,23 @@ class UnifiedCinderMixinTestCase(test.TestCase):
self.service._impl.upload_volume_to_image.assert_called_once_with(
"volume", container_format="bare", disk_format="raw", force=False)
def test_create_qos(self):
specs = {"consumer": "both",
"write_iops_sec": "10",
"read_iops_sec": "1000"}
self.assertEqual(
self.service._impl.create_qos.return_value,
self.service.create_qos(specs)
)
self.service._impl.create_qos.assert_called_once_with(specs)
def test_list_qos(self):
self.assertEqual(
self.service._impl.list_qos.return_value,
self.service.list_qos(True)
)
self.service._impl.list_qos.assert_called_once_with(True)
def test_delete_snapshot(self):
self.service.delete_snapshot("snapshot")
self.service._impl.delete_snapshot.assert_called_once_with("snapshot")