def make_dirs(self): """Make two input directories""" d1 = self.root_rp.append("hashtest1") re_init_rpath_dir(d1) d2 = self.root_rp.append("hashtest2") re_init_rpath_dir(d2) d1f1 = d1.append("file1") d1f1.write_string(self.s1) d1f1l = d1.append("file1_linked") d1f1l.hardlink(d1f1.path) d1f2 = d1.append("file2") d1f2.write_string(self.s2) d1f2l = d1.append("file2_linked") d1f2l.hardlink(d1f2.path) d1_hashlist = [ None, self.s1_hash, self.s1_hash, self.s2_hash, self.s2_hash ] d2f1 = d2.append("file1") rpath.copy_with_attribs(d1f1, d2f1) d2f1l = d2.append("file1_linked") d2f1l.write_string(self.s3) d1f2 = d2.append("file2") d1f2.mkdir() d2_hashlist = [None, self.s1_hash, self.s3_hash, None] return (d1, d1_hashlist, d2, d2_hashlist)
def _compare_at_time(self, t): """Restore file, make sure it is the same at time t""" log.Log("Checking result at time %s" % (t, ), 7) tf = tempdir.get_temp_rpath() restore.MirrorStruct._mirror_time = mirror_time restore.MirrorStruct._rest_time = t self.rf.set_relevant_incs() out_rorpath = self.rf.get_attribs().getRORPath() correct_result = self.time_rp_dict[t] if out_rorpath.isreg(): out_rorpath.setfile(self.rf.get_restore_fp()) rpath.copy_with_attribs(out_rorpath, tf) if not tf._equal_verbose(correct_result, check_index=0): return ("Restored file {rest!s} isn't same " "as original file {orig!s}.".format(rest=tf, orig=correct_result)) if tf.isreg(): with tf.open("rb") as tf_fd, correct_result.open("rb") as corr_fd: if not rpath._cmp_file_obj(tf_fd, corr_fd): return ("Content of restored file {rest!s} isn't same " "as original file {orig!s}.".format( rest=tf, orig=correct_result)) if tf.lstat(): tf.delete() return () # no error found
def end_process_directory(self): """Finish processing a directory""" rf = self.rf if rf.metadata_rorp.isdir(): if rf.mirror_rp.isdir(): rf.mirror_rp.setdata() if not rf.metadata_rorp.equal_loose(rf.mirror_rp): log.Log("Regressing attributes of path {pa}".format(pa=rf), log.INFO) rpath.copy_attribs(rf.metadata_rorp, rf.mirror_rp) else: rf.mirror_rp.delete() log.Log("Regressing file {fi}".format(fi=rf.mirror_rp), log.INFO) rpath.copy_with_attribs(rf.metadata_rorp, rf.mirror_rp) else: # replacing a dir with some other kind of file assert rf.mirror_rp.isdir(), ( "Mirror '{mrp!r}' can only be a directory.".format( mrp=rf.mirror_rp)) log.Log("Replacing directory {di}".format(di=rf), log.INFO) if rf.metadata_rorp.isreg(): self._restore_orig_regfile(rf) else: rf.mirror_rp.delete() rpath.copy_with_attribs(rf.metadata_rorp, rf.mirror_rp) if rf.regress_inc: log.Log("Deleting increment {ic}".format(ic=rf), log.INFO) rf.regress_inc.delete()
def testCopyWithAttribs(self): """Test copying with attribs (bug found earlier)""" out = RPath(self.lc, self.mainprefix, ("out",)) if out.lstat(): out.delete() for rp in [self.noperms, self.nowrite, self.rf, self.exec1, self.exec2, self.hl1, self.dir, self.sym]: rpath.copy_with_attribs(rp, out) assert rpath.cmp(rp, out) assert rp.equal_loose(out) out.delete()
def _set_dir_replacement(self, diff_rorp, base_rp): """Set self.dir_replacement, which holds data until done with dir This is used when base_rp is a dir, and diff_rorp is not. """ assert diff_rorp.get_attached_filetype() == 'snapshot', ( "File '{drp!r}' must be of type '{dtype}'.".format( drp=diff_rorp, dtype='snapshot')) self.dir_replacement = base_rp.get_temp_rpath(sibling=True) rpath.copy_with_attribs(diff_rorp, self.dir_replacement) if base_rp.isdir(): base_rp.chmod(0o700)
def testCtime(self): """Check to see if ctime read, compared""" rp = rpath.RPath(self.lc, self.prefix, ("ctimetest.1", )) rp2 = rpath.RPath(self.lc, self.prefix, ("ctimetest.2", )) rp.touch() rp.chmod(0o700) rpath.copy_with_attribs(rp, rp2) assert rpath.cmp_attribs(rp, rp2) time.sleep(1) rp2.chmod(0o755) rp2.chmod(0o700) rp2.setdata() assert rp2.getctime() > rp.getctime() assert not rpath.cmp_attribs(rp, rp2) rp.delete() rp2.delete()
def testCtime(self): """Check to see if ctime read, compared""" rp = rpath.RPath(self.lc, self.prefix, ("ctimetest.1", )) rp2 = rpath.RPath(self.lc, self.prefix, ("ctimetest.2", )) rp.touch() rp.chmod(0o700) rpath.copy_with_attribs(rp, rp2) self.assertTrue(rpath._cmp_file_attribs(rp, rp2)) time.sleep(1) rp2.chmod(0o755) rp2.chmod(0o700) rp2.setdata() self.assertGreater(rp2.getctime(), rp.getctime()) self.assertFalse(rpath._cmp_file_attribs(rp, rp2)) rp.delete() rp2.delete()
def compare_at_time(self, t): """Restore file, make sure it is the same at time t""" log.Log("Checking result at time %s" % (t,), 7) tf = TempFile.new(tempdir.append("foo")) restore.MirrorStruct._mirror_time = mirror_time restore.MirrorStruct._rest_time = t self.rf.set_relevant_incs() out_rorpath = self.rf.get_attribs().getRORPath() correct_result = self.time_rp_dict[t] if out_rorpath.isreg(): out_rorpath.setfile(self.rf.get_restore_fp()) rpath.copy_with_attribs(out_rorpath, tf) assert tf.equal_verbose(correct_result, check_index = 0), \ "%s, %s" % (tf, correct_result) if tf.isreg(): assert rpath.cmpfileobj(tf.open("rb"), correct_result.open("rb")) if tf.lstat(): tf.delete()
def _make_snapshot_increment(mirror, incpref, inc_time): """Copy mirror to incfile, since new is quite different""" compress = _is_compressed(mirror) if compress and mirror.isreg(): snapshotrp = get_inc(incpref, b"snapshot.gz", inc_time) else: snapshotrp = get_inc(incpref, b"snapshot", inc_time) if mirror.isspecial(): # check for errors when creating special increments eh = robust.get_error_handler("SpecialFileError") if robust.check_common_error(eh, rpath.copy_with_attribs, (mirror, snapshotrp, compress)) == 0: snapshotrp.setdata() if snapshotrp.lstat(): snapshotrp.delete() snapshotrp.touch() else: rpath.copy_with_attribs(mirror, snapshotrp, compress) return snapshotrp
def fast_process_file(self, index, rf): """Process when nothing is a directory""" if not rf.metadata_rorp.equal_loose(rf.mirror_rp): log.Log("Regressing file {fi}".format(fi=rf.metadata_rorp), log.INFO) if rf.metadata_rorp.isreg(): self._restore_orig_regfile(rf) else: if rf.mirror_rp.lstat(): rf.mirror_rp.delete() if rf.metadata_rorp.isspecial(): robust.check_common_error(None, rpath.copy_with_attribs, (rf.metadata_rorp, rf.mirror_rp)) else: rpath.copy_with_attribs(rf.metadata_rorp, rf.mirror_rp) if rf.regress_inc: log.Log("Deleting increment {ic}".format(ic=rf.regress_inc), log.INFO) rf.regress_inc.delete()
def _set_dir_replacement(self, diff_rorp, base_rp): """Set self.dir_replacement, which holds data until done with dir This is used when base_rp is a dir, and diff_rorp is not. Returns 1 for success or 0 for failure """ assert diff_rorp.get_attached_filetype() == 'snapshot', ( "Type attached to '{rp}' isn't '{exp}' but '{att}'.".format( rp=diff_rorp, exp="snapshot", att=diff_rorp.get_attached_filetype())) self.dir_replacement = base_rp.get_temp_rpath(sibling=True) if not self._patch_to_temp(None, diff_rorp, self.dir_replacement): if self.dir_replacement.lstat(): self.dir_replacement.delete() # Was an error, so now restore original directory rpath.copy_with_attribs( self.CCPP.get_mirror_rorp(diff_rorp.index), self.dir_replacement) return 0 else: return 1
def testInnerRestore(self): """Restore part of a dir, see if hard links preserved""" MakeOutputDir() output = rpath.RPath(Globals.local_connection, abs_output_dir) hlout1_dir = os.path.join(abs_test_dir, b"out_hardlink1") hlout2_dir = os.path.join(abs_test_dir, b"out_hardlink2") # Now set up directories out_hardlink1 and out_hardlink2 hlout1 = rpath.RPath(Globals.local_connection, hlout1_dir) if hlout1.lstat(): hlout1.delete() hlout1.mkdir() hlout1_sub = hlout1.append("subdir") hlout1_sub.mkdir() hl1_1 = hlout1_sub.append("hardlink1") hl1_2 = hlout1_sub.append("hardlink2") hl1_3 = hlout1_sub.append("hardlink3") hl1_4 = hlout1_sub.append("hardlink4") # 1 and 2 are hard linked, as are 3 and 4 hl1_1.touch() hl1_2.hardlink(hl1_1.path) hl1_3.touch() hl1_4.hardlink(hl1_3.path) hlout2 = rpath.RPath(Globals.local_connection, hlout2_dir) if hlout2.lstat(): hlout2.delete() xcopytree(hlout1_dir, hlout2_dir) hlout2_sub = hlout2.append("subdir") hl2_1 = hlout2_sub.append("hardlink1") hl2_2 = hlout2_sub.append("hardlink2") hl2_3 = hlout2_sub.append("hardlink3") hl2_4 = hlout2_sub.append("hardlink4") # Now 2 and 3 are hard linked, also 1 and 4 rpath.copy_with_attribs(hl1_1, hl2_1) rpath.copy_with_attribs(hl1_2, hl2_2) hl2_3.delete() hl2_3.hardlink(hl2_2.path) hl2_4.delete() hl2_4.hardlink(hl2_1.path) rpath.copy_attribs(hlout1_sub, hlout2_sub) # Now try backing up twice, making sure hard links are preserved InternalBackup(1, 1, hlout1.path, output.path) out_subdir = output.append("subdir") self.assertEqual( out_subdir.append("hardlink1").getinode(), out_subdir.append("hardlink2").getinode()) self.assertEqual( out_subdir.append("hardlink3").getinode(), out_subdir.append("hardlink4").getinode()) self.assertNotEqual( out_subdir.append("hardlink1").getinode(), out_subdir.append("hardlink3").getinode()) time.sleep(1) InternalBackup(1, 1, hlout2.path, output.path) out_subdir.setdata() self.assertEqual( out_subdir.append("hardlink1").getinode(), out_subdir.append("hardlink4").getinode()) self.assertEqual( out_subdir.append("hardlink2").getinode(), out_subdir.append("hardlink3").getinode()) self.assertNotEqual( out_subdir.append("hardlink1").getinode(), out_subdir.append("hardlink2").getinode()) # Now try restoring, still checking hard links. sub_dir = os.path.join(abs_output_dir, b"subdir") out2_dir = os.path.join(abs_test_dir, b"out2") out2 = rpath.RPath(Globals.local_connection, out2_dir) hlout1 = out2.append("hardlink1") hlout2 = out2.append("hardlink2") hlout3 = out2.append("hardlink3") hlout4 = out2.append("hardlink4") if out2.lstat(): out2.delete() InternalRestore(1, 1, sub_dir, out2_dir, 1) out2.setdata() for rp in [hlout1, hlout2, hlout3, hlout4]: rp.setdata() self.assertEqual(hlout1.getinode(), hlout2.getinode()) self.assertEqual(hlout3.getinode(), hlout4.getinode()) self.assertNotEqual(hlout1.getinode(), hlout3.getinode()) if out2.lstat(): out2.delete() InternalRestore(1, 1, sub_dir, out2_dir, int(time.time())) out2.setdata() for rp in [hlout1, hlout2, hlout3, hlout4]: rp.setdata() self.assertEqual(hlout1.getinode(), hlout4.getinode()) self.assertEqual(hlout2.getinode(), hlout3.getinode()) self.assertNotEqual(hlout1.getinode(), hlout2.getinode())
def testInnerRestore(self): """Restore part of a dir, see if hard links preserved""" MakeOutputDir() output = rpath.RPath(Globals.local_connection, "testfiles/output") # Now set up directories out_hardlink1 and out_hardlink2 hlout1 = rpath.RPath(Globals.local_connection, "testfiles/out_hardlink1") if hlout1.lstat(): hlout1.delete() hlout1.mkdir() hlout1_sub = hlout1.append("subdir") hlout1_sub.mkdir() hl1_1 = hlout1_sub.append("hardlink1") hl1_2 = hlout1_sub.append("hardlink2") hl1_3 = hlout1_sub.append("hardlink3") hl1_4 = hlout1_sub.append("hardlink4") # 1 and 2 are hard linked, as are 3 and 4 hl1_1.touch() hl1_2.hardlink(hl1_1.path) hl1_3.touch() hl1_4.hardlink(hl1_3.path) hlout2 = rpath.RPath(Globals.local_connection, "testfiles/out_hardlink2") if hlout2.lstat(): hlout2.delete() assert not os.system("cp -a testfiles/out_hardlink1 " "testfiles/out_hardlink2") hlout2_sub = hlout2.append("subdir") hl2_1 = hlout2_sub.append("hardlink1") hl2_2 = hlout2_sub.append("hardlink2") hl2_3 = hlout2_sub.append("hardlink3") hl2_4 = hlout2_sub.append("hardlink4") # Now 2 and 3 are hard linked, also 1 and 4 rpath.copy_with_attribs(hl1_1, hl2_1) rpath.copy_with_attribs(hl1_2, hl2_2) hl2_3.delete() hl2_3.hardlink(hl2_2.path) hl2_4.delete() hl2_4.hardlink(hl2_1.path) rpath.copy_attribs(hlout1_sub, hlout2_sub) # Now try backing up twice, making sure hard links are preserved InternalBackup(1, 1, hlout1.path, output.path) out_subdir = output.append("subdir") assert out_subdir.append("hardlink1").getinode() == \ out_subdir.append("hardlink2").getinode() assert out_subdir.append("hardlink3").getinode() == \ out_subdir.append("hardlink4").getinode() assert out_subdir.append("hardlink1").getinode() != \ out_subdir.append("hardlink3").getinode() time.sleep(1) InternalBackup(1, 1, hlout2.path, output.path) out_subdir.setdata() assert out_subdir.append("hardlink1").getinode() == \ out_subdir.append("hardlink4").getinode() assert out_subdir.append("hardlink2").getinode() == \ out_subdir.append("hardlink3").getinode() assert out_subdir.append("hardlink1").getinode() != \ out_subdir.append("hardlink2").getinode() # Now try restoring, still checking hard links. out2 = rpath.RPath(Globals.local_connection, "testfiles/out2") hlout1 = out2.append("hardlink1") hlout2 = out2.append("hardlink2") hlout3 = out2.append("hardlink3") hlout4 = out2.append("hardlink4") if out2.lstat(): out2.delete() InternalRestore(1, 1, "testfiles/output/subdir", "testfiles/out2", 1) out2.setdata() for rp in [hlout1, hlout2, hlout3, hlout4]: rp.setdata() assert hlout1.getinode() == hlout2.getinode() assert hlout3.getinode() == hlout4.getinode() assert hlout1.getinode() != hlout3.getinode() if out2.lstat(): out2.delete() InternalRestore(1, 1, "testfiles/output/subdir", "testfiles/out2", int(time.time())) out2.setdata() for rp in [hlout1, hlout2, hlout3, hlout4]: rp.setdata() assert hlout1.getinode() == hlout4.getinode(), \ "%s %s" % (hlout1.path, hlout4.path) assert hlout2.getinode() == hlout3.getinode() assert hlout1.getinode() != hlout2.getinode()