From 0fa9a4eadc886a4f1f426eff7e5acf2648463446 Mon Sep 17 00:00:00 2001 From: Kiran Date: Mon, 22 Jun 2015 17:02:14 +0530 Subject: [PATCH] Add Neutron Loadbalancer v1 create and update vips Enable benchmarking of the Neutron LoadBalancer v1 lb-vip-create and lb-vip-update APIs. Due to the different API scheme and confusing naming conventions in Neutron (LB is v1 API and LBaaS for v2 API) the appropriate code is explicitly marked with 'v1' since this only implements the API v1 benchmarking. Change-Id: I0b458044891a0931eea99785d088f0851650c3d6 --- rally-jobs/rally-neutron.yaml | 25 ++++++++++ .../scenarios/neutron/loadbalancer_v1.py | 31 ++++++++++++ .../openstack/scenarios/neutron/utils.py | 14 ++++++ .../neutron/create_and_update_vips.json | 30 +++++++++++ .../neutron/create_and_update_vips.yaml | 21 ++++++++ tests/unit/fakes.py | 3 ++ .../scenarios/neutron/test_loadbalancer_v1.py | 50 +++++++++++++++++++ .../openstack/scenarios/neutron/test_utils.py | 21 ++++++++ 8 files changed, 195 insertions(+) create mode 100644 samples/tasks/scenarios/neutron/create_and_update_vips.json create mode 100644 samples/tasks/scenarios/neutron/create_and_update_vips.yaml diff --git a/rally-jobs/rally-neutron.yaml b/rally-jobs/rally-neutron.yaml index 11747d547c..4326946267 100644 --- a/rally-jobs/rally-neutron.yaml +++ b/rally-jobs/rally-neutron.yaml @@ -212,6 +212,31 @@ failure_rate: max: 0 + NeutronLoadbalancerV1.create_and_update_vips: + - + args: + vip_create_args: {} + vip_update_args: {} + pool_create_args: {} + runner: + type: "constant" + times: 20 + concurrency: 10 + context: + users: + tenants: 4 + users_per_tenant: 5 + network: {} + quotas: + neutron: + network: -1 + subnet: -1 + pool: -1 + vip: -1 + sla: + failure_rate: + max: 0 + NeutronNetworks.create_and_update_networks: - args: diff --git a/rally/plugins/openstack/scenarios/neutron/loadbalancer_v1.py b/rally/plugins/openstack/scenarios/neutron/loadbalancer_v1.py index fad34f79e3..db11cb0bda 100644 --- a/rally/plugins/openstack/scenarios/neutron/loadbalancer_v1.py +++ b/rally/plugins/openstack/scenarios/neutron/loadbalancer_v1.py @@ -141,3 +141,34 @@ class NeutronLoadbalancerV1(utils.NeutronScenario): vips.append(self._create_v1_vip(pool, **vip_create_args)) for vip in vips: self._delete_v1_vip(vip["vip"]) + + @validation.restricted_parameters(["pool_id", "subnet_id"], + subdict="vip_create_args") + @validation.required_services(consts.Service.NEUTRON) + @validation.required_openstack(users=True) + @validation.required_contexts("network") + @scenario.configure(context={"cleanup": ["neutron"]}) + def create_and_update_vips(self, pool_create_args=None, + vip_update_args=None, + vip_create_args=None): + """Create vips(v1) and update vips(v1). + + Measure the "neutron lb-vip-create" and "neutron lb-vip-update" + command performance. The scenario creates a pool for every subnet + and then update those pools. + + :param pool_create_args: dict, POST /lb/pools request options + :param vip_create_args: dict, POST /lb/vips request options + :param vip_update_args: dict, POST /lb/vips update options + """ + vips = [] + pool_create_args = pool_create_args or {} + vip_create_args = vip_create_args or {} + vip_update_args = vip_update_args or {} + networks = self.context.get("tenant", {}).get("networks", []) + pools = self._create_v1_pools(networks, **pool_create_args) + with atomic.ActionTimer(self, "neutron.create_%s_vips" % len(pools)): + for pool in pools: + vips.append(self._create_v1_vip(pool, **vip_create_args)) + for vip in vips: + self._update_v1_vip(vip, **vip_update_args) diff --git a/rally/plugins/openstack/scenarios/neutron/utils.py b/rally/plugins/openstack/scenarios/neutron/utils.py index 33e2c2000b..0e58041fc9 100644 --- a/rally/plugins/openstack/scenarios/neutron/utils.py +++ b/rally/plugins/openstack/scenarios/neutron/utils.py @@ -376,3 +376,17 @@ class NeutronScenario(scenario.OpenStackScenario): :param vip: neutron Virtual IP object """ self.clients("neutron").delete_vip(vip["id"]) + + @atomic.action_timer("neutron.update_vip") + def _update_v1_vip(self, vip, **vip_update_args): + """Updates vip. + + This atomic function updates vip name and admin state + + :param vip: Vip object + :param vip_update_args: dict, POST /lb/vips update options + :returns: updated neutron vip dict + """ + self._warn_about_deprecated_name_kwarg(vip, vip_update_args) + body = {"vip": vip_update_args} + return self.clients("neutron").update_vip(vip["vip"]["id"], body) diff --git a/samples/tasks/scenarios/neutron/create_and_update_vips.json b/samples/tasks/scenarios/neutron/create_and_update_vips.json new file mode 100644 index 0000000000..b734a1fb02 --- /dev/null +++ b/samples/tasks/scenarios/neutron/create_and_update_vips.json @@ -0,0 +1,30 @@ +{ + "NeutronLoadbalancerV1.create_and_update_vips": [ + { + "args": { + "vip_create_args":{}, + "vip_update_args":{} + }, + "runner": { + "type": "constant", + "times": 100, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 1 + }, + "network": {}, + "quotas": { + "neutron": { + "network": -1, + "subnet": -1, + "pool": -1, + "vip": -1 + } + } + } + } + ] +} diff --git a/samples/tasks/scenarios/neutron/create_and_update_vips.yaml b/samples/tasks/scenarios/neutron/create_and_update_vips.yaml new file mode 100644 index 0000000000..df649b4df8 --- /dev/null +++ b/samples/tasks/scenarios/neutron/create_and_update_vips.yaml @@ -0,0 +1,21 @@ +--- + NeutronLoadbalancerV1.create_and_update_vips: + - + args: + vip_create_args: {} + vip_update_args: {} + runner: + type: "constant" + times: 100 + concurrency: 10 + context: + users: + tenants: 1 + users_per_tenant: 1 + network: {} + quotas: + neutron: + network: -1 + subnet: -1 + pool: -1 + vip: -1 diff --git a/tests/unit/fakes.py b/tests/unit/fakes.py index 12f6f09710..fced5e99e6 100644 --- a/tests/unit/fakes.py +++ b/tests/unit/fakes.py @@ -1189,6 +1189,9 @@ class FakeNeutronClient(object): def update_pool(self, pool_id, data): self.update_resource(pool_id, self.__pools, data) + def update_vip(self, vip_id, data): + self.update_resource(vip_id, self.__vips, data) + def update_subnet(self, subnet_id, data): self.update_resource(subnet_id, self.__subnets, data) diff --git a/tests/unit/plugins/openstack/scenarios/neutron/test_loadbalancer_v1.py b/tests/unit/plugins/openstack/scenarios/neutron/test_loadbalancer_v1.py index 42178dcffc..a129626299 100644 --- a/tests/unit/plugins/openstack/scenarios/neutron/test_loadbalancer_v1.py +++ b/tests/unit/plugins/openstack/scenarios/neutron/test_loadbalancer_v1.py @@ -190,3 +190,53 @@ class NeutronLoadbalancerv1TestCase(test.TestCase): [mock.call(pool, **vip_data) for pool in net["lb_pools"]]) neutron_scenario._delete_v1_vip.assert_has_calls( [mock.call(vip["vip"])]) + + @ddt.data( + {}, + {"vip_create_args": None}, + {"vip_create_args": {}}, + {"vip_create_args": {"name": "given-vip-name"}}, + {"pool_create_args": None}, + {"pool_create_args": {}}, + {"pool_create_args": {"name": "given-pool-name"}}, + ) + @ddt.unpack + def test_create_and_update_vips(self, pool_create_args=None, + vip_create_args=None, + vip_update_args=None): + neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1( + self._get_context()) + pools = [{ + "pool": { + "id": "pool-id", + } + }] + expected_vip = { + "vip": { + "id": "vip-id", + "name": "vip-name" + } + } + updated_vip = { + "vip": { + "id": "vip-id", + "name": "updated-vip-name" + } + } + vips = [expected_vip] + vip_data = vip_create_args or {} + vip_update_data = vip_update_args or {} + pool_data = pool_create_args or {} + networks = self._get_context()["tenant"]["networks"] + neutron_scenario._create_v1_pools = mock.Mock(return_value=pools) + neutron_scenario._create_v1_vip = mock.Mock(return_value=expected_vip) + neutron_scenario._update_v1_vip = mock.Mock(return_value=updated_vip) + neutron_scenario.create_and_update_vips( + pool_create_args=pool_create_args, vip_create_args=vip_create_args, + vip_update_args=vip_update_args) + neutron_scenario._create_v1_pools.assert_called_once_with( + networks, **pool_data) + neutron_scenario._create_v1_vip.assert_has_calls( + [mock.call(pool, **vip_data) for pool in pools]) + neutron_scenario._update_v1_vip.assert_has_calls( + [mock.call(vip, **vip_update_data) for vip in vips]) diff --git a/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py b/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py index 5c784c8ff8..38102a295a 100644 --- a/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py @@ -496,6 +496,27 @@ class NeutronScenarioTestCase(test.ScenarioTestCase): self._test_atomic_action_timer(scenario.atomic_actions(), "neutron.delete_vip") + def test_update_v1_vip(self): + scenario = utils.NeutronScenario() + scenario._generate_random_name = mock.Mock(return_value="random_name") + expected_vip = { + "vip": { + "name": scenario._generate_random_name.return_value, + "admin_state_up": False + } + } + self.clients("neutron").update_vip.return_value = expected_vip + + vip = {"vip": {"name": "vip-name", "id": "vip-id"}} + vip_update_args = {"name": "foo", "admin_state_up": False} + + result_vip = scenario._update_v1_vip(vip, **vip_update_args) + self.assertEqual(result_vip, expected_vip) + self.clients("neutron").update_vip.assert_called_once_with( + vip["vip"]["id"], expected_vip) + self._test_atomic_action_timer(scenario.atomic_actions(), + "neutron.update_vip") + class NeutronScenarioFunctionalTestCase(test.FakeClientsScenarioTestCase):