| # 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.api.network import base |
| from tempest.common.utils import data_utils |
| from tempest import test |
| |
| |
| class LoadBalancerTestJSON(base.BaseNetworkTest): |
| _interface = 'json' |
| |
| """ |
| 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 |
| @test.safe_setup |
| def setUpClass(cls): |
| super(LoadBalancerTestJSON, cls).setUpClass() |
| 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.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') |
| |
| resp, body = create_obj(**kwargs) |
| self.assertEqual('201', resp['status']) |
| 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: |
| resp, body = list_objs(**{key: value}) |
| self.assertEqual('200', resp['status']) |
| objs = [v[key] for v in body[obj_name + 's']] |
| self.assertIn(value, objs) |
| |
| @test.attr(type='smoke') |
| def test_list_vips(self): |
| # Verify the vIP exists in the list of all vIPs |
| resp, body = self.client.list_vips() |
| self.assertEqual('200', resp['status']) |
| vips = body['vips'] |
| self.assertIn(self.vip['id'], [v['id'] for v in vips]) |
| |
| @test.attr(type='smoke') |
| def test_list_vips_with_filter(self): |
| name = data_utils.rand_name('vip-') |
| resp, body = self.client.create_pool( |
| name=data_utils.rand_name("pool-"), lb_method="ROUND_ROBIN", |
| protocol="HTTPS", subnet_id=self.subnet['id']) |
| self.assertEqual('201', resp['status']) |
| 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') |
| def test_create_update_delete_pool_vip(self): |
| # Creates a vip |
| name = data_utils.rand_name('vip-') |
| address = self.subnet['allocation_pools'][0]['end'] |
| resp, 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'] |
| resp, body = self.client.create_vip(name=name, |
| protocol="HTTP", |
| protocol_port=80, |
| subnet_id=self.subnet['id'], |
| pool_id=pool['id'], |
| address=address) |
| self.assertEqual('201', resp['status']) |
| vip = body['vip'] |
| vip_id = vip['id'] |
| # Confirm VIP's address correctness with a show |
| resp, body = self.client.show_vip(vip_id) |
| self.assertEqual('200', resp['status']) |
| 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}} |
| resp, body = self.client.update_vip(vip_id, |
| name=new_name, |
| description=new_description, |
| connection_limit=10, |
| admin_state_up=False, |
| **update_data) |
| self.assertEqual('200', resp['status']) |
| 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']) |
| # Verification of vip delete |
| resp, body = self.client.delete_vip(vip['id']) |
| self.assertEqual('204', resp['status']) |
| self.client.wait_for_resource_deletion('vip', vip['id']) |
| # Verification of pool update |
| new_name = "New_pool" |
| resp, body = self.client.update_pool(pool['id'], |
| name=new_name, |
| description="new_description", |
| lb_method='LEAST_CONNECTIONS') |
| self.assertEqual('200', resp['status']) |
| 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']) |
| # Verification of pool delete |
| resp, body = self.client.delete_pool(pool['id']) |
| self.assertEqual('204', resp['status']) |
| |
| @test.attr(type='smoke') |
| def test_show_vip(self): |
| # Verifies the details of a vip |
| resp, body = self.client.show_vip(self.vip['id']) |
| self.assertEqual('200', resp['status']) |
| 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') |
| def test_show_pool(self): |
| # Here we need to new pool without any dependence with vips |
| resp, body = self.client.create_pool( |
| name=data_utils.rand_name("pool-"), |
| lb_method='ROUND_ROBIN', |
| protocol='HTTP', |
| subnet_id=self.subnet['id']) |
| self.assertEqual('201', resp['status']) |
| pool = body['pool'] |
| self.addCleanup(self.client.delete_pool, pool['id']) |
| # Verifies the details of a pool |
| resp, body = self.client.show_pool(pool['id']) |
| self.assertEqual('200', resp['status']) |
| 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') |
| def test_list_pools(self): |
| # Verify the pool exists in the list of all pools |
| resp, body = self.client.list_pools() |
| self.assertEqual('200', resp['status']) |
| pools = body['pools'] |
| self.assertIn(self.pool['id'], [p['id'] for p in pools]) |
| |
| @test.attr(type='smoke') |
| 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') |
| def test_list_members(self): |
| # Verify the member exists in the list of all members |
| resp, body = self.client.list_members() |
| self.assertEqual('200', resp['status']) |
| members = body['members'] |
| self.assertIn(self.member['id'], [m['id'] for m in members]) |
| |
| @test.attr(type='smoke') |
| def test_list_members_with_filters(self): |
| attr_exceptions = ['status', 'status_description'] |
| self._check_list_with_filter('member', attr_exceptions, |
| address="10.0.9.47", protocol_port=80, |
| pool_id=self.pool['id']) |
| |
| @test.attr(type='smoke') |
| def test_create_update_delete_member(self): |
| # Creates a member |
| resp, body = self.client.create_member(address="10.0.9.47", |
| protocol_port=80, |
| pool_id=self.pool['id']) |
| self.assertEqual('201', resp['status']) |
| member = body['member'] |
| # Verification of member update |
| resp, body = self.client.update_member(member['id'], |
| admin_state_up=False) |
| self.assertEqual('200', resp['status']) |
| updated_member = body['member'] |
| self.assertFalse(updated_member['admin_state_up']) |
| # Verification of member delete |
| resp, body = self.client.delete_member(member['id']) |
| self.assertEqual('204', resp['status']) |
| |
| @test.attr(type='smoke') |
| def test_show_member(self): |
| # Verifies the details of a member |
| resp, body = self.client.show_member(self.member['id']) |
| self.assertEqual('200', resp['status']) |
| 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') |
| def test_list_health_monitors(self): |
| # Verify the health monitor exists in the list of all health monitors |
| resp, body = self.client.list_health_monitors() |
| self.assertEqual('200', resp['status']) |
| health_monitors = body['health_monitors'] |
| self.assertIn(self.health_monitor['id'], |
| [h['id'] for h in health_monitors]) |
| |
| @test.attr(type='smoke') |
| 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') |
| def test_create_update_delete_health_monitor(self): |
| # Creates a health_monitor |
| resp, body = self.client.create_health_monitor(delay=4, |
| max_retries=3, |
| type="TCP", |
| timeout=1) |
| self.assertEqual('201', resp['status']) |
| health_monitor = body['health_monitor'] |
| # Verification of health_monitor update |
| resp, body = (self.client.update_health_monitor |
| (health_monitor['id'], |
| admin_state_up=False)) |
| self.assertEqual('200', resp['status']) |
| updated_health_monitor = body['health_monitor'] |
| self.assertFalse(updated_health_monitor['admin_state_up']) |
| # Verification of health_monitor delete |
| resp, body = self.client.delete_health_monitor(health_monitor['id']) |
| self.assertEqual('204', resp['status']) |
| |
| @test.attr(type='smoke') |
| def test_create_health_monitor_http_type(self): |
| hm_type = "HTTP" |
| resp, body = self.client.create_health_monitor(delay=4, |
| max_retries=3, |
| type=hm_type, |
| timeout=1) |
| self.assertEqual('201', resp['status']) |
| 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') |
| def test_update_health_monitor_http_method(self): |
| resp, body = self.client.create_health_monitor(delay=4, |
| max_retries=3, |
| type="HTTP", |
| timeout=1) |
| self.assertEqual('201', resp['status']) |
| health_monitor = body['health_monitor'] |
| self.addCleanup(self.client.delete_health_monitor, |
| health_monitor['id']) |
| resp, body = (self.client.update_health_monitor |
| (health_monitor['id'], |
| http_method="POST", |
| url_path="/home/user", |
| expected_codes="290")) |
| self.assertEqual('200', resp['status']) |
| 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') |
| def test_show_health_monitor(self): |
| # Verifies the details of a health_monitor |
| resp, body = self.client.show_health_monitor(self.health_monitor['id']) |
| self.assertEqual('200', resp['status']) |
| 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') |
| def test_associate_disassociate_health_monitor_with_pool(self): |
| # Verify that a health monitor can be associated with a pool |
| resp, body = (self.client.associate_health_monitor_with_pool |
| (self.health_monitor['id'], self.pool['id'])) |
| self.assertEqual('201', resp['status']) |
| resp, body = self.client.show_health_monitor( |
| self.health_monitor['id']) |
| health_monitor = body['health_monitor'] |
| resp, 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 |
| resp, body = (self.client.disassociate_health_monitor_with_pool |
| (self.health_monitor['id'], self.pool['id'])) |
| self.assertEqual('204', resp['status']) |
| resp, body = self.client.show_pool(self.pool['id']) |
| pool = body['pool'] |
| resp, 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') |
| def test_get_lb_pool_stats(self): |
| # Verify the details of pool stats |
| resp, body = self.client.list_lb_pool_stats(self.pool['id']) |
| self.assertEqual('200', resp['status']) |
| 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') |
| def test_update_list_of_health_monitors_associated_with_pool(self): |
| resp, _ = (self.client.associate_health_monitor_with_pool |
| (self.health_monitor['id'], self.pool['id'])) |
| self.assertEqual('201', resp['status']) |
| resp, _ = self.client.update_health_monitor( |
| self.health_monitor['id'], admin_state_up=False) |
| self.assertEqual('200', resp['status']) |
| resp, body = self.client.show_pool(self.pool['id']) |
| self.assertEqual('200', resp['status']) |
| health_monitors = body['pool']['health_monitors'] |
| for health_monitor_id in health_monitors: |
| resp, body = self.client.show_health_monitor(health_monitor_id) |
| self.assertEqual('200', resp['status']) |
| self.assertFalse(body['health_monitor']['admin_state_up']) |
| resp, _ = (self.client.disassociate_health_monitor_with_pool |
| (self.health_monitor['id'], self.pool['id'])) |
| self.assertEqual('204', resp['status']) |
| |
| @test.attr(type='smoke') |
| def test_update_admin_state_up_of_pool(self): |
| resp, _ = self.client.update_pool(self.pool['id'], |
| admin_state_up=False) |
| self.assertEqual('200', resp['status']) |
| resp, body = self.client.show_pool(self.pool['id']) |
| self.assertEqual('200', resp['status']) |
| pool = body['pool'] |
| self.assertFalse(pool['admin_state_up']) |
| |
| @test.attr(type='smoke') |
| def test_show_vip_associated_with_pool(self): |
| resp, body = self.client.show_pool(self.pool['id']) |
| self.assertEqual('200', resp['status']) |
| pool = body['pool'] |
| resp, body = self.client.show_vip(pool['vip_id']) |
| self.assertEqual('200', resp['status']) |
| vip = body['vip'] |
| self.assertEqual(self.vip['name'], vip['name']) |
| self.assertEqual(self.vip['id'], vip['id']) |
| |
| @test.attr(type='smoke') |
| def test_show_members_associated_with_pool(self): |
| resp, body = self.client.show_pool(self.pool['id']) |
| self.assertEqual('200', resp['status']) |
| members = body['pool']['members'] |
| for member_id in members: |
| resp, body = self.client.show_member(member_id) |
| self.assertEqual('200', resp['status']) |
| self.assertIsNotNone(body['member']['status']) |
| self.assertEqual(member_id, body['member']['id']) |
| self.assertIsNotNone(body['member']['admin_state_up']) |
| |
| @test.attr(type='smoke') |
| def test_update_pool_related_to_member(self): |
| # Create new pool |
| resp, body = self.client.create_pool( |
| name=data_utils.rand_name("pool-"), |
| lb_method='ROUND_ROBIN', |
| protocol='HTTP', |
| subnet_id=self.subnet['id']) |
| self.assertEqual('201', resp['status']) |
| new_pool = body['pool'] |
| self.addCleanup(self.client.delete_pool, new_pool['id']) |
| # Update member with new pool's id |
| resp, body = self.client.update_member(self.member['id'], |
| pool_id=new_pool['id']) |
| self.assertEqual('200', resp['status']) |
| # Confirm with show that pool_id change |
| resp, 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 |
| resp, body = self.client.update_member(self.member['id'], |
| pool_id=self.pool['id']) |
| self.assertEqual('200', resp['status']) |
| |
| @test.attr(type='smoke') |
| def test_update_member_weight(self): |
| resp, _ = self.client.update_member(self.member['id'], |
| weight=2) |
| self.assertEqual('200', resp['status']) |
| resp, body = self.client.show_member(self.member['id']) |
| self.assertEqual('200', resp['status']) |
| member = body['member'] |
| self.assertEqual(2, member['weight']) |
| |
| |
| class LoadBalancerTestXML(LoadBalancerTestJSON): |
| _interface = 'xml' |