nova-net: Migrate 'test_floating_ips' functional tests

This is probably the most involved of all the changes and requires a
significant expansion of the NeutronFixture to mock floating IP
interactions. All the API samples were based off responses pulled from a
DevStack configuration using openstackclient and old versions of the
novaclient (where the 'floating-ip-*' commands were still present) in
debug mode.

Change-Id: Ib2f10a51bebd10cc69b78427b485aeac19f59141
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
Stephen Finucane 2019-09-21 17:33:37 +01:00
parent ce84c7d014
commit 52cc4bfa0a
10 changed files with 186 additions and 67 deletions

View File

@ -1,3 +1,3 @@
{ {
"pool": "nova" "pool": "public"
} }

View File

@ -1,9 +1,9 @@
{ {
"floating_ip": { "floating_ip": {
"fixed_ip": null, "fixed_ip": null,
"id": 1, "id": "8baeddb4-45e2-4c36-8cb7-d79439a5f67c",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.1", "ip": "172.24.4.17",
"pool": "nova" "pool": "public"
} }
} }

View File

@ -1,9 +1,9 @@
{ {
"floating_ip": { "floating_ip": {
"fixed_ip": null, "fixed_ip": null,
"id": 1, "id": "8baeddb4-45e2-4c36-8cb7-d79439a5f67c",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.1", "ip": "172.24.4.17",
"pool": "nova" "pool": "public"
} }
} }

View File

@ -1,3 +1,3 @@
{ {
"floating_ips": [] "floating_ips": []
} }

View File

@ -2,17 +2,17 @@
"floating_ips": [ "floating_ips": [
{ {
"fixed_ip": null, "fixed_ip": null,
"id": 1, "id": "8baeddb4-45e2-4c36-8cb7-d79439a5f67c",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.1", "ip": "172.24.4.17",
"pool": "nova" "pool": "public"
}, },
{ {
"fixed_ip": null, "fixed_ip": null,
"id": 2, "id": "05ef7490-745a-4af9-98e5-610dc97493c4",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.2", "ip": "172.24.4.78",
"pool": "nova" "pool": "public"
} }
] ]
} }

View File

@ -1,9 +1,9 @@
{ {
"floating_ip": { "floating_ip": {
"fixed_ip": null, "fixed_ip": null,
"id": 1, "id": "8baeddb4-45e2-4c36-8cb7-d79439a5f67c",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.1", "ip": "172.24.4.17",
"pool": "nova" "pool": "public"
} }
} }

View File

@ -1,9 +1,9 @@
{ {
"floating_ip": { "floating_ip": {
"fixed_ip": null, "fixed_ip": null,
"id": 1, "id": "8baeddb4-45e2-4c36-8cb7-d79439a5f67c",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.1", "ip": "172.24.4.17",
"pool": "nova" "pool": "public"
} }
} }

View File

@ -2,17 +2,17 @@
"floating_ips": [ "floating_ips": [
{ {
"fixed_ip": null, "fixed_ip": null,
"id": 1, "id": "8baeddb4-45e2-4c36-8cb7-d79439a5f67c",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.1", "ip": "172.24.4.17",
"pool": "nova" "pool": "public"
}, },
{ {
"fixed_ip": null, "fixed_ip": null,
"id": 2, "id": "05ef7490-745a-4af9-98e5-610dc97493c4",
"instance_id": null, "instance_id": null,
"ip": "10.10.10.2", "ip": "172.24.4.78",
"pool": "nova" "pool": "public"
} }
] ]
} }

View File

@ -12,47 +12,166 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy
import nova.conf import nova.conf
from nova import context from nova.tests import fixtures
from nova.tests.functional.api_sample_tests import api_sample_base from nova.tests.functional.api_sample_tests import api_sample_base
CONF = nova.conf.CONF CONF = nova.conf.CONF
# TODO(stephenfin): Merge this back into the main class. We have to be careful
# with how we do this since if we register two networks we'll have ambiguous
# networks breaking auto-allocation
class NeutronFixture(fixtures.NeutronFixture):
network_1 = {
'id': fixtures.NeutronFixture.network_1['id'],
'name': 'public',
'description': '',
'status': 'ACTIVE',
'subnets': [
# NOTE(stephenfin): We set this below
],
'admin_state_up': True,
'tenant_id': fixtures.NeutronFixture.tenant_id,
'project_id': fixtures.NeutronFixture.tenant_id,
'shared': False,
'mtu': 1500,
'router:external': True,
'availability_zone_hints': [],
'availability_zones': [
'nova'
],
'port_security_enabled': True,
'ipv4_address_scope': None,
'ipv6_address_scope': None,
'is_default': True,
}
subnet_1 = {
'id': '6b0b19d2-22b8-45f9-bf32-06d0b89f2d47',
'name': 'public-subnet',
'description': '',
'ip_version': 4,
'ipv6_address_mode': None,
'ipv6_ra_mode': None,
'enable_dhcp': False,
'network_id': network_1['id'],
'tenant_id': fixtures.NeutronFixture.tenant_id,
'project_id': fixtures.NeutronFixture.tenant_id,
'dns_nameservers': [],
'gateway_ip': '172.24.4.1',
'allocation_pools': [
{
'start': '172.24.4.2',
'end': '172.24.4.254'
}
],
'host_routes': [],
'cidr': '172.24.4.0/24',
}
subnet_2 = {
'id': '503505c5-0dd2-4756-b355-4056aa0b6338',
'name': 'ipv6-public-subnet',
'description': '',
'ip_version': 6,
'ipv6_address_mode': None,
'ipv6_ra_mode': None,
'enable_dhcp': False,
'network_id': network_1['id'],
'tenant_id': fixtures.NeutronFixture.tenant_id,
'project_id': fixtures.NeutronFixture.tenant_id,
'dns_nameservers': [],
'gateway_ip': '2001:db8::2',
'allocation_pools': [
{'start': '2001:db8::1', 'end': '2001:db8::1'},
{'start': '2001:db8::3', 'end': '2001:db8::ffff:ffff:ffff:ffff'},
],
'host_routes': [],
'cidr': '2001:db8::/64',
}
network_1['subnets'] = [subnet_1['id'], subnet_2['id']]
floatingip_1 = {
'id': '8baeddb4-45e2-4c36-8cb7-d79439a5f67c',
'description': '',
'status': 'DOWN',
'floating_ip_address': '172.24.4.17',
'fixed_ip_address': None,
'router_id': None,
'tenant_id': fixtures.NeutronFixture.tenant_id,
'project_id': fixtures.NeutronFixture.tenant_id,
'floating_network_id': network_1['id'],
'port_details': None,
'port_id': None,
}
floatingip_2 = {
'id': '05ef7490-745a-4af9-98e5-610dc97493c4',
'description': '',
'status': 'DOWN',
'floating_ip_address': '172.24.4.78',
'fixed_ip_address': None,
'router_id': None,
'tenant_id': fixtures.NeutronFixture.tenant_id,
'project_id': fixtures.NeutronFixture.tenant_id,
'floating_network_id': network_1['id'],
'port_details': None,
'port_id': None,
}
def __init__(self, test):
super(NeutronFixture, self).__init__(test)
self._ports = {}
self._networks = {
self.network_1['id']: copy.deepcopy(self.network_1),
}
self._floatingips = {}
self._subnets = {
self.subnet_1['id']: copy.deepcopy(self.subnet_1),
self.subnet_2['id']: copy.deepcopy(self.subnet_2),
}
def create_floatingip(self, body=None):
for floatingip in [self.floatingip_1, self.floatingip_2]:
if floatingip['id'] not in self._floatingips:
self._floatingips[floatingip['id']] = copy.deepcopy(floatingip)
break
else:
# we can extend this later, if necessary
raise Exception('We only support adding a max of two floating IPs')
return {'floatingip': floatingip}
def delete_floatingip(self, floatingip):
if floatingip not in self._floatingips:
raise Exception('This floating IP has not been added yet')
del self._floatingips[floatingip]
def show_floatingip(self, floatingip, **_params):
if floatingip not in self._floatingips:
raise Exception('This floating IP has not been added yet')
return {'floatingip': self._floatingips[floatingip]}
def list_floatingips(self, retrieve_all=True, **_params):
return {'floatingips': copy.deepcopy(list(self._floatingips.values()))}
class FloatingIpsTest(api_sample_base.ApiSampleTestBaseV21): class FloatingIpsTest(api_sample_base.ApiSampleTestBaseV21):
USE_NEUTRON = False
sample_dir = "os-floating-ips" sample_dir = "os-floating-ips"
def setUp(self): def setUp(self):
super(FloatingIpsTest, self).setUp() super(FloatingIpsTest, self).setUp()
pool = CONF.default_floating_pool
interface = CONF.public_interface
self.ip_pool = [ # we use a custom NeutronFixture that mocks out floating IP stuff
{ self.neutron = self.useFixture(NeutronFixture(self))
'address': "10.10.10.1",
'pool': pool,
'interface': interface
},
{
'address': "10.10.10.2",
'pool': pool,
'interface': interface
},
{
'address': "10.10.10.3",
'pool': pool,
'interface': interface
},
]
self.compute.db.floating_ip_bulk_create(
context.get_admin_context(), self.ip_pool)
def tearDown(self): # we also use a more useful default floating pool value
self.compute.db.floating_ip_bulk_destroy( self.flags(default_floating_pool='public', group='neutron')
context.get_admin_context(), self.ip_pool)
super(FloatingIpsTest, self).tearDown()
def test_floating_ips_list_empty(self): def test_floating_ips_list_empty(self):
response = self._do_get('os-floating-ips') response = self._do_get('os-floating-ips')
@ -76,18 +195,17 @@ class FloatingIpsTest(api_sample_base.ApiSampleTestBaseV21):
def test_floating_ips_create(self): def test_floating_ips_create(self):
response = self._do_post('os-floating-ips', response = self._do_post('os-floating-ips',
'floating-ips-create-req', 'floating-ips-create-req',
{"pool": CONF.default_floating_pool}) {'pool': 'public'})
self._verify_response('floating-ips-create-resp', {}, response, 200) self._verify_response('floating-ips-create-resp', {}, response, 200)
return response
def test_floating_ips_get(self): def test_floating_ips_get(self):
self.test_floating_ips_create() floatingip = self.test_floating_ips_create().json()['floating_ip']
# NOTE(sdague): the first floating ip will always have 1 as an id, response = self._do_get('os-floating-ips/%s' % floatingip['id'])
# but it would be better if we could get this from the create
response = self._do_get('os-floating-ips/%d' % 1)
self._verify_response('floating-ips-get-resp', {}, response, 200) self._verify_response('floating-ips-get-resp', {}, response, 200)
def test_floating_ips_delete(self): def test_floating_ips_delete(self):
self.test_floating_ips_create() floatingip = self.test_floating_ips_create().json()['floating_ip']
response = self._do_delete('os-floating-ips/%d' % 1) response = self._do_delete('os-floating-ips/%s' % floatingip['id'])
self.assertEqual(202, response.status_code) self.assertEqual(202, response.status_code)
self.assertEqual("", response.text) self.assertEqual("", response.text)

View File

@ -98,6 +98,9 @@ class _IntegratedTestBase(test.TestCase):
placement = self.useFixture(func_fixtures.PlacementFixture()) placement = self.useFixture(func_fixtures.PlacementFixture())
self.placement_api = placement.api self.placement_api = placement.api
if self.USE_NEUTRON:
self.neutron = self.useFixture(nova_fixtures.NeutronFixture(self))
self._setup_services() self._setup_services()
self.addCleanup(nova.tests.unit.image.fake.FakeImageService_reset) self.addCleanup(nova.tests.unit.image.fake.FakeImageService_reset)
@ -116,9 +119,7 @@ class _IntegratedTestBase(test.TestCase):
self.flags(transport_url=self.cell_mappings['cell1'].transport_url) self.flags(transport_url=self.cell_mappings['cell1'].transport_url)
self.conductor = self.start_service('conductor') self.conductor = self.start_service('conductor')
if self.USE_NEUTRON: if not self.USE_NEUTRON:
self.neutron = self.useFixture(nova_fixtures.NeutronFixture(self))
else:
self.network = self.start_service('network', self.network = self.start_service('network',
manager=CONF.network_manager) manager=CONF.network_manager)
self.scheduler = self._setup_scheduler_service() self.scheduler = self._setup_scheduler_service()