Add tests for L3 conntrack helper
API tests for L3 Conntrack Helper plugin. Related-Bug: #1823633 Depends-On: https://review.opendev.org/670837 Change-Id: Ie085100f508f7a1cdb0fd4efbcffa1e2b485fbba
This commit is contained in:
parent
3a4fc7923e
commit
c9782faa9a
|
@ -27,6 +27,7 @@
|
||||||
- dns-integration
|
- dns-integration
|
||||||
- empty-string-filtering
|
- empty-string-filtering
|
||||||
- expose-port-forwarding-in-fip
|
- expose-port-forwarding-in-fip
|
||||||
|
- expose-l3-conntrack-helper
|
||||||
- ext-gw-mode
|
- ext-gw-mode
|
||||||
- external-net
|
- external-net
|
||||||
- extra_dhcp_opt
|
- extra_dhcp_opt
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
- floating-ip-port-forwarding
|
- floating-ip-port-forwarding
|
||||||
- floatingip-pools
|
- floatingip-pools
|
||||||
- ip-substring-filtering
|
- ip-substring-filtering
|
||||||
|
- l3-conntrack-helper
|
||||||
- l3-flavors
|
- l3-flavors
|
||||||
- l3-ha
|
- l3-ha
|
||||||
- l3_agent_scheduler
|
- l3_agent_scheduler
|
||||||
|
@ -100,6 +102,7 @@
|
||||||
neutron-uplink-status-propagation: true
|
neutron-uplink-status-propagation: true
|
||||||
neutron-network-segment-range: true
|
neutron-network-segment-range: true
|
||||||
neutron-port-forwarding: true
|
neutron-port-forwarding: true
|
||||||
|
neutron-conntrack-helper: true
|
||||||
devstack_local_conf:
|
devstack_local_conf:
|
||||||
post-config:
|
post-config:
|
||||||
$NEUTRON_CONF:
|
$NEUTRON_CONF:
|
||||||
|
|
|
@ -137,6 +137,7 @@ class BaseNetworkTest(test.BaseTestCase):
|
||||||
cls.keypairs = []
|
cls.keypairs = []
|
||||||
cls.trunks = []
|
cls.trunks = []
|
||||||
cls.network_segment_ranges = []
|
cls.network_segment_ranges = []
|
||||||
|
cls.conntrack_helpers = []
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def resource_cleanup(cls):
|
def resource_cleanup(cls):
|
||||||
|
@ -153,6 +154,10 @@ class BaseNetworkTest(test.BaseTestCase):
|
||||||
for floating_ip in cls.floating_ips:
|
for floating_ip in cls.floating_ips:
|
||||||
cls._try_delete_resource(cls.delete_floatingip, floating_ip)
|
cls._try_delete_resource(cls.delete_floatingip, floating_ip)
|
||||||
|
|
||||||
|
# Clean up conntrack helpers
|
||||||
|
for cth in cls.conntrack_helpers:
|
||||||
|
cls._try_delete_resource(cls.delete_conntrack_helper, cth)
|
||||||
|
|
||||||
# Clean up routers
|
# Clean up routers
|
||||||
for router in cls.routers:
|
for router in cls.routers:
|
||||||
cls._try_delete_resource(cls.delete_router,
|
cls._try_delete_resource(cls.delete_router,
|
||||||
|
@ -960,6 +965,55 @@ class BaseNetworkTest(test.BaseTestCase):
|
||||||
|
|
||||||
client.delete_trunk(trunk['id'])
|
client.delete_trunk(trunk['id'])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_conntrack_helper(cls, router_id, helper, protocol, port,
|
||||||
|
client=None):
|
||||||
|
"""Create a conntrack helper
|
||||||
|
|
||||||
|
Create a conntrack helper and schedule it for later deletion. If a
|
||||||
|
client is passed, then it is used for deleteing the CTH too.
|
||||||
|
|
||||||
|
:param router_id: The ID of the Neutron router associated to the
|
||||||
|
conntrack helper.
|
||||||
|
|
||||||
|
:param helper: The conntrack helper module alias
|
||||||
|
|
||||||
|
:param protocol: The conntrack helper IP protocol used in the conntrack
|
||||||
|
helper.
|
||||||
|
|
||||||
|
:param port: The conntrack helper IP protocol port number for the
|
||||||
|
conntrack helper.
|
||||||
|
|
||||||
|
:param client: network client to be used for creating and cleaning up
|
||||||
|
the conntrack helper.
|
||||||
|
"""
|
||||||
|
|
||||||
|
client = client or cls.client
|
||||||
|
|
||||||
|
cth = client.create_conntrack_helper(router_id, helper, protocol,
|
||||||
|
port)['conntrack_helper']
|
||||||
|
|
||||||
|
# save ID of router associated with conntrack helper for final cleanup
|
||||||
|
cth['router_id'] = router_id
|
||||||
|
|
||||||
|
# save client to be used later in cls.delete_conntrack_helper for final
|
||||||
|
# cleanup
|
||||||
|
cth['client'] = client
|
||||||
|
cls.conntrack_helpers.append(cth)
|
||||||
|
return cth
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def delete_conntrack_helper(cls, cth, client=None):
|
||||||
|
"""Delete conntrack helper
|
||||||
|
|
||||||
|
:param client: Client to be used
|
||||||
|
If client is not given it will use the client used to create the
|
||||||
|
conntrack helper, or cls.client if unknown.
|
||||||
|
"""
|
||||||
|
|
||||||
|
client = client or cth.get('client') or cls.client
|
||||||
|
client.delete_conntrack_helper(cth['router_id'], cth['id'])
|
||||||
|
|
||||||
|
|
||||||
class BaseAdminNetworkTest(BaseNetworkTest):
|
class BaseAdminNetworkTest(BaseNetworkTest):
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
# Copyright (c) 2019 Red Hat, Inc.
|
||||||
|
# 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.common import utils
|
||||||
|
from tempest.lib.common.utils import data_utils
|
||||||
|
from tempest.lib import decorators
|
||||||
|
from tempest.lib import exceptions
|
||||||
|
|
||||||
|
from neutron_tempest_plugin.api import base
|
||||||
|
from neutron_tempest_plugin import config
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
|
class ConntrackHelperTestJSON(base.BaseNetworkTest):
|
||||||
|
|
||||||
|
required_extensions = ['router', 'l3-conntrack-helper',
|
||||||
|
'expose-l3-conntrack-helper']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def resource_setup(cls):
|
||||||
|
super(ConntrackHelperTestJSON, cls).resource_setup()
|
||||||
|
cls.ext_net_id = CONF.network.public_network_id
|
||||||
|
|
||||||
|
# Create network, subnet
|
||||||
|
cls.network = cls.create_network()
|
||||||
|
cls.subnet = cls.create_subnet(cls.network)
|
||||||
|
|
||||||
|
@decorators.idempotent_id('6361c80e-902d-4c2a-88b4-ea8066507eee')
|
||||||
|
def test_create_list_update_show_delete_conntrack_helper(self):
|
||||||
|
# Create a router
|
||||||
|
router = self.create_router(data_utils.rand_name('router'),
|
||||||
|
external_network_id=self.ext_net_id)
|
||||||
|
|
||||||
|
# Create conntrack helper
|
||||||
|
created_cth = self.create_conntrack_helper(router['id'], helper='tftp',
|
||||||
|
protocol='udp', port=69)
|
||||||
|
self.assertEqual('tftp', created_cth['helper'])
|
||||||
|
self.assertEqual('udp', created_cth['protocol'])
|
||||||
|
self.assertEqual(69, created_cth['port'])
|
||||||
|
|
||||||
|
# List conntrack helpers
|
||||||
|
conntrack_helpers = self.client.list_conntrack_helpers(
|
||||||
|
router['id'])['conntrack_helpers']
|
||||||
|
self.assertIn(created_cth['id'],
|
||||||
|
{cth['id'] for cth in conntrack_helpers})
|
||||||
|
|
||||||
|
# Update conntrack helper
|
||||||
|
updated_conntrack_helper = self.client.update_conntrack_helper(
|
||||||
|
router['id'], created_cth['id'], port=6969)['conntrack_helper']
|
||||||
|
self.assertEqual(updated_conntrack_helper['port'], 6969)
|
||||||
|
|
||||||
|
# Show conntrack helper
|
||||||
|
conntrack_helper = self.client.get_conntrack_helper(
|
||||||
|
router['id'], created_cth['id'])['conntrack_helper']
|
||||||
|
self.assertEqual('tftp', conntrack_helper['helper'])
|
||||||
|
self.assertEqual('udp', conntrack_helper['protocol'])
|
||||||
|
self.assertEqual(6969, conntrack_helper['port'])
|
||||||
|
|
||||||
|
# Delete conntrack helper
|
||||||
|
self.client.delete_conntrack_helper(router['id'], created_cth['id'])
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.NotFound,
|
||||||
|
self.client.get_conntrack_helper, router['id'], created_cth['id'])
|
||||||
|
|
||||||
|
@decorators.idempotent_id('0a6ae20c-3f66-423e-93c6-cfedd1c93b8d')
|
||||||
|
def test_conntrack_helper_info_in_router_details(self):
|
||||||
|
# Create a router
|
||||||
|
router = self.create_router(data_utils.rand_name('router'),
|
||||||
|
external_network_id=self.ext_net_id)
|
||||||
|
|
||||||
|
# Ensure routerd does not have information about any conntrack helper
|
||||||
|
router = self.client.show_router(router['id'])['router']
|
||||||
|
self.assertEqual(0, len(router['conntrack_helpers']))
|
||||||
|
|
||||||
|
# Now create conntrack helper and ensure it's visible in Router details
|
||||||
|
cth = self.create_conntrack_helper(router['id'], helper='ftp',
|
||||||
|
protocol='tcp', port=21)
|
||||||
|
router = self.client.show_router(router['id'])['router']
|
||||||
|
self.assertEqual(1, len(router['conntrack_helpers']))
|
||||||
|
self.assertEqual('ftp', router['conntrack_helpers'][0]['helper'])
|
||||||
|
self.assertEqual('tcp', router['conntrack_helpers'][0]['protocol'])
|
||||||
|
self.assertEqual(21, router['conntrack_helpers'][0]['port'])
|
||||||
|
|
||||||
|
# Delete conntrack_helper and ensure it's no longer in Router details
|
||||||
|
self.client.delete_conntrack_helper(router['id'], cth['id'])
|
||||||
|
router = self.client.show_router(router['id'])['router']
|
||||||
|
self.assertEqual(0, len(router['conntrack_helpers']))
|
||||||
|
|
||||||
|
@decorators.idempotent_id('134469d9-fb25-4165-adc8-f4747f07caf1')
|
||||||
|
def test_2_conntrack_helpers_to_same_router(self):
|
||||||
|
# Create a router
|
||||||
|
router = self.create_router(data_utils.rand_name('router'),
|
||||||
|
external_network_id=self.ext_net_id)
|
||||||
|
|
||||||
|
cth_data = [{'helper': 'tftp', 'protocol': 'udp', 'port': 60},
|
||||||
|
{'helper': 'ftp', 'protocol': 'tcp', 'port': 21}]
|
||||||
|
created_cths = []
|
||||||
|
for cth in cth_data:
|
||||||
|
created_cth = self.create_conntrack_helper(
|
||||||
|
router_id=router['id'],
|
||||||
|
helper=cth['helper'],
|
||||||
|
protocol=cth['protocol'],
|
||||||
|
port=cth['port'])
|
||||||
|
self.assertEqual(cth['helper'], created_cth['helper'])
|
||||||
|
self.assertEqual(cth['protocol'], created_cth['protocol'])
|
||||||
|
self.assertEqual(cth['port'], created_cth['port'])
|
||||||
|
created_cths.append(created_cth)
|
||||||
|
|
||||||
|
# Check that conntrack helpers are in Router details
|
||||||
|
router = self.client.show_router(router['id'])['router']
|
||||||
|
self.assertEqual(len(cth_data), len(router['conntrack_helpers']))
|
||||||
|
for cth in created_cths:
|
||||||
|
expected_cth = cth.copy()
|
||||||
|
expected_cth.pop('id')
|
||||||
|
expected_cth.pop('client')
|
||||||
|
expected_cth.pop('router_id')
|
||||||
|
self.assertIn(expected_cth, router['conntrack_helpers'])
|
||||||
|
|
||||||
|
# Test list of conntrack helpers
|
||||||
|
conntrack_helpers = self.client.list_conntrack_helpers(
|
||||||
|
router['id'])['conntrack_helpers']
|
||||||
|
self.assertEqual(len(cth_data), len(conntrack_helpers))
|
|
@ -1020,6 +1020,49 @@ class NetworkClientJSON(service_client.RestClient):
|
||||||
self.expected_success(204, resp.status)
|
self.expected_success(204, resp.status)
|
||||||
service_client.ResponseBody(resp, body)
|
service_client.ResponseBody(resp, body)
|
||||||
|
|
||||||
|
def create_conntrack_helper(self, router_id, helper, protocol, port):
|
||||||
|
post_body = {'conntrack_helper': {
|
||||||
|
'helper': helper,
|
||||||
|
'protocol': protocol,
|
||||||
|
'port': port}}
|
||||||
|
body = jsonutils.dumps(post_body)
|
||||||
|
uri = '%s/routers/%s/conntrack_helpers' % (self.uri_prefix, router_id)
|
||||||
|
resp, body = self.post(uri, body)
|
||||||
|
self.expected_success(201, resp.status)
|
||||||
|
body = jsonutils.loads(body)
|
||||||
|
return service_client.ResponseBody(resp, body)
|
||||||
|
|
||||||
|
def get_conntrack_helper(self, router_id, cth_id):
|
||||||
|
uri = '%s/routers/%s/conntrack_helpers/%s' % (self.uri_prefix,
|
||||||
|
router_id, cth_id)
|
||||||
|
get_resp, get_resp_body = self.get(uri)
|
||||||
|
self.expected_success(200, get_resp.status)
|
||||||
|
body = jsonutils.loads(get_resp_body)
|
||||||
|
return service_client.ResponseBody(get_resp, body)
|
||||||
|
|
||||||
|
def list_conntrack_helpers(self, router_id):
|
||||||
|
uri = '%s/routers/%s/conntrack_helpers' % (self.uri_prefix, router_id)
|
||||||
|
resp, body = self.get(uri)
|
||||||
|
self.expected_success(200, resp.status)
|
||||||
|
body = jsonutils.loads(body)
|
||||||
|
return service_client.ResponseBody(resp, body)
|
||||||
|
|
||||||
|
def update_conntrack_helper(self, router_id, cth_id, **kwargs):
|
||||||
|
uri = '%s/routers/%s/conntrack_helpers/%s' % (self.uri_prefix,
|
||||||
|
router_id, cth_id)
|
||||||
|
put_body = jsonutils.dumps({'conntrack_helper': kwargs})
|
||||||
|
put_resp, resp_body = self.put(uri, put_body)
|
||||||
|
self.expected_success(200, put_resp.status)
|
||||||
|
body = jsonutils.loads(resp_body)
|
||||||
|
return service_client.ResponseBody(put_resp, body)
|
||||||
|
|
||||||
|
def delete_conntrack_helper(self, router_id, cth_id):
|
||||||
|
uri = '%s/routers/%s/conntrack_helpers/%s' % (self.uri_prefix,
|
||||||
|
router_id, cth_id)
|
||||||
|
resp, body = self.delete(uri)
|
||||||
|
self.expected_success(204, resp.status)
|
||||||
|
service_client.ResponseBody(resp, body)
|
||||||
|
|
||||||
def create_network_keystone_v3(self, name, project_id, tenant_id=None):
|
def create_network_keystone_v3(self, name, project_id, tenant_id=None):
|
||||||
uri = '%s/networks' % self.uri_prefix
|
uri = '%s/networks' % self.uri_prefix
|
||||||
post_data = {
|
post_data = {
|
||||||
|
|
Loading…
Reference in New Issue