You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
networking-l2gw/networking_l2gw/tests/unit/db/test_l2gw_db.py

419 lines
19 KiB
Python

# Copyright 2015 OpenStack Foundation
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# 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.
import mock
from neutron.callbacks import events
from neutron.callbacks import resources
from neutron import context
from neutron import manager
from neutron.tests.unit import testlib_api
from networking_l2gw.db.l2gateway import l2gateway_db
from networking_l2gw.services.l2gateway.common import constants
from networking_l2gw.services.l2gateway.common import l2gw_validators
from networking_l2gw.services.l2gateway import exceptions
from neutron_lib import exceptions as exc
from oslo_log import log as logging
from oslo_utils import importutils
from oslo_utils import uuidutils
DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2'
LOG = logging.getLogger(__name__)
_uuid = uuidutils.generate_uuid
class L2GWTestCase(testlib_api.SqlTestCase):
"""Unit test for l2 Gateway DB support."""
def setUp(self):
super(L2GWTestCase, self).setUp()
self.ctx = context.get_admin_context()
self.mixin = l2gateway_db.L2GatewayMixin()
self.gw_resource = constants.L2_GATEWAYS
self.con_resource = constants.CONNECTION_RESOURCE_NAME
self.plugin = importutils.import_object(DB_PLUGIN_KLASS)
def _create_l2gateway(self, l2gateway):
"""Create l2gateway helper method."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.create_l2_gateway(self.ctx, l2gateway)
def _get_l2_gateway_data(self, name, device_name):
"""Get l2 gateway data helper method."""
data = {"l2_gateway": {"name": name,
"devices":
[{"interfaces": [{"name": "port1",
"segmentation_id": ["111"]}],
"device_name": device_name}]}}
return data
def _get_l2_gateway_data_with_multiple_segid(self, name, device_name):
"""Get l2 gateway data helper method for multiple seg id."""
data = {"l2_gateway": {"name": name,
"devices":
[{"interfaces": [{"name": "port1",
"segmentation_id": ["111",
"123"]}],
"device_name": device_name}]}}
return data
def _get_l2_gateway_multiple_interface_data(self, name, device_name):
"""Get l2 gateway data helper method with multiple interface data."""
data = {"l2_gateway": {"name": name,
"devices":
[{"interfaces": [{"name": "port1",
"segmentation_id": ["4076"]},
{"name": "port1",
"segmentation_id": ["4074"]}],
"device_name": device_name}]}}
return data
def _get_l2_gw_multiple_interface_partial_seg_id_data(self, name,
device_name):
"""Get l2 gateway data helper method with partial seg id."""
data = {"l2_gateway": {"name": name,
"devices":
[{"interfaces": [{"name": "port1",
"segmentation_id": ["4076"]},
{"name": "port1"}],
"device_name": device_name}]}}
return data
def _get_l2_gw_invalid_seg_id_data(self, name,
device_name):
"""Get l2 gateway data helper method with invalid seg id."""
data = {"interfaces": [{"name": "port1",
"segmentation_id": ["test"]}],
"device_name": device_name}
return [data]
def _get_nw_data(self):
return {'network': {'id': 'fake-id',
'name': 'net1',
'admin_state_up': True,
'tenant_id': 'test-tenant',
'shared': False}}
def _get_l2_gateway_data_without_seg_id(self, name, device_name):
"""Get l2 gateway data helper method."""
data = {"l2_gateway": {"name": name,
"devices":
[{"interfaces": [{"name": "port1"}],
"device_name": device_name}]}}
return data
def test_l2_gateway_get(self):
"""Test l2 gateway get."""
name = "l2gw_1"
device_name = "device1"
data = self._get_l2_gateway_data(name, device_name)
result = self._create_l2gateway(data)
get_result = self._get_l2_gateway(result['id'])
self.assertEqual(name, get_result['name'])
def test_l2_gateway_get_invalid_id_failure(self):
"""Test l2 gateway get for an invalid L2 gateway UUID."""
# Generate a random UUID and try to retrieve a L2 gateway
# using that UUID.
self.assertRaises(exceptions.L2GatewayNotFound,
self._get_l2_gateway, _uuid())
def test_l2_gateway_create(self):
"""Test l2 gateway create."""
name = "l2gw_1"
device_name = "device1"
data = self._get_l2_gateway_data(name, device_name)
result = self._create_l2gateway(data)
self.assertEqual(result['name'], name)
def _get_l2_gateway(self, l2gw_id):
with self.ctx.session.begin(subtransactions=True):
return self.mixin.get_l2_gateway(self.ctx, l2gw_id)
def _get_l2_gateways(self):
"""Update l2gateway helper."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.get_l2_gateways(self.ctx)
def test_l2gateway_list(self):
"""Test l2 gateway list."""
name = "l2gw_1"
device_name = "device1"
data = self._get_l2_gateway_data(name, device_name)
self._create_l2gateway(data)
result2 = self._get_l2_gateways()
self.assertIn('id', result2[0])
def test_l2gateway_show(self):
"""Test l2 gateway show."""
name = "l2gw_1"
device_name = "device1"
data = self._get_l2_gateway_data(name, device_name)
gw = self._create_l2gateway(data)
l2gw_id = gw['id']
result = self._get_l2_gateway(l2gw_id)
self.assertEqual(name, result['name'])
def _update_l2_gateway(self, id, l2gateway):
"""Update l2gateway helper."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.update_l2_gateway(self.ctx, id, l2gateway)
def test_l2_gateway_update(self):
"""Test l2 gateway update."""
name_create = "l2gw_1"
name_update = "l2gw_2"
device_name = "device1"
data_l2gw_create = self._get_l2_gateway_data(name_create,
device_name)
gw_org = self._create_l2gateway(data_l2gw_create)
l2gw_id = gw_org['id']
l2_gw_update_dict = self._get_l2_gateway_data(name_update,
device_name)
result = self._update_l2_gateway(l2gw_id, l2_gw_update_dict)
self.assertNotEqual(result['name'], name_create)
def test_l2_gateway_update_without_devices(self):
"""Test l2 gateway update without devices."""
name_create = "l2gw_1"
name_update = "l2gw_updated"
device_name = "device1"
data_l2gw_create = self._get_l2_gateway_data(name_create,
device_name)
gw_org = self._create_l2gateway(data_l2gw_create)
l2gw_id = gw_org['id']
l2_gw_update_dict = {"l2_gateway": {"name": name_update}}
result = self._update_l2_gateway(l2gw_id, l2_gw_update_dict)
self.assertNotEqual(result['name'], name_create)
self.assertEqual(result['name'], name_update)
def _create_l2gateway_connection(self, l2gateway_con):
"""Create L2 gateway connection resource helper method."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.create_l2_gateway_connection(self.ctx,
l2gateway_con)
def _list_l2gateway_connection(self):
"""Create L2 gateway connection resource helper method."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.get_l2_gateway_connections(self.ctx)
def _delete_l2gw_connection_by_l2gw_id(self, l2gw_id):
"""Delete l2 gateway connection."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin._delete_connection_by_l2gw_id(self.ctx, l2gw_id)
def test_get_l2gw_ids_by_interface_switch(self):
"""Test get L2 gateway ids by interface and switch name."""
name = "l2gw_con1"
device_name = "device1"
data_l2gw = self._get_l2_gateway_data(name, device_name)
gw = self._create_l2gateway(data_l2gw)
net_data = self._get_nw_data()
net = self.plugin.create_network(self.ctx, net_data)
l2gw_id = gw['id']
data_con = {self.con_resource: {'l2_gateway_id': l2gw_id,
'network_id': net['id']}}
self._create_l2gateway_connection(data_con)
l2gw_id_list = self.mixin._get_l2gw_ids_by_interface_switch(
self.ctx, 'port1', 'device1')
self.assertEqual(l2gw_id_list[0], l2gw_id)
def test_l2gateway_connection_create_delete_list(self):
"""Test l2 gateway connection create and delete."""
name = "l2gw_con1"
device_name = "device_name1"
data_l2gw = self._get_l2_gateway_data(name, device_name)
gw = self._create_l2gateway(data_l2gw)
net_data = self._get_nw_data()
net = self.plugin.create_network(self.ctx, net_data)
l2gw_id = gw['id']
data_con = {self.con_resource: {'l2_gateway_id': l2gw_id,
'network_id': net['id']}}
gw_con = self._create_l2gateway_connection(data_con)
exp_net_id = gw_con['network_id']
self.assertEqual(net['id'], exp_net_id)
list_con = self._list_l2gateway_connection()
self.assertIn('id', list_con[0])
result = self._delete_l2gw_connection_by_l2gw_id(l2gw_id)
self.assertIsNone(result)
def _validate_l2_gateway_for_delete(self, l2gw_id):
"""Delete l2 gateway helper method."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.validate_l2_gateway_for_delete(self.ctx, l2gw_id)
def _validate_l2_gateway_for_create(self, l2gw):
"""Create l2 gateway helper method."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.validate_l2_gateway_for_create(self.ctx, l2gw)
def _validate_l2_gateway_for_update(self, l2gw_id, l2gw):
"""Update l2 gateway helper method."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.validate_l2_gateway_for_update(self.ctx,
l2gw_id, l2gw)
def test_l2gateway_con_create_and_delete_in_use_without_seg_id(self):
"""Test l2 gateway connection create without seg id when use."""
name = "l2gw_con2"
device_name = "device_name2"
data_l2gw = self._get_l2_gateway_data(name,
device_name)
gw = self._create_l2gateway(data_l2gw)
net_data = self._get_nw_data()
net = self.plugin.create_network(self.ctx, net_data)
l2gw_id = gw['id']
data_con = {self.con_resource: {'l2_gateway_id': l2gw_id,
'network_id': net['id']}}
self._create_l2gateway_connection(data_con)
self.assertRaises(exceptions.L2GatewayInUse,
self._validate_l2_gateway_for_delete, l2gw_id)
def _delete_l2gateway(self, l2gw_id):
"""Delete l2 gateway helper method."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.delete_l2_gateway(self.ctx,
l2gw_id)
def test_l2gateway_delete(self):
"""Test l2 gateway delete."""
data_l2gw = self._get_l2_gateway_data("gateway_delete",
"device_name")
gw_actual = self._create_l2gateway(data_l2gw)
l2gw_id = gw_actual['id']
result = self._delete_l2gateway(l2gw_id)
self.assertIsNone(result)
def _delete_l2gw_connection(self, con_id):
"""Delete l2 gateway connection."""
with self.ctx.session.begin(subtransactions=True):
return self.mixin.delete_l2_gateway_connection(self.ctx, con_id)
def test_l2_gateway_create_with_mul_interfaces(self):
"""Test l2 gateway create with multiple interfaces all seg id."""
name = "l2gw_1"
device_name = "device1"
data = self._get_l2_gateway_multiple_interface_data(name, device_name)
result = self._create_l2gateway(data)
self.assertEqual(result['name'], name)
def test_l2_gateway_create_with_mul_interfaces_inconsistent_seg_id(self):
"""Test l2 gateway create with multiple interfaces."""
name = "l2gw_1"
dev_name = "device1"
data = self._get_l2_gw_multiple_interface_partial_seg_id_data(name,
dev_name)
self.assertRaises(exceptions.L2GatewaySegmentationRequired,
self._validate_l2_gateway_for_create, data)
def test_l2_gateway_create_with_invalid_seg_id(self):
"""Test l2 gateway create with invalid seg-id."""
name = "l2gw_1"
dev_name = "device1"
data = self._get_l2_gw_invalid_seg_id_data(name, dev_name)
self.assertRaises(exc.InvalidInput,
l2gw_validators.validate_gwdevice_list, data)
def test_l2_gateway_create_with_multiple_segid(self):
"""Test l2 gateway create with multiple seg id."""
name = "l2gw_1"
device_name = "device1"
data = self._get_l2_gateway_data_with_multiple_segid(name, device_name)
result = self._create_l2gateway(data)
self.assertEqual(result['name'], name)
def test_l2_gateway_update_invalid_device_name(self):
"""Test l2 gateway update with invalid device name."""
name_create = "l2gw_1"
device_name = "device1"
invalid_device_name = "invalid_device"
data_l2gw_create = self._get_l2_gateway_data(name_create,
device_name)
data_l2gw_update = self._get_l2_gateway_data(name_create,
invalid_device_name)
gw_org = self._create_l2gateway(data_l2gw_create)
l2gw_id = gw_org['id']
self.assertRaises(exceptions.L2GatewayDeviceNotFound,
self._validate_l2_gateway_for_update, l2gw_id,
data_l2gw_update)
def test_l2gw_callback_update_port(self):
service_plugins = {constants.L2GW: mock.Mock()}
fake_context = mock.Mock()
fake_port = mock.Mock()
fake_kwargs = {'context': fake_context,
'port': fake_port}
with mock.patch.object(manager.NeutronManager,
'get_service_plugins',
return_value=service_plugins):
l2gateway_db.l2gw_callback(resources.PORT,
events.AFTER_UPDATE,
mock.Mock(),
**fake_kwargs)
self.assertTrue(service_plugins[constants.L2GW].
add_port_mac.called)
def test_l2gw_callback_delete_port(self):
service_plugins = {constants.L2GW: mock.Mock()}
fake_context = mock.Mock()
fake_port = mock.Mock()
fake_kwargs = {'context': fake_context,
'port': fake_port}
with mock.patch.object(manager.NeutronManager,
'get_service_plugins',
return_value=service_plugins):
l2gateway_db.l2gw_callback(resources.PORT,
events.AFTER_DELETE,
mock.Mock(),
**fake_kwargs)
self.assertTrue(service_plugins[constants.L2GW].
delete_port_mac.called)
def test_l2_gateway_create_output_aligned_with_input(self):
"""Test l2 gateway create output that is aligned with input dict."""
name = "l2gw_1"
device_name = "device1"
data = self._get_l2_gateway_data_with_multiple_segid(name, device_name)
result = self._create_l2gateway(data)
gw_input = data['l2_gateway']
devices_input = gw_input['devices']
devices_output = result['devices']
input_seg_list = devices_input[0]['interfaces'][0]['segmentation_id']
output_seg_list = devices_output[0]['interfaces'][0]['segmentation_id']
self.assertEqual(len(input_seg_list), len(output_seg_list))
def test_l2gateway_show_update_delete_invalid_id(self):
"""Test l2 gateway show, update and delete with invalid id."""
name = "l2gw_1"
name_update = "l2gw_2"
device_name = "device1"
invalid_l2gw_id = "invalid_id"
data_l2gw_create = self._get_l2_gateway_data(name, device_name)
data_l2gw_update = self._get_l2_gateway_data(name_update, device_name)
self._create_l2gateway(data_l2gw_create)
self.assertRaises(exceptions.L2GatewayNotFound,
self._get_l2_gateway, invalid_l2gw_id)
self.assertRaises(exceptions.L2GatewayNotFound,
self._validate_l2_gateway_for_update,
invalid_l2gw_id, data_l2gw_update)
self.assertRaises(exceptions.L2GatewayNotFound,
self._validate_l2_gateway_for_delete,
invalid_l2gw_id)