From 29e4bb0fbe463c1726cc25022c038b520ec2ddb1 Mon Sep 17 00:00:00 2001 From: Yuuichi Fujioka Date: Wed, 10 Jun 2015 17:18:12 +0900 Subject: [PATCH] Introduce an API test for specified floating ip address The test case checks whether admin can set floating IP address when creates a floating IP. Implements: blueprint allow-specific-floating-ip-address[1] [1] https://blueprints.launchpad.net/neutron/+spec/allow-specific-floating-ip-address Change-Id: I036da37402b826c1a73698e0ae21894a3ce676ab --- .../admin/test_floating_ips_admin_actions.py | 18 +++++++++ neutron/tests/api/base.py | 38 +++++++++++++++++++ neutron/tests/tempest/config.py | 4 ++ 3 files changed, 60 insertions(+) diff --git a/neutron/tests/api/admin/test_floating_ips_admin_actions.py b/neutron/tests/api/admin/test_floating_ips_admin_actions.py index 39ddbe2a288..e87d46ede54 100644 --- a/neutron/tests/api/admin/test_floating_ips_admin_actions.py +++ b/neutron/tests/api/admin/test_floating_ips_admin_actions.py @@ -12,6 +12,7 @@ # 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 testtools from tempest_lib.common.utils import data_utils from tempest_lib import exceptions as lib_exc @@ -132,3 +133,20 @@ class FloatingIPAdminTestJSON(base.BaseAdminNetworkTest): self.assertRaises(lib_exc.BadRequest, self.admin_client.update_floatingip, floating_ip['id'], port_id=port['port']['id']) + + @testtools.skipUnless( + CONF.network_feature_enabled.specify_floating_ip_address_available, + "Feature for specifying floating IP address is disabled") + @test.attr(type='smoke') + @test.idempotent_id('332a8ae4-402e-4b98-bb6f-532e5a87b8e0') + def test_create_floatingip_with_specified_ip_address(self): + fip = self.get_unused_ip(self.ext_net_id) + body = self.admin_client.create_floatingip( + floating_network_id=self.ext_net_id, + floating_ip_address=fip) + created_floating_ip = body['floatingip'] + self.addCleanup(self.admin_client.delete_floatingip, + created_floating_ip['id']) + self.assertIsNotNone(created_floating_ip['id']) + self.assertIsNotNone(created_floating_ip['tenant_id']) + self.assertEqual(created_floating_ip['floating_ip_address'], fip) diff --git a/neutron/tests/api/base.py b/neutron/tests/api/base.py index 0f31a9a2a84..131ba7b00ca 100644 --- a/neutron/tests/api/base.py +++ b/neutron/tests/api/base.py @@ -545,3 +545,41 @@ class BaseAdminNetworkTest(BaseNetworkTest): service_profile = body['service_profile'] cls.service_profiles.append(service_profile) return service_profile + + @classmethod + def get_unused_ip(cls, net_id): + """Get an unused ip address in a allocaion pool of net""" + body = cls.admin_client.list_ports(network_id=net_id) + ports = body['ports'] + used_ips = [] + for port in ports: + used_ips.extend( + [fixed_ip['ip_address'] for fixed_ip in port['fixed_ips']]) + body = cls.admin_client.list_subnets(network_id=net_id) + subnets = body['subnets'] + + for subnet in subnets: + cidr = subnet['cidr'] + allocation_pools = subnet['allocation_pools'] + iterators = [] + if allocation_pools: + for allocation_pool in allocation_pools: + iterators.append(netaddr.iter_iprange( + allocation_pool['start'], allocation_pool['end'])) + else: + net = netaddr.IPNetwork(cidr) + + def _iterip(): + for ip in net: + if ip not in (net.network, net.broadcast): + yield ip + iterators.append(_iterip) + + for iterator in iterators: + for ip in iterator: + if str(ip) not in used_ips: + return str(ip) + + message = ( + "net(%s) has no usable IP address in allocation pools" % net_id) + raise exceptions.InvalidConfiguration(message) diff --git a/neutron/tests/tempest/config.py b/neutron/tests/tempest/config.py index 200b24736f0..4b35d926e09 100644 --- a/neutron/tests/tempest/config.py +++ b/neutron/tests/tempest/config.py @@ -480,6 +480,10 @@ NetworkFeaturesGroup = [ "the extended IPv6 attributes ipv6_ra_mode " "and ipv6_address_mode" ), + cfg.BoolOpt('specify_floating_ip_address_available', + default=True, + help='Allow passing an IP Address of the floating ip when ' + 'creating the floating ip'), ] messaging_group = cfg.OptGroup(name='messaging',