[blivet:master 13/14] Change mdadm() so that it raises an exception when the command fails
mulhern
amulhern at redhat.com
Wed Jul 16 16:56:44 UTC 2014
Now mdexamine() and mddetail() raise an MDRaidError if called on an
inappropriate device, instead of silently failing to parse error output.
---
blivet/devicelibs/mdraid.py | 31 +++++++++++++++---------
tests/devicelibs_test/mdraid_interrogate_test.py | 28 ++++++++++++++++-----
2 files changed, 42 insertions(+), 17 deletions(-)
diff --git a/blivet/devicelibs/mdraid.py b/blivet/devicelibs/mdraid.py
index 83f87cf..7563dc1 100644
--- a/blivet/devicelibs/mdraid.py
+++ b/blivet/devicelibs/mdraid.py
@@ -80,17 +80,19 @@ def get_raid_superblock_size(size, version=None):
return headroom
def mdadm(args, capture=False):
- if capture:
- exec_func = util.capture_output
- else:
- exec_func = util.run_program
+ """ Run mdadm with specified arguments.
+ :param bool capture: if True, return the output of the command
+ :returns: the output of the command or None
+ :rtype: list of str or NoneType
+ :raises: MDRaidError if command fails
+ """
argv = ["mdadm"] + args
-
- ret = exec_func(argv)
- if ret and not capture:
+ (ret, out) = util.run_program_and_capture_output(argv)
+ if ret:
raise MDRaidError(ret)
- return ret
+ if capture:
+ return out
def mdcreate(device, level, disks, spares=0, metadataVer=None, bitmap=False):
""" Create an mdarray from a list of devices.
@@ -253,8 +255,11 @@ def mdexamine(device):
:rtype: a dict of strings
:returns: a dict containing labels and values extracted from output
"""
- _vars = mdadm(["--examine", "--export", device], capture=True).split()
- _bvars = mdadm(["--examine", "--brief", device], capture=True).split()
+ try:
+ _vars = mdadm(["--examine", "--export", device], capture=True).split()
+ _bvars = mdadm(["--examine", "--brief", device], capture=True).split()
+ except MDRaidError as e:
+ raise MDRaidError("mdexamine failed for %s: %s" % (device, e))
info = {}
if len(_bvars) > 1 and _bvars[1].startswith("/dev/md"):
@@ -300,7 +305,11 @@ def mddetail(device):
:rtype: a dict of strings
:returns: a dict containing labels and values extracted from output
"""
- lines = mdadm(["--detail", device], capture=True).split("\n")
+ try:
+ lines = mdadm(["--detail", device], capture=True).split("\n")
+ except MDRaidError as e:
+ raise MDRaidError("mddetail failed for %s: %s" % (device, e))
+
info = {}
for (name, colon, value) in (line.strip().partition(":") for line in lines):
value = value.strip()
diff --git a/tests/devicelibs_test/mdraid_interrogate_test.py b/tests/devicelibs_test/mdraid_interrogate_test.py
index 4399da9..9b1bbdc 100755
--- a/tests/devicelibs_test/mdraid_interrogate_test.py
+++ b/tests/devicelibs_test/mdraid_interrogate_test.py
@@ -8,6 +8,8 @@ import blivet.devicelibs.mdraid as mdraid
from . import mdraid_test
+from blivet.errors import MDRaidError
+
class MDRaidInterrogateTestCase(mdraid_test.MDRaidAsRootTestCase):
@@ -68,14 +70,14 @@ class MDExamineTestCase(MDRaidInterrogateTestCase):
mdraid.mdcreate(self._dev_name, raid.RAID1, self.loopDevices)
time.sleep(2) # wait for raid to settle
- # examining the array itself yield no data
- info = mdraid.mdexamine(self._dev_name)
- self.assertEqual(info, {})
+ # invoking mdexamine on the array itself raises an error
+ with self.assertRaisesRegexp(MDRaidError, "mdexamine failed"):
+ mdraid.mdexamine(self._dev_name)
def testMDExamineNonMDRaid(self):
- # invoking mdexamine on a device that is not an array member yields {}
- info = mdraid.mdexamine(self.loopDevices[0])
- self.assertEqual(info, {})
+ # invoking mdexamine on any non-array member raises an error
+ with self.assertRaisesRegexp(MDRaidError, "mdexamine failed"):
+ mdraid.mdexamine(self.loopDevices[0])
def _testMDExamine(self, names, metadataVersion=None, level=None, spares=0):
""" Test mdexamine for a specified metadataVersion.
@@ -216,5 +218,19 @@ class MDDetailTestCase(MDRaidInterrogateTestCase):
def testMDDetail0_90(self):
self._testMDDetail(self.names_0, metadataVersion='0.90')
+ def testMDDetailMDDevice(self):
+ mdraid.mdcreate(self._dev_name, raid.RAID1, self.loopDevices)
+ time.sleep(2) # wait for raid to settle
+
+ # invoking mddetail on a device raises an error
+ with self.assertRaisesRegexp(MDRaidError, "mddetail failed"):
+ mdraid.mddetail(self.loopDevices[0])
+
+ def testMDExamineNonMDRaid(self):
+ # invoking mdexamine on any non-array member raises an error
+ with self.assertRaisesRegexp(MDRaidError, "mdexamine failed"):
+ mdraid.mdexamine(self.loopDevices[0])
+
+
if __name__ == "__main__":
unittest.main()
--
1.9.3
More information about the anaconda-patches
mailing list