This commit replaces the references from nova.virt.hyperv.* to hyperv.nova.* and nova.tests.unit.virt.hyperv.* to hyperv.tests.unit.*.
165 lines
6.1 KiB
Python
165 lines
6.1 KiB
Python
# Copyright 2014 Cloudbase Solutions Srl
|
|
#
|
|
# 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 oslo_config import cfg
|
|
|
|
from hyperv.nova import vmutils
|
|
from hyperv.nova import volumeutils
|
|
from hyperv.tests.unit import test_basevolumeutils
|
|
|
|
CONF = cfg.CONF
|
|
CONF.import_opt('volume_attach_retry_count', 'hyperv.nova.volumeops',
|
|
'hyperv')
|
|
|
|
|
|
class VolumeUtilsTestCase(test_basevolumeutils.BaseVolumeUtilsTestCase):
|
|
"""Unit tests for the Hyper-V VolumeUtils class."""
|
|
|
|
_FAKE_PORTAL_ADDR = '10.1.1.1'
|
|
_FAKE_PORTAL_PORT = '3260'
|
|
_FAKE_LUN = 0
|
|
_FAKE_TARGET = 'iqn.2010-10.org.openstack:fake_target'
|
|
|
|
_FAKE_STDOUT_VALUE = 'The operation completed successfully'
|
|
|
|
def setUp(self):
|
|
super(VolumeUtilsTestCase, self).setUp()
|
|
self._volutils = volumeutils.VolumeUtils()
|
|
self._volutils._conn_wmi = mock.MagicMock()
|
|
self._volutils._conn_cimv2 = mock.MagicMock()
|
|
self.flags(volume_attach_retry_count=4, group='hyperv')
|
|
self.flags(volume_attach_retry_interval=0, group='hyperv')
|
|
|
|
def _test_login_target_portal(self, portal_connected):
|
|
fake_portal = '%s:%s' % (self._FAKE_PORTAL_ADDR,
|
|
self._FAKE_PORTAL_PORT)
|
|
|
|
self._volutils.execute = mock.MagicMock()
|
|
if portal_connected:
|
|
exec_output = 'Address and Socket: %s %s' % (
|
|
self._FAKE_PORTAL_ADDR, self._FAKE_PORTAL_PORT)
|
|
else:
|
|
exec_output = ''
|
|
|
|
self._volutils.execute.return_value = exec_output
|
|
|
|
self._volutils._login_target_portal(fake_portal)
|
|
|
|
call_list = self._volutils.execute.call_args_list
|
|
all_call_args = [arg for call in call_list for arg in call[0]]
|
|
|
|
if portal_connected:
|
|
self.assertIn('RefreshTargetPortal', all_call_args)
|
|
else:
|
|
self.assertIn('AddTargetPortal', all_call_args)
|
|
|
|
def test_login_connected_portal(self):
|
|
self._test_login_target_portal(True)
|
|
|
|
def test_login_new_portal(self):
|
|
self._test_login_target_portal(False)
|
|
|
|
def _test_login_target(self, target_connected=False, raise_exception=False,
|
|
use_chap=False):
|
|
fake_portal = '%s:%s' % (self._FAKE_PORTAL_ADDR,
|
|
self._FAKE_PORTAL_PORT)
|
|
self._volutils.execute = mock.MagicMock()
|
|
self._volutils._login_target_portal = mock.MagicMock()
|
|
|
|
if use_chap:
|
|
username, password = (mock.sentinel.username,
|
|
mock.sentinel.password)
|
|
else:
|
|
username, password = None, None
|
|
|
|
if target_connected:
|
|
self._volutils.execute.return_value = self._FAKE_TARGET
|
|
elif raise_exception:
|
|
self._volutils.execute.return_value = ''
|
|
else:
|
|
self._volutils.execute.side_effect = (
|
|
['', '', '', self._FAKE_TARGET, ''])
|
|
|
|
if raise_exception:
|
|
self.assertRaises(vmutils.HyperVException,
|
|
self._volutils.login_storage_target,
|
|
self._FAKE_LUN, self._FAKE_TARGET,
|
|
fake_portal, username, password)
|
|
else:
|
|
self._volutils.login_storage_target(self._FAKE_LUN,
|
|
self._FAKE_TARGET,
|
|
fake_portal,
|
|
username, password)
|
|
|
|
if target_connected:
|
|
call_list = self._volutils.execute.call_args_list
|
|
all_call_args = [arg for call in call_list for arg in call[0]]
|
|
self.assertNotIn('qlogintarget', all_call_args)
|
|
else:
|
|
self._volutils.execute.assert_any_call(
|
|
'iscsicli.exe', 'qlogintarget',
|
|
self._FAKE_TARGET, username, password)
|
|
|
|
def test_login_connected_target(self):
|
|
self._test_login_target(target_connected=True)
|
|
|
|
def test_login_disconncted_target(self):
|
|
self._test_login_target()
|
|
|
|
def test_login_target_exception(self):
|
|
self._test_login_target(raise_exception=True)
|
|
|
|
def test_login_target_using_chap(self):
|
|
self._test_login_target(use_chap=True)
|
|
|
|
def _test_execute_wrapper(self, raise_exception):
|
|
fake_cmd = ('iscsicli.exe', 'ListTargetPortals')
|
|
|
|
if raise_exception:
|
|
output = 'fake error'
|
|
else:
|
|
output = 'The operation completed successfully'
|
|
|
|
with mock.patch('nova.utils.execute') as fake_execute:
|
|
fake_execute.return_value = (output, None)
|
|
|
|
if raise_exception:
|
|
self.assertRaises(vmutils.HyperVException,
|
|
self._volutils.execute,
|
|
*fake_cmd)
|
|
else:
|
|
ret_val = self._volutils.execute(*fake_cmd)
|
|
self.assertEqual(output, ret_val)
|
|
|
|
def test_execute_raise_exception(self):
|
|
self._test_execute_wrapper(True)
|
|
|
|
def test_execute_exception(self):
|
|
self._test_execute_wrapper(False)
|
|
|
|
@mock.patch.object(volumeutils, 'utils')
|
|
def test_logout_storage_target(self, mock_utils):
|
|
mock_utils.execute.return_value = (self._FAKE_STDOUT_VALUE,
|
|
mock.sentinel.FAKE_STDERR_VALUE)
|
|
session = mock.MagicMock()
|
|
session.SessionId = mock.sentinel.FAKE_SESSION_ID
|
|
self._volutils._conn_wmi.query.return_value = [session]
|
|
|
|
self._volutils.logout_storage_target(mock.sentinel.FAKE_IQN)
|
|
mock_utils.execute.assert_called_once_with(
|
|
'iscsicli.exe', 'logouttarget', mock.sentinel.FAKE_SESSION_ID)
|