Beispiel #1
0
    def test_extend_volume(self, mock_rescan, mock_active_vioses):
        self.vol_drv._set_udid("vstor_uuid")
        mock_vios = mock.Mock(uuid='fake_uuid')
        # Test single vios
        mock_active_vioses.return_value = [mock_vios]
        self.vol_drv.extend_volume()
        mock_rescan.assert_called_once_with(self.vol_drv.vios_uuids[0],
                                            "vstor_uuid", self.adpt)
        mock_rescan.side_effect = pvm_exc.JobRequestFailed(
            operation_name='RescanVirtualDisk', error='fake_err')
        self.assertRaises(p_exc.VolumeExtendFailed, self.vol_drv.extend_volume)
        mock_rescan.side_effect = pvm_exc.VstorNotFound(stor_udid='stor_udid',
                                                        vios_uuid='uuid')
        self.assertRaises(p_exc.VolumeExtendFailed, self.vol_drv.extend_volume)

        # Test multiple vios
        mock_active_vioses.return_value = [mock_vios, mock_vios]
        mock_rescan.reset_mock()
        mock_rescan.side_effect = [
            pvm_exc.JobRequestFailed(operation_name='RescanVirtualDisk',
                                     error='fake_err'), None
        ]
        self.assertRaises(p_exc.VolumeExtendFailed, self.vol_drv.extend_volume)
        self.assertEqual(2, mock_rescan.call_count)
        mock_rescan.reset_mock()
        mock_rescan.side_effect = [
            None,
            pvm_exc.VstorNotFound(stor_udid='stor_udid', vios_uuid='uuid')
        ]
        self.vol_drv.extend_volume()
        self.assertEqual(2, mock_rescan.call_count)

        self.vol_drv._set_udid(None)
        self.assertRaises(nova_exc.InvalidBDM, self.vol_drv.extend_volume)
Beispiel #2
0
    def run_job(self,
                uuid,
                job_parms=None,
                timeout=CONF.pypowervm_job_request_timeout,
                sensitive=False,
                synchronous=True):
        """Invokes and polls a job.

        Adds job parameters to the job element if specified and calls the
        create_job method. It then monitors the job for completion and sends a
        JobRequestFailed exception if it did not complete successfully.

        :param uuid: uuid of the target
        :param job_parms: list of JobParamters to add
        :param timeout: maximum number of seconds for job to complete
        :param sensitive: If True, mask the Job payload in the logs.
        :param synchronous: If True (the default), wait for the Job to complete
                            or time out.  If False, return as soon as the Job
                            starts.  Note that this may still involve polling
                            (if the Job is waiting in queue to start), and may
                            still time out (if the Job hasn't started within
                            the requested timeout.)
        :raise JobRequestFailed: if the job did not complete successfully.
        :raise JobRequestTimedOut: if the job timed out.
        """
        if job_parms:
            self.add_job_parameters_to_existing(*job_parms)
        try:
            self.entry = self.adapter.create_job(
                self.entry.element,
                self._get_val_str(_JOB_GROUP_NAME),
                uuid,
                sensitive=sensitive).entry
        except pvmex.Error as exc:
            LOG.exception(exc)
            raise pvmex.JobRequestFailed(operation_name=self.op, error=exc)
        timed_out = self._monitor_job(timeout=timeout,
                                      sensitive=sensitive,
                                      synchronous=synchronous)
        if timed_out:
            try:
                self.cancel_job()
            except pvmex.JobRequestFailed as e:
                LOG.warn(six.text_type(e))
            exc = pvmex.JobRequestTimedOut(operation_name=self.op,
                                           seconds=timeout)
            LOG.error(exc.args[0])
            raise exc
        if not synchronous:
            # _monitor_job spawned a subthread that will delete_job when done.
            return
        self.delete_job()
        if self.job_status != JobStatus.COMPLETED_OK:
            exc = pvmex.JobRequestFailed(operation_name=self.op,
                                         error=self.get_job_message(''))
            LOG.error(exc.args[0])
            raise exc
Beispiel #3
0
    def test_connect_volume_job_fail(self, mock_get_vm_id, mock_discover):
        mock_get_vm_id.return_value = '2'
        mock_discover.side_effect = pvm_exc.JobRequestFailed(
            operation_name='ISCSIDiscovery', error='fake_err')

        # Run the method
        self.assertRaises(p_exc.VolumeAttachFailed,
                          self.multi_vol_drv.connect_volume, self.slot_mgr)
Beispiel #4
0
 def run(self):
     self.job.poll_while_status([JobStatus.RUNNING], 0, self.sensitive)
     self.job.delete_job()
     # If the Job failed, we still want to log it.
     if self.job.job_status != JobStatus.COMPLETED_OK:
         exc = pvmex.JobRequestFailed(operation_name=self.job.op,
                                      error=self.job.get_job_message())
         LOG.error(exc.args[0])
Beispiel #5
0
 def test_extend_volume(self, mock_rescan, mock_get_mgmt_partition):
     # FileIO driver can only have 1 uuid in vol_drv.vios_uuids
     mock_vios = mock.Mock(uuid='uuid1')
     mock_get_mgmt_partition.return_value = mock_vios
     self.vol_drv.extend_volume()
     mock_rescan.assert_called_once_with(self.vol_drv.vios_uuids[0],
                                         "fake_path", adapter=self.adpt)
     mock_rescan.side_effect = pvm_exc.JobRequestFailed(
         operation_name='RescanVirtualDisk', error='fake_err')
     self.assertRaises(p_exc.VolumeExtendFailed, self.vol_drv.extend_volume)
     mock_rescan.side_effect = pvm_exc.VstorNotFound(
         stor_udid='stor_udid', vios_uuid='uuid')
     self.assertRaises(p_exc.VolumeExtendFailed, self.vol_drv.extend_volume)
Beispiel #6
0
    def get_job_resp_exception_msg(self, default=''):
        """Gets the job message string from the ResponseException.

        :returns: String containing the job message or
                  default (defaults to empty string) if not found
        """
        job_message = self._get_val_str(_JOB_MESSAGE, default)
        if job_message:
            # See if there is a stack trace to log
            stack_trace = self._get_val_str(_JOB_STACKTRACE, default)
            if stack_trace:
                LOG.error(pvmex.JobRequestFailed(operation_name=self.op,
                                                 error=stack_trace))
        return job_message
Beispiel #7
0
 def test_force_immed_no_retry(self, mock_vios, mock_run_job):
     """With force_immediate=NO_RETRY, errors don't retry."""
     mock_vios.adapter = self.adpt
     mock_vios.rmc_state = pvm_bp.RMCState.ACTIVE
     for exc in (pexc.JobRequestFailed(error='e', operation_name='op'),
                 pexc.JobRequestTimedOut(operation_name='op', seconds=60)):
         mock_run_job.side_effect = exc
         self.assertRaises(pexc.VMPowerOffFailure,
                           power.power_off,
                           mock_vios,
                           'huuid',
                           force_immediate=power.Force.NO_RETRY)
         self.assertEqual(1, mock_run_job.call_count)
         mock_run_job.reset_mock()
Beispiel #8
0
    def test_power_on_syson_vios(self, mock_vios, mock_job_p, mock_run_job):
        """Validates a power on job when system is already on."""
        mock_vios.adapter = self.adpt
        mock_vios.rmc_state = pvm_bp.RMCState.ACTIVE
        for err_prefix in power._ALREADY_POWERED_ON_ERRS:
            mock_run_job.reset_mock()
            mock_run_job.side_effect = pexc.JobRequestFailed(
                error='PowerOn', operation_name=err_prefix)

            # Invoke the run the job, but succeed because it is already
            # powered on
            power._power_on_off(mock_vios, 'PowerOn', '1111')

            # This specific error should cause a retry.
            self.assertEqual(1, mock_run_job.call_count)
Beispiel #9
0
    def test_power_off_job_failure(self, mock_lpar, mock_job_p, mock_run_job):
        """Validates a power off job request failure."""
        mock_lpar.adapter = self.adpt
        mock_lpar.rmc_state = pvm_bp.RMCState.ACTIVE
        for rmc_err_prefix in power._OSSHUTDOWN_RMC_ERRS:
            mock_run_job.reset_mock()
            mock_run_job.side_effect = pexc.JobRequestFailed(
                error='PowerOff', operation_name=rmc_err_prefix)

            # Invoke the run, should power off graceful, fail, then force off
            # and fail again.
            self.assertRaises(pexc.VMPowerOffFailure, power._power_on_off,
                              mock_lpar, 'PowerOff', '1111')

        # It should have been called three times: one for the os shutdown,
        # one for vsp normal power off,
        # and another for the immediate power off
        self.assertEqual(3, mock_run_job.call_count)
Beispiel #10
0
 def efail(error='error'):
     """Returns a JobRequestFailed exception."""
     return pexc.JobRequestFailed(operation_name='foo', error=error)
Beispiel #11
0
    def test_get_iscsi_initiators(self, mock_iscsi_init, mock_active_vioses):
        # Set up mocks and clear out data that may have been set by other
        # tests
        iscsi._ISCSI_INITIATORS = dict()
        mock_iscsi_init.return_value = 'test_initiator'

        vios_ids = [
            '1300C76F-9814-4A4D-B1F0-5B69352A7DEA',
            '7DBBE705-E4C4-4458-8223-3EBE07015CA9'
        ]
        vios0 = mock.Mock(uuid=vios_ids[0])
        vios1 = mock.Mock(uuid=vios_ids[1])
        mock_active_vioses.return_value = [vios0, vios1]

        expected_output = {
            '1300C76F-9814-4A4D-B1F0-5B69352A7DEA': 'test_initiator',
            '7DBBE705-E4C4-4458-8223-3EBE07015CA9': 'test_initiator'
        }

        self.assertEqual(expected_output,
                         iscsi.get_iscsi_initiators(self.adpt, vios_ids))

        # Make sure it gets set properly in the backend
        self.assertEqual(expected_output, iscsi._ISCSI_INITIATORS)
        self.assertEqual(mock_active_vioses.call_count, 0)
        self.assertEqual(mock_iscsi_init.call_count, 2)

        # Invoke again, make sure it doesn't call down to the mgmt part again
        mock_iscsi_init.reset_mock()
        self.assertEqual(expected_output,
                         iscsi.get_iscsi_initiators(self.adpt, vios_ids))
        self.assertEqual(mock_active_vioses.call_count, 0)
        self.assertEqual(mock_iscsi_init.call_count, 0)

        # Invoke iscsi.get_iscsi_initiators with vios_id=None
        iscsi._ISCSI_INITIATORS = dict()
        mock_iscsi_init.reset_mock()
        self.assertEqual(expected_output,
                         iscsi.get_iscsi_initiators(self.adpt, None))
        self.assertEqual(expected_output, iscsi._ISCSI_INITIATORS)
        self.assertEqual(mock_active_vioses.call_count, 1)
        self.assertEqual(mock_iscsi_init.call_count, 2)

        # Invoke again with vios_id=None to ensure get_active_vioses,
        # discover_iscsi_initiator is not called
        mock_iscsi_init.reset_mock()
        mock_active_vioses.reset_mock()
        self.assertEqual(expected_output,
                         iscsi.get_iscsi_initiators(self.adpt, None))
        self.assertEqual(mock_active_vioses.call_count, 0)
        self.assertEqual(mock_iscsi_init.call_count, 0)

        # Invoke iscsi.get_iscsi_initiators with discover_iscsi_initiator()
        # raises ISCSIDiscoveryFailed exception
        iscsi._ISCSI_INITIATORS = dict()
        mock_iscsi_init.reset_mock()
        mock_iscsi_init.side_effect = pvm_exc.ISCSIDiscoveryFailed(
            vios_uuid='fake_vios_uid', status="fake_status")
        self.assertEqual(dict(),
                         iscsi.get_iscsi_initiators(self.adpt, vios_ids))
        self.assertEqual(dict(), iscsi._ISCSI_INITIATORS)

        # Invoke iscsi.get_iscsi_initiators with discover_iscsi_initiator()
        # raises JobRequestFailed exception
        iscsi._ISCSI_INITIATORS = dict()
        mock_iscsi_init.reset_mock()
        mock_iscsi_init.side_effect = pvm_exc.JobRequestFailed(
            operation_name='fake_operation_name', error="fake_error")
        self.assertEqual(dict(),
                         iscsi.get_iscsi_initiators(self.adpt, vios_ids))
        self.assertEqual(dict(), iscsi._ISCSI_INITIATORS)
Beispiel #12
0
    def test_discover_iscsi(self, mock_job_res, mock_job_p, mock_run_job,
                            mock_job_w):
        mock_job_w.return_value = self.mock_job
        mock_host_ip = '10.0.0.1:3290'
        mock_user = '******'
        mock_pass = '******'
        mock_iqn = 'fake_iqn'
        mock_uuid = 'uuid'
        mock_iface_name = 'iface_name'
        args = ['VirtualIOServer', mock_uuid]
        kwargs = {'suffix_type': 'do', 'suffix_parm': 'ISCSIDiscovery'}
        mock_job_res.return_value = {'DEV_OUTPUT': '["fake_iqn devName udid"]',
                                     'RETURN_CODE': '0'}
        device_name, udid = iscsi.discover_iscsi(
            self.adpt, mock_host_ip, mock_user, mock_pass, mock_iqn, mock_uuid,
            iface_name=mock_iface_name)

        self.adpt.read.assert_called_once_with(*args, **kwargs)
        self.assertEqual('devName', device_name)
        self.assertEqual('udid', udid)
        self.assertEqual(1, mock_run_job.call_count)
        mock_job_p.assert_has_calls([
            mock.call('hostIP', mock_host_ip), mock.call('user', mock_user),
            mock.call('password', mock_pass), mock.call('targetIQN', mock_iqn),
            mock.call('ifaceName', mock_iface_name),
            mock.call('multipath', str(False))], any_order=True)
        self.assertEqual(6, mock_job_p.call_count)

        # Test for lunid
        mock_job_p.reset_mock()
        mock_lunid = 2
        mock_job_res.return_value = {'DEV_OUTPUT': '["fake_iqn devName udid"]',
                                     'RETURN_CODE': '15'}
        device_name, udid = iscsi.discover_iscsi(
            self.adpt, mock_host_ip, mock_user, mock_pass, mock_iqn, mock_uuid,
            iface_name=mock_iface_name, lunid=mock_lunid)
        self.assertEqual(7, mock_job_p.call_count)
        mock_job_p.assert_any_call('targetLUN', str(mock_lunid))

        mock_job_res.return_value = {'DEV_OUTPUT': '["fake_iqn devName udid"]',
                                     'RETURN_CODE': '8'}
        self.assertRaises(pexc.ISCSIDiscoveryFailed, iscsi.discover_iscsi,
                          self.adpt, mock_host_ip, mock_user, mock_pass,
                          mock_iqn, mock_uuid, iface_name=mock_iface_name)

        # Check named args
        mock_job_p.reset_mock()
        mock_arg = mock.MagicMock()
        mock_job_res.return_value = {'DEV_OUTPUT': '["fake_iqn devName udid"]',
                                     'RETURN_CODE': '0'}

        device_name, udid = iscsi.discover_iscsi(
            self.adpt, mock_host_ip, mock_user, mock_pass, mock_iqn, mock_uuid,
            iface_name=mock_iface_name, lunid=mock_lunid, auth=mock_arg,
            discovery_auth=mock_arg, discovery_username=mock_arg,
            discovery_password=mock_arg, multipath=True)
        self.assertEqual('devName', device_name)
        self.assertEqual('udid', udid)

        # Check JobRequestFailed exception
        mock_run_job.side_effect = pexc.JobRequestFailed(
            operation_name='iscsi-discover', error='error')
        mock_job_res.return_value = {}
        self.assertRaises(pexc.JobRequestFailed, iscsi.discover_iscsi,
                          self.adpt, mock_host_ip, mock_user, mock_pass,
                          mock_iqn, mock_uuid, iface_name=mock_iface_name)
Beispiel #13
0
    def test_power_off_timeout_retry(self, mock_lpar, mock_job_p,
                                     mock_run_job):
        """Validate that when first power off times out, re-run."""
        mock_lpar.adapter = self.adpt
        mock_lpar.rmc_state = pvm_bp.RMCState.ACTIVE
        mock_run_job.side_effect = pexc.JobRequestTimedOut(
            operation_name='PowerOff', seconds=60)

        # Invoke the run, should power off graceful, fail, then force off
        # and fail again.
        self.assertRaises(pexc.VMPowerOffFailure, power._power_on_off,
                          mock_lpar, 'PowerOff', '1111')

        # It should have been called twice, once for the elegant power
        # off, and another for the immediate power off
        self.assertEqual(2, mock_run_job.call_count)
        mock_job_p.assert_has_calls([
            mock.call('operation', 'osshutdown'),
            mock.call('immediate', 'true'),
            mock.call('operation', 'shutdown'),
            mock.call('immediate', 'true')
        ])

        # Try a timedout only for the 2nd and 3rd job
        mock_run_job.reset_mock()
        mock_job_p.reset_mock()
        rmc_error = power._OSSHUTDOWN_RMC_ERRS[0]
        mock_run_job.side_effect = [
            pexc.JobRequestFailed(error='PowerOff', operation_name=rmc_error),
            pexc.JobRequestTimedOut(operation_name='PowerOff', seconds=60),
            pexc.JobRequestTimedOut(operation_name='PowerOff', seconds=60)
        ]

        self.assertRaises(pexc.VMPowerOffFailure, power._power_on_off,
                          mock_lpar, 'PowerOff', '1111')

        # It should have been called three times,
        # once for the immediate os shutdown, once for vsp normal,
        # and another time for vsp hard
        self.assertEqual(3, mock_run_job.call_count)
        mock_job_p.assert_has_calls([
            mock.call('operation', 'osshutdown'),
            mock.call('immediate', 'true'),
            mock.call('operation', 'shutdown'),
            mock.call('operation', 'shutdown'),
            mock.call('immediate', 'true')
        ])
        # Try IBMi
        mock_run_job.reset_mock()
        mock_job_p.reset_mock()
        mock_lpar.rmc_state = pvm_bp.RMCState.INACTIVE
        mock_lpar.env = pvm_bp.LPARType.OS400
        mock_lpar.ref_code = '00000000'
        mock_run_job.side_effect = pexc.JobRequestTimedOut(
            operation_name='PowerOff', seconds=60)

        self.assertRaises(pexc.VMPowerOffFailure, power._power_on_off,
                          mock_lpar, 'PowerOff', '1111')

        # It should have been called four times,
        # once for the normal os shutdown,
        # once for the immediate os shutdown, once for vsp normal,
        # and another time for vsp hard
        self.assertEqual(4, mock_run_job.call_count)
        mock_job_p.assert_has_calls([
            mock.call('operation', 'osshutdown'),
            mock.call('operation', 'osshutdown'),
            mock.call('immediate', 'true'),
            mock.call('operation', 'shutdown'),
            mock.call('operation', 'shutdown'),
            mock.call('immediate', 'true')
        ])