def test_get_lun_by_args(self): response = netapp_api.NaElement( etree.XML("""<results status="passed"> <num-records>2</num-records> <attributes-list> <lun-info> </lun-info> </attributes-list> </results>""")) self.connection.invoke_successfully.return_value = response lun = self.client.get_lun_by_args() self.assertEqual(1, len(lun))
def test_find_mapped_lun_igroup_no_igroups(self): response = netapp_api.NaElement( etree.XML(""" <results status="passed"> <initiator-groups /> </results>""")) initiators = fake.FC_FORMATTED_INITIATORS self.zapi_client.get_lun_map.return_value = response (igroup, lun_id) = self.library._find_mapped_lun_igroup('path', initiators) self.assertIsNone(igroup) self.assertIsNone(lun_id)
def test_get_vol_by_junc_vserver_not_found(self): fake_vserver = 'fake_vserver' fake_junc = 'fake_junction_path' response = netapp_api.NaElement( etree.XML("""<results status="passed"> <num-records>0</num-records> <attributes-list> </attributes-list> </results>""")) self.connection.invoke_successfully.return_value = response self.assertRaises(exception.NotFound, self.client.get_vol_by_junc_vserver, fake_vserver, fake_junc)
def test_get_lun_map_multiple_pages(self): path = '/vol/%s/%s' % (self.fake_volume, self.fake_lun) expected_lun_map = { "initiator-group": "igroup", "lun-id": "1337", "vserver": "vserver", } response = netapp_api.NaElement( etree.XML("""<results status="passed"> <num-records>1</num-records> <attributes-list> <lun-map-info> <lun-id>%(lun-id)s</lun-id> <initiator-group>%(initiator-group)s</initiator-group> <vserver>%(vserver)s</vserver> </lun-map-info> </attributes-list> <next-tag>blah</next-tag> </results>""" % expected_lun_map)) response_2 = netapp_api.NaElement( etree.XML("""<results status="passed"> <num-records>1</num-records> <attributes-list> <lun-map-info> <lun-id>%(lun-id)s</lun-id> <initiator-group>%(initiator-group)s</initiator-group> <vserver>%(vserver)s</vserver> </lun-map-info> </attributes-list> </results>""" % expected_lun_map)) self.connection.invoke_successfully.side_effect = [ response, response_2 ] lun_map = self.client.get_lun_map(path) self.assertEqual([expected_lun_map, expected_lun_map], lun_map)
def test_get_if_info_by_ip(self, mock_resolve_hostname): fake_ip = '192.168.1.101' response = netapp_api.NaElement( etree.XML("""<results status="passed"> <num-records>1</num-records> <attributes-list> <net-interface-info> </net-interface-info> </attributes-list> </results>""")) self.connection.invoke_successfully.return_value = response results = self.client.get_if_info_by_ip(fake_ip) self.assertEqual(1, len(results))
def test_get_iscsi_service_details(self): expected_iqn = 'iqn.1998-01.org.openstack.iscsi:name1' response = netapp_api.NaElement( etree.XML("""<results status="passed"> <num-records>1</num-records> <attributes-list> <iscsi-service-info> <node-name>%s</node-name> </iscsi-service-info> </attributes-list> </results>""" % expected_iqn)) self.connection.invoke_successfully.return_value = response iqn = self.client.get_iscsi_service_details() self.assertEqual(expected_iqn, iqn)
def test_get_actual_path_for_export(self): fake_export_path = 'fake_export_path' expected_actual_pathname = 'fake_actual_pathname' response = netapp_api.NaElement( etree.XML("""<results status="passed"> <actual-pathname>%(path)s</actual-pathname> </results>""" % {'path': expected_actual_pathname})) self.connection.invoke_successfully.return_value = response actual_pathname = self.client.get_actual_path_for_export( fake_export_path) __, __, _kwargs = self.connection.invoke_successfully.mock_calls[0] enable_tunneling = _kwargs['enable_tunneling'] self.assertEqual(expected_actual_pathname, actual_pathname) self.assertTrue(enable_tunneling)
def test_query_aggr_storage_disk(self): na_server = netapp_api.NaServer('127.0.0.1') body = etree.XML("""<results status="passed"> <attributes-list> <storage-disk-info> <disk-raid-info> <effective-disk-type>SATA</effective-disk-type> </disk-raid-info> </storage-disk-info> </attributes-list> </results>""") self.mock_object(ssc_cmode.netapp_api, 'invoke_api', mock.Mock(return_value=[netapp_api.NaElement(body)])) eff_disk_type = ssc_cmode.query_aggr_storage_disk(na_server, 'aggr0') self.assertEqual('SATA', eff_disk_type)
def test_get_igroup_by_initiators_multiple(self): initiators = ['11:22:33:44:55:66:77:88', '88:77:66:55:44:33:22:11'] expected_igroup = { 'initiator-group-os-type': 'default', 'initiator-group-type': 'fcp', 'initiator-group-name': 'openstack-igroup1', } response = netapp_api.NaElement( etree.XML("""<results status="passed"> <attributes-list> <initiator-group-info> <initiator-group-alua-enabled>true</initiator-group-alua-enabled> <initiator-group-name>%(initiator-group-name)s</initiator-group-name> <initiator-group-os-type>default</initiator-group-os-type> <initiator-group-throttle-borrow>false</initiator-group-throttle-borrow> <initiator-group-throttle-reserve>0</initiator-group-throttle-reserve> <initiator-group-type>%(initiator-group-type)s</initiator-group-type> <initiator-group-use-partner>true</initiator-group-use-partner> <initiator-group-uuid>f8aa707a-57fa-11e4-ad08-123478563412 </initiator-group-uuid> <initiator-group-vsa-enabled>false</initiator-group-vsa-enabled> <initiators> <initiator-info> <initiator-name>11:22:33:44:55:66:77:88</initiator-name> </initiator-info> <initiator-info> <initiator-name>88:77:66:55:44:33:22:11</initiator-name> </initiator-info> </initiators> <vserver>cinder-iscsi</vserver> </initiator-group-info> </attributes-list> <num-records>1</num-records> </results>""" % expected_igroup)) self.connection.invoke_successfully.return_value = response igroups = self.client.get_igroup_by_initiators(initiators) # make these lists of dicts comparable using hashable dictionaries igroups = set( [netapp_utils.hashabledict(igroup) for igroup in igroups]) expected = set([netapp_utils.hashabledict(expected_igroup)]) self.assertSetEqual(igroups, expected)
def test_get_igroup_by_initiators_multiple(self): initiators = fake.FC_FORMATTED_INITIATORS response = netapp_api.NaElement( etree.XML("""<results status="passed"> <initiator-groups> <initiator-group-info> <initiator-group-name>%(initiator-group-name)s</initiator-group-name> <initiator-group-type>%(initiator-group-type)s</initiator-group-type> <initiator-group-uuid>1477ee47-0e1f-4b35-a82c-dcca0b76fc44 </initiator-group-uuid> <initiator-group-os-type>linux</initiator-group-os-type> <initiators> <initiator-info> <initiator-name>21:00:00:24:ff:40:6c:c3</initiator-name> </initiator-info> <initiator-info> <initiator-name>21:00:00:24:ff:40:6c:c2</initiator-name> </initiator-info> </initiators> </initiator-group-info> <initiator-group-info> <initiator-group-name>openstack-igroup2</initiator-group-name> <initiator-group-type>fcp</initiator-group-type> <initiator-group-uuid>1477ee47-0e1f-4b35-a82c-dcca0b76fc44 </initiator-group-uuid> <initiator-group-os-type>linux</initiator-group-os-type> <initiators> <initiator-info> <initiator-name>21:00:00:24:ff:40:6c:c2</initiator-name> </initiator-info> </initiators> </initiator-group-info> </initiator-groups> </results>""" % fake.IGROUP1)) self.connection.invoke_successfully.return_value = response igroups = self.client.get_igroup_by_initiators(initiators) # make these lists of dicts comparable using hashable dictionaries igroups = set( [netapp_utils.hashabledict(igroup) for igroup in igroups]) expected = set([netapp_utils.hashabledict(fake.IGROUP1)]) self.assertSetEqual(igroups, expected)
def test_find_mapped_lun_igroup(self): response = netapp_api.NaElement( etree.XML(""" <results status="passed"> <initiator-groups> <initiator-group-info> <initiator-group-name>%(initiator-group-name)s</initiator-group-name> <initiator-group-type>%(initiator-group-type)s</initiator-group-type> <initiator-group-uuid>1477ee47-0e1f-4b35-a82c-dcca0b76fc44 </initiator-group-uuid> <initiator-group-os-type>linux</initiator-group-os-type> <initiator-group-throttle-reserve>0</initiator-group-throttle-reserve> <initiator-group-throttle-borrow>false </initiator-group-throttle-borrow> <initiator-group-vsa-enabled>false</initiator-group-vsa-enabled> <initiator-group-alua-enabled>true</initiator-group-alua-enabled> <initiator-group-report-scsi-name-enabled>true </initiator-group-report-scsi-name-enabled> <initiator-group-use-partner>true</initiator-group-use-partner> <initiators> <initiator-info> <initiator-name>21:00:00:24:ff:40:6c:c3</initiator-name> </initiator-info> <initiator-info> <initiator-name>21:00:00:24:ff:40:6c:c2</initiator-name> <initiator-alias-info> <initiator-alias>Centos</initiator-alias> </initiator-alias-info> </initiator-info> </initiators> <lun-id>2</lun-id> </initiator-group-info> </initiator-groups> </results>""" % fake.IGROUP1)) initiators = fake.FC_FORMATTED_INITIATORS self.zapi_client.get_lun_map.return_value = response (igroup, lun_id) = self.library._find_mapped_lun_igroup('path', initiators) self.assertEqual(fake.IGROUP1_NAME, igroup) self.assertEqual('2', lun_id)
def test_get_lun_by_args_with_args_specified(self): path = '/vol/%s/%s' % (self.fake_volume, self.fake_lun) response = netapp_api.NaElement( etree.XML("""<results status="passed"> <luns> <lun-info></lun-info> </luns> </results>""")) self.connection.invoke_successfully.return_value = response lun = self.client.get_lun_by_args(path=path) __, _args, __ = self.connection.invoke_successfully.mock_calls[0] actual_request = _args[0] lun_info_args = actual_request.get_children() # Assert request is made with correct arguments self.assertEqual('path', lun_info_args[0].get_name()) self.assertEqual(path, lun_info_args[0].get_content()) self.assertEqual(1, len(lun))
def test_get_iscsi_target_details(self): expected_target = { "address": "127.0.0.1", "port": "1337", "tpgroup-tag": "7777", } response = netapp_api.NaElement( etree.XML("""<results status="passed"> <iscsi-portal-list-entries> <iscsi-portal-list-entry-info> <ip-address>%(address)s</ip-address> <ip-port>%(port)s</ip-port> <tpgroup-tag>%(tpgroup-tag)s</tpgroup-tag> </iscsi-portal-list-entry-info> </iscsi-portal-list-entries> </results>""" % expected_target)) self.connection.invoke_successfully.return_value = response target_list = self.client.get_iscsi_target_details() self.assertEqual([expected_target], target_list)
def test_get_vol_by_junc_vserver(self): fake_vserver = 'fake_vserver' fake_junc = 'fake_junction_path' expected_flex_vol = 'fake_flex_vol' response = netapp_api.NaElement( etree.XML("""<results status="passed"> <num-records>1</num-records> <attributes-list> <volume-attributes> <volume-id-attributes> <name>%(flex_vol)s</name> </volume-id-attributes> </volume-attributes> </attributes-list> </results>""" % {'flex_vol': expected_flex_vol})) self.connection.invoke_successfully.return_value = response actual_flex_vol = self.client.get_vol_by_junc_vserver( fake_vserver, fake_junc) self.assertEqual(expected_flex_vol, actual_flex_vol)
def test_get_igroup_by_initiators(self): initiators = [fake.FC_FORMATTED_INITIATORS[0]] response = netapp_api.NaElement( etree.XML("""<results status="passed"> <initiator-groups> <initiator-group-info> <initiator-group-name>%(initiator-group-name)s</initiator-group-name> <initiator-group-type>%(initiator-group-type)s</initiator-group-type> <initiator-group-uuid>1477ee47-0e1f-4b35-a82c-dcca0b76fc44 </initiator-group-uuid> <initiator-group-os-type>linux</initiator-group-os-type> <initiator-group-throttle-reserve>0</initiator-group-throttle-reserve> <initiator-group-throttle-borrow>false </initiator-group-throttle-borrow> <initiator-group-vsa-enabled>false</initiator-group-vsa-enabled> <initiator-group-alua-enabled>true</initiator-group-alua-enabled> <initiator-group-report-scsi-name-enabled>true </initiator-group-report-scsi-name-enabled> <initiator-group-use-partner>true</initiator-group-use-partner> <initiators> <initiator-info> <initiator-name>21:00:00:24:ff:40:6c:c3</initiator-name> </initiator-info> </initiators> </initiator-group-info> </initiator-groups> </results>""" % fake.IGROUP1)) self.connection.invoke_successfully.return_value = response igroups = self.client.get_igroup_by_initiators(initiators) # make these lists of dicts comparable using hashable dictionaries igroups = set( [netapp_utils.hashabledict(igroup) for igroup in igroups]) expected = set([netapp_utils.hashabledict(fake.IGROUP1)]) self.assertSetEqual(igroups, expected)
def test_has_luns_mapped_to_initiator(self): initiator = fake.FC_FORMATTED_INITIATORS[0] version_response = netapp_api.NaElement( etree.XML(""" <results status="passed"> <lun-maps> <lun-map-info> <path>/vol/cinder1/volume-9be956b3-9854-4a5c-a7f5-13a16da52c9c</path> <initiator-group>openstack-4b57a80b-ebca-4d27-bd63-48ac5408d08b </initiator-group> <lun-id>0</lun-id> </lun-map-info> <lun-map-info> <path>/vol/cinder1/volume-ac90433c-a560-41b3-9357-7f3f80071eb5</path> <initiator-group>openstack-4b57a80b-ebca-4d27-bd63-48ac5408d08b </initiator-group> <lun-id>1</lun-id> </lun-map-info> </lun-maps> </results>""")) self.connection.invoke_successfully.return_value = version_response self.assertTrue(self.client._has_luns_mapped_to_initiator(initiator))
def test_query_aggr_options(self): na_server = netapp_api.NaServer('127.0.0.1') body = etree.XML("""<results status="passed"> <options> <aggr-option-info> <name>ha_policy</name> <value>cfo</value> </aggr-option-info> <aggr-option-info> <name>raidtype</name> <value>raid_dp</value> </aggr-option-info> </options> </results>""") self.mock_object(ssc_cmode.netapp_api, 'invoke_api', mock.Mock(return_value=[netapp_api.NaElement(body)])) aggr_attribs = ssc_cmode.query_aggr_options(na_server, 'aggr0') if aggr_attribs: self.assertEqual('cfo', aggr_attribs['ha_policy']) self.assertEqual('raid_dp', aggr_attribs['raid_type']) else: raise exception.InvalidParameterValue("Incorrect aggr options")
def test_query_cl_vols_for_ssc(self): na_server = netapp_api.NaServer('127.0.0.1') body = etree.XML("""<results status="passed"><attributes-list> <volume-attributes> <volume-id-attributes> <name>iscsi</name> <owning-vserver-name>Openstack</owning-vserver-name> <containing-aggregate-name>aggr0 </containing-aggregate-name> <junction-path>/iscsi</junction-path> <type>rw</type> </volume-id-attributes> <volume-space-attributes> <size-available>214748364</size-available> <size-total>224748364</size-total> <space-guarantee-enabled>enabled</space-guarantee-enabled> <space-guarantee>file</space-guarantee> </volume-space-attributes> <volume-state-attributes> <is-cluster-volume>true </is-cluster-volume> <is-vserver-root>false</is-vserver-root> <state>online</state> <is-inconsistent>false</is-inconsistent> <is-invalid>false</is-invalid> <is-junction-active>true</is-junction-active> </volume-state-attributes> </volume-attributes> <volume-attributes> <volume-id-attributes> <name>nfsvol</name> <owning-vserver-name>Openstack </owning-vserver-name> <containing-aggregate-name>aggr0 </containing-aggregate-name> <junction-path>/nfs</junction-path> <type>rw</type> </volume-id-attributes> <volume-space-attributes> <size-available>14748364</size-available> <size-total>24748364</size-total> <space-guarantee-enabled>enabled </space-guarantee-enabled> <space-guarantee>volume</space-guarantee> </volume-space-attributes> <volume-state-attributes> <is-cluster-volume>true </is-cluster-volume> <is-vserver-root>false</is-vserver-root> <state>online</state> <is-inconsistent>false</is-inconsistent> <is-invalid>false</is-invalid> <is-junction-active>true</is-junction-active> </volume-state-attributes> </volume-attributes> <volume-attributes> <volume-id-attributes> <name>nfsvol2</name> <owning-vserver-name>Openstack </owning-vserver-name> <containing-aggregate-name>aggr0 </containing-aggregate-name> <junction-path>/nfs2</junction-path> <type>rw</type> </volume-id-attributes> <volume-space-attributes> <size-available>14748364</size-available> <size-total>24748364</size-total> <space-guarantee-enabled>enabled </space-guarantee-enabled> <space-guarantee>volume</space-guarantee> </volume-space-attributes> <volume-state-attributes> <is-cluster-volume>true </is-cluster-volume> <is-vserver-root>false</is-vserver-root> <state>online</state> <is-inconsistent>true</is-inconsistent> <is-invalid>true</is-invalid> <is-junction-active>true</is-junction-active> </volume-state-attributes> </volume-attributes> <volume-attributes> <volume-id-attributes> <name>nfsvol3</name> <owning-vserver-name>Openstack </owning-vserver-name> <containing-aggregate-name>aggr0 </containing-aggregate-name> <junction-path>/nfs3</junction-path> <type>rw</type> </volume-id-attributes> <volume-space-attributes> <space-guarantee-enabled>enabled </space-guarantee-enabled> <space-guarantee>volume </space-guarantee> </volume-space-attributes> <volume-state-attributes> <is-cluster-volume>true </is-cluster-volume> <is-vserver-root>false</is-vserver-root> <state>online</state> <is-inconsistent>false</is-inconsistent> <is-invalid>false</is-invalid> <is-junction-active>true</is-junction-active> </volume-state-attributes> </volume-attributes> </attributes-list> <num-records>4</num-records></results>""") self.mock_object(ssc_cmode.netapp_api, 'invoke_api', mock.Mock(return_value=[netapp_api.NaElement(body)])) vols = ssc_cmode.query_cluster_vols_for_ssc(na_server, 'Openstack') self.assertEqual(2, len(vols)) for vol in vols: if vol.id['name'] != 'iscsi' or vol.id['name'] != 'nfsvol': pass else: raise exception.InvalidVolume('Invalid volume returned.')
def test_clone_file_when_clone_fails(self): """Ensure clone is cleaned up on failure.""" expected_src_path = "fake_src_path" expected_dest_path = "fake_dest_path" fake_volume_id = '0309c748-0d94-41f0-af46-4fbbd76686cf' fake_clone_op_id = 'c22ad299-ecec-4ec0-8de4-352b887bfce2' fake_clone_id_response = netapp_api.NaElement( etree.XML("""<results status="passed"> <clone-id> <clone-id-info> <volume-uuid>%(volume)s</volume-uuid> <clone-op-id>%(clone_id)s</clone-op-id> </clone-id-info> </clone-id> </results>""" % { 'volume': fake_volume_id, 'clone_id': fake_clone_op_id })) fake_clone_list_response = netapp_api.NaElement( etree.XML("""<results> <clone-list-status> <clone-id-info> <volume-uuid>%(volume)s</volume-uuid> <clone-op-id>%(clone_id)s</clone-op-id> </clone-id-info> <clone-op-id>%(clone_id)s</clone-op-id> </clone-list-status> <status> <ops-info> <clone-state>failed</clone-state> </ops-info> </status> </results>""" % { 'volume': fake_volume_id, 'clone_id': fake_clone_op_id })) fake_clone_clear_response = mock.Mock() self.connection.invoke_successfully.side_effect = [ fake_clone_id_response, fake_clone_list_response, fake_clone_clear_response ] self.assertRaises(netapp_api.NaApiError, self.client.clone_file, expected_src_path, expected_dest_path) __, _args, _kwargs = self.connection.invoke_successfully.mock_calls[0] actual_request = _args[0] enable_tunneling = _kwargs['enable_tunneling'] actual_src_path = actual_request \ .get_child_by_name('source-path').get_content() actual_dest_path = actual_request.get_child_by_name( 'destination-path').get_content() self.assertEqual(expected_src_path, actual_src_path) self.assertEqual(expected_dest_path, actual_dest_path) self.assertEqual( actual_request.get_child_by_name('destination-exists'), None) self.assertTrue(enable_tunneling) __, _args, _kwargs = self.connection.invoke_successfully.mock_calls[1] actual_request = _args[0] enable_tunneling = _kwargs['enable_tunneling'] actual_clone_id = actual_request.get_child_by_name('clone-id') actual_clone_id_info = actual_clone_id.get_child_by_name( 'clone-id-info') actual_clone_op_id = actual_clone_id_info.get_child_by_name( 'clone-op-id').get_content() actual_volume_uuid = actual_clone_id_info.get_child_by_name( 'volume-uuid').get_content() self.assertEqual(fake_clone_op_id, actual_clone_op_id) self.assertEqual(fake_volume_id, actual_volume_uuid) self.assertTrue(enable_tunneling) # Ensure that the clone-clear call is made upon error __, _args, _kwargs = self.connection.invoke_successfully.mock_calls[2] actual_request = _args[0] enable_tunneling = _kwargs['enable_tunneling'] actual_clone_id = actual_request \ .get_child_by_name('clone-id').get_content() self.assertEqual(fake_clone_op_id, actual_clone_id) self.assertTrue(enable_tunneling)
def test_check_is_naelement(self): element = netapp_api.NaElement('name') self.assertIsNone(self.client.check_is_naelement(element)) self.assertRaises(ValueError, self.client.check_is_naelement, None)