Пример #1
0
class ZadaraVPSADriverTestCase(test.TestCase):
    """Test case for Zadara VPSA volume driver."""

    def setUp(self):
        LOG.debug('Enter: setUp')
        super(ZadaraVPSADriverTestCase, self).setUp()

        global RUNTIME_VARS
        RUNTIME_VARS = copy.deepcopy(DEFAULT_RUNTIME_VARS)

        self.configuration = conf.Configuration(None)
        self.configuration.append_config_values(zadara_opts)
        self.configuration.reserved_percentage = 10
        self.configuration.zadara_user = '******'
        self.configuration.zadara_password = '******'
        self.configuration.zadara_vpsa_poolname = 'pool-0001'

        self.driver = ZadaraVPSAISCSIDriver(configuration=self.configuration)
        self.stubs.Set(httplib, 'HTTPConnection', FakeHTTPConnection)
        self.stubs.Set(httplib, 'HTTPSConnection', FakeHTTPSConnection)
        self.driver.do_setup(None)

    def tearDown(self):
        super(ZadaraVPSADriverTestCase, self).tearDown()

    def test_create_destroy(self):
        """Create/Delete volume."""
        volume = {'name': 'test_volume_01', 'size': 1}
        self.driver.create_volume(volume)
        self.driver.delete_volume(volume)

    def test_create_destroy_multiple(self):
        """Create/Delete multiple volumes."""
        self.flags(zadara_vpsa_allow_nonexistent_delete=False)
        self.driver.create_volume({'name': 'test_volume_01', 'size': 1})
        self.driver.create_volume({'name': 'test_volume_02', 'size': 2})
        self.driver.create_volume({'name': 'test_volume_03', 'size': 3})
        self.driver.delete_volume({'name': 'test_volume_02'})
        self.driver.delete_volume({'name': 'test_volume_03'})
        self.driver.delete_volume({'name': 'test_volume_01'})

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.delete_volume,
                          {'name': 'test_volume_04'})
        self.flags(zadara_vpsa_allow_nonexistent_delete=True)
        self.driver.delete_volume({'name': 'test_volume_04'})

    def test_destroy_non_existent(self):
        """Delete non-existent volume."""
        self.flags(zadara_vpsa_allow_nonexistent_delete=False)
        volume = {'name': 'test_volume_02', 'size': 1}
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.delete_volume,
                          volume)
        self.flags(zadara_vpsa_allow_nonexistent_delete=True)

    def test_empty_apis(self):
        """Test empty func (for coverage only)."""
        context = None
        volume = {'name': 'test_volume_01', 'size': 1}
        self.driver.create_export(context, volume)
        self.driver.ensure_export(context, volume)
        self.driver.remove_export(context, volume)

        self.assertRaises(NotImplementedError,
                          self.driver.local_path,
                          None)

        self.driver.check_for_setup_error()

    def test_volume_attach_detach(self):
        """Test volume attachment and detach."""
        volume = {'name': 'test_volume_01', 'size': 1, 'id': 123}
        connector = dict(initiator='test_iqn.1')

        self.driver.create_volume(volume)

        props = self.driver.initialize_connection(volume, connector)
        self.assertEqual(props['driver_volume_type'], 'iscsi')
        data = props['data']
        self.assertEqual(data['target_portal'], '1.1.1.1:3260')
        self.assertEqual(data['target_iqn'],
                         'iqn.2011-04.com.zadarastorage:vsa-xxx:1')
        self.assertEqual(data['target_lun'], '0')
        self.assertEqual(data['volume_id'], 123)
        self.assertEqual(data['auth_method'], 'CHAP')
        self.assertEqual(data['auth_username'], 'test_chap_user')
        self.assertEqual(data['auth_password'], 'test_chap_secret')

        self.driver.terminate_connection(volume, connector)
        self.driver.delete_volume(volume)

    def test_volume_attach_multiple_detach(self):
        """Test multiple volume attachment and detach."""
        volume = {'name': 'test_volume_01', 'size': 1, 'id': 123}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.driver.create_volume(volume)
        props1 = self.driver.initialize_connection(volume, connector1)
        props2 = self.driver.initialize_connection(volume, connector2)
        props3 = self.driver.initialize_connection(volume, connector3)

        self.driver.terminate_connection(volume, connector1)
        self.driver.terminate_connection(volume, connector3)
        self.driver.terminate_connection(volume, connector2)
        self.driver.delete_volume(volume)

    def test_wrong_attach_params(self):
        """Test different wrong attach scenarios."""
        volume1 = {'name': 'test_volume_01', 'size': 1, 'id': 101}
        volume2 = {'name': 'test_volume_02', 'size': 1, 'id': 102}
        volume3 = {'name': 'test_volume_03', 'size': 1, 'id': 103}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.initialize_connection,
                          volume1, connector1)

    def test_wrong_detach_params(self):
        """Test different wrong detachment scenarios."""

        volume1 = {'name': 'test_volume_01', 'size': 1, 'id': 101}
        volume2 = {'name': 'test_volume_02', 'size': 1, 'id': 102}
        volume3 = {'name': 'test_volume_03', 'size': 1, 'id': 103}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.driver.create_volume(volume1)
        self.driver.create_volume(volume2)
        props1 = self.driver.initialize_connection(volume1, connector1)
        props2 = self.driver.initialize_connection(volume2, connector2)

        self.assertRaises(exception.ZadaraServerNotFound,
                          self.driver.terminate_connection,
                          volume1, connector3)
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.terminate_connection,
                          volume3, connector1)
        self.assertRaises(exception.FailedCmdWithDump,
                          self.driver.terminate_connection,
                          volume1, connector2)

    def test_wrong_login_reply(self):
        """Test wrong login reply."""

        RUNTIME_VARS['login'] = """<hash>
                    <access-key>%s</access-key>
                    <status type="integer">0</status>
                </hash>"""
        self.assertRaises(exception.MalformedResponse,
                          self.driver.do_setup, None)

        RUNTIME_VARS['login'] = """
            <hash>
                <user>
                    <updated-at type="datetime">2012-04-30...</updated-at>
                    <id type="integer">1</id>
                    <created-at type="datetime">2012-02-21...</created-at>
                    <email>[email protected]</email>
                    <username>jsmith</username>
                </user>
                <access-key>%s</access-key>
                <status type="integer">0</status>
            </hash>"""
        self.assertRaises(exception.MalformedResponse,
                          self.driver.do_setup, None)

    def test_ssl_use(self):
        """Coverage test for SSL connection."""
        self.flags(zadara_vpsa_use_ssl=True)
        self.driver.do_setup(None)
        self.flags(zadara_vpsa_use_ssl=False)

    def test_bad_http_response(self):
        """Coverage test for non-good HTTP response."""
        RUNTIME_VARS['status'] = 400

        volume = {'name': 'test_volume_01', 'size': 1}
        self.assertRaises(exception.BadHTTPResponseStatus,
                          self.driver.create_volume, volume)

    def test_delete_without_detach(self):
        """Test volume deletion without detach."""

        volume1 = {'name': 'test_volume_01', 'size': 1, 'id': 101}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.driver.create_volume(volume1)
        props1 = self.driver.initialize_connection(volume1, connector1)
        props2 = self.driver.initialize_connection(volume1, connector2)
        props3 = self.driver.initialize_connection(volume1, connector3)

        self.flags(zadara_vpsa_auto_detach_on_delete=False)
        self.assertRaises(exception.VolumeAttached,
                          self.driver.delete_volume, volume1)

        self.flags(zadara_vpsa_auto_detach_on_delete=True)
        self.driver.delete_volume(volume1)

    def test_no_active_ctrl(self):

        RUNTIME_VARS['controllers'] = []

        volume = {'name': 'test_volume_01', 'size': 1, 'id': 123}
        connector = dict(initiator='test_iqn.1')

        self.driver.create_volume(volume)
        self.assertRaises(exception.ZadaraVPSANoActiveController,
                          self.driver.initialize_connection,
                          volume, connector)

    def test_create_destroy_snapshot(self):
        """Create/Delete snapshot test."""
        volume = {'name': 'test_volume_01', 'size': 1}
        snapshot = {'name': 'snap_01',
                    'volume_name': volume['name']}

        self.driver.create_volume(volume)

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_snapshot,
                          {'name': snapshot['name'],
                           'volume_name': 'wrong_vol'})

        self.driver.create_snapshot(snapshot)

        # Deleted should succeed for missing volume
        self.driver.delete_snapshot({'name': snapshot['name'],
                                     'volume_name': 'wrong_vol'})
        # Deleted should succeed for missing snap
        self.driver.delete_snapshot({'name': 'wrong_snap',
                                     'volume_name': volume['name']})

        self.driver.delete_snapshot(snapshot)
        self.driver.delete_volume(volume)

    def test_expand_volume(self):
        """Expand volume test."""
        volume = {'name': 'test_volume_01', 'size': 10}
        volume2 = {'name': 'test_volume_02', 'size': 10}

        self.driver.create_volume(volume)

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.extend_volume,
                          volume2, 15)
        self.assertRaises(exception.InvalidInput,
                          self.driver.extend_volume,
                          volume, 5)

        self.driver.extend_volume(volume, 15)
        self.driver.delete_volume(volume)

    def test_create_destroy_clones(self):
        """Create/Delete clones test."""
        volume1 = {'name': 'test_volume_01', 'size': 1}
        volume2 = {'name': 'test_volume_02', 'size': 1}
        volume3 = {'name': 'test_volume_03', 'size': 1}
        snapshot = {'name': 'snap_01',
                    'volume_name': volume1['name']}

        self.driver.create_volume(volume1)
        self.driver.create_snapshot(snapshot)

        # Test invalid vol reference
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_volume_from_snapshot,
                          volume2,
                          {'name': snapshot['name'],
                           'volume_name': 'wrong_vol'})
        # Test invalid snap reference
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_volume_from_snapshot,
                          volume2,
                          {'name': 'wrong_snap',
                           'volume_name': snapshot['volume_name']})
        # Test invalid src_vref for volume clone
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_cloned_volume,
                          volume3, volume2)

        self.driver.create_volume_from_snapshot(volume2, snapshot)
        self.driver.create_cloned_volume(volume3, volume1)

        self.driver.delete_volume(volume3)
        self.driver.delete_volume(volume2)
        self.driver.delete_snapshot(snapshot)
        self.driver.delete_volume(volume1)

    def test_get_volume_stats(self):
        """Get stats test."""

        self.mox.StubOutWithMock(self.configuration, 'safe_get')
        self.configuration.safe_get('volume_backend_name'). \
            AndReturn('ZadaraVPSAISCSIDriver')
        self.mox.ReplayAll()

        data = self.driver.get_volume_stats(True)

        self.assertEqual(data['vendor_name'], 'Zadara Storage')
        self.assertEqual(data['total_capacity_gb'], 'infinite')
        self.assertEqual(data['free_capacity_gb'], 'infinite')

        self.assertEqual(data,
                         {'total_capacity_gb': 'infinite',
                          'free_capacity_gb': 'infinite',
                          'reserved_percentage':
                          self.configuration.reserved_percentage,
                          'QoS_support': False,
                          'vendor_name': 'Zadara Storage',
                          'driver_version': self.driver.VERSION,
                          'storage_protocol': 'iSCSI',
                          'volume_backend_name': 'ZadaraVPSAISCSIDriver',
                          })
Пример #2
0
class ZadaraVPSADriverTestCase(test.TestCase):
    """Test case for Zadara VPSA volume driver."""

    def setUp(self):
        LOG.debug('Enter: setUp')
        super(ZadaraVPSADriverTestCase, self).setUp()

        global RUNTIME_VARS
        RUNTIME_VARS = copy.deepcopy(DEFAULT_RUNTIME_VARS)

        self.configuration = conf.Configuration(None)
        self.configuration.append_config_values(zadara_opts)
        self.configuration.reserved_percentage = 10
        self.configuration.zadara_user = '******'
        self.configuration.zadara_password = '******'
        self.configuration.zadara_vpsa_poolname = 'pool-0001'

        self.driver = ZadaraVPSAISCSIDriver(configuration=self.configuration)
        self.stubs.Set(httplib, 'HTTPConnection', FakeHTTPConnection)
        self.stubs.Set(httplib, 'HTTPSConnection', FakeHTTPSConnection)
        self.driver.do_setup(None)

    def tearDown(self):
        super(ZadaraVPSADriverTestCase, self).tearDown()

    def test_create_destroy(self):
        """Create/Delete volume."""
        volume = {'name': 'test_volume_01', 'size': 1}
        self.driver.create_volume(volume)
        self.driver.delete_volume(volume)

    def test_create_destroy_multiple(self):
        """Create/Delete multiple volumes."""
        self.flags(zadara_vpsa_allow_nonexistent_delete=False)
        self.driver.create_volume({'name': 'test_volume_01', 'size': 1})
        self.driver.create_volume({'name': 'test_volume_02', 'size': 2})
        self.driver.create_volume({'name': 'test_volume_03', 'size': 3})
        self.driver.delete_volume({'name': 'test_volume_02'})
        self.driver.delete_volume({'name': 'test_volume_03'})
        self.driver.delete_volume({'name': 'test_volume_01'})

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.delete_volume,
                          {'name': 'test_volume_04'})
        self.flags(zadara_vpsa_allow_nonexistent_delete=True)
        self.driver.delete_volume({'name': 'test_volume_04'})

    def test_destroy_non_existent(self):
        """Delete non-existent volume."""
        self.flags(zadara_vpsa_allow_nonexistent_delete=False)
        volume = {'name': 'test_volume_02', 'size': 1}
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.delete_volume,
                          volume)
        self.flags(zadara_vpsa_allow_nonexistent_delete=True)

    def test_empty_apis(self):
        """Test empty func (for coverage only)."""
        context = None
        volume = {'name': 'test_volume_01', 'size': 1}
        self.driver.create_export(context, volume)
        self.driver.ensure_export(context, volume)
        self.driver.remove_export(context, volume)

        self.assertRaises(NotImplementedError,
                          self.driver.local_path,
                          None)

        self.driver.check_for_setup_error()

    def test_volume_attach_detach(self):
        """Test volume attachment and detach."""
        volume = {'name': 'test_volume_01', 'size': 1, 'id': 123}
        connector = dict(initiator='test_iqn.1')

        self.driver.create_volume(volume)

        props = self.driver.initialize_connection(volume, connector)
        self.assertEqual(props['driver_volume_type'], 'iscsi')
        data = props['data']
        self.assertEqual(data['target_portal'], '1.1.1.1:3260')
        self.assertEqual(data['target_iqn'],
                         'iqn.2011-04.com.zadarastorage:vsa-xxx:1')
        self.assertEqual(data['target_lun'], '0')
        self.assertEqual(data['volume_id'], 123)
        self.assertEqual(data['auth_method'], 'CHAP')
        self.assertEqual(data['auth_username'], 'test_chap_user')
        self.assertEqual(data['auth_password'], 'test_chap_secret')

        self.driver.terminate_connection(volume, connector)
        self.driver.delete_volume(volume)

    def test_volume_attach_multiple_detach(self):
        """Test multiple volume attachment and detach."""
        volume = {'name': 'test_volume_01', 'size': 1, 'id': 123}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.driver.create_volume(volume)
        props1 = self.driver.initialize_connection(volume, connector1)
        props2 = self.driver.initialize_connection(volume, connector2)
        props3 = self.driver.initialize_connection(volume, connector3)

        self.driver.terminate_connection(volume, connector1)
        self.driver.terminate_connection(volume, connector3)
        self.driver.terminate_connection(volume, connector2)
        self.driver.delete_volume(volume)

    def test_wrong_attach_params(self):
        """Test different wrong attach scenarios."""
        volume1 = {'name': 'test_volume_01', 'size': 1, 'id': 101}
        volume2 = {'name': 'test_volume_02', 'size': 1, 'id': 102}
        volume3 = {'name': 'test_volume_03', 'size': 1, 'id': 103}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.initialize_connection,
                          volume1, connector1)

    def test_wrong_detach_params(self):
        """Test different wrong detachment scenarios."""

        volume1 = {'name': 'test_volume_01', 'size': 1, 'id': 101}
        volume2 = {'name': 'test_volume_02', 'size': 1, 'id': 102}
        volume3 = {'name': 'test_volume_03', 'size': 1, 'id': 103}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.driver.create_volume(volume1)
        self.driver.create_volume(volume2)
        props1 = self.driver.initialize_connection(volume1, connector1)
        props2 = self.driver.initialize_connection(volume2, connector2)

        self.assertRaises(exception.ZadaraServerNotFound,
                          self.driver.terminate_connection,
                          volume1, connector3)
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.terminate_connection,
                          volume3, connector1)
        self.assertRaises(exception.FailedCmdWithDump,
                          self.driver.terminate_connection,
                          volume1, connector2)

    def test_wrong_login_reply(self):
        """Test wrong login reply."""

        RUNTIME_VARS['login'] = """<hash>
                    <access-key>%s</access-key>
                    <status type="integer">0</status>
                </hash>"""
        self.assertRaises(exception.MalformedResponse,
                          self.driver.do_setup, None)

        RUNTIME_VARS['login'] = """
            <hash>
                <user>
                    <updated-at type="datetime">2012-04-30...</updated-at>
                    <id type="integer">1</id>
                    <created-at type="datetime">2012-02-21...</created-at>
                    <email>[email protected]</email>
                    <username>jsmith</username>
                </user>
                <access-key>%s</access-key>
                <status type="integer">0</status>
            </hash>"""
        self.assertRaises(exception.MalformedResponse,
                          self.driver.do_setup, None)

    def test_ssl_use(self):
        """Coverage test for SSL connection."""
        self.flags(zadara_vpsa_use_ssl=True)
        self.driver.do_setup(None)
        self.flags(zadara_vpsa_use_ssl=False)

    def test_bad_http_response(self):
        """Coverage test for non-good HTTP response."""
        RUNTIME_VARS['status'] = 400

        volume = {'name': 'test_volume_01', 'size': 1}
        self.assertRaises(exception.BadHTTPResponseStatus,
                          self.driver.create_volume, volume)

    def test_delete_without_detach(self):
        """Test volume deletion without detach."""

        volume1 = {'name': 'test_volume_01', 'size': 1, 'id': 101}
        connector1 = dict(initiator='test_iqn.1')
        connector2 = dict(initiator='test_iqn.2')
        connector3 = dict(initiator='test_iqn.3')

        self.driver.create_volume(volume1)
        props1 = self.driver.initialize_connection(volume1, connector1)
        props2 = self.driver.initialize_connection(volume1, connector2)
        props3 = self.driver.initialize_connection(volume1, connector3)

        self.flags(zadara_vpsa_auto_detach_on_delete=False)
        self.assertRaises(exception.VolumeAttached,
                          self.driver.delete_volume, volume1)

        self.flags(zadara_vpsa_auto_detach_on_delete=True)
        self.driver.delete_volume(volume1)

    def test_no_active_ctrl(self):

        RUNTIME_VARS['controllers'] = []

        volume = {'name': 'test_volume_01', 'size': 1, 'id': 123}
        connector = dict(initiator='test_iqn.1')

        self.driver.create_volume(volume)
        self.assertRaises(exception.ZadaraVPSANoActiveController,
                          self.driver.initialize_connection,
                          volume, connector)

    def test_create_destroy_snapshot(self):
        """Create/Delete snapshot test."""
        volume = {'name': 'test_volume_01', 'size': 1}
        snapshot = {'name': 'snap_01',
                    'volume_name': volume['name']}

        self.driver.create_volume(volume)

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_snapshot,
                          {'name': snapshot['name'],
                           'volume_name': 'wrong_vol'})

        self.driver.create_snapshot(snapshot)

        # Deleted should succeed for missing volume
        self.driver.delete_snapshot({'name': snapshot['name'],
                                     'volume_name': 'wrong_vol'})
        # Deleted should succeed for missing snap
        self.driver.delete_snapshot({'name': 'wrong_snap',
                                     'volume_name': volume['name']})

        self.driver.delete_snapshot(snapshot)
        self.driver.delete_volume(volume)

    def test_expand_volume(self):
        """Expand volume test."""
        volume = {'name': 'test_volume_01', 'size': 10}
        volume2 = {'name': 'test_volume_02', 'size': 10}

        self.driver.create_volume(volume)

        self.assertRaises(exception.VolumeNotFound,
                          self.driver.extend_volume,
                          volume2, 15)
        self.assertRaises(exception.InvalidInput,
                          self.driver.extend_volume,
                          volume, 5)

        self.driver.extend_volume(volume, 15)
        self.driver.delete_volume(volume)

    def test_create_destroy_clones(self):
        """Create/Delete clones test."""
        volume1 = {'name': 'test_volume_01', 'size': 1}
        volume2 = {'name': 'test_volume_02', 'size': 1}
        volume3 = {'name': 'test_volume_03', 'size': 1}
        snapshot = {'name': 'snap_01',
                    'volume_name': volume1['name']}

        self.driver.create_volume(volume1)
        self.driver.create_snapshot(snapshot)

        # Test invalid vol reference
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_volume_from_snapshot,
                          volume2,
                          {'name': snapshot['name'],
                           'volume_name': 'wrong_vol'})
        # Test invalid snap reference
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_volume_from_snapshot,
                          volume2,
                          {'name': 'wrong_snap',
                           'volume_name': snapshot['volume_name']})
        # Test invalid src_vref for volume clone
        self.assertRaises(exception.VolumeNotFound,
                          self.driver.create_cloned_volume,
                          volume3, volume2)

        self.driver.create_volume_from_snapshot(volume2, snapshot)
        self.driver.create_cloned_volume(volume3, volume1)

        self.driver.delete_volume(volume3)
        self.driver.delete_volume(volume2)
        self.driver.delete_snapshot(snapshot)
        self.driver.delete_volume(volume1)

    def test_get_volume_stats(self):
        """Get stats test."""

        self.mox.StubOutWithMock(self.configuration, 'safe_get')
        self.configuration.safe_get('volume_backend_name'). \
            AndReturn('ZadaraVPSAISCSIDriver')
        self.mox.ReplayAll()

        data = self.driver.get_volume_stats(True)

        self.assertEqual(data['vendor_name'], 'Zadara Storage')
        self.assertEqual(data['total_capacity_gb'], 'infinite')
        self.assertEqual(data['free_capacity_gb'], 'infinite')

        self.assertEqual(data,
                         {'total_capacity_gb': 'infinite',
                          'free_capacity_gb': 'infinite',
                          'reserved_percentage':
                          self.configuration.reserved_percentage,
                          'QoS_support': False,
                          'vendor_name': 'Zadara Storage',
                          'driver_version': self.driver.VERSION,
                          'storage_protocol': 'iSCSI',
                          'volume_backend_name': 'ZadaraVPSAISCSIDriver',
                          })