def test_non_root(self): """Main non-root -> root test""" input_rp1, input_rp2 = self.make_root_dirs() Globals.change_ownership = 1 output_rp = rpath.RPath(Globals.local_connection, abs_output_dir) re_init_rpath_dir(output_rp, userid) restore_rp = rpath.RPath(Globals.local_connection, abs_restore_dir) empty_rp = rpath.RPath(Globals.local_connection, os.path.join(old_test_dir, b"empty")) self.backup(input_rp1, output_rp, 1000000) self.restore(output_rp, restore_rp) assert CompareRecursive(input_rp1, restore_rp, compare_ownership=1) self.backup(input_rp2, output_rp, 2000000) self.restore(output_rp, restore_rp) assert CompareRecursive(input_rp2, restore_rp, compare_ownership=1) self.backup(empty_rp, output_rp, 3000000) self.restore(output_rp, restore_rp) assert CompareRecursive(empty_rp, restore_rp, compare_ownership=1) self.restore(output_rp, restore_rp, 1000000) assert CompareRecursive(input_rp1, restore_rp, compare_ownership=1) self.restore(output_rp, restore_rp, 2000000) assert CompareRecursive(input_rp2, restore_rp, compare_ownership=1)
def test_final_local(self): """Test backing up and restoring using 'rdiff-backup' script""" self.make_backup_dirs() self.make_temp_out_dirs() rdiff_backup(1, 1, self.ea_test1_rpath.path, tempdir.path, current_time=10000) assert CompareRecursive(self.ea_test1_rpath, tempdir, compare_eas=1) rdiff_backup(1, 1, self.ea_test2_rpath.path, tempdir.path, current_time=20000) assert CompareRecursive(self.ea_test2_rpath, tempdir, compare_eas=1) rdiff_backup(1, 1, tempdir.path, restore_dir.path, extra_options=b'-r 10000') assert CompareRecursive(self.ea_test1_rpath, restore_dir, compare_eas=1)
def restore_dir_test(self, mirror_local, dest_local): """Run whole dir tests If any of the above tests don't work, try rerunning makerestoretest3. """ Myrm(abs_output_dir) restore3_dir = os.path.join(old_test_dir, b"restoretest3") target_rp = rpath.RPath(Globals.local_connection, abs_output_dir) inc1_rp = rpath.RPath(Globals.local_connection, os.path.join(old_test_dir, b"increment1")) inc2_rp = rpath.RPath(Globals.local_connection, os.path.join(old_test_dir, b"increment2")) inc3_rp = rpath.RPath(Globals.local_connection, os.path.join(old_test_dir, b"increment3")) inc4_rp = rpath.RPath(Globals.local_connection, os.path.join(old_test_dir, b"increment4")) InternalRestore(mirror_local, dest_local, restore3_dir, abs_output_dir, 45000) assert CompareRecursive(inc4_rp, target_rp) InternalRestore(mirror_local, dest_local, restore3_dir, abs_output_dir, 35000) assert CompareRecursive(inc3_rp, target_rp, compare_hardlinks=0) InternalRestore(mirror_local, dest_local, restore3_dir, abs_output_dir, 25000) assert CompareRecursive(inc2_rp, target_rp, compare_hardlinks=0) InternalRestore(mirror_local, dest_local, restore3_dir, abs_output_dir, 5000) assert CompareRecursive(inc1_rp, target_rp, compare_hardlinks=0)
def testEquality(self): """Test rorp_eq function in conjunction with CompareRecursive""" assert CompareRecursive(self.hlinks_rp1, self.hlinks_rp1copy) assert CompareRecursive(self.hlinks_rp1, self.hlinks_rp2, compare_hardlinks=None) assert not CompareRecursive( self.hlinks_rp1, self.hlinks_rp2, compare_hardlinks=1)
def testWindowsMode(self): """Test backup with quoting enabled We need to delete from the increment? directories long file names, because quoting adds too many extra letters. """ def delete_long(base_rp, length=100): """Delete filenames longer than length given""" for rp in selection.Select(base_rp).set_iter(): if len(rp.dirsplit()[1]) > length: rp.delete() if not Local.wininc2.lstat() or not Local.wininc3.lstat(): os.system(b"cp -a testfiles/increment2 testfiles/win-increment2") os.system(b"cp -a testfiles/increment3 testfiles/win-increment3") delete_long(Local.wininc2) delete_long(Local.wininc3) old_schema = self.rb_schema self.rb_schema = old_schema + b" --override-chars-to-quote '^a-z0-9_ -.' " self.set_connections(None, None, None, None) self.delete_tmpdirs() # Back up increment2, this contains a file with colons self.exec_rb(20000, b'testfiles/win-increment2', b'testfiles/output') self.rb_schema = old_schema # Quoting setting should now be saved time.sleep(1) # Back up increment3 self.exec_rb(30000, b'testfiles/win-increment3', b'testfiles/output') # Now check to make sure no ":" in output directory popen_fp = os.popen(b"find testfiles/output -name '*:*' | wc") wc_output = popen_fp.read() popen_fp.close() assert wc_output.split() == [b"0", b"0", b"0"], wc_output # Start restore of increment 2 Globals.chars_to_quote = b'^a-z0-9_ -.' inc_paths = self.getinc_paths(b"increments.", b"testfiles/output/rdiff-backup-data", 1) Globals.chars_to_quote = None assert len(inc_paths) == 1, inc_paths self.exec_rb(None, inc_paths[0], b'testfiles/restoretarget2') assert CompareRecursive(Local.wininc2, Local.rpout2, compare_hardlinks=0) # Restore increment 3 again, using different syntax self.rb_schema = old_schema + b'-r 30000 ' self.exec_rb(None, b'testfiles/output', b'testfiles/restoretarget3') assert CompareRecursive(Local.wininc3, Local.rpout3, compare_hardlinks=0) self.rb_schema = old_schema
def testLegacy(self): """Test restoring directory with no mirror_metadata file""" self.delete_tmpdirs() rdiff_backup(True, True, Local.vftrp.path, Local.rpout.path, current_time=10000) rdiff_backup(True, True, Local.emptyrp.path, Local.rpout.path, current_time=20000) # remove mirror_metadata files to simulate old style backups # pathlib.Path doesn't work with bytes hence need to work with str path for mirror_file in pathlib.Path( os.fsdecode(Local.rpout.append( b'rdiff-backup-data').path)).glob('mirror_metadata*'): mirror_file.unlink() rdiff_backup(True, True, Local.rpout.path, Local.rpout1.path, extra_options=b'-r0') assert CompareRecursive(Local.vftrp, Local.rpout1, compare_hardlinks=0)
def make_root_dirs(self): """Make directory createable only by root""" rp = rpath.RPath(Globals.local_connection, os.path.join(abs_test_dir, b"root_out1")) re_init_rpath_dir(rp) rp1 = rp.append("1") rp1.touch() rp2 = rp.append("2") rp2.touch() rp2.chown(1, 1) rp3 = rp.append("3") rp3.touch() rp3.chown(2, 2) rp4 = rp.append("dev") rp4.makedev('c', 4, 28) sp = rpath.RPath(Globals.local_connection, os.path.join(abs_test_dir, b"root_out2")) if sp.lstat(): Myrm(sp.path) Run(b"cp -a %s %s" % (rp.path, sp.path)) rp2 = sp.append("2") rp2.chown(2, 2) rp3 = sp.append("3") rp3.chown(1, 1) assert not CompareRecursive(rp, sp, compare_ownership=1) return rp, sp
def compare_no_times(self, src_rp, dest_rp): """Compare but disregard directories attributes""" def equal(src_rorp, dest_rorp): return ((src_rorp.isdir() and dest_rorp.isdir()) or src_rorp == dest_rorp) return CompareRecursive(src_rp, dest_rp, None, equal)
def test_backup(self): """Test back up, simple restores""" in_rp1, in_rp2 = self.make_dirs() outrp = rpath.RPath(Globals.local_connection, abs_output_dir) re_init_rpath_dir(outrp, userid) remote_schema = b'su -c "rdiff-backup --server" %s' % (user.encode(), ) cmd_schema = (b"rdiff-backup -v%i" % verbosity + b" --current-time %i --remote-schema '%%s' %b '%b'::%b") cmd1 = cmd_schema % (10000, in_rp1.path, remote_schema, outrp.path) Run(cmd1) in_rp1.setdata() outrp.setdata() cmd2 = cmd_schema % (20000, in_rp2.path, remote_schema, outrp.path) Run(cmd2) in_rp2.setdata() outrp.setdata() rout_rp = rpath.RPath(Globals.local_connection, abs_restore_dir) restore_schema = (b"rdiff-backup -v%i" % verbosity + b" -r %b --remote-schema '%%s' '%b'::%b %b") Myrm(rout_rp.path) cmd3 = restore_schema % (b'10000', remote_schema, outrp.path, rout_rp.path) Run(cmd3) assert CompareRecursive(in_rp1, rout_rp) rout_perms = rout_rp.append('unreadable_dir').getperms() outrp_perms = outrp.append('unreadable_dir').getperms() assert rout_perms == 0, rout_perms assert outrp_perms == 0, outrp_perms Myrm(rout_rp.path) cmd4 = restore_schema % (b"now", remote_schema, outrp.path, rout_rp.path) Run(cmd4) assert CompareRecursive(in_rp2, rout_rp) rout_perms = rout_rp.append('unreadable_dir').getperms() outrp_perms = outrp.append('unreadable_dir').getperms() assert rout_perms == 0, rout_perms assert outrp_perms == 0, outrp_perms self.cause_regress(outrp) cmd5 = (b'su -c "rdiff-backup --check-destination-dir %s" %s' % (outrp.path, user.encode())) Run(cmd5)
def cycle_once(min_max_time_pair, curtime, input_rp, old_rp): """Backup input_rp, kill, regress, and then compare""" time.sleep(1) self.exec_and_kill(min_max_time_pair, curtime, input_rp.path, Local.rpout.path) result = self.mark_incomplete(curtime, Local.rpout) assert not self.exec_rb(None, 1, '--check-destination-dir', Local.rpout.path) assert CompareRecursive(old_rp, Local.rpout, compare_hardlinks=0) return result
def runtest(self, regress_function): """Test regressing a full directory to older state Make two directories, one with one more backup in it. Then regress the bigger one, and then make sure they compare the same. Regress_function takes a time and should regress self.output_rp back to that time. """ self.output_rp.setdata() if self.output_rp.lstat(): Myrm(self.output_rp.path) rdiff_backup(1, 1, self.incrp[0].path, self.output_rp.path, current_time=10000) assert CompareRecursive(self.incrp[0], self.output_rp) rdiff_backup(1, 1, self.incrp[1].path, self.output_rp.path, current_time=20000) assert CompareRecursive(self.incrp[1], self.output_rp) rdiff_backup(1, 1, self.incrp[2].path, self.output_rp.path, current_time=30000) assert CompareRecursive(self.incrp[2], self.output_rp) rdiff_backup(1, 1, self.incrp[3].path, self.output_rp.path, current_time=40000) assert CompareRecursive(self.incrp[3], self.output_rp) Globals.rbdir = self.output_rbdir_rp regress_function(30000) assert CompareRecursive(self.incrp[2], self.output_rp, compare_hardlinks=0) regress_function(20000) assert CompareRecursive(self.incrp[1], self.output_rp, compare_hardlinks=0) regress_function(10000) assert CompareRecursive(self.incrp[0], self.output_rp, compare_hardlinks=0)
def testProcLocalToRemote(self): """Test mirroring proc remote""" procout_dir = os.path.join(abs_test_dir, b"procoutput") Myrm(procout_dir) procout = rpath.RPath(Globals.local_connection, procout_dir) rdiff_backup(True, False, '/proc', procout.path, current_time=10000) time.sleep(1) rdiff_backup(True, False, '/proc', procout.path, current_time=20000) time.sleep(1) rdiff_backup(True, False, Local.inc1rp.path, procout.path, current_time=30000) assert CompareRecursive(Local.inc1rp, procout) time.sleep(1) rdiff_backup(True, False, '/proc', procout.path, current_time=40000)
def test_long_socket_name(self): """Test when socket name is saved to a backup directory with a long name It addresses an issue where socket wasn't created with mknod but with socket.socket and bind, which has a limit at 107 characters.""" input_dir = os.path.join(old_test_dir, b"select", b"filetypes") # create a target directory with a long name next to 107 output_dir = os.path.join(abs_test_dir, b"tenletters" * 10) Myrm(output_dir) restore_dir = os.path.join(abs_test_dir, b"restoresme" * 10) Myrm(restore_dir) # backup and restore the input directory with socket, then compare rdiff_backup(True, True, input_dir, output_dir) rdiff_backup(True, True, output_dir, restore_dir, extra_options=b'-r 0') CompareRecursive(rpath.RPath(Globals.local_connection, input_dir), rpath.RPath(Globals.local_connection, restore_dir))
def testTerm(self): """Run rdiff-backup, termining and regressing each time Because rdiff-backup must be killed, the timing should be updated """ count, killed_too_soon, killed_too_late = 5, [0] * 4, [0] * 4 self.delete_tmpdirs() # Back up killtest3 first because it is big and the first case # is kind of special (there's no incrementing, so different # code) self.exec_rb(10000, 1, Local.ktrp[2].path, Local.rpout.path) assert CompareRecursive(Local.ktrp[2], Local.rpout) def cycle_once(min_max_time_pair, curtime, input_rp, old_rp): """Backup input_rp, kill, regress, and then compare""" time.sleep(1) self.exec_and_kill(min_max_time_pair, curtime, input_rp.path, Local.rpout.path) result = self.mark_incomplete(curtime, Local.rpout) assert not self.exec_rb(None, 1, '--check-destination-dir', Local.rpout.path) assert CompareRecursive(old_rp, Local.rpout, compare_hardlinks=0) return result # Keep backing ktrp[0], and then regressing to ktrp[2]. Then go to ktrp[0] for i in range(count): result = cycle_once(self.time_pairs[1], 20000, Local.ktrp[0], Local.ktrp[2]) if result == 0: killed_too_late[0] += 1 elif result == -1: killed_too_soon[0] += 1 self.exec_rb(20000, 1, Local.ktrp[0].path, Local.rpout.path) # Now keep regressing from ktrp[1], only staying there at the end for i in range(count): result = cycle_once(self.time_pairs[2], 30000, Local.ktrp[1], Local.ktrp[0]) if result == 0: killed_too_late[1] += 1 elif result == -1: killed_too_soon[1] += 1 self.exec_rb(30000, 1, Local.ktrp[1].path, Local.rpout.path) # Now keep regressing from ktrp[2], only staying there at the end for i in range(count): result = cycle_once(self.time_pairs[3], 40000, Local.ktrp[2], Local.ktrp[1]) if result == 0: killed_too_late[2] += 1 elif result == -1: killed_too_soon[2] += 1 self.exec_rb(40000, 1, Local.ktrp[2].path, Local.rpout.path) # Now keep regressing from ktrp[3], only staying there at the end for i in range(count): result = cycle_once(self.time_pairs[4], 50000, Local.ktrp[3], Local.ktrp[2]) if result == 0: killed_too_late[3] += 1 elif result == -1: killed_too_soon[3] += 1 print("Killed too soon out of %s: %s" % (count, killed_too_soon)) print("Killed too late out of %s: %s" % (count, killed_too_late))
def runtest(self, from_local, to_local): self.delete_tmpdirs() # Backing up increment1 rdiff_backup(from_local, to_local, Local.inc1rp.path, Local.rpout.path, current_time=10000) assert CompareRecursive(Local.inc1rp, Local.rpout) time.sleep(1) # Backing up increment2 rdiff_backup(from_local, to_local, Local.inc2rp.path, Local.rpout.path, current_time=20000) assert CompareRecursive(Local.inc2rp, Local.rpout) time.sleep(1) # Backing up increment3 rdiff_backup(from_local, to_local, Local.inc3rp.path, Local.rpout.path, current_time=30000) assert CompareRecursive(Local.inc3rp, Local.rpout) time.sleep(1) # Backing up increment4 rdiff_backup(from_local, to_local, Local.inc4rp.path, Local.rpout.path, current_time=40000) assert CompareRecursive(Local.inc4rp, Local.rpout) # Getting restore rps inc_paths = self.getinc_paths( b"increments.", os.path.join(Local.rpout.path, b"rdiff-backup-data")) assert len(inc_paths) == 3 # Restoring increment1 rdiff_backup(from_local, to_local, inc_paths[0], Local.rpout1.path) assert CompareRecursive(Local.inc1rp, Local.rpout1) # Restoring increment2 rdiff_backup(from_local, to_local, inc_paths[1], Local.rpout2.path) assert CompareRecursive(Local.inc2rp, Local.rpout2) # Restoring increment3 rdiff_backup(from_local, to_local, inc_paths[2], Local.rpout3.path) assert CompareRecursive(Local.inc3rp, Local.rpout3) # Test restoration of a few random files vft_paths = self.getinc_paths( b"various_file_types.", os.path.join(Local.rpout.path, b"rdiff-backup-data", b"increments")) rdiff_backup(from_local, to_local, vft_paths[1], Local.vft_out.path) self.refresh(Local.vft_in, Local.vft_out) assert CompareRecursive(Local.vft_in, Local.vft_out) timbar_paths = self.getinc_paths( b"timbar.pyc.", os.path.join(Local.rpout.path, b"rdiff-backup-data", b"increments")) rdiff_backup(from_local, to_local, timbar_paths[0], Local.timbar_out.path) self.refresh(Local.timbar_in, Local.timbar_out) assert Local.timbar_in.equal_loose(Local.timbar_out) rdiff_backup(from_local, to_local, Local.rpout.append('various_file_types').path, Local.vft_recover.path, extra_options=b"--restore-as-of 25000") self.refresh(Local.vft_recover, Local.vft_in) assert CompareRecursive(Local.vft_recover, Local.vft_in) # Make sure too many increment files not created assert len( self.getinc_paths( b"nochange.", os.path.join(Local.rpout.path, b"rdiff-backup-data", b"increments"))) == 0 nochange_incs = len( self.getinc_paths( b"", os.path.join(Local.rpout.path, b"rdiff-backup-data", b"increments", b"nochange"))) assert nochange_incs == 1 or nochange_incs == 0, nochange_incs