It was suggested that we replace TestCase with NoDBTestCase [1]. This does two things. First it prevents the test case setup from running the database schema migrations unnecessarily which should improve performance. Second it will cause the test to fail if the code does touch the DB when the developer is claiming that it shouldn't. [1] https://review.openstack.org/#/c/409404/46/nova/tests/unit/virt/powervm/test_media.py Change-Id: I8bcc9cbdcadd9fe89a4450ca405387899baa9fc3
167 lines
6.5 KiB
Python
167 lines
6.5 KiB
Python
# Copyright 2016 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 nova import test
|
|
from nova_powervm.virt.powervm import exception as p_exc
|
|
from nova_powervm.virt.powervm import slot
|
|
|
|
from pypowervm import exceptions as pvm_exc
|
|
|
|
|
|
class TestNovaSlotManager(test.NoDBTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestNovaSlotManager, self).setUp()
|
|
self.store_api = mock.MagicMock()
|
|
self.inst = mock.MagicMock(uuid='uuid1')
|
|
|
|
def test_build_slot_mgr(self):
|
|
# Test when NVRAM store exists
|
|
# The Swift-backed implementation of PowerVM SlotMapStore is returned
|
|
self.store_api.fetch_slot_map = mock.MagicMock(return_value=None)
|
|
slot_mgr = slot.build_slot_mgr(self.inst, self.store_api, adapter=None,
|
|
vol_drv_iter=None)
|
|
self.assertIsInstance(slot_mgr, slot.SwiftSlotManager)
|
|
self.assertFalse(slot_mgr.is_rebuild)
|
|
|
|
# Test when no NVRAM store is set up
|
|
# The no-op implementation of PowerVM SlotMapStore is returned
|
|
self.assertIsInstance(
|
|
slot.build_slot_mgr(self.inst, None, adapter=None,
|
|
vol_drv_iter=None),
|
|
slot.NoopSlotManager)
|
|
|
|
# Test that the rebuild flag is set when it is flagged as a rebuild
|
|
slot_mgr = slot.build_slot_mgr(
|
|
self.inst, self.store_api, adapter='adpt', vol_drv_iter='test')
|
|
self.assertTrue(slot_mgr.is_rebuild)
|
|
|
|
|
|
class TestSwiftSlotManager(test.NoDBTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestSwiftSlotManager, self).setUp()
|
|
self.store_api = mock.MagicMock()
|
|
self.store_api.fetch_slot_map = mock.MagicMock(return_value=None)
|
|
self.inst = mock.MagicMock(uuid='a2e71b38-160f-4650-bbdc-2a10cd507e2b')
|
|
self.slot_mgr = slot.SwiftSlotManager(self.store_api,
|
|
instance=self.inst)
|
|
|
|
def test_load(self):
|
|
# load() should have been called internally by __init__
|
|
self.store_api.fetch_slot_map.assert_called_with(
|
|
self.inst.uuid + '_slot_map')
|
|
|
|
def test_save(self):
|
|
# Mock the call
|
|
self.store_api.store_slot_map = mock.MagicMock()
|
|
|
|
# Run save
|
|
self.slot_mgr.save()
|
|
|
|
# Not called because nothing changed
|
|
self.store_api.store_slot_map.assert_not_called()
|
|
|
|
# Change something
|
|
mock_vfcmap = mock.Mock(server_adapter=mock.Mock(lpar_slot_num=123))
|
|
self.slot_mgr.register_vfc_mapping(mock_vfcmap, 'fabric')
|
|
|
|
# Run save
|
|
self.slot_mgr.save()
|
|
|
|
# Validate the call
|
|
self.store_api.store_slot_map.assert_called_once_with(
|
|
self.inst.uuid + '_slot_map', mock.ANY)
|
|
|
|
def test_delete(self):
|
|
# Mock the call
|
|
self.store_api.delete_slot_map = mock.MagicMock()
|
|
|
|
# Run delete
|
|
self.slot_mgr.delete()
|
|
|
|
# Validate the call
|
|
self.store_api.delete_slot_map.assert_called_once_with(
|
|
self.inst.uuid + '_slot_map')
|
|
|
|
@mock.patch('pypowervm.tasks.slot_map.RebuildSlotMap')
|
|
@mock.patch('pypowervm.tasks.storage.ComprehensiveScrub')
|
|
def test_init_recreate_map(self, mock_ftsk, mock_rebuild_slot):
|
|
vios1, vios2 = mock.Mock(uuid='uuid1'), mock.Mock(uuid='uuid2')
|
|
mock_ftsk.return_value.feed = [vios1, vios2]
|
|
self.slot_mgr.init_recreate_map(mock.Mock(), self._vol_drv_iter())
|
|
self.assertEqual(1, mock_ftsk.call_count)
|
|
mock_rebuild_slot.assert_called_once_with(
|
|
self.slot_mgr, mock.ANY, {'udid': ['uuid2']}, ['a', 'b'])
|
|
|
|
@mock.patch('pypowervm.tasks.slot_map.RebuildSlotMap')
|
|
@mock.patch('pypowervm.tasks.storage.ComprehensiveScrub')
|
|
def test_init_recreate_map_fails(self, mock_ftsk, mock_rebuild_slot):
|
|
vios1, vios2 = mock.Mock(uuid='uuid1'), mock.Mock(uuid='uuid2')
|
|
mock_ftsk.return_value.feed = [vios1, vios2]
|
|
mock_rebuild_slot.side_effect = (
|
|
pvm_exc.InvalidHostForRebuildNotEnoughVIOS(udid='udid56'))
|
|
self.assertRaises(
|
|
p_exc.InvalidRebuild, self.slot_mgr.init_recreate_map, mock.Mock(),
|
|
self._vol_drv_iter())
|
|
|
|
@mock.patch('pypowervm.tasks.slot_map.RebuildSlotMap')
|
|
@mock.patch('pypowervm.tasks.storage.ComprehensiveScrub')
|
|
def test_init_recreate_map_fileio(self, mock_ftsk, mock_rebuild_slot):
|
|
vios1, vios2 = mock.Mock(uuid='uuid1'), mock.Mock(uuid='uuid2')
|
|
mock_ftsk.return_value.feed = [vios1, vios2]
|
|
expected_vio_wrap = [vios1, vios2]
|
|
self.slot_mgr.init_recreate_map(mock.Mock(), self._vol_drv_iter_2())
|
|
self.assertEqual(1, mock_ftsk.call_count)
|
|
mock_rebuild_slot.assert_called_once_with(
|
|
self.slot_mgr, expected_vio_wrap,
|
|
{'udidvscsi': ['uuid1'], 'udid': ['uuid1']}, [])
|
|
|
|
def _vol_drv_iter_2(self):
|
|
mock_fileio = mock.Mock()
|
|
mock_fileio.vol_type.return_value = 'fileio'
|
|
mock_fileio.is_volume_on_vios.side_effect = ((True, 'udid'),
|
|
(False, None))
|
|
mock_scsi = mock.Mock()
|
|
mock_scsi.vol_type.return_value = 'vscsi'
|
|
mock_scsi.is_volume_on_vios.side_effect = ((True, 'udidvscsi'),
|
|
(False, None))
|
|
|
|
vol_drv = [mock_fileio, mock_scsi]
|
|
for type in vol_drv:
|
|
yield mock.Mock(), type
|
|
|
|
def _vol_drv_iter(self):
|
|
mock_scsi = mock.Mock()
|
|
mock_scsi.vol_type.return_value = 'vscsi'
|
|
mock_scsi.is_volume_on_vios.side_effect = ((False, None),
|
|
(True, 'udid'))
|
|
|
|
mock_npiv1 = mock.Mock()
|
|
mock_npiv1.vol_type.return_value = 'npiv'
|
|
mock_npiv1._fabric_names.return_value = ['a', 'b']
|
|
|
|
mock_npiv2 = mock.Mock()
|
|
mock_npiv2.vol_type.return_value = 'npiv'
|
|
mock_npiv2._fabric_names.return_value = ['a', 'b', 'c']
|
|
|
|
vol_drv = [mock_scsi, mock_npiv1, mock_npiv2]
|
|
for type in vol_drv:
|
|
yield mock.Mock(), type
|