diff --git a/rally-jobs/nova.yaml b/rally-jobs/nova.yaml index 73c2bb3f..15587d62 100755 --- a/rally-jobs/nova.yaml +++ b/rally-jobs/nova.yaml @@ -1060,6 +1060,22 @@ failure_rate: max: 0 + NovaAggregates.create_aggregate_add_and_remove_host: + - + args: + availability_zone: "nova" + runner: + type: "constant" + times: 10 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + NovaAvailabilityZones.list_availability_zones: - args: diff --git a/rally/plugins/openstack/scenarios/nova/aggregates.py b/rally/plugins/openstack/scenarios/nova/aggregates.py index 887b06b6..2863ad4e 100644 --- a/rally/plugins/openstack/scenarios/nova/aggregates.py +++ b/rally/plugins/openstack/scenarios/nova/aggregates.py @@ -84,3 +84,23 @@ class CreateAndUpdateAggregate(utils.NovaScenario): """ aggregate = self._create_aggregate(availability_zone) self._update_aggregate(aggregate) + + +@validation.required_services(consts.Service.NOVA) +@validation.required_openstack(admin=True) +@scenario.configure(context={"admin_cleanup": ["nova"]}, + name="NovaAggregates.create_aggregate_add_and_remove_host") +class CreateAggregateAddAndRemoveHost(utils.NovaScenario): + """Scenario for add a host to and remove the host from an aggregate.""" + + def run(self, availability_zone): + """Create an aggregate, add a host to and remove the host from it + + Measure "nova aggregate-add-host" and "nova aggregate-remove-host" + command performance. + """ + aggregate = self._create_aggregate(availability_zone) + hosts = self._list_hosts(zone=None) + host_name = hosts[0].host_name + self._aggregate_add_host(aggregate, host_name) + self._aggregate_remove_host(aggregate, host_name) diff --git a/rally/plugins/openstack/scenarios/nova/utils.py b/rally/plugins/openstack/scenarios/nova/utils.py index bf030563..4a62e01b 100755 --- a/rally/plugins/openstack/scenarios/nova/utils.py +++ b/rally/plugins/openstack/scenarios/nova/utils.py @@ -1166,3 +1166,25 @@ class NovaScenario(scenario.OpenStackScenario): "availability_zone": availability_zone} return self.admin_clients("nova").aggregates.update(aggregate, values) + + @atomic.action_timer("nova.aggregate_add_host") + def _aggregate_add_host(self, aggregate, host): + """Add a host into the Host Aggregate. + + :param aggregate: The aggregate add host to + :param host: The host add to aggregate + :returns: The aggregate that has been added host to + """ + return self.admin_clients("nova").aggregates.add_host(aggregate, + host) + + @atomic.action_timer("nova.aggregate_remove_host") + def _aggregate_remove_host(self, aggregate, host): + """Remove a host from an aggregate. + + :param aggregate: The aggregate remove host from + :param host: The host to remove + :returns: The aggregate that has been removed host from + """ + return self.admin_clients("nova").aggregates.remove_host(aggregate, + host) diff --git a/samples/tasks/scenarios/nova/create-aggregate-add-and-remove-host.json b/samples/tasks/scenarios/nova/create-aggregate-add-and-remove-host.json new file mode 100644 index 00000000..8f52fca2 --- /dev/null +++ b/samples/tasks/scenarios/nova/create-aggregate-add-and-remove-host.json @@ -0,0 +1,25 @@ +{ + "NovaAggregates.create_aggregate_add_and_remove_host": [ + { + "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-aggregate-add-and-remove-host.yaml b/samples/tasks/scenarios/nova/create-aggregate-add-and-remove-host.yaml new file mode 100644 index 00000000..ae3ccb06 --- /dev/null +++ b/samples/tasks/scenarios/nova/create-aggregate-add-and-remove-host.yaml @@ -0,0 +1,16 @@ +--- + NovaAggregates.create_aggregate_add_and_remove_host: + - + 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 cded6c18..68ae77ee 100644 --- a/tests/unit/plugins/openstack/scenarios/nova/test_aggregates.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_aggregates.py @@ -52,3 +52,22 @@ class NovaAggregatesTestCase(test.TestCase): scenario._create_aggregate.assert_called_once_with("nova") aggregate = scenario._create_aggregate.return_value scenario._update_aggregate.assert_called_once_with(aggregate) + + def test_create_aggregate_add_and_remove_host(self): + fake_aggregate = "fake_aggregate" + fake_hosts = [mock.Mock(host_name="fake_host_name")] + scenario = aggregates.CreateAggregateAddAndRemoveHost() + scenario._create_aggregate = mock.MagicMock( + return_value=fake_aggregate) + scenario._list_hosts = mock.MagicMock( + return_value=fake_hosts) + scenario._aggregate_add_host = mock.MagicMock() + scenario._aggregate_remove_host = mock.MagicMock() + scenario.run(availability_zone="nova") + scenario._create_aggregate.assert_called_once_with( + "nova") + scenario._list_hosts.assert_called_once_with(zone=None) + scenario._aggregate_add_host.assert_called_once_with( + "fake_aggregate", "fake_host_name") + scenario._aggregate_remove_host.assert_called_once_with( + "fake_aggregate", "fake_host_name") diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py index 4d779c35..a0fc30ed 100755 --- a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py @@ -1096,3 +1096,26 @@ class NovaScenarioTestCase(test.ScenarioTestCase): aggregate, values) self._test_atomic_action_timer(nova_scenario.atomic_actions(), "nova.update_aggregate") + + def test_aggregate_add_host(self): + nova_scenario = utils.NovaScenario(context=self.context) + result = nova_scenario._aggregate_add_host("fake_agg", "fake_host") + self.assertEqual( + self.admin_clients("nova").aggregates.add_host.return_value, + result) + self.admin_clients("nova").aggregates.add_host.assert_called_once_with( + "fake_agg", "fake_host") + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.aggregate_add_host") + + def test_aggregate_remove_host(self): + nova_scenario = utils.NovaScenario(context=self.context) + result = nova_scenario._aggregate_remove_host("fake_agg", "fake_host") + self.assertEqual( + self.admin_clients("nova").aggregates.remove_host.return_value, + result) + self.admin_clients( + "nova").aggregates.remove_host.assert_called_once_with( + "fake_agg", "fake_host") + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.aggregate_remove_host")