Coverage for manila/tests/share/drivers/ibm/test_gpfs.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 (c) 2014 IBM Corp.
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.
15"""Unit tests for the IBM GPFS driver module."""
17import re
18import socket
19from unittest import mock
21import ddt
22from oslo_config import cfg
24from manila import context
25from manila import exception
26import manila.share.configuration as config
27import manila.share.drivers.ibm.gpfs as gpfs
28from manila.share import share_types
29from manila import ssh_utils
30from manila import test
31from manila.tests import fake_share
32from manila import utils
35CONF = cfg.CONF
38@ddt.ddt
39class GPFSShareDriverTestCase(test.TestCase):
40 """Tests GPFSShareDriver."""
42 def setUp(self):
43 super(GPFSShareDriverTestCase, self).setUp()
44 self._context = context.get_admin_context()
45 self._gpfs_execute = mock.Mock(return_value=('', ''))
46 self.GPFS_PATH = '/usr/lpp/mmfs/bin/'
48 self._helper_fake = mock.Mock()
49 CONF.set_default('driver_handles_share_servers', False)
50 CONF.set_default('share_backend_name', 'GPFS')
51 self.fake_conf = config.Configuration(None)
52 self._driver = gpfs.GPFSShareDriver(execute=self._gpfs_execute,
53 configuration=self.fake_conf)
54 self._knfs_helper = gpfs.KNFSHelper(self._gpfs_execute,
55 self.fake_conf)
56 self._ces_helper = gpfs.CESHelper(self._gpfs_execute,
57 self.fake_conf)
58 self.fakedev = "/dev/gpfs0"
59 self.fakefspath = "/gpfs0"
60 self.fakesharepath = "/gpfs0/share-fakeid"
61 self.fakeexistingshare = "existingshare"
62 self.fakesnapshotpath = "/gpfs0/.snapshots/snapshot-fakesnapshotid"
64 self.fake_ces_exports = """
65mmcesnfslsexport:nfsexports:HEADER:version:reserved:reserved:Path:Delegations:Clients:Access_Type:Protocols:Transports:Squash:Anonymous_uid:Anonymous_gid:SecType:PrivilegedPort:DefaultDelegations:Manage_Gids:NFS_Commit:
66mmcesnfslsexport:nfsexports:0:1:::/gpfs0/share-fakeid:none:44.3.2.11:RW:3,4:TCP:ROOT_SQUASH:-2:-2:SYS:FALSE:none:FALSE:FALSE:
67mmcesnfslsexport:nfsexports:0:1:::/gpfs0/share-fakeid:none:1:2:3:4:5:6:7:8:RW:3,4:TCP:ROOT_SQUASH:-2:-2:SYS:FALSE:none:FALSE:FALSE:
68mmcesnfslsexport:nfsexports:0:1:::/gpfs0/share-fakeid:none:10.0.0.1:RW:3,4:TCP:ROOT_SQUASH:-2:-2:SYS:FALSE:none:FALSE:FALSE:
70 """
71 self.fake_ces_exports_not_found = """
73mmcesnfslsexport:nfsexports:HEADER:version:reserved:reserved:Path:Delegations:Clients:Access_Type:Protocols:Transports:Squash:Anonymous_uid:Anonymous_gid:SecType:PrivilegedPort:DefaultDelegations:Manage_Gids:NFS_Commit:
75 """
77 self.mock_object(gpfs.os.path, 'exists', mock.Mock(return_value=True))
78 self._driver._helpers = {
79 'CES': self._helper_fake
80 }
81 self.share = fake_share.fake_share(share_proto='NFS',
82 host='fakehost@fakehost#GPFS')
83 self.server = {
84 'backend_details': {
85 'ip': '1.2.3.4',
86 'instance_id': 'fake'
87 }
88 }
89 self.access = fake_share.fake_access()
90 self.snapshot = fake_share.fake_snapshot()
91 self.local_ip = "192.11.22.1"
92 self.remote_ip = "192.11.22.2"
93 self.remote_ip2 = "2.2.2.2"
94 gpfs_nfs_server_list = [self.remote_ip, self.local_ip, self.remote_ip2,
95 "fake_location"]
96 self._knfs_helper.configuration.gpfs_nfs_server_list = (
97 gpfs_nfs_server_list)
98 self._ces_helper.configuration.gpfs_nfs_server_list = (
99 gpfs_nfs_server_list)
100 self._ces_helper.configuration.ganesha_config_path = (
101 "fake_ganesha_config_path")
102 self.sshlogin = "fake_login"
103 self.sshkey = "fake_sshkey"
104 self.gservice = "fake_ganesha_service"
105 self._ces_helper.configuration.gpfs_ssh_login = self.sshlogin
106 self._ces_helper.configuration.gpfs_ssh_private_key = self.sshkey
107 self._ces_helper.configuration.ganesha_service_name = self.gservice
108 self.mock_object(socket, 'gethostname',
109 mock.Mock(return_value="testserver"))
110 self.mock_object(socket, 'gethostbyname_ex', mock.Mock(
111 return_value=('localhost',
112 ['localhost.localdomain', 'testserver'],
113 ['127.0.0.1', self.local_ip])
114 ))
116 def test__run_ssh(self):
117 cmd_list = ['fake', 'cmd']
118 expected_cmd = 'fake cmd'
119 ssh_pool = mock.Mock()
120 ssh = mock.Mock()
121 self.mock_object(ssh_utils,
122 'SSHPool',
123 mock.Mock(return_value=ssh_pool))
124 ssh_pool.item = mock.Mock(return_value=ssh)
125 setattr(ssh, '__enter__', mock.Mock())
126 setattr(ssh, '__exit__', mock.Mock())
127 self.mock_object(self._driver, '_gpfs_ssh_execute')
128 self._driver._run_ssh(self.local_ip, cmd_list)
130 self._driver._gpfs_ssh_execute.assert_called_once_with(
131 mock.ANY, expected_cmd, check_exit_code=True,
132 ignore_exit_code=None)
134 def test__run_ssh_exception(self):
135 cmd_list = ['fake', 'cmd']
136 ssh_pool = mock.Mock()
137 ssh = mock.Mock()
138 self.mock_object(ssh_utils,
139 'SSHPool',
140 mock.Mock(return_value=ssh_pool))
141 ssh_pool.item = mock.Mock(return_value=ssh)
142 self.mock_object(self._driver, '_gpfs_ssh_execute')
143 self.assertRaises(exception.GPFSException,
144 self._driver._run_ssh,
145 self.local_ip, cmd_list)
147 def test__gpfs_ssh_execute(self):
148 cmd = 'fake cmd'
149 expected_out = 'cmd successful'
150 expected_err = 'cmd error'
151 ssh = mock.Mock()
152 stdin_stream = mock.Mock()
153 stdout_stream = mock.Mock()
154 stderr_stream = mock.Mock()
155 ssh.exec_command = mock.Mock(return_value=(stdin_stream,
156 stdout_stream,
157 stderr_stream))
158 stdout_stream.channel.recv_exit_status = mock.Mock(return_value=-1)
159 stdout_stream.read = mock.Mock(return_value=expected_out)
160 stderr_stream.read = mock.Mock(return_value=expected_err)
161 stdin_stream.close = mock.Mock()
162 actual_out, actual_err = self._driver._gpfs_ssh_execute(ssh, cmd)
164 self.assertEqual(actual_out, expected_out)
165 self.assertEqual(actual_err, expected_err)
167 def test__gpfs_ssh_execute_exception(self):
168 cmd = 'fake cmd'
169 ssh = mock.Mock()
170 stdin_stream = mock.Mock()
171 stdout_stream = mock.Mock()
172 stderr_stream = mock.Mock()
173 ssh.exec_command = mock.Mock(return_value=(stdin_stream,
174 stdout_stream,
175 stderr_stream))
176 stdout_stream.channel.recv_exit_status = mock.Mock(return_value=1)
177 stdout_stream.read = mock.Mock()
178 stderr_stream.read = mock.Mock()
179 stdin_stream.close = mock.Mock()
180 self.assertRaises(exception.ProcessExecutionError,
181 self._driver._gpfs_ssh_execute,
182 ssh, cmd)
184 def test_get_share_stats_refresh_false(self):
185 self._driver._stats = {'fake_key': 'fake_value'}
186 result = self._driver.get_share_stats(False)
187 self.assertEqual(self._driver._stats, result)
189 def test_get_share_stats_refresh_true(self):
190 self.mock_object(
191 self._driver, '_get_available_capacity',
192 mock.Mock(return_value=(11111.0, 12345.0)))
193 result = self._driver.get_share_stats(True)
194 expected_keys = [
195 'qos', 'driver_version', 'share_backend_name',
196 'free_capacity_gb', 'total_capacity_gb',
197 'driver_handles_share_servers',
198 'reserved_percentage', 'vendor_name', 'storage_protocol',
199 ]
200 for key in expected_keys:
201 self.assertIn(key, result)
202 self.assertFalse(result['driver_handles_share_servers'])
203 self.assertEqual('IBM', result['vendor_name'])
204 self._driver._get_available_capacity.assert_called_once_with(
205 self._driver.configuration.gpfs_mount_point_base)
207 def test_do_setup(self):
208 self.mock_object(self._driver, '_setup_helpers')
209 self._driver.do_setup(self._context)
210 self.assertEqual(self._driver._gpfs_execute,
211 self._driver._gpfs_remote_execute)
212 self._driver._setup_helpers.assert_called_once_with()
214 def test_do_setup_gpfs_local_execute(self):
215 self.mock_object(self._driver, '_setup_helpers')
216 self._driver.configuration.is_gpfs_node = True
217 self._driver.do_setup(self._context)
218 self.assertEqual(self._driver._gpfs_execute,
219 self._driver._gpfs_local_execute)
220 self._driver._setup_helpers.assert_called_once_with()
222 def test_setup_helpers(self):
223 self._driver._helpers = {}
224 CONF.set_default('gpfs_share_helpers', ['CES=fakenfs'])
225 self.mock_object(gpfs.importutils, 'import_class',
226 mock.Mock(return_value=self._helper_fake))
227 self._driver._setup_helpers()
228 gpfs.importutils.import_class.assert_has_calls(
229 [mock.call('fakenfs')]
230 )
231 self.assertEqual(len(self._driver._helpers), 1)
233 @ddt.data(fake_share.fake_share(),
234 fake_share.fake_share(share_proto='NFSBOGUS'))
235 def test__get_helper_with_wrong_proto(self, share):
236 self.assertRaises(exception.InvalidShare,
237 self._driver._get_helper, share)
239 def test__local_path(self):
240 sharename = 'fakesharename'
241 self._driver.configuration.gpfs_mount_point_base = (
242 self.fakefspath)
243 local_path = self._driver._local_path(sharename)
244 self.assertEqual(self.fakefspath + '/' + sharename,
245 local_path)
247 def test__get_share_path(self):
248 self._driver.configuration.gpfs_mount_point_base = (
249 self.fakefspath)
250 share_path = self._driver._get_share_path(self.share)
251 self.assertEqual(self.fakefspath + '/' + self.share['name'],
252 share_path)
254 def test__get_snapshot_path(self):
255 self._driver.configuration.gpfs_mount_point_base = (
256 self.fakefspath)
257 snapshot_path = self._driver._get_snapshot_path(self.snapshot)
258 self.assertEqual(self.fakefspath + '/' + self.snapshot['share_name'] +
259 '/.snapshots/' + self.snapshot['name'],
260 snapshot_path)
262 def test_check_for_setup_error_for_gpfs_state(self):
263 self.mock_object(self._driver, '_check_gpfs_state',
264 mock.Mock(return_value=False))
265 self.assertRaises(exception.GPFSException,
266 self._driver.check_for_setup_error)
268 def test_check_for_setup_error_for_export_ip(self):
269 self.mock_object(self._driver, '_check_gpfs_state',
270 mock.Mock(return_value=True))
272 self._driver.configuration.gpfs_share_export_ip = None
273 self.assertRaises(exception.InvalidParameterValue,
274 self._driver.check_for_setup_error)
276 def test_check_for_setup_error_for_gpfs_mount_point_base(self):
277 self.mock_object(self._driver, '_check_gpfs_state',
278 mock.Mock(return_value=True))
279 self._driver.configuration.gpfs_share_export_ip = self.local_ip
280 self._driver.configuration.gpfs_mount_point_base = 'test'
281 self.assertRaises(exception.GPFSException,
282 self._driver.check_for_setup_error)
284 def test_check_for_setup_error_for_directory_check(self):
285 self.mock_object(self._driver, '_check_gpfs_state',
286 mock.Mock(return_value=True))
287 self._driver.configuration.gpfs_share_export_ip = self.local_ip
288 self._driver.configuration.gpfs_mount_point_base = self.fakefspath
289 self.mock_object(self._driver, '_is_dir',
290 mock.Mock(return_value=False))
291 self.assertRaises(exception.GPFSException,
292 self._driver.check_for_setup_error)
294 def test_check_for_setup_error_for_gpfs_path_check(self):
295 self.mock_object(self._driver, '_check_gpfs_state',
296 mock.Mock(return_value=True))
297 self._driver.configuration.gpfs_share_export_ip = self.local_ip
298 self._driver.configuration.gpfs_mount_point_base = self.fakefspath
299 self.mock_object(self._driver, '_is_dir',
300 mock.Mock(return_value=True))
301 self.mock_object(self._driver, '_is_gpfs_path',
302 mock.Mock(return_value=False))
303 self.assertRaises(exception.GPFSException,
304 self._driver.check_for_setup_error)
306 def test_check_for_setup_error_for_nfs_server_type(self):
307 self.mock_object(self._driver, '_check_gpfs_state',
308 mock.Mock(return_value=True))
309 self._driver.configuration.gpfs_share_export_ip = self.local_ip
310 self._driver.configuration.gpfs_mount_point_base = self.fakefspath
311 self.mock_object(self._driver, '_is_dir',
312 mock.Mock(return_value=True))
313 self.mock_object(self._driver, '_is_gpfs_path',
314 mock.Mock(return_value=True))
315 self._driver.configuration.gpfs_nfs_server_type = 'test'
316 self.assertRaises(exception.InvalidParameterValue,
317 self._driver.check_for_setup_error)
319 def test_check_for_setup_error_for_nfs_server_list(self):
320 self.mock_object(self._driver, '_check_gpfs_state',
321 mock.Mock(return_value=True))
322 self._driver.configuration.gpfs_share_export_ip = self.local_ip
323 self._driver.configuration.gpfs_mount_point_base = self.fakefspath
324 self.mock_object(self._driver, '_is_dir',
325 mock.Mock(return_value=True))
326 self.mock_object(self._driver, '_is_gpfs_path',
327 mock.Mock(return_value=True))
328 self._driver.configuration.gpfs_nfs_server_type = 'KNFS'
329 self._driver.configuration.gpfs_nfs_server_list = None
330 self.assertRaises(exception.InvalidParameterValue,
331 self._driver.check_for_setup_error)
333 def test__get_available_capacity(self):
334 path = self.fakefspath
335 mock_out = "Filesystem 1-blocks Used Available Capacity Mounted on\n\
336 /dev/gpfs0 100 30 70 30% /gpfs0"
337 self.mock_object(self._driver, '_gpfs_execute',
338 mock.Mock(return_value=(mock_out, '')))
339 available, size = self._driver._get_available_capacity(path)
340 self.assertEqual(70, available)
341 self.assertEqual(100, size)
343 def test_create_share(self):
344 self._helper_fake.create_export.return_value = 'fakelocation'
345 methods = ('_create_share', '_get_share_path')
346 for method in methods:
347 self.mock_object(self._driver, method)
348 result = self._driver.create_share(self._context, self.share,
349 share_server=self.server)
350 self._driver._create_share.assert_called_once_with(self.share)
351 self._driver._get_share_path.assert_called_once_with(self.share)
353 self.assertEqual(result, 'fakelocation')
355 def test_create_share_from_snapshot(self):
356 self._helper_fake.create_export.return_value = 'fakelocation'
357 self._driver._get_share_path = mock.Mock(return_value=self.
358 fakesharepath)
359 self._driver._create_share_from_snapshot = mock.Mock()
360 result = self._driver.create_share_from_snapshot(self._context,
361 self.share,
362 self.snapshot,
363 share_server=None)
364 self._driver._get_share_path.assert_called_once_with(self.share)
365 self._driver._create_share_from_snapshot.assert_called_once_with(
366 self.share, self.snapshot,
367 self.fakesharepath
368 )
369 self.assertEqual(result, 'fakelocation')
371 def test_create_snapshot(self):
372 self._driver._create_share_snapshot = mock.Mock()
373 self._driver.create_snapshot(self._context, self.snapshot,
374 share_server=None)
375 self._driver._create_share_snapshot.assert_called_once_with(
376 self.snapshot
377 )
379 def test_delete_share(self):
380 self._driver._get_share_path = mock.Mock(
381 return_value=self.fakesharepath
382 )
383 self._driver._delete_share = mock.Mock()
385 self._driver.delete_share(self._context, self.share,
386 share_server=None)
388 self._driver._get_share_path.assert_called_once_with(self.share)
389 self._driver._delete_share.assert_called_once_with(self.share)
390 self._helper_fake.remove_export.assert_called_once_with(
391 self.fakesharepath, self.share
392 )
394 def test_delete_snapshot(self):
395 self._driver._delete_share_snapshot = mock.Mock()
396 self._driver.delete_snapshot(self._context, self.snapshot,
397 share_server=None)
398 self._driver._delete_share_snapshot.assert_called_once_with(
399 self.snapshot
400 )
402 def test__delete_share_snapshot(self):
403 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
404 self._driver._gpfs_execute = mock.Mock(return_value=0)
405 self._driver._delete_share_snapshot(self.snapshot)
406 self._driver._gpfs_execute.assert_called_once_with(
407 self.GPFS_PATH + 'mmdelsnapshot', self.fakedev,
408 self.snapshot['name'], '-j', self.snapshot['share_name']
409 )
410 self._driver._get_gpfs_device.assert_called_once_with()
412 def test__delete_share_snapshot_exception(self):
413 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
414 self._driver._gpfs_execute = mock.Mock(
415 side_effect=exception.ProcessExecutionError
416 )
417 self.assertRaises(exception.GPFSException,
418 self._driver._delete_share_snapshot, self.snapshot)
419 self._driver._get_gpfs_device.assert_called_once_with()
420 self._driver._gpfs_execute.assert_called_once_with(
421 self.GPFS_PATH + 'mmdelsnapshot', self.fakedev,
422 self.snapshot['name'], '-j', self.snapshot['share_name']
423 )
425 def test_extend_share(self):
426 self._driver._extend_share = mock.Mock()
427 self._driver.extend_share(self.share, 10)
428 self._driver._extend_share.assert_called_once_with(self.share, 10)
430 def test__extend_share(self):
431 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
432 self._driver._gpfs_execute = mock.Mock(return_value=True)
433 self._driver._extend_share(self.share, 10)
434 self._driver._gpfs_execute.assert_called_once_with(
435 self.GPFS_PATH + 'mmsetquota', self.fakedev + ':' +
436 self.share['name'], '--block', '0:10G')
437 self._driver._get_gpfs_device.assert_called_once_with()
439 def test__extend_share_exception(self):
440 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
441 self._driver._gpfs_execute = mock.Mock(
442 side_effect=exception.ProcessExecutionError
443 )
444 self.assertRaises(exception.GPFSException,
445 self._driver._extend_share, self.share, 10)
446 self._driver._gpfs_execute.assert_called_once_with(
447 self.GPFS_PATH + 'mmsetquota', self.fakedev + ':' +
448 self.share['name'], '--block', '0:10G')
449 self._driver._get_gpfs_device.assert_called_once_with()
451 def test_update_access_allow(self):
452 """Test allow_access functionality via update_access."""
453 self._driver._get_share_path = mock.Mock(
454 return_value=self.fakesharepath
455 )
456 self._helper_fake.allow_access = mock.Mock()
458 self._driver.update_access(self._context,
459 self.share,
460 ["ignored"],
461 [self.access],
462 [],
463 [],
464 share_server=None)
466 self._helper_fake.allow_access.assert_called_once_with(
467 self.fakesharepath, self.share, self.access)
468 self.assertFalse(self._helper_fake.resync_access.called)
469 self._driver._get_share_path.assert_called_once_with(self.share)
471 def test_update_access_deny(self):
472 """Test deny_access functionality via update_access."""
473 self._driver._get_share_path = mock.Mock(return_value=self.
474 fakesharepath)
475 self._helper_fake.deny_access = mock.Mock()
477 self._driver.update_access(self._context,
478 self.share,
479 ["ignored"],
480 [],
481 [self.access],
482 [],
483 share_server=None)
485 self._helper_fake.deny_access.assert_called_once_with(
486 self.fakesharepath, self.share, self.access)
487 self.assertFalse(self._helper_fake.resync_access.called)
488 self._driver._get_share_path.assert_called_once_with(self.share)
490 def test_update_access_both(self):
491 """Test update_access with allow and deny lists."""
492 self._driver._get_share_path = mock.Mock(return_value=self.
493 fakesharepath)
494 self._helper_fake.deny_access = mock.Mock()
495 self._helper_fake.allow_access = mock.Mock()
496 self._helper_fake.resync_access = mock.Mock()
498 access_1 = fake_share.fake_access(access_to="1.1.1.1")
499 access_2 = fake_share.fake_access(access_to="2.2.2.2")
500 self._driver.update_access(self._context,
501 self.share,
502 ["ignore"],
503 [access_1],
504 [access_2],
505 [],
506 share_server=None)
508 self.assertFalse(self._helper_fake.resync_access.called)
509 self._helper_fake.allow_access.assert_called_once_with(
510 self.fakesharepath, self.share, access_1)
511 self._helper_fake.deny_access.assert_called_once_with(
512 self.fakesharepath, self.share, access_2)
513 self._driver._get_share_path.assert_called_once_with(self.share)
515 def test_update_access_resync(self):
516 """Test recovery mode update_access."""
517 self._driver._get_share_path = mock.Mock(return_value=self.
518 fakesharepath)
519 self._helper_fake.deny_access = mock.Mock()
520 self._helper_fake.allow_access = mock.Mock()
521 self._helper_fake.resync_access = mock.Mock()
523 access_1 = fake_share.fake_access(access_to="1.1.1.1")
524 access_2 = fake_share.fake_access(access_to="2.2.2.2")
525 self._driver.update_access(self._context,
526 self.share,
527 [access_1, access_2],
528 [],
529 [],
530 [],
531 share_server=None)
533 self._helper_fake.resync_access.assert_called_once_with(
534 self.fakesharepath, self.share, [access_1, access_2])
535 self.assertFalse(self._helper_fake.allow_access.called)
536 self.assertFalse(self._helper_fake.allow_access.called)
537 self._driver._get_share_path.assert_called_once_with(self.share)
539 def test__check_gpfs_state_active(self):
540 fakeout = "mmgetstate::state:\nmmgetstate::active:"
541 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
542 result = self._driver._check_gpfs_state()
543 self._driver._gpfs_execute.assert_called_once_with(
544 self.GPFS_PATH + 'mmgetstate', '-Y')
545 self.assertEqual(result, True)
547 def test__check_gpfs_state_down(self):
548 fakeout = "mmgetstate::state:\nmmgetstate::down:"
549 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
550 result = self._driver._check_gpfs_state()
551 self._driver._gpfs_execute.assert_called_once_with(
552 self.GPFS_PATH + 'mmgetstate', '-Y')
553 self.assertEqual(result, False)
555 def test__check_gpfs_state_wrong_output_exception(self):
556 fakeout = "mmgetstate fake out"
557 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
558 self.assertRaises(exception.GPFSException,
559 self._driver._check_gpfs_state)
560 self._driver._gpfs_execute.assert_called_once_with(
561 self.GPFS_PATH + 'mmgetstate', '-Y')
563 def test__check_gpfs_state_exception(self):
564 self._driver._gpfs_execute = mock.Mock(
565 side_effect=exception.ProcessExecutionError
566 )
567 self.assertRaises(exception.GPFSException,
568 self._driver._check_gpfs_state)
569 self._driver._gpfs_execute.assert_called_once_with(
570 self.GPFS_PATH + 'mmgetstate', '-Y')
572 def test__is_dir_success(self):
573 fakeoutput = "directory"
574 self._driver._gpfs_execute = mock.Mock(return_value=(fakeoutput, ''))
575 result = self._driver._is_dir(self.fakefspath)
576 self._driver._gpfs_execute.assert_called_once_with(
577 'stat', '--format=%F', self.fakefspath, run_as_root=False
578 )
579 self.assertEqual(result, True)
581 def test__is_dir_failure(self):
582 fakeoutput = "regular file"
583 self._driver._gpfs_execute = mock.Mock(return_value=(fakeoutput, ''))
584 result = self._driver._is_dir(self.fakefspath)
585 self._driver._gpfs_execute.assert_called_once_with(
586 'stat', '--format=%F', self.fakefspath, run_as_root=False
587 )
588 self.assertEqual(result, False)
590 def test__is_dir_exception(self):
591 self._driver._gpfs_execute = mock.Mock(
592 side_effect=exception.ProcessExecutionError
593 )
594 self.assertRaises(exception.GPFSException,
595 self._driver._is_dir, self.fakefspath)
596 self._driver._gpfs_execute.assert_called_once_with(
597 'stat', '--format=%F', self.fakefspath, run_as_root=False
598 )
600 def test__is_gpfs_path_ok(self):
601 self._driver._gpfs_execute = mock.Mock(return_value=0)
602 result = self._driver._is_gpfs_path(self.fakefspath)
603 self._driver._gpfs_execute.assert_called_once_with(
604 self.GPFS_PATH + 'mmlsattr', self.fakefspath)
605 self.assertEqual(result, True)
607 def test__is_gpfs_path_exception(self):
608 self._driver._gpfs_execute = mock.Mock(
609 side_effect=exception.ProcessExecutionError
610 )
611 self.assertRaises(exception.GPFSException,
612 self._driver._is_gpfs_path,
613 self.fakefspath)
614 self._driver._gpfs_execute.assert_called_once_with(
615 self.GPFS_PATH + 'mmlsattr', self.fakefspath)
617 def test__get_gpfs_device(self):
618 fakeout = "Filesystem\n" + self.fakedev
619 orig_val = self._driver.configuration.gpfs_mount_point_base
620 self._driver.configuration.gpfs_mount_point_base = self.fakefspath
621 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
622 result = self._driver._get_gpfs_device()
623 self._driver._gpfs_execute.assert_called_once_with('df',
624 self.fakefspath)
625 self.assertEqual(result, self.fakedev)
626 self._driver.configuration.gpfs_mount_point_base = orig_val
628 def test__get_gpfs_device_exception(self):
629 self._driver._gpfs_execute = mock.Mock(
630 side_effect=exception.ProcessExecutionError)
631 self.assertRaises(exception.GPFSException,
632 self._driver._get_gpfs_device)
634 def test__create_share(self):
635 sizestr = '%sG' % self.share['size']
636 self._driver._gpfs_execute = mock.Mock(return_value=True)
637 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
638 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
639 self._driver._create_share(self.share)
640 self._driver._gpfs_execute.assert_any_call(
641 self.GPFS_PATH + 'mmcrfileset', self.fakedev, self.share['name'],
642 '--inode-space', 'new')
643 self._driver._gpfs_execute.assert_any_call(
644 self.GPFS_PATH + 'mmlinkfileset', self.fakedev, self.share['name'],
645 '-J', self.fakesharepath)
646 self._driver._gpfs_execute.assert_any_call(
647 self.GPFS_PATH + 'mmsetquota', self.fakedev + ':' +
648 self.share['name'], '--block', '0:' + sizestr)
649 self._driver._gpfs_execute.assert_any_call(
650 'chmod', '777', self.fakesharepath)
652 self._driver._local_path.assert_called_once_with(self.share['name'])
653 self._driver._get_gpfs_device.assert_called_once_with()
655 def test__create_share_exception(self):
656 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
657 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
658 self._driver._gpfs_execute = mock.Mock(
659 side_effect=exception.ProcessExecutionError
660 )
661 self.assertRaises(exception.GPFSException,
662 self._driver._create_share, self.share)
663 self._driver._get_gpfs_device.assert_called_once_with()
664 self._driver._local_path.assert_called_once_with(self.share['name'])
665 self._driver._gpfs_execute.assert_called_once_with(
666 self.GPFS_PATH + 'mmcrfileset', self.fakedev, self.share['name'],
667 '--inode-space', 'new')
669 def test__delete_share(self):
670 self._driver._gpfs_execute = mock.Mock(return_value=True)
671 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
672 self._driver._delete_share(self.share)
673 self._driver._gpfs_execute.assert_any_call(
674 self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
675 self.share['name'], '-f', ignore_exit_code=[2])
676 self._driver._gpfs_execute.assert_any_call(
677 self.GPFS_PATH + 'mmdelfileset', self.fakedev, self.share['name'],
678 '-f', ignore_exit_code=[2])
679 self._driver._get_gpfs_device.assert_called_once_with()
681 def test__delete_share_exception(self):
682 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
683 self._driver._gpfs_execute = mock.Mock(
684 side_effect=exception.ProcessExecutionError
685 )
686 self.assertRaises(exception.GPFSException,
687 self._driver._delete_share, self.share)
688 self._driver._get_gpfs_device.assert_called_once_with()
689 self._driver._gpfs_execute.assert_called_once_with(
690 self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
691 self.share['name'], '-f', ignore_exit_code=[2])
693 def test__create_share_snapshot(self):
694 self._driver._gpfs_execute = mock.Mock(return_value=True)
695 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
696 self._driver._create_share_snapshot(self.snapshot)
697 self._driver._gpfs_execute.assert_called_once_with(
698 self.GPFS_PATH + 'mmcrsnapshot', self.fakedev,
699 self.snapshot['name'], '-j', self.snapshot['share_name']
700 )
701 self._driver._get_gpfs_device.assert_called_once_with()
703 def test__create_share_snapshot_exception(self):
704 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
705 self._driver._gpfs_execute = mock.Mock(
706 side_effect=exception.ProcessExecutionError
707 )
708 self.assertRaises(exception.GPFSException,
709 self._driver._create_share_snapshot, self.snapshot)
710 self._driver._get_gpfs_device.assert_called_once_with()
711 self._driver._gpfs_execute.assert_called_once_with(
712 self.GPFS_PATH + 'mmcrsnapshot', self.fakedev,
713 self.snapshot['name'], '-j', self.snapshot['share_name']
714 )
716 def test__create_share_from_snapshot(self):
717 self._driver._gpfs_execute = mock.Mock(return_value=True)
718 self._driver._create_share = mock.Mock(return_value=True)
719 self._driver._get_snapshot_path = mock.Mock(return_value=self.
720 fakesnapshotpath)
721 self._driver._create_share_from_snapshot(self.share, self.snapshot,
722 self.fakesharepath)
723 self._driver._gpfs_execute.assert_called_once_with(
724 'rsync', '-rp', self.fakesnapshotpath + '/', self.fakesharepath
725 )
726 self._driver._create_share.assert_called_once_with(self.share)
727 self._driver._get_snapshot_path.assert_called_once_with(self.snapshot)
729 def test__create_share_from_snapshot_exception(self):
730 self._driver._create_share = mock.Mock(return_value=True)
731 self._driver._get_snapshot_path = mock.Mock(return_value=self.
732 fakesnapshotpath)
733 self._driver._gpfs_execute = mock.Mock(
734 side_effect=exception.ProcessExecutionError
735 )
736 self.assertRaises(exception.GPFSException,
737 self._driver._create_share_from_snapshot,
738 self.share, self.snapshot, self.fakesharepath)
739 self._driver._create_share.assert_called_once_with(self.share)
740 self._driver._get_snapshot_path.assert_called_once_with(self.snapshot)
741 self._driver._gpfs_execute.assert_called_once_with(
742 'rsync', '-rp', self.fakesnapshotpath + '/', self.fakesharepath
743 )
745 @ddt.data("mmlsfileset::allocInodes:\nmmlsfileset::100096:",
746 "mmlsfileset::allocInodes:\nmmlsfileset::0:")
747 def test__is_share_valid_with_quota(self, fakeout):
748 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
750 result = self._driver._is_share_valid(self.fakedev, self.fakesharepath)
752 self._driver._gpfs_execute.assert_called_once_with(
753 self.GPFS_PATH + 'mmlsfileset', self.fakedev, '-J',
754 self.fakesharepath, '-L', '-Y')
755 if fakeout == "mmlsfileset::allocInodes:\nmmlsfileset::100096:":
756 self.assertTrue(result)
757 else:
758 self.assertFalse(result)
760 def test__is_share_valid_exception(self):
761 self._driver._gpfs_execute = mock.Mock(
762 side_effect=exception.ProcessExecutionError)
764 self.assertRaises(exception.ManageInvalidShare,
765 self._driver._is_share_valid, self.fakedev,
766 self.fakesharepath)
768 self._driver._gpfs_execute.assert_called_once_with(
769 self.GPFS_PATH + 'mmlsfileset', self.fakedev, '-J',
770 self.fakesharepath, '-L', '-Y')
772 def test__is_share_valid_no_share_exist_exception(self):
773 fakeout = "mmlsfileset::allocInodes:"
774 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
776 self.assertRaises(exception.GPFSException,
777 self._driver._is_share_valid, self.fakedev,
778 self.fakesharepath)
780 self._driver._gpfs_execute.assert_called_once_with(
781 self.GPFS_PATH + 'mmlsfileset', self.fakedev, '-J',
782 self.fakesharepath, '-L', '-Y')
784 def test__get_share_name(self):
785 fakeout = "mmlsfileset::filesetName:\nmmlsfileset::existingshare:"
786 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
788 result = self._driver._get_share_name(self.fakedev, self.fakesharepath)
790 self.assertEqual('existingshare', result)
792 def test__get_share_name_exception(self):
793 self._driver._gpfs_execute = mock.Mock(
794 side_effect=exception.ProcessExecutionError)
796 self.assertRaises(exception.ManageInvalidShare,
797 self._driver._get_share_name, self.fakedev,
798 self.fakesharepath)
800 self._driver._gpfs_execute.assert_called_once_with(
801 self.GPFS_PATH + 'mmlsfileset', self.fakedev, '-J',
802 self.fakesharepath, '-L', '-Y')
804 def test__get_share_name_no_share_exist_exception(self):
805 fakeout = "mmlsfileset::filesetName:"
806 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
808 self.assertRaises(exception.GPFSException,
809 self._driver._get_share_name, self.fakedev,
810 self.fakesharepath)
812 self._driver._gpfs_execute.assert_called_once_with(
813 self.GPFS_PATH + 'mmlsfileset', self.fakedev, '-J',
814 self.fakesharepath, '-L', '-Y')
816 @ddt.data("mmlsquota::blockLimit:\nmmlsquota::1048577",
817 "mmlsquota::blockLimit:\nmmlsquota::1048576",
818 "mmlsquota::blockLimit:\nmmlsquota::0")
819 def test__manage_existing(self, fakeout):
820 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
821 self._helper_fake.create_export.return_value = 'fakelocation'
822 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
824 actual_size, actual_path = self._driver._manage_existing(
825 self.fakedev, self.share, self.fakeexistingshare)
827 self._driver._gpfs_execute.assert_any_call(
828 self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
829 self.fakeexistingshare, '-f')
830 self._driver._gpfs_execute.assert_any_call(
831 self.GPFS_PATH + 'mmchfileset', self.fakedev,
832 self.fakeexistingshare, '-j', self.share['name'])
833 self._driver._gpfs_execute.assert_any_call(
834 self.GPFS_PATH + 'mmlinkfileset', self.fakedev, self.share['name'],
835 '-J', self.fakesharepath)
836 self._driver._gpfs_execute.assert_any_call(
837 'chmod', '777', self.fakesharepath)
838 if fakeout == "mmlsquota::blockLimit:\nmmlsquota::1048577":
839 self._driver._gpfs_execute.assert_called_with(
840 self.GPFS_PATH + 'mmsetquota', self.fakedev + ':' +
841 self.share['name'], '--block', '0:2G')
842 self.assertEqual(2, actual_size)
843 self.assertEqual('fakelocation', actual_path)
844 elif fakeout == "mmlsquota::blockLimit:\nmmlsquota::0":
845 self._driver._gpfs_execute.assert_called_with(
846 self.GPFS_PATH + 'mmsetquota', self.fakedev + ':' +
847 self.share['name'], '--block', '0:1G')
848 self.assertEqual(1, actual_size)
849 self.assertEqual('fakelocation', actual_path)
850 else:
851 self.assertEqual(1, actual_size)
852 self.assertEqual('fakelocation', actual_path)
854 def test__manage_existing_fileset_unlink_exception(self):
855 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
856 self._driver._gpfs_execute = mock.Mock(
857 side_effect=exception.ProcessExecutionError)
859 self.assertRaises(exception.GPFSException,
860 self._driver._manage_existing, self.fakedev,
861 self.share, self.fakeexistingshare)
863 self._driver._local_path.assert_called_once_with(self.share['name'])
864 self._driver._gpfs_execute.assert_called_once_with(
865 self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
866 self.fakeexistingshare, '-f')
868 def test__manage_existing_fileset_creation_exception(self):
869 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
870 self.mock_object(self._driver, '_gpfs_execute', mock.Mock(
871 side_effect=['', exception.ProcessExecutionError]))
873 self.assertRaises(exception.GPFSException,
874 self._driver._manage_existing, self.fakedev,
875 self.share, self.fakeexistingshare)
877 self._driver._local_path.assert_any_call(self.share['name'])
878 self._driver._gpfs_execute.assert_has_calls([
879 mock.call(self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
880 self.fakeexistingshare, '-f'),
881 mock.call(self.GPFS_PATH + 'mmchfileset', self.fakedev,
882 self.fakeexistingshare, '-j', self.share['name'])])
884 def test__manage_existing_fileset_relink_exception(self):
885 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
886 self.mock_object(self._driver, '_gpfs_execute', mock.Mock(
887 side_effect=['', '', exception.ProcessExecutionError]))
889 self.assertRaises(exception.GPFSException,
890 self._driver._manage_existing, self.fakedev,
891 self.share, self.fakeexistingshare)
893 self._driver._local_path.assert_any_call(self.share['name'])
894 self._driver._gpfs_execute.assert_has_calls([
895 mock.call(self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
896 self.fakeexistingshare, '-f'),
897 mock.call(self.GPFS_PATH + 'mmchfileset', self.fakedev,
898 self.fakeexistingshare, '-j', self.share['name']),
899 mock.call(self.GPFS_PATH + 'mmlinkfileset', self.fakedev,
900 self.share['name'], '-J', self.fakesharepath)])
902 def test__manage_existing_permission_change_exception(self):
903 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
904 self.mock_object(self._driver, '_gpfs_execute', mock.Mock(
905 side_effect=['', '', '', exception.ProcessExecutionError]))
907 self.assertRaises(exception.GPFSException,
908 self._driver._manage_existing, self.fakedev,
909 self.share, self.fakeexistingshare)
911 self._driver._local_path.assert_any_call(self.share['name'])
912 self._driver._gpfs_execute.assert_has_calls([
913 mock.call(self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
914 self.fakeexistingshare, '-f'),
915 mock.call(self.GPFS_PATH + 'mmchfileset', self.fakedev,
916 self.fakeexistingshare, '-j', self.share['name']),
917 mock.call(self.GPFS_PATH + 'mmlinkfileset', self.fakedev,
918 self.share['name'], '-J', self.fakesharepath),
919 mock.call('chmod', '777', self.fakesharepath)])
921 def test__manage_existing_checking_quota_of_fileset_exception(self):
922 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
923 self.mock_object(self._driver, '_gpfs_execute', mock.Mock(
924 side_effect=['', '', '', '', exception.ProcessExecutionError]))
926 self.assertRaises(exception.GPFSException,
927 self._driver._manage_existing, self.fakedev,
928 self.share, self.fakeexistingshare)
930 self._driver._local_path.assert_any_call(self.share['name'])
931 self._driver._gpfs_execute.assert_has_calls([
932 mock.call(self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
933 self.fakeexistingshare, '-f'),
934 mock.call(self.GPFS_PATH + 'mmchfileset', self.fakedev,
935 self.fakeexistingshare, '-j', self.share['name']),
936 mock.call(self.GPFS_PATH + 'mmlinkfileset', self.fakedev,
937 self.share['name'], '-J', self.fakesharepath),
938 mock.call('chmod', '777', self.fakesharepath),
939 mock.call(self.GPFS_PATH + 'mmlsquota', '-j', self.share['name'],
940 '-Y', self.fakedev)])
942 def test__manage_existing_unable_to_get_quota_of_fileset_exception(self):
943 fakeout = "mmlsquota::blockLimit:"
944 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
945 self._driver._gpfs_execute = mock.Mock(return_value=(fakeout, ''))
947 self.assertRaises(exception.GPFSException,
948 self._driver._manage_existing, self.fakedev,
949 self.share, self.fakeexistingshare)
951 self._driver._local_path.assert_any_call(self.share['name'])
952 self._driver._gpfs_execute.assert_any_call(
953 self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
954 self.fakeexistingshare, '-f')
955 self._driver._gpfs_execute.assert_any_call(
956 self.GPFS_PATH + 'mmchfileset', self.fakedev,
957 self.fakeexistingshare, '-j', self.share['name'])
958 self._driver._gpfs_execute.assert_any_call(
959 self.GPFS_PATH + 'mmlinkfileset', self.fakedev,
960 self.share['name'], '-J', self.fakesharepath)
961 self._driver._gpfs_execute.assert_any_call(
962 'chmod', '777', self.fakesharepath)
963 self._driver._gpfs_execute.assert_called_with(
964 self.GPFS_PATH + 'mmlsquota', '-j', self.share['name'],
965 '-Y', self.fakedev)
967 def test__manage_existing_set_quota_of_fileset_less_than_1G_exception(
968 self):
969 sizestr = '1G'
970 mock_out = "mmlsquota::blockLimit:\nmmlsquota::0:", None
971 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
972 self.mock_object(self._driver, '_gpfs_execute', mock.Mock(
973 side_effect=['', '', '', '', mock_out,
974 exception.ProcessExecutionError]))
976 self.assertRaises(exception.GPFSException,
977 self._driver._manage_existing, self.fakedev,
978 self.share, self.fakeexistingshare)
980 self._driver._local_path.assert_any_call(self.share['name'])
981 self._driver._gpfs_execute.assert_has_calls([
982 mock.call(self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
983 self.fakeexistingshare, '-f'),
984 mock.call(self.GPFS_PATH + 'mmchfileset', self.fakedev,
985 self.fakeexistingshare, '-j', self.share['name']),
986 mock.call(self.GPFS_PATH + 'mmlinkfileset', self.fakedev,
987 self.share['name'], '-J', self.fakesharepath),
988 mock.call('chmod', '777', self.fakesharepath),
989 mock.call(self.GPFS_PATH + 'mmlsquota', '-j', self.share['name'],
990 '-Y', self.fakedev),
991 mock.call(self.GPFS_PATH + 'mmsetquota', self.fakedev + ':' +
992 self.share['name'], '--block', '0:' + sizestr)])
994 def test__manage_existing_set_quota_of_fileset_grater_than_1G_exception(
995 self):
996 sizestr = '2G'
997 mock_out = "mmlsquota::blockLimit:\nmmlsquota::1048577:", None
998 self._driver._local_path = mock.Mock(return_value=self.fakesharepath)
999 self.mock_object(self._driver, '_gpfs_execute', mock.Mock(
1000 side_effect=['', '', '', '', mock_out,
1001 exception.ProcessExecutionError]))
1003 self.assertRaises(exception.GPFSException,
1004 self._driver._manage_existing, self.fakedev,
1005 self.share, self.fakeexistingshare)
1007 self._driver._local_path.assert_any_call(self.share['name'])
1008 self._driver._gpfs_execute.assert_has_calls([
1009 mock.call(self.GPFS_PATH + 'mmunlinkfileset', self.fakedev,
1010 self.fakeexistingshare, '-f'),
1011 mock.call(self.GPFS_PATH + 'mmchfileset', self.fakedev,
1012 self.fakeexistingshare, '-j', self.share['name']),
1013 mock.call(self.GPFS_PATH + 'mmlinkfileset', self.fakedev,
1014 self.share['name'], '-J', self.fakesharepath),
1015 mock.call('chmod', '777', self.fakesharepath),
1016 mock.call(self.GPFS_PATH + 'mmlsquota', '-j', self.share['name'],
1017 '-Y', self.fakedev),
1018 mock.call(self.GPFS_PATH + 'mmsetquota', self.fakedev + ':' +
1019 self.share['name'], '--block', '0:' + sizestr)])
1021 def test_manage_existing(self):
1022 self._driver._manage_existing = mock.Mock(return_value=('1',
1023 'fakelocation'))
1024 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
1025 self._driver._is_share_valid = mock.Mock(return_value=True)
1026 self._driver._get_share_name = mock.Mock(return_value=self.
1027 fakeexistingshare)
1028 self._helper_fake._has_client_access = mock.Mock(return_value=[])
1030 result = self._driver.manage_existing(self.share, {})
1032 self.assertEqual('1', result['size'])
1033 self.assertEqual('fakelocation', result['export_locations'])
1035 def test_manage_existing_incorrect_path_exception(self):
1036 share = fake_share.fake_share(export_location="wrong_ip::wrong_path")
1038 self.assertRaises(exception.ShareBackendException,
1039 self._driver.manage_existing, share, {})
1041 def test_manage_existing_incorrect_ip_exception(self):
1042 share = fake_share.fake_share(export_location="wrong_ip:wrong_path")
1044 self.assertRaises(exception.ShareBackendException,
1045 self._driver.manage_existing, share, {})
1047 def test__manage_existing_invalid_export_exception(self):
1048 share = fake_share.fake_share(export_location="wrong_ip/wrong_path")
1050 self.assertRaises(exception.ShareBackendException,
1051 self._driver.manage_existing, share, {})
1053 @ddt.data(True, False)
1054 def test_manage_existing_invalid_share_exception(self, valid_share):
1055 self._driver._get_gpfs_device = mock.Mock(return_value=self.fakedev)
1056 self._driver._is_share_valid = mock.Mock(return_value=valid_share)
1057 if valid_share:
1058 self._driver._get_share_name = mock.Mock(return_value=self.
1059 fakeexistingshare)
1060 self._helper_fake._has_client_access = mock.Mock()
1061 else:
1062 self.assertFalse(self._helper_fake._has_client_access.called)
1064 self.assertRaises(exception.ManageInvalidShare,
1065 self._driver.manage_existing, self.share, {})
1067 def test__gpfs_local_execute(self):
1068 self.mock_object(utils, 'execute', mock.Mock(return_value=True))
1069 cmd = "testcmd"
1070 self._driver._gpfs_local_execute(cmd, ignore_exit_code=[2])
1071 utils.execute.assert_called_once_with(cmd, run_as_root=True,
1072 check_exit_code=[2, 0])
1074 def test__gpfs_remote_execute(self):
1075 self._driver._run_ssh = mock.Mock(return_value=True)
1076 cmd = "testcmd"
1077 orig_value = self._driver.configuration.gpfs_share_export_ip
1078 self._driver.configuration.gpfs_share_export_ip = self.local_ip
1079 self._driver._gpfs_remote_execute(cmd, check_exit_code=True)
1080 self._driver._run_ssh.assert_called_once_with(
1081 self.local_ip, tuple([cmd]), None, True
1082 )
1083 self._driver.configuration.gpfs_share_export_ip = orig_value
1085 def test_knfs_resync_access(self):
1086 self._knfs_helper.allow_access = mock.Mock()
1087 path = self.fakesharepath
1088 to_remove = '3.3.3.3'
1089 fake_exportfs_before = ('%(path)s\n\t\t%(ip)s\n'
1090 '/other/path\n\t\t4.4.4.4\n' %
1091 {'path': path, 'ip': to_remove})
1092 fake_exportfs_after = '/other/path\n\t\t4.4.4.4\n'
1093 self._knfs_helper._execute = mock.Mock(
1094 return_value=(fake_exportfs_before, ''))
1095 self._knfs_helper._publish_access = mock.Mock(
1096 side_effect=[[(fake_exportfs_before, '')],
1097 [(fake_exportfs_after, '')]])
1099 access_1 = fake_share.fake_access(access_to="1.1.1.1")
1100 access_2 = fake_share.fake_access(access_to="2.2.2.2")
1101 self._knfs_helper.resync_access(path, self.share, [access_1, access_2])
1103 self._knfs_helper.allow_access.assert_has_calls([
1104 mock.call(path, self.share, access_1, error_on_exists=False),
1105 mock.call(path, self.share, access_2, error_on_exists=False)])
1106 self._knfs_helper._execute.assert_called_once_with(
1107 'exportfs', run_as_root=True)
1108 self._knfs_helper._publish_access.assert_has_calls([
1109 mock.call('exportfs', '-u',
1110 '%(ip)s:%(path)s' % {'ip': to_remove, 'path': path},
1111 check_exit_code=[0, 1]),
1112 mock.call('exportfs')])
1114 @ddt.data('rw', 'ro')
1115 def test_knfs_get_export_options(self, access_level):
1116 mock_out = {"knfs:export_options": "no_root_squash"}
1117 self.mock_object(share_types, 'get_extra_specs_from_share',
1118 mock.Mock(return_value=mock_out))
1119 access = fake_share.fake_access(access_level=access_level)
1120 out = self._knfs_helper.get_export_options(self.share, access, 'KNFS')
1121 self.assertEqual("no_root_squash,%s" % access_level, out)
1123 def test_knfs_get_export_options_default(self):
1124 self.mock_object(share_types, 'get_extra_specs_from_share',
1125 mock.Mock(return_value={}))
1126 access = self.access
1127 out = self._knfs_helper.get_export_options(self.share, access, 'KNFS')
1128 self.assertEqual("rw", out)
1130 def test_knfs_get_export_options_invalid_option_ro(self):
1131 mock_out = {"knfs:export_options": "ro"}
1132 self.mock_object(share_types, 'get_extra_specs_from_share',
1133 mock.Mock(return_value=mock_out))
1134 access = self.access
1135 share = fake_share.fake_share(share_type="fake_share_type")
1136 self.assertRaises(exception.InvalidInput,
1137 self._knfs_helper.get_export_options,
1138 share, access, 'KNFS')
1140 def test_knfs_get_export_options_invalid_option_rw(self):
1141 mock_out = {"knfs:export_options": "rw"}
1142 self.mock_object(share_types, 'get_extra_specs_from_share',
1143 mock.Mock(return_value=mock_out))
1144 access = self.access
1145 share = fake_share.fake_share(share_type="fake_share_type")
1146 self.assertRaises(exception.InvalidInput,
1147 self._knfs_helper.get_export_options,
1148 share, access, 'KNFS')
1150 @ddt.data(("/gpfs0/share-fakeid\t10.0.0.1", None),
1151 ("", None),
1152 ("/gpfs0/share-fakeid\t10.0.0.1", "10.0.0.1"),
1153 ("/gpfs0/share-fakeid\t10.0.0.1", "10.0.0.2"))
1154 @ddt.unpack
1155 def test_knfs__has_client_access(self, mock_out, access_to):
1156 self._knfs_helper._execute = mock.Mock(return_value=[mock_out, 0])
1158 result = self._knfs_helper._has_client_access(self.fakesharepath,
1159 access_to)
1161 self._ces_helper._execute.assert_called_once_with('exportfs',
1162 check_exit_code=True,
1163 run_as_root=True)
1164 if mock_out == "/gpfs0/share-fakeid\t10.0.0.1":
1165 if access_to in (None, "10.0.0.1"):
1166 self.assertTrue(result)
1167 else:
1168 self.assertFalse(result)
1169 else:
1170 self.assertFalse(result)
1172 def test_knfs_allow_access(self):
1173 self._knfs_helper._execute = mock.Mock(
1174 return_value=['/fs0 <world>', 0]
1175 )
1176 self.mock_object(re, 'search', mock.Mock(return_value=None))
1177 export_opts = None
1178 self._knfs_helper.get_export_options = mock.Mock(
1179 return_value=export_opts
1180 )
1181 self._knfs_helper._publish_access = mock.Mock()
1182 access = self.access
1183 local_path = self.fakesharepath
1184 self._knfs_helper.allow_access(local_path, self.share, access)
1185 self._knfs_helper._execute.assert_called_once_with('exportfs',
1186 run_as_root=True)
1187 self.assertTrue(re.search.called)
1188 self._knfs_helper.get_export_options.assert_any_call(
1189 self.share, access, 'KNFS')
1190 cmd = ['exportfs', '-o', export_opts, ':'.join([access['access_to'],
1191 local_path])]
1192 self._knfs_helper._publish_access.assert_called_once_with(*cmd)
1194 def test_knfs_allow_access_access_exists(self):
1195 out = ['/fs0 <world>', 0]
1196 self._knfs_helper._execute = mock.Mock(return_value=out)
1197 self.mock_object(re, 'search', mock.Mock(return_value="fake"))
1198 self._knfs_helper.get_export_options = mock.Mock()
1199 access = self.access
1200 local_path = self.fakesharepath
1201 self.assertRaises(exception.ShareAccessExists,
1202 self._knfs_helper.allow_access,
1203 local_path, self.share, access)
1204 self._knfs_helper._execute.assert_any_call('exportfs',
1205 run_as_root=True)
1206 self.assertTrue(re.search.called)
1207 self.assertFalse(self._knfs_helper.get_export_options.called)
1209 def test_knfs_allow_access_publish_exception(self):
1210 self._knfs_helper.get_export_options = mock.Mock()
1211 self._knfs_helper._publish_access = mock.Mock(
1212 side_effect=exception.ProcessExecutionError('boom'))
1214 self.assertRaises(exception.GPFSException,
1215 self._knfs_helper.allow_access,
1216 self.fakesharepath,
1217 self.share,
1218 self.access,
1219 error_on_exists=False)
1221 self.assertTrue(self._knfs_helper.get_export_options.called)
1222 self.assertTrue(self._knfs_helper._publish_access.called)
1224 def test_knfs_allow_access_invalid_access(self):
1225 access = fake_share.fake_access(access_type='test')
1226 self.assertRaises(exception.InvalidShareAccess,
1227 self._knfs_helper.allow_access,
1228 self.fakesharepath, self.share,
1229 access)
1231 def test_knfs_allow_access_exception(self):
1232 self._knfs_helper._execute = mock.Mock(
1233 side_effect=exception.ProcessExecutionError
1234 )
1235 access = self.access
1236 local_path = self.fakesharepath
1237 self.assertRaises(exception.GPFSException,
1238 self._knfs_helper.allow_access,
1239 local_path, self.share,
1240 access)
1241 self._knfs_helper._execute.assert_called_once_with('exportfs',
1242 run_as_root=True)
1244 def test_knfs__verify_denied_access_pass(self):
1245 local_path = self.fakesharepath
1246 ip = self.access['access_to']
1247 fake_exportfs = ('/shares/share-1\n\t\t1.1.1.1\n'
1248 '/shares/share-2\n\t\t2.2.2.2\n')
1249 self._knfs_helper._publish_access = mock.Mock(
1250 return_value=[(fake_exportfs, '')])
1252 self._knfs_helper._verify_denied_access(local_path, self.share, ip)
1254 self._knfs_helper._publish_access.assert_called_once_with('exportfs')
1256 def test_knfs__verify_denied_access_fail(self):
1257 local_path = self.fakesharepath
1258 ip = self.access['access_to']
1259 data = {'path': local_path, 'ip': ip}
1260 fake_exportfs = ('/shares/share-1\n\t\t1.1.1.1\n'
1261 '%(path)s\n\t\t%(ip)s\n'
1262 '/shares/share-2\n\t\t2.2.2.2\n') % data
1263 self._knfs_helper._publish_access = mock.Mock(
1264 return_value=[(fake_exportfs, '')])
1266 self.assertRaises(exception.GPFSException,
1267 self._knfs_helper._verify_denied_access,
1268 local_path,
1269 self.share,
1270 ip)
1272 self._knfs_helper._publish_access.assert_called_once_with('exportfs')
1274 def test_knfs__verify_denied_access_exception(self):
1275 self._knfs_helper._publish_access = mock.Mock(
1276 side_effect=exception.ProcessExecutionError
1277 )
1279 ip = self.access['access_to']
1280 local_path = self.fakesharepath
1282 self.assertRaises(exception.GPFSException,
1283 self._knfs_helper._verify_denied_access,
1284 local_path,
1285 self.share,
1286 ip)
1288 self._knfs_helper._publish_access.assert_called_once_with('exportfs')
1290 @ddt.data((None, False),
1291 ('', False),
1292 (' ', False),
1293 ('Some error to log', True))
1294 @ddt.unpack
1295 def test_knfs__verify_denied_access_stderr(self, stderr, is_logged):
1296 """Stderr debug logging should only happen when not empty."""
1297 outputs = [('', stderr)]
1298 self._knfs_helper._publish_access = mock.Mock(return_value=outputs)
1299 gpfs.LOG.debug = mock.Mock()
1301 self._knfs_helper._verify_denied_access(
1302 self.fakesharepath, self.share, self.remote_ip)
1304 self._knfs_helper._publish_access.assert_called_once_with('exportfs')
1305 self.assertEqual(is_logged, gpfs.LOG.debug.called)
1307 def test_knfs_deny_access(self):
1308 self._knfs_helper._publish_access = mock.Mock(return_value=[('', '')])
1310 access = self.access
1311 local_path = self.fakesharepath
1312 self._knfs_helper.deny_access(local_path, self.share, access)
1314 deny = ['exportfs', '-u', ':'.join([access['access_to'], local_path])]
1315 self._knfs_helper._publish_access.assert_has_calls([
1316 mock.call(*deny, check_exit_code=[0, 1]),
1317 mock.call('exportfs')])
1319 def test_knfs_deny_access_exception(self):
1320 self._knfs_helper._publish_access = mock.Mock(
1321 side_effect=exception.ProcessExecutionError
1322 )
1324 access = self.access
1325 local_path = self.fakesharepath
1326 cmd = ['exportfs', '-u', ':'.join([access['access_to'], local_path])]
1327 self.assertRaises(exception.GPFSException,
1328 self._knfs_helper.deny_access, local_path,
1329 self.share, access)
1331 self._knfs_helper._publish_access.assert_called_once_with(
1332 *cmd, check_exit_code=[0, 1])
1334 def test_knfs__publish_access(self):
1335 self.mock_object(utils, 'execute')
1337 fake_command = 'fakecmd'
1338 cmd = [fake_command]
1339 self._knfs_helper._publish_access(*cmd)
1341 utils.execute.assert_any_call(*cmd, run_as_root=True,
1342 check_exit_code=True)
1343 remote_login = self.sshlogin + '@' + self.remote_ip
1344 remote_login2 = self.sshlogin + '@' + self.remote_ip2
1345 utils.execute.assert_has_calls([
1346 mock.call('ssh', remote_login, fake_command,
1347 check_exit_code=True, run_as_root=False),
1348 mock.call(fake_command, check_exit_code=True, run_as_root=True),
1349 mock.call('ssh', remote_login2, fake_command,
1350 check_exit_code=True, run_as_root=False)])
1351 self.assertTrue(socket.gethostbyname_ex.called)
1352 self.assertTrue(socket.gethostname.called)
1354 def test_knfs__publish_access_exception(self):
1355 self.mock_object(
1356 utils, 'execute',
1357 mock.Mock(side_effect=(0, exception.ProcessExecutionError)))
1359 fake_command = 'fakecmd'
1360 cmd = [fake_command]
1361 self.assertRaises(exception.ProcessExecutionError,
1362 self._knfs_helper._publish_access, *cmd)
1364 self.assertTrue(socket.gethostbyname_ex.called)
1365 self.assertTrue(socket.gethostname.called)
1366 remote_login = self.sshlogin + '@' + self.remote_ip
1367 utils.execute.assert_has_calls([
1368 mock.call('ssh', remote_login, fake_command,
1369 check_exit_code=True, run_as_root=False),
1370 mock.call(fake_command, check_exit_code=True, run_as_root=True)])
1372 @ddt.data('rw', 'ro')
1373 def test_ces_get_export_options(self, access_level):
1374 mock_out = {"ces:export_options": "squash=no_root_squash"}
1375 self.mock_object(share_types, 'get_extra_specs_from_share',
1376 mock.Mock(return_value=mock_out))
1377 access = fake_share.fake_access(access_level=access_level)
1378 out = self._ces_helper.get_export_options(self.share, access, 'CES')
1379 self.assertEqual("squash=no_root_squash,access_type=%s" % access_level,
1380 out)
1382 def test_ces_get_export_options_default(self):
1383 self.mock_object(share_types, 'get_extra_specs_from_share',
1384 mock.Mock(return_value={}))
1385 access = self.access
1386 out = self._ces_helper.get_export_options(self.share, access,
1387 'CES')
1388 self.assertEqual("access_type=rw", out)
1390 def test_ces_get_export_options_invalid_option_ro(self):
1391 mock_out = {"ces:export_options": "access_type=ro"}
1392 self.mock_object(share_types, 'get_extra_specs_from_share',
1393 mock.Mock(return_value=mock_out))
1394 access = self.access
1395 share = fake_share.fake_share(share_type="fake_share_type")
1396 self.assertRaises(exception.InvalidInput,
1397 self._ces_helper.get_export_options,
1398 share, access, 'CES')
1400 def test_ces_get_export_options_invalid_option_rw(self):
1401 mock_out = {"ces:export_options": "access_type=rw"}
1402 self.mock_object(share_types, 'get_extra_specs_from_share',
1403 mock.Mock(return_value=mock_out))
1404 access = self.access
1405 share = fake_share.fake_share(share_type="fake_share_type")
1406 self.assertRaises(exception.InvalidInput,
1407 self._ces_helper.get_export_options,
1408 share, access, 'CES')
1410 def test__get_nfs_client_exports_exception(self):
1411 self._ces_helper._execute = mock.Mock(return_value=('junk', ''))
1413 local_path = self.fakesharepath
1414 self.assertRaises(exception.GPFSException,
1415 self._ces_helper._get_nfs_client_exports,
1416 local_path)
1418 self._ces_helper._execute.assert_called_once_with(
1419 self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n', local_path, '-Y')
1421 @ddt.data('44.3.2.11', '1:2:3:4:5:6:7:8')
1422 def test__fix_export_data(self, ip):
1423 data = None
1424 for line in self.fake_ces_exports.splitlines(): 1424 ↛ 1430line 1424 didn't jump to line 1430 because the loop on line 1424 didn't complete
1425 if "HEADER" in line:
1426 headers = line.split(':')
1427 if ip in line:
1428 data = line.split(':')
1429 break
1430 self.assertIsNotNone(
1431 data, "Test data did not contain a line with the test IP.")
1433 result_data = self._ces_helper._fix_export_data(data, headers)
1435 self.assertEqual(ip, result_data[headers.index('Clients')])
1437 @ddt.data((None, True),
1438 ('44.3.2.11', True),
1439 ('44.3.2.1', False),
1440 ('4.3.2.1', False),
1441 ('4.3.2.11', False),
1442 ('1.2.3.4', False),
1443 ('', False),
1444 ('*', False),
1445 ('.', False),
1446 ('1:2:3:4:5:6:7:8', True))
1447 @ddt.unpack
1448 def test_ces__has_client_access(self, ip, has_access):
1449 mock_out = self.fake_ces_exports
1450 self._ces_helper._execute = mock.Mock(
1451 return_value=(mock_out, ''))
1453 local_path = self.fakesharepath
1454 self.assertEqual(has_access,
1455 self._ces_helper._has_client_access(local_path, ip))
1457 self._ces_helper._execute.assert_called_once_with(
1458 self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n', local_path, '-Y')
1460 def test_ces_remove_export_no_exports(self):
1461 mock_out = self.fake_ces_exports_not_found
1462 self._ces_helper._execute = mock.Mock(
1463 return_value=(mock_out, ''))
1465 local_path = self.fakesharepath
1466 self._ces_helper.remove_export(local_path, self.share)
1468 self._ces_helper._execute.assert_called_once_with(
1469 self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n', local_path, '-Y')
1471 def test_ces_remove_export_existing_exports(self):
1472 mock_out = self.fake_ces_exports
1473 self._ces_helper._execute = mock.Mock(
1474 return_value=(mock_out, ''))
1476 local_path = self.fakesharepath
1477 self._ces_helper.remove_export(local_path, self.share)
1479 self._ces_helper._execute.assert_has_calls([
1480 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n',
1481 local_path, '-Y'),
1482 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'remove',
1483 local_path),
1484 ])
1486 def test_ces_remove_export_exception(self):
1487 local_path = self.fakesharepath
1488 self._ces_helper._execute = mock.Mock(
1489 side_effect=exception.ProcessExecutionError)
1490 self.assertRaises(exception.GPFSException,
1491 self._ces_helper.remove_export,
1492 local_path, self.share)
1494 def test_ces_allow_access(self):
1495 mock_out = self.fake_ces_exports_not_found
1496 self._ces_helper._execute = mock.Mock(
1497 return_value=(mock_out, ''))
1499 export_opts = "access_type=rw"
1500 self._ces_helper.get_export_options = mock.Mock(
1501 return_value=export_opts)
1503 access = self.access
1504 local_path = self.fakesharepath
1506 self._ces_helper.allow_access(local_path, self.share, access)
1508 self._ces_helper._execute.assert_has_calls([
1509 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n',
1510 local_path, '-Y'),
1511 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'add', local_path,
1512 '-c', access['access_to'] + '(' + export_opts + ')')])
1514 def test_ces_allow_access_existing_exports(self):
1515 mock_out = self.fake_ces_exports
1516 self._ces_helper._execute = mock.Mock(
1517 return_value=(mock_out, ''))
1519 export_opts = "access_type=rw"
1520 self._ces_helper.get_export_options = mock.Mock(
1521 return_value=export_opts)
1523 access = self.access
1524 local_path = self.fakesharepath
1526 self._ces_helper.allow_access(self.fakesharepath, self.share,
1527 self.access)
1529 self._ces_helper._execute.assert_has_calls([
1530 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n',
1531 local_path, '-Y'),
1532 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'change', local_path,
1533 '--nfsadd', access['access_to'] + '(' +
1534 export_opts + ')')])
1536 def test_ces_allow_access_invalid_access_type(self):
1537 access = fake_share.fake_access(access_type='test')
1538 self.assertRaises(exception.InvalidShareAccess,
1539 self._ces_helper.allow_access,
1540 self.fakesharepath, self.share,
1541 access)
1543 def test_ces_allow_access_exception(self):
1544 access = self.access
1545 local_path = self.fakesharepath
1546 self._ces_helper._execute = mock.Mock(
1547 side_effect=exception.ProcessExecutionError)
1548 self.assertRaises(exception.GPFSException,
1549 self._ces_helper.allow_access, local_path,
1550 self.share, access)
1552 def test_ces_deny_access(self):
1553 mock_out = self.fake_ces_exports
1554 self._ces_helper._execute = mock.Mock(
1555 return_value=(mock_out, ''))
1557 access = self.access
1558 local_path = self.fakesharepath
1560 self._ces_helper.deny_access(local_path, self.share, access)
1562 self._ces_helper._execute.assert_has_calls([
1563 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n',
1564 local_path, '-Y'),
1565 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'change', local_path,
1566 '--nfsremove', access['access_to'])])
1568 def test_ces_deny_access_exception(self):
1569 access = self.access
1570 local_path = self.fakesharepath
1571 self._ces_helper._execute = mock.Mock(
1572 side_effect=exception.ProcessExecutionError)
1573 self.assertRaises(exception.GPFSException,
1574 self._ces_helper.deny_access, local_path,
1575 self.share, access)
1577 def test_ces_resync_access_add(self):
1578 mock_out = self.fake_ces_exports_not_found
1579 self._ces_helper._execute = mock.Mock(return_value=(mock_out, ''))
1580 self.mock_object(share_types, 'get_extra_specs_from_share',
1581 mock.Mock(return_value={}))
1583 access_rules = [self.access]
1584 local_path = self.fakesharepath
1585 self._ces_helper.resync_access(local_path, self.share, access_rules)
1587 self._ces_helper._execute.assert_has_calls([
1588 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n',
1589 local_path, '-Y'),
1590 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'add', local_path,
1591 '-c', self.access['access_to'] + '(' + "access_type=rw" +
1592 ')')
1593 ])
1594 share_types.get_extra_specs_from_share.assert_called_once_with(
1595 self.share)
1597 def test_ces_resync_access_change(self):
1599 class SortedMatch(object):
1600 def __init__(self, f, expected):
1601 self.assertEqual = f
1602 self.expected = expected
1604 def __eq__(self, actual):
1605 expected_list = self.expected.split(',')
1606 actual_list = actual.split(',')
1607 self.assertEqual(sorted(expected_list), sorted(actual_list))
1608 return True
1610 mock_out = self.fake_ces_exports
1611 self._ces_helper._execute = mock.Mock(
1612 return_value=(mock_out, ''))
1613 self.mock_object(share_types, 'get_extra_specs_from_share',
1614 mock.Mock(return_value={}))
1616 access_rules = [fake_share.fake_access(access_to='1.1.1.1'),
1617 fake_share.fake_access(
1618 access_to='10.0.0.1', access_level='ro')]
1619 local_path = self.fakesharepath
1620 self._ces_helper.resync_access(local_path, self.share, access_rules)
1622 share_types.get_extra_specs_from_share.assert_called_once_with(
1623 self.share)
1624 to_remove = '1:2:3:4:5:6:7:8,44.3.2.11'
1625 to_add = access_rules[0]['access_to'] + '(' + "access_type=rw" + ')'
1626 to_change = access_rules[1]['access_to'] + '(' + "access_type=ro" + ')'
1627 self._ces_helper._execute.assert_has_calls([
1628 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n',
1629 local_path, '-Y'),
1630 mock.call(self.GPFS_PATH + 'mmnfs', 'export', 'change', local_path,
1631 '--nfsremove', SortedMatch(self.assertEqual, to_remove),
1632 '--nfsadd', to_add,
1633 '--nfschange', to_change)
1634 ])
1636 def test_ces_resync_nothing(self):
1637 """Test that hits the add-no-rules case."""
1638 mock_out = self.fake_ces_exports_not_found
1639 self._ces_helper._execute = mock.Mock(return_value=(mock_out, ''))
1641 local_path = self.fakesharepath
1642 self._ces_helper.resync_access(local_path, None, [])
1644 self._ces_helper._execute.assert_called_once_with(
1645 self.GPFS_PATH + 'mmnfs', 'export', 'list', '-n', local_path, '-Y')