text: #    (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
  import six
  
  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 = """
  <HTML>
  <HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Expires" CONTENT="-1">
  <TITLE>NSInfo Page</TITLE>
  </HEAD>
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>
  </HTML>
  """
  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 = """
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>"""
  zone_post_page_no_error = """
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>"""
  secinfo_resp = """
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>
  """
  authenticate_resp = """<HTML>
  <PRE>
  --BEGIN AUTHENTICATE
  authenticated = yes
  username=admin
  userrole=admin
  adCapable=1
  currentAD=AD0
  trueADEnvironment=0
  adId=0
  adList=ALL
  contextType=0
  --END AUTHENTICATE
  </PRE>
  </BODY>
  """
  un_authenticate_resp = """<HTML>
  <HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Expires" CONTENT="-1">
  <TITLE>Authentication</TITLE>
  </HEAD>
  <BODY>
  <PRE>
  --BEGIN AUTHENTICATE
  authenticated = no
  errCode = -3
  authType = Custom_Basic
  realm = FC Switch Administration
  --END AUTHENTICATE
  </PRE>
  </BODY>
  </HTML>"""
  switch_page_resp = """<HTML>
  <HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Expires" CONTENT="-1">
  </HEAD>
  <BODY>
  <PRE>
  --BEGIN SWITCH INFORMATION
  didOffset=96
  swFWVersion=v7.3.0b_rc1_bld06
  swDomain=2
  --END SWITCH INFORMATION
  </PRE>
  </BODY>
  </HTML>
  """
  switch_page_invalid_firm = """<HTML>
  <HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Expires" CONTENT="-1">
  </HEAD>
  <BODY>
  <PRE>
  --BEGIN SWITCH INFORMATION
  didOffset=96
  swFWVersion=v6.1.1
  swDomain=2
  --END SWITCH INFORMATION
  </PRE>
  </BODY>
  </HTML>
  """
  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 = """
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>
  """
  session_info_vf_not_changed = """
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>
  """
  session_info_AD = """<HTML>
  <HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Expires" CONTENT="-1">
  <TITLE>Webtools Session Info</TITLE>
  </HEAD>
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>
  </HTML>
  """
  zone_info = """<HTML>
  <HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Expires" CONTENT="-1">
  <TITLE>Zone Configuration Information</TITLE>
  </HEAD>
  <BODY>
  <PRE>
  --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
  </PRE>
  </BODY>
  </HTML>
  
  """
  
  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)),
              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(
              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': '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)
  