Coverage for manila/tests/share/drivers/dell_emc/common/enas/test_connector.py: 100%
114 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright (c) 2015 EMC Corporation.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16from unittest import mock
17from urllib import error as url_error
18from urllib import request as url_request
20from eventlet import greenthread
21from oslo_concurrency import processutils
23from manila import exception
24from manila.share import configuration as conf
25from manila.share.drivers.dell_emc.common.enas import connector
26from manila import ssh_utils
27from manila import test
28from manila.tests.share.drivers.dell_emc.common.enas import fakes
29from manila.tests.share.drivers.dell_emc.common.enas import utils as enas_utils
32class XMLAPIConnectorTestData(object):
33 FAKE_BODY = '<fakebody></fakebody>'
34 FAKE_RESP = '<Response></Response>'
35 FAKE_METHOD = 'fake_method'
37 FAKE_KEY = 'key'
38 FAKE_VALUE = 'value'
40 @staticmethod
41 def req_auth_url():
42 return 'https://' + fakes.FakeData.emc_nas_server + '/Login'
44 @staticmethod
45 def req_credential():
46 return (
47 'user=' + fakes.FakeData.emc_nas_login
48 + '&password=' + fakes.FakeData.emc_nas_password
49 + '&Login=Login'
50 ).encode()
52 @staticmethod
53 def req_url_encode():
54 return {'Content-Type': 'application/x-www-form-urlencoded'}
56 @staticmethod
57 def req_url():
58 return (
59 'https://'
60 + fakes.FakeData.emc_nas_server
61 + '/servlets/CelerraManagementServices'
62 )
65XML_CONN_TD = XMLAPIConnectorTestData
68class XMLAPIConnectorTest(test.TestCase):
69 @mock.patch.object(url_request, 'Request', mock.Mock())
70 def setUp(self):
71 super(XMLAPIConnectorTest, self).setUp()
73 emc_share_driver = fakes.FakeEMCShareDriver()
75 self.configuration = emc_share_driver.configuration
77 xml_socket = mock.Mock()
78 xml_socket.read = mock.Mock(return_value=XML_CONN_TD.FAKE_RESP)
79 opener = mock.Mock()
80 opener.open = mock.Mock(return_value=xml_socket)
82 with mock.patch.object(url_request, 'build_opener',
83 mock.Mock(return_value=opener)):
84 self.XmlConnector = connector.XMLAPIConnector(
85 configuration=self.configuration, debug=False)
87 expected_calls = [
88 mock.call(XML_CONN_TD.req_auth_url(),
89 XML_CONN_TD.req_credential(),
90 XML_CONN_TD.req_url_encode()),
91 ]
93 url_request.Request.assert_has_calls(expected_calls)
95 def test_request_with_debug(self):
96 self.XmlConnector.debug = True
98 request = mock.Mock()
99 request.headers = {XML_CONN_TD.FAKE_KEY: XML_CONN_TD.FAKE_VALUE}
100 request.get_full_url = mock.Mock(
101 return_value=XML_CONN_TD.FAKE_VALUE)
103 with mock.patch.object(url_request, 'Request',
104 mock.Mock(return_value=request)):
105 rsp = self.XmlConnector.request(XML_CONN_TD.FAKE_BODY,
106 XML_CONN_TD.FAKE_METHOD)
108 self.assertEqual(XML_CONN_TD.FAKE_RESP, rsp)
110 def test_request_with_no_authorized_exception(self):
111 xml_socket = mock.Mock()
112 xml_socket.read = mock.Mock(return_value=XML_CONN_TD.FAKE_RESP)
114 hook = enas_utils.RequestSideEffect()
115 hook.append(ex=url_error.HTTPError(XML_CONN_TD.req_url(),
116 '403', 'fake_message', None, None))
117 hook.append(xml_socket)
118 hook.append(xml_socket)
120 self.XmlConnector.url_opener.open = mock.Mock(side_effect=hook)
122 self.XmlConnector.request(XML_CONN_TD.FAKE_BODY)
124 def test_request_with_general_exception(self):
125 hook = enas_utils.RequestSideEffect()
126 hook.append(ex=url_error.HTTPError(XML_CONN_TD.req_url(),
127 'error_code', 'fake_message',
128 None, None))
129 self.XmlConnector.url_opener.open = mock.Mock(side_effect=hook)
131 self.assertRaises(exception.ManilaException,
132 self.XmlConnector.request,
133 XML_CONN_TD.FAKE_BODY)
136class MockSSH(object):
137 def __enter__(self):
138 return self
140 def __exit__(self, type, value, traceback):
141 pass
144class MockSSHPool(object):
145 def __init__(self):
146 self.ssh = MockSSH()
148 def item(self):
149 try:
150 return self.ssh
151 finally:
152 pass
155class CmdConnectorTest(test.TestCase):
156 def setUp(self):
157 super(CmdConnectorTest, self).setUp()
159 self.configuration = conf.Configuration(None)
160 self.configuration.append_config_values = mock.Mock(return_value=0)
161 self.configuration.emc_nas_login = fakes.FakeData.emc_nas_login
162 self.configuration.emc_nas_password = fakes.FakeData.emc_nas_password
163 self.configuration.emc_nas_server = fakes.FakeData.emc_nas_server
164 self.configuration.emc_ssl_cert_verify = False
165 self.configuration.emc_ssl_cert_path = None
167 self.sshpool = MockSSHPool()
168 with mock.patch.object(ssh_utils, "SSHPool",
169 mock.Mock(return_value=self.sshpool)):
170 self.CmdHelper = connector.SSHConnector(
171 configuration=self.configuration, debug=False)
173 ssh_utils.SSHPool.assert_called_once_with(
174 ip=fakes.FakeData.emc_nas_server,
175 port=22,
176 conn_timeout=None,
177 login=fakes.FakeData.emc_nas_login,
178 password=fakes.FakeData.emc_nas_password)
180 def test_run_ssh(self):
181 with mock.patch.object(processutils, "ssh_execute",
182 mock.Mock(return_value=('fake_output', ''))):
183 cmd_list = ['fake', 'cmd']
184 self.CmdHelper.run_ssh(cmd_list)
186 processutils.ssh_execute.assert_called_once_with(
187 self.sshpool.item(), 'fake cmd', check_exit_code=False)
189 def test_run_ssh_with_debug(self):
190 self.CmdHelper.debug = True
192 with mock.patch.object(processutils, "ssh_execute",
193 mock.Mock(return_value=('fake_output', ''))):
194 cmd_list = ['fake', 'cmd']
195 self.CmdHelper.run_ssh(cmd_list)
197 processutils.ssh_execute.assert_called_once_with(
198 self.sshpool.item(), 'fake cmd', check_exit_code=False)
200 @mock.patch.object(
201 processutils, "ssh_execute",
202 mock.Mock(side_effect=processutils.ProcessExecutionError))
203 def test_run_ssh_exception(self):
204 cmd_list = ['fake', 'cmd']
206 self.mock_object(greenthread, 'sleep', mock.Mock())
208 sshpool = MockSSHPool()
210 with mock.patch.object(ssh_utils, "SSHPool",
211 mock.Mock(return_value=sshpool)):
212 self.CmdHelper = connector.SSHConnector(self.configuration)
214 self.assertRaises(processutils.ProcessExecutionError,
215 self.CmdHelper.run_ssh,
216 cmd_list,
217 True)
219 ssh_utils.SSHPool.assert_called_once_with(
220 ip=fakes.FakeData.emc_nas_server,
221 port=22,
222 conn_timeout=None,
223 login=fakes.FakeData.emc_nas_login,
224 password=fakes.FakeData.emc_nas_password)
226 processutils.ssh_execute.assert_called_once_with(
227 sshpool.item(), 'fake cmd', check_exit_code=True)