def test_restore_large_file(self): """This file should take more than one block to save, so it tests routines that must operate on multiple blocks. """ infile = self.create_file("bigfile", "") block = b"\0" * 1024 * 1024 h = hashlib.md5() with infile.open("wb") as f: for _ in range(50): h.update(block) f.write(block) scan.scan() backup.backup() ss = models.Snapshot.objects.get() restore.restore_item(ss.root, self.restoredir, self.key) outfile = pathlib.Path(self.restoredir, "bigfile") h2 = hashlib.md5() with outfile.open("rb") as f: while True: a = f.read(64 * 2**10) if not a: break h2.update(a) self.assertEqual(h.hexdigest(), h2.hexdigest())
def test_restore_multiple_revisions(self): self.create_file("file", "contents A") scan.scan() backup.backup() self.create_file("file", "new contents") scan.scan() backup.backup() snapshots = list(models.Snapshot.objects.order_by("date")) self.assertEqual(2, len(snapshots)) self.assertEqual(6, models.Object.objects.count()) restoredir = pathlib.Path(self.restoredir) restore.restore_item(snapshots[0].root, restoredir / "ss1", self.key) restore.restore_item(snapshots[1].root, restoredir / "ss2", self.key) file1 = restoredir / "ss1" / "file" file2 = restoredir / "ss2" / "file" self.assertEqual("contents A", file1.read_text()) self.assertEqual("new contents", file2.read_text())
def test_restore_time_dir(self): dir_a = pathlib.Path(self.backupdir, "dir1") dir_a.mkdir() os.utime(dir_a, ns=(123456789, 987654321)) scan.scan() backup.backup() ss = models.Snapshot.objects.get() # The directory atime gets reset before we back it up, so just check # that whatever value it had when it was backed up, that's what gets # restored. tree = ss.root.children.get() info = list(models.Object.unpack_payload(tree.payload))[1] atime = info['atime'] restore.restore_item(ss.root, self.restoredir, self.key) dir1 = pathlib.Path(self.restoredir, "dir1") stat_result = dir1.stat() self.assertEqual( 987654321, stat_result.st_mtime_ns, ) self.assertEqual( atime, stat_result.st_atime_ns, )
def test_simple_restore(self): self.create_file("file1", "contents1") self.create_file("dir/file2", "contents2") scan.scan() backup.backup() ss = models.Snapshot.objects.get() restore.restore_item(ss.root, self.restoredir, self.key) self.assert_restored_file("file1", "contents1") self.assert_restored_file("dir/file2", "contents2")
def test_restore_invalid_utf8_filename(self): name = os.fsdecode(b"\xFF\xFFHello\xFF\xFF") self.assertRaises(UnicodeEncodeError, name.encode, "utf-8") self.create_file(name, "contents") scan.scan() backup.backup() ss = models.Snapshot.objects.get() restore.restore_item(ss.root, self.restoredir, self.key)
def test_restore_mode(self): file_a = self.create_file("file1", "contents") file_a.chmod(0o777) scan.scan() backup.backup() ss = models.Snapshot.objects.get() restore.restore_item(ss.root, self.restoredir, self.key) file_b = pathlib.Path(self.restoredir, "file1") stat_result = file_b.stat() self.assertEqual( 0o777, stat.S_IMODE(stat_result.st_mode), )
def test_restore_single_file(self): self.create_file("file", "contents") scan.scan() backup.backup() root = models.Snapshot.objects.get().root # Should just be one child inode = root.children.get() filename = pathlib.Path(self.restoredir, "my_file") restore.restore_item(inode, filename, self.key) self.assertEqual("contents", filename.read_text())
def test_restore_uid_gid(self): file_a = self.create_file("file1", "contents") try: os.chown(file_a, 1, 1) except PermissionError: raise unittest.SkipTest("Process doesn't have chown permission") scan.scan() backup.backup() ss = models.Snapshot.objects.get() restore.restore_item(ss.root, self.restoredir, self.key) file_b = pathlib.Path(self.restoredir, "file1") stat_result = file_b.stat() self.assertEqual(1, stat_result.st_uid) self.assertEqual(1, stat_result.st_gid)
def test_restore_time(self): file_a = self.create_file("file1", "contents") os.utime(file_a, ns=(123456789, 987654321)) scan.scan() backup.backup() ss = models.Snapshot.objects.get() restore.restore_item(ss.root, self.restoredir, self.key) file_b = pathlib.Path(self.restoredir, "file1") stat_result = file_b.stat() self.assertEqual( 123456789, stat_result.st_atime_ns, ) self.assertEqual( 987654321, stat_result.st_mtime_ns, )