Merge "Add cinder.CreateAndListQos scenario"
This commit is contained in:
commit
ce2b44a2a8
@ -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
|
||||
|
@ -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)
|
||||
|
41
rally/plugins/openstack/scenarios/cinder/qos_specs.py
Normal file
41
rally/plugins/openstack/scenarios/cinder/qos_specs.py
Normal 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)
|
@ -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):
|
||||
|
@ -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.
|
||||
|
||||
|
29
samples/tasks/scenarios/cinder/create-and-list-qos.json
Normal file
29
samples/tasks/scenarios/cinder/create-and-list-qos.json
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
19
samples/tasks/scenarios/cinder/create-and-list-qos.yaml
Normal file
19
samples/tasks/scenarios/cinder/create-and-list-qos.yaml
Normal 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
|
@ -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()
|
@ -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,
|
||||
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user