diff --git a/rally-jobs/nova.yaml b/rally-jobs/nova.yaml index 41c76dfc..dc907633 100755 --- a/rally-jobs/nova.yaml +++ b/rally-jobs/nova.yaml @@ -1377,3 +1377,19 @@ sla: failure_rate: max: 0 + + NovaAggregates.create_and_get_aggregate_details: + - + args: + availability_zone: "nova" + runner: + type: "constant" + times: 10 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 diff --git a/rally/plugins/openstack/scenarios/nova/aggregates.py b/rally/plugins/openstack/scenarios/nova/aggregates.py index 2863ad4e..1ece7183 100644 --- a/rally/plugins/openstack/scenarios/nova/aggregates.py +++ b/rally/plugins/openstack/scenarios/nova/aggregates.py @@ -104,3 +104,19 @@ class CreateAggregateAddAndRemoveHost(utils.NovaScenario): host_name = hosts[0].host_name self._aggregate_add_host(aggregate, host_name) self._aggregate_remove_host(aggregate, host_name) + + +@validation.required_services(consts.Service.NOVA) +@validation.required_openstack(admin=True) +@scenario.configure(context={"admin_cleanup": ["nova"]}, + name="NovaAggregates.create_and_get_aggregate_details") +class CreateAndGetAggregateDetails(utils.NovaScenario): + """Scenario for create and get aggregate details.""" + + def run(self, availability_zone): + """Create an aggregate and then get its details. + + This scenario first creates an aggregate and then get details of it. + """ + aggregate = self._create_aggregate(availability_zone) + self._get_aggregate_details(aggregate) diff --git a/rally/plugins/openstack/scenarios/nova/utils.py b/rally/plugins/openstack/scenarios/nova/utils.py index 1d80649f..8701603c 100755 --- a/rally/plugins/openstack/scenarios/nova/utils.py +++ b/rally/plugins/openstack/scenarios/nova/utils.py @@ -1097,6 +1097,15 @@ class NovaScenario(scenario.OpenStackScenario): return self.admin_clients("nova").aggregates.create(aggregate_name, availability_zone) + @atomic.action_timer("nova.get_aggregate_details") + def _get_aggregate_details(self, aggregate): + """Get details of the specified aggregate. + + :param aggregate: The aggregate to get details + :returns: Detailed information of aggregate + """ + return self.admin_clients("nova").aggregates.get_details(aggregate) + @atomic.action_timer("nova.delete_aggregate") def _delete_aggregate(self, aggregate): """Delete the specified aggregate. diff --git a/samples/tasks/scenarios/nova/create-and-get-aggregate-details.json b/samples/tasks/scenarios/nova/create-and-get-aggregate-details.json new file mode 100644 index 00000000..45efe31e --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-get-aggregate-details.json @@ -0,0 +1,25 @@ +{ + "NovaAggregates.create_and_get_aggregate_details": [ + { + "args": { + "availability_zone": "nova" + }, + "runner": { + "type": "constant", + "times": 10, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 2 + } + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/create-and-get-aggregate-details.yaml b/samples/tasks/scenarios/nova/create-and-get-aggregate-details.yaml new file mode 100644 index 00000000..1bf4fefd --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-get-aggregate-details.yaml @@ -0,0 +1,16 @@ +--- + NovaAggregates.create_and_get_aggregate_details: + - + args: + availability_zone: "nova" + runner: + type: "constant" + times: 10 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_aggregates.py b/tests/unit/plugins/openstack/scenarios/nova/test_aggregates.py index 68ae77ee..b173a3d7 100644 --- a/tests/unit/plugins/openstack/scenarios/nova/test_aggregates.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_aggregates.py @@ -71,3 +71,12 @@ class NovaAggregatesTestCase(test.TestCase): "fake_aggregate", "fake_host_name") scenario._aggregate_remove_host.assert_called_once_with( "fake_aggregate", "fake_host_name") + + def test_create_and_get_aggregate_details(self): + scenario = aggregates.CreateAndGetAggregateDetails() + scenario._create_aggregate = mock.Mock() + scenario._get_aggregate_details = mock.Mock() + scenario.run(availability_zone="nova") + scenario._create_aggregate.assert_called_once_with("nova") + aggregate = scenario._create_aggregate.return_value + scenario._get_aggregate_details.assert_called_once_with(aggregate) diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py index caaec5d5..67d2ac8a 100755 --- a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py @@ -1141,6 +1141,18 @@ class NovaScenarioTestCase(test.ScenarioTestCase): self._test_atomic_action_timer(nova_scenario.atomic_actions(), "nova.delete_aggregate") + def test_get_aggregate_details(self): + nova_scenario = utils.NovaScenario(context=self.context) + result = nova_scenario._get_aggregate_details("fake_aggregate") + self.assertEqual( + self.admin_clients("nova").aggregates.get_details.return_value, + result) + self.admin_clients( + "nova").aggregates.get_details.assert_called_once_with( + "fake_aggregate") + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.get_aggregate_details") + def test_update_aggregate(self): aggregate = mock.Mock() nova_scenario = utils.NovaScenario(context=self.context)