def test_transition_fs_sync_cow_full(self): scratch = "{}/scratch".format(self.mount) falloc = 50 self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path, fallocated_space=falloc), 0) self.addCleanup(dattobd.destroy, self.minor) util.dd("/dev/zero", scratch, falloc + 10, bs="1M") self.addCleanup(os.remove, scratch) # Possible errors doing this: # * EINVAL: The file system already performed the sync # * EFBIG: The module performed the sync # We want the former to happen, so make the OS sync everything. os.sync() self.assertEqual(dattobd.transition_to_incremental(self.minor), errno.EINVAL) snapdev = dattobd.info(self.minor) self.assertIsNotNone(snapdev) self.assertEqual(snapdev["error"], -errno.EFBIG) self.assertEqual(snapdev["state"], 3)
def test_transition_mod_sync_cow_full(self): scratch = "{}/scratch".format(self.mount) falloc = 50 self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path, fallocated_space=falloc), 0) self.addCleanup(dattobd.destroy, self.minor) util.dd("/dev/zero", scratch, falloc + 10, bs="1M") self.addCleanup(os.remove, scratch) # Possible errors doing this: # * EINVAL: The file system already performed the sync # * EFBIG: The module performed the sync # We want the later to happen, so try to transition without calling sync. err = dattobd.transition_to_incremental(self.minor) if (err != errno.EFBIG): self.skipTest("Kernel flushed before module") snapdev = dattobd.info(self.minor) self.assertIsNotNone(snapdev) self.assertEqual(snapdev["error"], -errno.EFBIG) self.assertEqual(snapdev["state"], 2)
def test_destroy_active_snapshot(self): self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), 0) self.assertEqual(dattobd.destroy(self.minor), 0) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_destroy_active_incremental(self): self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), 0) self.assertEqual(dattobd.transition_to_incremental(self.minor), 0) self.assertEqual(dattobd.destroy(self.minor), 0) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_setup_readonly_volume(self): util.mount(self.device, self.mount, opts="remount,ro") self.addCleanup(util.mount, self.device, self.mount, opts="remount,rw") self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), errno.EINVAL) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_destroy_unverified_incremental(self): util.unmount(self.mount) self.addCleanup(util.mount, self.device, self.mount) self.assertEqual( dattobd.reload_incremental(self.minor, self.device, self.cow_reload_path), 0) self.assertEqual(dattobd.destroy(self.minor), 0) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_setup_already_tracked_volume(self): self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), 0) self.addCleanup(dattobd.destroy, self.minor) self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), errno.EBUSY) self.assertTrue(os.path.exists(self.snap_device)) self.assertIsNotNone(dattobd.info(self.minor))
def test_destroy_dormant_snapshot(self): self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), 0) util.unmount(self.mount) self.addCleanup(os.remove, self.cow_full_path) self.addCleanup(util.mount, self.device, self.mount) self.assertEqual(dattobd.destroy(self.minor), 0) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_track_writes(self): testfile = "{}/testfile".format(self.mount) self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), 0) self.addCleanup(dattobd.destroy, self.minor) os.sync() info = dattobd.info(self.minor) start_nr = info["nr_changed_blocks"] self.assertNotEqual(start_nr, 0) with open(testfile, "w") as f: f.write("The quick brown fox") self.addCleanup(os.remove, testfile) os.sync() info = dattobd.info(self.minor) end_nr = info["nr_changed_blocks"] self.assertGreater(end_nr, start_nr)
def test_setup_volume(self): self.assertEqual( dattobd.setup(self.minor, self.device, self.cow_full_path), 0) self.addCleanup(dattobd.destroy, self.minor) self.assertTrue(os.path.exists(self.snap_device)) snapdev = dattobd.info(self.minor) self.assertIsNotNone(snapdev) self.assertEqual(snapdev["error"], 0) self.assertEqual(snapdev["state"], 3) self.assertEqual(snapdev["cow"], "/{}".format(self.cow_file)) self.assertEqual(snapdev["bdev"], self.device) self.assertEqual(snapdev["version"], 1)
def test_transition_nonexistent_snapshot(self): self.assertIsNone(dattobd.info(self.minor)) self.assertEqual(dattobd.transition_to_incremental(self.minor), errno.ENOENT)
def test_setup_cow_file_on_wrong_device(self): self.assertEqual( dattobd.setup(self.minor, self.device, "/tmp/{}".format(self.cow_file)), errno.EINVAL) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_setup_cow_file_path_is_dir(self): self.assertEqual(dattobd.setup(self.minor, self.device, self.mount), errno.EISDIR) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_setup_volume_path_is_dir(self): self.assertEqual( dattobd.setup(self.minor, self.mount, self.cow_full_path), errno.ENOTBLK) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))
def test_setup_invalid_minor(self): self.assertEqual(dattobd.setup(1000, self.device, self.cow_full_path), errno.EINVAL) self.assertFalse(os.path.exists(self.snap_device)) self.assertIsNone(dattobd.info(self.minor))