# (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 unittest import mock from unittest.mock import patch from oslo_utils import encodeutils from cinder.tests.unit import test from cinder.zonemanager.drivers.brocade import (brcd_http_fc_zone_client as client) from cinder.zonemanager.drivers.brocade import exception as b_exception 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 = """
--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 = """
--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 = """
--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 = """
--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( b_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(b_exception.BrocadeZoningHttpException, self.get_parsed_data, switch_page_resp, valid_delimiter1, invalid_delimiter) self.assertRaises(b_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(b_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(b_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( b_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( b_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(b_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(b_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)), bytes) 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( b_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(b_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': 'openstack50060b0000c26604201900051ee8e329'} res = self.delete_zones_cfgs(cfgs, zones_to_delete.copy(), delete_zones_info, active_cfg) self.assertEqual((zones, {}, ''), res) 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)