summaryrefslogtreecommitdiff
path: root/subversion/tests/cmdline/svnrdump_tests.py
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/tests/cmdline/svnrdump_tests.py')
-rwxr-xr-xsubversion/tests/cmdline/svnrdump_tests.py189
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,
]