def setUp(self): # backup back_os_path_exists = os.path.exists self.addCleanup(self._restore, back_os_path_exists) super(EMCVNXCLIDriverISCSITestCase, self).setUp() self.configuration = conf.Configuration(None) self.configuration.append_config_values = mock.Mock(return_value=0) self.configuration.naviseccli_path = '/opt/Navisphere/bin/naviseccli' self.configuration.san_ip = '10.0.0.1' self.configuration.storage_vnx_pool_name = 'unit_test_pool' self.configuration.san_login = '******' self.configuration.san_password = '******' self.configuration.default_timeout = 0 self.testData = EMCVNXCLIDriverTestData() self.navisecclicmd = '/opt/Navisphere/bin/naviseccli ' + \ '-address 10.0.0.1 -user sysadmin -password sysadmin -scope 0 ' os.path.exists = mock.Mock(return_value=1) EMCVnxCli._cli_execute = mock.Mock(side_effect=self._fake_cli_executor) self.driver = EMCCLIISCSIDriver(configuration=self.configuration) self.driver.cli.wait_interval = 0
class EMCVNXCLIDriverISCSITestCase(test.TestCase): def _fake_cli_executor(self, *cmd, **kwargv): # mock cli if cmd == ("storagepool", "-list", "-name", "unit_test_pool", "-state"): return None, 0 elif cmd == ('storagepool', '-list', '-name', 'unit_test_pool', '-userCap', '-availableCap'): pool_details = "test\ntest\ntest\ntotal capacity:10000\n" + \ "test\nfree capacity:1000\ntest\ntest" return pool_details, 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'): return None, 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'failed_vol1'): return None, 1023 elif cmd == ('lun', '-create', '-type', 'Thin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'): return None, 0 elif cmd == ('lun', '-list', '-name', 'vol1'): return " 10\nReady", 0 elif cmd == ('lun', '-destroy', '-name', 'vol1', '-forceDetach', '-o'): return "Lun deleted successfully", 0 elif cmd == ('lun', '-destroy', '-name', 'failed_vol1', '-forceDetach', '-o'): return "Lun deleted successfully", 1023 elif cmd == ('lun', '-list', '-name', 'vol-vol1'): return " 16\n", 0 elif cmd == ('snap', '-create', '-res', '16', '-name', 'snapshot1', '-allowReadWrite', 'yes'): return "Create Snap successfully", 0 elif cmd == ('snap', '-create', '-res', '16', '-name', 'failed_snapshot', '-allowReadWrite', 'yes'): return "Create Snap failed", 1023 elif cmd == ('snap', '-destroy', '-id', 'snapshot1', '-o'): return "Delete Snap successfully", 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnapdest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnap_edest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap'): return "create mount point successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap_e'): return "create mount point successfully", 0 elif cmd == ('lun', '-attach', '-name', 'volfromsnap', '-snapName', 'snapshot1'): return None, 0 elif cmd == ('lun', '-attach', '-name', 'volfromsnap_e', '-snapName', 'snapshot1'): return None, 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap'): return " 10\n", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnapdest'): return " 101\n", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap_e'): return " 20\n", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap_edest'): return " 201\n", 0 elif cmd == ('migrate', '-start', '-source', '10', '-dest', '101', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('migrate', '-start', '-source', '20', '-dest', '201', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap', '-attachedSnapshot'): return "\n test \n :N/A", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap_e', '-attachedSnapshot'): return "\n test \n :N", 0 elif cmd == ('snap', '-create', '-res', '22', '-name', 'clone1src-temp-snapshot', '-allowReadWrite', 'yes'): return "Create Snap successfully", 0 elif cmd == ('lun', '-list', '-name', 'clone1src'): return " 22\n", 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1dest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1'): return "create mount point successfully", 0 elif cmd == ('lun', '-attach', '-name', 'clone1', '-snapName', 'clone1src-temp-snapshot'): return 'create temp snap successfully', 0 elif cmd == ('lun', '-list', '-name', 'clone1'): return " 30\n", 0 elif cmd == ('lun', '-list', '-name', 'clone1dest'): return " 301\n", 0 elif cmd == ('migrate', '-start', '-source', '30', '-dest', '301', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('lun', '-list', '-name', 'clone1', '-attachedSnapshot'): return "\n test \n :N/A", 0 elif cmd == ('snap', '-destroy', '-id', 'clone1src-temp-snapshot', '-o'): return None, 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1_edest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1_e'): return "create mount point successfully", 0 elif cmd == ('lun', '-attach', '-name', 'clone1_e', '-snapName', 'clone1src-temp-snapshot'): return None, 0 elif cmd == ('lun', '-list', '-name', 'clone1_e'): return " 40\n", 0 elif cmd == ('lun', '-list', '-name', 'clone1_edest'): return " 401\n", 0 elif cmd == ('migrate', '-start', '-source', '40', '-dest', '401', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('lun', '-list', '-name', 'clone1_e', '-attachedSnapshot'): return "\n test \n :N", 0 elif cmd == ('lun', '-expand', '-name', 'vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds'): return "Expand volume successfully", 0 elif cmd == ('lun', '-expand', '-name', 'failed_vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds'): return "Expand volume failed because it has snap", 97 elif cmd == ('lun', '-expand', '-name', 'failed_vol1', '-capacity', 3, '-sq', 'gb', '-o', '-ignoreThresholds'): return "Expand volume failed", 1023 elif cmd == ('storagegroup', '-list', '-gname', 'fakehost'): return '\nStorage Group Name: fakehost' + \ '\nStorage Group UID: 78:47:C4:F2:CA:' + \ '\n\nHLU/ALU Pairs:\n\n HLU Number ' + \ 'ALU Number\n ---------- ----------\n' + \ ' 10 64\nShareable: YES\n', 0 elif cmd == ('lun', '-list', '-l', '10', '-owner'): return '\n\nCurrent Owner: SP A', 0 elif cmd == ('storagegroup', '-addhlu', '-o', '-gname', 'fakehost', '-hlu', 1, '-alu', '10'): return None, 0 elif cmd == ('connection', '-getport', '-sp', 'A'): return 'SP: A\nPort ID: 5\nPort WWN: iqn.1992-04.' + \ 'com.emc:cx.fnm00124000215.a5\niSCSI Alias: 0215.a5\n', 0 else: self.assertTrue(False) def setUp(self): # backup back_os_path_exists = os.path.exists self.addCleanup(self._restore, back_os_path_exists) super(EMCVNXCLIDriverISCSITestCase, self).setUp() self.configuration = conf.Configuration(None) self.configuration.append_config_values = mock.Mock(return_value=0) self.configuration.naviseccli_path = '/opt/Navisphere/bin/naviseccli' self.configuration.san_ip = '10.0.0.1' self.configuration.storage_vnx_pool_name = 'unit_test_pool' self.configuration.san_login = '******' self.configuration.san_password = '******' self.configuration.default_timeout = 0 self.testData = EMCVNXCLIDriverTestData() self.navisecclicmd = '/opt/Navisphere/bin/naviseccli ' + \ '-address 10.0.0.1 -user sysadmin -password sysadmin -scope 0 ' os.path.exists = mock.Mock(return_value=1) EMCVnxCli._cli_execute = mock.Mock(side_effect=self._fake_cli_executor) self.driver = EMCCLIISCSIDriver(configuration=self.configuration) self.driver.cli.wait_interval = 0 def _restore(self, back_os_path_exists): # recover os.path.exists = back_os_path_exists def test_create_destroy_volume_withoutExtraSpec(self): # case self.driver.create_volume(self.testData.test_volume) self.driver.delete_volume(self.testData.test_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('lun', '-destroy', '-name', 'vol1', '-forceDetach', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_destroy_volume_withExtraSpec(self): # mock extra_specs = {'storage:provisioning': 'Thin'} volume_types.get = mock.Mock(return_value=extra_specs) # case self.driver.create_volume(self.testData.test_volume) self.driver.delete_volume(self.testData.test_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('lun', '-destroy', '-name', 'vol1', '-forceDetach', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_get_volume_stats(self): # mock self.configuration.safe_get = mock.Mock(return_value=0) # case rc = self.driver.get_volume_stats(True) stats = {'volume_backend_name': 'EMCCLIISCSIDriver', 'free_capacity_gb': 1000.0, 'driver_version': '02.00.00', 'total_capacity_gb': 10000.0, 'reserved_percentage': 0, 'vendor_name': 'EMC', 'storage_protocol': 'iSCSI'} self.assertEqual(stats, rc) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-userCap', '-availableCap')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_destroy_volume_snapshot(self): # case self.driver.create_snapshot(self.testData.test_snapshot) self.driver.delete_snapshot(self.testData.test_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'vol-vol1'), mock.call('snap', '-create', '-res', '16', '-name', 'snapshot1', '-allowReadWrite', 'yes'), mock.call('snap', '-destroy', '-id', 'snapshot1', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) @mock.patch.object( EMCCLIISCSIDriver, '_do_iscsi_discovery', return_value=['10.0.0.3:3260,1 ' 'iqn.1992-04.com.emc:cx.apm00123907237.a8', '10.0.0.4:3260,2 ' 'iqn.1992-04.com.emc:cx.apm00123907237.b8']) def test_initialize_connection(self, _mock_iscsi_discovery): # case rc = self.driver.initialize_connection( self.testData.test_volume, self.testData.connector) connect_info = {'driver_volume_type': 'iscsi', 'data': {'target_lun': -1, 'volume_id': '1', 'target_iqn': 'iqn.1992-04.com.emc:' + 'cx.apm00123907237.b8', 'target_discovered': True, 'target_portal': '10.0.0.4:3260'}} self.assertEqual(connect_info, rc) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-l', '10', '-owner'), mock.call('storagegroup', '-addhlu', '-o', '-gname', 'fakehost', '-hlu', 1, '-alu', '10'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-l', '10', '-owner'), mock.call('connection', '-getport', '-sp', 'A')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_terminate_connection(self): # case self.driver.terminate_connection(self.testData.test_volume, self.testData.connector) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-l', '10', '-owner')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_volume, self.testData.test_failed_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'failed_vol1')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_snapshot_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_snapshot, self.testData.test_failed_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'vol-vol1'), mock.call('snap', '-create', '-res', '16', '-name', 'failed_snapshot', '-allowReadWrite', 'yes')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_from_snapshot(self): # case self.driver.create_volume_from_snapshot(self.testData.test_volfromsnap, self.testData.test_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnapdest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap'), mock.call('lun', '-attach', '-name', 'volfromsnap', '-snapName', 'snapshot1'), mock.call('lun', '-list', '-name', 'volfromsnap'), mock.call('lun', '-list', '-name', 'volfromsnapdest'), mock.call('migrate', '-start', '-source', '10', '-dest', '101', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'volfromsnap', '-attachedSnapshot')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_from_snapshot_sync_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_volume_from_snapshot, self.testData.test_volfromsnap_e, self.testData.test_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnap_edest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap_e'), mock.call('lun', '-attach', '-name', 'volfromsnap_e', '-snapName', 'snapshot1'), mock.call('lun', '-list', '-name', 'volfromsnap_e'), mock.call('lun', '-list', '-name', 'volfromsnap_edest'), mock.call('migrate', '-start', '-source', '20', '-dest', '201', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'volfromsnap_e', '-attachedSnapshot')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_cloned_volume(self): # case self.driver.create_cloned_volume(self.testData.test_clone, self.testData.test_clone_src) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'clone1src'), mock.call('snap', '-create', '-res', '22', '-name', 'clone1src-temp-snapshot', '-allowReadWrite', 'yes'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1dest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1'), mock.call('lun', '-attach', '-name', 'clone1', '-snapName', 'clone1src-temp-snapshot'), mock.call('lun', '-list', '-name', 'clone1'), mock.call('lun', '-list', '-name', 'clone1dest'), mock.call('migrate', '-start', '-source', '30', '-dest', '301', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'clone1', '-attachedSnapshot'), mock.call('snap', '-destroy', '-id', 'clone1src-temp-snapshot', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_clone_sync_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_cloned_volume, self.testData.test_clone_e, self.testData.test_clone_src) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'clone1src'), mock.call('snap', '-create', '-res', '22', '-name', 'clone1src-temp-snapshot', '-allowReadWrite', 'yes'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1_edest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1_e'), mock.call('lun', '-attach', '-name', 'clone1_e', '-snapName', 'clone1src-temp-snapshot'), mock.call('lun', '-list', '-name', 'clone1_e'), mock.call('lun', '-list', '-name', 'clone1_edest'), mock.call('migrate', '-start', '-source', '40', '-dest', '401', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'clone1_e', '-attachedSnapshot')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_delete_volume_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.delete_volume, self.testData.test_failed_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-destroy', '-name', 'failed_vol1', '-forceDetach', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_extend_volume(self): # case self.driver.extend_volume(self.testData.test_volume, 2) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-expand', '-name', 'vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_extend_volume_has_snapshot(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, self.testData.test_failed_volume, 2) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-expand', '-name', 'failed_vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_extend_volume_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, self.testData.test_failed_volume, 3) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-expand', '-name', 'failed_vol1', '-capacity', 3, '-sq', 'gb', '-o', '-ignoreThresholds')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_remove_export(self): # case self.driver.create_export(None, self.testData.test_volume) self.driver.remove_export(None, self.testData.test_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'vol1')] EMCVnxCli._cli_execute.assert_has_calls(expected)
class EMCVNXCLIDriverISCSITestCase(test.TestCase): def _fake_cli_executor(self, *cmd, **kwargv): # mock cli if cmd == ("storagepool", "-list", "-name", "unit_test_pool", "-state"): return None, 0 elif cmd == ('storagepool', '-list', '-name', 'unit_test_pool', '-userCap', '-availableCap'): pool_details = "test\ntest\ntest\ntotal capacity:10000\n" + \ "test\nfree capacity:1000\ntest\ntest" return pool_details, 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'): return None, 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'failed_vol1'): return None, 1023 elif cmd == ('lun', '-create', '-type', 'Thin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'): return None, 0 elif cmd == ('lun', '-list', '-name', 'vol1'): return " 10\nReady", 0 elif cmd == ('lun', '-destroy', '-name', 'vol1', '-forceDetach', '-o'): return "Lun deleted successfully", 0 elif cmd == ('lun', '-destroy', '-name', 'failed_vol1', '-forceDetach', '-o'): return "Lun deleted successfully", 1023 elif cmd == ('lun', '-list', '-name', 'vol-vol1'): return " 16\n", 0 elif cmd == ('snap', '-create', '-res', '16', '-name', 'snapshot1', '-allowReadWrite', 'yes'): return "Create Snap successfully", 0 elif cmd == ('snap', '-create', '-res', '16', '-name', 'failed_snapshot', '-allowReadWrite', 'yes'): return "Create Snap failed", 1023 elif cmd == ('snap', '-destroy', '-id', 'snapshot1', '-o'): return "Delete Snap successfully", 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnapdest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnap_edest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap'): return "create mount point successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap_e'): return "create mount point successfully", 0 elif cmd == ('lun', '-attach', '-name', 'volfromsnap', '-snapName', 'snapshot1'): return None, 0 elif cmd == ('lun', '-attach', '-name', 'volfromsnap_e', '-snapName', 'snapshot1'): return None, 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap'): return " 10\n", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnapdest'): return " 101\n", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap_e'): return " 20\n", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap_edest'): return " 201\n", 0 elif cmd == ('migrate', '-start', '-source', '10', '-dest', '101', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('migrate', '-start', '-source', '20', '-dest', '201', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap', '-attachedSnapshot'): return "\n test \n :N/A", 0 elif cmd == ('lun', '-list', '-name', 'volfromsnap_e', '-attachedSnapshot'): return "\n test \n :N", 0 elif cmd == ('snap', '-create', '-res', '22', '-name', 'clone1src-temp-snapshot', '-allowReadWrite', 'yes'): return "Create Snap successfully", 0 elif cmd == ('lun', '-list', '-name', 'clone1src'): return " 22\n", 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1dest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1'): return "create mount point successfully", 0 elif cmd == ('lun', '-attach', '-name', 'clone1', '-snapName', 'clone1src-temp-snapshot'): return 'create temp snap successfully', 0 elif cmd == ('lun', '-list', '-name', 'clone1'): return " 30\n", 0 elif cmd == ('lun', '-list', '-name', 'clone1dest'): return " 301\n", 0 elif cmd == ('migrate', '-start', '-source', '30', '-dest', '301', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('lun', '-list', '-name', 'clone1', '-attachedSnapshot'): return "\n test \n :N/A", 0 elif cmd == ('snap', '-destroy', '-id', 'clone1src-temp-snapshot', '-o'): return None, 0 elif cmd == ('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1_edest'): return "create temp volume successfully", 0 elif cmd == ('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1_e'): return "create mount point successfully", 0 elif cmd == ('lun', '-attach', '-name', 'clone1_e', '-snapName', 'clone1src-temp-snapshot'): return None, 0 elif cmd == ('lun', '-list', '-name', 'clone1_e'): return " 40\n", 0 elif cmd == ('lun', '-list', '-name', 'clone1_edest'): return " 401\n", 0 elif cmd == ('migrate', '-start', '-source', '40', '-dest', '401', '-rate', 'ASAP', '-o'): return None, 0 elif cmd == ('lun', '-list', '-name', 'clone1_e', '-attachedSnapshot'): return "\n test \n :N", 0 elif cmd == ('lun', '-expand', '-name', 'vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds'): return "Expand volume successfully", 0 elif cmd == ('lun', '-expand', '-name', 'failed_vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds'): return "Expand volume failed because it has snap", 97 elif cmd == ('lun', '-expand', '-name', 'failed_vol1', '-capacity', 3, '-sq', 'gb', '-o', '-ignoreThresholds'): return "Expand volume failed", 1023 elif cmd == ('storagegroup', '-list', '-gname', 'fakehost'): return '\nStorage Group Name: fakehost' + \ '\nStorage Group UID: 78:47:C4:F2:CA:' + \ '\n\nHLU/ALU Pairs:\n\n HLU Number ' + \ 'ALU Number\n ---------- ----------\n' + \ ' 10 64\nShareable: YES\n', 0 elif cmd == ('lun', '-list', '-l', '10', '-owner'): return '\n\nCurrent Owner: SP A', 0 elif cmd == ('storagegroup', '-addhlu', '-o', '-gname', 'fakehost', '-hlu', 1, '-alu', '10'): return None, 0 elif cmd == ('connection', '-getport', '-sp', 'A'): return 'SP: A\nPort ID: 5\nPort WWN: iqn.1992-04.' + \ 'com.emc:cx.fnm00124000215.a5\niSCSI Alias: 0215.a5\n', 0 else: self.assertTrue(False) def setUp(self): # backup back_os_path_exists = os.path.exists self.addCleanup(self._restore, back_os_path_exists) super(EMCVNXCLIDriverISCSITestCase, self).setUp() self.configuration = conf.Configuration(None) self.configuration.append_config_values = mock.Mock(return_value=0) self.configuration.naviseccli_path = '/opt/Navisphere/bin/naviseccli' self.configuration.san_ip = '10.0.0.1' self.configuration.storage_vnx_pool_name = 'unit_test_pool' self.configuration.san_login = '******' self.configuration.san_password = '******' self.configuration.default_timeout = 0 self.testData = EMCVNXCLIDriverTestData() self.navisecclicmd = '/opt/Navisphere/bin/naviseccli ' + \ '-address 10.0.0.1 -user sysadmin -password sysadmin -scope 0 ' os.path.exists = mock.Mock(return_value=1) EMCVnxCli._cli_execute = mock.Mock(side_effect=self._fake_cli_executor) self.driver = EMCCLIISCSIDriver(configuration=self.configuration) self.driver.cli.wait_interval = 0 def _restore(self, back_os_path_exists): # recover os.path.exists = back_os_path_exists def test_create_destroy_volume_withoutExtraSpec(self): # case self.driver.create_volume(self.testData.test_volume) self.driver.delete_volume(self.testData.test_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('lun', '-destroy', '-name', 'vol1', '-forceDetach', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_destroy_volume_withExtraSpec(self): # mock extra_specs = {'storage:provisioning': 'Thin'} volume_types.get = mock.Mock(return_value=extra_specs) # case self.driver.create_volume(self.testData.test_volume) self.driver.delete_volume(self.testData.test_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'vol1'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('lun', '-destroy', '-name', 'vol1', '-forceDetach', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_get_volume_stats(self): # mock self.configuration.safe_get = mock.Mock(return_value=0) # case rc = self.driver.get_volume_stats(True) stats = {'volume_backend_name': 'EMCCLIISCSIDriver', 'free_capacity_gb': 1000.0, 'driver_version': '02.00.00', 'total_capacity_gb': 10000.0, 'reserved_percentage': 0, 'vendor_name': 'EMC', 'storage_protocol': 'iSCSI'} self.assertEqual(rc, stats) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-userCap', '-availableCap')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_destroy_volume_snapshot(self): # case self.driver.create_snapshot(self.testData.test_snapshot) self.driver.delete_snapshot(self.testData.test_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'vol-vol1'), mock.call('snap', '-create', '-res', '16', '-name', 'snapshot1', '-allowReadWrite', 'yes'), mock.call('snap', '-destroy', '-id', 'snapshot1', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) @mock.patch.object( EMCCLIISCSIDriver, '_do_iscsi_discovery', return_value=['10.0.0.3:3260,1 ' 'iqn.1992-04.com.emc:cx.apm00123907237.a8', '10.0.0.4:3260,2 ' 'iqn.1992-04.com.emc:cx.apm00123907237.b8']) def test_initialize_connection(self, _mock_iscsi_discovery): # case rc = self.driver.initialize_connection( self.testData.test_volume, self.testData.connector) connect_info = {'driver_volume_type': 'iscsi', 'data': {'target_lun': -1, 'volume_id': '1', 'target_iqn': 'iqn.1992-04.com.emc:' + 'cx.apm00123907237.b8', 'target_discovered': True, 'target_portal': '10.0.0.4:3260'}} self.assertEqual(rc, connect_info) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-l', '10', '-owner'), mock.call('storagegroup', '-addhlu', '-o', '-gname', 'fakehost', '-hlu', 1, '-alu', '10'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-l', '10', '-owner'), mock.call('connection', '-getport', '-sp', 'A')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_terminate_connection(self): # case self.driver.terminate_connection(self.testData.test_volume, self.testData.connector) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-name', 'vol1'), mock.call('storagegroup', '-list', '-gname', 'fakehost'), mock.call('lun', '-list', '-l', '10', '-owner')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_volume, self.testData.test_failed_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'failed_vol1')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_snapshot_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_snapshot, self.testData.test_failed_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'vol-vol1'), mock.call('snap', '-create', '-res', '16', '-name', 'failed_snapshot', '-allowReadWrite', 'yes')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_from_snapshot(self): # case self.driver.create_volume_from_snapshot(self.testData.test_volfromsnap, self.testData.test_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnapdest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap'), mock.call('lun', '-attach', '-name', 'volfromsnap', '-snapName', 'snapshot1'), mock.call('lun', '-list', '-name', 'volfromsnap'), mock.call('lun', '-list', '-name', 'volfromsnapdest'), mock.call('migrate', '-start', '-source', '10', '-dest', '101', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'volfromsnap', '-attachedSnapshot')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_from_snapshot_sync_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_volume_from_snapshot, self.testData.test_volfromsnap_e, self.testData.test_snapshot) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'volfromsnap_edest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'vol-vol1', '-name', 'volfromsnap_e'), mock.call('lun', '-attach', '-name', 'volfromsnap_e', '-snapName', 'snapshot1'), mock.call('lun', '-list', '-name', 'volfromsnap_e'), mock.call('lun', '-list', '-name', 'volfromsnap_edest'), mock.call('migrate', '-start', '-source', '20', '-dest', '201', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'volfromsnap_e', '-attachedSnapshot')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_cloned_volume(self): # case self.driver.create_cloned_volume(self.testData.test_clone, self.testData.test_clone_src) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'clone1src'), mock.call('snap', '-create', '-res', '22', '-name', 'clone1src-temp-snapshot', '-allowReadWrite', 'yes'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1dest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1'), mock.call('lun', '-attach', '-name', 'clone1', '-snapName', 'clone1src-temp-snapshot'), mock.call('lun', '-list', '-name', 'clone1'), mock.call('lun', '-list', '-name', 'clone1dest'), mock.call('migrate', '-start', '-source', '30', '-dest', '301', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'clone1', '-attachedSnapshot'), mock.call('snap', '-destroy', '-id', 'clone1src-temp-snapshot', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_volume_clone_sync_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_cloned_volume, self.testData.test_clone_e, self.testData.test_clone_src) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'clone1src'), mock.call('snap', '-create', '-res', '22', '-name', 'clone1src-temp-snapshot', '-allowReadWrite', 'yes'), mock.call('lun', '-create', '-type', 'NonThin', '-capacity', 1, '-sq', 'gb', '-poolName', 'unit_test_pool', '-name', 'clone1_edest'), mock.call('lun', '-create', '-type', 'Snap', '-primaryLunName', 'clone1src', '-name', 'clone1_e'), mock.call('lun', '-attach', '-name', 'clone1_e', '-snapName', 'clone1src-temp-snapshot'), mock.call('lun', '-list', '-name', 'clone1_e'), mock.call('lun', '-list', '-name', 'clone1_edest'), mock.call('migrate', '-start', '-source', '40', '-dest', '401', '-rate', 'ASAP', '-o'), mock.call('lun', '-list', '-name', 'clone1_e', '-attachedSnapshot')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_delete_volume_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.delete_volume, self.testData.test_failed_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-destroy', '-name', 'failed_vol1', '-forceDetach', '-o')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_extend_volume(self): # case self.driver.extend_volume(self.testData.test_volume, 2) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-expand', '-name', 'vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_extend_volume_has_snapshot(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, self.testData.test_failed_volume, 2) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-expand', '-name', 'failed_vol1', '-capacity', 2, '-sq', 'gb', '-o', '-ignoreThresholds')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_extend_volume_failed(self): # case self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, self.testData.test_failed_volume, 3) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-expand', '-name', 'failed_vol1', '-capacity', 3, '-sq', 'gb', '-o', '-ignoreThresholds')] EMCVnxCli._cli_execute.assert_has_calls(expected) def test_create_remove_export(self): # case self.driver.create_export(None, self.testData.test_volume) self.driver.remove_export(None, self.testData.test_volume) expected = [mock.call('storagepool', '-list', '-name', 'unit_test_pool', '-state'), mock.call('lun', '-list', '-name', 'vol1')] EMCVnxCli._cli_execute.assert_has_calls(expected)