def test_action_verify(self): """test different ways of verifying""" # removing multiple increments fails without --force self.assertEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201"), b"verify", ()), 0) self.assertEqual( comtst.rdiff_backup_action( True, None, self.bak_path, None, ("--api-version", "201", "--force"), # now forcing! b"verify", ("--at", "1B")), 0) # corrupt the backup repository with open(os.path.join(self.bak_path, b"fileNew"), "w") as fd: fd.write("corrupt data") self.assertNotEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201"), b"verify", ("--at", "now")), 0) # all tests were successful self.success = True
def test_location_map_filenames_change_quotes(self): """ test the "backup" and "restore" actions with quoted filenames while changing the quoted characters, which isn't supported """ # we backup twice to the same backup repository at different times self.assertEqual( comtst.rdiff_backup_action( False, False, self.from1_path, self.bak_path, ("--api-version", "201", "--current-time", "10000", "--chars-to-quote", "A-P"), b"backup", ()), 0) # we try the 2nd time to change the chars-to-quote, which fails self.assertNotEqual( comtst.rdiff_backup_action( False, True, self.from2_path, self.bak_path, ("--api-version", "201", "--current-time", "15000", "--chars-to-quote", "H-Z"), b"backup", ()), 0) self.assertNotEqual( comtst.rdiff_backup_action( False, True, self.from2_path, self.bak_path, ("--api-version", "201", "--current-time", "20000", "--chars-to-quote", "H-Z", "--force"), b"backup", ()), 0) # then we restore the last mirror to a directory without issue self.assertEqual( comtst.rdiff_backup_action(True, True, self.bak_path, self.to1_path, ("--api-version", "201"), b"restore", ()), 0) self.assertFalse(fileset.compare_paths(self.from1_path, self.to1_path)) # all tests were successful self.success = True
def test_location_map_filenames(self): """ test the "backup" and "restore" actions with quoted filenames """ # we backup twice to the same backup repository at different times self.assertEqual( comtst.rdiff_backup_action( False, False, self.from1_path, self.bak_path, ("--api-version", "201", "--current-time", "10000", "--chars-to-quote", "A-Z"), b"backup", ()), 0) self.assertEqual( comtst.rdiff_backup_action( False, True, self.from2_path, self.bak_path, ("--api-version", "201", "--current-time", "20000", "--chars-to-quote", "A-Z"), b"backup", ()), 0) # then we restore the increment and the last mirror to two directories self.assertEqual( comtst.rdiff_backup_action(True, False, self.bak_path, self.to1_path, ("--api-version", "201"), b"restore", ("--at", "1B")), 0) self.assertEqual( comtst.rdiff_backup_action(True, True, self.bak_path, self.to2_path, ("--api-version", "201"), b"restore", ()), 0) self.assertFalse(fileset.compare_paths(self.from1_path, self.to1_path)) self.assertFalse(fileset.compare_paths(self.from2_path, self.to2_path)) # all tests were successful self.success = True
def test_action_listfileschangedsince(self): """test the list files at time action""" # we list the files at different times self.assertEqual(comtst.rdiff_backup_action( False, None, self.bak_path, None, ("--api-version", "201"), b"list", ("files", "--changed-since", "now"), return_stdout=True), b"""""") self.assertEqual(comtst.rdiff_backup_action( True, None, self.bak_path, None, ("--api-version", "201"), b"list", ("files", "--changed-since", "10000"), return_stdout=True), b"""changed fileChanged new fileNew deleted fileOld """) self.assertEqual(comtst.rdiff_backup_action( True, None, self.bak_path, None, ("--api-version", "201"), b"list", ("files", "--changed-since", "15000"), return_stdout=True), b"""changed fileChanged new fileNew deleted fileOld """) self.assertEqual(comtst.rdiff_backup_action( True, None, self.bak_path, None, ("--api-version", "201"), b"list", ("files", "--changed-since", "1B"), return_stdout=True), b"""changed fileChanged new fileNew deleted fileOld """) # all tests were successful self.success = True
def test_forced_regress(self): """test different ways of regressing even if not necessary""" # regressing a successful backup with force simply removes it self.assertEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201", "--force"), b"regress", ()), 0) # we do it twice self.assertEqual( comtst.rdiff_backup_action(True, None, self.bak_path, None, ("--api-version", "201", "--force"), b"regress", ()), 0) # we restore and compare self.assertEqual( comtst.rdiff_backup_action(True, True, self.bak_path, self.to1_path, ("--api-version", "201"), b"restore", ()), 0) self.assertFalse(fileset.compare_paths(self.from1_path, self.to1_path)) # the last tentative to regress forcefully ends with a warning self.assertEqual( comtst.rdiff_backup_action(True, None, self.bak_path, None, ("--api-version", "201", "--force"), b"regress", ()), 2) # all tests were successful self.success = True
def setUp(self): self.base_dir = os.path.join(comtst.abs_test_dir, b"action_list") self.from1_struct = { "from1": {"subs": { "fileChanged": {"content": "initial"}, "fileOld": {}, "fileUnchanged": {"content": "unchanged"}, }} } self.from1_path = os.path.join(self.base_dir, b"from1") self.from2_struct = { "from2": {"subs": { "fileChanged": {"content": "modified"}, "fileNew": {}, "fileUnchanged": {"content": "unchanged"}, }} } self.from2_path = os.path.join(self.base_dir, b"from2") fileset.create_fileset(self.base_dir, self.from1_struct) fileset.create_fileset(self.base_dir, self.from2_struct) fileset.remove_fileset(self.base_dir, {"bak": {"type": "dir"}}) self.bak_path = os.path.join(self.base_dir, b"bak") self.success = False # we backup twice to the same backup repository at different times comtst.rdiff_backup_action( True, True, self.from1_path, self.bak_path, ("--api-version", "201", "--current-time", "10000"), b"backup", ()) comtst.rdiff_backup_action( True, True, self.from2_path, self.bak_path, ("--api-version", "201", "--current-time", "20000"), b"backup", ())
def test_location_map_hardlinks_rotate(self): """ verify that hardlinked files can be rotated, see issue #272 i.e. first one removed and new one added. """ # backup a 1st time self.assertEqual( comtst.rdiff_backup_action( True, True, self.from1_path, self.bak_path, ("--api-version", "201", "--current-time", "10000"), b"backup", ()), 0) # kind of rotate the hard linked file os.remove(os.path.join(self.from1_path, b'hardlink1')) os.link(os.path.join(self.from1_path, b'hardlink3'), os.path.join(self.from1_path, b'hardlink4')) # backup a 2nd time self.assertEqual( comtst.rdiff_backup_action( True, True, self.from1_path, self.bak_path, ("--api-version", "201", "--current-time", "20000"), b"backup", ()), 0) # verify that the files still have the same inode in the repo self.assertEqual( os.lstat(os.path.join(self.bak_path, b'hardlink2')).st_ino, os.lstat(os.path.join(self.bak_path, b'hardlink3')).st_ino) self.assertEqual( os.lstat(os.path.join(self.bak_path, b'hardlink3')).st_ino, os.lstat(os.path.join(self.bak_path, b'hardlink4')).st_ino) # restore the hardlinked files self.assertEqual( comtst.rdiff_backup_action(True, True, self.bak_path, self.to1_path, ("--api-version", "201"), b"restore", ()), 0) # verify that the files have been properly restored with same inodes self.assertEqual( os.lstat(os.path.join(self.to1_path, b'hardlink2')).st_ino, os.lstat(os.path.join(self.to1_path, b'hardlink3')).st_ino) self.assertEqual( os.lstat(os.path.join(self.to1_path, b'hardlink3')).st_ino, os.lstat(os.path.join(self.to1_path, b'hardlink4')).st_ino) # all tests were successful self.success = True
def test_check_failed_errorlog(self): """ Validate that one unreadable file doesn't fail the whole backup """ src_dir = os.path.join(comtst.old_test_dir, b"rpath2") base_dir = comtst.re_init_subdir(comtst.abs_test_dir, b"robust") target_dir = os.path.join(base_dir, b"bak") self.assertEqual(comtst.rdiff_backup_action( True, True, src_dir, target_dir, ("--api-version", "201"), b"backup", ()), 0)
def test_action_listincrements(self): """test the list increments action, without and with size""" # we need to use a regex for different timezones self.assertRegex( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201", "--parsable"), b"list", ("increments", ), return_stdout=True), b"""--- - base: increments.1970-01-0[12]T[0-9][0-9]:[14]6:40.*.dir time: 10000 type: directory - base: bak time: 20000 type: directory ... """) # we need to use a regex for different filesystem types # especially directories can have any kind of size self.assertRegex( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201", "--parsable"), b"list", ("increments", "--size"), return_stdout=True), b"""--- - size: [0-9]+ time: 10000 total_size: [0-9]+ - size: [0-9]+ time: 20000 total_size: [0-9]+ ... """) # all tests were successful self.success = True
def testReQuote(self): inrp = rpath.RPath(Globals.local_connection, os.path.join(ct.abs_test_dir, b"requote")) ct.re_init_rpath_dir(inrp) inrp.append("ABC_XYZ.1").touch() outrp = rpath.RPath(Globals.local_connection, ct.abs_output_dir) ct.re_init_rpath_dir(outrp) self.assertEqual( ct.rdiff_backup_action(True, True, inrp.path, outrp.path, ("--chars-to-quote", "A-C"), b"backup", ()), 0) time.sleep(1) inrp.append("ABC_XYZ.2").touch() # enforce a requote of the whole repository and see it refused self.assertNotEqual( ct.rdiff_backup_action(True, True, inrp.path, outrp.path, ("--chars-to-quote", "X-Z", "--force"), b"backup", ()), 0)
def test_action_test(self): """test the "test" action""" # the test action works with one or two locations (or more) self.assertEqual( comtst.rdiff_backup_action(False, False, b"/dummy1", b"/dummy2", (), b"test", ()), 0) self.assertEqual( comtst.rdiff_backup_action(False, True, b"/dummy1", None, (), b"test", ()), 0) # but it doesn't work with a local one self.assertNotEqual( comtst.rdiff_backup_action(False, True, b"/dummy1", b"/dummy2", (), b"test", ()), 0) # and it doesn't work without any location self.assertNotEqual( comtst.rdiff_backup_action(True, True, None, None, (), b"test", ()), 0)
def test_action_regress(self): """test different ways of regressing""" # regressing a successful backup doesn't do anything self.assertEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201"), b"regress", ()), 0) # we again simulate a crash _repo_shadow.ShadowRepo.touch_current_mirror( rpath.RPath(Globals.local_connection, self.bak_path, ("rdiff-backup-data", )), Time.timetostring(20000)) # the current process (the test) is still running, hence it fails self.assertNotEqual( comtst.rdiff_backup_action(True, None, self.bak_path, None, ("--api-version", "201"), b"regress", ()), 0) # but it runs with --force self.assertEqual( comtst.rdiff_backup_action(True, None, self.bak_path, None, ("--api-version", "201", "--force"), b"regress", ()), 0) # we restore and compare self.assertEqual( comtst.rdiff_backup_action(True, True, self.bak_path, self.to2_path, ("--api-version", "201"), b"restore", ()), 0) self.assertFalse(fileset.compare_paths(self.from2_path, self.to2_path)) # we again simulate a crash _repo_shadow.ShadowRepo.touch_current_mirror( rpath.RPath(Globals.local_connection, self.bak_path, ("rdiff-backup-data", )), Time.timetostring(10000)) # and then try to backup, which fails because without force self.assertNotEqual( comtst.rdiff_backup_action( True, True, self.from4_path, self.bak_path, ("--api-version", "201", "--current-time", "40000"), b"backup", ()), 0) # now with --force, it can't be exactly the same time or it fails # on error_log already existing self.assertEqual( comtst.rdiff_backup_action( True, True, self.from4_path, self.bak_path, ("--api-version", "201", "--current-time", "40001", "--force"), b"backup", ()), 0) # we restore and compare self.assertEqual( comtst.rdiff_backup_action(True, True, self.bak_path, self.to4_path, ("--api-version", "201"), b"restore", ()), 0) self.assertFalse(fileset.compare_paths(self.from4_path, self.to4_path)) # all tests were successful self.success = True
def test_action_removeincsolderthan(self): """test different ways of removing increments""" # removing multiple increments fails without --force self.assertNotEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201"), b"remove", ("increments", "--older-than", "1B")), 0) self.assertEqual( comtst.rdiff_backup_action( False, None, self.bak_path, None, ("--api-version", "201", "--force"), # now forcing! b"remove", ("increments", "--older-than", "1B")), 0) # then check that only one increment and mirror remain self.assertRegex( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201", "--parsable"), b"list", ("increments", ), return_stdout=True), b"""--- - base: increments.1970-01-0[12]T[0-9][0-9][:-][25]0[:-]00.*.dir time: 30000 type: directory - base: bak time: 40000 type: directory ... """) # check that nothing happens if no increment is old enough issue #616 self.assertEqual( comtst.rdiff_backup_action( False, None, self.bak_path, None, ("--api-version", "201", "--force"), b"remove", ("increments", "--older-than", "30000")), 0) self.assertRegex( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201", "--parsable"), b"list", ("increments", ), return_stdout=True), b"""--- - base: increments.1970-01-0[12]T[0-9][0-9][:-][25]0[:-]00.*.dir time: 30000 type: directory - base: bak time: 40000 type: directory ... """) # then remove the last increment self.assertEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ( "--api-version", "201", ), b"remove", ("increments", "--older-than", "30001")), 0) # and check that only the mirror is left self.assertEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201", "--parsable"), b"list", ("increments", ), return_stdout=True), b"""--- - base: bak time: 40000 type: directory ... """) # then try to remove the mirror self.assertEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ( "--api-version", "201", ), b"remove", ("increments", "--older-than", "now")), 0) # and check that it is still there self.assertEqual( comtst.rdiff_backup_action(False, None, self.bak_path, None, ("--api-version", "201", "--parsable"), b"list", ("increments", ), return_stdout=True), b"""--- - base: bak time: 40000 type: directory ... """) # all tests were successful self.success = True
def test_action_compare(self): """test different ways of comparing directories""" # first try without date self.assertNotEqual( comtst.rdiff_backup_action(False, True, self.from1_path, self.bak_path, ("--api-version", "201"), b"compare", ("--method", "meta")), 0) self.assertEqual( comtst.rdiff_backup_action(True, False, self.from2_path, self.bak_path, ("--api-version", "201"), b"compare", ("--method", "meta")), 0) # Note that the meta method doesn't recognize the differences # between from2 and from3 because only the hash differentiates them # then with date self.assertEqual( comtst.rdiff_backup_action(False, True, self.from1_path, self.bak_path, ("--api-version", "201"), b"compare", ("--at", "10000")), 0) self.assertNotEqual( comtst.rdiff_backup_action(True, False, self.from2_path, self.bak_path, ("--api-version", "201"), b"compare", ("--at", "15000")), 0) # then try to compare with hashes self.assertNotEqual( comtst.rdiff_backup_action(False, True, self.from1_path, self.bak_path, ("--api-version", "201"), b"compare", ("--method", "hash")), 0) self.assertEqual( comtst.rdiff_backup_action(True, False, self.from2_path, self.bak_path, ("--api-version", "201"), b"compare", ("--at", "now", "--method", "hash")), 0) self.assertEqual( comtst.rdiff_backup_action(False, False, self.from3_path, self.bak_path, ("--api-version", "201", "--parsable"), b"compare", ("--method", "hash"), return_stdout=True), b"""--- - path: fileChanged reason: metadata the same, data changed ... """) # then try to compare full self.assertNotEqual( comtst.rdiff_backup_action(False, True, self.from1_path, self.bak_path, ("--api-version", "201"), b"compare", ("--method", "full")), 0) self.assertEqual( comtst.rdiff_backup_action(True, False, self.from1_path, self.bak_path, ("--api-version", "201"), b"compare", ("--at", "1B", "--method", "full")), 0) self.assertEqual( comtst.rdiff_backup_action(True, True, self.from3_path, self.bak_path, ("--api-version", "201", "--parsable"), b"compare", ("--method", "full"), return_stdout=True), b"""--- - path: fileChanged reason: metadata the same, data changed ... """) # all tests were successful self.success = True