From c2983cff5ec4d4292f7b08dec484a83b78057ac9 Mon Sep 17 00:00:00 2001 From: Alexander Gubanov Date: Mon, 20 Apr 2015 16:15:21 +0300 Subject: [PATCH] Adds Nova floating IPs bulk tests Added methods for creating nova floating IPs by range and configuration files for these operations. Change-Id: I7f94b0d484fe3580f017b09ba90fb4b175b6655d --- rally-jobs/rally.yaml | 32 ++++++++++ rally/benchmark/context/cleanup/resources.py | 12 ++++ .../scenarios/nova/floating_ips_bulk.py | 58 +++++++++++++++++++ rally/benchmark/scenarios/nova/utils.py | 19 ++++++ rally/benchmark/validation.py | 8 +++ .../create-and-delete-floating-ips-bulk.json | 20 +++++++ .../create-and-delete-floating-ips-bulk.yaml | 13 +++++ .../create-and-list-floating-ips-bulk.json | 20 +++++++ .../create-and-list-floating-ips-bulk.yaml | 14 +++++ .../context/cleanup/test_resources.py | 18 ++++++ .../scenarios/nova/test_floating_ips_bulk.py | 50 ++++++++++++++++ .../benchmark/scenarios/nova/test_utils.py | 38 ++++++++++++ tests/unit/benchmark/test_validation.py | 6 ++ 13 files changed, 308 insertions(+) create mode 100644 rally/benchmark/scenarios/nova/floating_ips_bulk.py create mode 100644 samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.json create mode 100644 samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.yaml create mode 100644 samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.json create mode 100644 samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.yaml create mode 100644 tests/unit/benchmark/scenarios/nova/test_floating_ips_bulk.py diff --git a/rally-jobs/rally.yaml b/rally-jobs/rally.yaml index a4b66cb592..b831789aa4 100755 --- a/rally-jobs/rally.yaml +++ b/rally-jobs/rally.yaml @@ -1526,3 +1526,35 @@ sla: failure_rate: max: 0 + + NovaFloatingIpsBulk.create_and_list_floating_ips_bulk: + - + args: + start_cidr: "10.2.0.0/24" + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + + NovaFloatingIpsBulk.create_and_delete_floating_ips_bulk: + - + args: + start_cidr: "10.2.0.0/24" + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 diff --git a/rally/benchmark/context/cleanup/resources.py b/rally/benchmark/context/cleanup/resources.py index 5372ee40eb..903bbd76a0 100644 --- a/rally/benchmark/context/cleanup/resources.py +++ b/rally/benchmark/context/cleanup/resources.py @@ -84,6 +84,18 @@ class NovaQuotas(QuotaMixin, base.ResourceManager): pass +@base.resource("nova", "floating_ips_bulk", order=next(_nova_order), + admin_required=True) +class NovaFloatingIpsBulk(SynchronizedDeletion, base.ResourceManager): + + def id(self): + return self.raw_resource.address + + def list(self): + return [floating_ip for floating_ip in self._manager().list() + if floating_ip.pool.startswith("rally_fip_pool_")] + + # EC2 _ec2_order = get_order(250) diff --git a/rally/benchmark/scenarios/nova/floating_ips_bulk.py b/rally/benchmark/scenarios/nova/floating_ips_bulk.py new file mode 100644 index 0000000000..95a2f8a7b2 --- /dev/null +++ b/rally/benchmark/scenarios/nova/floating_ips_bulk.py @@ -0,0 +1,58 @@ +# Copyright 2015: Mirantis Inc. +# 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.benchmark.scenarios import base +from rally.benchmark.scenarios.nova import utils +from rally.benchmark import validation +from rally import consts + + +class NovaFloatingIpsBulk(utils.NovaScenario): + """Benchmark scenarios for create nova floating IP by range.""" + + @validation.restricted_parameters("pool") + @validation.required_parameters("start_cidr") + @validation.required_services(consts.Service.NOVA) + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["nova"]}) + def create_and_list_floating_ips_bulk(self, start_cidr, **kwargs): + """Create nova floating IP by range and list it. + + This scenario creates a floating IP by range and then lists all. + + :param start_cidr: Floating IP range + :param kwargs: Optional additional arguments for range IP creation + """ + + self._create_floating_ips_bulk(start_cidr, **kwargs) + self._list_floating_ips_bulk() + + @validation.restricted_parameters("pool") + @validation.required_parameters("start_cidr") + @validation.required_services(consts.Service.NOVA) + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["nova"]}) + def create_and_delete_floating_ips_bulk(self, start_cidr, **kwargs): + """Create nova floating IP by range and delete it. + + This scenario creates a floating IP by range and then delete it. + + :param start_cidr: Floating IP range + :param kwargs: Optional additional arguments for range IP creation + """ + + floating_ips_bulk = self._create_floating_ips_bulk(start_cidr, + **kwargs) + self._delete_floating_ips_bulk(floating_ips_bulk.ip_range) diff --git a/rally/benchmark/scenarios/nova/utils.py b/rally/benchmark/scenarios/nova/utils.py index 2fb414f2ff..a6f9a44664 100644 --- a/rally/benchmark/scenarios/nova/utils.py +++ b/rally/benchmark/scenarios/nova/utils.py @@ -21,6 +21,7 @@ import six from rally.benchmark.scenarios import base from rally.benchmark import utils as bench_utils +from rally.benchmark.wrappers import network as network_wrapper from rally import exceptions @@ -698,3 +699,21 @@ class NovaScenario(base.Scenario): """Return security groups list.""" with base.AtomicAction(self, "nova.list_security_groups"): return self.clients("nova").security_groups.list() + + @base.atomic_action_timer("nova.list_floating_ips_bulk") + def _list_floating_ips_bulk(self): + """List all floating IPs.""" + return self.admin_clients("nova").floating_ips_bulk.list() + + @base.atomic_action_timer("nova.create_floating_ips_bulk") + def _create_floating_ips_bulk(self, ip_range, **kwargs): + """Create floating IPs by range.""" + ip_range = network_wrapper.generate_cidr(start_cidr=ip_range) + pool_name = self._generate_random_name(prefix="rally_fip_pool_") + return self.admin_clients("nova").floating_ips_bulk.create( + ip_range=ip_range, pool=pool_name, **kwargs) + + @base.atomic_action_timer("nova.delete_floating_ips_bulk") + def _delete_floating_ips_bulk(self, ip_range): + """Delete floating IPs by range.""" + return self.admin_clients("nova").floating_ips_bulk.delete(ip_range) diff --git a/rally/benchmark/validation.py b/rally/benchmark/validation.py index 973a63d142..9e60e424f1 100644 --- a/rally/benchmark/validation.py +++ b/rally/benchmark/validation.py @@ -494,3 +494,11 @@ def volume_type_exists(config, clients, deployment, param_name): message = (_("Must have at least one volume type created " "when specifying use of volume types.")) return ValidationResult(False, message) + + +@validator +def restricted_parameters(config, clients, deployment, param_name): + """Validator that check that parameter is not set.""" + if param_name in config.get("args", {}): + return ValidationResult(False, "You can't specify parameter `%s`" % + param_name) \ No newline at end of file diff --git a/samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.json b/samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.json new file mode 100644 index 0000000000..48ea4bf239 --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.json @@ -0,0 +1,20 @@ +{ + "NovaFloatingIpsBulk.create_and_delete_floating_ips_bulk": [ + { + "args": { + "start_cidr": "10.2.0.0/24" + }, + "runner": { + "type": "constant", + "times": 5, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.yaml b/samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.yaml new file mode 100644 index 0000000000..4535eb4c62 --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-delete-floating-ips-bulk.yaml @@ -0,0 +1,13 @@ +--- + NovaFloatingIpsBulk.create_and_delete_floating_ips_bulk: + - + args: + start_cidr: "10.2.0.0/24" + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 diff --git a/samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.json b/samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.json new file mode 100644 index 0000000000..e596088e58 --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.json @@ -0,0 +1,20 @@ +{ + "NovaFloatingIpsBulk.create_and_list_floating_ips_bulk": [ + { + "args": { + "start_cidr": "10.2.0.0/24" + }, + "runner": { + "type": "constant", + "times": 5, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.yaml b/samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.yaml new file mode 100644 index 0000000000..606342c019 --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-list-floating-ips-bulk.yaml @@ -0,0 +1,14 @@ +--- + NovaFloatingIpsBulk.create_and_list_floating_ips_bulk: + - + args: + start_cidr: "10.2.0.0/24" + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 + diff --git a/tests/unit/benchmark/context/cleanup/test_resources.py b/tests/unit/benchmark/context/cleanup/test_resources.py index d3fb745e62..60415b0435 100644 --- a/tests/unit/benchmark/context/cleanup/test_resources.py +++ b/tests/unit/benchmark/context/cleanup/test_resources.py @@ -96,6 +96,24 @@ class NovaSecurityGroupTestCase(test.TestCase): resources.NovaSecurityGroup().list()) +class NovaFloatingIpsBulkTestCase(test.TestCase): + + def test_id(self): + ip_range = resources.NovaFloatingIpsBulk() + ip_range.raw_resource = mock.MagicMock() + self.assertEqual(ip_range.raw_resource.address, ip_range.id()) + + @mock.patch("%s.base.ResourceManager._manager" % BASE) + def test_list(self, mock_manager): + ip_range = [mock.MagicMock(), mock.MagicMock(), mock.MagicMock()] + ip_range[0].pool = "a" + ip_range[1].pool = "rally_fip_pool_a" + ip_range[2].pool = "rally_fip_pool_b" + + mock_manager().list.return_value = ip_range + self.assertEqual(ip_range[1:], resources.NovaFloatingIpsBulk().list()) + + class EC2MixinTestCase(test.TestCase): def get_ec2_mixin(self): diff --git a/tests/unit/benchmark/scenarios/nova/test_floating_ips_bulk.py b/tests/unit/benchmark/scenarios/nova/test_floating_ips_bulk.py new file mode 100644 index 0000000000..2478dbc458 --- /dev/null +++ b/tests/unit/benchmark/scenarios/nova/test_floating_ips_bulk.py @@ -0,0 +1,50 @@ +# Copyright 2015: Mirantis Inc. +# 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.benchmark.scenarios.nova import floating_ips_bulk +from tests.unit import test + + +class NovaFloatingIPsBulkTestCase(test.TestCase): + + def test_create_and_list_floating_ips_bulk(self): + scenario = floating_ips_bulk.NovaFloatingIpsBulk() + scenario._create_floating_ips_bulk = mock.MagicMock() + scenario._list_floating_ips_bulk = mock.MagicMock() + start_cidr = "10.2.0.0/24" + scenario.create_and_list_floating_ips_bulk(start_cidr=start_cidr, + fakearg="fakearg") + + scenario._create_floating_ips_bulk.assert_called_once_with( + start_cidr, fakearg="fakearg") + scenario._list_floating_ips_bulk.assert_called_once_with() + + def test_create_and_delete_floating_ips_bulk(self): + scenario = floating_ips_bulk.NovaFloatingIpsBulk() + fake_floating_ips_bulk = mock.MagicMock() + fake_floating_ips_bulk.ip_range = "10.2.0.0/24" + scenario._create_floating_ips_bulk = mock.MagicMock( + return_value=fake_floating_ips_bulk) + scenario._delete_floating_ips_bulk = mock.MagicMock() + start_cidr = "10.2.0.0/24" + scenario.create_and_delete_floating_ips_bulk(start_cidr=start_cidr, + fakearg="fakearg") + + scenario._create_floating_ips_bulk.assert_called_once_with( + start_cidr, fakearg="fakearg") + scenario._delete_floating_ips_bulk.assert_called_once_with( + fake_floating_ips_bulk.ip_range) diff --git a/tests/unit/benchmark/scenarios/nova/test_utils.py b/tests/unit/benchmark/scenarios/nova/test_utils.py index 5c5335abb9..efb86c0f04 100644 --- a/tests/unit/benchmark/scenarios/nova/test_utils.py +++ b/tests/unit/benchmark/scenarios/nova/test_utils.py @@ -733,3 +733,41 @@ class NovaScenarioTestCase(test.TestCase): self.keypair) self._test_atomic_action_timer(nova_scenario.atomic_actions(), "nova.delete_keypair") + + @mock.patch(NOVA_UTILS + ".NovaScenario.admin_clients") + def test__list_floating_ips_bulk(self, mock_clients): + floating_ips_bulk_list = ["foo_floating_ips_bulk"] + mock_clients("nova").floating_ips_bulk.list.return_value = ( + floating_ips_bulk_list) + nova_scenario = utils.NovaScenario() + return_floating_ips_bulk_list = nova_scenario._list_floating_ips_bulk() + self.assertEqual(floating_ips_bulk_list, return_floating_ips_bulk_list) + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.list_floating_ips_bulk") + + @mock.patch(NOVA_UTILS + ".network_wrapper.generate_cidr") + @mock.patch(NOVA_UTILS + ".NovaScenario.admin_clients") + def test__create_floating_ips_bulk(self, mock_clients, mock_gencidr): + fake_cidr = "10.2.0.0/24" + fake_pool = "test1" + fake_floating_ips_bulk = mock.MagicMock() + fake_floating_ips_bulk.ip_range = fake_cidr + fake_floating_ips_bulk.pool = fake_pool + mock_clients("nova").floating_ips_bulk.create.return_value = ( + fake_floating_ips_bulk) + nova_scenario = utils.NovaScenario() + return_iprange = nova_scenario._create_floating_ips_bulk(fake_cidr) + mock_gencidr.assert_called_once_with(start_cidr=fake_cidr) + self.assertEqual(return_iprange, fake_floating_ips_bulk) + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.create_floating_ips_bulk") + + @mock.patch(NOVA_UTILS + ".NovaScenario.admin_clients") + def test__delete_floating_ips_bulk(self, mock_clients): + fake_cidr = "10.2.0.0/24" + nova_scenario = utils.NovaScenario() + nova_scenario._delete_floating_ips_bulk(fake_cidr) + mock_clients("nova").floating_ips_bulk.delete.assert_called_once_with( + fake_cidr) + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.delete_floating_ips_bulk") diff --git a/tests/unit/benchmark/test_validation.py b/tests/unit/benchmark/test_validation.py index 9dd1944fd5..0eba897184 100644 --- a/tests/unit/benchmark/test_validation.py +++ b/tests/unit/benchmark/test_validation.py @@ -639,3 +639,9 @@ class ValidatorsTestCase(test.TestCase): fake_service.state = "down" result = validator({}, None, deployment) self.assertFalse(result.is_valid, result.msg) + + def test_restricted_parameters(self): + validator = self._unwrap_validator( + validation.restricted_parameters, "param_name") + result = validator({"args": {}}, None, None) + self.assertTrue(result.is_valid, result.msg)