| # Copyright 2013 OpenStack Foundation |
| # 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 tempest_lib.common.utils import data_utils |
| from tempest_lib import decorators |
| |
| from tempest.api.network import base |
| from tempest import test |
| |
| |
| class LoadBalancerTestJSON(base.BaseNetworkTest): |
| |
| """ |
| Tests the following operations in the Neutron API using the REST client for |
| Neutron: |
| |
| create vIP, and Pool |
| show vIP |
| list vIP |
| update vIP |
| delete vIP |
| update pool |
| delete pool |
| show pool |
| list pool |
| health monitoring operations |
| """ |
| |
| @classmethod |
| def resource_setup(cls): |
| super(LoadBalancerTestJSON, cls).resource_setup() |
| if not test.is_extension_enabled('lbaas', 'network'): |
| msg = "lbaas extension not enabled." |
| raise cls.skipException(msg) |
| cls.network = cls.create_network() |
| cls.name = cls.network['name'] |
| cls.subnet = cls.create_subnet(cls.network) |
| pool_name = data_utils.rand_name('pool-') |
| vip_name = data_utils.rand_name('vip-') |
| cls.pool = cls.create_pool(pool_name, "ROUND_ROBIN", |
| "HTTP", cls.subnet) |
| cls.vip = cls.create_vip(name=vip_name, |
| protocol="HTTP", |
| protocol_port=80, |
| subnet=cls.subnet, |
| pool=cls.pool) |
| cls.member = cls.create_member(80, cls.pool, cls._ip_version) |
| cls.member_address = ("10.0.9.47" if cls._ip_version == 4 |
| else "2015::beef") |
| cls.health_monitor = cls.create_health_monitor(delay=4, |
| max_retries=3, |
| Type="TCP", |
| timeout=1) |
| |
| def _check_list_with_filter(self, obj_name, attr_exceptions, **kwargs): |
| create_obj = getattr(self.client, 'create_' + obj_name) |
| delete_obj = getattr(self.client, 'delete_' + obj_name) |
| list_objs = getattr(self.client, 'list_' + obj_name + 's') |
| |
| body = create_obj(**kwargs) |
| obj = body[obj_name] |
| self.addCleanup(delete_obj, obj['id']) |
| for key, value in obj.iteritems(): |
| # It is not relevant to filter by all arguments. That is why |
| # there is a list of attr to except |
| if key not in attr_exceptions: |
| body = list_objs(**{key: value}) |
| objs = [v[key] for v in body[obj_name + 's']] |
| self.assertIn(value, objs) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('c96dbfab-4a80-4e74-a535-e950b5bedd47') |
| def test_list_vips(self): |
| # Verify the vIP exists in the list of all vIPs |
| body = self.client.list_vips() |
| vips = body['vips'] |
| self.assertIn(self.vip['id'], [v['id'] for v in vips]) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('b8853f65-5089-4e69-befd-041a143427ff') |
| def test_list_vips_with_filter(self): |
| name = data_utils.rand_name('vip-') |
| body = self.client.create_pool(name=data_utils.rand_name("pool-"), |
| lb_method="ROUND_ROBIN", |
| protocol="HTTPS", |
| subnet_id=self.subnet['id']) |
| pool = body['pool'] |
| self.addCleanup(self.client.delete_pool, pool['id']) |
| attr_exceptions = ['status', 'session_persistence', |
| 'status_description'] |
| self._check_list_with_filter( |
| 'vip', attr_exceptions, name=name, protocol="HTTPS", |
| protocol_port=81, subnet_id=self.subnet['id'], pool_id=pool['id'], |
| description=data_utils.rand_name('description-'), |
| admin_state_up=False) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('27f56083-9af9-4a48-abe9-ca1bcc6c9035') |
| def test_create_update_delete_pool_vip(self): |
| # Creates a vip |
| name = data_utils.rand_name('vip-') |
| address = self.subnet['allocation_pools'][0]['end'] |
| body = self.client.create_pool( |
| name=data_utils.rand_name("pool-"), |
| lb_method='ROUND_ROBIN', |
| protocol='HTTP', |
| subnet_id=self.subnet['id']) |
| pool = body['pool'] |
| body = self.client.create_vip(name=name, |
| protocol="HTTP", |
| protocol_port=80, |
| subnet_id=self.subnet['id'], |
| pool_id=pool['id'], |
| address=address) |
| vip = body['vip'] |
| vip_id = vip['id'] |
| # Confirm VIP's address correctness with a show |
| body = self.client.show_vip(vip_id) |
| vip = body['vip'] |
| self.assertEqual(address, vip['address']) |
| # Verification of vip update |
| new_name = "New_vip" |
| new_description = "New description" |
| persistence_type = "HTTP_COOKIE" |
| update_data = {"session_persistence": { |
| "type": persistence_type}} |
| body = self.client.update_vip(vip_id, |
| name=new_name, |
| description=new_description, |
| connection_limit=10, |
| admin_state_up=False, |
| **update_data) |
| updated_vip = body['vip'] |
| self.assertEqual(new_name, updated_vip['name']) |
| self.assertEqual(new_description, updated_vip['description']) |
| self.assertEqual(10, updated_vip['connection_limit']) |
| self.assertFalse(updated_vip['admin_state_up']) |
| self.assertEqual(persistence_type, |
| updated_vip['session_persistence']['type']) |
| self.client.delete_vip(vip['id']) |
| self.client.wait_for_resource_deletion('vip', vip['id']) |
| # Verification of pool update |
| new_name = "New_pool" |
| body = self.client.update_pool(pool['id'], |
| name=new_name, |
| description="new_description", |
| lb_method='LEAST_CONNECTIONS') |
| updated_pool = body['pool'] |
| self.assertEqual(new_name, updated_pool['name']) |
| self.assertEqual('new_description', updated_pool['description']) |
| self.assertEqual('LEAST_CONNECTIONS', updated_pool['lb_method']) |
| self.client.delete_pool(pool['id']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('0435a95e-1d19-4d90-9e9f-3b979e9ad089') |
| def test_show_vip(self): |
| # Verifies the details of a vip |
| body = self.client.show_vip(self.vip['id']) |
| vip = body['vip'] |
| for key, value in vip.iteritems(): |
| # 'status' should not be confirmed in api tests |
| if key != 'status': |
| self.assertEqual(self.vip[key], value) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('6e7a7d31-8451-456d-b24a-e50479ce42a7') |
| def test_show_pool(self): |
| # Here we need to new pool without any dependence with vips |
| body = self.client.create_pool(name=data_utils.rand_name("pool-"), |
| lb_method='ROUND_ROBIN', |
| protocol='HTTP', |
| subnet_id=self.subnet['id']) |
| pool = body['pool'] |
| self.addCleanup(self.client.delete_pool, pool['id']) |
| # Verifies the details of a pool |
| body = self.client.show_pool(pool['id']) |
| shown_pool = body['pool'] |
| for key, value in pool.iteritems(): |
| # 'status' should not be confirmed in api tests |
| if key != 'status': |
| self.assertEqual(value, shown_pool[key]) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('d1ab1ffa-e06a-487f-911f-56418cb27727') |
| def test_list_pools(self): |
| # Verify the pool exists in the list of all pools |
| body = self.client.list_pools() |
| pools = body['pools'] |
| self.assertIn(self.pool['id'], [p['id'] for p in pools]) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('27cc4c1a-caac-4273-b983-2acb4afaad4f') |
| def test_list_pools_with_filters(self): |
| attr_exceptions = ['status', 'vip_id', 'members', 'provider', |
| 'status_description'] |
| self._check_list_with_filter( |
| 'pool', attr_exceptions, name=data_utils.rand_name("pool-"), |
| lb_method="ROUND_ROBIN", protocol="HTTPS", |
| subnet_id=self.subnet['id'], |
| description=data_utils.rand_name('description-'), |
| admin_state_up=False) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('282d0dfd-5c3a-4c9b-b39c-c99782f39193') |
| def test_list_members(self): |
| # Verify the member exists in the list of all members |
| body = self.client.list_members() |
| members = body['members'] |
| self.assertIn(self.member['id'], [m['id'] for m in members]) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('243b5126-24c6-4879-953e-7c7e32d8a57f') |
| def test_list_members_with_filters(self): |
| attr_exceptions = ['status', 'status_description'] |
| self._check_list_with_filter('member', attr_exceptions, |
| address=self.member_address, |
| protocol_port=80, |
| pool_id=self.pool['id']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('fb833ee8-9e69-489f-b540-a409762b78b2') |
| def test_create_update_delete_member(self): |
| # Creates a member |
| body = self.client.create_member(address=self.member_address, |
| protocol_port=80, |
| pool_id=self.pool['id']) |
| member = body['member'] |
| # Verification of member update |
| body = self.client.update_member(member['id'], |
| admin_state_up=False) |
| updated_member = body['member'] |
| self.assertFalse(updated_member['admin_state_up']) |
| # Verification of member delete |
| self.client.delete_member(member['id']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('893cd71f-a7dd-4485-b162-f6ab9a534914') |
| def test_show_member(self): |
| # Verifies the details of a member |
| body = self.client.show_member(self.member['id']) |
| member = body['member'] |
| for key, value in member.iteritems(): |
| # 'status' should not be confirmed in api tests |
| if key != 'status': |
| self.assertEqual(self.member[key], value) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('8e5822c5-68a4-4224-8d6c-a617741ebc2d') |
| def test_list_health_monitors(self): |
| # Verify the health monitor exists in the list of all health monitors |
| body = self.client.list_health_monitors() |
| health_monitors = body['health_monitors'] |
| self.assertIn(self.health_monitor['id'], |
| [h['id'] for h in health_monitors]) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('49bac58a-511c-4875-b794-366698211d25') |
| def test_list_health_monitors_with_filters(self): |
| attr_exceptions = ['status', 'status_description', 'pools'] |
| self._check_list_with_filter('health_monitor', attr_exceptions, |
| delay=5, max_retries=4, type="TCP", |
| timeout=2) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('e8ce05c4-d554-4d1e-a257-ad32ce134bb5') |
| def test_create_update_delete_health_monitor(self): |
| # Creates a health_monitor |
| body = self.client.create_health_monitor(delay=4, |
| max_retries=3, |
| type="TCP", |
| timeout=1) |
| health_monitor = body['health_monitor'] |
| # Verification of health_monitor update |
| body = (self.client.update_health_monitor |
| (health_monitor['id'], |
| admin_state_up=False)) |
| updated_health_monitor = body['health_monitor'] |
| self.assertFalse(updated_health_monitor['admin_state_up']) |
| # Verification of health_monitor delete |
| body = self.client.delete_health_monitor(health_monitor['id']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('d3e1aebc-06c2-49b3-9816-942af54012eb') |
| def test_create_health_monitor_http_type(self): |
| hm_type = "HTTP" |
| body = self.client.create_health_monitor(delay=4, |
| max_retries=3, |
| type=hm_type, |
| timeout=1) |
| health_monitor = body['health_monitor'] |
| self.addCleanup(self.client.delete_health_monitor, |
| health_monitor['id']) |
| self.assertEqual(hm_type, health_monitor['type']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('0eff9f67-90fb-4bb1-b4ed-c5fda99fff0c') |
| def test_update_health_monitor_http_method(self): |
| body = self.client.create_health_monitor(delay=4, |
| max_retries=3, |
| type="HTTP", |
| timeout=1) |
| health_monitor = body['health_monitor'] |
| self.addCleanup(self.client.delete_health_monitor, |
| health_monitor['id']) |
| body = (self.client.update_health_monitor |
| (health_monitor['id'], |
| http_method="POST", |
| url_path="/home/user", |
| expected_codes="290")) |
| updated_health_monitor = body['health_monitor'] |
| self.assertEqual("POST", updated_health_monitor['http_method']) |
| self.assertEqual("/home/user", updated_health_monitor['url_path']) |
| self.assertEqual("290", updated_health_monitor['expected_codes']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('08e126ab-1407-483f-a22e-b11cc032ca7c') |
| def test_show_health_monitor(self): |
| # Verifies the details of a health_monitor |
| body = self.client.show_health_monitor(self.health_monitor['id']) |
| health_monitor = body['health_monitor'] |
| for key, value in health_monitor.iteritems(): |
| # 'status' should not be confirmed in api tests |
| if key != 'status': |
| self.assertEqual(self.health_monitor[key], value) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('87f7628e-8918-493d-af50-0602845dbb5b') |
| def test_associate_disassociate_health_monitor_with_pool(self): |
| # Verify that a health monitor can be associated with a pool |
| self.client.associate_health_monitor_with_pool( |
| self.health_monitor['id'], self.pool['id']) |
| body = self.client.show_health_monitor( |
| self.health_monitor['id']) |
| health_monitor = body['health_monitor'] |
| body = self.client.show_pool(self.pool['id']) |
| pool = body['pool'] |
| self.assertIn(pool['id'], |
| [p['pool_id'] for p in health_monitor['pools']]) |
| self.assertIn(health_monitor['id'], pool['health_monitors']) |
| # Verify that a health monitor can be disassociated from a pool |
| (self.client.disassociate_health_monitor_with_pool |
| (self.health_monitor['id'], self.pool['id'])) |
| body = self.client.show_pool(self.pool['id']) |
| pool = body['pool'] |
| body = self.client.show_health_monitor( |
| self.health_monitor['id']) |
| health_monitor = body['health_monitor'] |
| self.assertNotIn(health_monitor['id'], pool['health_monitors']) |
| self.assertNotIn(pool['id'], |
| [p['pool_id'] for p in health_monitor['pools']]) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('525fc7dc-be24-408d-938d-822e9783e027') |
| def test_get_lb_pool_stats(self): |
| # Verify the details of pool stats |
| body = self.client.list_lb_pool_stats(self.pool['id']) |
| stats = body['stats'] |
| self.assertIn("bytes_in", stats) |
| self.assertIn("total_connections", stats) |
| self.assertIn("active_connections", stats) |
| self.assertIn("bytes_out", stats) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('66236be2-5121-4047-8cde-db4b83b110a5') |
| def test_update_list_of_health_monitors_associated_with_pool(self): |
| (self.client.associate_health_monitor_with_pool |
| (self.health_monitor['id'], self.pool['id'])) |
| self.client.update_health_monitor( |
| self.health_monitor['id'], admin_state_up=False) |
| body = self.client.show_pool(self.pool['id']) |
| health_monitors = body['pool']['health_monitors'] |
| for health_monitor_id in health_monitors: |
| body = self.client.show_health_monitor(health_monitor_id) |
| self.assertFalse(body['health_monitor']['admin_state_up']) |
| (self.client.disassociate_health_monitor_with_pool |
| (self.health_monitor['id'], self.pool['id'])) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('44ec9b40-b501-41e2-951f-4fc673b15ac0') |
| def test_update_admin_state_up_of_pool(self): |
| self.client.update_pool(self.pool['id'], |
| admin_state_up=False) |
| body = self.client.show_pool(self.pool['id']) |
| pool = body['pool'] |
| self.assertFalse(pool['admin_state_up']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('466a9d4c-37c6-4ea2-b807-133437beb48c') |
| def test_show_vip_associated_with_pool(self): |
| body = self.client.show_pool(self.pool['id']) |
| pool = body['pool'] |
| body = self.client.show_vip(pool['vip_id']) |
| vip = body['vip'] |
| self.assertEqual(self.vip['name'], vip['name']) |
| self.assertEqual(self.vip['id'], vip['id']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('7b97694e-69d0-4151-b265-e1052a465aa8') |
| def test_show_members_associated_with_pool(self): |
| body = self.client.show_pool(self.pool['id']) |
| members = body['pool']['members'] |
| for member_id in members: |
| body = self.client.show_member(member_id) |
| self.assertIsNotNone(body['member']['status']) |
| self.assertEqual(member_id, body['member']['id']) |
| self.assertIsNotNone(body['member']['admin_state_up']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('73ed6f27-595b-4b2c-969c-dbdda6b8ab34') |
| def test_update_pool_related_to_member(self): |
| # Create new pool |
| body = self.client.create_pool(name=data_utils.rand_name("pool-"), |
| lb_method='ROUND_ROBIN', |
| protocol='HTTP', |
| subnet_id=self.subnet['id']) |
| new_pool = body['pool'] |
| self.addCleanup(self.client.delete_pool, new_pool['id']) |
| # Update member with new pool's id |
| body = self.client.update_member(self.member['id'], |
| pool_id=new_pool['id']) |
| # Confirm with show that pool_id change |
| body = self.client.show_member(self.member['id']) |
| member = body['member'] |
| self.assertEqual(member['pool_id'], new_pool['id']) |
| # Update member with old pool id, this is needed for clean up |
| body = self.client.update_member(self.member['id'], |
| pool_id=self.pool['id']) |
| |
| @test.attr(type='smoke') |
| @test.idempotent_id('cf63f071-bbe3-40ba-97a0-a33e11923162') |
| def test_update_member_weight(self): |
| self.client.update_member(self.member['id'], |
| weight=2) |
| body = self.client.show_member(self.member['id']) |
| member = body['member'] |
| self.assertEqual(2, member['weight']) |
| |
| |
| @decorators.skip_because(bug="1402007") |
| class LoadBalancerIpV6TestJSON(LoadBalancerTestJSON): |
| _ip_version = 6 |