diff options
Diffstat (limited to 'subversion/tests/cmdline/svnrdump_tests.py')
-rwxr-xr-x | subversion/tests/cmdline/svnrdump_tests.py | 189 |
1 files changed, 130 insertions, 59 deletions
diff --git a/subversion/tests/cmdline/svnrdump_tests.py b/subversion/tests/cmdline/svnrdump_tests.py index 334bd15..1b564d7 100755 --- a/subversion/tests/cmdline/svnrdump_tests.py +++ b/subversion/tests/cmdline/svnrdump_tests.py @@ -34,7 +34,6 @@ from svntest.verify import SVNUnexpectedStdout, SVNUnexpectedStderr from svntest.verify import SVNExpectedStderr from svntest.main import write_restrictive_svnserve_conf from svntest.main import server_has_partial_replay -from svnadmin_tests import test_create # (abbreviation) Skip = svntest.testcase.Skip_deco @@ -61,36 +60,27 @@ mismatched_headers_re = re.compile( ###################################################################### # Helper routines -def build_repos(sbox): - """Build an empty sandbox repository""" - - # Cleanup after the last run by removing any left-over repository. - svntest.main.safe_rmtree(sbox.repo_dir) - - # Create an empty repository. - svntest.main.create_repos(sbox.repo_dir) - -def compare_repos_dumps(svnrdump_sbox, svnadmin_dumpfile): - """Compare two dumpfiles, one created from SVNRDUMP_SBOX, and other given - by SVNADMIN_DUMPFILE. The dumpfiles do not need to match linewise, as the - SVNADMIN_DUMPFILE contents will first be loaded into a repository and then +def compare_repos_dumps(sbox, other_dumpfile, + bypass_prop_validation=False): + """Compare two dumpfiles, one created from SBOX, and other given + by OTHER_DUMPFILE. The dumpfiles do not need to match linewise, as the + OTHER_DUMPFILE contents will first be loaded into a repository and then re-dumped to do the match, which should generate the same dumpfile as - dumping SVNRDUMP_SBOX.""" - - svnrdump_contents = svntest.actions.run_and_verify_dump( - svnrdump_sbox.repo_dir) + dumping SBOX.""" - svnadmin_sbox = svnrdump_sbox.clone_dependent() - svntest.main.safe_rmtree(svnadmin_sbox.repo_dir) - svntest.main.create_repos(svnadmin_sbox.repo_dir) - svntest.actions.run_and_verify_load(svnadmin_sbox.repo_dir, svnadmin_dumpfile) + sbox_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir) - svnadmin_contents = svntest.actions.run_and_verify_dump( - svnadmin_sbox.repo_dir) + # Load and dump the other dumpfile (using svnadmin) + other_sbox = sbox.clone_dependent() + other_sbox.build(create_wc=False, empty=True) + svntest.actions.run_and_verify_load(other_sbox.repo_dir, other_dumpfile, + bypass_prop_validation) + other_dumpfile = svntest.actions.run_and_verify_dump(other_sbox.repo_dir) + ### This call kind-of assumes EXPECTED is first and ACTUAL is second. svntest.verify.compare_dump_files( - "Dump files", "DUMP", svnadmin_contents, svnrdump_contents) + "Dump files", "DUMP", other_dumpfile, sbox_dumpfile) def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None, subdir = None, bypass_prop_validation = False, @@ -103,7 +93,7 @@ def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None, array of optional additional options to pass to 'svnrdump dump'.""" # Create an empty sandbox repository - build_repos(sbox) + sbox.build(create_wc=False, empty=True) # This directory contains all the dump files svnrdump_tests_dir = os.path.join(os.path.dirname(sys.argv[0]), @@ -111,11 +101,10 @@ def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None, # Load the specified dump file into the sbox repository using # svnadmin load - svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir, + original_dumpfile = open(os.path.join(svnrdump_tests_dir, dumpfile_name), 'rb').readlines() - - svntest.actions.run_and_verify_load(sbox.repo_dir, svnadmin_dumpfile, + svntest.actions.run_and_verify_load(sbox.repo_dir, original_dumpfile, bypass_prop_validation) repo_url = sbox.repo_url @@ -129,28 +118,29 @@ def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None, [], 0, *opts) if expected_dumpfile_name: - svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir, + expected_dumpfile = open(os.path.join(svnrdump_tests_dir, expected_dumpfile_name), 'rb').readlines() # Compare the output from stdout if ignore_base_checksums: - svnadmin_dumpfile = [l for l in svnadmin_dumpfile + expected_dumpfile = [l for l in expected_dumpfile if not l.startswith('Text-delta-base-md5')] svnrdump_dumpfile = [l for l in svnrdump_dumpfile if not l.startswith('Text-delta-base-md5')] - svnadmin_dumpfile = [l for l in svnadmin_dumpfile + expected_dumpfile = [l for l in expected_dumpfile if not mismatched_headers_re.match(l)] svnrdump_dumpfile = [l for l in svnrdump_dumpfile if not mismatched_headers_re.match(l)] - svnadmin_dumpfile = svntest.verify.UnorderedOutput(svnadmin_dumpfile) + expected_dumpfile = svntest.verify.UnorderedOutput(expected_dumpfile) svntest.verify.compare_and_display_lines( - "Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile, + "Dump files", "DUMP", expected_dumpfile, svnrdump_dumpfile, None) else: - compare_repos_dumps(sbox, svnadmin_dumpfile) + # The expected dumpfile is the result of dumping SBOX. + compare_repos_dumps(sbox, svnrdump_dumpfile, bypass_prop_validation) def run_load_test(sbox, dumpfile_name, expected_dumpfile_name = None, expect_deltas = True): @@ -158,7 +148,7 @@ def run_load_test(sbox, dumpfile_name, expected_dumpfile_name = None, dump' and check that the same dumpfile is produced""" # Create an empty sandbox repository - build_repos(sbox) + sbox.build(create_wc=False, empty=True) # Create the revprop-change hook for this test svntest.actions.enable_revprop_changes(sbox.repo_dir) @@ -169,36 +159,37 @@ def run_load_test(sbox, dumpfile_name, expected_dumpfile_name = None, # Load the specified dump file into the sbox repository using # svnrdump load - svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir, + original_dumpfile = open(os.path.join(svnrdump_tests_dir, dumpfile_name), 'rb').readlines() # Set the UUID of the sbox repository to the UUID specified in the # dumpfile ### RA layer doesn't have a set_uuid functionality - uuid = svnrdump_dumpfile[2].split(' ')[1][:-1] - svntest.actions.run_and_verify_svnadmin2("Setting UUID", None, None, 0, + uuid = original_dumpfile[2].split(' ')[1][:-1] + svntest.actions.run_and_verify_svnadmin2(None, None, 0, 'setuuid', sbox.repo_dir, uuid) - svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile, + svntest.actions.run_and_verify_svnrdump(original_dumpfile, svntest.verify.AnyOutput, [], 0, 'load', sbox.repo_url) - # Create a dump file using svnadmin dump - svnadmin_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, + # Re-dump the rdump-loaded repo using svnadmin dump + resulted_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, expect_deltas) if expected_dumpfile_name: - svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir, + expected_dumpfile = open(os.path.join(svnrdump_tests_dir, expected_dumpfile_name), 'rb').readlines() # Compare the output from stdout svntest.verify.compare_and_display_lines( - "Dump files", "DUMP", svnrdump_dumpfile, svnadmin_dumpfile) + "Dump files", "DUMP", expected_dumpfile, resulted_dumpfile) else: - compare_repos_dumps(sbox, svnrdump_dumpfile) + expected_dumpfile = original_dumpfile + compare_repos_dumps(sbox, expected_dumpfile) ###################################################################### # Tests @@ -410,7 +401,7 @@ def reflect_dropped_renumbered_revs(sbox): "svnrdump renumbers dropped revs in mergeinfo" # Create an empty sandbox repository - build_repos(sbox) + sbox.build(create_wc=False, empty=True) # Create the revprop-change hook for this test svntest.actions.enable_revprop_changes(sbox.repo_dir) @@ -431,7 +422,8 @@ def reflect_dropped_renumbered_revs(sbox): # Create the 'toplevel' directory in repository and then load the same # dumpfile into that subtree. - svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 10.\n'], + svntest.actions.run_and_verify_svn(['Committing transaction...\n', + 'Committed revision 10.\n'], [], "mkdir", sbox.repo_url + "/toplevel", "-m", "Create toplevel dir to load into") svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile, @@ -444,7 +436,7 @@ def reflect_dropped_renumbered_revs(sbox): url + "/trunk - /branch1:4-8\n", url + "/toplevel/trunk - /toplevel/branch1:14-18\n", ]) - svntest.actions.run_and_verify_svn(None, expected_output, [], + svntest.actions.run_and_verify_svn(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) @@ -473,7 +465,7 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): "don't drop mergeinfo revs in incremental svnrdump" # Create an empty repos. - test_create(sbox) + sbox.build(empty=True) # Create the revprop-change hook for this test svntest.actions.enable_revprop_changes(sbox.repo_dir) @@ -488,7 +480,7 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): # | | | | # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | # r1 | | | | | | - # intial | | | |______ | | + # initial | | | |______ | | # import copy | copy | merge merge # | | | merge (r5) (r8) # | | | (r9) | | @@ -542,7 +534,7 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): url + "B2 - /trunk:9\n", url + "B1/B/E - /branches/B2/B/E:11-12\n", "/trunk/B/E:5-6,8-9\n"]) - svntest.actions.run_and_verify_svn(None, expected_output, [], + svntest.actions.run_and_verify_svn(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) @@ -579,7 +571,8 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): dump_fp.close() # Blow away the current repos and create an empty one in its place. - test_create(sbox) + svntest.main.safe_rmtree(sbox.repo_dir, True) # Fix race with bdb in svnserve + sbox.build(empty=True) # Create the revprop-change hook for this test svntest.actions.enable_revprop_changes(sbox.repo_dir) @@ -604,7 +597,7 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): # Check the mergeinfo, we use the same expected output as before, # as it (duh!) should be exactly the same as when we loaded the # repos in one shot. - svntest.actions.run_and_verify_svn(None, expected_output, [], + svntest.actions.run_and_verify_svn(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) @@ -614,7 +607,8 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): # PART 3: Load a full dump to an non-empty repository. # # Reset our sandbox. - test_create(sbox) + svntest.main.safe_rmtree(sbox.repo_dir, True) # Fix race with bdb in svnserve + sbox.build(empty=True) # Create the revprop-change hook for this test svntest.actions.enable_revprop_changes(sbox.repo_dir) @@ -668,14 +662,15 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): url + "B2 - /Projects/Project-X/trunk:15\n", url + "B1/B/E - /Projects/Project-X/branches/B2/B/E:17-18\n", "/Projects/Project-X/trunk/B/E:11-12,14-15\n"]) - svntest.actions.run_and_verify_svn(None, expected_output, [], + svntest.actions.run_and_verify_svn(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) # PART 4: Load a a series of incremental dumps to an non-empty repository. # # Reset our sandbox. - test_create(sbox) + svntest.main.safe_rmtree(sbox.repo_dir, True) # Fix race with bdb in svnserve + sbox.build(empty=True) # Create the revprop-change hook for this test svntest.actions.enable_revprop_changes(sbox.repo_dir) @@ -710,7 +705,7 @@ def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox): # Check the resulting mergeinfo. We expect the exact same results # as Part 3. # See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16. - svntest.actions.run_and_verify_svn(None, expected_output, [], + svntest.actions.run_and_verify_svn(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) @@ -720,14 +715,15 @@ def svnrdump_load_partial_incremental_dump(sbox): "svnrdump load partial incremental dump" # Create an empty sandbox repository - build_repos(sbox) + sbox.build(create_wc=False, empty=True) # Create the revprop-change hook for this test svntest.actions.enable_revprop_changes(sbox.repo_dir) # Create the 'A' directory in repository and then load the partial # incremental dump into the root of the repository. - svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 1.\n'], + svntest.actions.run_and_verify_svn(['Committing transaction...\n', + 'Committed revision 1.\n'], [], "mkdir", sbox.repo_url + "/A", "-m", "Create toplevel dir to load into") @@ -769,6 +765,53 @@ def only_trunk_A_range_dump(sbox): #---------------------------------------------------------------------- +@Issue(4490) +def load_prop_change_in_non_deltas_dump(sbox): + "load: prop change in non-deltas dump" + # 'svnrdump load' crashed when processing a node record with a non-delta + # properties block if the node previously had any svn:* properties. + + sbox.build() + sbox.simple_propset('svn:eol-style', 'native', 'iota', 'A/mu', 'A/B/lambda') + sbox.simple_commit() + + # Any prop change on a node that had an svn:* prop triggered the crash, + # so test an svn:* prop deletion and also some other prop changes. + sbox.simple_propdel('svn:eol-style', 'iota') + sbox.simple_propset('svn:eol-style', 'LF', 'A/mu') + sbox.simple_propset('p1', 'v1', 'A/B/lambda') + sbox.simple_commit() + + # Create a non-deltas dump. Use 'svnadmin', as svnrdump doesn't have that + # option. + dump = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False) + + # Try to load that dump. + sbox.build(create_wc=False, empty=True) + svntest.actions.enable_revprop_changes(sbox.repo_dir) + svntest.actions.run_and_verify_svnrdump(dump, + [], [], 0, + '-q', 'load', sbox.repo_url) + +#---------------------------------------------------------------------- + +@Issue(4476) +def dump_mergeinfo_contains_r0(sbox): + "dump: mergeinfo that contains r0" + ### We pass the original dump file name as 'expected_dumpfile_name' because + ### run_dump_test is currently broken when we don't. + run_dump_test(sbox, "mergeinfo-contains-r0.dump", + bypass_prop_validation=True) + +#---------------------------------------------------------------------- + +@XFail() +@Issue(4476) +def load_mergeinfo_contains_r0(sbox): + "load: mergeinfo that contains r0" + run_load_test(sbox, "mergeinfo-contains-r0.dump", + expected_dumpfile_name="mergeinfo-contains-r0.expected.dump") + #---------------------------------------------------------------------- # Regression test for issue 4551 "svnrdump load commits wrong properties, @@ -870,6 +913,30 @@ def load_non_deltas_replace_copy_with_props(sbox): actual = map(str.strip, out) svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual) +# Regression test for issue #4552 "svnrdump writes duplicate headers for a +# replace-with-copy". 'svnrdump dump' wrote the Node-path and Node-kind +# headers twice for the 'delete' record of a replace-with-copy. +@Issue(4552) +def dump_replace_with_copy(sbox): + "dump replace with copy" + sbox.build() + + # Copy file/dir, replacing something + sbox.simple_rm('A/D/gamma', 'A/C') + sbox.simple_copy('A/mu@1', 'A/D/gamma') + sbox.simple_copy('A/B@1', 'A/C') + sbox.simple_commit() + + # Dump with 'svnrdump' + dumpfile = svntest.actions.run_and_verify_svnrdump( + None, svntest.verify.AnyOutput, [], 0, + 'dump', '--quiet', '--incremental', '-r2', + sbox.repo_url) + + # Check the 'delete' record headers: expect this parse to fail if headers + # are duplicated + svntest.verify.DumpParser(dumpfile).parse() + # Regression test for issue 4551 "svnrdump load commits wrong properties, # or fails, on a non-deltas dumpfile". In this test, a node's props are # modified, and the failure mode is that RA-serf would end up deleting @@ -969,8 +1036,12 @@ test_list = [ None, range_dump, only_trunk_range_dump, only_trunk_A_range_dump, + load_prop_change_in_non_deltas_dump, + dump_mergeinfo_contains_r0, + load_mergeinfo_contains_r0, load_non_deltas_copy_with_props, load_non_deltas_replace_copy_with_props, + dump_replace_with_copy, load_non_deltas_with_props, ] |