From 0db5a4dcdf25ee68a3f2d63a2bcc387ad3859cd3 Mon Sep 17 00:00:00 2001
From: David Lehman <dlehman@redhat.com>
Date: Fri, 16 May 2014 11:18:41 -0500
Subject: [PATCH 16/18] Add tests for snapshots.

---
 tests/devices_test.py    | 121 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/devicetree_test.py |  41 ++++++++++++++++
 2 files changed, 162 insertions(+)

diff --git a/tests/devices_test.py b/tests/devices_test.py
index 6598eba..e2ea29d 100644
--- a/tests/devices_test.py
+++ b/tests/devices_test.py
@@ -10,8 +10,15 @@ import blivet
 from blivet.errors import DeviceError
 from blivet.errors import MDRaidError
 
+from blivet.devices import BTRFSSnapShotDevice
 from blivet.devices import BTRFSSubVolumeDevice
 from blivet.devices import BTRFSVolumeDevice
+from blivet.devices import LVMLogicalVolumeDevice
+from blivet.devices import LVMSnapShotDevice
+from blivet.devices import LVMThinPoolDevice
+from blivet.devices import LVMThinLogicalVolumeDevice
+from blivet.devices import LVMThinSnapShotDevice
+from blivet.devices import LVMVolumeGroupDevice
 from blivet.devices import MDRaidArrayDevice
 from blivet.devices import OpticalDevice
 from blivet.devices import StorageDevice
@@ -486,6 +493,11 @@ class BTRFSDeviceTestCase(DeviceStateTestCase):
            BTRFSSubVolumeDevice,
            "dev1", parents=parents)
 
+        self.assertEqual(self.dev1.isleaf, False)
+        self.assertEqual(self.dev2.isleaf, True)
+        member = self.dev1.parents[0]
+        self.assertEqual(member.isleaf, False)
+
     def testBTRFSDeviceMethods(self):
         """Test for method calls on initialized BTRFS Devices."""
         # volumes do not have ancestor volumes
@@ -503,6 +515,115 @@ class BTRFSDeviceTestCase(DeviceStateTestCase):
            "cannot directly set size of btrfs volume"):
             self.dev1.size = 32
 
+    def testBTRFSSnapShotDeviceInit(self):
+        parents = [StorageDevice("p1", fmt=blivet.formats.getFormat("btrfs"))]
+        vol = BTRFSVolumeDevice("test", parents=parents)
+        self.assertRaisesRegexp(ValueError,
+                                "non-existent btrfs snapshots must have a source",
+                                BTRFSSnapShotDevice,
+                                "snap1", parents=[vol])
+
+        self.assertRaisesRegexp(ValueError,
+                                "btrfs snapshot source must already exist",
+                                BTRFSSnapShotDevice,
+                                "snap1", parents=[vol], source=vol)
+
+        self.assertRaisesRegexp(ValueError,
+                                "btrfs snapshot source must be a btrfs subvolume",
+                                BTRFSSnapShotDevice,
+                                "snap1", parents=[vol], source=parents[0])
+
+        parents2 = [StorageDevice("p1", fmt=blivet.formats.getFormat("btrfs"))]
+        vol2 = BTRFSVolumeDevice("test2", parents=parents2, exists=True)
+        self.assertRaisesRegexp(ValueError,
+                                ".*snapshot and source must be in the same volume",
+                                BTRFSSnapShotDevice,
+                                "snap1", parents=[vol], source=vol2)
+
+        vol.exists = True
+        snap = BTRFSSnapShotDevice("snap1", parents=[vol], source=vol)
+        self.assertEqual(snap.isleaf, True)
+        self.assertEqual(vol.isleaf, False)
+
+        self.assertEqual(snap.dependsOn(vol), True)
+        self.assertEqual(vol.dependsOn(snap), False)
+
+class LVMDeviceTest(unittest.TestCase):
+    def testLVMSnapShotDeviceInit(self):
+        pv = StorageDevice("pv1", fmt=blivet.formats.getFormat("lvmpv"),
+                           size=Size("1 GiB"))
+        vg = LVMVolumeGroupDevice("testvg", parents=[pv])
+        lv = LVMLogicalVolumeDevice("testlv", parents=[vg],
+                                    fmt=blivet.formats.getFormat("xfs"))
+
+        self.assertRaisesRegexp(ValueError,
+                                "lvm snapshot devices require an origin lv",
+                                LVMSnapShotDevice,
+                                "snap1", parents=[vg])
+
+        self.assertRaisesRegexp(ValueError,
+                                "lvm snapshot origin volume must already exist",
+                                LVMSnapShotDevice,
+                                "snap1", parents=[vg], origin=lv)
+
+        self.assertRaisesRegexp(ValueError,
+                                "lvm snapshot origin must be a logical volume",
+                                LVMSnapShotDevice,
+                                "snap1", parents=[vg], origin=pv)
+
+        self.assertRaisesRegexp(ValueError,
+                                "only existing vorigin snapshots are supported",
+                                LVMSnapShotDevice,
+                                "snap1", parents=[vg], vorigin=True)
+
+        lv.exists = True
+        snap1 = LVMSnapShotDevice("snap1", parents=[vg], origin=lv)
+
+        self.assertEqual(snap1.format, lv.format)
+        snap1.format = blivet.formats.getFormat("DM_snapshot_cow", exists=True)
+        self.assertEqual(snap1.format, lv.format)
+
+        self.assertEqual(snap1.isleaf, True)
+        self.assertEqual(lv.isleaf, False)
+
+        self.assertEqual(snap1.dependsOn(lv), True)
+        self.assertEqual(lv.dependsOn(snap1), False)
+
+    def testLVMThinSnapShotDeviceInit(self):
+        pv = StorageDevice("pv1", fmt=blivet.formats.getFormat("lvmpv"),
+                           size=Size("1 GiB"))
+        vg = LVMVolumeGroupDevice("testvg", parents=[pv])
+        pool = LVMThinPoolDevice("pool1", parents=[vg], size=Size("500 MiB"))
+        thinlv = LVMThinLogicalVolumeDevice("thinlv", parents=[pool],
+                                            size=Size("200 MiB"))
+
+        self.assertRaisesRegexp(ValueError,
+                                "lvm thin snapshots require an origin",
+                                LVMThinSnapShotDevice,
+                                "snap1", parents=[pool])
+
+        self.assertRaisesRegexp(ValueError,
+                                "lvm snapshot origin volume must already exist",
+                                LVMThinSnapShotDevice,
+                                "snap1", parents=[pool], origin=thinlv)
+
+        self.assertRaisesRegexp(ValueError,
+                                "lvm snapshot origin must be a logical volume",
+                                LVMThinSnapShotDevice,
+                                "snap1", parents=[pool], origin=pv)
+
+        # now make the constructor succeed so we can test some properties
+        thinlv.exists = True
+        snap1 = LVMThinSnapShotDevice("snap1", parents=[pool], origin=thinlv)
+        self.assertEqual(snap1.isleaf, True)
+        self.assertEqual(thinlv.isleaf, True)
+
+        self.assertEqual(snap1.dependsOn(thinlv), True)
+        self.assertEqual(thinlv.dependsOn(snap1), False)
+
+        snap1.exists = True
+        self.assertEqual(snap1.dependsOn(thinlv), False)
+
 class DeviceNameTestCase(unittest.TestCase):
     """Test device name validation"""
 
diff --git a/tests/devicetree_test.py b/tests/devicetree_test.py
index b0105f9..004afca 100644
--- a/tests/devicetree_test.py
+++ b/tests/devicetree_test.py
@@ -8,6 +8,7 @@ from blivet import devicelibs
 from blivet import devicefactory
 from blivet import util
 from blivet.udev import udev_trigger
+from blivet.devices import LVMSnapShotDevice, LVMThinSnapShotDevice
 
 """
     TODO:
@@ -137,6 +138,27 @@ class LVMTestCase(BlivetResetTestCase):
                                   None,
                                   disks=self.blivet.disks[:])
 
+class LVMSnapShotTestCase(BlivetResetTestCase):
+    def _set_up_storage(self):
+        self.blivet.factoryDevice(devicefactory.DEVICE_TYPE_LVM,
+                                  Size("1 GiB"),
+                                  label="ROOT",
+                                  disks=self.blivet.disks[:],
+                                  container_name="blivet_test",
+                                  container_size=devicefactory.SIZE_POLICY_MAX)
+
+    def setUp(self):
+        super(BlivetResetTestCase, self).setUp() # pylint: disable=bad-super-call
+        root = self.blivet.lvs[0]
+        snap = LVMSnapShotDevice("rootsnap1", parents=[root.vg], origin=root,
+                                 size=Size("768MiB"))
+        self.blivet.createDevice(snap)
+        self.blivet.doIt()
+
+        self.device_attr_dicts = []
+        self.collect_expected_data()
+
+
 class LVMThinpTestCase(BlivetResetTestCase):
     def _set_up_storage(self):
         self.blivet.factoryDevice(devicefactory.DEVICE_TYPE_LVM,
@@ -148,6 +170,25 @@ class LVMThinpTestCase(BlivetResetTestCase):
                                   label="ROOT",
                                   disks=self.blivet.disks[:])
 
+class LVMThinSnapShotTestCase(LVMThinpTestCase):
+    def _set_up_storage(self):
+        self.blivet.factoryDevice(devicefactory.DEVICE_TYPE_LVM_THINP,
+                                  Size("1 GiB"),
+                                  label="ROOT",
+                                  disks=self.blivet.disks[:])
+
+    def setUp(self):
+        super(BlivetResetTestCase, self).setUp() # pylint: disable=bad-super-call
+
+        root = self.blivet.thinlvs[0]
+        snap = LVMThinSnapShotDevice("rootsnap1", parents=[root.pool],
+                                     origin=root)
+        self.blivet.createDevice(snap)
+        self.blivet.doIt()
+
+        self.device_attr_dicts = []
+        self.collect_expected_data()
+
 class LVMRaidTestCase(BlivetResetTestCase):
     def _set_up_storage(self):
         # This isn't exactly autopart, but it should be plenty close to it.
-- 
1.9.0

