]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix _get_disk_of_partition edgecase in utils
authorgit-harry <git-harry@live.co.uk>
Fri, 28 Nov 2014 12:35:43 +0000 (12:35 +0000)
committergit-harry <git-harry@live.co.uk>
Fri, 28 Nov 2014 12:56:33 +0000 (12:56 +0000)
_get_disk_of_partition in cinder/utils returns a disk device path,
calculated from a supplied partition device path, and stat for a device.

If the disk path calculated by the function, using a regex, is not a
block device the function will return the original device path argument
and the stat object for disk path that was not a block device.

This commit modifies the function so that if the supplied device path is
returned by the function the stat of that path is guaranteed to be
returned.

Change-Id: I7ce0a748fe4a0ebaa02cba11baadb8c71c007aa2

cinder/tests/test_utils.py
cinder/utils.py

index 9381de239703bf7236010c1d32aa4f3af85047cd..6e02759f112ab65cdb1d173032318cbe542cca8a 100644 (file)
@@ -603,6 +603,49 @@ class GenericUtilsTestCase(test.TestCase):
         self.assertIsNone(dev)
 
 
+class GetDiskOfPartitionTestCase(test.TestCase):
+    def test_devpath_is_diskpath(self):
+        devpath = '/some/path'
+        st_mock = mock.Mock()
+        output = utils._get_disk_of_partition(devpath, st_mock)
+        self.assertEqual('/some/path', output[0])
+        self.assertIs(st_mock, output[1])
+
+        with mock.patch('os.stat') as mock_stat:
+            devpath = '/some/path'
+            output = utils._get_disk_of_partition(devpath)
+            mock_stat.assert_called_once_with(devpath)
+            self.assertEqual(devpath, output[0])
+            self.assertIs(mock_stat.return_value, output[1])
+
+    @mock.patch('os.stat', side_effect=OSError)
+    def test_stat_oserror(self, mock_stat):
+        st_mock = mock.Mock()
+        devpath = '/some/path1'
+        output = utils._get_disk_of_partition(devpath, st_mock)
+        mock_stat.assert_called_once_with('/some/path')
+        self.assertEqual(devpath, output[0])
+        self.assertIs(st_mock, output[1])
+
+    @mock.patch('stat.S_ISBLK', return_value=True)
+    @mock.patch('os.stat')
+    def test_diskpath_is_block_device(self, mock_stat, mock_isblk):
+        st_mock = mock.Mock()
+        devpath = '/some/path1'
+        output = utils._get_disk_of_partition(devpath, st_mock)
+        self.assertEqual('/some/path', output[0])
+        self.assertEqual(mock_stat.return_value, output[1])
+
+    @mock.patch('stat.S_ISBLK', return_value=False)
+    @mock.patch('os.stat')
+    def test_diskpath_is_not_block_device(self, mock_stat, mock_isblk):
+        st_mock = mock.Mock()
+        devpath = '/some/path1'
+        output = utils._get_disk_of_partition(devpath, st_mock)
+        self.assertEqual(devpath, output[0])
+        self.assertEqual(st_mock, output[1])
+
+
 class MonkeyPatchTestCase(test.TestCase):
     """Unit test for utils.monkey_patch()."""
     def setUp(self):
index eca0d9121144487ef6e2a3dd4ad439699e0dc134..c2d751f3fa82483a0050bd80e626bdb07d02cdf9 100644 (file)
@@ -627,17 +627,17 @@ def _get_disk_of_partition(devpath, st=None):
     for '/dev/disk1p1' ('p' is prepended to the partition number if the disk
     name ends with numbers).
     """
-    if st is None:
-        st = os.stat(devpath)
     diskpath = re.sub('(?:(?<=\d)p)?\d+$', '', devpath)
     if diskpath != devpath:
         try:
-            st = os.stat(diskpath)
-            if stat.S_ISBLK(st.st_mode):
-                return (diskpath, st)
+            st_disk = os.stat(diskpath)
+            if stat.S_ISBLK(st_disk.st_mode):
+                return (diskpath, st_disk)
         except OSError:
             pass
     # devpath is not a partition
+    if st is None:
+        st = os.stat(devpath)
     return (devpath, st)