Coverage for manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py: 99%
858 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 2015 Hewlett Packard Enterprise Development LP
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
15import sys
16from unittest import mock
18import ddt
19if 'hpe3parclient' not in sys.modules: 19 ↛ 20line 19 didn't jump to line 20 because the condition on line 19 was never true
20 sys.modules['hpe3parclient'] = mock.Mock()
21from oslo_utils import units
23from manila.data import utils as data_utils
24from manila import exception
25from manila.share.drivers.hpe import hpe_3par_mediator as hpe3parmediator
26from manila import test
27from manila.tests.share.drivers.hpe import test_hpe_3par_constants as constants
28from manila import utils
31CLIENT_VERSION_MIN_OK = hpe3parmediator.MIN_CLIENT_VERSION
32TEST_WSAPI_VERSION_STR = '30201292'
35@ddt.ddt
36class HPE3ParMediatorTestCase(test.TestCase):
38 def setUp(self):
39 super(HPE3ParMediatorTestCase, self).setUp()
41 # Fake utils.execute
42 self.mock_object(utils, 'execute', mock.Mock(return_value={}))
44 # Fake data_utils.Copy
45 class FakeCopy(object):
47 def run(self):
48 pass
50 def get_progress(self):
51 return {'total_progress': 100}
53 self.mock_copy = self.mock_object(
54 data_utils, 'Copy', mock.Mock(return_value=FakeCopy()))
56 # This is the fake client to use.
57 self.mock_client = mock.Mock()
59 # Take over the hpe3parclient module and stub the constructor.
60 hpe3parclient = sys.modules['hpe3parclient']
61 hpe3parclient.version_tuple = CLIENT_VERSION_MIN_OK
63 # Need a fake constructor to return the fake client.
64 # This is also be used for constructor error tests.
65 self.mock_object(hpe3parclient.file_client, 'HPE3ParFilePersonaClient')
66 self.mock_client_constructor = (
67 hpe3parclient.file_client.HPE3ParFilePersonaClient
68 )
69 self.mock_client = self.mock_client_constructor()
71 # Set the mediator to use in tests.
72 self.mediator = hpe3parmediator.HPE3ParMediator(
73 hpe3par_username=constants.USERNAME,
74 hpe3par_password=constants.PASSWORD,
75 hpe3par_api_url=constants.API_URL,
76 hpe3par_debug=constants.EXPECTED_HPE_DEBUG,
77 hpe3par_san_ip=constants.EXPECTED_IP_1234,
78 hpe3par_san_login=constants.SAN_LOGIN,
79 hpe3par_san_password=constants.SAN_PASSWORD,
80 hpe3par_san_ssh_port=constants.PORT,
81 hpe3par_cifs_admin_access_username=constants.USERNAME,
82 hpe3par_cifs_admin_access_password=constants.PASSWORD,
83 hpe3par_cifs_admin_access_domain=constants.EXPECTED_CIFS_DOMAIN,
84 hpe3par_share_mount_path=constants.EXPECTED_MOUNT_PATH,
85 ssh_conn_timeout=constants.TIMEOUT,
86 my_ip=constants.EXPECTED_MY_IP)
88 def test_mediator_no_client(self):
89 """Test missing hpe3parclient error."""
91 mock_log = self.mock_object(hpe3parmediator, 'LOG')
92 self.mock_object(hpe3parmediator.HPE3ParMediator, 'no_client', None)
94 self.assertRaises(exception.HPE3ParInvalidClient,
95 self.mediator.do_setup)
97 mock_log.error.assert_called_once_with(mock.ANY)
99 def test_mediator_setup_client_init_error(self):
100 """Any client init exceptions should result in a ManilaException."""
102 self.mock_client_constructor.side_effect = (
103 Exception('Any exception. E.g., bad version or some other '
104 'non-Manila Exception.'))
105 self.assertRaises(exception.ManilaException, self.mediator.do_setup)
107 def test_mediator_setup_client_ssh_error(self):
109 # This could be anything the client comes up with, but the
110 # mediator should turn it into a ManilaException.
111 non_manila_exception = Exception('non-manila-except')
112 self.mock_client.setSSHOptions.side_effect = non_manila_exception
114 self.assertRaises(exception.ManilaException, self.mediator.do_setup)
115 self.mock_client.assert_has_calls(
116 [mock.call.setSSHOptions(constants.EXPECTED_IP_1234,
117 constants.SAN_LOGIN,
118 constants.SAN_PASSWORD,
119 port=constants.PORT,
120 conn_timeout=constants.TIMEOUT)])
122 def test_mediator_vfs_exception(self):
123 """Backend exception during get_vfs."""
125 self.init_mediator()
126 self.mock_client.getvfs.side_effect = Exception('non-manila-except')
127 self.assertRaises(exception.ManilaException,
128 self.mediator.get_vfs,
129 fpg=constants.EXPECTED_FPG)
130 expected_calls = [
131 mock.call.getvfs(fpg=constants.EXPECTED_FPG, vfs=None),
132 ]
133 self.mock_client.assert_has_calls(expected_calls)
135 def test_mediator_vfs_not_found(self):
136 """VFS not found."""
137 self.init_mediator()
138 self.mock_client.getvfs.return_value = {'total': 0}
139 self.assertRaises(exception.ManilaException,
140 self.mediator.get_vfs,
141 fpg=constants.EXPECTED_FPG)
142 expected_calls = [
143 mock.call.getvfs(fpg=constants.EXPECTED_FPG, vfs=None),
144 ]
145 self.mock_client.assert_has_calls(expected_calls)
147 @ddt.data((constants.EXPECTED_CLIENT_GET_VFS_RETURN_VALUE,
148 constants.EXPECTED_MEDIATOR_GET_VFS_RET_VAL),
149 (constants.EXPECTED_CLIENT_GET_VFS_RETURN_VALUE_MULTI,
150 constants.EXPECTED_MEDIATOR_GET_VFS_RET_VAL_MULTI))
151 @ddt.unpack
152 def test_mediator_get_vfs(self, get_vfs_val, exp_vfs_val):
153 """VFS not found."""
154 self.init_mediator()
155 self.mock_client.getvfs.return_value = get_vfs_val
157 ret_val = self.mediator.get_vfs(constants.EXPECTED_FPG)
158 self.assertEqual(exp_vfs_val, ret_val)
159 expected_calls = [
160 mock.call.getvfs(fpg=constants.EXPECTED_FPG, vfs=None),
161 ]
162 self.mock_client.assert_has_calls(expected_calls)
164 def init_mediator(self):
165 """Basic mediator setup for re-use with tests that need one."""
167 self.mock_client.getWsApiVersion.return_value = {
168 'build': TEST_WSAPI_VERSION_STR,
169 }
171 self.mock_client.getvfs.return_value = {
172 'total': 1,
173 'members': [{'vfsname': constants.EXPECTED_VFS}]
174 }
175 self.mock_client.getfshare.return_value = {
176 'total': 1,
177 'members': [
178 {'fstoreName': constants.EXPECTED_FSTORE,
179 'shareName': constants.EXPECTED_SHARE_ID,
180 'shareDir': constants.EXPECTED_SHARE_PATH,
181 'share_proto': constants.NFS,
182 'sharePath': constants.EXPECTED_SHARE_PATH,
183 'comment': constants.EXPECTED_COMMENT,
184 }]
185 }
186 self.mock_client.setfshare.return_value = []
187 self.mock_client.setfsquota.return_value = []
188 self.mock_client.getfsquota.return_value = constants.GET_FSQUOTA
189 self.mediator.do_setup()
191 def test_mediator_setup_success(self):
192 """Do a mediator setup without errors."""
194 self.init_mediator()
195 self.assertIsNotNone(self.mediator._client)
197 expected_calls = [
198 mock.call.setSSHOptions(constants.EXPECTED_IP_1234,
199 constants.SAN_LOGIN,
200 constants.SAN_PASSWORD,
201 port=constants.PORT,
202 conn_timeout=constants.TIMEOUT),
203 mock.call.getWsApiVersion(),
204 mock.call.debug_rest(constants.EXPECTED_HPE_DEBUG)
205 ]
206 self.mock_client.assert_has_calls(expected_calls)
208 def test_mediator_client_login_error(self):
209 """Test exception during login."""
210 self.init_mediator()
212 self.mock_client.login.side_effect = constants.FAKE_EXCEPTION
214 self.assertRaises(exception.ShareBackendException,
215 self.mediator._wsapi_login)
217 expected_calls = [mock.call.login(constants.USERNAME,
218 constants.PASSWORD)]
219 self.mock_client.assert_has_calls(expected_calls)
221 def test_mediator_client_logout_error(self):
222 """Test exception during logout."""
223 self.init_mediator()
225 mock_log = self.mock_object(hpe3parmediator, 'LOG')
226 fake_exception = constants.FAKE_EXCEPTION
227 self.mock_client.http.unauthenticate.side_effect = fake_exception
229 self.mediator._wsapi_logout()
231 # Warning is logged (no exception thrown).
232 self.assertTrue(mock_log.warning.called)
233 expected_calls = [mock.call.http.unauthenticate()]
234 self.mock_client.assert_has_calls(expected_calls)
236 def test_mediator_client_version_unsupported(self):
237 """Try a client with version less than minimum."""
239 self.hpe3parclient = sys.modules['hpe3parclient']
240 self.hpe3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0],
241 CLIENT_VERSION_MIN_OK[1],
242 CLIENT_VERSION_MIN_OK[2] - 1)
243 mock_log = self.mock_object(hpe3parmediator, 'LOG')
245 self.assertRaises(exception.HPE3ParInvalidClient,
246 self.init_mediator)
248 mock_log.error.assert_called_once_with(mock.ANY)
250 def test_mediator_client_version_supported(self):
251 """Try a client with a version greater than the minimum."""
253 # The setup success already tests the min version. Try version > min.
254 self.hpe3parclient = sys.modules['hpe3parclient']
255 self.hpe3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0],
256 CLIENT_VERSION_MIN_OK[1],
257 CLIENT_VERSION_MIN_OK[2] + 1)
258 self.init_mediator()
259 expected_calls = [
260 mock.call.setSSHOptions(constants.EXPECTED_IP_1234,
261 constants.SAN_LOGIN,
262 constants.SAN_PASSWORD,
263 port=constants.PORT,
264 conn_timeout=constants.TIMEOUT),
265 mock.call.getWsApiVersion(),
266 mock.call.debug_rest(constants.EXPECTED_HPE_DEBUG)
267 ]
268 self.mock_client.assert_has_calls(expected_calls)
270 def test_mediator_client_version_exception(self):
271 """Test the getWsApiVersion exception handling."""
273 self.mock_client.getWsApiVersion.side_effect = constants.FAKE_EXCEPTION
274 self.assertRaises(exception.ShareBackendException,
275 self.init_mediator)
277 def test_mediator_client_version_bad_return_value(self):
278 """Test the getWsApiVersion exception handling with bad value."""
280 # Expecting a dict with 'build' in it. This would fail badly.
281 self.mock_client.getWsApiVersion.return_value = 'bogus'
282 self.assertRaises(exception.ShareBackendException,
283 self.mediator.do_setup)
285 def get_expected_calls_for_create_share(self,
286 client_version,
287 expected_fpg,
288 expected_vfsname,
289 expected_protocol,
290 extra_specs,
291 expected_project_id,
292 expected_share_id):
293 expected_sharedir = expected_share_id
295 createfshare_kwargs = dict(comment=mock.ANY,
296 fpg=expected_fpg,
297 sharedir=expected_sharedir,
298 fstore=expected_project_id)
300 if expected_protocol == constants.NFS_LOWER:
302 createfshare_kwargs['clientip'] = '127.0.0.1'
304 # Options from extra-specs.
305 opt_string = extra_specs.get('hpe3par:nfs_options', [])
306 opt_list = opt_string.split(',')
307 # Options that the mediator adds.
308 nfs_options = ['rw', 'no_root_squash', 'insecure']
309 nfs_options += opt_list
310 expected_options = ','.join(nfs_options)
312 createfshare_kwargs['options'] = OptionMatcher(
313 self.assertListEqual, expected_options)
315 expected_calls = [
316 mock.call.createfstore(expected_vfsname, expected_project_id,
317 comment=mock.ANY,
318 fpg=expected_fpg),
319 mock.call.getfsquota(fpg=expected_fpg,
320 vfs=expected_vfsname,
321 fstore=expected_project_id),
322 mock.call.setfsquota(expected_vfsname,
323 fpg=expected_fpg,
324 hcapacity='2048',
325 scapacity='2048',
326 fstore=expected_project_id),
327 mock.call.createfshare(expected_protocol, expected_vfsname,
328 expected_share_id,
329 **createfshare_kwargs),
330 mock.call.getfshare(expected_protocol, expected_share_id,
331 fpg=expected_fpg, vfs=expected_vfsname,
332 fstore=expected_project_id)]
333 else:
335 smb_opts = (hpe3parmediator.ACCESS_BASED_ENUM,
336 hpe3parmediator.CONTINUOUS_AVAIL,
337 hpe3parmediator.CACHE)
339 for smb_opt in smb_opts:
340 opt_value = extra_specs.get('hpe3par:smb_%s' % smb_opt)
341 if opt_value:
342 opt_key = hpe3parmediator.SMB_EXTRA_SPECS_MAP[smb_opt]
343 createfshare_kwargs[opt_key] = opt_value
345 expected_calls = [
346 mock.call.createfstore(expected_vfsname, expected_project_id,
347 comment=mock.ANY,
348 fpg=expected_fpg),
349 mock.call.getfsquota(fpg=expected_fpg,
350 vfs=expected_vfsname,
351 fstore=expected_project_id),
352 mock.call.setfsquota(expected_vfsname,
353 fpg=expected_fpg,
354 hcapacity='2048',
355 scapacity='2048',
356 fstore=expected_project_id),
357 mock.call.createfshare(expected_protocol, expected_vfsname,
358 expected_share_id,
359 **createfshare_kwargs),
360 mock.call.getfshare(expected_protocol, expected_share_id,
361 fpg=expected_fpg, vfs=expected_vfsname,
362 fstore=expected_project_id)]
363 return expected_calls
365 @staticmethod
366 def _build_smb_extra_specs(**kwargs):
367 extra_specs = {'driver_handles_share_servers': False}
368 for k, v in kwargs.items():
369 extra_specs['hpe3par:smb_%s' % k] = v
370 return extra_specs
372 @ddt.data(((4, 0, 0), None, None, None),
373 ((4, 0, 0), 'true', None, None),
374 ((4, 0, 0), None, 'false', None),
375 ((4, 0, 0), None, 'false', None),
376 ((4, 0, 0), None, None, 'optimized'),
377 ((4, 0, 0), 'true', 'false', 'optimized'))
378 @ddt.unpack
379 def test_mediator_create_cifs_share(self, client_version, abe, ca, cache):
380 self.hpe3parclient = sys.modules['hpe3parclient']
381 self.hpe3parclient.version_tuple = client_version
382 self.init_mediator()
384 self.mock_client.getfshare.return_value = {
385 'message': None,
386 'total': 1,
387 'members': [{'shareName': constants.EXPECTED_SHARE_NAME}]
388 }
390 extra_specs = self._build_smb_extra_specs(access_based_enum=abe,
391 continuous_avail=ca,
392 cache=cache)
394 location = self.mediator.create_share(constants.EXPECTED_PROJECT_ID,
395 constants.EXPECTED_SHARE_ID,
396 constants.CIFS,
397 extra_specs,
398 constants.EXPECTED_FPG,
399 constants.EXPECTED_VFS,
400 size=constants.EXPECTED_SIZE_1)
402 self.assertEqual(constants.EXPECTED_SHARE_NAME, location)
404 expected_calls = self.get_expected_calls_for_create_share(
405 client_version,
406 constants.EXPECTED_FPG,
407 constants.EXPECTED_VFS,
408 constants.SMB_LOWER,
409 extra_specs,
410 constants.EXPECTED_PROJECT_ID,
411 constants.EXPECTED_SHARE_ID)
413 self.mock_client.assert_has_calls(expected_calls)
415 @ddt.data('ro',
416 'rw',
417 'no_root_squash',
418 'root_squash',
419 'secure',
420 'insecure',
421 'hide,insecure,no_wdelay,ro,bogus,root_squash,test')
422 def test_mediator_create_nfs_share_bad_options(self, nfs_options):
423 self.init_mediator()
425 extra_specs = {'hpe3par:nfs_options': nfs_options}
427 self.assertRaises(exception.InvalidInput,
428 self.mediator.create_share,
429 constants.EXPECTED_PROJECT_ID,
430 constants.EXPECTED_SHARE_ID,
431 constants.NFS.lower(),
432 extra_specs,
433 constants.EXPECTED_FPG,
434 constants.EXPECTED_VFS,
435 size=constants.EXPECTED_SIZE_1)
437 self.assertFalse(self.mock_client.createfshare.called)
439 @ddt.data('sync',
440 'no_wdelay,sec=sys,hide,sync')
441 def test_mediator_create_nfs_share(self, nfs_options):
442 self.init_mediator()
444 self.mock_client.getfshare.return_value = {
445 'message': None,
446 'total': 1,
447 'members': [{'sharePath': constants.EXPECTED_SHARE_PATH}]
448 }
450 extra_specs = {'hpe3par:nfs_options': nfs_options}
452 location = self.mediator.create_share(constants.EXPECTED_PROJECT_ID,
453 constants.EXPECTED_SHARE_ID,
454 constants.NFS.lower(),
455 extra_specs,
456 constants.EXPECTED_FPG,
457 constants.EXPECTED_VFS,
458 size=constants.EXPECTED_SIZE_1)
460 self.assertEqual(constants.EXPECTED_SHARE_PATH, location)
462 expected_calls = self.get_expected_calls_for_create_share(
463 hpe3parmediator.MIN_CLIENT_VERSION,
464 constants.EXPECTED_FPG,
465 constants.EXPECTED_VFS,
466 constants.NFS.lower(),
467 extra_specs,
468 constants.EXPECTED_PROJECT_ID,
469 constants.EXPECTED_SHARE_ID)
471 self.mock_client.assert_has_calls(expected_calls)
473 def test_mediator_create_nfs_share_get_exception(self):
474 self.init_mediator()
476 self.mock_client.getfshare.side_effect = constants.FAKE_EXCEPTION
478 self.assertRaises(exception.ShareBackendException,
479 self.mediator.create_share,
480 constants.EXPECTED_PROJECT_ID,
481 constants.EXPECTED_SHARE_ID,
482 constants.NFS.lower(),
483 constants.EXPECTED_EXTRA_SPECS,
484 constants.EXPECTED_FPG,
485 constants.EXPECTED_VFS,
486 size=constants.EXPECTED_SIZE_1)
488 @ddt.data(0, 2)
489 def test_mediator_create_nfs_share_get_fail(self, count):
490 self.init_mediator()
492 self.mock_client.getfshare.return_value = {'total': count}
494 self.assertRaises(exception.ShareBackendException,
495 self.mediator.create_share,
496 constants.EXPECTED_PROJECT_ID,
497 constants.EXPECTED_SHARE_ID,
498 constants.NFS.lower(),
499 constants.EXPECTED_EXTRA_SPECS,
500 constants.EXPECTED_FPG,
501 constants.EXPECTED_VFS,
502 size=constants.EXPECTED_SIZE_1)
504 @ddt.data(True, False)
505 def test_mediator_create_cifs_share_from_snapshot(self, require_cifs_ip):
506 self.init_mediator()
507 self.mediator.hpe3par_require_cifs_ip = require_cifs_ip
509 self.mock_client.getfsnap.return_value = {
510 'message': None,
511 'total': 1,
512 'members': [{'snapName': constants.EXPECTED_SNAP_ID,
513 'fstoreName': constants.EXPECTED_FSTORE}]
514 }
516 location = self.mediator.create_share_from_snapshot(
517 constants.EXPECTED_SHARE_ID,
518 constants.CIFS,
519 constants.EXPECTED_EXTRA_SPECS,
520 constants.EXPECTED_PROJECT_ID,
521 constants.EXPECTED_SHARE_ID,
522 constants.EXPECTED_SNAP_ID,
523 constants.EXPECTED_FPG,
524 constants.EXPECTED_VFS,
525 [constants.EXPECTED_IP_10203040])
527 self.assertEqual(constants.EXPECTED_SHARE_ID, location)
529 expected_kwargs_ro = {
530 'comment': mock.ANY,
531 'fpg': constants.EXPECTED_FPG,
532 'fstore': constants.EXPECTED_FSTORE,
533 }
534 expected_kwargs_rw = expected_kwargs_ro.copy()
536 expected_kwargs_ro['sharedir'] = '.snapshot/%s/%s' % (
537 constants.EXPECTED_SNAP_ID, constants.EXPECTED_SHARE_ID)
538 expected_kwargs_rw['sharedir'] = constants.EXPECTED_SHARE_ID
540 if require_cifs_ip:
541 expected_kwargs_ro['allowip'] = constants.EXPECTED_MY_IP
542 expected_kwargs_rw['allowip'] = (
543 ','.join((constants.EXPECTED_MY_IP,
544 constants.EXPECTED_IP_127)))
546 expected_calls = [
547 mock.call.getfsnap('*_%s' % constants.EXPECTED_SNAP_ID,
548 vfs=constants.EXPECTED_VFS,
549 fpg=constants.EXPECTED_FPG,
550 pat=True,
551 fstore=constants.EXPECTED_FSTORE),
552 mock.call.createfshare(constants.SMB_LOWER,
553 constants.EXPECTED_VFS,
554 constants.EXPECTED_SHARE_ID,
555 **expected_kwargs_ro),
556 mock.call.getfshare(constants.SMB_LOWER,
557 constants.EXPECTED_SHARE_ID,
558 fpg=constants.EXPECTED_FPG,
559 vfs=constants.EXPECTED_VFS,
560 fstore=constants.EXPECTED_FSTORE),
561 mock.call.createfshare(constants.SMB_LOWER,
562 constants.EXPECTED_VFS,
563 constants.EXPECTED_SHARE_ID,
564 **expected_kwargs_rw),
565 mock.call.getfshare(constants.SMB_LOWER,
566 constants.EXPECTED_SHARE_ID,
567 fpg=constants.EXPECTED_FPG,
568 vfs=constants.EXPECTED_VFS,
569 fstore=constants.EXPECTED_FSTORE),
570 mock.call.setfshare(constants.SMB_LOWER,
571 constants.EXPECTED_VFS,
572 constants.EXPECTED_SHARE_ID,
573 allowperm=constants.ADD_USERNAME,
574 comment=mock.ANY,
575 fpg=constants.EXPECTED_FPG,
576 fstore=constants.EXPECTED_FSTORE),
577 mock.call.setfshare(constants.SMB_LOWER,
578 constants.EXPECTED_VFS,
579 constants.EXPECTED_SHARE_ID,
580 allowperm=constants.ADD_USERNAME,
581 comment=mock.ANY,
582 fpg=constants.EXPECTED_FPG,
583 fstore=constants.EXPECTED_FSTORE),
584 mock.call.setfshare(constants.SMB_LOWER,
585 constants.EXPECTED_VFS,
586 constants.EXPECTED_SUPER_SHARE,
587 allowperm=constants.DROP_USERNAME,
588 comment=mock.ANY,
589 fpg=constants.EXPECTED_FPG,
590 fstore=constants.EXPECTED_FSTORE),
591 mock.call.removefshare(constants.SMB_LOWER,
592 constants.EXPECTED_VFS,
593 constants.EXPECTED_SHARE_ID,
594 fpg=constants.EXPECTED_FPG,
595 fstore=constants.EXPECTED_FSTORE),
596 ]
598 self.mock_client.assert_has_calls(expected_calls)
600 def test_mediator_create_cifs_share_from_snapshot_ro(self):
601 self.init_mediator()
603 # RO because CIFS admin access username is not configured
604 self.mediator.hpe3par_cifs_admin_access_username = None
606 self.mock_client.getfsnap.return_value = {
607 'message': None,
608 'total': 1,
609 'members': [{'snapName': constants.EXPECTED_SNAP_ID,
610 'fstoreName': constants.EXPECTED_FSTORE}]
611 }
613 location = self.mediator.create_share_from_snapshot(
614 constants.EXPECTED_SHARE_ID,
615 constants.CIFS,
616 constants.EXPECTED_EXTRA_SPECS,
617 constants.EXPECTED_PROJECT_ID,
618 constants.EXPECTED_SHARE_ID,
619 constants.EXPECTED_SNAP_ID,
620 constants.EXPECTED_FPG,
621 constants.EXPECTED_VFS,
622 [constants.EXPECTED_IP_10203040],
623 comment=constants.EXPECTED_COMMENT)
625 self.assertEqual(constants.EXPECTED_SHARE_ID, location)
627 share_dir = '.snapshot/%s/%s' % (
628 constants.EXPECTED_SNAP_ID, constants.EXPECTED_SHARE_ID)
630 expected_kwargs_ro = {
631 'comment': constants.EXPECTED_COMMENT,
632 'fpg': constants.EXPECTED_FPG,
633 'fstore': constants.EXPECTED_FSTORE,
634 'sharedir': share_dir,
635 }
637 self.mock_client.createfshare.assert_called_once_with(
638 constants.SMB_LOWER,
639 constants.EXPECTED_VFS,
640 constants.EXPECTED_SHARE_ID,
641 **expected_kwargs_ro
642 )
644 def test_mediator_create_nfs_share_from_snapshot(self):
645 self.init_mediator()
647 self.mock_client.getfsnap.return_value = {
648 'message': None,
649 'total': 1,
650 'members': [{'snapName': constants.EXPECTED_SNAP_ID,
651 'fstoreName': constants.EXPECTED_FSTORE}]
652 }
654 location = self.mediator.create_share_from_snapshot(
655 constants.EXPECTED_SHARE_ID,
656 constants.NFS,
657 constants.EXPECTED_EXTRA_SPECS,
658 constants.EXPECTED_PROJECT_ID,
659 constants.EXPECTED_SHARE_ID,
660 constants.EXPECTED_SNAP_ID,
661 constants.EXPECTED_FPG,
662 constants.EXPECTED_VFS,
663 [constants.EXPECTED_IP_10203040])
665 self.assertEqual(constants.EXPECTED_SHARE_PATH, location)
667 expected_calls = [
668 mock.call.getfsnap('*_%s' % constants.EXPECTED_SNAP_ID,
669 vfs=constants.EXPECTED_VFS,
670 fpg=constants.EXPECTED_FPG,
671 pat=True,
672 fstore=constants.EXPECTED_FSTORE),
673 mock.call.createfshare(constants.NFS_LOWER,
674 constants.EXPECTED_VFS,
675 constants.EXPECTED_SHARE_ID,
676 comment=mock.ANY,
677 fpg=constants.EXPECTED_FPG,
678 sharedir='.snapshot/%s/%s' %
679 (constants.EXPECTED_SNAP_ID,
680 constants.EXPECTED_SHARE_ID),
681 fstore=constants.EXPECTED_FSTORE,
682 clientip=constants.EXPECTED_MY_IP,
683 options='ro,no_root_squash,insecure'),
684 mock.call.getfshare(constants.NFS_LOWER,
685 constants.EXPECTED_SHARE_ID,
686 fpg=constants.EXPECTED_FPG,
687 vfs=constants.EXPECTED_VFS,
688 fstore=constants.EXPECTED_FSTORE),
689 mock.call.createfshare(constants.NFS_LOWER,
690 constants.EXPECTED_VFS,
691 constants.EXPECTED_SHARE_ID,
692 comment=mock.ANY,
693 fpg=constants.EXPECTED_FPG,
694 sharedir=constants.EXPECTED_SHARE_ID,
695 fstore=constants.EXPECTED_FSTORE,
696 clientip=','.join((
697 constants.EXPECTED_MY_IP,
698 constants.EXPECTED_IP_127)),
699 options='rw,no_root_squash,insecure'),
700 mock.call.getfshare(constants.NFS_LOWER,
701 constants.EXPECTED_SHARE_ID,
702 fpg=constants.EXPECTED_FPG,
703 vfs=constants.EXPECTED_VFS,
704 fstore=constants.EXPECTED_FSTORE),
705 mock.call.getfshare(constants.NFS_LOWER,
706 constants.EXPECTED_SHARE_ID,
707 fpg=constants.EXPECTED_FPG,
708 vfs=constants.EXPECTED_VFS,
709 fstore=constants.EXPECTED_FSTORE),
710 mock.call.setfshare(constants.NFS_LOWER,
711 constants.EXPECTED_VFS,
712 constants.EXPECTED_SHARE_ID,
713 clientip=''.join(('-',
714 constants.EXPECTED_MY_IP)),
715 comment=mock.ANY,
716 fpg=constants.EXPECTED_FPG,
717 fstore=constants.EXPECTED_FSTORE),
718 mock.call.removefshare(constants.NFS_LOWER,
719 constants.EXPECTED_VFS,
720 constants.EXPECTED_SHARE_ID,
721 fpg=constants.EXPECTED_FPG,
722 fstore=constants.EXPECTED_FSTORE),
723 ]
725 self.mock_client.assert_has_calls(expected_calls)
727 def test_mediator_create_share_from_snap_copy_incomplete(self):
728 self.init_mediator()
730 self.mock_client.getfsnap.return_value = {
731 'message': None,
732 'total': 1,
733 'members': [{'snapName': constants.EXPECTED_SNAP_ID,
734 'fstoreName': constants.EXPECTED_FSTORE}]
735 }
737 mock_bad_copy = mock.Mock()
738 mock_bad_copy.get_progress.return_value = {'total_progress': 99}
739 self.mock_object(
740 data_utils, 'Copy', mock.Mock(return_value=mock_bad_copy))
742 self.assertRaises(exception.ShareBackendException,
743 self.mediator.create_share_from_snapshot,
744 constants.EXPECTED_SHARE_ID,
745 constants.NFS,
746 constants.EXPECTED_EXTRA_SPECS,
747 constants.EXPECTED_PROJECT_ID,
748 constants.EXPECTED_SHARE_ID,
749 constants.EXPECTED_SNAP_ID,
750 constants.EXPECTED_FPG,
751 constants.EXPECTED_VFS,
752 [constants.EXPECTED_IP_10203040])
753 self.assertTrue(mock_bad_copy.run.called)
754 self.assertTrue(mock_bad_copy.get_progress.called)
756 def test_mediator_create_share_from_snap_copy_exception(self):
757 self.init_mediator()
759 self.mock_client.getfsnap.return_value = {
760 'message': None,
761 'total': 1,
762 'members': [{'snapName': constants.EXPECTED_SNAP_ID,
763 'fstoreName': constants.EXPECTED_FSTORE}]
764 }
766 mock_bad_copy = mock.Mock()
767 mock_bad_copy.run.side_effect = Exception('run exception')
768 self.mock_object(
769 data_utils, 'Copy', mock.Mock(return_value=mock_bad_copy))
771 self.assertRaises(exception.ShareBackendException,
772 self.mediator.create_share_from_snapshot,
773 constants.EXPECTED_SHARE_ID,
774 constants.NFS,
775 constants.EXPECTED_EXTRA_SPECS,
776 constants.EXPECTED_PROJECT_ID,
777 constants.EXPECTED_SHARE_ID,
778 constants.EXPECTED_SNAP_ID,
779 constants.EXPECTED_FPG,
780 constants.EXPECTED_VFS,
781 [constants.EXPECTED_IP_10203040])
782 self.assertTrue(mock_bad_copy.run.called)
784 def test_mediator_create_share_from_snap_not_found(self):
785 self.init_mediator()
787 self.mock_client.getfsnap.return_value = {
788 'message': None,
789 'total': 0,
790 'members': []
791 }
793 self.assertRaises(exception.ShareBackendException,
794 self.mediator.create_share_from_snapshot,
795 constants.EXPECTED_SHARE_ID,
796 constants.NFS,
797 constants.EXPECTED_EXTRA_SPECS,
798 constants.EXPECTED_PROJECT_ID,
799 constants.EXPECTED_SHARE_ID,
800 constants.EXPECTED_SNAP_ID,
801 constants.EXPECTED_FPG,
802 constants.EXPECTED_VFS,
803 [constants.EXPECTED_IP_10203040])
805 def test_mediator_delete_nfs_share(self):
806 self.init_mediator()
808 share_id = 'foo'
809 osf_share_id = '-'.join(('osf', share_id))
810 osf_ro_share_id = '-ro-'.join(('osf', share_id))
811 fstore = osf_share_id
813 self.mock_object(self.mediator,
814 '_find_fstore',
815 mock.Mock(return_value=fstore))
816 self.mock_object(self.mediator, '_delete_file_tree')
817 self.mock_object(self.mediator, '_update_capacity_quotas')
819 self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
820 share_id,
821 constants.EXPECTED_SIZE_1,
822 constants.NFS,
823 constants.EXPECTED_FPG,
824 constants.EXPECTED_VFS,
825 constants.EXPECTED_SHARE_IP)
827 expected_calls = [
828 mock.call.removefshare(constants.NFS_LOWER,
829 constants.EXPECTED_VFS,
830 osf_share_id,
831 fpg=constants.EXPECTED_FPG,
832 fstore=fstore),
833 mock.call.removefshare(constants.NFS_LOWER,
834 constants.EXPECTED_VFS,
835 osf_ro_share_id,
836 fpg=constants.EXPECTED_FPG,
837 fstore=fstore),
838 mock.call.removefstore(constants.EXPECTED_VFS,
839 fstore,
840 fpg=constants.EXPECTED_FPG),
841 ]
842 self.mock_client.assert_has_calls(expected_calls)
844 self.assertFalse(self.mediator._delete_file_tree.called)
845 self.assertFalse(self.mediator._update_capacity_quotas.called)
847 def test_mediator_delete_share_not_found(self):
848 self.init_mediator()
850 self.mock_object(self.mediator,
851 '_find_fstore',
852 mock.Mock(return_value=None))
853 self.mock_object(self.mediator, '_delete_file_tree')
854 self.mock_object(self.mediator, '_update_capacity_quotas')
856 self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
857 constants.EXPECTED_SHARE_ID,
858 constants.EXPECTED_SIZE_1,
859 constants.CIFS,
860 constants.EXPECTED_FPG,
861 constants.EXPECTED_VFS,
862 constants.EXPECTED_IP_10203040)
864 self.assertFalse(self.mock_client.removefshare.called)
866 self.assertFalse(self.mediator._delete_file_tree.called)
867 self.assertFalse(self.mediator._update_capacity_quotas.called)
869 def test_mediator_delete_nfs_share_only_readonly(self):
870 self.init_mediator()
872 fstores = (None, constants.EXPECTED_FSTORE)
873 self.mock_object(self.mediator,
874 '_find_fstore',
875 mock.Mock(side_effect=fstores))
876 self.mock_object(self.mediator, '_delete_file_tree')
877 self.mock_object(self.mediator, '_update_capacity_quotas')
879 self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
880 constants.EXPECTED_SHARE_ID,
881 constants.EXPECTED_SIZE_1,
882 constants.NFS,
883 constants.EXPECTED_FPG,
884 constants.EXPECTED_VFS,
885 constants.EXPECTED_IP_10203040)
887 self.mock_client.removefshare.assert_called_once_with(
888 constants.NFS_LOWER,
889 constants.EXPECTED_VFS,
890 constants.EXPECTED_SHARE_ID,
891 fpg=constants.EXPECTED_FPG,
892 fstore=constants.EXPECTED_FSTORE
893 )
895 self.assertFalse(self.mediator._delete_file_tree.called)
896 self.assertFalse(self.mediator._update_capacity_quotas.called)
898 def test_mediator_delete_share_exception(self):
899 self.init_mediator()
900 self.mock_client.removefshare.side_effect = Exception(
901 'removeshare fail.')
903 self.assertRaises(exception.ShareBackendException,
904 self.mediator.delete_share,
905 constants.EXPECTED_PROJECT_ID,
906 constants.EXPECTED_SHARE_ID,
907 constants.EXPECTED_SIZE_1,
908 constants.CIFS,
909 constants.EXPECTED_FPG,
910 constants.EXPECTED_VFS,
911 constants.EXPECTED_IP_10203040)
913 expected_calls = [
914 mock.call.removefshare(constants.SMB_LOWER,
915 constants.EXPECTED_VFS,
916 constants.EXPECTED_SHARE_ID,
917 fpg=constants.EXPECTED_FPG,
918 fstore=constants.EXPECTED_FSTORE),
919 ]
921 self.mock_client.assert_has_calls(expected_calls)
923 def test_mediator_delete_fstore_exception(self):
924 self.init_mediator()
925 self.mock_object(self.mediator,
926 '_find_fstore',
927 mock.Mock(return_value=constants.EXPECTED_SHARE_ID))
928 self.mock_object(self.mediator, '_delete_file_tree')
929 self.mock_object(self.mediator, '_update_capacity_quotas')
930 self.mock_client.removefstore.side_effect = Exception(
931 'removefstore fail.')
933 self.assertRaises(exception.ShareBackendException,
934 self.mediator.delete_share,
935 constants.EXPECTED_PROJECT_ID,
936 constants.SHARE_ID,
937 constants.EXPECTED_SIZE_1,
938 constants.CIFS,
939 constants.EXPECTED_FPG,
940 constants.EXPECTED_VFS,
941 constants.EXPECTED_IP_10203040)
943 expected_calls = [
944 mock.call.removefshare(constants.SMB_LOWER,
945 constants.EXPECTED_VFS,
946 constants.EXPECTED_SHARE_ID,
947 fpg=constants.EXPECTED_FPG,
948 fstore=constants.EXPECTED_SHARE_ID),
949 mock.call.removefshare(constants.SMB_LOWER,
950 constants.EXPECTED_VFS,
951 constants.EXPECTED_SHARE_ID_RO,
952 fpg=constants.EXPECTED_FPG,
953 fstore=constants.EXPECTED_SHARE_ID),
954 mock.call.removefstore(constants.EXPECTED_VFS,
955 constants.EXPECTED_SHARE_ID,
956 fpg=constants.EXPECTED_FPG),
957 ]
958 self.mock_client.assert_has_calls(expected_calls)
960 self.assertFalse(self.mediator._delete_file_tree.called)
961 self.assertFalse(self.mediator._update_capacity_quotas.called)
963 def test_mediator_delete_file_tree_exception(self):
964 self.init_mediator()
965 mock_log = self.mock_object(hpe3parmediator, 'LOG')
966 self.mock_object(self.mediator,
967 '_find_fstore',
968 mock.Mock(return_value=constants.EXPECTED_FSTORE))
969 self.mock_object(self.mediator,
970 '_delete_file_tree',
971 mock.Mock(side_effect=Exception('test')))
972 self.mock_object(self.mediator, '_update_capacity_quotas')
974 self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
975 constants.SHARE_ID,
976 constants.EXPECTED_SIZE_1,
977 constants.CIFS,
978 constants.EXPECTED_FPG,
979 constants.EXPECTED_VFS,
980 constants.EXPECTED_IP_10203040)
982 expected_calls = [
983 mock.call.removefshare(constants.SMB_LOWER,
984 constants.EXPECTED_VFS,
985 constants.EXPECTED_SHARE_ID,
986 fpg=constants.EXPECTED_FPG,
987 fstore=constants.EXPECTED_FSTORE),
988 mock.call.removefshare(constants.SMB_LOWER,
989 constants.EXPECTED_VFS,
990 constants.EXPECTED_SHARE_ID_RO,
991 fpg=constants.EXPECTED_FPG,
992 fstore=constants.EXPECTED_FSTORE),
993 ]
994 self.mock_client.assert_has_calls(expected_calls)
996 self.assertTrue(self.mediator._delete_file_tree.called)
997 self.assertFalse(self.mediator._update_capacity_quotas.called)
998 mock_log.warning.assert_called_once_with(mock.ANY, mock.ANY)
1000 def test_mediator_delete_cifs_share(self):
1001 self.init_mediator()
1003 self.mock_object(self.mediator,
1004 '_find_fstore',
1005 mock.Mock(return_value=constants.EXPECTED_FSTORE))
1006 self.mock_object(self.mediator,
1007 '_create_mount_directory',
1008 mock.Mock(return_value={}))
1009 self.mock_object(self.mediator,
1010 '_mount_super_share',
1011 mock.Mock(return_value={}))
1012 self.mock_object(self.mediator,
1013 '_delete_share_directory',
1014 mock.Mock(return_value={}))
1015 self.mock_object(self.mediator,
1016 '_unmount_share',
1017 mock.Mock(return_value={}))
1018 self.mock_object(self.mediator,
1019 '_update_capacity_quotas',
1020 mock.Mock(return_value={}))
1022 self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
1023 constants.EXPECTED_SHARE_ID,
1024 constants.EXPECTED_SIZE_1,
1025 constants.CIFS,
1026 constants.EXPECTED_FPG,
1027 constants.EXPECTED_VFS,
1028 constants.EXPECTED_IP_10203040)
1030 expected_calls = [
1031 mock.call.removefshare(constants.SMB_LOWER,
1032 constants.EXPECTED_VFS,
1033 constants.EXPECTED_SHARE_ID,
1034 fpg=constants.EXPECTED_FPG,
1035 fstore=constants.EXPECTED_FSTORE),
1036 mock.call.createfshare(constants.SMB_LOWER,
1037 constants.EXPECTED_VFS,
1038 constants.EXPECTED_SUPER_SHARE,
1039 allowip=constants.EXPECTED_MY_IP,
1040 comment=(
1041 constants.EXPECTED_SUPER_SHARE_COMMENT),
1042 fpg=constants.EXPECTED_FPG,
1043 fstore=constants.EXPECTED_FSTORE,
1044 sharedir=''),
1045 mock.call.setfshare(constants.SMB_LOWER,
1046 constants.EXPECTED_VFS,
1047 constants.EXPECTED_SUPER_SHARE,
1048 comment=(
1049 constants.EXPECTED_SUPER_SHARE_COMMENT),
1050 allowperm=(
1051 '+' + constants.USERNAME + ':fullcontrol'),
1052 fpg=constants.EXPECTED_FPG,
1053 fstore=constants.EXPECTED_FSTORE),
1054 ]
1055 self.mock_client.assert_has_calls(expected_calls)
1057 expected_mount_path = constants.EXPECTED_MOUNT_PATH + (
1058 constants.EXPECTED_SHARE_ID)
1060 expected_share_path = '/'.join((expected_mount_path,
1061 constants.EXPECTED_SHARE_ID))
1062 self.mediator._create_mount_directory.assert_called_once_with(
1063 expected_mount_path)
1064 self.mediator._mount_super_share.assert_called_once_with(
1065 constants.SMB_LOWER,
1066 expected_mount_path,
1067 constants.EXPECTED_FPG,
1068 constants.EXPECTED_VFS,
1069 constants.EXPECTED_FSTORE,
1070 constants.EXPECTED_IP_10203040)
1071 self.mediator._delete_share_directory.assert_has_calls([
1072 mock.call(expected_share_path),
1073 mock.call(expected_mount_path),
1074 ])
1075 self.mediator._unmount_share.assert_called_once_with(
1076 expected_mount_path)
1077 self.mediator._update_capacity_quotas.assert_called_once_with(
1078 constants.EXPECTED_FSTORE,
1079 0,
1080 constants.EXPECTED_SIZE_1,
1081 constants.EXPECTED_FPG,
1082 constants.EXPECTED_VFS)
1084 def test_mediator_delete_cifs_share_and_fstore(self):
1085 self.init_mediator()
1087 self.mock_object(self.mediator,
1088 '_find_fstore',
1089 mock.Mock(return_value=constants.EXPECTED_SHARE_ID))
1090 self.mock_object(self.mediator, '_delete_file_tree')
1091 self.mock_object(self.mediator, '_update_capacity_quotas')
1093 self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
1094 constants.EXPECTED_SHARE_ID,
1095 constants.EXPECTED_SIZE_1,
1096 constants.CIFS,
1097 constants.EXPECTED_FPG,
1098 constants.EXPECTED_VFS,
1099 constants.EXPECTED_IP_10203040)
1101 expected_calls = [
1102 mock.call.removefshare(constants.SMB_LOWER,
1103 constants.EXPECTED_VFS,
1104 constants.EXPECTED_SHARE_ID,
1105 fpg=constants.EXPECTED_FPG,
1106 fstore=constants.EXPECTED_SHARE_ID),
1107 mock.call.removefstore(constants.EXPECTED_VFS,
1108 constants.EXPECTED_SHARE_ID,
1109 fpg=constants.EXPECTED_FPG),
1110 ]
1111 self.mock_client.assert_has_calls(expected_calls)
1113 self.assertFalse(self.mediator._delete_file_tree.called)
1114 self.assertFalse(self.mediator._update_capacity_quotas.called)
1116 def test_mediator_delete_share_with_fstore_per_share_false(self):
1117 self.init_mediator()
1118 self.mediator.hpe3par_fstore_per_share = False
1119 share_size = int(constants.EXPECTED_SIZE_1)
1120 fstore_init_size = int(
1121 constants.GET_FSQUOTA['members'][0]['hardBlock'])
1123 expected_capacity = (0 - share_size) * units.Ki + fstore_init_size
1124 self.mock_object(self.mediator,
1125 '_find_fstore',
1126 mock.Mock(return_value=constants.EXPECTED_FSTORE))
1127 self.mock_object(self.mediator,
1128 '_create_mount_directory',
1129 mock.Mock(return_value={}))
1130 self.mock_object(self.mediator,
1131 '_mount_super_share',
1132 mock.Mock(return_value={}))
1133 self.mock_object(self.mediator,
1134 '_delete_share_directory',
1135 mock.Mock(return_value={}))
1136 self.mock_object(self.mediator,
1137 '_unmount_share',
1138 mock.Mock(return_value={}))
1140 self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
1141 constants.EXPECTED_SHARE_ID,
1142 constants.EXPECTED_SIZE_1,
1143 constants.CIFS,
1144 constants.EXPECTED_FPG,
1145 constants.EXPECTED_VFS,
1146 constants.EXPECTED_IP_10203040)
1148 expected_calls = [
1149 mock.call.removefshare(constants.SMB_LOWER,
1150 constants.EXPECTED_VFS,
1151 constants.EXPECTED_SHARE_ID,
1152 fpg=constants.EXPECTED_FPG,
1153 fstore=constants.EXPECTED_FSTORE),
1154 mock.call.createfshare(constants.SMB_LOWER,
1155 constants.EXPECTED_VFS,
1156 constants.EXPECTED_SUPER_SHARE,
1157 allowip=constants.EXPECTED_MY_IP,
1158 comment=(
1159 constants.EXPECTED_SUPER_SHARE_COMMENT),
1160 fpg=constants.EXPECTED_FPG,
1161 fstore=constants.EXPECTED_FSTORE,
1162 sharedir=''),
1163 mock.call.setfshare(constants.SMB_LOWER,
1164 constants.EXPECTED_VFS,
1165 constants.EXPECTED_SUPER_SHARE,
1166 comment=(
1167 constants.EXPECTED_SUPER_SHARE_COMMENT),
1168 allowperm=(
1169 '+' + constants.USERNAME + ':fullcontrol'),
1170 fpg=constants.EXPECTED_FPG,
1171 fstore=constants.EXPECTED_FSTORE),
1172 mock.call.getfsquota(fpg=constants.EXPECTED_FPG,
1173 fstore=constants.EXPECTED_FSTORE,
1174 vfs=constants.EXPECTED_VFS),
1175 mock.call.setfsquota(constants.EXPECTED_VFS,
1176 fpg=constants.EXPECTED_FPG,
1177 fstore=constants.EXPECTED_FSTORE,
1178 scapacity=str(expected_capacity),
1179 hcapacity=str(expected_capacity))]
1180 self.mock_client.assert_has_calls(expected_calls)
1182 expected_mount_path = constants.EXPECTED_MOUNT_PATH + (
1183 constants.EXPECTED_SHARE_ID)
1184 self.mediator._create_mount_directory.assert_called_with(
1185 expected_mount_path)
1186 self.mediator._mount_super_share.assert_called_with(
1187 constants.SMB_LOWER, expected_mount_path, constants.EXPECTED_FPG,
1188 constants.EXPECTED_VFS, constants.EXPECTED_FSTORE,
1189 constants.EXPECTED_IP_10203040)
1190 self.mediator._delete_share_directory.assert_called_with(
1191 expected_mount_path)
1192 self.mediator._unmount_share.assert_called_with(
1193 expected_mount_path)
1195 def test_mediator_create_snapshot(self):
1196 self.init_mediator()
1198 self.mediator.create_snapshot(constants.EXPECTED_PROJECT_ID,
1199 constants.EXPECTED_SHARE_ID,
1200 constants.NFS,
1201 constants.EXPECTED_SNAP_NAME,
1202 constants.EXPECTED_FPG,
1203 constants.EXPECTED_VFS)
1205 expected_calls = [
1206 mock.call.createfsnap(constants.EXPECTED_VFS,
1207 constants.EXPECTED_PROJECT_ID,
1208 constants.EXPECTED_SNAP_NAME,
1209 fpg=constants.EXPECTED_FPG)
1210 ]
1211 self.mock_client.assert_has_calls(expected_calls)
1213 def test_mediator_create_snapshot_not_allowed(self):
1214 self.init_mediator()
1215 self.mock_client.getfshare.return_value['members'][0]['shareDir'] = (
1216 None)
1217 self.mock_client.getfshare.return_value['members'][0]['sharePath'] = (
1218 'foo/.snapshot/foo')
1220 self.assertRaises(exception.ShareBackendException,
1221 self.mediator.create_snapshot,
1222 constants.EXPECTED_PROJECT_ID,
1223 constants.EXPECTED_SHARE_ID,
1224 constants.NFS,
1225 constants.EXPECTED_SNAP_NAME,
1226 constants.EXPECTED_FPG,
1227 constants.EXPECTED_VFS)
1229 def test_mediator_create_snapshot_share_not_found(self):
1230 self.init_mediator()
1232 mock_find_fshare = self.mock_object(self.mediator,
1233 '_find_fshare',
1234 mock.Mock(return_value=None))
1236 self.assertRaises(exception.ShareBackendException,
1237 self.mediator.create_snapshot,
1238 constants.EXPECTED_PROJECT_ID,
1239 constants.EXPECTED_SHARE_ID,
1240 constants.NFS,
1241 constants.EXPECTED_SNAP_NAME,
1242 constants.EXPECTED_FPG,
1243 constants.EXPECTED_VFS)
1245 mock_find_fshare.assert_called_once_with(constants.EXPECTED_PROJECT_ID,
1246 constants.EXPECTED_SHARE_ID,
1247 constants.NFS,
1248 constants.EXPECTED_FPG,
1249 constants.EXPECTED_VFS)
1251 def test_mediator_create_snapshot_backend_exception(self):
1252 self.init_mediator()
1254 # createfsnap exception
1255 self.mock_client.createfsnap.side_effect = Exception(
1256 'createfsnap fail.')
1258 self.assertRaises(exception.ShareBackendException,
1259 self.mediator.create_snapshot,
1260 constants.EXPECTED_PROJECT_ID,
1261 constants.EXPECTED_SHARE_ID,
1262 constants.NFS,
1263 constants.EXPECTED_SNAP_NAME,
1264 constants.EXPECTED_FPG,
1265 constants.EXPECTED_VFS)
1267 def test_mediator_delete_snapshot(self):
1268 self.init_mediator()
1270 expected_name_from_array = 'name-from-array'
1272 self.mock_client.getfsnap.return_value = {
1273 'total': 1,
1274 'members': [
1275 {
1276 'snapName': expected_name_from_array,
1277 'fstoreName': constants.EXPECTED_PROJECT_ID,
1278 }
1279 ],
1280 'message': None
1281 }
1283 self.mock_client.getfshare.side_effect = [
1284 # some typical independent NFS share (path) and SMB share (dir)
1285 {
1286 'total': 1,
1287 'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore'}]
1288 },
1289 {
1290 'total': 1,
1291 'members': [{'shareDir': []}],
1292 }
1293 ]
1295 self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID,
1296 constants.EXPECTED_SHARE_ID,
1297 constants.NFS,
1298 constants.EXPECTED_SNAP_NAME,
1299 constants.EXPECTED_FPG,
1300 constants.EXPECTED_VFS)
1302 expected_calls = [
1303 mock.call.getfsnap('*_%s' % constants.EXPECTED_SNAP_NAME,
1304 vfs=constants.EXPECTED_VFS,
1305 fpg=constants.EXPECTED_FPG,
1306 pat=True,
1307 fstore=constants.EXPECTED_PROJECT_ID),
1308 mock.call.getfshare(constants.NFS_LOWER,
1309 fpg=constants.EXPECTED_FPG,
1310 vfs=constants.EXPECTED_VFS,
1311 fstore=constants.EXPECTED_PROJECT_ID),
1312 mock.call.getfshare(constants.SMB_LOWER,
1313 fpg=constants.EXPECTED_FPG,
1314 vfs=constants.EXPECTED_VFS,
1315 fstore=constants.EXPECTED_PROJECT_ID),
1316 mock.call.removefsnap(constants.EXPECTED_VFS,
1317 constants.EXPECTED_PROJECT_ID,
1318 fpg=constants.EXPECTED_FPG,
1319 snapname=expected_name_from_array),
1320 mock.call.startfsnapclean(constants.EXPECTED_FPG,
1321 reclaimStrategy='maxspeed')
1322 ]
1323 self.mock_client.assert_has_calls(expected_calls)
1325 def test_mediator_delete_snapshot_not_found(self):
1326 self.init_mediator()
1328 self.mock_client.getfsnap.return_value = {
1329 'total': 0,
1330 'members': [],
1331 }
1333 self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID,
1334 constants.EXPECTED_SHARE_ID,
1335 constants.NFS,
1336 constants.EXPECTED_SNAP_NAME,
1337 constants.EXPECTED_FPG,
1338 constants.EXPECTED_VFS)
1340 expected_calls = [
1341 mock.call.getfsnap('*_%s' % constants.EXPECTED_SNAP_NAME,
1342 vfs=constants.EXPECTED_VFS,
1343 fpg=constants.EXPECTED_FPG,
1344 pat=True,
1345 fstore=constants.EXPECTED_SHARE_ID),
1346 ]
1348 # Code coverage for early exit when nothing to delete.
1349 self.mock_client.assert_has_calls(expected_calls)
1350 self.assertFalse(self.mock_client.getfshare.called)
1351 self.assertFalse(self.mock_client.removefsnap.called)
1352 self.assertFalse(self.mock_client.startfsnapclean.called)
1354 def test_mediator_delete_snapshot_shared_nfs(self):
1355 self.init_mediator()
1357 # Mock a share under this snapshot for NFS
1358 snapshot_dir = '.snapshot/DT_%s' % constants.EXPECTED_SNAP_NAME
1359 snapshot_path = '%s/%s' % (constants.EXPECTED_SHARE_PATH, snapshot_dir)
1361 self.mock_client.getfsnap.return_value = {
1362 'total': 1,
1363 'members': [{'snapName': constants.EXPECTED_SNAP_NAME}]
1364 }
1366 self.mock_client.getfshare.side_effect = [
1367 # some typical independent NFS share (path) and SMB share (dir)
1368 {
1369 'total': 1,
1370 'members': [{'sharePath': snapshot_path}],
1371 },
1372 {
1373 'total': 0,
1374 'members': [],
1375 }
1376 ]
1378 self.assertRaises(exception.Invalid,
1379 self.mediator.delete_snapshot,
1380 constants.EXPECTED_PROJECT_ID,
1381 constants.EXPECTED_SHARE_ID,
1382 constants.NFS,
1383 constants.EXPECTED_SNAP_NAME,
1384 constants.EXPECTED_FPG,
1385 constants.EXPECTED_VFS)
1387 def test_mediator_delete_snapshot_shared_smb(self):
1388 self.init_mediator()
1390 # Mock a share under this snapshot for SMB
1391 snapshot_dir = '.snapshot/DT_%s' % constants.EXPECTED_SNAP_NAME
1393 self.mock_client.getfsnap.return_value = {
1394 'total': 1,
1395 'members': [{'snapName': constants.EXPECTED_SNAP_NAME}]
1396 }
1398 self.mock_client.getfshare.side_effect = [
1399 # some typical independent NFS share (path) and SMB share (dir)
1400 {
1401 'total': 1,
1402 'members': [{'sharePath': constants.EXPECTED_SHARE_PATH}],
1403 },
1404 {
1405 'total': 1,
1406 'members': [{'shareDir': snapshot_dir}],
1407 }
1408 ]
1410 self.assertRaises(exception.Invalid,
1411 self.mediator.delete_snapshot,
1412 constants.EXPECTED_PROJECT_ID,
1413 constants.EXPECTED_SHARE_ID,
1414 constants.NFS,
1415 constants.EXPECTED_SNAP_NAME,
1416 constants.EXPECTED_FPG,
1417 constants.EXPECTED_VFS)
1419 def _assert_delete_snapshot_raises(self):
1420 self.assertRaises(exception.ShareBackendException,
1421 self.mediator.delete_snapshot,
1422 constants.EXPECTED_PROJECT_ID,
1423 constants.EXPECTED_SHARE_ID,
1424 constants.NFS,
1425 constants.EXPECTED_SNAP_NAME,
1426 constants.EXPECTED_FPG,
1427 constants.EXPECTED_VFS)
1429 def test_mediator_delete_snapshot_backend_exceptions(self):
1430 self.init_mediator()
1432 # getfsnap exception
1433 self.mock_client.getfsnap.side_effect = Exception('getfsnap fail.')
1434 self._assert_delete_snapshot_raises()
1436 # getfsnap OK
1437 self.mock_client.getfsnap.side_effect = None
1438 self.mock_client.getfsnap.return_value = {
1439 'total': 1,
1440 'members': [{'snapName': constants.EXPECTED_SNAP_NAME,
1441 'fstoreName': constants.EXPECTED_FSTORE}]
1442 }
1444 # getfshare exception
1445 self.mock_client.getfshare.side_effect = Exception('getfshare fail.')
1446 self._assert_delete_snapshot_raises()
1448 # getfshare OK
1449 def mock_fshare(*args, **kwargs):
1450 if args[0] == constants.NFS_LOWER:
1451 return {
1452 'total': 1,
1453 'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore',
1454 'fstoreName': constants.EXPECTED_FSTORE}]
1455 }
1456 else:
1457 return {
1458 'total': 1,
1459 'members': [{'shareDir': [],
1460 'fstoreName': constants.EXPECTED_FSTORE}]
1461 }
1463 self.mock_client.getfshare.side_effect = mock_fshare
1465 # removefsnap exception
1466 self.mock_client.removefsnap.side_effect = Exception(
1467 'removefsnap fail.')
1468 self._assert_delete_snapshot_raises()
1470 # removefsnap OK
1471 self.mock_client.removefsnap.side_effect = None
1472 self.mock_client.removefsnap.return_value = []
1474 # startfsnapclean exception (logged, not raised)
1475 self.mock_client.startfsnapclean.side_effect = Exception(
1476 'startfsnapclean fail.')
1477 mock_log = self.mock_object(hpe3parmediator, 'LOG')
1479 self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID,
1480 constants.EXPECTED_SHARE_ID,
1481 constants.NFS,
1482 constants.EXPECTED_SNAP_NAME,
1483 constants.EXPECTED_FPG,
1484 constants.EXPECTED_VFS)
1486 expected_calls = [
1487 mock.call.getfsnap('*_%s' % constants.EXPECTED_SNAP_NAME,
1488 vfs=constants.EXPECTED_VFS,
1489 fpg=constants.EXPECTED_FPG,
1490 pat=True,
1491 fstore=constants.EXPECTED_FSTORE),
1492 mock.call.getfshare(constants.NFS_LOWER,
1493 fpg=constants.EXPECTED_FPG,
1494 vfs=constants.EXPECTED_VFS,
1495 fstore=constants.EXPECTED_FSTORE),
1496 mock.call.getfshare(constants.SMB_LOWER,
1497 fpg=constants.EXPECTED_FPG,
1498 vfs=constants.EXPECTED_VFS,
1499 fstore=constants.EXPECTED_FSTORE),
1500 mock.call.removefsnap(constants.EXPECTED_VFS,
1501 constants.EXPECTED_FSTORE,
1502 fpg=constants.EXPECTED_FPG,
1503 snapname=constants.EXPECTED_SNAP_NAME),
1504 mock.call.startfsnapclean(constants.EXPECTED_FPG,
1505 reclaimStrategy='maxspeed'),
1506 ]
1507 self.mock_client.assert_has_calls(expected_calls)
1508 self.assertTrue(mock_log.debug.called)
1509 self.assertTrue(mock_log.exception.called)
1511 @ddt.data('volname.1', ['volname.2', 'volname.3'])
1512 def test_mediator_get_fpg_status(self, volume_name_or_list):
1513 """Mediator converts client stats to capacity result."""
1514 expected_capacity = constants.EXPECTED_SIZE_2
1515 expected_free = constants.EXPECTED_SIZE_1
1517 self.init_mediator()
1518 self.mock_client.getfpg.return_value = {
1519 'total': 1,
1520 'members': [
1521 {
1522 'capacityKiB': str(expected_capacity * units.Mi),
1523 'availCapacityKiB': str(expected_free * units.Mi),
1524 'vvs': volume_name_or_list,
1525 }
1526 ],
1527 'message': None,
1528 }
1530 self.mock_client.getfsquota.return_value = {
1531 'total': 3,
1532 'members': [
1533 {'hardBlock': 1 * units.Ki},
1534 {'hardBlock': 2 * units.Ki},
1535 {'hardBlock': 3 * units.Ki},
1536 ],
1537 'message': None,
1538 }
1540 self.mock_client.getVolume.return_value = {
1541 'provisioningType': hpe3parmediator.DEDUPE}
1543 expected_result = {
1544 'pool_name': constants.EXPECTED_FPG,
1545 'free_capacity_gb': expected_free,
1546 'hpe3par_flash_cache': False,
1547 'hp3par_flash_cache': False,
1548 'dedupe': True,
1549 'thin_provisioning': True,
1550 'total_capacity_gb': expected_capacity,
1551 'provisioned_capacity_gb': 6,
1552 }
1554 result = self.mediator.get_fpg_status(constants.EXPECTED_FPG)
1555 self.assertEqual(expected_result, result)
1556 expected_calls = [
1557 mock.call.getfpg(constants.EXPECTED_FPG)
1558 ]
1559 self.mock_client.assert_has_calls(expected_calls)
1561 def test_mediator_get_fpg_status_exception(self):
1562 """Exception during get_fpg_status call to getfpg."""
1563 self.init_mediator()
1565 self.mock_client.getfpg.side_effect = constants.FAKE_EXCEPTION
1567 self.assertRaises(exception.ShareBackendException,
1568 self.mediator.get_fpg_status,
1569 constants.EXPECTED_FPG)
1571 expected_calls = [mock.call.getfpg(constants.EXPECTED_FPG)]
1572 self.mock_client.assert_has_calls(expected_calls)
1574 def test_mediator_get_fpg_status_error(self):
1575 """Unexpected result from getfpg during get_fpg_status."""
1576 self.init_mediator()
1578 self.mock_client.getfpg.return_value = {'total': 0}
1580 self.assertRaises(exception.ShareBackendException,
1581 self.mediator.get_fpg_status,
1582 constants.EXPECTED_FPG)
1584 expected_calls = [mock.call.getfpg(constants.EXPECTED_FPG)]
1585 self.mock_client.assert_has_calls(expected_calls)
1587 def test_mediator_get_fpg_status_bad_prov_type(self):
1588 """Test get_fpg_status handling of unexpected provisioning type."""
1589 self.init_mediator()
1591 self.mock_client.getfpg.return_value = {
1592 'total': 1,
1593 'members': [
1594 {
1595 'capacityKiB': '1',
1596 'availCapacityKiB': '1',
1597 'vvs': 'foo',
1598 }
1599 ],
1600 'message': None,
1601 }
1602 self.mock_client.getVolume.return_value = {
1603 'provisioningType': 'BOGUS'}
1605 self.assertRaises(exception.ShareBackendException,
1606 self.mediator.get_fpg_status,
1607 constants.EXPECTED_FPG)
1609 expected_calls = [mock.call.getfpg(constants.EXPECTED_FPG)]
1610 self.mock_client.assert_has_calls(expected_calls)
1612 def test_mediator_get_provisioned_error(self):
1613 """Test error during get provisioned GB."""
1614 self.init_mediator()
1616 error_return = {'message': 'Some error happened.'}
1617 self.mock_client.getfsquota.return_value = error_return
1619 self.assertRaises(exception.ShareBackendException,
1620 self.mediator.get_provisioned_gb,
1621 constants.EXPECTED_FPG)
1623 expected_calls = [mock.call.getfsquota(fpg=constants.EXPECTED_FPG)]
1624 self.mock_client.assert_has_calls(expected_calls)
1626 def test_mediator_get_provisioned_exception(self):
1627 """Test exception during get provisioned GB."""
1628 self.init_mediator()
1630 self.mock_client.getfsquota.side_effect = constants.FAKE_EXCEPTION
1632 self.assertRaises(exception.ShareBackendException,
1633 self.mediator.get_provisioned_gb,
1634 constants.EXPECTED_FPG)
1636 expected_calls = [mock.call.getfsquota(fpg=constants.EXPECTED_FPG)]
1637 self.mock_client.assert_has_calls(expected_calls)
1639 def test_update_access_resync_rules_nfs(self):
1640 self.init_mediator()
1642 getfshare_result = {
1643 'shareName': constants.EXPECTED_SHARE_NAME,
1644 'fstoreName': constants.EXPECTED_FSTORE,
1645 'clients': [constants.EXPECTED_IP_127],
1646 'comment': constants.EXPECTED_COMMENT,
1647 }
1648 self.mock_client.getfshare.return_value = {
1649 'total': 1,
1650 'members': [getfshare_result],
1651 'message': None,
1652 }
1654 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1655 constants.EXPECTED_SHARE_ID,
1656 constants.NFS,
1657 constants.EXPECTED_EXTRA_SPECS,
1658 [constants.ACCESS_RULE_NFS],
1659 None,
1660 None,
1661 constants.EXPECTED_FPG,
1662 constants.EXPECTED_VFS)
1664 expected_calls = [
1665 mock.call.setfshare(
1666 constants.NFS_LOWER,
1667 constants.EXPECTED_VFS,
1668 constants.EXPECTED_SHARE_NAME,
1669 clientip='+' + constants.EXPECTED_IP_1234,
1670 fpg=constants.EXPECTED_FPG,
1671 fstore=constants.EXPECTED_FSTORE,
1672 comment=constants.EXPECTED_COMMENT),
1673 ]
1674 self.mock_client.assert_has_calls(expected_calls)
1676 def test_update_access_resync_rules_cifs(self):
1677 self.init_mediator()
1679 getfshare_result = {
1680 'shareName': constants.EXPECTED_SHARE_NAME,
1681 'fstoreName': constants.EXPECTED_FSTORE,
1682 'allowPerm': [['foo_user', 'fullcontrol']],
1683 'allowIP': '',
1684 'comment': constants.EXPECTED_COMMENT,
1685 }
1686 self.mock_client.getfshare.return_value = {
1687 'total': 1,
1688 'members': [getfshare_result],
1689 'message': None,
1690 }
1692 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1693 constants.EXPECTED_SHARE_ID,
1694 constants.CIFS,
1695 constants.EXPECTED_EXTRA_SPECS,
1696 [constants.ACCESS_RULE_CIFS],
1697 None,
1698 None,
1699 constants.EXPECTED_FPG,
1700 constants.EXPECTED_VFS)
1702 expected_calls = [
1703 mock.call.setfshare(
1704 constants.SMB_LOWER,
1705 constants.EXPECTED_VFS,
1706 constants.EXPECTED_SHARE_NAME,
1707 allowperm='+' + constants.USERNAME + ':fullcontrol',
1708 fpg=constants.EXPECTED_FPG,
1709 fstore=constants.EXPECTED_FSTORE,
1710 comment=constants.EXPECTED_COMMENT),
1711 ]
1712 self.mock_client.assert_has_calls(expected_calls)
1714 def test_mediator_allow_ip_ro_access_cifs_error(self):
1715 self.init_mediator()
1717 self.assertRaises(exception.InvalidShareAccess,
1718 self.mediator.update_access,
1719 constants.EXPECTED_PROJECT_ID,
1720 constants.EXPECTED_SHARE_ID,
1721 constants.CIFS,
1722 constants.EXPECTED_EXTRA_SPECS,
1723 [constants.ACCESS_RULE_NFS],
1724 [constants.ADD_RULE_IP_RO],
1725 [],
1726 constants.EXPECTED_FPG,
1727 constants.EXPECTED_VFS)
1729 @ddt.data(constants.CIFS, constants.NFS)
1730 def test_mediator_allow_rw_snapshot_error(self, proto):
1731 self.init_mediator()
1732 getfshare_result = {
1733 'shareName': 'foo_ro_name',
1734 'fstoreName': 'foo_fstore',
1735 'comment': 'foo_comment',
1736 }
1737 path = 'foo/.snapshot/foo'
1738 if proto == constants.NFS:
1739 getfshare_result['sharePath'] = path
1740 else:
1741 getfshare_result['shareDir'] = path
1743 self.mock_client.getfshare.return_value = {
1744 'total': 1,
1745 'members': [getfshare_result],
1746 'message': None,
1747 }
1749 self.assertRaises(exception.InvalidShareAccess,
1750 self.mediator.update_access,
1751 constants.EXPECTED_PROJECT_ID,
1752 constants.EXPECTED_SHARE_ID,
1753 constants.CIFS,
1754 constants.EXPECTED_EXTRA_SPECS,
1755 [constants.ACCESS_RULE_NFS],
1756 [constants.ADD_RULE_IP],
1757 [],
1758 constants.EXPECTED_FPG,
1759 constants.EXPECTED_VFS)
1761 @ddt.data((constants.READ_WRITE, True),
1762 (constants.READ_WRITE, False),
1763 (constants.READ_ONLY, True),
1764 (constants.READ_ONLY, False))
1765 @ddt.unpack
1766 def test_mediator_allow_user_access_cifs(self, access_level, use_other):
1767 """"Allow user access to cifs share."""
1768 self.init_mediator()
1770 if use_other: # Don't find share until second attempt.
1771 findings = (None,
1772 self.mock_client.getfshare.return_value['members'][0])
1773 mock_find_fshare = self.mock_object(
1774 self.mediator, '_find_fshare', mock.Mock(side_effect=findings))
1776 if access_level == constants.READ_ONLY:
1777 expected_allowperm = '+%s:read' % constants.USERNAME
1778 else:
1779 expected_allowperm = '+%s:fullcontrol' % constants.USERNAME
1781 constants.ADD_RULE_USER['access_level'] = access_level
1782 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1783 constants.EXPECTED_SHARE_ID,
1784 constants.CIFS,
1785 constants.EXPECTED_EXTRA_SPECS,
1786 [constants.ACCESS_RULE_CIFS],
1787 [constants.ADD_RULE_USER],
1788 [],
1789 constants.EXPECTED_FPG,
1790 constants.EXPECTED_VFS)
1792 expected_calls = [
1793 mock.call.setfshare(constants.SMB_LOWER,
1794 constants.EXPECTED_VFS,
1795 constants.EXPECTED_SHARE_ID,
1796 allowperm=expected_allowperm,
1797 comment=constants.EXPECTED_COMMENT,
1798 fpg=constants.EXPECTED_FPG,
1799 fstore=constants.EXPECTED_FSTORE)
1801 ]
1802 self.mock_client.assert_has_calls(expected_calls)
1803 if use_other:
1804 readonly = access_level == constants.READ_ONLY
1805 expected_find_calls = [
1806 mock.call(constants.EXPECTED_PROJECT_ID,
1807 constants.EXPECTED_SHARE_ID,
1808 constants.SMB_LOWER,
1809 constants.EXPECTED_FPG,
1810 constants.EXPECTED_VFS,
1811 readonly=readonly),
1812 mock.call(constants.EXPECTED_PROJECT_ID,
1813 constants.EXPECTED_SHARE_ID,
1814 constants.SMB_LOWER,
1815 constants.EXPECTED_FPG,
1816 constants.EXPECTED_VFS,
1817 readonly=not readonly),
1818 ]
1819 mock_find_fshare.assert_has_calls(expected_find_calls)
1821 @ddt.data(constants.CIFS, constants.NFS)
1822 def test_mediator_deny_rw_snapshot_error(self, proto):
1823 self.init_mediator()
1824 getfshare_result = {
1825 'shareName': 'foo_ro_name',
1826 'fstoreName': 'foo_fstore',
1827 'comment': 'foo_comment',
1828 }
1829 path = 'foo/.snapshot/foo'
1830 if proto == constants.NFS:
1831 getfshare_result['sharePath'] = path
1832 else:
1833 getfshare_result['shareDir'] = path
1835 self.mock_client.getfshare.return_value = {
1836 'total': 1,
1837 'members': [getfshare_result],
1838 'message': None,
1839 }
1840 mock_log = self.mock_object(hpe3parmediator, 'LOG')
1842 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1843 constants.EXPECTED_SHARE_ID,
1844 proto,
1845 constants.EXPECTED_EXTRA_SPECS,
1846 [constants.ACCESS_RULE_NFS],
1847 [],
1848 [constants.DELETE_RULE_IP],
1849 constants.EXPECTED_FPG,
1850 constants.EXPECTED_VFS)
1852 self.assertFalse(self.mock_client.setfshare.called)
1853 self.assertTrue(mock_log.error.called)
1855 def test_mediator_deny_user_access_cifs(self):
1856 """"Deny user access to cifs share."""
1857 self.init_mediator()
1859 expected_denyperm = '-%s:fullcontrol' % constants.USERNAME
1861 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1862 constants.EXPECTED_SHARE_ID,
1863 constants.CIFS,
1864 constants.EXPECTED_EXTRA_SPECS,
1865 [constants.ACCESS_RULE_CIFS],
1866 [],
1867 [constants.DELETE_RULE_USER],
1868 constants.EXPECTED_FPG,
1869 constants.EXPECTED_VFS)
1871 expected_calls = [
1872 mock.call.setfshare(constants.SMB_LOWER,
1873 constants.EXPECTED_VFS,
1874 constants.EXPECTED_SHARE_ID,
1875 allowperm=expected_denyperm,
1876 comment=constants.EXPECTED_COMMENT,
1877 fpg=constants.EXPECTED_FPG,
1878 fstore=constants.EXPECTED_FSTORE)
1880 ]
1881 self.mock_client.assert_has_calls(expected_calls)
1883 def test_mediator_allow_ip_access_cifs(self):
1884 """"Allow ip access to cifs share."""
1885 self.init_mediator()
1887 expected_allowip = '+%s' % constants.EXPECTED_IP_1234
1889 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1890 constants.EXPECTED_SHARE_ID,
1891 constants.CIFS,
1892 constants.EXPECTED_EXTRA_SPECS,
1893 [constants.ACCESS_RULE_NFS],
1894 [constants.ADD_RULE_IP],
1895 [],
1896 constants.EXPECTED_FPG,
1897 constants.EXPECTED_VFS)
1899 expected_calls = [
1900 mock.call.setfshare(constants.SMB_LOWER,
1901 constants.EXPECTED_VFS,
1902 constants.EXPECTED_SHARE_ID,
1903 allowip=expected_allowip,
1904 comment=constants.EXPECTED_COMMENT,
1905 fpg=constants.EXPECTED_FPG,
1906 fstore=constants.EXPECTED_FSTORE)
1907 ]
1908 self.mock_client.assert_has_calls(expected_calls)
1910 def test_mediator_deny_ip_access_cifs(self):
1911 """"Deny ip access to cifs share."""
1912 self.init_mediator()
1914 expected_denyip = '-%s' % constants.EXPECTED_IP_1234
1916 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1917 constants.EXPECTED_SHARE_ID,
1918 constants.CIFS,
1919 constants.EXPECTED_EXTRA_SPECS,
1920 [constants.ACCESS_RULE_NFS],
1921 [],
1922 [constants.DELETE_RULE_IP],
1923 constants.EXPECTED_FPG,
1924 constants.EXPECTED_VFS)
1926 expected_calls = [
1927 mock.call.setfshare(constants.SMB_LOWER,
1928 constants.EXPECTED_VFS,
1929 constants.EXPECTED_SHARE_ID,
1930 allowip=expected_denyip,
1931 comment=constants.EXPECTED_COMMENT,
1932 fpg=constants.EXPECTED_FPG,
1933 fstore=constants.EXPECTED_FSTORE)
1934 ]
1935 self.mock_client.assert_has_calls(expected_calls)
1937 def test_mediator_allow_ip_access_nfs(self):
1938 """"Allow ip access to nfs share."""
1939 self.init_mediator()
1940 already_exists = (hpe3parmediator.IP_ALREADY_EXISTS %
1941 constants.EXPECTED_IP_1234)
1942 self.mock_client.setfshare.side_effect = ([], [already_exists])
1944 expected_clientip = '+%s' % constants.EXPECTED_IP_1234
1946 for _ in range(2): # Test 2nd allow w/ already exists message.
1947 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1948 constants.EXPECTED_SHARE_ID,
1949 constants.NFS,
1950 constants.EXPECTED_EXTRA_SPECS,
1951 [constants.ACCESS_RULE_NFS],
1952 [constants.ADD_RULE_IP],
1953 [],
1954 constants.EXPECTED_FPG,
1955 constants.EXPECTED_VFS)
1957 expected_calls = 2 * [
1958 mock.call.setfshare(constants.NFS.lower(),
1959 constants.EXPECTED_VFS,
1960 constants.EXPECTED_SHARE_ID,
1961 clientip=expected_clientip,
1962 fpg=constants.EXPECTED_FPG,
1963 fstore=constants.EXPECTED_FSTORE,
1964 comment=constants.EXPECTED_COMMENT),
1965 ]
1967 self.mock_client.assert_has_calls(expected_calls, any_order=True)
1969 def test_mediator_deny_ip_access_nfs(self):
1970 """"Deny ip access to nfs share."""
1971 self.init_mediator()
1973 expected_clientip = '-%s' % constants.EXPECTED_IP_1234
1975 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
1976 constants.EXPECTED_SHARE_ID,
1977 constants.NFS,
1978 constants.EXPECTED_EXTRA_SPECS,
1979 [constants.ACCESS_RULE_NFS],
1980 [],
1981 [constants.DELETE_RULE_IP],
1982 constants.EXPECTED_FPG,
1983 constants.EXPECTED_VFS)
1985 expected_calls = [
1986 mock.call.setfshare(constants.NFS.lower(),
1987 constants.EXPECTED_VFS,
1988 constants.EXPECTED_SHARE_ID,
1989 clientip=expected_clientip,
1990 fpg=constants.EXPECTED_FPG,
1991 fstore=constants.EXPECTED_FSTORE,
1992 comment=constants.EXPECTED_COMMENT)
1993 ]
1994 self.mock_client.assert_has_calls(expected_calls)
1996 def test_mediator_deny_ip_ro_access_nfs_legacy(self):
1997 self.init_mediator()
1999 # Fail to find share with new naming. Succeed finding legacy naming.
2000 legacy = {
2001 'shareName': 'foo_name',
2002 'fstoreName': 'foo_fstore',
2003 'comment': 'foo_comment',
2004 'sharePath': 'foo/.snapshot/foo',
2005 }
2006 fshares = (None, legacy)
2007 mock_find_fshare = self.mock_object(self.mediator,
2008 '_find_fshare',
2009 mock.Mock(side_effect=fshares))
2011 expected_clientip = '-%s' % constants.EXPECTED_IP_1234
2013 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
2014 constants.EXPECTED_SHARE_ID,
2015 constants.NFS,
2016 constants.EXPECTED_EXTRA_SPECS,
2017 [constants.ACCESS_RULE_NFS],
2018 [],
2019 [constants.DELETE_RULE_IP_RO],
2020 constants.EXPECTED_FPG,
2021 constants.EXPECTED_VFS)
2023 expected_calls = [
2024 mock.call.setfshare(constants.NFS.lower(),
2025 constants.EXPECTED_VFS,
2026 legacy['shareName'],
2027 clientip=expected_clientip,
2028 fpg=constants.EXPECTED_FPG,
2029 fstore=legacy['fstoreName'],
2030 comment=legacy['comment'])
2031 ]
2032 self.mock_client.assert_has_calls(expected_calls)
2034 expected_find_fshare_calls = [
2035 mock.call(constants.EXPECTED_PROJECT_ID,
2036 constants.EXPECTED_SHARE_ID,
2037 constants.NFS_LOWER,
2038 constants.EXPECTED_FPG,
2039 constants.EXPECTED_VFS,
2040 readonly=True),
2041 mock.call(constants.EXPECTED_PROJECT_ID,
2042 constants.EXPECTED_SHARE_ID,
2043 constants.NFS_LOWER,
2044 constants.EXPECTED_FPG,
2045 constants.EXPECTED_VFS,
2046 readonly=False),
2047 ]
2048 mock_find_fshare.assert_has_calls(expected_find_fshare_calls)
2050 def test_mediator_allow_user_access_nfs(self):
2051 """"Allow user access to nfs share is not supported."""
2052 self.init_mediator()
2054 self.assertRaises(exception.HPE3ParInvalid,
2055 self.mediator.update_access,
2056 constants.EXPECTED_PROJECT_ID,
2057 constants.EXPECTED_SHARE_ID,
2058 constants.NFS,
2059 constants.EXPECTED_EXTRA_SPECS,
2060 [constants.ACCESS_RULE_NFS],
2061 [constants.ADD_RULE_USER],
2062 [],
2063 constants.EXPECTED_FPG,
2064 constants.EXPECTED_VFS)
2066 def test_mediator_allow_access_bad_proto(self):
2067 """"Allow user access to unsupported protocol."""
2068 self.init_mediator()
2070 self.assertRaises(exception.InvalidShareAccess,
2071 self.mediator.update_access,
2072 constants.EXPECTED_PROJECT_ID,
2073 constants.EXPECTED_SHARE_ID,
2074 'unsupported_other_protocol',
2075 constants.EXPECTED_EXTRA_SPECS,
2076 [constants.ACCESS_RULE_NFS],
2077 [constants.ADD_RULE_IP],
2078 [],
2079 constants.EXPECTED_FPG,
2080 constants.EXPECTED_VFS)
2082 def test_mediator_allow_access_bad_type(self):
2083 """"Allow user access to unsupported access type."""
2084 self.init_mediator()
2086 self.assertRaises(exception.InvalidInput,
2087 self.mediator.update_access,
2088 constants.EXPECTED_PROJECT_ID,
2089 constants.EXPECTED_SHARE_ID,
2090 constants.CIFS,
2091 constants.EXPECTED_EXTRA_SPECS,
2092 [constants.ACCESS_RULE_NFS],
2093 [constants.ADD_RULE_BAD_TYPE],
2094 [],
2095 constants.EXPECTED_FPG,
2096 constants.EXPECTED_VFS)
2098 def test_mediator_allow_access_missing_nfs_share(self):
2099 self.init_mediator()
2100 mock_find_fshare = self.mock_object(self.mediator,
2101 '_find_fshare',
2102 mock.Mock(return_value=None))
2104 self.assertRaises(exception.HPE3ParInvalid,
2105 self.mediator.update_access,
2106 constants.EXPECTED_PROJECT_ID,
2107 constants.EXPECTED_SHARE_ID,
2108 constants.NFS,
2109 constants.EXPECTED_EXTRA_SPECS,
2110 [constants.ACCESS_RULE_NFS],
2111 [constants.ADD_RULE_IP],
2112 [],
2113 constants.EXPECTED_FPG,
2114 constants.EXPECTED_VFS)
2116 expected_calls = [
2117 mock.call(constants.EXPECTED_PROJECT_ID,
2118 constants.EXPECTED_SHARE_ID,
2119 constants.NFS_LOWER,
2120 constants.EXPECTED_FPG,
2121 constants.EXPECTED_VFS,
2122 readonly=False),
2123 mock.call(constants.EXPECTED_PROJECT_ID,
2124 constants.EXPECTED_SHARE_ID,
2125 constants.NFS_LOWER,
2126 constants.EXPECTED_FPG,
2127 constants.EXPECTED_VFS,
2128 readonly=True),
2129 ]
2130 mock_find_fshare.assert_has_calls(expected_calls)
2132 def test_mediator_allow_nfs_ro_access(self):
2133 self.init_mediator()
2134 getfshare_result = {
2135 'shareName': 'foo_ro_name',
2136 'fstoreName': 'foo_fstore',
2137 'shareDir': 'foo_dir',
2138 'comment': 'foo_comment',
2139 }
2140 findings = (None, getfshare_result)
2141 mock_find_fshare = self.mock_object(self.mediator,
2142 '_find_fshare',
2143 mock.Mock(side_effect=findings))
2144 self.mock_client.getfshare.return_value = {
2145 'total': 1,
2146 'members': [getfshare_result],
2147 'message': None,
2148 }
2150 share_id = 'foo'
2152 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
2153 share_id,
2154 constants.NFS,
2155 constants.EXPECTED_EXTRA_SPECS,
2156 [constants.ACCESS_RULE_NFS],
2157 [constants.ADD_RULE_IP_RO],
2158 [],
2159 constants.EXPECTED_FPG,
2160 constants.EXPECTED_VFS)
2162 expected_calls = [
2163 mock.call(constants.EXPECTED_PROJECT_ID,
2164 share_id,
2165 constants.NFS_LOWER,
2166 constants.EXPECTED_FPG,
2167 constants.EXPECTED_VFS,
2168 readonly=True),
2169 mock.call(constants.EXPECTED_PROJECT_ID,
2170 share_id,
2171 constants.NFS_LOWER,
2172 constants.EXPECTED_FPG,
2173 constants.EXPECTED_VFS,
2174 readonly=False),
2175 ]
2176 mock_find_fshare.assert_has_calls(expected_calls)
2178 ro_share = 'osf-ro-%s' % share_id
2180 expected_calls = [
2181 mock.call.createfshare(constants.NFS_LOWER,
2182 constants.EXPECTED_VFS,
2183 ro_share,
2184 clientip=constants.EXPECTED_IP_127_2,
2185 comment=getfshare_result['comment'],
2186 fpg=constants.EXPECTED_FPG,
2187 fstore=getfshare_result['fstoreName'],
2188 options='ro,no_root_squash,insecure',
2189 sharedir=getfshare_result['shareDir']),
2190 mock.call.getfshare(constants.NFS_LOWER,
2191 ro_share,
2192 fstore=getfshare_result['fstoreName'],
2193 fpg=constants.EXPECTED_FPG,
2194 vfs=constants.EXPECTED_VFS),
2195 mock.call.setfshare(constants.NFS_LOWER,
2196 constants.EXPECTED_VFS,
2197 getfshare_result['shareName'],
2198 clientip='+%s' % constants.EXPECTED_IP_1234,
2199 comment=getfshare_result['comment'],
2200 fpg=constants.EXPECTED_FPG,
2201 fstore=getfshare_result['fstoreName']),
2202 ]
2203 self.mock_client.assert_has_calls(expected_calls)
2205 def test_mediator_deny_access_missing_nfs_share(self):
2206 self.init_mediator()
2207 mock_find_fshare = self.mock_object(self.mediator,
2208 '_find_fshare',
2209 mock.Mock(return_value=None))
2211 self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
2212 constants.EXPECTED_SHARE_ID,
2213 constants.NFS,
2214 constants.EXPECTED_EXTRA_SPECS,
2215 [constants.ACCESS_RULE_NFS],
2216 [],
2217 [constants.DELETE_RULE_IP],
2218 constants.EXPECTED_FPG,
2219 constants.EXPECTED_VFS)
2221 expected_calls = [
2222 mock.call(constants.EXPECTED_PROJECT_ID,
2223 constants.EXPECTED_SHARE_ID,
2224 constants.NFS_LOWER,
2225 constants.EXPECTED_FPG,
2226 constants.EXPECTED_VFS,
2227 readonly=False),
2228 ]
2229 mock_find_fshare.assert_has_calls(expected_calls)
2231 @ddt.data((hpe3parmediator.ALLOW, 'ip', True,
2232 ['IP address foo already exists']),
2233 (hpe3parmediator.ALLOW, 'ip', False,
2234 ['Another share already exists for this path and client']),
2235 (hpe3parmediator.ALLOW, 'user', True,
2236 ['"allow" permission already exists for "foo"']),
2237 (hpe3parmediator.DENY, 'ip', True,
2238 ['foo does not exist, cannot be removed']),
2239 (hpe3parmediator.DENY, 'user', True,
2240 ['foo:fullcontrol" does not exist, cannot delete it.']),
2241 (hpe3parmediator.DENY, 'user', False,
2242 ['SMB share osf-foo does not exist']),
2243 (hpe3parmediator.ALLOW, 'ip', True, ['\r']),
2244 (hpe3parmediator.ALLOW, 'user', True, ['\r']),
2245 (hpe3parmediator.DENY, 'ip', True, ['\r']),
2246 (hpe3parmediator.DENY, 'user', True, ['\r']),
2247 (hpe3parmediator.ALLOW, 'ip', True, []),
2248 (hpe3parmediator.ALLOW, 'user', True, []),
2249 (hpe3parmediator.DENY, 'ip', True, []),
2250 (hpe3parmediator.DENY, 'user', True, []))
2251 @ddt.unpack
2252 def test_ignore_benign_access_results(self, access, access_type,
2253 expect_false, results):
2255 returned = self.mediator.ignore_benign_access_results(
2256 access, access_type, 'foo', results)
2258 if expect_false:
2259 self.assertFalse(returned)
2260 else:
2261 self.assertEqual(results, returned)
2263 @ddt.data((2, 1, True),
2264 (2, 1, False),
2265 (1, 2, True),
2266 (1, 2, False),
2267 (1024, 2048, True),
2268 (1024, 2048, False),
2269 (2048, 1024, True),
2270 (2048, 1024, False),
2271 (99999999, 1, True),
2272 (99999999, 1, False),
2273 (1, 99999999, True),
2274 (1, 99999999, False),
2275 )
2276 @ddt.unpack
2277 def test_mediator_resize_share(self, new_size, old_size, fstore_per_share):
2278 self.init_mediator()
2279 fstore = 'foo_fstore'
2280 mock_find_fstore = self.mock_object(self.mediator,
2281 '_find_fstore',
2282 mock.Mock(return_value=fstore))
2283 fstore_init_size = int(
2284 constants.GET_FSQUOTA['members'][0]['hardBlock'])
2285 self.mediator.hpe3par_fstore_per_share = fstore_per_share
2287 if fstore_per_share:
2288 expected_capacity = new_size * units.Ki
2289 else:
2290 expected_capacity = (
2291 (new_size - old_size) * units.Ki + fstore_init_size)
2293 self.mediator.resize_share(
2294 constants.EXPECTED_PROJECT_ID,
2295 constants.EXPECTED_SHARE_ID,
2296 constants.NFS,
2297 new_size,
2298 old_size,
2299 constants.EXPECTED_FPG,
2300 constants.EXPECTED_VFS)
2302 mock_find_fstore.assert_called_with(constants.EXPECTED_PROJECT_ID,
2303 constants.EXPECTED_SHARE_ID,
2304 constants.NFS,
2305 constants.EXPECTED_FPG,
2306 constants.EXPECTED_VFS,
2307 allow_cross_protocol=False)
2308 self.mock_client.setfsquota.assert_called_with(
2309 constants.EXPECTED_VFS,
2310 fpg=constants.EXPECTED_FPG,
2311 fstore=fstore,
2312 scapacity=str(expected_capacity),
2313 hcapacity=str(expected_capacity))
2315 @ddt.data(['This is a fake setfsquota returned error'], Exception('boom'))
2316 def test_mediator_resize_share_setfsquota_side_effects(self, side_effect):
2317 self.init_mediator()
2318 fstore_init_size = int(
2319 constants.GET_FSQUOTA['members'][0]['hardBlock'])
2320 fstore = 'foo_fstore'
2321 new_size = 2
2322 old_size = 1
2323 expected_capacity = (new_size - old_size) * units.Ki + fstore_init_size
2324 mock_find_fstore = self.mock_object(self.mediator,
2325 '_find_fstore',
2326 mock.Mock(return_value=fstore))
2327 self.mock_client.setfsquota.side_effect = side_effect
2329 self.assertRaises(exception.ShareBackendException,
2330 self.mediator.resize_share,
2331 constants.EXPECTED_PROJECT_ID,
2332 constants.EXPECTED_SHARE_ID,
2333 constants.NFS,
2334 new_size,
2335 old_size,
2336 constants.EXPECTED_FPG,
2337 constants.EXPECTED_VFS)
2339 mock_find_fstore.assert_called_with(constants.EXPECTED_PROJECT_ID,
2340 constants.EXPECTED_SHARE_ID,
2341 constants.NFS,
2342 constants.EXPECTED_FPG,
2343 constants.EXPECTED_VFS,
2344 allow_cross_protocol=False)
2345 self.mock_client.setfsquota.assert_called_with(
2346 constants.EXPECTED_VFS,
2347 fpg=constants.EXPECTED_FPG,
2348 fstore=fstore,
2349 scapacity=str(expected_capacity),
2350 hcapacity=str(expected_capacity))
2352 def test_mediator_resize_share_not_found(self):
2353 self.init_mediator()
2354 mock_find_fshare = self.mock_object(self.mediator,
2355 '_find_fshare',
2356 mock.Mock(return_value=None))
2358 self.assertRaises(exception.InvalidShare,
2359 self.mediator.resize_share,
2360 constants.EXPECTED_PROJECT_ID,
2361 constants.EXPECTED_SHARE_ID,
2362 constants.NFS,
2363 999,
2364 99,
2365 constants.EXPECTED_FPG,
2366 constants.EXPECTED_VFS)
2368 mock_find_fshare.assert_called_with(constants.EXPECTED_PROJECT_ID,
2369 constants.EXPECTED_SHARE_ID,
2370 constants.NFS,
2371 constants.EXPECTED_FPG,
2372 constants.EXPECTED_VFS,
2373 allow_cross_protocol=False)
2375 @ddt.data((('nfs', 'NFS', 'nFs'), 'smb'),
2376 (('smb', 'SMB', 'SmB', 'CIFS', 'cifs', 'CiFs'), 'nfs'))
2377 @ddt.unpack
2378 def test_other_protocol(self, protocols, expected_other):
2379 for protocol in protocols:
2380 self.assertEqual(expected_other,
2381 hpe3parmediator.HPE3ParMediator().other_protocol(
2382 protocol))
2384 @ddt.data('', 'bogus')
2385 def test_other_protocol_exception(self, protocol):
2386 self.assertRaises(exception.InvalidShareAccess,
2387 hpe3parmediator.HPE3ParMediator().other_protocol,
2388 protocol)
2390 @ddt.data(('osf-uid', None, None, 'osf-uid'),
2391 ('uid', None, True, 'osf-ro-uid'),
2392 ('uid', None, False, 'osf-uid'),
2393 ('uid', 'smb', True, 'osf-smb-ro-uid'),
2394 ('uid', 'smb', False, 'osf-smb-uid'),
2395 ('uid', 'nfs', True, 'osf-nfs-ro-uid'),
2396 ('uid', 'nfs', False, 'osf-nfs-uid'))
2397 @ddt.unpack
2398 def test_ensure_prefix(self, uid, protocol, readonly, expected):
2399 self.assertEqual(expected,
2400 hpe3parmediator.HPE3ParMediator().ensure_prefix(
2401 uid, protocol=protocol, readonly=readonly))
2403 def test_find_fstore_search(self):
2404 self.init_mediator()
2406 mock_find_fshare = self.mock_object(self.mediator,
2407 '_find_fshare',
2408 mock.Mock(return_value=None))
2410 result = self.mediator._find_fstore(constants.EXPECTED_PROJECT_ID,
2411 constants.EXPECTED_SHARE_ID,
2412 constants.NFS,
2413 constants.EXPECTED_FPG,
2414 constants.EXPECTED_VFS)
2416 mock_find_fshare.assert_called_once_with(constants.EXPECTED_PROJECT_ID,
2417 constants.EXPECTED_SHARE_ID,
2418 constants.NFS,
2419 constants.EXPECTED_FPG,
2420 constants.EXPECTED_VFS,
2421 allow_cross_protocol=False)
2422 self.assertIsNone(result)
2424 def test_find_fstore_search_xproto(self):
2425 self.init_mediator()
2427 mock_find_fshare = self.mock_object(self.mediator,
2428 '_find_fshare_with_proto',
2429 mock.Mock(return_value=None))
2431 result = self.mediator._find_fstore(constants.EXPECTED_PROJECT_ID,
2432 constants.EXPECTED_SHARE_ID,
2433 constants.NFS,
2434 constants.EXPECTED_FPG,
2435 constants.EXPECTED_VFS,
2436 allow_cross_protocol=True)
2438 expected_calls = [
2439 mock.call(constants.EXPECTED_PROJECT_ID,
2440 constants.EXPECTED_SHARE_ID,
2441 constants.NFS,
2442 constants.EXPECTED_FPG,
2443 constants.EXPECTED_VFS,
2444 readonly=False),
2445 mock.call(constants.EXPECTED_PROJECT_ID,
2446 constants.EXPECTED_SHARE_ID,
2447 constants.SMB_LOWER,
2448 constants.EXPECTED_FPG,
2449 constants.EXPECTED_VFS,
2450 readonly=False),
2451 ]
2452 mock_find_fshare.assert_has_calls(expected_calls)
2453 self.assertIsNone(result)
2455 def test_find_fshare_search(self):
2456 self.init_mediator()
2458 self.mock_client.getfshare.return_value = {}
2460 result = self.mediator._find_fshare(constants.EXPECTED_PROJECT_ID,
2461 constants.EXPECTED_SHARE_ID,
2462 constants.NFS,
2463 constants.EXPECTED_FPG,
2464 constants.EXPECTED_VFS)
2466 expected_calls = [
2467 mock.call.getfshare(constants.NFS_LOWER,
2468 constants.EXPECTED_SHARE_ID,
2469 fpg=constants.EXPECTED_FPG,
2470 vfs=constants.EXPECTED_VFS,
2471 fstore=constants.EXPECTED_PROJECT_ID),
2472 mock.call.getfshare(constants.NFS_LOWER,
2473 constants.EXPECTED_SHARE_ID,
2474 fpg=constants.EXPECTED_FPG,
2475 vfs=constants.EXPECTED_VFS,
2476 fstore=constants.EXPECTED_SHARE_ID),
2477 mock.call.getfshare(constants.NFS_LOWER,
2478 constants.EXPECTED_SHARE_ID,
2479 fpg=constants.EXPECTED_FPG),
2480 mock.call.getfshare(constants.NFS_LOWER,
2481 constants.EXPECTED_SHARE_ID),
2482 ]
2483 self.mock_client.assert_has_calls(expected_calls)
2484 self.assertIsNone(result)
2486 def test_find_fshare_exception(self):
2487 self.init_mediator()
2489 self.mock_client.getfshare.side_effect = Exception('test unexpected')
2491 self.assertRaises(exception.ShareBackendException,
2492 self.mediator._find_fshare,
2493 constants.EXPECTED_PROJECT_ID,
2494 constants.EXPECTED_SHARE_ID,
2495 constants.NFS,
2496 constants.EXPECTED_FPG,
2497 constants.EXPECTED_VFS)
2499 self.mock_client.getfshare.assert_called_once_with(
2500 constants.NFS_LOWER,
2501 constants.EXPECTED_SHARE_ID,
2502 fpg=constants.EXPECTED_FPG,
2503 vfs=constants.EXPECTED_VFS,
2504 fstore=constants.EXPECTED_PROJECT_ID)
2506 def test_find_fshare_hit(self):
2507 self.init_mediator()
2509 expected_result = {'shareName': 'hit'}
2510 self.mock_client.getfshare.return_value = {
2511 'total': 1,
2512 'members': [expected_result]
2513 }
2515 result = self.mediator._find_fshare(constants.EXPECTED_PROJECT_ID,
2516 constants.EXPECTED_SHARE_ID,
2517 constants.NFS,
2518 constants.EXPECTED_FPG,
2519 constants.EXPECTED_VFS)
2521 self.mock_client.getfshare.assert_called_once_with(
2522 constants.NFS_LOWER,
2523 constants.EXPECTED_SHARE_ID,
2524 fpg=constants.EXPECTED_FPG,
2525 vfs=constants.EXPECTED_VFS,
2526 fstore=constants.EXPECTED_PROJECT_ID),
2527 self.assertEqual(expected_result, result)
2529 def test_find_fsnap_search(self):
2530 self.init_mediator()
2532 self.mock_client.getfsnap.return_value = {}
2534 result = self.mediator._find_fsnap(constants.EXPECTED_PROJECT_ID,
2535 constants.EXPECTED_SHARE_ID,
2536 constants.NFS,
2537 constants.EXPECTED_SNAP_ID,
2538 constants.EXPECTED_FPG,
2539 constants.EXPECTED_VFS)
2541 expected_snap_pattern = '*_%s' % constants.EXPECTED_SNAP_ID
2543 expected_calls = [
2544 mock.call.getfsnap(expected_snap_pattern,
2545 vfs=constants.EXPECTED_VFS,
2546 fpg=constants.EXPECTED_FPG,
2547 pat=True,
2548 fstore=constants.EXPECTED_PROJECT_ID),
2549 mock.call.getfsnap(expected_snap_pattern,
2550 vfs=constants.EXPECTED_VFS,
2551 fpg=constants.EXPECTED_FPG,
2552 pat=True,
2553 fstore=constants.EXPECTED_SHARE_ID),
2554 mock.call.getfsnap(expected_snap_pattern,
2555 fpg=constants.EXPECTED_FPG,
2556 pat=True),
2557 mock.call.getfsnap(expected_snap_pattern, pat=True),
2558 ]
2559 self.mock_client.assert_has_calls(expected_calls)
2560 self.assertIsNone(result)
2562 def test_find_fsnap_exception(self):
2563 self.init_mediator()
2565 self.mock_client.getfsnap.side_effect = Exception('test unexpected')
2567 self.assertRaises(exception.ShareBackendException,
2568 self.mediator._find_fsnap,
2569 constants.EXPECTED_PROJECT_ID,
2570 constants.EXPECTED_SHARE_ID,
2571 constants.NFS,
2572 constants.EXPECTED_SNAP_ID,
2573 constants.EXPECTED_FPG,
2574 constants.EXPECTED_VFS)
2576 expected_snap_pattern = '*_%s' % constants.EXPECTED_SNAP_ID
2578 self.mock_client.getfsnap.assert_called_once_with(
2579 expected_snap_pattern,
2580 vfs=constants.EXPECTED_VFS,
2581 fpg=constants.EXPECTED_FPG,
2582 pat=True,
2583 fstore=constants.EXPECTED_PROJECT_ID)
2585 def test_find_fsnap_hit(self):
2586 self.init_mediator()
2588 expected_result = {'snapName': 'hit'}
2589 self.mock_client.getfsnap.return_value = {
2590 'total': 1,
2591 'members': [expected_result]
2592 }
2594 result = self.mediator._find_fsnap(constants.EXPECTED_PROJECT_ID,
2595 constants.EXPECTED_SHARE_ID,
2596 constants.NFS,
2597 constants.EXPECTED_SNAP_ID,
2598 constants.EXPECTED_FPG,
2599 constants.EXPECTED_VFS)
2601 expected_snap_pattern = '*_%s' % constants.EXPECTED_SNAP_ID
2603 self.mock_client.getfsnap.assert_called_once_with(
2604 expected_snap_pattern,
2605 vfs=constants.EXPECTED_VFS,
2606 fpg=constants.EXPECTED_FPG,
2607 pat=True,
2608 fstore=constants.EXPECTED_PROJECT_ID)
2610 self.assertEqual(expected_result, result)
2612 def test_fsip_exists(self):
2613 self.init_mediator()
2615 # Make the result member a superset of the fsip items.
2616 fsip_plus = constants.EXPECTED_FSIP.copy()
2617 fsip_plus.update({'k': 'v', 'k2': 'v2'})
2619 self.mock_client.getfsip.return_value = {
2620 'total': 3,
2621 'members': [{'bogus1': 1}, fsip_plus, {'bogus2': '2'}]
2622 }
2624 self.assertTrue(self.mediator.fsip_exists(constants.EXPECTED_FSIP))
2626 self.mock_client.getfsip.assert_called_once_with(
2627 constants.EXPECTED_VFS,
2628 fpg=constants.EXPECTED_FPG)
2630 def test_fsip_does_not_exist(self):
2631 self.init_mediator()
2633 self.mock_client.getfsip.return_value = {
2634 'total': 3,
2635 'members': [{'bogus1': 1}, constants.OTHER_FSIP, {'bogus2': '2'}]
2636 }
2638 self.assertFalse(self.mediator.fsip_exists(constants.EXPECTED_FSIP))
2640 self.mock_client.getfsip.assert_called_once_with(
2641 constants.EXPECTED_VFS,
2642 fpg=constants.EXPECTED_FPG)
2644 def test_fsip_exists_exception(self):
2645 self.init_mediator()
2647 class FakeException(Exception):
2648 pass
2650 self.mock_client.getfsip.side_effect = FakeException()
2652 self.assertRaises(exception.ShareBackendException,
2653 self.mediator.fsip_exists,
2654 constants.EXPECTED_FSIP)
2656 self.mock_client.getfsip.assert_called_once_with(
2657 constants.EXPECTED_VFS,
2658 fpg=constants.EXPECTED_FPG)
2660 def test_create_fsip_success(self):
2661 self.init_mediator()
2663 # Make the result member a superset of the fsip items.
2664 fsip_plus = constants.EXPECTED_FSIP.copy()
2665 fsip_plus.update({'k': 'v', 'k2': 'v2'})
2667 self.mock_client.getfsip.return_value = {
2668 'total': 3,
2669 'members': [{'bogus1': 1}, fsip_plus, {'bogus2': '2'}]
2670 }
2672 self.mediator.create_fsip(constants.EXPECTED_IP_1234,
2673 constants.EXPECTED_SUBNET,
2674 constants.EXPECTED_VLAN_TAG,
2675 constants.EXPECTED_FPG,
2676 constants.EXPECTED_VFS)
2678 self.mock_client.getfsip.assert_called_once_with(
2679 constants.EXPECTED_VFS,
2680 fpg=constants.EXPECTED_FPG)
2682 expected_calls = [
2683 mock.call.createfsip(constants.EXPECTED_IP_1234,
2684 constants.EXPECTED_SUBNET,
2685 constants.EXPECTED_VFS,
2686 fpg=constants.EXPECTED_FPG,
2687 vlantag=constants.EXPECTED_VLAN_TAG),
2688 mock.call.getfsip(constants.EXPECTED_VFS,
2689 fpg=constants.EXPECTED_FPG),
2690 ]
2691 self.mock_client.assert_has_calls(expected_calls)
2693 def test_create_fsip_exception(self):
2694 self.init_mediator()
2696 class FakeException(Exception):
2697 pass
2699 self.mock_client.createfsip.side_effect = FakeException()
2701 self.assertRaises(exception.ShareBackendException,
2702 self.mediator.create_fsip,
2703 constants.EXPECTED_IP_1234,
2704 constants.EXPECTED_SUBNET,
2705 constants.EXPECTED_VLAN_TAG,
2706 constants.EXPECTED_FPG,
2707 constants.EXPECTED_VFS)
2709 self.mock_client.createfsip.assert_called_once_with(
2710 constants.EXPECTED_IP_1234,
2711 constants.EXPECTED_SUBNET,
2712 constants.EXPECTED_VFS,
2713 fpg=constants.EXPECTED_FPG,
2714 vlantag=constants.EXPECTED_VLAN_TAG)
2716 def test_create_fsip_get_none(self):
2717 self.init_mediator()
2719 self.mock_client.getfsip.return_value = {'members': []}
2721 self.assertRaises(exception.ShareBackendException,
2722 self.mediator.create_fsip,
2723 constants.EXPECTED_IP_1234,
2724 constants.EXPECTED_SUBNET,
2725 constants.EXPECTED_VLAN_TAG,
2726 constants.EXPECTED_FPG,
2727 constants.EXPECTED_VFS)
2729 expected_calls = [
2730 mock.call.createfsip(constants.EXPECTED_IP_1234,
2731 constants.EXPECTED_SUBNET,
2732 constants.EXPECTED_VFS,
2733 fpg=constants.EXPECTED_FPG,
2734 vlantag=constants.EXPECTED_VLAN_TAG),
2735 mock.call.getfsip(constants.EXPECTED_VFS,
2736 fpg=constants.EXPECTED_FPG),
2737 ]
2738 self.mock_client.assert_has_calls(expected_calls)
2740 def test_remove_fsip_success(self):
2741 self.init_mediator()
2743 self.mock_client.getfsip.return_value = {
2744 'members': [constants.OTHER_FSIP]
2745 }
2747 self.mediator.remove_fsip(constants.EXPECTED_IP_1234,
2748 constants.EXPECTED_FPG,
2749 constants.EXPECTED_VFS)
2751 expected_calls = [
2752 mock.call.removefsip(constants.EXPECTED_VFS,
2753 constants.EXPECTED_IP_1234,
2754 fpg=constants.EXPECTED_FPG),
2755 mock.call.getfsip(constants.EXPECTED_VFS,
2756 fpg=constants.EXPECTED_FPG),
2757 ]
2758 self.mock_client.assert_has_calls(expected_calls)
2760 @ddt.data(('ip', None),
2761 ('ip', ''),
2762 (None, 'vfs'),
2763 ('', 'vfs'),
2764 (None, None),
2765 ('', ''))
2766 @ddt.unpack
2767 def test_remove_fsip_without_ip_or_vfs(self, ip, vfs):
2768 self.init_mediator()
2769 self.mediator.remove_fsip(ip, constants.EXPECTED_FPG, vfs)
2770 self.assertFalse(self.mock_client.removefsip.called)
2772 def test_remove_fsip_not_gone(self):
2773 self.init_mediator()
2775 self.mock_client.getfsip.return_value = {
2776 'members': [constants.EXPECTED_FSIP]
2777 }
2779 self.assertRaises(exception.ShareBackendException,
2780 self.mediator.remove_fsip,
2781 constants.EXPECTED_IP_1234,
2782 constants.EXPECTED_FPG,
2783 constants.EXPECTED_VFS)
2785 expected_calls = [
2786 mock.call.removefsip(constants.EXPECTED_VFS,
2787 constants.EXPECTED_IP_1234,
2788 fpg=constants.EXPECTED_FPG),
2789 mock.call.getfsip(constants.EXPECTED_VFS,
2790 fpg=constants.EXPECTED_FPG),
2791 ]
2792 self.mock_client.assert_has_calls(expected_calls)
2794 def test_remove_fsip_exception(self):
2795 self.init_mediator()
2797 class FakeException(Exception):
2798 pass
2800 self.mock_client.removefsip.side_effect = FakeException()
2802 self.assertRaises(exception.ShareBackendException,
2803 self.mediator.remove_fsip,
2804 constants.EXPECTED_IP_1234,
2805 constants.EXPECTED_FPG,
2806 constants.EXPECTED_VFS)
2808 self.mock_client.removefsip.assert_called_once_with(
2809 constants.EXPECTED_VFS,
2810 constants.EXPECTED_IP_1234,
2811 fpg=constants.EXPECTED_FPG)
2813 def test__create_mount_directory(self):
2814 self.init_mediator()
2816 mount_location = '/mnt/foo'
2817 self.mediator._create_mount_directory(mount_location)
2819 utils.execute.assert_called_with('mkdir', mount_location,
2820 run_as_root=True)
2822 def test__create_mount_directory_error(self):
2823 self.init_mediator()
2825 self.mock_object(utils, 'execute',
2826 mock.Mock(side_effect=Exception('mkdir error.')))
2827 mock_log = self.mock_object(hpe3parmediator, 'LOG')
2829 mount_location = '/mnt/foo'
2830 self.mediator._create_mount_directory(mount_location)
2831 utils.execute.assert_called_with('mkdir', mount_location,
2832 run_as_root=True)
2834 # Warning is logged (no exception thrown).
2835 self.assertTrue(mock_log.warning.called)
2837 def test__mount_super_share(self):
2838 self.init_mediator()
2840 # Test mounting NFS share.
2841 protocol = 'nfs'
2842 mount_location = '/mnt/foo'
2843 fpg = 'foo-fpg'
2844 vfs = 'bar-vfs'
2845 fstore = 'fstore'
2846 mount_path = '%s:/%s/%s/%s/' % (constants.EXPECTED_IP_10203040, fpg,
2847 vfs, fstore)
2848 self.mediator._mount_super_share(protocol, mount_location, fpg, vfs,
2849 fstore,
2850 constants.EXPECTED_IP_10203040)
2852 utils.execute.assert_called_with('mount', '-t', protocol, mount_path,
2853 mount_location, run_as_root=True)
2855 # Test mounting CIFS share.
2856 protocol = 'smb'
2857 mount_path = '//%s/%s/' % (constants.EXPECTED_IP_10203040,
2858 constants.EXPECTED_SUPER_SHARE)
2859 user = 'username=%s,password=%s,domain=%s' % (
2860 constants.USERNAME, constants.PASSWORD,
2861 constants.EXPECTED_CIFS_DOMAIN)
2862 self.mediator._mount_super_share(protocol, mount_location, fpg, vfs,
2863 fstore,
2864 constants.EXPECTED_IP_10203040)
2866 utils.execute.assert_called_with('mount', '-t', 'cifs', mount_path,
2867 mount_location, '-o', user,
2868 run_as_root=True)
2870 def test__mount_super_share_error(self):
2871 self.init_mediator()
2873 self.mock_object(utils, 'execute',
2874 mock.Mock(side_effect=Exception('mount error.')))
2875 mock_log = self.mock_object(hpe3parmediator, 'LOG')
2877 protocol = 'nfs'
2878 mount_location = '/mnt/foo'
2879 fpg = 'foo-fpg'
2880 vfs = 'bar-vfs'
2881 fstore = 'fstore'
2882 self.mediator._mount_super_share(protocol, mount_location, fpg, vfs,
2883 fstore,
2884 constants.EXPECTED_IP_10203040)
2886 # Warning is logged (no exception thrown).
2887 self.assertTrue(mock_log.warning.called)
2889 def test__delete_share_directory(self):
2890 self.init_mediator()
2892 mount_location = '/mnt/foo'
2893 self.mediator._delete_share_directory(mount_location)
2895 utils.execute.assert_called_with('rm', '-rf', mount_location,
2896 run_as_root=True)
2898 def test__delete_share_directory_error(self):
2899 self.init_mediator()
2901 self.mock_object(utils, 'execute',
2902 mock.Mock(side_effect=Exception('rm error.')))
2903 mock_log = self.mock_object(hpe3parmediator, 'LOG')
2905 mount_location = '/mnt/foo'
2906 self.mediator._delete_share_directory(mount_location)
2908 # Warning is logged (no exception thrown).
2909 self.assertTrue(mock_log.warning.called)
2911 def test__unmount_share(self):
2912 self.init_mediator()
2914 mount_dir = '/mnt/foo'
2915 self.mediator._unmount_share(mount_dir)
2917 utils.execute.assert_called_with('umount', mount_dir, run_as_root=True)
2919 def test__unmount_share_error(self):
2920 self.init_mediator()
2922 self.mock_object(utils, 'execute',
2923 mock.Mock(side_effect=Exception('umount error.')))
2924 mock_log = self.mock_object(hpe3parmediator, 'LOG')
2926 mount_dir = '/mnt/foo'
2927 self.mediator._unmount_share(mount_dir)
2929 # Warning is logged (no exception thrown).
2930 self.assertTrue(mock_log.warning.called)
2932 def test__delete_file_tree_no_config_options(self):
2933 self.init_mediator()
2935 mock_log = self.mock_object(hpe3parmediator, 'LOG')
2937 self.mediator.hpe3par_cifs_admin_access_username = None
2938 self.mediator._delete_file_tree(
2939 constants.EXPECTED_SHARE_ID,
2940 constants.SMB_LOWER,
2941 constants.EXPECTED_FPG,
2942 constants.EXPECTED_VFS,
2943 constants.EXPECTED_FSTORE,
2944 constants.EXPECTED_SHARE_IP)
2946 # Warning is logged (no exception thrown).
2947 self.assertTrue(mock_log.warning.called)
2949 def test__create_super_share_createfshare_exception(self):
2950 self.init_mediator()
2952 self.mock_client.createfshare.side_effect = (
2953 Exception("createfshare error."))
2955 self.assertRaises(
2956 exception.ShareBackendException,
2957 self.mediator._create_super_share,
2958 constants.NFS_LOWER,
2959 constants.EXPECTED_FPG,
2960 constants.EXPECTED_VFS,
2961 constants.EXPECTED_FSTORE)
2963 def test__create_super_share_setfshare_exception(self):
2964 self.init_mediator()
2966 self.mock_client.setfshare.side_effect = (
2967 Exception("setfshare error."))
2969 self.assertRaises(
2970 exception.ShareBackendException,
2971 self.mediator._create_super_share,
2972 constants.SMB_LOWER,
2973 constants.EXPECTED_FPG,
2974 constants.EXPECTED_VFS,
2975 constants.EXPECTED_FSTORE)
2977 def test__revoke_admin_smb_access_error(self):
2978 self.init_mediator()
2980 self.mock_client.setfshare.side_effect = (
2981 Exception("setfshare error"))
2983 self.assertRaises(
2984 exception.ShareBackendException,
2985 self.mediator._revoke_admin_smb_access,
2986 constants.SMB_LOWER,
2987 constants.EXPECTED_FPG,
2988 constants.EXPECTED_VFS,
2989 constants.EXPECTED_FSTORE,
2990 constants.EXPECTED_COMMENT)
2992 def test_build_export_locations_bad_protocol(self):
2993 self.assertRaises(exception.InvalidShareAccess,
2994 self.mediator.build_export_locations,
2995 "BOGUS",
2996 [constants.EXPECTED_IP_1234],
2997 constants.EXPECTED_SHARE_PATH)
2999 def test_build_export_locations_bad_ip(self):
3000 self.assertRaises(exception.InvalidInput,
3001 self.mediator.build_export_locations,
3002 constants.NFS,
3003 None,
3004 None)
3006 def test_build_export_locations_bad_path(self):
3007 self.assertRaises(exception.InvalidInput,
3008 self.mediator.build_export_locations,
3009 constants.NFS,
3010 [constants.EXPECTED_IP_1234],
3011 None)
3014class OptionMatcher(object):
3015 """Options string order can vary. Compare as lists."""
3017 def __init__(self, assert_func, expected_string):
3018 self.assert_func = assert_func
3019 self.expected = expected_string.split(',')
3021 def __eq__(self, actual_string):
3022 actual = actual_string.split(',')
3023 self.assert_func(sorted(self.expected), sorted(actual))
3024 return True