def test_find_share(self):
"""_find_share simple use case."""
- mox = self.mox
drv = self._driver
-
drv._mounted_shares = [self.TEST_NFS_EXPORT1, self.TEST_NFS_EXPORT2]
- mox.StubOutWithMock(drv, '_get_capacity_info')
- drv._get_capacity_info(self.TEST_NFS_EXPORT1).\
- AndReturn((5 * units.Gi, 2 * units.Gi,
- 2 * units.Gi))
- drv._get_capacity_info(self.TEST_NFS_EXPORT1).\
- AndReturn((5 * units.Gi, 2 * units.Gi,
- 2 * units.Gi))
- drv._get_capacity_info(self.TEST_NFS_EXPORT2).\
- AndReturn((10 * units.Gi, 3 * units.Gi,
- 1 * units.Gi))
- drv._get_capacity_info(self.TEST_NFS_EXPORT2).\
- AndReturn((10 * units.Gi, 3 * units.Gi,
- 1 * units.Gi))
-
- mox.ReplayAll()
-
- self.assertEqual(self.TEST_NFS_EXPORT2,
- drv._find_share(self.TEST_SIZE_IN_GB))
-
- mox.VerifyAll()
+ with mock.patch.object(drv, '_get_capacity_info')\
+ as mock_get_capacity_info:
+ mock_get_capacity_info.side_effect = [
+ (5 * units.Gi, 2 * units.Gi, 2 * units.Gi),
+ (10 * units.Gi, 3 * units.Gi, 1 * units.Gi)]
+ self.assertEqual(self.TEST_NFS_EXPORT2,
+ drv._find_share(self.TEST_SIZE_IN_GB))
+ self.assertTrue(mock.call(self.TEST_NFS_EXPORT1) in
+ mock_get_capacity_info.call_args_list)
+ self.assertTrue(mock.call(self.TEST_NFS_EXPORT2) in
+ mock_get_capacity_info.call_args_list)
+ self.assertEqual(mock_get_capacity_info.call_count, 2)
def test_find_share_should_throw_error_if_there_is_not_enough_space(self):
"""_find_share should throw error if there is no share to host vol."""
target_share_reserved = 0
for nfs_share in self._mounted_shares:
- if not self._is_share_eligible(nfs_share, volume_size_in_gib):
+ total_size, total_available, total_allocated = (
+ self._get_capacity_info(nfs_share))
+ share_info = {'total_size': total_size,
+ 'total_available': total_available,
+ 'total_allocated': total_allocated,
+ }
+ if not self._is_share_eligible(nfs_share, volume_size_in_gib,
+ share_info):
continue
- _total_size, _total_available, total_allocated = \
- self._get_capacity_info(nfs_share)
if target_share is not None:
if target_share_reserved > total_allocated:
target_share = nfs_share
return target_share
- def _is_share_eligible(self, nfs_share, volume_size_in_gib):
+ def _is_share_eligible(self, nfs_share, volume_size_in_gib,
+ share_info=None):
"""Verifies NFS share is eligible to host volume with given size.
First validation step: ratio of actual space (used_space / total_space)
# 'nfs_used_ratio' is deprecated, so derive used_ratio from
# reserved_percentage.
+ if share_info is None:
+ total_size, total_available, total_allocated = (
+ self._get_capacity_info(nfs_share))
+ share_info = {'total_size': total_size,
+ 'total_available': total_available,
+ 'total_allocated': total_allocated,
+ }
used_percentage = 100 - self.reserved_percentage
used_ratio = used_percentage / 100.0
oversub_ratio = self.over_subscription_ratio
requested_volume_size = volume_size_in_gib * units.Gi
- total_size, total_available, total_allocated = \
- self._get_capacity_info(nfs_share)
- apparent_size = max(0, total_size * oversub_ratio)
- apparent_available = max(0, apparent_size - total_allocated)
+ apparent_size = max(0, share_info['total_size'] * oversub_ratio)
+ apparent_available = max(0, apparent_size -
+ share_info['total_allocated'])
- actual_used_ratio = (total_size - total_available) / float(total_size)
+ actual_used_ratio = ((share_info['total_size'] -
+ share_info['total_available']) /
+ float(share_info['total_size']))
if actual_used_ratio > used_ratio:
# NOTE(morganfainberg): We check the used_ratio first since
# with oversubscription it is possible to not have the actual
if apparent_available <= requested_volume_size:
LOG.debug('%s is above nfs_oversub_ratio', nfs_share)
return False
- if total_allocated / total_size >= oversub_ratio:
+ if share_info['total_allocated'] / share_info['total_size'] >= (
+ oversub_ratio):
LOG.debug('%s reserved space is above nfs_oversub_ratio',
nfs_share)
return False