summaryrefslogtreecommitdiff
path: root/nova/tests/unit/virt/powervm/test_vif.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/tests/unit/virt/powervm/test_vif.py')
-rw-r--r--nova/tests/unit/virt/powervm/test_vif.py327
1 files changed, 0 insertions, 327 deletions
diff --git a/nova/tests/unit/virt/powervm/test_vif.py b/nova/tests/unit/virt/powervm/test_vif.py
deleted file mode 100644
index 985c48abe5..0000000000
--- a/nova/tests/unit/virt/powervm/test_vif.py
+++ /dev/null
@@ -1,327 +0,0 @@
-# Copyright 2017 IBM Corp.
-#
-# 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.
-
-import mock
-from pypowervm import exceptions as pvm_ex
-from pypowervm.wrappers import network as pvm_net
-
-from nova import exception
-from nova.network import model
-from nova import test
-from nova.virt.powervm import vif
-
-
-def cna(mac):
- """Builds a mock Client Network Adapter for unit tests."""
- return mock.Mock(spec=pvm_net.CNA, mac=mac, vswitch_uri='fake_href')
-
-
-class TestVifFunctions(test.NoDBTestCase):
-
- def setUp(self):
- super(TestVifFunctions, self).setUp()
-
- self.adpt = mock.Mock()
-
- @mock.patch('nova.virt.powervm.vif.PvmOvsVifDriver')
- def test_build_vif_driver(self, mock_driver):
- # Valid vif type
- driver = vif._build_vif_driver(self.adpt, 'instance', {'type': 'ovs'})
- self.assertEqual(mock_driver.return_value, driver)
-
- mock_driver.reset_mock()
-
- # Fail if no vif type
- self.assertRaises(exception.VirtualInterfacePlugException,
- vif._build_vif_driver, self.adpt, 'instance',
- {'type': None})
- mock_driver.assert_not_called()
-
- # Fail if invalid vif type
- self.assertRaises(exception.VirtualInterfacePlugException,
- vif._build_vif_driver, self.adpt, 'instance',
- {'type': 'bad_type'})
- mock_driver.assert_not_called()
-
- @mock.patch('oslo_serialization.jsonutils.dumps')
- @mock.patch('pypowervm.wrappers.event.Event')
- def test_push_vif_event(self, mock_event, mock_dumps):
- mock_vif = mock.Mock(mac='MAC', href='HREF')
- vif._push_vif_event(self.adpt, 'action', mock_vif, mock.Mock(),
- 'pvm_sea')
- mock_dumps.assert_called_once_with(
- {'provider': 'NOVA_PVM_VIF', 'action': 'action', 'mac': 'MAC',
- 'type': 'pvm_sea'})
- mock_event.bld.assert_called_once_with(self.adpt, 'HREF',
- mock_dumps.return_value)
- mock_event.bld.return_value.create.assert_called_once_with()
-
- mock_dumps.reset_mock()
- mock_event.bld.reset_mock()
- mock_event.bld.return_value.create.reset_mock()
-
- # Exception reraises
- mock_event.bld.return_value.create.side_effect = IndexError
- self.assertRaises(IndexError, vif._push_vif_event, self.adpt, 'action',
- mock_vif, mock.Mock(), 'pvm_sea')
- mock_dumps.assert_called_once_with(
- {'provider': 'NOVA_PVM_VIF', 'action': 'action', 'mac': 'MAC',
- 'type': 'pvm_sea'})
- mock_event.bld.assert_called_once_with(self.adpt, 'HREF',
- mock_dumps.return_value)
- mock_event.bld.return_value.create.assert_called_once_with()
-
- @mock.patch('nova.virt.powervm.vif._push_vif_event')
- @mock.patch('nova.virt.powervm.vif._build_vif_driver')
- def test_plug(self, mock_bld_drv, mock_event):
- """Test the top-level plug method."""
- mock_vif = {'address': 'MAC', 'type': 'pvm_sea'}
-
- # 1) With new_vif=True (default)
- vnet = vif.plug(self.adpt, 'instance', mock_vif)
-
- mock_bld_drv.assert_called_once_with(self.adpt, 'instance', mock_vif)
- mock_bld_drv.return_value.plug.assert_called_once_with(mock_vif,
- new_vif=True)
- self.assertEqual(mock_bld_drv.return_value.plug.return_value, vnet)
- mock_event.assert_called_once_with(self.adpt, 'plug', vnet, mock.ANY,
- 'pvm_sea')
-
- # Clean up
- mock_bld_drv.reset_mock()
- mock_bld_drv.return_value.plug.reset_mock()
- mock_event.reset_mock()
-
- # 2) Plug returns None (which it should IRL whenever new_vif=False).
- mock_bld_drv.return_value.plug.return_value = None
- vnet = vif.plug(self.adpt, 'instance', mock_vif, new_vif=False)
-
- mock_bld_drv.assert_called_once_with(self.adpt, 'instance', mock_vif)
- mock_bld_drv.return_value.plug.assert_called_once_with(mock_vif,
- new_vif=False)
- self.assertIsNone(vnet)
- mock_event.assert_not_called()
-
- @mock.patch('nova.virt.powervm.vif._build_vif_driver')
- def test_plug_raises(self, mock_vif_drv):
- """HttpError is converted to VirtualInterfacePlugException."""
- vif_drv = mock.Mock(plug=mock.Mock(side_effect=pvm_ex.HttpError(
- resp=mock.Mock())))
- mock_vif_drv.return_value = vif_drv
- mock_vif = {'address': 'vifaddr'}
- self.assertRaises(exception.VirtualInterfacePlugException,
- vif.plug, 'adap', 'inst', mock_vif,
- new_vif='new_vif')
- mock_vif_drv.assert_called_once_with('adap', 'inst', mock_vif)
- vif_drv.plug.assert_called_once_with(mock_vif, new_vif='new_vif')
-
- @mock.patch('nova.virt.powervm.vif._push_vif_event')
- @mock.patch('nova.virt.powervm.vif._build_vif_driver')
- def test_unplug(self, mock_bld_drv, mock_event):
- """Test the top-level unplug method."""
- mock_vif = {'address': 'MAC', 'type': 'pvm_sea'}
-
- # 1) With default cna_w_list
- mock_bld_drv.return_value.unplug.return_value = 'vnet_w'
- vif.unplug(self.adpt, 'instance', mock_vif)
- mock_bld_drv.assert_called_once_with(self.adpt, 'instance', mock_vif)
- mock_bld_drv.return_value.unplug.assert_called_once_with(
- mock_vif, cna_w_list=None)
- mock_event.assert_called_once_with(self.adpt, 'unplug', 'vnet_w',
- mock.ANY, 'pvm_sea')
- # Clean up
- mock_bld_drv.reset_mock()
- mock_bld_drv.return_value.unplug.reset_mock()
- mock_event.reset_mock()
-
- # 2) With specified cna_w_list
- mock_bld_drv.return_value.unplug.return_value = None
- vif.unplug(self.adpt, 'instance', mock_vif, cna_w_list='cnalist')
- mock_bld_drv.assert_called_once_with(self.adpt, 'instance', mock_vif)
- mock_bld_drv.return_value.unplug.assert_called_once_with(
- mock_vif, cna_w_list='cnalist')
- mock_event.assert_not_called()
-
- @mock.patch('nova.virt.powervm.vif._build_vif_driver')
- def test_unplug_raises(self, mock_vif_drv):
- """HttpError is converted to VirtualInterfacePlugException."""
- vif_drv = mock.Mock(unplug=mock.Mock(side_effect=pvm_ex.HttpError(
- resp=mock.Mock())))
- mock_vif_drv.return_value = vif_drv
- mock_vif = {'address': 'vifaddr'}
- self.assertRaises(exception.VirtualInterfaceUnplugException,
- vif.unplug, 'adap', 'inst', mock_vif,
- cna_w_list='cna_w_list')
- mock_vif_drv.assert_called_once_with('adap', 'inst', mock_vif)
- vif_drv.unplug.assert_called_once_with(
- mock_vif, cna_w_list='cna_w_list')
-
-
-class TestVifOvsDriver(test.NoDBTestCase):
-
- def setUp(self):
- super(TestVifOvsDriver, self).setUp()
-
- self.adpt = mock.Mock()
- self.inst = mock.MagicMock(uuid='inst_uuid')
- self.drv = vif.PvmOvsVifDriver(self.adpt, self.inst)
-
- @mock.patch('pypowervm.tasks.cna.crt_p2p_cna', autospec=True)
- @mock.patch('pypowervm.tasks.partition.get_this_partition', autospec=True)
- @mock.patch('nova.virt.powervm.vm.get_pvm_uuid')
- def test_plug(self, mock_pvm_uuid, mock_mgmt_lpar, mock_p2p_cna,):
- # Mock the data
- mock_pvm_uuid.return_value = 'lpar_uuid'
- mock_mgmt_lpar.return_value = mock.Mock(uuid='mgmt_uuid')
- # mock_trunk_dev_name.return_value = 'device'
-
- cna_w, trunk_wraps = mock.MagicMock(), [mock.MagicMock()]
- mock_p2p_cna.return_value = cna_w, trunk_wraps
-
- # Run the plug
- network_model = model.Model({'bridge': 'br0', 'meta': {'mtu': 1450}})
- mock_vif = model.VIF(address='aa:bb:cc:dd:ee:ff', id='vif_id',
- network=network_model, devname='device')
- self.drv.plug(mock_vif)
-
- # Validate the calls
- ovs_ext_ids = ('iface-id=vif_id,iface-status=active,'
- 'attached-mac=aa:bb:cc:dd:ee:ff,vm-uuid=inst_uuid')
- mock_p2p_cna.assert_called_once_with(
- self.adpt, None, 'lpar_uuid', ['mgmt_uuid'],
- 'NovaLinkVEABridge', configured_mtu=1450, crt_vswitch=True,
- mac_addr='aa:bb:cc:dd:ee:ff', dev_name='device', ovs_bridge='br0',
- ovs_ext_ids=ovs_ext_ids)
-
- @mock.patch('pypowervm.tasks.partition.get_this_partition', autospec=True)
- @mock.patch('nova.virt.powervm.vm.get_pvm_uuid')
- @mock.patch('nova.virt.powervm.vm.get_cnas')
- @mock.patch('pypowervm.tasks.cna.find_trunks', autospec=True)
- def test_plug_existing_vif(self, mock_find_trunks, mock_get_cnas,
- mock_pvm_uuid, mock_mgmt_lpar):
- # Mock the data
- t1, t2 = mock.MagicMock(), mock.MagicMock()
- mock_find_trunks.return_value = [t1, t2]
-
- mock_cna = mock.Mock(mac='aa:bb:cc:dd:ee:ff')
- mock_get_cnas.return_value = [mock_cna]
-
- mock_pvm_uuid.return_value = 'lpar_uuid'
-
- mock_mgmt_lpar.return_value = mock.Mock(uuid='mgmt_uuid')
-
- self.inst = mock.MagicMock(uuid='c2e7ff9f-b9b6-46fa-8716-93bbb795b8b4')
- self.drv = vif.PvmOvsVifDriver(self.adpt, self.inst)
-
- # Run the plug
- network_model = model.Model({'bridge': 'br0', 'meta': {'mtu': 1500}})
- mock_vif = model.VIF(address='aa:bb:cc:dd:ee:ff', id='vif_id',
- network=network_model, devname='devname')
- resp = self.drv.plug(mock_vif, new_vif=False)
-
- self.assertIsNone(resp)
-
- # Validate if trunk.update got invoked for all trunks of CNA of vif
- self.assertTrue(t1.update.called)
- self.assertTrue(t2.update.called)
-
- @mock.patch('pypowervm.tasks.cna.find_trunks')
- @mock.patch('nova.virt.powervm.vm.get_cnas')
- def test_unplug(self, mock_get_cnas, mock_find_trunks):
- # Set up the mocks
- mock_cna = mock.Mock(mac='aa:bb:cc:dd:ee:ff')
- mock_get_cnas.return_value = [mock_cna]
-
- t1, t2 = mock.MagicMock(), mock.MagicMock()
- mock_find_trunks.return_value = [t1, t2]
-
- # Call the unplug
- mock_vif = {'address': 'aa:bb:cc:dd:ee:ff',
- 'network': {'bridge': 'br-int'}}
- self.drv.unplug(mock_vif)
-
- # The trunks and the cna should have been deleted
- self.assertTrue(t1.delete.called)
- self.assertTrue(t2.delete.called)
- self.assertTrue(mock_cna.delete.called)
-
-
-class TestVifSeaDriver(test.NoDBTestCase):
-
- def setUp(self):
- super(TestVifSeaDriver, self).setUp()
-
- self.adpt = mock.Mock()
- self.inst = mock.Mock()
- self.drv = vif.PvmSeaVifDriver(self.adpt, self.inst)
-
- @mock.patch('nova.virt.powervm.vm.get_pvm_uuid')
- @mock.patch('pypowervm.tasks.cna.crt_cna')
- def test_plug_from_neutron(self, mock_crt_cna, mock_pvm_uuid):
- """Tests that a VIF can be created. Mocks Neutron net"""
-
- # Set up the mocks. Look like Neutron
- fake_vif = {'details': {'vlan': 5}, 'network': {'meta': {}},
- 'address': 'aabbccddeeff'}
-
- def validate_crt(adpt, host_uuid, lpar_uuid, vlan, mac_addr=None):
- self.assertIsNone(host_uuid)
- self.assertEqual(5, vlan)
- self.assertEqual('aabbccddeeff', mac_addr)
- return pvm_net.CNA.bld(self.adpt, 5, 'host_uuid',
- mac_addr=mac_addr)
- mock_crt_cna.side_effect = validate_crt
-
- # Invoke
- resp = self.drv.plug(fake_vif)
-
- # Validate (along with validate method above)
- self.assertEqual(1, mock_crt_cna.call_count)
- self.assertIsNotNone(resp)
- self.assertIsInstance(resp, pvm_net.CNA)
-
- def test_plug_existing_vif(self):
- """Tests that a VIF need not be created."""
-
- # Set up the mocks
- fake_vif = {'network': {'meta': {'vlan': 5}},
- 'address': 'aabbccddeeff'}
-
- # Invoke
- resp = self.drv.plug(fake_vif, new_vif=False)
-
- self.assertIsNone(resp)
-
- @mock.patch('nova.virt.powervm.vm.get_cnas')
- def test_unplug_vifs(self, mock_vm_get):
- """Tests that a delete of the vif can be done."""
- # Mock up the CNA response. Two should already exist, the other
- # should not.
- cnas = [cna('AABBCCDDEEFF'), cna('AABBCCDDEE11'), cna('AABBCCDDEE22')]
- mock_vm_get.return_value = cnas
-
- # Run method. The AABBCCDDEE11 won't be unplugged (wasn't invoked
- # below) and the last unplug will also just no-op because its not on
- # the VM.
- self.drv.unplug({'address': 'aa:bb:cc:dd:ee:ff'})
- self.drv.unplug({'address': 'aa:bb:cc:dd:ee:22'})
- self.drv.unplug({'address': 'aa:bb:cc:dd:ee:33'})
-
- # The delete should have only been called once for each applicable vif.
- # The second CNA didn't have a matching mac so it should be skipped.
- self.assertEqual(1, cnas[0].delete.call_count)
- self.assertEqual(0, cnas[1].delete.call_count)
- self.assertEqual(1, cnas[2].delete.call_count)