diff --git a/rally-jobs/cinder.yaml b/rally-jobs/cinder.yaml index f8dbd19520..e1209e2130 100755 --- a/rally-jobs/cinder.yaml +++ b/rally-jobs/cinder.yaml @@ -1006,3 +1006,22 @@ sla: failure_rate: max: 0 + + CinderQos.create_and_get_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 diff --git a/rally/plugins/openstack/scenarios/cinder/qos_specs.py b/rally/plugins/openstack/scenarios/cinder/qos_specs.py index 9307acc544..362f56b5d1 100644 --- a/rally/plugins/openstack/scenarios/cinder/qos_specs.py +++ b/rally/plugins/openstack/scenarios/cinder/qos_specs.py @@ -39,3 +39,18 @@ class CreateAndListQos(cinder_utils.CinderBasic): "created qos:{}\n" "Pool of qos:{}").format(qos, pool_list) self.assertIn(qos, pool_list, err_msg=msg) + + +@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_get_qos") +class CreateAndGetQos(cinder_utils.CinderBasic): + def run(self, specs): + """Create a qos, then get details of the qos. + + :param specs: A dict of key/value pairs to create qos + """ + qos = self.admin_cinder.create_qos(specs) + self.admin_cinder.get_qos(qos.id) diff --git a/rally/plugins/openstack/services/storage/block.py b/rally/plugins/openstack/services/storage/block.py index 85666f9adc..a305b755c5 100644 --- a/rally/plugins/openstack/services/storage/block.py +++ b/rally/plugins/openstack/services/storage/block.py @@ -207,6 +207,15 @@ class BlockStorage(service.UnifiedOpenStackService): """ return self._impl.list_qos(search_opts) + @service.should_be_overridden + def get_qos(self, qos_id): + """Get a specific qos specs. + + :param qos_id: The ID of the :class:`QoSSpecs` to get. + :rtype: :class:`QoSSpecs` + """ + return self._impl.get_qos(qos_id) + @service.should_be_overridden def create_snapshot(self, volume_id, force=False, name=None, description=None, metadata=None): diff --git a/rally/plugins/openstack/services/storage/cinder_common.py b/rally/plugins/openstack/services/storage/cinder_common.py index 59ed7f6723..a9c1d74ae4 100644 --- a/rally/plugins/openstack/services/storage/cinder_common.py +++ b/rally/plugins/openstack/services/storage/cinder_common.py @@ -225,6 +225,16 @@ class CinderMixin(object): with atomic.ActionTimer(self, aname): return self._get_client().qos_specs.list(search_opts) + def get_qos(self, qos_id): + """Get a specific qos specs. + + :param qos_id: The ID of the :class: 'QoSSpecs' to get + :rtype: :class: 'QoSSpecs' + """ + aname = "cinder_v%s.get_qos" % self.version + with atomic.ActionTimer(self, aname): + return self._get_client().qos_specs.get(qos_id) + def delete_snapshot(self, snapshot): """Delete the given snapshot. @@ -487,6 +497,14 @@ class UnifiedCinderMixin(object): """ return self._impl.list_qos(search_opts) + def get_qos(self, qos_id): + """Get a specific qos specs. + + :param qos_id: The ID of the :class: 'QoSSpecs' to get + :rtype: :class: 'QoSSpecs' + """ + return self._impl.get_qos(qos_id) + def delete_snapshot(self, snapshot): """Delete the given backup. diff --git a/samples/tasks/scenarios/cinder/create-and-get-qos.json b/samples/tasks/scenarios/cinder/create-and-get-qos.json new file mode 100644 index 0000000000..c9c08f2e0a --- /dev/null +++ b/samples/tasks/scenarios/cinder/create-and-get-qos.json @@ -0,0 +1,29 @@ +{ + "CinderQos.create_and_get_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 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/cinder/create-and-get-qos.yaml b/samples/tasks/scenarios/cinder/create-and-get-qos.yaml new file mode 100644 index 0000000000..40d1c48e74 --- /dev/null +++ b/samples/tasks/scenarios/cinder/create-and-get-qos.yaml @@ -0,0 +1,19 @@ +--- + CinderQos.create_and_get_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 diff --git a/tests/unit/plugins/openstack/scenarios/cinder/test_qos_specs.py b/tests/unit/plugins/openstack/scenarios/cinder/test_qos_specs.py index c1d25d3c6c..d282515599 100644 --- a/tests/unit/plugins/openstack/scenarios/cinder/test_qos_specs.py +++ b/tests/unit/plugins/openstack/scenarios/cinder/test_qos_specs.py @@ -43,7 +43,6 @@ class CinderQosTestCase(test.ScenarioTestCase): 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] @@ -78,3 +77,17 @@ class CinderQosTestCase(test.ScenarioTestCase): scenario.run, specs) mock_service.create_qos.assert_called_once_with(specs) mock_service.list_qos.assert_called_once_with() + + def test_create_and_get_qos(self): + mock_service = self.mock_cinder.return_value + qos = mock.MagicMock() + specs = {"consumer": "both", + "write_iops_sec": "10", + "read_iops_sec": "1000"} + + scenario = qos_specs.CreateAndGetQos(self._get_context()) + mock_service.create_qos.return_value = qos + + scenario.run(specs) + mock_service.create_qos.assert_called_once_with(specs) + mock_service.get_qos.assert_called_once_with(qos.id) diff --git a/tests/unit/plugins/openstack/services/storage/test_block.py b/tests/unit/plugins/openstack/services/storage/test_block.py index 17c29518d6..3a63114957 100644 --- a/tests/unit/plugins/openstack/services/storage/test_block.py +++ b/tests/unit/plugins/openstack/services/storage/test_block.py @@ -131,6 +131,12 @@ class BlockTestCase(test.TestCase): ) self.service._impl.list_qos.assert_called_once_with(True) + def test_get_qos(self): + self.assertEqual( + self.service._impl.get_qos.return_value, + self.service.get_qos("qos")) + self.service._impl.get_qos.assert_called_once_with("qos") + def test_create_snapshot(self): self.assertEqual( self.service._impl.create_snapshot.return_value, diff --git a/tests/unit/plugins/openstack/services/storage/test_cinder_common.py b/tests/unit/plugins/openstack/services/storage/test_cinder_common.py index 776b70289b..e70f2ef7d1 100644 --- a/tests/unit/plugins/openstack/services/storage/test_cinder_common.py +++ b/tests/unit/plugins/openstack/services/storage/test_cinder_common.py @@ -251,6 +251,13 @@ class CinderMixinTestCase(test.ScenarioTestCase): ) self.cinder.qos_specs.list.assert_called_once_with(True) + def test_get_qos(self): + result = self.service.get_qos("qos") + self.assertEqual( + self.cinder.qos_specs.get.return_value, + result) + self.cinder.qos_specs.get.assert_called_once_with("qos") + def test_delete_snapshot(self): snapshot = mock.Mock() self.service.delete_snapshot(snapshot) @@ -493,6 +500,12 @@ class UnifiedCinderMixinTestCase(test.TestCase): ) self.service._impl.list_qos.assert_called_once_with(True) + def test_get_qos(self): + self.assertEqual( + self.service._impl.get_qos.return_value, + self.service.get_qos("qos")) + self.service._impl.get_qos.assert_called_once_with("qos") + def test_delete_snapshot(self): self.service.delete_snapshot("snapshot") self.service._impl.delete_snapshot.assert_called_once_with("snapshot")