From 61dcd5697e8a3c7145b2800f0c0d0b3bb5647ba8 Mon Sep 17 00:00:00 2001 From: Dorin Paslaru Date: Wed, 17 Aug 2016 21:58:10 +0300 Subject: [PATCH] Refactors wmi exceptions usage There are conditional imports (Windows specific modules), done in most of os-win's modules. One of the modules is wmi, is mostly used in try-except blocks. Imports wmi.x_wmi and wmi.x_wmi_timed_out exceptions into os_win.exceptions. Refactors wmi exceptions usage. Change-Id: I40107892c63d6186fa3d8bac36e56b28ef8c7910 --- os_win/exceptions.py | 16 +++++++++ os_win/tests/test_base.py | 5 +-- os_win/tests/utils/compute/test_vmutils.py | 4 +-- .../tests/utils/network/test_networkutils.py | 12 +++---- .../utils/storage/initiator/test_fc_utils.py | 3 +- os_win/tests/utils/storage/test_smbutils.py | 15 ++++----- os_win/utils/compute/clusterutils.py | 5 +-- os_win/utils/compute/livemigrationutils.py | 6 +--- os_win/utils/compute/vmutils.py | 6 +--- os_win/utils/jobutils.py | 6 +--- os_win/utils/network/networkutils.py | 8 ++--- .../storage/initiator/iscsi_wmi_utils.py | 6 +--- os_win/utils/storage/smbutils.py | 5 ++- .../storage/target/iscsi_target_utils.py | 33 ++++++++----------- 14 files changed, 54 insertions(+), 76 deletions(-) diff --git a/os_win/exceptions.py b/os_win/exceptions.py index d63e1820..8f59459e 100644 --- a/os_win/exceptions.py +++ b/os_win/exceptions.py @@ -17,8 +17,24 @@ Utility class for VM related operations on Hyper-V. """ +import sys + from os_win._i18n import _ +# Define WMI specific exceptions, so WMI won't have to be imported in any +# module that expects those exceptions. +if sys.platform == 'win32': + import wmi + + x_wmi = wmi.x_wmi + x_wmi_timed_out = wmi.x_wmi_timed_out +else: + class x_wmi(Exception): + pass + + class x_wmi_timed_out(x_wmi): + pass + class OSWinException(Exception): msg_fmt = 'An exception has been encountered.' diff --git a/os_win/tests/test_base.py b/os_win/tests/test_base.py index 2ceb9128..439e5b22 100644 --- a/os_win/tests/test_base.py +++ b/os_win/tests/test_base.py @@ -18,8 +18,10 @@ import mock from oslotest import base from six.moves import builtins +from os_win import exceptions -class FakeWMIExc(Exception): + +class FakeWMIExc(exceptions.x_wmi): def __init__(self, hresult=None): excepinfo = [None] * 5 + [hresult] self.com_error = mock.Mock(excepinfo=excepinfo) @@ -31,7 +33,6 @@ class OsWinBaseTestCase(base.BaseTestCase): super(OsWinBaseTestCase, self).setUp() self._mock_wmi = mock.MagicMock() - self._mock_wmi.x_wmi = FakeWMIExc mock_os = mock.MagicMock(Version='6.3.0') self._mock_wmi.WMI.return_value.Win32_OperatingSystem.return_value = ( diff --git a/os_win/tests/utils/compute/test_vmutils.py b/os_win/tests/utils/compute/test_vmutils.py index 14e0c241..a395169d 100644 --- a/os_win/tests/utils/compute/test_vmutils.py +++ b/os_win/tests/utils/compute/test_vmutils.py @@ -947,8 +947,6 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase): @mock.patch.object(vmutils, 'patcher') def test_vm_power_state_change_event_handler(self, mock_patcher, mock_tpool, mock_sleep): - self._mock_wmi.x_wmi_timed_out = exceptions.HyperVException - enabled_state = constants.HYPERV_VM_STATE_ENABLED hv_enabled_state = self._vmutils._vm_power_states_map[enabled_state] fake_event = mock.Mock(ElementName=mock.sentinel.vm_name, @@ -957,7 +955,7 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase): fake_listener = ( self._vmutils._conn.Msvm_ComputerSystem.watch_for.return_value) - mock_tpool.execute.side_effect = (self._mock_wmi.x_wmi_timed_out, + mock_tpool.execute.side_effect = (exceptions.x_wmi_timed_out, fake_event, Exception, KeyboardInterrupt) diff --git a/os_win/tests/utils/network/test_networkutils.py b/os_win/tests/utils/network/test_networkutils.py index 1f9d61a3..1add2b6b 100644 --- a/os_win/tests/utils/network/test_networkutils.py +++ b/os_win/tests/utils/network/test_networkutils.py @@ -145,15 +145,13 @@ class NetworkUtilsTestCase(test_base.OsWinBaseTestCase): @mock.patch.object(networkutils, 'patcher') @mock.patch.object(networkutils.tpool, 'execute') - @mock.patch.object(networkutils, 'wmi', create=True) @mock.patch.object(networkutils.NetworkUtils, '_get_event_wql_query') - def test_get_vnic_event_listener(self, mock_get_event_query, mock_wmi, + def test_get_vnic_event_listener(self, mock_get_event_query, mock_execute, mock_patcher): - mock_wmi.x_wmi_timed_out = ValueError event = mock.MagicMock() port_class = self.netutils._conn.Msvm_SyntheticEthernetPortSettingData wmi_event_listener = port_class.watch_for.return_value - mock_execute.side_effect = [mock_wmi.x_wmi_timed_out, event] + mock_execute.side_effect = [exceptions.x_wmi_timed_out, event] # callback will raise an exception in order to stop iteration in the # listener. @@ -254,14 +252,12 @@ class NetworkUtilsTestCase(test_base.OsWinBaseTestCase): expected_result = conn.Msvm_ComputerSystem.return_value[0] self.assertEqual(expected_result, resulted_vm) - @mock.patch.object(networkutils, 'wmi', create=True) - def test_remove_switch_port(self, mock_wmi): + def test_remove_switch_port(self): mock_sw_port = self._mock_get_switch_port_alloc() self.netutils._switch_ports[self._FAKE_PORT_NAME] = mock_sw_port self.netutils._vlan_sds[mock_sw_port.InstanceID] = mock.MagicMock() - mock_wmi.x_wmi = Exception self.netutils._jobutils.remove_virt_resource.side_effect = ( - mock_wmi.x_wmi) + exceptions.x_wmi) self.netutils.remove_switch_port(self._FAKE_PORT_NAME, False) diff --git a/os_win/tests/utils/storage/initiator/test_fc_utils.py b/os_win/tests/utils/storage/initiator/test_fc_utils.py index 9cc4ade9..bba3ee36 100644 --- a/os_win/tests/utils/storage/initiator/test_fc_utils.py +++ b/os_win/tests/utils/storage/initiator/test_fc_utils.py @@ -29,8 +29,7 @@ class FCUtilsTestCase(base.BaseTestCase): _FAKE_ADAPTER_NAME = 'fake_adapter_name' _FAKE_ADAPTER_WWN = list(range(8)) - @mock.patch.object(fc_utils, 'wmi', create=True) - def setUp(self, mock_wmi): + def setUp(self): super(FCUtilsTestCase, self).setUp() self._setup_lib_mocks() diff --git a/os_win/tests/utils/storage/test_smbutils.py b/os_win/tests/utils/storage/test_smbutils.py index 98b9634b..e07e2679 100644 --- a/os_win/tests/utils/storage/test_smbutils.py +++ b/os_win/tests/utils/storage/test_smbutils.py @@ -72,10 +72,8 @@ class SMBUtilsTestCase(test_base.OsWinBaseTestCase): UserName=mock.sentinel.username, Password=mock.sentinel.password) - @mock.patch.object(smbutils, 'wmi', create=True) - def test_mount_smb_share_failed(self, mock_wmi): - mock_wmi.x_wmi = Exception - self._smb_conn.Msft_SmbMapping.Create.side_effect = mock_wmi.x_wmi + def test_mount_smb_share_failed(self): + self._smb_conn.Msft_SmbMapping.Create.side_effect = exceptions.x_wmi self.assertRaises(exceptions.SMBException, self._smbutils.mount_smb_share, @@ -101,14 +99,13 @@ class SMBUtilsTestCase(test_base.OsWinBaseTestCase): def test_force_unmount_smb_share(self): self._test_unmount_smb_share(force=True) - @mock.patch.object(smbutils, 'wmi', create=True) - def test_unmount_smb_share_wmi_exception(self, mock_wmi): - mock_wmi.x_wmi = Exception + def test_unmount_smb_share_wmi_exception(self): fake_mapping = mock.Mock() - fake_mapping.Remove.side_effect = mock_wmi.x_wmi + fake_mapping.Remove.side_effect = exceptions.x_wmi self._smb_conn.Msft_SmbMapping.return_value = [fake_mapping] - self.assertRaises(mock_wmi.x_wmi, self._smbutils.unmount_smb_share, + self.assertRaises(exceptions.SMBException, + self._smbutils.unmount_smb_share, mock.sentinel.share_path, force=True) @mock.patch.object(smbutils, 'ctypes') diff --git a/os_win/utils/compute/clusterutils.py b/os_win/utils/compute/clusterutils.py index 0f926541..92dcb68d 100644 --- a/os_win/utils/compute/clusterutils.py +++ b/os_win/utils/compute/clusterutils.py @@ -28,9 +28,6 @@ from os_win._i18n import _, _LE from os_win import exceptions from os_win.utils import baseutils -if sys.platform == 'win32': - import wmi - LOG = logging.getLogger(__name__) @@ -234,5 +231,5 @@ class ClusterUtils(baseutils.BaseUtils): except Exception: LOG.exception( _LE("Exception during failover callback.")) - except wmi.x_wmi_timed_out: + except exceptions.x_wmi_timed_out: pass diff --git a/os_win/utils/compute/livemigrationutils.py b/os_win/utils/compute/livemigrationutils.py index 2ff0235e..8f361a19 100644 --- a/os_win/utils/compute/livemigrationutils.py +++ b/os_win/utils/compute/livemigrationutils.py @@ -14,7 +14,6 @@ # under the License. import platform -import sys from oslo_log import log as logging @@ -26,9 +25,6 @@ from os_win.utils.compute import vmutils from os_win.utils import jobutils from os_win.utils.storage.initiator import iscsi_wmi_utils -if sys.platform == 'win32': - import wmi - LOG = logging.getLogger(__name__) @@ -45,7 +41,7 @@ class LiveMigrationUtils(baseutils.BaseUtilsVirt): def _get_conn_v2(self, host='localhost'): try: return self._get_wmi_obj(self._wmi_namespace % host) - except wmi.x_wmi as ex: + except exceptions.x_wmi as ex: LOG.exception(_LE('Get version 2 connection error')) if ex.com_error.hresult == -2147217394: msg = (_('Live migration is not supported on target host "%s"') diff --git a/os_win/utils/compute/vmutils.py b/os_win/utils/compute/vmutils.py index 66d24654..45ec5bf5 100644 --- a/os_win/utils/compute/vmutils.py +++ b/os_win/utils/compute/vmutils.py @@ -21,7 +21,6 @@ Hyper-V Server / Windows Server 2012. """ import functools -import sys import time import uuid @@ -42,9 +41,6 @@ from os_win.utils import baseutils from os_win.utils import jobutils from os_win.utils import pathutils -if sys.platform == 'win32': - import wmi - CONF = cfg.CONF LOG = logging.getLogger(__name__) @@ -856,7 +852,7 @@ class VMUtils(baseutils.BaseUtilsVirt): LOG.exception(err_msg, dict(vm_name=vm_name, vm_power_state=vm_power_state)) - except wmi.x_wmi_timed_out: + except exceptions.x_wmi_timed_out: pass except Exception: LOG.exception( diff --git a/os_win/utils/jobutils.py b/os_win/utils/jobutils.py index 3470802a..3ce5b0d0 100644 --- a/os_win/utils/jobutils.py +++ b/os_win/utils/jobutils.py @@ -18,7 +18,6 @@ Base Utility class for operations on Hyper-V. """ -import sys import time from oslo_log import log as logging @@ -32,9 +31,6 @@ from os_win.utils import win32utils LOG = logging.getLogger(__name__) -if sys.platform == 'win32': - import wmi - class JobUtils(baseutils.BaseUtilsVirt): @@ -127,7 +123,7 @@ class JobUtils(baseutils.BaseUtilsVirt): job.RequestStateChange( self._KILL_JOB_STATE_CHANGE_REQUEST) - except wmi.x_wmi as ex: + except exceptions.x_wmi as ex: hresult = win32utils.Win32Utils.get_com_error_hresult( ex.com_error) # The job may had been completed right before we've diff --git a/os_win/utils/network/networkutils.py b/os_win/utils/network/networkutils.py index 34237a8f..ecd19089 100644 --- a/os_win/utils/network/networkutils.py +++ b/os_win/utils/network/networkutils.py @@ -23,7 +23,6 @@ import re from eventlet import patcher from eventlet import tpool -import sys from os_win._i18n import _ from os_win import exceptions @@ -31,9 +30,6 @@ from os_win.utils import _wqlutils from os_win.utils import baseutils from os_win.utils import jobutils -if sys.platform == 'win32': - import wmi - class NetworkUtils(baseutils.BaseUtilsVirt): @@ -230,7 +226,7 @@ class NetworkUtils(baseutils.BaseUtilsVirt): try: event = listen() callback(event.ElementName) - except wmi.x_wmi_timed_out: + except exceptions.x_wmi_timed_out: # no new event published. pass @@ -295,7 +291,7 @@ class NetworkUtils(baseutils.BaseUtilsVirt): if not vnic_deleted: try: self._jobutils.remove_virt_resource(sw_port) - except wmi.x_wmi: + except exceptions.x_wmi: # port may have already been destroyed by Hyper-V pass diff --git a/os_win/utils/storage/initiator/iscsi_wmi_utils.py b/os_win/utils/storage/initiator/iscsi_wmi_utils.py index 170cfb17..884f468c 100644 --- a/os_win/utils/storage/initiator/iscsi_wmi_utils.py +++ b/os_win/utils/storage/initiator/iscsi_wmi_utils.py @@ -18,7 +18,6 @@ Helper methods for operations related to the management of volumes and storage repositories on Windows Server 2012 and above """ -import sys import time from oslo_config import cfg @@ -30,9 +29,6 @@ from os_win import _utils from os_win import exceptions from os_win.utils.storage.initiator import base_iscsi_utils -if sys.platform == 'win32': - import wmi - LOG = logging.getLogger(__name__) CONF = cfg.CONF @@ -99,7 +95,7 @@ class ISCSIInitiatorWMIUtils(base_iscsi_utils.BaseISCSIInitiatorUtils): target.Connect(NodeAddress=target_iqn, IsPersistent=True, **auth) time.sleep(CONF.hyperv.volume_attach_retry_interval) - except wmi.x_wmi as exc: + except exceptions.x_wmi as exc: LOG.debug("Attempt %(attempt)d to connect to target " "%(target_iqn)s failed. Retrying. " "WMI exception: %(exc)s " % diff --git a/os_win/utils/storage/smbutils.py b/os_win/utils/storage/smbutils.py index ddcedddf..7beb1c68 100644 --- a/os_win/utils/storage/smbutils.py +++ b/os_win/utils/storage/smbutils.py @@ -28,7 +28,6 @@ from os_win.utils import win32utils if sys.platform == 'win32': kernel32 = ctypes.windll.kernel32 - import wmi LOG = logging.getLogger(__name__) @@ -61,7 +60,7 @@ class SMBUtils(baseutils.BaseUtils): self._smb_conn.Msft_SmbMapping.Create(RemotePath=share_path, UserName=username, Password=password) - except wmi.x_wmi as exc: + except exceptions.x_wmi as exc: err_msg = (_( 'Unable to mount SMBFS share: %(share_path)s ' 'WMI exception: %(wmi_exc)s') % {'share_path': share_path, @@ -81,7 +80,7 @@ class SMBUtils(baseutils.BaseUtils): mapping.Remove(Force=force) except AttributeError: pass - except wmi.x_wmi: + except exceptions.x_wmi: # If this fails, a 'Generic Failure' exception is raised. # This happens even if we unforcefully unmount an in-use # share, for which reason we'll simply ignore it in this diff --git a/os_win/utils/storage/target/iscsi_target_utils.py b/os_win/utils/storage/target/iscsi_target_utils.py index 80efe3eb..37ca9df1 100644 --- a/os_win/utils/storage/target/iscsi_target_utils.py +++ b/os_win/utils/storage/target/iscsi_target_utils.py @@ -13,8 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -import sys - from oslo_log import log as logging from os_win._i18n import _, _LI @@ -25,9 +23,6 @@ from os_win.utils import hostutils from os_win.utils import pathutils from os_win.utils import win32utils -if sys.platform == 'win32': - import wmi - LOG = logging.getLogger(__name__) @@ -119,7 +114,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): """Creates ISCSI target.""" try: self._conn_wmi.WT_Host.NewHost(HostName=target_name) - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_code = self._win32utils.get_com_err_code(wmi_exc.com_error) target_exists = err_code == self._ERR_FILE_EXISTS @@ -141,7 +136,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): return wt_host.RemoveAllWTDisks() wt_host.Delete_() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _("Failed to delete ISCSI target %s") raise exceptions.ISCSITargetWMIException(err_msg % target_name, wmi_exc=wmi_exc) @@ -173,7 +168,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): wt_host.CHAPUserName = chap_username wt_host.CHAPSecret = chap_password wt_host.put() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Failed to set CHAP credentials on target %s.') raise exceptions.ISCSITargetWMIException(err_msg % target_name, wmi_exc=wmi_exc) @@ -191,7 +186,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): wt_idmethod.Method = id_method wt_idmethod.Value = initiator wt_idmethod.put() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Could not associate initiator %(initiator)s to ' 'iSCSI target: %(target_name)s.') raise exceptions.ISCSITargetWMIException( @@ -204,7 +199,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): wt_idmethod = self._get_wt_idmethod(initiator, target_name) if wt_idmethod: wt_idmethod.Delete_() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Could not deassociate initiator %(initiator)s from ' 'iSCSI target: %(target_name)s.') raise exceptions.ISCSITargetWMIException( @@ -217,7 +212,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): self._conn_wmi.WT_Disk.NewWTDisk(DevicePath=vhd_path, Description=wtd_name, SizeInMB=size_mb) - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Failed to create WT Disk. ' 'VHD path: %(vhd_path)s ' 'WT disk name: %(wtd_name)s') @@ -231,7 +226,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): try: self._conn_wmi.WT_Disk.ImportWTDisk(DevicePath=vhd_path, Description=wtd_name) - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _("Failed to import WT disk: %s.") raise exceptions.ISCSITargetWMIException(err_msg % vhd_path, wmi_exc=wmi_exc) @@ -241,7 +236,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): wt_disk = self._get_wt_disk(wtd_name) wt_disk.Enabled = enabled wt_disk.put() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Could not change disk status. WT Disk name: %s') raise exceptions.ISCSITargetWMIException(err_msg % wtd_name, wmi_exc=wmi_exc) @@ -251,7 +246,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): wt_disk = self._get_wt_disk(wtd_name, fail_if_not_found=False) if wt_disk: wt_disk.Delete_() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _("Failed to remove WT disk: %s.") raise exceptions.ISCSITargetWMIException(err_msg % wtd_name, wmi_exc=wmi_exc) @@ -260,7 +255,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): try: wt_disk = self._get_wt_disk(wtd_name) wt_disk.Extend(additional_mb) - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Could not extend WT Disk %(wtd_name)s ' 'with additional %(additional_mb)s MB.') raise exceptions.ISCSITargetWMIException( @@ -274,7 +269,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): wt_disk = self._get_wt_disk(wtd_name) wt_host = self._get_wt_host(target_name) wt_host.AddWTDisk(wt_disk.WTD) - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Could not add WTD Disk %(wtd_name)s to ' 'iSCSI target %(target_name)s.') raise exceptions.ISCSITargetWMIException( @@ -291,7 +286,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): wt_snap = self._conn_wmi.WT_Snapshot(Id=snap_id)[0] wt_snap.Description = snapshot_name wt_snap.put() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Failed to create snapshot. ' 'WT Disk name: %(wtd_name)s ' 'Snapshot name: %(snapshot_name)s') @@ -315,7 +310,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): self._pathutils.copy(src_path, dest_path) wt_disk.Delete_() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Failed to export snapshot %(snapshot_name)s ' 'to %(dest_path)s.') raise exceptions.ISCSITargetWMIException( @@ -330,7 +325,7 @@ class ISCSITargetUtils(baseutils.BaseUtils): fail_if_not_found=False) if wt_snapshot: wt_snapshot.Delete_() - except wmi.x_wmi as wmi_exc: + except exceptions.x_wmi as wmi_exc: err_msg = _('Failed delete snapshot %s.') raise exceptions.ISCSITargetWMIException(err_msg % snapshot_name, wmi_exc=wmi_exc)