dragonflow/dragonflow/tests/unit/test_mech_driver.py

326 lines
14 KiB
Python

# 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.
"""Unit testing for dragonflow mechanism driver."""
import mock
import six
from neutron.tests.unit.plugins.ml2 import test_plugin
class empty_wrapper(object):
def __init__(self, type):
pass
def __call__(self, f):
@six.wraps(f)
def wrapped_f(*args, **kwargs):
return f(*args, **kwargs)
return wrapped_f
class DFMechanismDriverTestCase(test_plugin.Ml2PluginV2TestCase):
_mechanism_drivers = ['logger', 'df']
def get_additional_service_plugins(self):
p = super(DFMechanismDriverTestCase,
self).get_additional_service_plugins()
p.update({'revision_plugin_name': 'revisions'})
return p
def setUp(self):
mock.patch('dragonflow.db.neutron.lockedobjects_db.wrap_db_lock',
side_effect=empty_wrapper).start()
nbapi_instance = mock.patch('dragonflow.db.api_nb.NbApi').start()
nbapi_instance.get_instance.return_value = mock.MagicMock()
super(DFMechanismDriverTestCase, self).setUp()
mm = self.driver.mechanism_manager
self.mech_driver = mm.mech_drivers['df'].obj
self.mech_driver.post_fork_initialize(None, None, None)
class TestDFMechDriver(DFMechanismDriverTestCase):
def setUp(self):
super(TestDFMechDriver, self).setUp()
self.nb_api = self.mech_driver.nb_api
def _test_create_security_group_revision(self):
s = {'security_group': {'tenant_id': 'some_tenant', 'name': '',
'description': 'des'}}
sg = self.driver.create_security_group(self.context, s)
self.assertGreater(sg['revision_number'], 0)
self.nb_api.create_security_group.assert_called_with(
id=sg['id'], topic=sg['tenant_id'],
name=sg['name'], rules=sg['security_group_rules'],
version=sg['revision_number'])
return sg
def test_create_security_group_revision(self):
self._test_create_security_group_revision()
def test_update_security_group_revision(self):
sg = self._test_create_security_group_revision()
data = {'security_group': {'name': 'updated'}}
new_sg = self.driver.update_security_group(
self.context, sg['id'], data)
self.assertGreater(new_sg['revision_number'], sg['revision_number'])
self.nb_api.update_security_group.assert_called_with(
id=sg['id'], topic=sg['tenant_id'],
name='updated', rules=new_sg['security_group_rules'],
version=new_sg['revision_number'])
def test_create_delete_sg_rule_revision(self):
sg = self._test_create_security_group_revision()
r = {'security_group_rule': {'tenant_id': 'some_tenant',
'port_range_min': 80, 'protocol': 6,
'port_range_max': 90,
'remote_ip_prefix': '0.0.0.0/0',
'ethertype': 'IPv4',
'remote_group_id': None,
'direction': 'ingress',
'security_group_id': sg['id']}}
rule = self.driver.create_security_group_rule(self.context, r)
new_sg = self.driver.get_security_group(self.context, sg['id'])
self.assertGreater(new_sg['revision_number'], sg['revision_number'])
self.nb_api.add_security_group_rules.assert_called_with(
sg['id'], sg['tenant_id'],
sg_rules=[rule], sg_version=new_sg['revision_number'])
self.mech_driver._get_security_group_id_from_security_group_rule = (
mock.Mock(return_value=sg['id']))
self.driver.delete_security_group_rule(self.context, rule['id'])
newer_sg = self.driver.get_security_group(self.context, sg['id'])
self.assertGreater(newer_sg['revision_number'],
new_sg['revision_number'])
self.nb_api.delete_security_group_rule.assert_called_with(
sg['id'], rule['id'], sg['tenant_id'],
sg_version=newer_sg['revision_number'])
def _test_create_network_revision(self):
with self.network() as n:
network = n['network']
self.assertGreater(network['revision_number'], 0)
self.nb_api.create_lswitch.assert_called_with(
id=network['id'], topic=network['tenant_id'],
name=network['name'],
network_type=network['provider:network_type'],
segmentation_id=network['provider:segmentation_id'],
physical_network=network['provider:physical_network'],
router_external=network['router:external'],
mtu=network['mtu'], version=network['revision_number'],
subnets=[],
qos_policy_id=None)
return network
def test_create_network_revision(self):
self._test_create_network_revision()
def test_create_update_delete_subnet_network_revision(self):
network = self._test_create_network_revision()
with self.subnet(network={'network': network}) as s:
subnet = s['subnet']
subnet_id = s['subnet']['id']
new_network = self.driver.get_network(self.context, network['id'])
self.assertGreater(new_network['revision_number'],
network['revision_number'])
self.nb_api.add_subnet.assert_called_with(
subnet_id, network['id'], subnet['tenant_id'], name=subnet['name'],
nw_version=new_network['revision_number'],
enable_dhcp=subnet['enable_dhcp'], cidr=subnet['cidr'],
dhcp_ip=mock.ANY, gateway_ip=subnet['gateway_ip'],
dns_nameservers=subnet['dns_nameservers'],
host_routes=subnet['host_routes'])
data = {'subnet': {'name': 'updated'}}
req = self.new_update_request('subnets', data, subnet_id)
req.get_response(self.api)
network = new_network
new_network = self.driver.get_network(self.context, network['id'])
self.assertGreater(new_network['revision_number'],
network['revision_number'])
self.nb_api.update_subnet.assert_called_with(
subnet_id, network['id'], subnet['tenant_id'], name='updated',
nw_version=new_network['revision_number'],
enable_dhcp=subnet['enable_dhcp'], cidr=subnet['cidr'],
dhcp_ip=mock.ANY, gateway_ip=subnet['gateway_ip'],
dns_nameservers=subnet['dns_nameservers'],
host_routes=subnet['host_routes'])
network = new_network
req = self.new_delete_request('subnets', subnet_id)
req.get_response(self.api)
network = new_network
new_network = self.driver.get_network(self.context, network['id'])
self.assertGreater(new_network['revision_number'],
network['revision_number'])
self.nb_api.delete_subnet.assert_called_with(
subnet_id, network['id'], subnet['tenant_id'],
nw_version=new_network['revision_number'])
def test_create_update_port_allowed_address_pairs(self):
kwargs = {'allowed_address_pairs':
[{"ip_address": "10.1.1.10"},
{"ip_address": "20.1.1.20",
"mac_address": "aa:bb:cc:dd:ee:ff"}]}
with self.subnet(enable_dhcp=False) as subnet:
with self.port(subnet=subnet,
arg_list=('allowed_address_pairs',),
**kwargs) as p:
port = p['port']
self.assertTrue(self.nb_api.create_lport.called)
called_args = self.nb_api.create_lport.call_args_list[0][1]
expected_aap = [{"ip_address": "10.1.1.10",
"mac_address": port['mac_address']},
{"ip_address": "20.1.1.20",
"mac_address": "aa:bb:cc:dd:ee:ff"}]
self.assertItemsEqual(expected_aap,
called_args.get("allowed_address_pairs"))
data = {'port': {'allowed_address_pairs': []}}
req = self.new_update_request(
'ports',
data, port['id'])
req.get_response(self.api)
self.assertTrue(self.nb_api.update_lport.called)
called_args = self.nb_api.update_lport.call_args_list[0][1]
self.assertEqual([], called_args.get("allowed_address_pairs"))
def test_create_update_port_revision(self):
with self.port(name='port', device_owner='fake_owner',
device_id='fake_id') as p:
port = p['port']
self.assertGreater(port['revision_number'], 0)
self.nb_api.create_lport.assert_called_with(
id=port['id'],
lswitch_id=port['network_id'],
topic=port['tenant_id'],
macs=[port['mac_address']], ips=mock.ANY,
subnets=mock.ANY, name=port['name'],
enabled=port['admin_state_up'],
chassis=mock.ANY, tunnel_key=mock.ANY,
version=port['revision_number'],
device_owner=port['device_owner'],
device_id=port['device_id'],
security_groups=mock.ANY,
port_security_enabled=mock.ANY,
remote_vtep=False,
allowed_address_pairs=mock.ANY,
binding_profile=mock.ANY,
binding_vnic_type=mock.ANY,
qos_policy_id=None)
data = {'port': {'name': 'updated'}}
req = self.new_update_request('ports', data, port['id'])
req.get_response(self.api)
prev_version = port['revision_number']
port = self.driver.get_port(self.context, port['id'])
self.assertGreater(port['revision_number'], prev_version)
self.nb_api.update_lport.assert_called_with(
id=port['id'],
topic=port['tenant_id'],
macs=[port['mac_address']], ips=mock.ANY,
subnets=mock.ANY, name=port['name'],
enabled=port['admin_state_up'],
chassis=mock.ANY,
version=port['revision_number'],
device_owner=port['device_owner'],
device_id=port['device_id'],
remote_vtep=False,
security_groups=mock.ANY,
port_security_enabled=mock.ANY,
allowed_address_pairs=mock.ANY,
binding_profile=mock.ANY,
binding_vnic_type=mock.ANY,
qos_policy_id=None)
def test_delete_network(self):
network = self._test_create_network_revision()
req = self.new_delete_request('networks', network['id'])
req.get_response(self.api)
self.nb_api.delete_lswitch.assert_called_with(
id=network['id'], topic=network['tenant_id'])
def test_create_update_remote_port(self):
profile = {"port_key": "remote_port", "host_ip": "20.0.0.2"}
profile_arg = {'binding:profile': profile}
with self.port(arg_list=('binding:profile',),
**profile_arg) as port:
port = port['port']
self.nb_api.create_lport.assert_called_with(
id=port['id'],
lswitch_id=port['network_id'],
topic=port['tenant_id'],
macs=[port['mac_address']], ips=mock.ANY,
subnets=mock.ANY, name=mock.ANY,
enabled=port['admin_state_up'],
chassis="20.0.0.2", tunnel_key=mock.ANY,
version=port['revision_number'],
device_owner=port['device_owner'],
device_id=port['device_id'],
security_groups=mock.ANY,
port_security_enabled=mock.ANY,
qos_policy_id=mock.ANY,
remote_vtep=True,
allowed_address_pairs=mock.ANY,
binding_profile=profile,
binding_vnic_type=mock.ANY)
profile['host_ip'] = "20.0.0.20"
data = {'port': {'binding:profile': profile}}
req = self.new_update_request('ports', data, port['id'])
req.get_response(self.api)
self.nb_api.update_lport.assert_called_with(
id=port['id'],
topic=port['tenant_id'],
macs=[port['mac_address']], ips=mock.ANY,
subnets=mock.ANY, name=mock.ANY,
enabled=port['admin_state_up'],
chassis="20.0.0.20",
version=mock.ANY,
device_owner=port['device_owner'],
device_id=port['device_id'],
qos_policy_id=mock.ANY,
remote_vtep=True,
security_groups=mock.ANY,
port_security_enabled=mock.ANY,
allowed_address_pairs=mock.ANY,
binding_profile=profile,
binding_vnic_type=mock.ANY)
def test_delete_port(self):
with self.port() as p:
port = p['port']
req = self.new_delete_request('ports', port['id'])
req.get_response(self.api)
self.nb_api.delete_lport.assert_called_with(
id=port['id'], topic=port['tenant_id'])
def test_delete_security_group(self):
sg = self._test_create_security_group_revision()
self.driver.delete_security_group(self.context, sg['id'])
self.nb_api.delete_security_group.assert_called_with(
sg['id'], topic=sg['tenant_id'])
class TestDFMechansimDriverAllowedAddressPairs(
test_plugin.TestMl2AllowedAddressPairs,
DFMechanismDriverTestCase):
pass