summaryrefslogtreecommitdiff
path: root/rdiff-backup/testing/regressiontest.py
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup/testing/regressiontest.py')
-rw-r--r--rdiff-backup/testing/regressiontest.py410
1 files changed, 410 insertions, 0 deletions
diff --git a/rdiff-backup/testing/regressiontest.py b/rdiff-backup/testing/regressiontest.py
new file mode 100644
index 0000000..5d4d27e
--- /dev/null
+++ b/rdiff-backup/testing/regressiontest.py
@@ -0,0 +1,410 @@
+import unittest, os
+
+execfile("commontest.py")
+rbexec("setconnections.py")
+
+
+"""Regression tests
+
+This one must be run in the rdiff-backup directory, as it requres
+chdir-wrapper, the various rdiff-backup files, and the directory
+testfiles
+"""
+
+Globals.set('change_source_perms', 1)
+Globals.counter = 0
+Log.setverbosity(7)
+
+class Local:
+ """This is just a place to put increments relative to the local
+ connection"""
+ def get_local_rp(extension):
+ return RPath(Globals.local_connection, "testfiles/" + extension)
+
+ inc1rp = get_local_rp('increment1')
+ inc2rp = get_local_rp('increment2')
+ inc3rp = get_local_rp('increment3')
+ inc4rp = get_local_rp('increment4')
+
+ rpout = get_local_rp('output')
+ rpout_inc = get_local_rp('output_inc')
+ rpout1 = get_local_rp('restoretarget1')
+ rpout2 = get_local_rp('restoretarget2')
+ rpout3 = get_local_rp('restoretarget3')
+ rpout4 = get_local_rp('restoretarget4')
+
+ noperms = get_local_rp('noperms')
+ noperms_out = get_local_rp('noperms_output')
+
+ rootfiles = get_local_rp('root')
+ rootfiles2 = get_local_rp('root2')
+ rootfiles21 = get_local_rp('root2.1')
+ rootfiles_out = get_local_rp('root_output')
+ rootfiles_out2 = get_local_rp('root_output2')
+
+ prefix = get_local_rp('.')
+
+
+class PathSetter(unittest.TestCase):
+ def get_prefix_and_conn(self, path, return_path):
+ """Return (prefix, connection) tuple"""
+ if path:
+ return (return_path,
+ SetConnections.init_connection("python ./chdir-wrapper "+path))
+ else: return ('./', Globals.local_connection)
+
+ def get_src_rp(self, path):
+ return RPath(self.src_conn, self.src_prefix + path)
+
+ def get_dest_rp(self, path):
+ return RPath(self.dest_conn, self.dest_prefix + path)
+
+ def set_rbdir(self, rpout):
+ """Create rdiff-backup-data dir if not already, tell everyone"""
+ self.rbdir = self.rpout.append('rdiff-backup-data')
+ self.rpout.mkdir()
+ self.rbdir.mkdir()
+ SetConnections.UpdateGlobal('rbdir', self.rbdir)
+
+ # Better safe than sorry - cover all possibilities
+ Globals.add_regexp("testfiles/output/rdiff-backup-data", 1)
+ Globals.add_regexp("./testfiles/output/rdiff-backup-data", 1)
+ Globals.add_regexp("../testfiles/output/rdiff-backup-data", 1)
+ Globals.add_regexp("../../testfiles/output/rdiff-backup-data", 1)
+
+ def setPathnames(self, src_path, src_return, dest_path, dest_return):
+ """Start servers which will run in src_path and dest_path respectively
+
+ If either is None, then no server will be run and local
+ process will handle that end. src_return and dest_return are
+ the prefix back to the original rdiff-backup directory. So
+ for instance is src_path is "test2/tmp", then src_return will
+ be '../'.
+
+ """
+ # Clear old data that may rely on deleted connections
+ Globals.isbackup_writer = None
+ Globals.isbackup_reader = None
+ Globals.rbdir = None
+
+ print "Setting up connection"
+ self.src_prefix, self.src_conn = \
+ self.get_prefix_and_conn(src_path, src_return)
+ self.dest_prefix, self.dest_conn = \
+ self.get_prefix_and_conn(dest_path, dest_return)
+ SetConnections.BackupInitConnections(self.src_conn, self.dest_conn)
+
+ os.system(MiscDir+"/myrm testfiles/output* testfiles/restoretarget* "
+ "testfiles/noperms_output testfiles/root_output "
+ "testfiles/unreadable_out")
+ self.inc1rp = self.get_src_rp("testfiles/increment1")
+ self.inc2rp = self.get_src_rp('testfiles/increment2')
+ self.inc3rp = self.get_src_rp('testfiles/increment3')
+ self.inc4rp = self.get_src_rp('testfiles/increment4')
+
+ self.rpout_inc = self.get_dest_rp('testfiles/output_inc')
+ self.rpout1 = self.get_dest_rp('testfiles/restoretarget1')
+ self.rpout2 = self.get_dest_rp('testfiles/restoretarget2')
+ self.rpout3 = self.get_dest_rp('testfiles/restoretarget3')
+ self.rpout4 = self.get_dest_rp('testfiles/restoretarget4')
+
+ self.rpout = self.get_dest_rp('testfiles/output')
+ self.set_rbdir(self.rpout)
+
+ self.noperms = self.get_src_rp('testfiles/noperms')
+ self.noperms_out = self.get_dest_rp('testfiles/noperms_output')
+
+ self.rootfiles = self.get_src_rp('testfiles/root')
+ self.rootfiles_out = self.get_dest_rp('testfiles/root_output')
+ self.rootfiles2 = self.get_src_rp('testfiles/root2')
+ self.rootfiles21 = self.get_src_rp('testfiles/root2.1')
+ self.rootfiles_out2 = self.get_dest_rp('testfiles/root_output2')
+
+ self.one_unreadable = self.get_src_rp('testfiles/one_unreadable')
+ self.one_unreadable_out = self.get_dest_rp('testfiles/unreadable_out')
+
+ def tearDown(self):
+ print "Taking down connections"
+ SetConnections.CloseConnections()
+
+
+class IncrementTest(PathSetter):
+ def testLocalinc(self):
+ """Test self.incrementing, and then restoring, local"""
+ self.setPathnames(None, None, None, None)
+ self.runtest()
+
+ def test_remote_src(self):
+ """Increment/Restore when source directory is remote"""
+ self.setPathnames('test1', '../', None, None)
+ self.runtest()
+
+ def test_remote_dest(self):
+ """Increment/Restore when target directory is remote"""
+ self.setPathnames(None, None, 'test2', '../')
+ self.runtest()
+
+ def test_remote_both(self):
+ """Increment/Restore when both directories are remote"""
+ self.setPathnames('test1', '../', 'test2/tmp', '../../')
+ self.runtest()
+
+ def OldtestRecoveryLocal(self):
+ """Test to see if rdiff-backup can continue with bad increment"""
+ os.system(MiscDir+'/myrm testfiles/recovery_out_backup')
+ self.setPathnames(None, None, None, None)
+ Time.setprevtime(1006136450)
+ Time.setcurtime()
+ Globals.add_regexp('.*rdiff-backup-data', 1)
+ os.system('cp -a testfiles/recovery_out testfiles/recovery_out_backup')
+ recovery_in = self.get_src_rp('testfiles/recovery')
+ recovery_out = self.get_dest_rp('testfiles/recovery_out_backup')
+ recovery_inc = self.get_dest_rp('testfiles/recovery_out_backup/'
+ 'rdiff-backup-data/increments')
+ HighLevel.Mirror_and_increment(recovery_in, recovery_out,
+ recovery_inc)
+ # Should probably check integrity of increments, but for now
+ # allow if it doesn't during the Mirror_and_increment
+
+ def OldtestRecoveryRemote(self):
+ """Test Recovery with both connections remote"""
+ os.system(MiscDir+'/myrm testfiles/recovery_out_backup')
+ self.setPathnames('test1', '../', 'test2/tmp', '../../')
+ Time.setprevtime(1006136450)
+ Time.setcurtime()
+ Globals.add_regexp('.*rdiff-backup-data', 1)
+ os.system('cp -a testfiles/recovery_out testfiles/recovery_out_backup')
+ recovery_in = self.get_src_rp('testfiles/recovery')
+ recovery_out = self.get_dest_rp('testfiles/recovery_out_backup')
+ recovery_inc = self.get_dest_rp('testfiles/recovery_out_backup/'
+ 'rdiff-backup-data/increments')
+ HighLevel.Mirror_and_increment(recovery_in, recovery_out,
+ recovery_inc)
+ # Should probably check integrity of increments, but for now
+ # allow if it doesn't during the Mirror_and_increment
+
+ def runtest(self):
+ """After setting connections, etc., run actual test using this"""
+ Time.setcurtime()
+ SaveState.init_filenames(1)
+ HighLevel.Mirror(self.inc1rp, self.rpout)
+ assert RPath.cmp_recursive(Local.inc1rp, Local.rpout)
+
+ Time.setcurtime()
+ Time.setprevtime(999500000)
+ HighLevel.Mirror_and_increment(self.inc2rp, self.rpout, self.rpout_inc)
+ assert RPath.cmp_recursive(Local.inc2rp, Local.rpout)
+
+ Time.setcurtime()
+ Time.setprevtime(999510000)
+ HighLevel.Mirror_and_increment(self.inc3rp, self.rpout, self.rpout_inc)
+ assert RPath.cmp_recursive(Local.inc3rp, Local.rpout)
+
+ Time.setcurtime()
+ Time.setprevtime(999520000)
+ HighLevel.Mirror_and_increment(self.inc4rp, self.rpout, self.rpout_inc)
+ assert RPath.cmp_recursive(Local.inc4rp, Local.rpout)
+
+
+ print "Restoring to self.inc4"
+ HighLevel.Restore(999530000, self.rpout, self.get_inctup(),
+ self.rpout4)
+ assert RPath.cmp_recursive(Local.inc4rp, Local.rpout4)
+
+ print "Restoring to self.inc3"
+ HighLevel.Restore(999520000, self.rpout, self.get_inctup(),
+ self.rpout3)
+ assert RPath.cmp_recursive(Local.inc3rp, Local.rpout3)
+
+ print "Restoring to self.inc2"
+ HighLevel.Restore(999510000, self.rpout, self.get_inctup(),
+ self.rpout2)
+ assert RPath.cmp_recursive(Local.inc2rp, Local.rpout2)
+
+ print "Restoring to self.inc1"
+ HighLevel.Restore(999500000, self.rpout, self.get_inctup(),
+ self.rpout1)
+ assert RPath.cmp_recursive(Local.inc1rp, Local.rpout1)
+
+ def get_inctup(self):
+ """Return inc tuples as expected by Restore.RestoreRecursive
+
+ Assumes output increment directory is
+ testfiles/output_inc._____.
+
+ """
+ filenames = filter(lambda x: x.startswith("output_inc."),
+ Local.prefix.listdir())
+ rplist = map(lambda x: Local.prefix.append(x), filenames)
+ return IndexedTuple((), (Local.prefix.append("output_inc"), rplist))
+
+
+class MirrorTest(PathSetter):
+ """Test some mirroring functions"""
+ def testLocalMirror(self):
+ """Test Local mirroring"""
+ self.setPathnames(None, None, None, None)
+ self.runtest()
+
+ def testPartialLocalMirror(self):
+ """Test updating an existing directory"""
+ self.setPathnames(None, None, None, None)
+ self.run_partial_test()
+
+ def testRemoteMirror(self):
+ """Mirroring when destination is remote"""
+ self.setPathnames(None, None, 'test1', '../')
+ self.runtest()
+
+ def testPartialRemoteMirror(self):
+ """Partial mirroring when destination is remote"""
+ self.setPathnames(None, None, 'test1', '../')
+ self.run_partial_test()
+
+ def testSourceRemoteMirror(self):
+ """Mirroring when source is remote"""
+ self.setPathnames('test2', '../', None, None)
+ self.runtest()
+
+ def testPartialSourceRemoteMirror(self):
+ """Partial Mirroring when source is remote"""
+ self.setPathnames('test2', '../', None, None)
+ self.run_partial_test()
+
+ def testBothRemoteMirror(self):
+ """Mirroring when both directories are remote"""
+ self.setPathnames('test1', '../', 'test2/tmp', '../../')
+ self.runtest()
+
+ def testPartialBothRemoteMirror(self):
+ """Partial mirroring when both directories are remote"""
+ self.setPathnames('test1', '../', 'test2/tmp', '../../')
+ self.run_partial_test()
+
+ def testNopermsLocal(self):
+ "Test mirroring a directory that has no permissions"
+ self.setPathnames(None, None, None, None)
+ Time.setcurtime()
+ SaveState.init_filenames(None)
+ HighLevel.Mirror(self.noperms, self.noperms_out, None)
+ # Can't compare because we don't have the permissions to do it right
+ #assert RPath.cmp_recursive(Local.noperms, Local.noperms_out)
+
+ def testNopermsRemote(self):
+ "No permissions mirroring (remote)"
+ self.setPathnames('test1', '../', 'test2/tmp', '../../')
+ Time.setcurtime()
+ SaveState.init_filenames(None)
+ HighLevel.Mirror(self.noperms, self.noperms_out, checkpoint=None)
+ #assert RPath.cmp_recursive(Local.noperms, Local.noperms_out)
+
+ def testPermSkipLocal(self):
+ """Test to see if rdiff-backup will skip unreadable files"""
+ self.setPathnames(None, None, None, None)
+ Globals.change_source_perms = None
+ Time.setcurtime()
+ SaveState.init_filenames(None)
+ HighLevel.Mirror(self.one_unreadable, self.one_unreadable_out, checkpoint=None)
+ Globals.change_source_perms = 1
+ HighLevel.Mirror(self.one_unreadable, self.one_unreadable_out)
+ # Could add test, but for now just make sure it doesn't exit
+
+ def testPermSkipRemote(self):
+ """Test skip of unreadable files remote"""
+ self.setPathnames('test1', '../', 'test2/tmp', '../../')
+ Globals.change_source_perms = None
+ Time.setcurtime()
+ SaveState.init_filenames(None)
+ HighLevel.Mirror(self.one_unreadable, self.one_unreadable_out)
+ Globals.change_source_perms = 1
+ HighLevel.Mirror(self.one_unreadable, self.one_unreadable_out)
+ # Could add test, but for now just make sure it doesn't exit
+
+ def refresh(self, *rps):
+ for rp in rps: rp.setdata()
+
+ def _testRootLocal(self):
+ """Test mirroring a directory with dev files and different owners"""
+ self.setPathnames(None, None, None, None)
+ Globals.change_ownership = 1
+ self.refresh(self.rootfiles, self.rootfiles_out,
+ Local.rootfiles, Local.rootfiles_out) # add uid/gid info
+ HighLevel.Mirror(self.rootfiles, self.rootfiles_out)
+ assert RPath.cmp_recursive(Local.rootfiles, Local.rootfiles_out)
+ Globals.change_ownership = None
+ self.refresh(self.rootfiles, self.rootfiles_out,
+ Local.rootfiles, Local.rootfiles_out) # remove that info
+
+ def _testRootRemote(self):
+ """Mirroring root files both ends remote"""
+ self.setPathnames('test1', '../', 'test2/tmp', '../../')
+ for conn in Globals.connections:
+ conn.Globals.set('change_ownership', 1)
+ self.refresh(self.rootfiles, self.rootfiles_out,
+ Local.rootfiles, Local.rootfiles_out) # add uid/gid info
+ HighLevel.Mirror(self.rootfiles, self.rootfiles_out)
+ assert RPath.cmp_recursive(Local.rootfiles, Local.rootfiles_out)
+ for coon in Globals.connections:
+ conn.Globals.set('change_ownership', None)
+ self.refresh(self.rootfiles, self.rootfiles_out,
+ Local.rootfiles, Local.rootfiles_out) # remove that info
+
+ def testRoot2Local(self):
+ """Make sure we can backup a directory we don't own"""
+ self.setPathnames(None, None, None, None)
+ Globals.change_ownership = Globals.change_source_perms = None
+ self.refresh(self.rootfiles2, self.rootfiles_out2,
+ Local.rootfiles2, Local.rootfiles_out2) # add uid/gid info
+ HighLevel.Mirror(self.rootfiles2, self.rootfiles_out2)
+ assert RPath.cmp_recursive(Local.rootfiles2, Local.rootfiles_out2)
+ self.refresh(self.rootfiles2, self.rootfiles_out2,
+ Local.rootfiles2, Local.rootfiles_out2) # remove that info
+ HighLevel.Mirror(self.rootfiles21, self.rootfiles_out2)
+ assert RPath.cmp_recursive(Local.rootfiles21, Local.rootfiles_out2)
+ self.refresh(self.rootfiles21, self.rootfiles_out2,
+ Local.rootfiles21, Local.rootfiles_out2) # remove that info
+ Globals.change_source_perms = 1
+
+ def deleteoutput(self):
+ os.system(MiscDir+"/myrm testfiles/output*")
+ self.rbdir = self.rpout.append('rdiff-backup-data')
+ self.rpout.mkdir()
+ self.rbdir.mkdir()
+ self.reset_rps()
+
+ def reset_rps(self):
+ """Use after external changes made, to update the rps"""
+ for rp in [self.rpout, Local.rpout,
+ self.rpout_inc, Local.rpout_inc,
+ self.rpout1, Local.rpout1,
+ self.rpout2, Local.rpout2,
+ self.rpout3, Local.rpout3,
+ self.rpout4, Local.rpout4]:
+ rp.setdata()
+
+ def runtest(self):
+ Time.setcurtime()
+ SaveState.init_filenames(None)
+ assert self.rbdir.lstat()
+ HighLevel.Mirror(self.inc1rp, self.rpout)
+ assert RPath.cmp_recursive(Local.inc1rp, Local.rpout)
+
+ self.deleteoutput()
+
+ HighLevel.Mirror(self.inc2rp, self.rpout)
+ assert RPath.cmp_recursive(Local.inc2rp, Local.rpout)
+
+ def run_partial_test(self):
+ os.system("cp -a testfiles/increment3 testfiles/output")
+ self.reset_rps()
+
+ Time.setcurtime()
+ SaveState.init_filenames(None)
+ HighLevel.Mirror(self.inc1rp, self.rpout)
+ #RPath.copy_attribs(self.inc1rp, self.rpout)
+ assert RPath.cmp_recursive(Local.inc1rp, Local.rpout)
+
+ HighLevel.Mirror(self.inc2rp, self.rpout)
+ assert RPath.cmp_recursive(Local.inc2rp, Local.rpout)
+
+if __name__ == "__main__": unittest.main()