# (c) Copyright 2016 Brocade Communications Systems 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. # """Unit tests for brcd fc zone client http(s).""" import time from oslo_utils import encodeutils import mock from mock import patch import six from cinder import exception from cinder import test from cinder.zonemanager.drivers.brocade import (brcd_http_fc_zone_client as client) import cinder.zonemanager.drivers.brocade.fc_zone_constants as zone_constant cfgs = {'openstack_cfg': 'zone1;zone2'} cfgs_to_delete = { 'openstack_cfg': 'zone1;zone2;openstack50060b0000c26604201900051ee8e329'} zones = {'zone1': '20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11', 'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11'} zones_to_delete = { 'zone1': '20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11', 'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11', 'openstack50060b0000c26604201900051ee8e329': '50:06:0b:00:00:c2:66:04;20:19:00:05:1e:e8:e3:29'} alias = {} qlps = {} ifas = {} parsed_raw_zoneinfo = "" random_no = '' auth_version = '' session = None active_cfg = 'openstack_cfg' activate = True no_activate = False vf_enable = True ns_info = ['10:00:00:05:1e:7c:64:96'] nameserver_info = """ NSInfo Page
--BEGIN DEVICEPORT 10:00:00:05:1e:7c:64:96
node.wwn=20:00:00:05:1e:7c:64:96
deviceport.portnum=9
deviceport.portid=300900
deviceport.portIndex=9
deviceport.porttype=N
deviceport.portwwn=10:00:00:05:1e:7c:64:96
--END DEVICEPORT 10:00:00:05:1e:7c:64:96
""" mocked_zone_string = 'zonecfginfo=openstack_cfg zone1;zone2 '\ 'zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 '\ 'zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 '\ 'alia1 10:00:00:05:1e:7c:64:96;10:21:10:05:33:0e:96:12 '\ 'qlp 10:11:f4:ce:46:ae:68:6c;20:11:f4:ce:46:ae:68:6c '\ 'fa1 20:15:f4:ce:96:ae:68:6c;20:11:f4:ce:46:ae:68:6c '\ 'openstack_cfg null &saveonly=false' mocked_zone_string_no_activate = 'zonecfginfo=openstack_cfg zone1;zone2 '\ 'zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 '\ 'zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 '\ 'alia1 10:00:00:05:1e:7c:64:96;10:21:10:05:33:0e:96:12 '\ 'qlp 10:11:f4:ce:46:ae:68:6c;20:11:f4:ce:46:ae:68:6c '\ 'fa1 20:15:f4:ce:96:ae:68:6c;20:11:f4:ce:46:ae:68:6c &saveonly=true' zone_string_to_post = "zonecfginfo=openstack_cfg "\ "openstack50060b0000c26604201900051ee8e329;zone1;zone2 "\ "openstack50060b0000c26604201900051ee8e329 "\ "50:06:0b:00:00:c2:66:04;20:19:00:05:1e:e8:e3:29 "\ "zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 "\ "zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 "\ "openstack_cfg null &saveonly=false" zone_string_to_post_no_activate = "zonecfginfo=openstack_cfg "\ "openstack50060b0000c26604201900051ee8e329;zone1;zone2 "\ "openstack50060b0000c26604201900051ee8e329 "\ "50:06:0b:00:00:c2:66:04;20:19:00:05:1e:e8:e3:29 " \ "zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 "\ "zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 "\ "&saveonly=true" zone_string_to_post_invalid_request = "zonecfginfo=openstack_cfg "\ "openstack50060b0000c26604201900051ee8e32900000000000000000000000000;"\ "zone1;zone2 openstack50060b0000c26604201900051ee8e329000000000000000000000"\ "00000 50:06:0b:00:00:c2:66:04;20:19:00:05:1e:e8:e3:29 "\ "zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 "\ "zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 &saveonly=true" zone_string_del_to_post = "zonecfginfo=openstack_cfg zone1;zone2"\ " zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 "\ "zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 "\ "openstack_cfg null &saveonly=false" zone_string_del_to_post_no_active = "zonecfginfo=openstack_cfg zone1;zone2"\ " zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 " \ "zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 "\ "&saveonly=true" zone_post_page = """
--BEGIN ZONE_TXN_INFO
txnId=34666
adId=0
user=admin
roleUser=admin
openTxnOwner=
openTxnId=0
openTxnAbortable=0
txnStarttime=1421916354
txnEndtime=1421916355
currStateInt=4
prevStateInt=3
actionInt=5
currState=done
prevState=progress
action=error
sessionId=5892021
selfAborted=false
status=done
errorCode=-1
errorMessage=Name too long
--END ZONE_TXN_INFO
""" zone_post_page_no_error = """
--BEGIN ZONE_TXN_INFO
txnId=34666
adId=0
user=admin
roleUser=admin
openTxnOwner=
openTxnId=0
openTxnAbortable=0
txnStarttime=1421916354
txnEndtime=1421916355
currStateInt=4
prevStateInt=3
actionInt=5
currState=done
prevState=progress
action=error
sessionId=5892021
selfAborted=false
status=done
errorCode=0
errorMessage=
--END ZONE_TXN_INFO
""" secinfo_resp = """
--BEGIN SECINFO
SECURITY = OFF
RANDOM = 6281590
DefaultPasswdBitmap = 0
primaryFCS = no
switchType = 66
resource = 10.24.48.210
REALM = FC Switch Administration
AUTHMETHOD = Custom_Basic
hasUpfrontLogin=yes
AUTHVERSION = 1
vfEnabled=false
vfSupported=true
--END SECINFO
""" authenticate_resp = """
--BEGIN AUTHENTICATE
authenticated = yes
username=admin
userrole=admin
adCapable=1
currentAD=AD0
trueADEnvironment=0
adId=0
adList=ALL
contextType=0
--END AUTHENTICATE
""" un_authenticate_resp = """ Authentication
--BEGIN AUTHENTICATE
authenticated = no
errCode = -3
authType = Custom_Basic
realm = FC Switch Administration
--END AUTHENTICATE
""" switch_page_resp = """
--BEGIN SWITCH INFORMATION
didOffset=96
swFWVersion=v7.3.0b_rc1_bld06
swDomain=2
--END SWITCH INFORMATION
""" switch_page_invalid_firm = """
--BEGIN SWITCH INFORMATION
didOffset=96
swFWVersion=v6.1.1
swDomain=2
--END SWITCH INFORMATION
""" parsed_value = """ didOffset=96 swFWVersion=v7.3.0b_rc1_bld06 swDomain=2 """ parsed_session_info_vf = """ sessionId=524461483 user=admin userRole=admin isAdminRole=Yes authSource=0 sessionIp=172.26.1.146 valid=yes adName= adId=128 adCapable=1 currentAD=AD0 currentADId=0 homeAD=AD0 trueADEnvironment=0 adList= adIdList= pfAdmin=0 switchIsMember=0 definedADList=AD0,Physical Fabric definedADIdList=0,255, effectiveADList=AD0,Physical Fabric rc=0 err= contextType=1 vfEnabled=true vfSupported=true HomeVF=128 sessionLFId=2 isContextManageable=1 manageableLFList=2,128, activeLFList=128,2, """ session_info_vf = """
--BEGIN SESSION
sessionId=524461483
user=admin
userRole=admin
isAdminRole=Yes
authSource=0
sessionIp=172.26.1.146
valid=yes
adName=
adId=128
adCapable=1
currentAD=AD0
currentADId=0
homeAD=AD0
trueADEnvironment=0
adList=
adIdList=
pfAdmin=0
switchIsMember=0
definedADList=AD0,Physical Fabric
definedADIdList=0,255,
effectiveADList=AD0,Physical Fabric
rc=0
err=
contextType=1
vfEnabled=true
vfSupported=true
HomeVF=128
sessionLFId=2
isContextManageable=1
manageableLFList=2,128,
activeLFList=128,2,
--END SESSION
""" session_info_vf_not_changed = """
--BEGIN SESSION
sessionId=524461483
user=admin
userRole=admin
isAdminRole=Yes
authSource=0
sessionIp=172.26.1.146
User-Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,
valid=yes
adName=
adId=128
adCapable=1
currentAD=AD0
currentADId=0
homeAD=AD0
trueADEnvironment=0
adList=
adIdList=
pfAdmin=0
switchIsMember=0
definedADList=AD0,Physical Fabric
definedADIdList=0,255,
effectiveADList=AD0,Physical Fabric
rc=0
err=
contextType=1
vfEnabled=true
vfSupported=true
HomeVF=128
sessionLFId=128
isContextManageable=1
manageableLFList=2,128,
activeLFList=128,2,
--END SESSION
""" session_info_AD = """ Webtools Session Info
--BEGIN SESSION
sessionId=-2096740776
user=
userRole=root
isAdminRole=No
authSource=0
sessionIp=
User-Agent=
valid=no
adName=
adId=0
adCapable=1
currentAD=AD0
currentADId=0
homeAD=AD0
trueADEnvironment=0
adList=
adIdList=
pfAdmin=0
switchIsMember=1
definedADList=AD0,Physical Fabric
definedADIdList=0,255,
effectiveADList=AD0,Physical Fabric
rc=-2
err=Could not obtain session data from store
contextType=0
--END SESSION
""" zone_info = """ Zone Configuration Information
--BEGIN ZONE CHANGE
LastZoneChangeTime=1421926251
--END ZONE CHANGE
isZoneTxnSupported=true
ZoneLicense=true
QuickLoopLicense=true
DefZoneStatus=noaccess
McDataDefaultZone=false
McDataSafeZone=false
AvailableZoneSize=1043890
--BEGIN ZONE INFO
openstack_cfg zone1;zone2 """\
"""zone1 20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11 """\
    """zone2 20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11 """\
    """alia1 10:00:00:05:1e:7c:64:96;10:21:10:05:33:0e:96:12 """\
    """qlp 10:11:f4:ce:46:ae:68:6c;20:11:f4:ce:46:ae:68:6c """\
    """fa1 20:15:f4:ce:96:ae:68:6c;20:11:f4:ce:46:ae:68:6c """\
    """openstack_cfg null 1045274"""\
    """--END ZONE INFO
""" active_zone_set = { 'zones': {'zone1': ['20:01:00:05:33:0e:96:15', '20:00:00:05:33:0e:93:11'], 'zone2': ['20:01:00:05:33:0e:96:14', '20:00:00:05:33:0e:93:11']}, 'active_zone_config': 'openstack_cfg'} updated_zones = {'zone1': '20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11', 'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11', 'test_updated_zone': '20:01:00:05:33:0e:96:10;20:00:00:05:33:0e:93:11'} updated_cfgs = {'openstack_cfg': 'test_updated_zone;zone1;zone2'} valid_zone_name = "openstack50060b0000c26604201900051ee8e329" class TestBrcdHttpFCZoneClient(client.BrcdHTTPFCZoneClient, test.TestCase): def setUp(self): self.auth_header = "YWRtaW46cGFzc3dvcmQ6NDM4ODEyNTIw" self.switch_user = "admin" self.switch_pwd = "password" self.protocol = "HTTPS" self.conn = None self.alias = {} self.qlps = {} self.ifas = {} self.parsed_raw_zoneinfo = "" self.random_no = '' self.auth_version = '' self.session = None super(TestBrcdHttpFCZoneClient, self).setUp() # override some of the functions def __init__(self, *args, **kwargs): test.TestCase.__init__(self, *args, **kwargs) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_create_auth_token(self, connect_mock): connect_mock.return_value = secinfo_resp self.assertEqual("Custom_Basic YWRtaW46cGFzc3dvcmQ6NjI4MTU5MA==", self.create_auth_token()) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_authenticate(self, connect_mock): connect_mock.return_value = authenticate_resp self.assertEqual( (True, "Custom_Basic YWRtaW46eHh4Og=="), self.authenticate()) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_authenticate_failed(self, connect_mock): connect_mock.return_value = un_authenticate_resp self.assertRaises( exception.BrocadeZoningHttpException, self.authenticate) def test_get_parsed_data(self): valid_delimiter1 = zone_constant.SWITCHINFO_BEGIN valid_delimiter2 = zone_constant.SWITCHINFO_END invalid_delimiter = "--END SWITCH INFORMATION1" self.assertEqual(parsed_value, self.get_parsed_data( switch_page_resp, valid_delimiter1, valid_delimiter2)) self.assertRaises(exception.BrocadeZoningHttpException, self.get_parsed_data, switch_page_resp, valid_delimiter1, invalid_delimiter) self.assertRaises(exception.BrocadeZoningHttpException, self.get_parsed_data, switch_page_resp, invalid_delimiter, valid_delimiter2) def test_get_nvp_value(self): valid_keyname = zone_constant.FIRMWARE_VERSION invalid_keyname = "swFWVersion1" self.assertEqual( "v7.3.0b_rc1_bld06", self.get_nvp_value(parsed_value, valid_keyname)) self.assertRaises(exception.BrocadeZoningHttpException, self.get_nvp_value, parsed_value, invalid_keyname) def test_get_managable_vf_list(self): manageable_list = ['2', '128'] self.assertEqual( manageable_list, self.get_managable_vf_list(session_info_vf)) self.assertRaises(exception.BrocadeZoningHttpException, self.get_managable_vf_list, session_info_AD) @mock.patch.object(client.BrcdHTTPFCZoneClient, 'is_vf_enabled') def test_check_change_vf_context_vf_enabled(self, is_vf_enabled_mock): is_vf_enabled_mock.return_value = (True, session_info_vf) self.vfid = None self.assertRaises( exception.BrocadeZoningHttpException, self.check_change_vf_context) self.vfid = "2" with mock.patch.object(self, 'change_vf_context') \ as change_vf_context_mock: self.check_change_vf_context() change_vf_context_mock.assert_called_once_with( self.vfid, session_info_vf) @mock.patch.object(client.BrcdHTTPFCZoneClient, 'is_vf_enabled') def test_check_change_vf_context_vf_disabled(self, is_vf_enabled_mock): is_vf_enabled_mock.return_value = (False, session_info_AD) self.vfid = "128" self.assertRaises( exception.BrocadeZoningHttpException, self.check_change_vf_context) @mock.patch.object(client.BrcdHTTPFCZoneClient, 'get_managable_vf_list') @mock.patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_change_vf_context_valid(self, connect_mock, get_managable_vf_list_mock): get_managable_vf_list_mock.return_value = ['2', '128'] connect_mock.return_value = session_info_vf self.assertIsNone(self.change_vf_context("2", session_info_vf)) data = zone_constant.CHANGE_VF.format(vfid="2") headers = {zone_constant.AUTH_HEADER: self.auth_header} connect_mock.assert_called_once_with( zone_constant.POST_METHOD, zone_constant.SESSION_PAGE, data, headers) @mock.patch.object(client.BrcdHTTPFCZoneClient, 'get_managable_vf_list') @mock.patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_change_vf_context_vf_not_changed(self, connect_mock, get_managable_vf_list_mock): get_managable_vf_list_mock.return_value = ['2', '128'] connect_mock.return_value = session_info_vf_not_changed self.assertRaises(exception.BrocadeZoningHttpException, self.change_vf_context, "2", session_info_vf) data = zone_constant.CHANGE_VF.format(vfid="2") headers = {zone_constant.AUTH_HEADER: self.auth_header} connect_mock.assert_called_once_with( zone_constant.POST_METHOD, zone_constant.SESSION_PAGE, data, headers) @mock.patch.object(client.BrcdHTTPFCZoneClient, 'get_managable_vf_list') def test_change_vf_context_vfid_not_managaed(self, get_managable_vf_list_mock): get_managable_vf_list_mock.return_value = ['2', '128'] self.assertRaises(exception.BrocadeZoningHttpException, self.change_vf_context, "12", session_info_vf) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_is_supported_firmware(self, connect_mock): connect_mock.return_value = switch_page_resp self.assertTrue(self.is_supported_firmware()) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_is_supported_firmware_invalid(self, connect_mock): connect_mock.return_value = switch_page_invalid_firm self.assertFalse(self.is_supported_firmware()) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_get_active_zone_set(self, connect_mock): connect_mock.return_value = zone_info returned_zone_map = self.get_active_zone_set() self.assertDictEqual(active_zone_set, returned_zone_map) def test_form_zone_string(self): new_alias = { 'alia1': u'10:00:00:05:1e:7c:64:96;10:21:10:05:33:0e:96:12'} new_qlps = {'qlp': u'10:11:f4:ce:46:ae:68:6c;20:11:f4:ce:46:ae:68:6c'} new_ifas = {'fa1': u'20:15:f4:ce:96:ae:68:6c;20:11:f4:ce:46:ae:68:6c'} self.assertEqual(type(self.form_zone_string( cfgs, active_cfg, zones, new_alias, new_qlps, new_ifas, True)), six.binary_type) self.assertEqual( encodeutils.safe_encode(mocked_zone_string), self.form_zone_string( cfgs, active_cfg, zones, new_alias, new_qlps, new_ifas, True)) self.assertEqual( encodeutils.safe_encode(mocked_zone_string_no_activate), self.form_zone_string( cfgs, active_cfg, zones, new_alias, new_qlps, new_ifas, False)) @patch.object(client.BrcdHTTPFCZoneClient, 'post_zone_data') def test_add_zones_activate(self, post_zone_data_mock): post_zone_data_mock.return_value = ("0", "") self.cfgs = cfgs.copy() self.zones = zones.copy() self.alias = alias.copy() self.qlps = qlps.copy() self.ifas = ifas.copy() self.active_cfg = active_cfg add_zones_info = {valid_zone_name: ['50:06:0b:00:00:c2:66:04', '20:19:00:05:1e:e8:e3:29'] } self.add_zones(add_zones_info, True) post_zone_data_mock.assert_called_once_with( encodeutils.safe_encode(zone_string_to_post)) @patch.object(client.BrcdHTTPFCZoneClient, 'post_zone_data') def test_add_zones_invalid_zone_name(self, post_zone_data_mock): post_zone_data_mock.return_value = ("-1", "Name Too Long") self.cfgs = cfgs.copy() self.zones = zones.copy() self.alias = alias.copy() self.qlps = qlps.copy() self.ifas = ifas.copy() self.active_cfg = active_cfg invalid_zone_name = valid_zone_name + "00000000000000000000000000" add_zones_info = {invalid_zone_name: ['50:06:0b:00:00:c2:66:04', '20:19:00:05:1e:e8:e3:29'] } self.assertRaises( exception.BrocadeZoningHttpException, self.add_zones, add_zones_info, False) @patch.object(client.BrcdHTTPFCZoneClient, 'post_zone_data') def test_add_zones_no_activate(self, post_zone_data_mock): post_zone_data_mock.return_value = ("0", "") self.cfgs = cfgs.copy() self.zones = zones.copy() self.alias = alias.copy() self.qlps = qlps.copy() self.ifas = ifas.copy() self.active_cfg = active_cfg add_zones_info = {valid_zone_name: ['50:06:0b:00:00:c2:66:04', '20:19:00:05:1e:e8:e3:29'] } self.add_zones(add_zones_info, False) post_zone_data_mock.assert_called_once_with( encodeutils.safe_encode(zone_string_to_post_no_activate)) @patch.object(client.BrcdHTTPFCZoneClient, 'post_zone_data') def test_delete_zones_activate(self, post_zone_data_mock): post_zone_data_mock.return_value = ("0", "") self.cfgs = cfgs_to_delete.copy() self.zones = zones_to_delete.copy() self.alias = alias.copy() self.qlps = qlps.copy() self.ifas = ifas.copy() self.active_cfg = active_cfg delete_zones_info = valid_zone_name self.delete_zones(delete_zones_info, True) post_zone_data_mock.assert_called_once_with( encodeutils.safe_encode(zone_string_del_to_post)) @patch.object(client.BrcdHTTPFCZoneClient, 'post_zone_data') def test_delete_zones_no_activate(self, post_zone_data_mock): post_zone_data_mock.return_value = ("0", "") self.cfgs = cfgs_to_delete.copy() self.zones = zones_to_delete.copy() self.alias = alias.copy() self.qlps = qlps.copy() self.ifas = ifas.copy() self.active_cfg = active_cfg delete_zones_info = valid_zone_name self.delete_zones(delete_zones_info, False) post_zone_data_mock.assert_called_once_with( encodeutils.safe_encode(zone_string_del_to_post_no_active)) @patch.object(client.BrcdHTTPFCZoneClient, 'post_zone_data') def test_delete_zones_invalid_zone_name(self, post_zone_data_mock): post_zone_data_mock.return_value = ("0", "") self.cfgs = cfgs_to_delete.copy() self.zones = zones_to_delete.copy() self.alias = alias.copy() self.qlps = qlps.copy() self.ifas = ifas.copy() self.active_cfg = active_cfg delete_zones_info = 'openstack50060b0000c26604201900051ee8e32' self.assertRaises(exception.BrocadeZoningHttpException, self.delete_zones, delete_zones_info, False) @patch.object(time, 'sleep') @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_post_zone_data(self, connect_mock, sleep_mock): connect_mock.return_value = zone_post_page self.assertEqual( ("-1", "Name too long"), self.post_zone_data(zone_string_to_post)) connect_mock.return_value = zone_post_page_no_error self.assertEqual(("0", ""), self.post_zone_data(zone_string_to_post)) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_get_nameserver_info(self, connect_mock): connect_mock.return_value = nameserver_info self.assertEqual(ns_info, self.get_nameserver_info()) @patch.object(client.BrcdHTTPFCZoneClient, 'get_session_info') def test_is_vf_enabled(self, get_session_info_mock): get_session_info_mock.return_value = session_info_vf self.assertEqual((True, parsed_session_info_vf), self.is_vf_enabled()) def test_delete_zones_cfgs(self): cfgs = {'openstack_cfg': 'zone1;zone2'} zones = {'zone1': '20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11', 'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11'} delete_zones_info = valid_zone_name self.assertEqual( (zones, cfgs, active_cfg), self.delete_zones_cfgs( cfgs_to_delete.copy(), zones_to_delete.copy(), delete_zones_info, active_cfg)) cfgs = {'openstack_cfg': 'zone2'} zones = {'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11'} delete_zones_info = valid_zone_name + ";zone1" self.assertEqual( (zones, cfgs, active_cfg), self.delete_zones_cfgs( cfgs_to_delete.copy(), zones_to_delete.copy(), delete_zones_info, active_cfg)) def test_add_zones_cfgs(self): add_zones_info = {valid_zone_name: ['50:06:0b:00:00:c2:66:04', '20:19:00:05:1e:e8:e3:29'] } updated_cfgs = { 'openstack_cfg': valid_zone_name + ';zone1;zone2'} updated_zones = { 'zone1': '20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11', 'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11', valid_zone_name: '50:06:0b:00:00:c2:66:04;20:19:00:05:1e:e8:e3:29'} self.assertEqual((updated_zones, updated_cfgs, active_cfg), self.add_zones_cfgs( cfgs.copy(), zones.copy(), add_zones_info, active_cfg, "openstack_cfg")) add_zones_info = {valid_zone_name: ['50:06:0b:00:00:c2:66:04', '20:19:00:05:1e:e8:e3:29'], 'test4': ['20:06:0b:00:00:b2:66:07', '20:10:00:05:1e:b8:c3:19'] } updated_cfgs = { 'openstack_cfg': 'test4;openstack50060b0000c26604201900051ee8e329;zone1;zone2'} updated_zones = { 'zone1': '20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11', 'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11', valid_zone_name: '50:06:0b:00:00:c2:66:04;20:19:00:05:1e:e8:e3:29', 'test4': '20:06:0b:00:00:b2:66:07;20:10:00:05:1e:b8:c3:19'} result = self.add_zones_cfgs(cfgs.copy(), zones.copy(), add_zones_info, active_cfg, "openstack_cfg") self.assertEqual(updated_zones, result[0]) self.assertEqual(active_cfg, result[2]) result_cfg = result[1]['openstack_cfg'] self.assertIn('test4', result_cfg) self.assertIn('openstack50060b0000c26604201900051ee8e329', result_cfg) self.assertIn('zone1', result_cfg) self.assertIn('zone2', result_cfg) @patch.object(client.BrcdHTTPFCZoneClient, 'connect') def test_get_zone_info(self, connect_mock): connect_mock.return_value = zone_info self.get_zone_info() self.assertEqual({'openstack_cfg': 'zone1;zone2'}, self.cfgs) self.assertEqual( {'zone1': '20:01:00:05:33:0e:96:15;20:00:00:05:33:0e:93:11', 'zone2': '20:01:00:05:33:0e:96:14;20:00:00:05:33:0e:93:11'}, self.zones) self.assertEqual('openstack_cfg', self.active_cfg) self.assertEqual( {'alia1': '10:00:00:05:1e:7c:64:96;10:21:10:05:33:0e:96:12'}, self.alias) self.assertEqual( {'fa1': '20:15:f4:ce:96:ae:68:6c;20:11:f4:ce:46:ae:68:6c'}, self.ifas) self.assertEqual( {'qlp': '10:11:f4:ce:46:ae:68:6c;20:11:f4:ce:46:ae:68:6c'}, self.qlps)