Files
nova-powervm/nova_powervm/tests/virt/powervm/test_mgmt.py
Eric Fried f05ed1f942 Remove data files
Data files are now and should continue to be gleaned from pypowervm,
which should be relied upon to keep them current (with respect to the
REST API), clean, and consolidated.

A recent pypowervm change set has added all the data files needed by
this project, so they are removed from here.

The test utilities used to load these files were also refactored (moved
to a different package).  This change set accomodates that refactor.

Change-Id: Ic289c0fda3fe8271465f4c66ab99238d880931b3
2015-10-02 17:04:44 -05:00

145 lines
5.9 KiB
Python

# Copyright 2015 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 exception
from nova import test
from pypowervm.tests import test_fixtures as pvm_fx
from pypowervm.tests.test_utils import pvmhttp
from pypowervm.wrappers import logical_partition as pvm_lpar
from nova_powervm.virt.powervm import exception as npvmex
from nova_powervm.virt.powervm import mgmt
LPAR_HTTPRESP_FILE = "lpar.txt"
class TestMgmt(test.TestCase):
def setUp(self):
super(TestMgmt, self).setUp()
self.apt = self.useFixture(pvm_fx.AdapterFx()).adpt
lpar_http = pvmhttp.load_pvm_resp(LPAR_HTTPRESP_FILE, adapter=self.apt)
self.assertNotEqual(lpar_http, None,
"Could not load %s " % LPAR_HTTPRESP_FILE)
self.resp = lpar_http.response
def test_get_mgmt_partition(self):
self.apt.read.return_value = self.resp
mp_wrap = mgmt.get_mgmt_partition(self.apt)
self.assertIsInstance(mp_wrap, pvm_lpar.LPAR)
self.assertTrue(mp_wrap.is_mgmt_partition)
@mock.patch('glob.glob')
@mock.patch('nova.utils.execute')
@mock.patch('os.path.realpath')
def test_discover_vscsi_disk(self, mock_realpath, mock_exec, mock_glob):
scanpath = '/sys/bus/vio/devices/30000005/host*/scsi_host/host*/scan'
udid = ('275b5d5f88fa5611e48be9000098be9400'
'13fb2aa55a2d7b8d150cb1b7b6bc04d6')
devlink = ('/dev/disk/by-id/scsi-SIBM_3303_NVDISK' + udid)
mapping = mock.Mock()
mapping.client_adapter.slot_number = 5
mapping.backing_storage.udid = udid
# Realistically, first glob would return e.g. .../host0/.../host0/...
# but it doesn't matter for test purposes.
mock_glob.side_effect = [[scanpath], [devlink]]
mgmt.discover_vscsi_disk(mapping)
mock_glob.assert_has_calls(
[mock.call(scanpath), mock.call('/dev/disk/by-id/*' + udid[-32:])])
mock_exec.assert_called_with('tee', '-a', scanpath,
process_input='- - -', run_as_root=True)
mock_realpath.assert_called_with(devlink)
@mock.patch('time.sleep')
@mock.patch('glob.glob')
@mock.patch('nova.utils.execute')
def test_discover_vscsi_disk_not_one_result(self, mock_exec, mock_glob,
mock_sleep):
"""Zero or more than one disk is found by discover_vscsi_disk."""
udid = ('275b5d5f88fa5611e48be9000098be9400'
'13fb2aa55a2d7b8d150cb1b7b6bc04d6')
mapping = mock.Mock()
mapping.client_adapter.slot_number = 5
mapping.backing_storage.udid = udid
# No disks found
mock_glob.side_effect = lambda path: []
self.assertRaises(npvmex.NoDiskDiscoveryException,
mgmt.discover_vscsi_disk, mapping)
self.assertTrue(mock_sleep.call_count)
# Multiple disks found
mock_sleep.reset_mock()
mock_glob.side_effect = [['path'], ['/dev/sde', '/dev/sdf']]
self.assertRaises(npvmex.UniqueDiskDiscoveryException,
mgmt.discover_vscsi_disk, mapping)
self.assertEqual(0, mock_sleep.call_count)
@mock.patch('time.sleep')
@mock.patch('os.path.realpath')
@mock.patch('os.stat')
@mock.patch('nova.utils.execute')
def test_remove_block_dev(self, mock_exec, mock_stat, mock_realpath,
mock_sleep):
link = '/dev/link/foo'
realpath = '/dev/sde'
delpath = '/sys/block/sde/device/delete'
mock_realpath.return_value = realpath
# Good path
mock_stat.side_effect = (None, None, OSError())
mgmt.remove_block_dev(link)
mock_realpath.assert_called_with(link)
mock_stat.assert_has_calls([mock.call(realpath), mock.call(delpath),
mock.call(realpath)])
mock_exec.assert_called_with('tee', '-a', delpath, process_input='1',
run_as_root=True)
self.assertEqual(0, mock_sleep.call_count)
# Device param not found
mock_exec.reset_mock()
mock_stat.reset_mock()
mock_stat.side_effect = (OSError(), None, None)
self.assertRaises(exception.InvalidDevicePath, mgmt.remove_block_dev,
link)
# stat was called once; exec was not called
self.assertEqual(1, mock_stat.call_count)
self.assertEqual(0, mock_exec.call_count)
# Delete special file not found
mock_exec.reset_mock()
mock_stat.reset_mock()
mock_stat.side_effect = (None, OSError(), None)
self.assertRaises(exception.InvalidDevicePath, mgmt.remove_block_dev,
link)
# stat was called twice; exec was not called
self.assertEqual(2, mock_stat.call_count)
self.assertEqual(0, mock_exec.call_count)
# Deletion was attempted, but device is still there
mock_exec.reset_mock()
mock_stat.reset_mock()
mock_sleep.reset_mock()
mock_stat.side_effect = lambda path: 1
self.assertRaises(
npvmex.DeviceDeletionException, mgmt.remove_block_dev, link)
# stat was called many times; exec was called once
self.assertTrue(mock_stat.call_count > 4)
self.assertEqual(1, mock_exec.call_count)
# sleep was called many times
self.assertTrue(mock_sleep.call_count)