Coverage for manila/tests/share/drivers/maprfs/test_maprfs.py: 99%
457 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) 2016, MapR Technologies
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 MapRFS native protocol driver module."""
17from unittest import mock
19from oslo_concurrency import processutils
20from oslo_config import cfg
22from manila import context
23from manila import exception
24import manila.share.configuration as config
25from manila.share.drivers.maprfs import driver_util as mapru
26import manila.share.drivers.maprfs.maprfs_native as maprfs
27from manila import ssh_utils
28from manila import test
29from manila.tests import fake_share
30from manila import utils
32CONF = cfg.CONF
35class MapRFSNativeShareDriverTestCase(test.TestCase):
36 """Tests MapRFSNativeShareDriver."""
38 def setUp(self):
39 super(MapRFSNativeShareDriverTestCase, self).setUp()
40 self._context = context.get_admin_context()
41 self._hdfs_execute = mock.Mock(return_value=('', ''))
42 self.local_ip = '192.168.1.1'
43 CONF.set_default('driver_handles_share_servers', False)
44 CONF.set_default('maprfs_clinode_ip', [self.local_ip])
45 CONF.set_default('maprfs_ssh_name', 'fake_sshname')
46 CONF.set_default('maprfs_ssh_pw', 'fake_sshpw')
47 CONF.set_default('maprfs_ssh_private_key', 'fake_sshkey')
48 CONF.set_default('maprfs_rename_managed_volume', True)
50 self.fake_conf = config.Configuration(None)
51 self.cluster_name = 'fake'
52 export_locations = {0: {'path': '/share-0'}}
53 export_locations[0]['el_metadata'] = {
54 'volume-name': 'share-0'}
55 self.share = fake_share.fake_share(share_proto='MAPRFS',
56 name='share-0', size=2, share_id=1,
57 export_locations=export_locations,
58 export_location='/share-0')
59 self.snapshot = fake_share.fake_snapshot(share_proto='MAPRFS',
60 name='fake',
61 share_name=self.share['name'],
62 share_id=self.share['id'],
63 share=self.share,
64 share_instance=self.share,
65 provider_location='fake')
66 self.access = fake_share.fake_access(access_type='user',
67 access_to='fake',
68 access_level='rw')
70 self.snapshot = self.snapshot.values
71 self.snapshot.update(share_instance=self.share)
72 self.export_path = 'maprfs:///share-0 -C -Z -N fake'
73 self.fakesnapshot_path = '/share-0/.snapshot/snapshot-0'
74 self.hadoop_bin = '/usr/bin/hadoop'
75 self.maprcli_bin = '/usr/bin/maprcli'
77 self.mock_object(utils, 'execute')
78 self.mock_object(
79 mapru.socket, 'gethostname', mock.Mock(return_value='testserver'))
80 self.mock_object(
81 mapru.socket, 'gethostbyname_ex', mock.Mock(return_value=(
82 'localhost',
83 ['localhost.localdomain',
84 mapru.socket.gethostname.return_value],
85 ['127.0.0.1', self.local_ip])))
86 self._driver = maprfs.MapRFSNativeShareDriver(
87 configuration=self.fake_conf)
88 self._driver.do_setup(self._context)
89 self._driver.api.get_share_metadata = mock.Mock(return_value={})
90 self._driver.api.update_share_metadata = mock.Mock()
92 def test_do_setup(self):
93 self._driver.do_setup(self._context)
95 self.assertIsNotNone(self._driver._maprfs_util)
96 self.assertEqual([self.local_ip], self._driver._maprfs_util.hosts)
98 def test_check_for_setup_error(self):
99 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
100 self._driver._maprfs_util.check_state = mock.Mock(return_value=True)
101 self._driver._maprfs_util.maprfs_ls = mock.Mock()
103 self._driver.check_for_setup_error()
105 def test_check_for_setup_error_exception_config(self):
106 self._driver.configuration.maprfs_clinode_ip = None
108 self.assertRaises(exception.MapRFSException,
109 self._driver.check_for_setup_error)
111 def test_check_for_setup_error_exception_no_dir(self):
112 self._driver._maprfs_util.check_state = mock.Mock(return_value=True)
113 self._driver._maprfs_util.maprfs_ls = mock.Mock(
114 side_effect=exception.ProcessExecutionError)
116 self.assertRaises(exception.MapRFSException,
117 self._driver.check_for_setup_error)
119 def test_check_for_setup_error_exception_cldb_state(self):
120 self._driver._check_maprfs_state = mock.Mock(return_value=False)
122 self.assertRaises(exception.MapRFSException,
123 self._driver.check_for_setup_error)
125 def test__check_maprfs_state_healthy(self):
126 fake_out = """Found 8 items
127 drwxr-xr-x - mapr mapr 0 2016-07-29 05:38 /apps"""
128 self._driver._maprfs_util._execute = mock.Mock(
129 return_value=(fake_out, ''))
131 result = self._driver._check_maprfs_state()
133 self._driver._maprfs_util._execute.assert_called_once_with(
134 self.hadoop_bin, 'fs', '-ls', '/', check_exit_code=False)
135 self.assertTrue(result)
137 def test__check_maprfs_state_down(self):
138 fake_out = "No CLDB"
139 self._driver._maprfs_util._execute = mock.Mock(
140 return_value=(fake_out, ''))
142 result = self._driver._check_maprfs_state()
144 self._driver._maprfs_util._execute.assert_called_once_with(
145 self.hadoop_bin, 'fs', '-ls', '/', check_exit_code=False)
146 self.assertFalse(result)
148 def test__check_maprfs_state_exception(self):
149 self._driver._maprfs_util._execute = mock.Mock(
150 side_effect=exception.ProcessExecutionError)
152 self.assertRaises(exception.MapRFSException,
153 self._driver._check_maprfs_state)
154 self._driver._maprfs_util._execute.assert_called_once_with(
155 self.hadoop_bin, 'fs', '-ls', '/', check_exit_code=False)
157 def test_create_share_unsupported_proto(self):
158 self._driver.api.get_share_metadata = mock.Mock(return_value={})
159 self._driver._get_share_path = mock.Mock()
161 self.assertRaises(exception.MapRFSException,
162 self._driver.create_share,
163 self._context,
164 fake_share.fake_share(share_id=1),
165 share_server=None)
166 self.assertFalse(self._driver._get_share_path.called)
168 def test_manage_existing(self):
169 self._driver._maprfs_util.get_volume_info_by_path = mock.Mock(
170 return_value={'quota': 1024, 'totalused': 966,
171 'volumename': 'fake'})
172 self._driver._maprfs_util._execute = mock.Mock()
173 self._driver._maprfs_util.get_cluster_name = mock.Mock(
174 return_value="fake")
176 def test_manage_existing_no_rename(self):
177 self._driver._maprfs_util.get_volume_info_by_path = mock.Mock(
178 return_value={'quota': 1024, 'totalused': 966,
179 'volumename': 'fake'})
180 self._driver._maprfs_util._execute = mock.Mock()
181 self._driver._maprfs_util.get_cluster_name = mock.Mock(
182 return_value="fake")
184 result = self._driver.manage_existing(self.share, {'rename': 'no'})
186 self.assertEqual(1, result['size'])
188 def test_manage_existing_exception(self):
189 self._driver._maprfs_util.get_volume_info_by_path = mock.Mock(
190 side_effect=exception.ProcessExecutionError)
192 self.assertRaises(exception.MapRFSException,
193 self._driver.manage_existing, self.share, {})
195 def test_manage_existing_invalid_share(self):
196 def fake_execute(self, *cmd, **kwargs):
197 check_exit_code = kwargs.get('check_exit_code', True)
198 if check_exit_code: 198 ↛ 199line 198 didn't jump to line 199 because the condition on line 198 was never true
199 raise exception.ProcessExecutionError
200 else:
201 return 'No such volume', 0
203 self._driver._maprfs_util._execute = fake_execute
205 mock_execute = self._driver.manage_existing
207 self.assertRaises(exception.ManageInvalidShare, mock_execute,
208 self.share, {})
210 def test_manage_existing_snapshot(self):
211 self._driver._maprfs_util.get_snapshot_list = mock.Mock(
212 return_value=[self.snapshot['provider_location']])
213 self._driver._maprfs_util.maprfs_du = mock.Mock(return_value=11)
215 update = self._driver.manage_existing_snapshot(self.snapshot, {})
217 self.assertEqual(1, update['size'])
219 def test_manage_existing_snapshot_invalid(self):
220 self._driver._maprfs_util.get_snapshot_list = mock.Mock(
221 return_value=[])
223 mock_execute = self._driver.manage_existing_snapshot
225 self.assertRaises(exception.ManageInvalidShareSnapshot, mock_execute,
226 self.snapshot, {})
228 def test_manage_existing_snapshot_exception(self):
229 self._driver._maprfs_util.get_snapshot_list = mock.Mock(
230 side_effect=exception.ProcessExecutionError)
232 mock_execute = self._driver.manage_existing_snapshot
234 self.assertRaises(exception.MapRFSException, mock_execute,
235 self.snapshot, {})
237 def test_manage_existing_with_no_quota(self):
238 self._driver._maprfs_util.get_volume_info_by_path = mock.Mock(
239 return_value={'quota': 0, 'totalused': 1999,
240 'volumename': 'fake'})
241 self._driver._maprfs_util.rename_volume = mock.Mock()
242 self._driver._maprfs_util.get_cluster_name = mock.Mock(
243 return_value="fake")
245 result = self._driver.manage_existing(self.share, {})
247 self.assertEqual(2, result['size'])
249 def test__set_volume_size(self):
250 volume = self._driver._volume_name(self.share['name'])
251 sizestr = str(self.share['size']) + 'G'
252 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
254 self._driver._maprfs_util.set_volume_size(volume,
255 self.share['size'])
257 self._driver._maprfs_util._execute.assert_called_once_with(
258 self.maprcli_bin, 'volume', 'modify', '-name', volume, '-quota',
259 sizestr)
261 def test_extend_share(self):
262 volume = self._driver._volume_name(self.share['name'])
263 self._driver._maprfs_util.set_volume_size = mock.Mock()
265 self._driver.extend_share(self.share, self.share['size'])
267 self._driver._maprfs_util.set_volume_size.assert_called_once_with(
268 volume, self.share['size'])
270 def test_extend_exception(self):
271 self._driver._maprfs_util.set_volume_size = mock.Mock(
272 side_effect=exception.ProcessExecutionError)
274 self.assertRaises(exception.MapRFSException, self._driver.extend_share,
275 self.share, self.share['size'])
277 def test_shrink_share(self):
278 volume = self._driver._volume_name(self.share['name'])
279 self._driver._maprfs_util.set_volume_size = mock.Mock()
280 self._driver._maprfs_util.get_volume_info = mock.Mock(
281 return_value={'total_user': 0})
283 self._driver.shrink_share(self.share, self.share['size'])
285 self._driver._maprfs_util.set_volume_size.assert_called_once_with(
286 volume, self.share['size'])
288 def test_update_access_add(self):
289 aces = {
290 'volumeAces': {
291 'readAce': 'u:fake|fake:fake',
292 'writeAce': 'u:fake',
293 }
294 }
295 volume = self._driver._volume_name(self.share['name'])
296 self._driver._maprfs_util.get_volume_info = mock.Mock(
297 return_value=aces)
298 self._driver._maprfs_util.group_exists = mock.Mock(return_value=True)
299 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
301 self._driver.update_access(self._context, self.share, [self.access],
302 [self.access], [], [])
304 self._driver._maprfs_util._execute.assert_any_call(
305 self.maprcli_bin, 'volume', 'modify', '-name', volume, '-readAce',
306 'g:' + self.access['access_to'], '-writeAce',
307 'g:' + self.access['access_to'])
309 def test_update_access_add_no_user_no_group_exists(self):
310 aces = {
311 'volumeAces': {
312 'readAce': 'u:fake|fake:fake',
313 'writeAce': 'u:fake',
314 }
315 }
316 volume = self._driver._volume_name(self.share['name'])
317 self._driver._maprfs_util.get_volume_info = mock.Mock(
318 return_value=aces)
319 self._driver._maprfs_util.group_exists = mock.Mock(return_value=False)
320 self._driver._maprfs_util.user_exists = mock.Mock(return_value=False)
321 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
323 self._driver.update_access(self._context, self.share, [self.access],
324 [self.access], [], [])
326 self._driver._maprfs_util._execute.assert_any_call(
327 self.maprcli_bin, 'volume', 'modify', '-name', volume, '-readAce',
328 'g:' + self.access['access_to'], '-writeAce',
329 'g:' + self.access['access_to'])
331 def test_update_access_delete(self):
332 aces = {
333 'volumeAces': {
334 'readAce': 'p',
335 'writeAce': 'p',
336 }
337 }
338 volume = self._driver._volume_name(self.share['name'])
339 self._driver._maprfs_util.get_volume_info = mock.Mock(
340 return_value=aces)
341 self._driver._maprfs_util.group_exists = mock.Mock(return_value=True)
342 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
344 self._driver.update_access(self._context, self.share, [], [],
345 [self.access], [])
347 self._driver._maprfs_util._execute.assert_any_call(
348 self.maprcli_bin, 'volume', 'modify', '-name', volume, '-readAce',
349 '',
350 '-writeAce', '')
352 def test_update_access_recover(self):
353 aces = {
354 'volumeAces': {
355 'readAce': 'u:fake',
356 'writeAce': 'u:fake',
357 }
358 }
359 volume = self._driver._volume_name(self.share['name'])
360 self._driver._maprfs_util.get_volume_info = mock.Mock(
361 return_value=aces)
362 self._driver._maprfs_util.group_exists = mock.Mock(return_value=False)
363 self._driver._maprfs_util.user_exists = mock.Mock(return_value=True)
364 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
366 self._driver.update_access(self._context, self.share, [self.access],
367 [], [], [])
369 self._driver._maprfs_util._execute.assert_any_call(
370 self.maprcli_bin, 'volume', 'modify', '-name', volume, '-readAce',
371 'u:' + self.access['access_to'], '-writeAce',
372 'u:' + self.access['access_to'])
374 def test_update_access_share_not_exists(self):
375 self._driver._maprfs_util.volume_exists = mock.Mock(
376 return_value=False)
377 self._driver._maprfs_util.group_exists = mock.Mock(return_value=True)
378 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
380 self._driver.update_access(self._context, self.share, [self.access],
381 [], [], [])
383 self._driver._maprfs_util._execute.assert_not_called()
385 def test_update_access_exception(self):
386 aces = {
387 'volumeAces': {
388 'readAce': 'p',
389 'writeAce': 'p',
390 }
391 }
392 self._driver._maprfs_util.get_volume_info = mock.Mock(
393 return_value=aces)
394 self._driver._maprfs_util.group_exists = mock.Mock(return_value=True)
395 utils.execute = mock.Mock(
396 side_effect=exception.ProcessExecutionError(stdout='ERROR'))
398 self.assertRaises(exception.MapRFSException,
399 self._driver.update_access, self._context,
400 self.share, [self.access], [], [], [])
402 def test_update_access_invalid_access(self):
403 access = fake_share.fake_access(access_type='ip', access_to='fake',
404 access_level='rw')
406 self.assertRaises(exception.InvalidShareAccess,
407 self._driver.update_access, self._context,
408 self.share, [access], [], [], [])
410 def test_ensure_share(self):
411 self._driver._maprfs_util.volume_exists = mock.Mock(
412 return_value=True)
413 self._driver._maprfs_util.get_volume_info = mock.Mock(
414 return_value={'mountdir': self.share['export_location']})
415 self._driver._maprfs_util.get_cluster_name = mock.Mock(
416 return_value=self.cluster_name)
418 result = self._driver.ensure_share(self._context, self.share)
420 self.assertEqual(self.export_path, result[0]['path'])
422 def test_create_share(self):
423 size_str = str(self.share['size']) + 'G'
424 path = self._driver._share_dir(self.share['name'])
425 self._driver.api.get_share_metadata = mock.Mock(
426 return_value={'_fake': 'fake'})
427 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
428 self._driver._maprfs_util.set_volume_size = mock.Mock()
429 self._driver._maprfs_util.maprfs_chmod = mock.Mock()
430 self._driver._maprfs_util.get_cluster_name = mock.Mock(
431 return_value=self.cluster_name)
433 self._driver.create_share(self._context, self.share)
435 self._driver._maprfs_util._execute.assert_called_once_with(
436 self.maprcli_bin, 'volume', 'create', '-name', self.share['name'],
437 '-path', path, '-quota', size_str, '-readAce', '', '-writeAce', '',
438 '-fake', 'fake')
439 self._driver._maprfs_util.maprfs_chmod.assert_called_once_with(path,
440 '777')
442 def test_create_share_with_custom_name(self):
443 size_str = str(self.share['size']) + 'G'
444 self._driver.api.get_share_metadata = mock.Mock(
445 return_value={'_name': 'fake', '_path': 'fake'})
446 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
447 self._driver._maprfs_util.set_volume_size = mock.Mock()
448 self._driver._maprfs_util.maprfs_chmod = mock.Mock()
449 self._driver._maprfs_util.get_cluster_name = mock.Mock(
450 return_value=self.cluster_name)
452 self._driver.create_share(self._context, self.share)
454 self._driver._maprfs_util._execute.assert_called_once_with(
455 self.maprcli_bin, 'volume', 'create', '-name', 'fake',
456 '-path', 'fake', '-quota', size_str, '-readAce', '', '-writeAce',
457 '')
458 self._driver._maprfs_util.maprfs_chmod.assert_called_once_with('fake',
459 '777')
461 def test_create_share_exception(self):
462 self._driver.api.get_share_metadata = mock.Mock(return_value={})
463 self._driver._maprfs_util._execute = mock.Mock(
464 side_effect=exception.ProcessExecutionError)
465 self._driver._maprfs_util.set_volume_size = mock.Mock()
466 self._driver._maprfs_util.maprfs_chmod = mock.Mock()
467 self._driver._maprfs_util.get_cluster_name = mock.Mock(
468 return_value=self.cluster_name)
470 self.assertRaises(exception.MapRFSException, self._driver.create_share,
471 self._context, self.share)
473 def test_create_share_from_snapshot(self):
474 fake_snapshot = dict(self.snapshot)
475 fake_snapshot.update(share_instance={'share_id': 1})
476 size_str = str(self.share['size']) + 'G'
477 path = self._driver._share_dir(self.share['name'])
478 snapthot_path = self._driver._get_snapshot_path(self.snapshot) + '/*'
479 self._driver._maprfs_util._execute = mock.Mock(
480 return_value=('Found', 0))
481 self._driver._maprfs_util.set_volume_size = mock.Mock()
482 self._driver._maprfs_util.get_cluster_name = mock.Mock(
483 return_value=self.cluster_name)
484 self._driver.api.get_share_metadata = mock.Mock(
485 return_value={'_fake': 'fake', 'fake2': 'fake2'})
486 mock_execute = self._driver._maprfs_util._execute
488 self._driver.create_share_from_snapshot(self._context, self.share,
489 self.snapshot)
491 mock_execute.assert_any_call(self.hadoop_bin, 'fs', '-cp', '-p',
492 snapthot_path, path)
493 mock_execute.assert_any_call(self.maprcli_bin, 'volume', 'create',
494 '-name',
495 self.share['name'], '-path', path,
496 '-quota', size_str, '-readAce', '',
497 '-writeAce', '', '-fake', 'fake')
499 def test_create_share_from_snapshot_wrong_tenant(self):
500 fake_snapshot = dict(self.snapshot)
501 fake_snapshot.update(share_instance={'share_id': 10})
502 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
503 self._driver._maprfs_util.set_volume_size = mock.Mock()
504 self._driver._maprfs_util.get_cluster_name = mock.Mock(
505 return_value=self.cluster_name)
507 def fake_meta(context, share):
508 return {'_tenantuser': 'fake'} if share['id'] == 10 else {}
510 self._driver.api.get_share_metadata = fake_meta
512 self.assertRaises(exception.MapRFSException,
513 self._driver.create_share_from_snapshot,
514 self._context, self.share, fake_snapshot)
516 def test_create_share_from_snapshot_exception(self):
517 fake_snapshot = dict(self.snapshot)
518 fake_snapshot.update(share_instance={'share_id': 10})
519 self._driver._maprfs_util._execute = mock.Mock(
520 return_value=('Found 0', 0))
521 self._driver._maprfs_util.maprfs_cp = mock.Mock(
522 side_effect=exception.ProcessExecutionError)
523 self._driver.api.get_share_metadata = mock.Mock(
524 return_value={'_tenantuser': 'fake'})
526 self.assertRaises(exception.MapRFSException,
527 self._driver.create_share_from_snapshot,
528 self._context, self.share, self.snapshot)
530 def test_delete_share(self):
531 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
533 self._driver.delete_share(self._context, self.share)
535 self._driver._maprfs_util._execute.assert_called_once_with(
536 self.maprcli_bin, 'volume', 'remove', '-name', self.share['name'],
537 '-force', 'true', check_exit_code=False)
539 def test_delete_share_skip(self):
540 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
541 self._driver.api.get_share_metadata = mock.Mock(
542 return_value={'_name': 'error'})
544 self._driver.delete_share(self._context, self.share)
546 self._driver._maprfs_util._execute.assert_not_called()
548 def test_delete_share_exception(self):
549 self._driver._maprfs_util._execute = mock.Mock(
550 side_effect=exception.ProcessExecutionError)
552 self.assertRaises(exception.MapRFSException, self._driver.delete_share,
553 self._context, self.share)
555 def test_delete_share_not_exist(self):
556 self._driver._maprfs_util._execute = mock.Mock(
557 return_value=('No such volume', 0))
559 self._driver.delete_share(self._context, self.share)
561 def test_create_snapshot(self):
562 volume = self._driver._volume_name(self.share['name'])
563 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
565 self._driver.create_snapshot(self._context, self.snapshot)
567 self._driver._maprfs_util._execute.assert_called_once_with(
568 self.maprcli_bin, 'volume', 'snapshot', 'create', '-snapshotname',
569 self.snapshot['name'], '-volume', volume)
571 def test_create_snapshot_exception(self):
572 self._driver._maprfs_util._execute = mock.Mock(
573 side_effect=exception.ProcessExecutionError)
575 self.assertRaises(exception.MapRFSException,
576 self._driver.create_snapshot, self._context,
577 self.snapshot)
579 def test_delete_snapshot(self):
580 volume = self._driver._volume_name(self.share['name'])
581 self._driver._maprfs_util._execute = mock.Mock(return_value=('', 0))
583 self._driver.delete_snapshot(self._context, self.snapshot)
585 self._driver._maprfs_util._execute.assert_called_once_with(
586 self.maprcli_bin, 'volume', 'snapshot', 'remove', '-snapshotname',
587 self.snapshot['name'], '-volume', volume, check_exit_code=False)
589 def test_delete_snapshot_exception(self):
590 self._driver._maprfs_util._execute = mock.Mock(
591 return_value=('ERROR (fake)', None))
593 self.assertRaises(exception.MapRFSException,
594 self._driver.delete_snapshot,
595 self._context, self.snapshot)
597 def test__execute(self):
598 first_host_skip = 'first'
599 available_host = 'available'
600 hosts = [first_host_skip, self.local_ip, available_host, 'extra']
601 test_config = mock.Mock()
602 test_config.maprfs_clinode_ip = hosts
603 test_config.maprfs_ssh_name = 'fake_maprfs_ssh_name'
604 test_maprfs_util = mapru.get_version_handler(test_config)
605 # mutable container
606 done = [False]
607 skips = []
609 def fake_ssh_run(host, cmd, check_exit_code):
610 if host == available_host:
611 done[0] = True
612 return '', 0
613 else:
614 skips.append(host)
615 raise Exception()
617 test_maprfs_util._run_ssh = fake_ssh_run
619 test_maprfs_util._execute('fake', 'cmd')
621 self.assertTrue(done[0])
622 self.assertEqual(available_host, test_maprfs_util.hosts[0])
623 self.assertEqual(first_host_skip, test_maprfs_util.hosts[2])
624 self.assertEqual([first_host_skip], skips)
625 utils.execute.assert_called_once_with(
626 'sudo', 'su', '-', 'fake_maprfs_ssh_name', '-c', 'fake cmd',
627 check_exit_code=True)
629 def test__execute_exeption(self):
630 utils.execute = mock.Mock(side_effect=Exception)
632 self.assertRaises(exception.ProcessExecutionError,
633 self._driver._maprfs_util._execute, "fake", "cmd")
635 def test__execute_native_exeption(self):
636 utils.execute = mock.Mock(
637 side_effect=exception.ProcessExecutionError(stdout='fake'))
639 self.assertRaises(exception.ProcessExecutionError,
640 self._driver._maprfs_util._execute, "fake", "cmd")
642 def test__execute_local(self):
643 self.mock_object(utils, 'execute', mock.Mock(return_value=("fake", 0)))
645 self._driver._maprfs_util._execute("fake", "cmd")
647 utils.execute.assert_called_once_with('sudo', 'su', '-',
648 'fake_sshname', '-c', 'fake cmd',
649 check_exit_code=True)
651 def test_share_shrink_error(self):
652 fake_info = {
653 'totalused': 1024,
654 'quota': 2024
655 }
656 self._driver._maprfs_util._execute = mock.Mock()
657 self._driver._maprfs_util.get_volume_info = mock.Mock(
658 return_value=fake_info)
660 self.assertRaises(exception.ShareShrinkingPossibleDataLoss,
661 self._driver.shrink_share, self.share, 1)
663 def test__get_volume_info(self):
664 fake_out = """
665 {"data": [{"mounted":1,"quota":"1024","used":"0","totalused":"0"}]}
666 """
667 self._driver._maprfs_util._execute = mock.Mock(
668 return_value=(fake_out, 0))
670 result = self._driver._maprfs_util.get_volume_info('fake_name')
672 self.assertEqual('0', result['used'])
674 def test__get_volume_info_by_path(self):
675 fake_out = """
676 {"data": [{"mounted":1,"quota":"1024","used":"0","totalused":"0"}]}
677 """
678 self._driver._maprfs_util._execute = mock.Mock(
679 return_value=(fake_out, 0))
681 result = self._driver._maprfs_util.get_volume_info_by_path('fake_path')
683 self.assertEqual('0', result['used'])
685 def test__get_volume_info_by_path_not_exist(self):
686 fake_out = "No such volume"
687 self._driver._maprfs_util._execute = mock.Mock(
688 return_value=(fake_out, 0))
690 result = self._driver._maprfs_util.get_volume_info_by_path(
691 'fake_path', check_if_exists=True)
693 self.assertIsNone(result)
695 def test_get_share_stats_refresh_false(self):
696 self._driver._stats = {'fake_key': 'fake_value'}
698 result = self._driver.get_share_stats(False)
700 self.assertEqual(self._driver._stats, result)
702 def test_get_share_stats_refresh_true(self):
703 self._driver._maprfs_util.fs_capacity = mock.Mock(
704 return_value=(1143554.0, 124111.0))
706 result = self._driver.get_share_stats(True)
708 expected_keys = [
709 'qos', 'driver_version', 'share_backend_name',
710 'free_capacity_gb', 'total_capacity_gb',
711 'driver_handles_share_servers',
712 'reserved_percentage', 'reserved_snapshot_percentage',
713 'reserved_share_extend_percentage',
714 'vendor_name', 'storage_protocol',
715 ]
716 for key in expected_keys:
717 self.assertIn(key, result)
718 self.assertEqual('MAPRFS', result['storage_protocol'])
719 self._driver._maprfs_util.fs_capacity.assert_called_once_with()
721 def test_get_share_stats_refresh_exception(self):
722 self._driver._maprfs_util.fs_capacity = mock.Mock(
723 side_effect=exception.ProcessExecutionError)
725 self.assertRaises(exception.MapRFSException,
726 self._driver.get_share_stats, True)
728 def test__get_available_capacity(self):
729 fake_out = """Filesystem Size Used Available Use%
730 maprfs:/// 26367492096 1231028224 25136463872 5%
731 """
732 self._driver._maprfs_util._execute = mock.Mock(
733 return_value=(fake_out, ''))
735 total, free = self._driver._maprfs_util.fs_capacity()
737 self._driver._maprfs_util._execute.assert_called_once_with(
738 self.hadoop_bin, 'fs', '-df')
739 self.assertEqual(26367492096, total)
740 self.assertEqual(25136463872, free)
742 def test__get_available_capacity_exception(self):
743 fake_out = 'fake'
744 self._driver._maprfs_util._execute = mock.Mock(
745 return_value=(fake_out, ''))
747 self.assertRaises(exception.ProcessExecutionError,
748 self._driver._maprfs_util.fs_capacity)
750 def test__get_snapshot_list(self):
751 fake_out = """{"data":[{"snapshotname":"fake-snapshot"}]}"""
752 self._driver._maprfs_util._execute = mock.Mock(
753 return_value=(fake_out, None))
755 snapshot_list = self._driver._maprfs_util.get_snapshot_list(
756 volume_name='fake', volume_path='fake')
758 self.assertEqual(['fake-snapshot'], snapshot_list)
760 def test__cluster_name(self):
761 fake_info = """{
762 "data":[
763 {
764 "version":"fake",
765 "cluster":{
766 "name":"fake",
767 "secure":false,
768 "ip":"10.10.10.10",
769 "id":"7133813101868836065",
770 "nodesUsed":1,
771 "totalNodesAllowed":-1
772 }
773 }
774 ]
775 }
776 """
777 self._driver._maprfs_util._execute = mock.Mock(
778 return_value=(fake_info, 0))
780 name = self._driver._maprfs_util.get_cluster_name()
782 self.assertEqual('fake', name)
784 def test__cluster_name_exception(self):
785 fake_info = 'fake'
787 self._driver._maprfs_util._execute = mock.Mock(
788 return_value=(fake_info, 0))
790 self.assertRaises(exception.ProcessExecutionError,
791 self._driver._maprfs_util.get_cluster_name)
793 def test__run_ssh(self):
794 ssh_output = 'fake_ssh_output'
795 cmd_list = ['fake', 'cmd']
796 ssh = mock.Mock()
797 ssh.get_transport = mock.Mock()
798 ssh.get_transport().is_active = mock.Mock(return_value=False)
799 ssh_pool = mock.Mock()
800 ssh_pool.create = mock.Mock(return_value=ssh)
801 self.mock_object(ssh_utils,
802 'SSHPool',
803 mock.Mock(return_value=ssh_pool))
804 self.mock_object(processutils, 'ssh_execute',
805 mock.Mock(return_value=ssh_output))
806 result = self._driver._maprfs_util._run_ssh(
807 self.local_ip, cmd_list, check_exit_code=False)
808 ssh_utils.SSHPool.assert_called_once_with(
809 self._driver.configuration.maprfs_clinode_ip[0],
810 self._driver.configuration.maprfs_ssh_port,
811 self._driver.configuration.ssh_conn_timeout,
812 self._driver.configuration.maprfs_ssh_name,
813 password=self._driver.configuration.maprfs_ssh_pw,
814 privatekey=self._driver.configuration.maprfs_ssh_private_key,
815 min_size=self._driver.configuration.ssh_min_pool_conn,
816 max_size=self._driver.configuration.ssh_max_pool_conn)
817 ssh_pool.create.assert_called()
818 ssh.get_transport().is_active.assert_called_once_with()
819 processutils.ssh_execute.assert_called_once_with(
820 ssh, 'fake cmd', check_exit_code=False)
821 self.assertEqual(ssh_output, result)
823 def test__run_ssh_exception(self):
824 cmd_list = ['fake', 'cmd']
825 ssh = mock.Mock()
826 ssh.get_transport = mock.Mock()
827 ssh.get_transport().is_active = mock.Mock(return_value=True)
828 ssh_pool = mock.Mock()
829 ssh_pool.create = mock.Mock(return_value=ssh)
830 self.mock_object(ssh_utils,
831 'SSHPool',
832 mock.Mock(return_value=ssh_pool))
833 self.mock_object(processutils, 'ssh_execute', mock.Mock(
834 side_effect=exception.ProcessExecutionError))
835 self.assertRaises(exception.ProcessExecutionError,
836 self._driver._maprfs_util._run_ssh,
837 self.local_ip,
838 cmd_list)
839 ssh_utils.SSHPool.assert_called_once_with(
840 self._driver.configuration.maprfs_clinode_ip[0],
841 self._driver.configuration.maprfs_ssh_port,
842 self._driver.configuration.ssh_conn_timeout,
843 self._driver.configuration.maprfs_ssh_name,
844 password=self._driver.configuration.maprfs_ssh_pw,
845 privatekey=self._driver.configuration.maprfs_ssh_private_key,
846 min_size=self._driver.configuration.ssh_min_pool_conn,
847 max_size=self._driver.configuration.ssh_max_pool_conn)
848 ssh_pool.create.assert_called_once_with()
849 ssh.get_transport().is_active.assert_called_once_with()
850 processutils.ssh_execute.assert_called_once_with(
851 ssh, 'fake cmd', check_exit_code=False)
853 def test__share_dir(self):
854 self._driver._base_volume_dir = '/volumes'
855 share_dir = '/volumes/' + self.share['name']
856 actual_dir = self._driver._share_dir(self.share['name'])
858 self.assertEqual(share_dir, actual_dir)
860 def test__get_volume_name(self):
861 volume_name = self._driver._get_volume_name("fake", self.share)
863 self.assertEqual('share-0', volume_name)
865 def test__maprfs_du(self):
866 self._driver._maprfs_util._execute = mock.Mock(
867 return_value=('1024 /', 0))
869 size = self._driver._maprfs_util.maprfs_du('/')
871 self._driver._maprfs_util._execute.assert_called()
872 self.assertEqual(1024, size)
874 def test__maprfs_ls(self):
875 self._driver._maprfs_util._execute = mock.Mock(
876 return_value=('fake', 0))
878 self._driver._maprfs_util.maprfs_ls('/')
880 self._driver._maprfs_util._execute.assert_called_with(self.hadoop_bin,
881 'fs', '-ls', '/')
883 def test_rename_volume(self):
884 self._driver._maprfs_util._execute = mock.Mock(
885 return_value=('fake', 0))
887 self._driver._maprfs_util.rename_volume('fake', 'newfake')
889 self._driver._maprfs_util._execute.assert_called_with(self.maprcli_bin,
890 'volume',
891 'rename',
892 '-name', 'fake',
893 '-newname',
894 'newfake')
896 def test__run_as_user(self):
897 cmd = ['fake', 'cmd']
898 u_cmd = self._driver._maprfs_util._as_user(cmd, 'user')
900 self.assertEqual(['sudo', 'su', '-', 'user', '-c', 'fake cmd'], u_cmd)
902 def test__add_params(self):
903 params = {'p1': 1, 'p2': 2, 'p3': '3'}
904 cmd = ['fake', 'cmd']
905 cmd_with_params = self._driver._maprfs_util._add_params(cmd, **params)
907 self.assertEqual(cmd[:2], cmd_with_params[:2])
909 def test_get_network_allocations_number(self):
910 number = self._driver.get_admin_network_allocations_number()
912 self.assertEqual(0, number)
914 def test__user_exists(self):
915 fake_out = 'user:x:1000:1000::/opt/user:/bin/bash'
916 self._driver._maprfs_util._execute = mock.Mock(
917 return_value=(fake_out, 0))
919 result = self._driver._maprfs_util.user_exists('user')
921 self.assertTrue(result)
923 def test__group_exists(self):
924 fake_out = 'user:x:1000:'
925 self._driver._maprfs_util._execute = mock.Mock(
926 return_value=(fake_out, 0))
928 result = self._driver._maprfs_util.group_exists('user')
930 self.assertTrue(result)