# Copyright 2014 Violin Memory, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Tests for Violin Memory 6000 Series All-Flash Array iSCSI driver """ import mock from oslo_utils import units from cinder import context from cinder.db.sqlalchemy import models from cinder import exception from cinder import test from cinder.tests import fake_vmem_xgtools_client as vxg from cinder.volume import configuration as conf from cinder.volume.drivers.violin import v6000_common from cinder.volume.drivers.violin import v6000_iscsi VOLUME_ID = "abcdabcd-1234-abcd-1234-abcdeffedcba" VOLUME = { "name": "volume-" + VOLUME_ID, "id": VOLUME_ID, "display_name": "fake_volume", "size": 2, "host": "irrelevant", "volume_type": None, "volume_type_id": None, } SNAPSHOT_ID = "abcdabcd-1234-abcd-1234-abcdeffedcbb" SNAPSHOT = { "name": "snapshot-" + SNAPSHOT_ID, "id": SNAPSHOT_ID, "volume_id": VOLUME_ID, "volume_name": "volume-" + VOLUME_ID, "volume_size": 2, "display_name": "fake_snapshot", "volume": VOLUME, } SRC_VOL_ID = "abcdabcd-1234-abcd-1234-abcdeffedcbc" SRC_VOL = { "name": "volume-" + SRC_VOL_ID, "id": SRC_VOL_ID, "display_name": "fake_src_vol", "size": 2, "host": "irrelevant", "volume_type": None, "volume_type_id": None, } INITIATOR_IQN = "iqn.1111-22.org.debian:11:222" CONNECTOR = { "initiator": INITIATOR_IQN, "host": "irrelevant" } class V6000ISCSIDriverTestCase(test.TestCase): """Test cases for VMEM iSCSI driver.""" def setUp(self): super(V6000ISCSIDriverTestCase, self).setUp() self.conf = self.setup_configuration() self.driver = v6000_iscsi.V6000ISCSIDriver(configuration=self.conf) self.driver.common.container = 'myContainer' self.driver.device_id = 'ata-VIOLIN_MEMORY_ARRAY_23109R00000022' self.driver.gateway_iscsi_ip_addresses_mga = '1.2.3.4' self.driver.gateway_iscsi_ip_addresses_mgb = '1.2.3.4' self.driver.array_info = [{"node": 'hostname_mga', "addr": '1.2.3.4', "conn": self.driver.common.mga}, {"node": 'hostname_mgb', "addr": '1.2.3.4', "conn": self.driver.common.mgb}] self.stats = {} self.driver.set_initialized() def tearDown(self): super(V6000ISCSIDriverTestCase, self).tearDown() def setup_configuration(self): config = mock.Mock(spec=conf.Configuration) config.volume_backend_name = 'v6000_iscsi' config.san_ip = '1.1.1.1' config.san_login = 'admin' config.san_password = '' config.san_thin_provision = False config.san_is_local = False config.gateway_mga = '2.2.2.2' config.gateway_mgb = '3.3.3.3' config.use_igroups = False config.request_timeout = 300 config.container = 'myContainer' config.iscsi_port = 3260 config.iscsi_target_prefix = 'iqn.2004-02.com.vmem:' return config def setup_mock_vshare(self, m_conf=None): """Create a fake VShare communication object.""" _m_vshare = mock.Mock(name='VShare', version='1.1.1', spec=vxg.mock_client_conf) if m_conf: _m_vshare.configure_mock(**m_conf) return _m_vshare @mock.patch.object(v6000_common.V6000Common, 'check_for_setup_error') def test_check_for_setup_error(self, m_setup_func): bn = "/vshare/config/iscsi/enable" response = {bn: True} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) result = self.driver.check_for_setup_error() m_setup_func.assert_called_with() self.driver.common.vip.basic.get_node_values.assert_called_with(bn) self.assertTrue(result is None) @mock.patch.object(v6000_common.V6000Common, 'check_for_setup_error') def test_check_for_setup_error_iscsi_is_disabled(self, m_setup_func): bn = "/vshare/config/iscsi/enable" response = {bn: False} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) self.assertRaises(exception.ViolinInvalidBackendConfig, self.driver.check_for_setup_error) @mock.patch.object(v6000_common.V6000Common, 'check_for_setup_error') def test_check_for_setup_error_no_iscsi_ips_for_mga(self, m_setup_func): bn = "/vshare/config/iscsi/enable" response = {bn: True} self.driver.gateway_iscsi_ip_addresses_mga = '' conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) self.assertRaises(exception.ViolinInvalidBackendConfig, self.driver.check_for_setup_error) @mock.patch.object(v6000_common.V6000Common, 'check_for_setup_error') def test_check_for_setup_error_no_iscsi_ips_for_mgb(self, m_setup_func): bn = "/vshare/config/iscsi/enable" response = {bn: True} self.driver.gateway_iscsi_ip_addresses_mgb = '' conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) self.assertRaises(exception.ViolinInvalidBackendConfig, self.driver.check_for_setup_error) def test_create_volume(self): """Volume created successfully.""" self.driver.common._create_lun = mock.Mock() result = self.driver.create_volume(VOLUME) self.driver.common._create_lun.assert_called_with(VOLUME) self.assertTrue(result is None) def test_delete_volume(self): """Volume deleted successfully.""" self.driver.common._delete_lun = mock.Mock() result = self.driver.delete_volume(VOLUME) self.driver.common._delete_lun.assert_called_with(VOLUME) self.assertTrue(result is None) def test_create_snapshot(self): """Snapshot created successfully.""" self.driver.common._create_lun_snapshot = mock.Mock() result = self.driver.create_snapshot(SNAPSHOT) self.driver.common._create_lun_snapshot.assert_called_with(SNAPSHOT) self.assertTrue(result is None) def test_delete_snapshot(self): """Snapshot deleted successfully.""" self.driver.common._delete_lun_snapshot = mock.Mock() result = self.driver.delete_snapshot(SNAPSHOT) self.driver.common._delete_lun_snapshot.assert_called_with(SNAPSHOT) self.assertTrue(result is None) @mock.patch.object(context, 'get_admin_context') def test_create_volume_from_snapshot(self, m_context_func): """Volume created from a snapshot successfully.""" m_context_func.return_value = None self.driver.common._create_lun = mock.Mock() self.driver.copy_volume_data = mock.Mock() result = self.driver.create_volume_from_snapshot(VOLUME, SNAPSHOT) m_context_func.assert_called_with() self.driver.common._create_lun.assert_called_with(VOLUME) self.driver.copy_volume_data.assert_called_with(None, SNAPSHOT, VOLUME) self.assertTrue(result is None) @mock.patch.object(context, 'get_admin_context') def test_create_cloned_volume(self, m_context_func): """Volume clone created successfully.""" m_context_func.return_value = None self.driver.common._create_lun = mock.Mock() self.driver.copy_volume_data = mock.Mock() result = self.driver.create_cloned_volume(VOLUME, SRC_VOL) m_context_func.assert_called_with() self.driver.common._create_lun.assert_called_with(VOLUME) self.driver.copy_volume_data.assert_called_with(None, SRC_VOL, VOLUME) self.assertTrue(result is None) def test_initialize_connection(self): lun_id = 1 igroup = None tgt = self.driver.array_info[0] iqn = "%s%s:%s" % (self.conf.iscsi_target_prefix, tgt['node'], VOLUME['id']) volume = mock.MagicMock(spec=models.Volume) def getitem(name): return VOLUME[name] volume.__getitem__.side_effect = getitem self.driver.common.vip = self.setup_mock_vshare() self.driver._get_short_name = mock.Mock(return_value=VOLUME['id']) self.driver._create_iscsi_target = mock.Mock(return_value=tgt) self.driver._export_lun = mock.Mock(return_value=lun_id) props = self.driver.initialize_connection(volume, CONNECTOR) self.driver._get_short_name.assert_called_with(volume['id']) self.driver._create_iscsi_target.assert_called_with(volume) self.driver._export_lun.assert_called_with(volume, CONNECTOR, igroup) self.driver.common.vip.basic.save_config.assert_called_with() self.assertEqual("1.2.3.4:3260", props['data']['target_portal']) self.assertEqual(iqn, props['data']['target_iqn']) self.assertEqual(lun_id, props['data']['target_lun']) self.assertEqual(volume['id'], props['data']['volume_id']) def test_initialize_connection_with_snapshot_object(self): lun_id = 1 igroup = None tgt = self.driver.array_info[0] iqn = "%s%s:%s" % (self.conf.iscsi_target_prefix, tgt['node'], SNAPSHOT['id']) snapshot = mock.MagicMock(spec=models.Snapshot) def getitem(name): return SNAPSHOT[name] snapshot.__getitem__.side_effect = getitem self.driver.common.vip = self.setup_mock_vshare() self.driver._get_short_name = mock.Mock(return_value=SNAPSHOT['id']) self.driver._create_iscsi_target = mock.Mock(return_value=tgt) self.driver._export_snapshot = mock.Mock(return_value=lun_id) props = self.driver.initialize_connection(snapshot, CONNECTOR) self.driver._get_short_name.assert_called_with(SNAPSHOT['id']) self.driver._create_iscsi_target.assert_called_with(snapshot) self.driver._export_snapshot.assert_called_with(snapshot, CONNECTOR, igroup) self.driver.common.vip.basic.save_config.assert_called_with() self.assertEqual("1.2.3.4:3260", props['data']['target_portal']) self.assertEqual(iqn, props['data']['target_iqn']) self.assertEqual(lun_id, props['data']['target_lun']) self.assertEqual(SNAPSHOT['id'], props['data']['volume_id']) def test_initialize_connection_with_igroups_enabled(self): self.conf.use_igroups = True lun_id = 1 igroup = 'test-igroup-1' tgt = self.driver.array_info[0] iqn = "%s%s:%s" % (self.conf.iscsi_target_prefix, tgt['node'], VOLUME['id']) volume = mock.MagicMock(spec=models.Volume) def getitem(name): return VOLUME[name] volume.__getitem__.side_effect = getitem self.driver.common.vip = self.setup_mock_vshare() self.driver.common._get_igroup = mock.Mock(return_value=igroup) self.driver._add_igroup_member = mock.Mock() self.driver._get_short_name = mock.Mock(return_value=VOLUME['id']) self.driver._create_iscsi_target = mock.Mock(return_value=tgt) self.driver._export_lun = mock.Mock(return_value=lun_id) props = self.driver.initialize_connection(volume, CONNECTOR) self.driver.common._get_igroup.assert_called_with(volume, CONNECTOR) self.driver._add_igroup_member.assert_called_with(CONNECTOR, igroup) self.driver._get_short_name.assert_called_with(volume['id']) self.driver._create_iscsi_target.assert_called_with(volume) self.driver._export_lun.assert_called_with(volume, CONNECTOR, igroup) self.driver.common.vip.basic.save_config.assert_called_with() self.assertEqual("1.2.3.4:3260", props['data']['target_portal']) self.assertEqual(iqn, props['data']['target_iqn']) self.assertEqual(lun_id, props['data']['target_lun']) self.assertEqual(volume['id'], props['data']['volume_id']) def test_terminate_connection(self): volume = mock.MagicMock(spec=models.Volume) self.driver.common.vip = self.setup_mock_vshare() self.driver._unexport_lun = mock.Mock() self.driver._delete_iscsi_target = mock.Mock() result = self.driver.terminate_connection(volume, CONNECTOR) self.driver._unexport_lun.assert_called_with(volume) self.driver._delete_iscsi_target.assert_called_with(volume) self.driver.common.vip.basic.save_config.assert_called_with() self.assertTrue(result is None) def test_terminate_connection_with_snapshot_object(self): snapshot = mock.MagicMock(spec=models.Snapshot) self.driver.common.vip = self.setup_mock_vshare() self.driver._unexport_snapshot = mock.Mock() self.driver._delete_iscsi_target = mock.Mock() result = self.driver.terminate_connection(snapshot, CONNECTOR) self.driver._unexport_snapshot.assert_called_with(snapshot) self.driver._delete_iscsi_target.assert_called_with(snapshot) self.driver.common.vip.basic.save_config.assert_called_with() self.assertTrue(result is None) def test_get_volume_stats(self): self.driver._update_stats = mock.Mock() self.driver._update_stats() result = self.driver.get_volume_stats(True) self.driver._update_stats.assert_called_with() self.assertEqual(self.driver.stats, result) def test_create_iscsi_target(self): target_name = VOLUME['id'] response = {'code': 0, 'message': 'success'} m_vshare = self.setup_mock_vshare() self.driver.common.vip = m_vshare self.driver.common.mga = m_vshare self.driver.common.mgb = m_vshare self.driver._get_short_name = mock.Mock(return_value=VOLUME['id']) self.driver.common._send_cmd_and_verify = mock.Mock( return_value=response) self.driver.common._send_cmd = mock.Mock(return_value=response) calls = [mock.call(self.driver.common.mga.iscsi.bind_ip_to_target, '', VOLUME['id'], self.driver.gateway_iscsi_ip_addresses_mga), mock.call(self.driver.common.mgb.iscsi.bind_ip_to_target, '', VOLUME['id'], self.driver.gateway_iscsi_ip_addresses_mgb)] result = self.driver._create_iscsi_target(VOLUME) self.driver._get_short_name.assert_called_with(VOLUME['id']) self.driver.common._send_cmd_and_verify.assert_called_with( self.driver.common.vip.iscsi.create_iscsi_target, self.driver._wait_for_targetstate, '', [target_name], [target_name]) self.driver.common._send_cmd.assert_has_calls(calls) self.assertTrue(result in self.driver.array_info) def test_delete_iscsi_target(self): response = {'code': 0, 'message': 'success'} self.driver.common.vip = self.setup_mock_vshare() self.driver._get_short_name = mock.Mock(return_value=VOLUME['id']) self.driver.common._send_cmd = mock.Mock(return_value=response) result = self.driver._delete_iscsi_target(VOLUME) self.driver._get_short_name.assert_called_with(VOLUME['id']) self.driver.common._send_cmd( self.driver.common.vip.iscsi.delete_iscsi_target, '', VOLUME['id']) self.assertTrue(result is None) def test_delete_iscsi_target_fails_with_exception(self): response = {'code': 14000, 'message': 'Generic error'} failure = exception.ViolinBackendErr self.driver.common.vip = self.setup_mock_vshare() self.driver._get_short_name = mock.Mock(return_value=VOLUME['id']) self.driver.common._send_cmd = mock.Mock( side_effect=failure(response['message'])) self.assertRaises(failure, self.driver._delete_iscsi_target, VOLUME) def test_export_lun(self): igroup = 'test-igroup-1' lun_id = '1' response = {'code': 0, 'message': ''} self.driver.common.vip = self.setup_mock_vshare() self.driver._get_short_name = mock.Mock(return_value=VOLUME['id']) self.driver.common._send_cmd_and_verify = mock.Mock( return_value=response) self.driver.common._get_lun_id = mock.Mock(return_value=lun_id) result = self.driver._export_lun(VOLUME, CONNECTOR, igroup) self.driver._get_short_name.assert_called_with(VOLUME['id']) self.driver.common._send_cmd_and_verify.assert_called_with( self.driver.common.vip.lun.export_lun, self.driver.common._wait_for_export_config, '', [self.driver.common.container, VOLUME['id'], VOLUME['id'], igroup, 'auto'], [VOLUME['id'], 'state=True']) self.driver.common._get_lun_id.assert_called_with(VOLUME['id']) self.assertEqual(lun_id, result) def test_export_lun_fails_with_exception(self): igroup = 'test-igroup-1' lun_id = '1' response = {'code': 14000, 'message': 'Generic error'} failure = exception.ViolinBackendErr self.driver.common.vip = self.setup_mock_vshare() self.driver._get_short_name = mock.Mock(return_value=VOLUME['id']) self.driver.common._send_cmd_and_verify = mock.Mock( side_effect=failure(response['message'])) self.driver._get_lun_id = mock.Mock(return_value=lun_id) self.assertRaises(failure, self.driver._export_lun, VOLUME, CONNECTOR, igroup) def test_unexport_lun(self): response = {'code': 0, 'message': ''} self.driver.common.vip = self.setup_mock_vshare() self.driver.common._send_cmd_and_verify = mock.Mock( return_value=response) result = self.driver._unexport_lun(VOLUME) self.driver.common._send_cmd_and_verify.assert_called_with( self.driver.common.vip.lun.unexport_lun, self.driver.common._wait_for_export_config, '', [self.driver.common.container, VOLUME['id'], 'all', 'all', 'auto'], [VOLUME['id'], 'state=False']) self.assertTrue(result is None) def test_unexport_lun_fails_with_exception(self): response = {'code': 14000, 'message': 'Generic error'} failure = exception.ViolinBackendErr self.driver.common.vip = self.setup_mock_vshare() self.driver.common._send_cmd_and_verify = mock.Mock( side_effect=failure(response['message'])) self.assertRaises(failure, self.driver._unexport_lun, VOLUME) def test_export_snapshot(self): lun_id = '1' igroup = 'test-igroup-1' response = {'code': 0, 'message': ''} self.driver.common.vip = self.setup_mock_vshare() self.driver._get_short_name = mock.Mock(return_value=SNAPSHOT['id']) self.driver.common._send_cmd = mock.Mock(return_value=response) self.driver.common._wait_for_export_config = mock.Mock() self.driver.common._get_snapshot_id = mock.Mock(return_value=lun_id) result = self.driver._export_snapshot(SNAPSHOT, CONNECTOR, igroup) self.driver._get_short_name.assert_called_with(SNAPSHOT['id']) self.driver.common._send_cmd.assert_called_with( self.driver.common.vip.snapshot.export_lun_snapshot, '', self.driver.common.container, SNAPSHOT['volume_id'], SNAPSHOT['id'], igroup, SNAPSHOT['id'], 'auto') self.driver.common._wait_for_export_config.assert_called_with( SNAPSHOT['volume_id'], SNAPSHOT['id'], state=True) self.driver.common._get_snapshot_id.assert_called_once_with( SNAPSHOT['volume_id'], SNAPSHOT['id']) self.assertEqual(lun_id, result) def test_unexport_snapshot(self): response = {'code': 0, 'message': ''} self.driver.common.vip = self.setup_mock_vshare() self.driver.common._send_cmd = mock.Mock(return_value=response) self.driver.common._wait_for_export_config = mock.Mock() result = self.driver._unexport_snapshot(SNAPSHOT) self.driver.common._send_cmd.assert_called_with( self.driver.common.vip.snapshot.unexport_lun_snapshot, '', self.driver.common.container, SNAPSHOT['volume_id'], SNAPSHOT['id'], 'all', 'all', 'auto', False) self.driver.common._wait_for_export_config.assert_called_with( SNAPSHOT['volume_id'], SNAPSHOT['id'], state=False) self.assertTrue(result is None) def test_add_igroup_member(self): igroup = 'test-group-1' response = {'code': 0, 'message': 'success'} conf = { 'igroup.add_initiators.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) result = self.driver._add_igroup_member(CONNECTOR, igroup) self.driver.common.vip.igroup.add_initiators.assert_called_with( igroup, CONNECTOR['initiator']) self.assertTrue(result is None) def test_update_stats(self): backend_name = self.conf.volume_backend_name vendor_name = "Violin Memory, Inc." tot_bytes = 100 * units.Gi free_bytes = 50 * units.Gi bn0 = '/cluster/state/master_id' bn1 = "/vshare/state/global/1/container/myContainer/total_bytes" bn2 = "/vshare/state/global/1/container/myContainer/free_bytes" response1 = {bn0: '1'} response2 = {bn1: tot_bytes, bn2: free_bytes} conf = { 'basic.get_node_values.side_effect': [response1, response2], } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) result = self.driver._update_stats() calls = [mock.call(bn0), mock.call([bn1, bn2])] self.driver.common.vip.basic.get_node_values.assert_has_calls(calls) self.assertEqual(100, self.driver.stats['total_capacity_gb']) self.assertEqual(50, self.driver.stats['free_capacity_gb']) self.assertEqual(backend_name, self.driver.stats['volume_backend_name']) self.assertEqual(vendor_name, self.driver.stats['vendor_name']) self.assertTrue(result is None) def test_update_stats_fails_data_query(self): backend_name = self.conf.volume_backend_name vendor_name = "Violin Memory, Inc." bn0 = '/cluster/state/master_id' response1 = {bn0: '1'} response2 = {} conf = { 'basic.get_node_values.side_effect': [response1, response2], } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) self.assertTrue(self.driver._update_stats() is None) self.assertEqual(0, self.driver.stats['total_capacity_gb']) self.assertEqual(0, self.driver.stats['free_capacity_gb']) self.assertEqual(backend_name, self.driver.stats['volume_backend_name']) self.assertEqual(vendor_name, self.driver.stats['vendor_name']) def testGetShortName_LongName(self): long_name = "abcdefghijklmnopqrstuvwxyz1234567890" short_name = "abcdefghijklmnopqrstuvwxyz123456" self.assertEqual(short_name, self.driver._get_short_name(long_name)) def testGetShortName_ShortName(self): long_name = "abcdef" short_name = "abcdef" self.assertEqual(short_name, self.driver._get_short_name(long_name)) def testGetShortName_EmptyName(self): long_name = "" short_name = "" self.assertEqual(short_name, self.driver._get_short_name(long_name)) def test_get_active_iscsi_ips(self): bn0 = "/net/interface/config/*" bn1 = ["/net/interface/state/eth4/addr/ipv4/1/ip", "/net/interface/state/eth4/flags/link_up"] response1 = {"/net/interface/config/eth4": "eth4"} response2 = {"/net/interface/state/eth4/addr/ipv4/1/ip": "1.1.1.1", "/net/interface/state/eth4/flags/link_up": True} conf = { 'basic.get_node_values.side_effect': [response1, response2], } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) results = self.driver._get_active_iscsi_ips(self.driver.common.vip) calls = [mock.call(bn0), mock.call(bn1)] self.driver.common.vip.basic.get_node_values.assert_has_calls(calls) self.assertEqual(1, len(results)) self.assertEqual("1.1.1.1", results[0]) def test_get_active_iscsi_ips_with_invalid_interfaces(self): response = {"/net/interface/config/lo": "lo", "/net/interface/config/vlan10": "vlan10", "/net/interface/config/eth1": "eth1", "/net/interface/config/eth2": "eth2", "/net/interface/config/eth3": "eth3"} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) result = self.driver._get_active_iscsi_ips(self.driver.common.vip) self.assertEqual(0, len(result)) def test_get_active_iscsi_ips_with_no_interfaces(self): response = {} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) result = self.driver._get_active_iscsi_ips(self.driver.common.vip) self.assertEqual(0, len(result)) def test_get_hostname(self): bn = '/system/hostname' response = {bn: 'MYHOST'} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) result = self.driver._get_hostname() self.driver.common.vip.basic.get_node_values.assert_called_with(bn) self.assertEqual("MYHOST", result) def test_get_hostname_mga(self): bn = '/system/hostname' response = {bn: 'MYHOST'} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) self.driver.common.mga = self.setup_mock_vshare(m_conf=conf) self.assertEqual("MYHOST", self.driver._get_hostname('mga')) def test_get_hostname_mgb(self): response = {"/system/hostname": "MYHOST"} bn = '/system/hostname' response = {bn: 'MYHOST'} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) self.driver.common.mgb = self.setup_mock_vshare(m_conf=conf) self.assertEqual("MYHOST", self.driver._get_hostname('mgb')) def test_get_hostname_query_fails(self): response = {} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.vip = self.setup_mock_vshare(m_conf=conf) self.assertEqual(self.conf.san_ip, self.driver._get_hostname()) def test_wait_for_targetstate(self): target = 'mytarget' bn = "/vshare/config/iscsi/target/%s" % target response = {bn: target} conf = { 'basic.get_node_values.return_value': response, } self.driver.common.mga = self.setup_mock_vshare(m_conf=conf) self.driver.common.mgb = self.setup_mock_vshare(m_conf=conf) result = self.driver._wait_for_targetstate(target) self.driver.common.mga.basic.get_node_values.assert_called_with(bn) self.driver.common.mgb.basic.get_node_values.assert_called_with(bn) self.assertTrue(result)