[blivet 1/8] Add some basic unit tests for MDRaidArrayDevice.

mulhern amulhern at redhat.com
Thu Nov 21 16:59:43 UTC 2013


Add some basic tests to check the state of an MDRaidArrayDevice
after initialization and to check the behavior of some methods.

These tests are added mostly to detect regressions during an anticipated
refactoring.

These tests are very much after the fact and capture the current
behavior, not necessarily the intended or correct behavior.

Therefore, it is fairly likely that if some change to the code
causes a failure, it may be that the test itself is what has
been shown to be wrong.

In some cases, the class was internally inconsistent, in these cases
the inconsistency was resolved. In deciding how to resolve these
inconsistencies more significant methods and simpler code was considered
to have greater credibility than less significant methods or more
complicated code. Errors having to do with None having no attribute
or not being iterable were considered to be unintentional and given
low credibility.

The changes to the tested code are:

* Check whether a smallestMember actually exists and set
smallestMemberSize to 0 if one does not exist or if there are no devices.
Still go through the checks for level even if smallestMemberSize is 0
in order to catch invalid raid level.

* In rawArraySize for RAID10, divide by 2 instead of 2.0. I believe that
if there are three disks available then we get only one disk's worth of data.
Do the same in size.

* A semantics preserving change to initializer.
This change preserves the semantics of the if statement completely.
The advantage is that self.level is no longer
set to any arbitrary value which allows error checking in self.level
setter itself.

* Make level setter error checking.
Previously, the level could be set to anything in the initializer.
Now that this is not true, it is possible to check for invalid values in
the level setter. Valid values are an integer RAID level, "container", or
None.

* smallestMember is altered in a semantically equivalent way, except that
if not self.devices evaluates to True an exception will not be thrown.
Previously, it would have been thrown if self.devices was not a list.
It uses min instead of smallest, since we only need the minimum element
in self.devices.

* totalDevices is also semantically equivalent, but the len of self.parents
is only calculated if needed.

* description is extended so that it makes a somewhat sensible string if
self.level is None.

* In initializer,
use memberDevices setter rather than assigning to _memberDevices
directly in order to get the error checking in the setter.

* formatArgs now returns its formatArgs value
---
 blivet/devicelibs/mdraid.py |   2 +-
 blivet/devices.py           |  45 ++++--
 tests/devices_test.py       | 386 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 417 insertions(+), 16 deletions(-)
 create mode 100644 tests/devices_test.py

diff --git a/blivet/devicelibs/mdraid.py b/blivet/devicelibs/mdraid.py
index 27010f2..1c21c04 100644
--- a/blivet/devicelibs/mdraid.py
+++ b/blivet/devicelibs/mdraid.py
@@ -85,7 +85,7 @@ def get_raid_min_members(raidlevel):
         if isRaid(raid, raidlevel):
             return min_members
 
-    raise MDRaidError("invalid raid level %d" % raidlevel)
+    raise MDRaidError("invalid raid level %s" % raidlevel)
 
 def get_raid_max_spares(raidlevel, nummembers):
     """Return the maximum number of raid spares for raidlevel."""
diff --git a/blivet/devices.py b/blivet/devices.py
index 66a4ab2..276822a 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -2978,11 +2978,13 @@ class MDRaidArrayDevice(StorageDevice):
                                major=major, minor=minor, size=size,
                                parents=parents, sysfsPath=sysfsPath)
 
-        self.level = level
         if level == "container":
             self._type = "mdcontainer"
+            self.level = "container"
         elif level is not None:
             self.level = mdraid.raidLevel(level)
+        else:
+            self.level = None
 
         # For new arrays check if we have enough members
         if (not exists and parents and
@@ -2996,7 +2998,7 @@ class MDRaidArrayDevice(StorageDevice):
 
         self.uuid = uuid
         self._totalDevices = util.numeric_type(totalDevices)
-        self._memberDevices = util.numeric_type(memberDevices)
+        self.memberDevices = util.numeric_type(memberDevices)
 
         self.chunkSize = 512.0 / 1024.0         # chunk size in MB
 
@@ -3028,7 +3030,7 @@ class MDRaidArrayDevice(StorageDevice):
         """ Return the raid level
 
             :returns: raid level value
-            :rtype:   int
+            :rtype:   an int representing a raid level, "container", or None
         """
         return self._level
 
@@ -3037,11 +3039,15 @@ class MDRaidArrayDevice(StorageDevice):
         """ Set the RAID level and enforce restrictions based on it.
 
             :param value: new raid level
-            :param type:  int
+            :param type:  a valid raid level int, "container", or None
             :returns:     None
 
             Sets createBitmap True unless level is 0
         """
+        if not value in mdraid.raid_levels and \
+           value != "container" and value is not None:
+            raise mdraid.MDRaidError("invalid raid level %s" % str(value))
+
         self._level = value
 
         # bitmaps are not meaningful on raid0 according to mdadm-3.0.3
@@ -3057,7 +3063,13 @@ class MDRaidArrayDevice(StorageDevice):
 
         Returns the raw size in MB
         """
-        smallestMemberSize = self.smallestMember.size
+        smallestMember = self.smallestMember
+        if smallestMember is None:
+            log.debug("device has no members, size is 0")
+            smallestMemberSize = 0
+        else:
+            smallestMemberSize = smallestMember.size
+
         if self.level == mdraid.RAID0:
             size = self.memberDevices * smallestMemberSize
         elif self.level == mdraid.RAID1:
@@ -3069,10 +3081,11 @@ class MDRaidArrayDevice(StorageDevice):
         elif self.level == mdraid.RAID6:
             size = (self.memberDevices - 2) * smallestMemberSize
         elif self.level == mdraid.RAID10:
-            size = (self.memberDevices / 2.0) * smallestMemberSize
+            size = (self.memberDevices / 2) * smallestMemberSize
         else:
             size = smallestMemberSize
             log.error("unknown RAID level %s" % (self.level))
+
         log.debug("raw RAID %s size == %s" % (self.level, size))
         return size
 
@@ -3083,11 +3096,10 @@ class MDRaidArrayDevice(StorageDevice):
 
     @property
     def smallestMember(self):
-        try:
-            smallest = sorted(self.devices, key=lambda d: d.size)[0]
-        except IndexError:
-            smallest = None
-        return smallest
+        if not self.devices:
+            return None
+        else:
+            return min(self.devices, key=lambda d: d.size)
 
     @property
     def size(self):
@@ -3117,7 +3129,7 @@ class MDRaidArrayDevice(StorageDevice):
                 size = (self.memberDevices - 2) * smallestMemberSize
                 size -= size % self.chunkSize
             elif self.level == mdraid.RAID10:
-                size = (self.memberDevices / 2.0) * smallestMemberSize
+                size = (self.memberDevices / 2) * smallestMemberSize
                 size -= size % self.chunkSize
             log.debug("non-existent RAID %s size == %s" % (self.level, size))
         else:
@@ -3132,6 +3144,8 @@ class MDRaidArrayDevice(StorageDevice):
             levelstr = "stripe"
         elif self.level == mdraid.RAID1:
             levelstr = "mirror"
+        elif self.level is None:
+            levelstr = "unknown level"
         else:
             levelstr = "raid%s" % self.level
 
@@ -3180,10 +3194,10 @@ class MDRaidArrayDevice(StorageDevice):
     @property
     def totalDevices(self):
         """ Total number of devices in the array, including spares. """
-        count = len(self.parents)
         if not self.exists:
-            count = self._totalDevices
-        return count
+            return self._totalDevices
+        else:
+            return len(self.parents)
 
     def _getMemberDevices(self):
         return self._memberDevices
@@ -3467,6 +3481,7 @@ class MDRaidArrayDevice(StorageDevice):
             elif self.level == mdraid.RAID0:
                 formatArgs = ['-R',
                               'stride=%d' % (self.memberDevices * 16)]
+        return formatArgs
 
     @property
     def mediaPresent(self):
diff --git a/tests/devices_test.py b/tests/devices_test.py
new file mode 100644
index 0000000..73ab45c
--- /dev/null
+++ b/tests/devices_test.py
@@ -0,0 +1,386 @@
+#!/usr/bin/python
+
+import unittest
+
+from mock import Mock
+
+import blivet
+
+from blivet.errors import DeviceError
+
+from blivet.devices import Device
+from blivet.devices import MDRaidArrayDevice
+from blivet.devices import mdraid
+
+class MDRaidArrayDeviceTestCase(unittest.TestCase):
+    """Note that these tests postdate the code that they test.
+       Therefore, they capture the behavior of the code as it is now,
+       not necessarily its intended or correct behavior. See the initial
+       commit message for this file for further details.
+    """
+
+    def stateCheck(self, device, **kwargs):
+        """Checks the current state of an mdraid device by means of its
+           fields or properties.
+
+           Every kwarg should be a key which is a field or property
+           of an MDRaidArrayDevice and a value which is a function of
+           two parameters and should call the appropriate assert* functions.
+           These values override those in the state_functions dict.
+
+           If the value is None, then the test starts the debugger instead.
+        """
+        self.longMessage = True
+        state_functions = {
+           "createBitmap" : lambda x,m: self.assertTrue(x, m),
+           "currentSize" : lambda x, m: self.assertEqual(x, 0, m),
+           "description" : lambda x, m: self.assertEqual(x, "MDRAID set (unknown level)", m),
+           "devices" : lambda x, m: self.assertEqual(x, [], m),
+           "exists" : self.assertFalse,
+           "format" : self.assertIsNotNone,
+           "formatArgs" : lambda x, m: self.assertEqual(x, [], m),
+           "formatClass" : self.assertIsNotNone,
+           "isDisk" : self.assertFalse,
+           "level" : self.assertIsNone,
+           "major" : lambda x, m: self.assertEqual(x, 0, m),
+           "mediaPresent" : self.assertFalse,
+           "metadataVersion" : lambda x, m: self.assertEqual(x, "default", m),
+           "minor" : lambda x, m: self.assertEqual(x, 0, m),
+           "parents" : lambda x, m: self.assertEqual(x, [], m),
+           "partitionable" : self.assertFalse,
+           "rawArraySize" : lambda x, m: self.assertEqual(x, 0, m),
+           "size" : lambda x, m: self.assertEqual(x, 0, m),
+           "smallestMember" : lambda x, m: self.assertIsNone(x, m),
+           "spares" : lambda x, m: self.assertEqual(x, 0, m),
+           "superBlockSize" : lambda x, m: self.assertEqual(x, 0, m),
+           "sysfsPath" : lambda x, m: self.assertEqual(x, "", m),
+           "uuid" : self.assertIsNone,
+           "memberDevices" : lambda x, m: self.assertEqual(x, 0, m),
+           "totalDevices" : lambda x, m: self.assertEqual(x, 0, m),
+           "type" : lambda x, m: self.assertEqual(x, "mdarray", m) }
+        for k,v in state_functions.items():
+            if kwargs.has_key(k):
+                key = kwargs[k]
+                if key is None:
+                    import pdb
+                    pdb.set_trace()
+                    getattr(device, k)
+                else:
+                    kwargs[k](getattr(device, k), k)
+            else:
+                v(getattr(device, k), k)
+
+    def setUp(self):
+        self.dev0 = MDRaidArrayDevice("dev0")
+
+        self.dev1 = MDRaidArrayDevice("dev1", level="container")
+        self.dev2 = MDRaidArrayDevice("dev2", level="raid0")
+        self.dev3 = MDRaidArrayDevice("dev3", level="raid1")
+        self.dev4 = MDRaidArrayDevice("dev4", level="raid4")
+        self.dev5 = MDRaidArrayDevice("dev5", level="raid5")
+        self.dev6 = MDRaidArrayDevice("dev6", level="raid6")
+        self.dev7 = MDRaidArrayDevice("dev7", level="raid10")
+
+        self.dev8 = MDRaidArrayDevice("dev8", exists=True)
+        self.dev9 = MDRaidArrayDevice(
+           "dev9",
+           level="raid0",
+           parents=[
+              MDRaidArrayDevice("parent", level="container"),
+              MDRaidArrayDevice("other")])
+
+        self.dev10 = MDRaidArrayDevice(
+           "dev10",
+           level="raid0",
+           size=32)
+
+        self.dev11 = MDRaidArrayDevice(
+           "dev11",
+           level=1,
+           parents=[
+              MDRaidArrayDevice("parent", level="container"),
+              MDRaidArrayDevice("other")],
+           size=32)
+
+        self.dev12 = MDRaidArrayDevice(
+           "dev12",
+           level=1,
+           memberDevices=2,
+           parents=[
+              Mock(**{"type": "mdcontainer",
+                      "size": 4}),
+              Mock(**{"size": 2})],
+           size=32,
+           totalDevices=2)
+
+        self.dev13 = MDRaidArrayDevice(
+           "dev13",
+           level=0,
+           memberDevices=3,
+           parents=[
+              Mock(**{"size": 4}),
+              Mock(**{"size": 2})],
+           size=32,
+           totalDevices=3)
+
+        self.dev14 = MDRaidArrayDevice(
+           "dev14",
+           level=4,
+           memberDevices=3,
+           parents=[
+              Mock(**{"size": 4}),
+              Mock(**{"size": 2}),
+              Mock(**{"size": 2})],
+           totalDevices=3)
+
+        self.dev15 = MDRaidArrayDevice(
+           "dev15",
+           level=5,
+           memberDevices=3,
+           parents=[
+              Mock(**{"size": 4}),
+              Mock(**{"size": 2}),
+              Mock(**{"size": 2})],
+           totalDevices=3)
+
+        self.dev16 = MDRaidArrayDevice(
+           "dev16",
+           level=6,
+           memberDevices=4,
+           parents=[
+              Mock(**{"size": 4}),
+              Mock(**{"size": 4}),
+              Mock(**{"size": 2}),
+              Mock(**{"size": 2})],
+           totalDevices=4)
+
+        self.dev17 = MDRaidArrayDevice(
+           "dev17",
+           level=10,
+           memberDevices=4,
+           parents=[
+              Mock(**{"size": 4}),
+              Mock(**{"size": 4}),
+              Mock(**{"size": 2}),
+              Mock(**{"size": 2})],
+           totalDevices=4)
+
+        self.dev18 = MDRaidArrayDevice(
+           "dev18",
+           level=10,
+           memberDevices=4,
+           parents=[
+              Mock(**{"size": 4}),
+              Mock(**{"size": 4}),
+              Mock(**{"size": 2}),
+              Mock(**{"size": 2})],
+           totalDevices=5)
+
+
+    def testMDRaidArrayDeviceInit(self, *args, **kwargs):
+        """Tests the state of a MDRaidArrayDevice after initialization.
+           For some combinations of arguments the initializer will throw
+           an exception.
+        """
+        self.stateCheck(self.dev0)
+
+
+        ##
+        ## level tests
+        ##
+        self.stateCheck(self.dev1,
+                        description=lambda x, m: self.assertEqual(x, "BIOS RAID container", m),
+                        level=lambda x, m: self.assertEqual(x, "container", m),
+                        type=lambda x, m: self.assertEqual(x, "mdcontainer", m))
+        self.stateCheck(self.dev2,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (stripe)", m),
+                        createBitmap=self.assertFalse,
+                        level=lambda x, m: self.assertEqual(x, 0, m))
+        self.stateCheck(self.dev3,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (mirror)", m),
+                        level=lambda x, m: self.assertEqual(x, 1, m))
+        self.stateCheck(self.dev4,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid4)", m),
+                        level=lambda x, m: self.assertEqual(x, 4, m))
+        self.stateCheck(self.dev5,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid5)", m),
+                        level=lambda x, m: self.assertEqual(x, 5, m))
+        self.stateCheck(self.dev6,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid6)", m),
+                        level=lambda x, m: self.assertEqual(x, 6, m))
+        self.stateCheck(self.dev7,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid10)", m),
+                        level=lambda x, m: self.assertEqual(x, 10, m))
+
+        ##
+        ## existing device tests
+        ##
+        self.stateCheck(self.dev8,
+                        exists=self.assertTrue,
+                        metadataVersion=self.assertIsNone)
+
+
+        ##
+        ## mdbiosraidarray tests
+        ##
+        self.stateCheck(self.dev9,
+                        createBitmap=self.assertFalse,
+                        description=lambda x, m: self.assertEqual(x, "BIOS RAID set (stripe)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 2, m),
+                        isDisk=self.assertTrue,
+                        level=lambda x, m: self.assertEqual(x, 0, m),
+                        mediaPresent=self.assertTrue,
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        partitionable=self.assertTrue,
+                        smallestMember=self.assertIsNotNone,
+                        type = lambda x, m: self.assertEqual(x, "mdbiosraidarray", m))
+
+        ##
+        ## size tests
+        ##
+        self.stateCheck(self.dev10,
+                        createBitmap=self.assertFalse,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (stripe)", m),
+                        level=lambda x, m: self.assertEqual(x, 0, m))
+
+        self.stateCheck(self.dev11,
+                        description=lambda x, m: self.assertEqual(x, "BIOS RAID set (mirror)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 2, m),
+                        isDisk=self.assertTrue,
+                        level=lambda x, m: self.assertEqual(x, 1, m),
+                        mediaPresent=self.assertTrue,
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        partitionable=self.assertTrue,
+                        smallestMember=self.assertIsNotNone,
+                        type=lambda x, m: self.assertEqual(x, "mdbiosraidarray", m))
+
+        ##
+        ## rawArraySize tests
+        ##
+        self.stateCheck(self.dev12,
+                        description=lambda x, m: self.assertEqual(x, "BIOS RAID set (mirror)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 2, m),
+                        isDisk=self.assertTrue,
+                        level=lambda x, m: self.assertEqual(x, 1, m),
+                        mediaPresent=self.assertTrue,
+                        memberDevices=lambda x, m: self.assertEqual(x, 2, m),
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        partitionable=self.assertTrue,
+                        rawArraySize=lambda x, m: self.assertEqual(x, 2, m),
+                        smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 2, m),
+                        type = lambda x, m: self.assertEqual(x, "mdbiosraidarray", m))
+
+        self.stateCheck(self.dev13,
+                        createBitmap=self.assertFalse,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (stripe)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 2, m),
+                        level=lambda x, m: self.assertEqual(x, 0, m),
+                        memberDevices=lambda x, m: self.assertEqual(x, 3, m),
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        rawArraySize=lambda x, m: self.assertEqual(x, 6, m),
+                        size=lambda x, m: self.assertEqual(x, 6, m),
+                        smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 3, m))
+
+        self.stateCheck(self.dev14,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid4)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 3, m),
+                        level=lambda x, m: self.assertEqual(x, 4, m),
+                        memberDevices=lambda x, m: self.assertEqual(x, 3, m),
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
+                        size=lambda x, m: self.assertEqual(x, 4, m),
+                        smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 3, m))
+
+        self.stateCheck(self.dev15,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid5)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 3, m),
+                        level=lambda x, m: self.assertEqual(x, 5, m),
+                        memberDevices=lambda x, m: self.assertEqual(x, 3, m),
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
+                        size=lambda x, m: self.assertEqual(x, 4, m),
+                        smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 3, m))
+
+        self.stateCheck(self.dev16,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid6)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 4, m),
+                        level=lambda x, m: self.assertEqual(x, 6, m),
+                        memberDevices=lambda x, m: self.assertEqual(x, 4, m),
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
+                        size=lambda x, m: self.assertEqual(x, 4, m),
+                        smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 4, m))
+
+        self.stateCheck(self.dev17,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid10)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 4, m),
+                        level=lambda x, m: self.assertEqual(x, 10, m),
+                        memberDevices=lambda x, m: self.assertEqual(x, 4, m),
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
+                        size=lambda x, m: self.assertEqual(x, 4, m),
+                        smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 4, m))
+
+        self.stateCheck(self.dev18,
+                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid10)", m),
+                        devices=lambda x, m: self.assertEqual(len(x), 4, m),
+                        level=lambda x, m: self.assertEqual(x, 10, m),
+                        memberDevices=lambda x, m: self.assertEqual(x, 4, m),
+                        parents=lambda x, m: self.assertNotEqual(x, [], m),
+                        rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
+                        size=lambda x, m: self.assertEqual(x, 4, m),
+                        smallestMember=self.assertIsNotNone,
+                        spares=lambda x, m: self.assertEqual(x, 1, m),
+                        totalDevices=lambda x, m: self.assertEqual(x, 5, m))
+
+        self.assertRaisesRegexp(mdraid.MDRaidError,
+                                "invalid raid level",
+                                MDRaidArrayDevice,
+                                "dev",
+                                level="raid2")
+
+        self.assertRaisesRegexp(mdraid.MDRaidError,
+                                "invalid raid level",
+                                MDRaidArrayDevice,
+                                "dev",
+                                parents=[Device("parent")])
+
+        self.assertRaisesRegexp(DeviceError,
+                                "A RAID0 set requires at least 2 members",
+                                MDRaidArrayDevice,
+                                "dev",
+                                level="raid0",
+                                parents=[Device("parent")])
+
+        self.assertRaisesRegexp(mdraid.MDRaidError,
+                                "invalid raid level descriptor junk",
+                                MDRaidArrayDevice,
+                                "dev",
+                                level="junk")
+
+        self.assertRaisesRegexp(ValueError,
+                                "memberDevices cannot be greater than totalDevices",
+                                MDRaidArrayDevice,
+                                "dev",
+                                memberDevices=2)
+
+
+    def testMDRaidArrayDeviceMethods(self, *args, **kwargs):
+        """Test for method calls on initialized MDRaidDevices."""
+        with self.assertRaisesRegexp(mdraid.MDRaidError, "invalid raid level" ):
+            self.dev7.level = "junk"
+
+
+def suite():
+    return unittest.TestLoader().loadTestsFromTestCase(MDRaidArrayDeviceTestCase)
+
+
+if __name__ == "__main__":
+    unittest.main()
+
-- 
1.8.3.1



More information about the anaconda-patches mailing list