import sys, os
import re
import svntest
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
Skip = svntest.testcase.Skip_deco
SkipUnless = svntest.testcase.SkipUnless_deco
XFail = svntest.testcase.XFail_deco
Issues = svntest.testcase.Issues_deco
Issue = svntest.testcase.Issue_deco
Wimp = svntest.testcase.Wimp_deco
Item = svntest.wc.StateItem
mismatched_headers_re = re.compile(
"Prop-delta: .*|Text-content-sha1: .*|Text-copy-source-md5: .*|"
"Text-copy-source-sha1: .*|Text-delta-base-sha1: .*"
)
def build_repos(sbox):
"""Build an empty sandbox repository"""
svntest.main.safe_rmtree(sbox.repo_dir)
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
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)
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)
svnadmin_contents = svntest.actions.run_and_verify_dump(
svnadmin_sbox.repo_dir)
svntest.verify.compare_dump_files(
"Dump files", "DUMP", svnadmin_contents, svnrdump_contents)
def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None,
subdir = None, bypass_prop_validation = False,
ignore_base_checksums = False):
"""Load a dumpfile using 'svnadmin load', dump it with 'svnrdump
dump' and check that the same dumpfile is produced or that
expected_dumpfile_name is produced if provided. Additionally, the
subdir argument appends itself to the URL"""
build_repos(sbox)
svnrdump_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
'svnrdump_tests_data')
svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
dumpfile_name),
'rb').readlines()
svntest.actions.run_and_verify_load(sbox.repo_dir, svnadmin_dumpfile,
bypass_prop_validation)
repo_url = sbox.repo_url
if subdir:
repo_url = repo_url + subdir
svnrdump_dumpfile = \
svntest.actions.run_and_verify_svnrdump(None, svntest.verify.AnyOutput,
[], 0, '-q', 'dump',
repo_url)
if expected_dumpfile_name:
svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
expected_dumpfile_name),
'rb').readlines()
if ignore_base_checksums:
svnadmin_dumpfile = [l for l in svnadmin_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 = svntest.verify.UnorderedOutput(svnadmin_dumpfile)
svntest.verify.compare_and_display_lines(
"Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile,
None, mismatched_headers_re)
else:
compare_repos_dumps(sbox, svnadmin_dumpfile)
def run_load_test(sbox, dumpfile_name, expected_dumpfile_name = None,
expect_deltas = True):
"""Load a dumpfile using 'svnrdump load', dump it with 'svnadmin
dump' and check that the same dumpfile is produced"""
build_repos(sbox)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
svnrdump_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
'svnrdump_tests_data')
svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir,
dumpfile_name),
'rb').readlines()
uuid = svnrdump_dumpfile[2].split(' ')[1][:-1]
svntest.actions.run_and_verify_svnadmin2("Setting UUID", None, None, 0,
'setuuid', sbox.repo_dir,
uuid)
svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile,
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
svnadmin_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_name),
'rb').readlines()
svntest.verify.compare_and_display_lines(
"Dump files", "DUMP", svnrdump_dumpfile, svnadmin_dumpfile)
else:
compare_repos_dumps(sbox, svnrdump_dumpfile)
@Skip(svntest.main.is_ra_type_dav_serf)
def basic_dump(sbox):
"dump: standard sbox repos"
sbox.build(read_only = True, create_wc = False)
out = \
svntest.actions.run_and_verify_svnrdump(None, svntest.verify.AnyOutput,
[], 0, '-q', 'dump',
sbox.repo_url)
if not out[0].startswith('SVN-fs-dump-format-version:'):
raise svntest.Failure('No valid output')
@Skip(svntest.main.is_ra_type_dav_serf)
def revision_0_dump(sbox):
"dump: revision zero"
run_dump_test(sbox, "revision-0.dump")
def revision_0_load(sbox):
"load: revision zero"
run_load_test(sbox, "revision-0.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def skeleton_dump(sbox):
"dump: skeleton repository"
run_dump_test(sbox, "skeleton.dump")
def skeleton_load(sbox):
"load: skeleton repository"
run_load_test(sbox, "skeleton.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def sparse_propchanges_dump(sbox):
"dump: sparse file/dir propchanges"
run_dump_test(sbox, "sparse-propchanges.dump")
@Issue(3902)
def sparse_propchanges_load(sbox):
"load: sparse file/dir propchanges"
run_load_test(sbox, "sparse-propchanges.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def copy_and_modify_dump(sbox):
"dump: copy and modify"
run_dump_test(sbox, "copy-and-modify.dump")
def copy_and_modify_load(sbox):
"load: copy and modify"
run_load_test(sbox, "copy-and-modify.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def no_author_dump(sbox):
"dump: copy revs with no svn:author revprops"
run_dump_test(sbox, "no-author.dump")
def no_author_load(sbox):
"load: copy revs with no svn:author revprops"
run_load_test(sbox, "no-author.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def copy_from_previous_version_and_modify_dump(sbox):
"dump: copy from previous version and modify"
run_dump_test(sbox, "copy-from-previous-version-and-modify.dump")
def copy_from_previous_version_and_modify_load(sbox):
"load: copy from previous version and modify"
run_load_test(sbox, "copy-from-previous-version-and-modify.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def modified_in_place_dump(sbox):
"dump: modified in place"
run_dump_test(sbox, "modified-in-place.dump")
def modified_in_place_load(sbox):
"load: modified in place"
run_load_test(sbox, "modified-in-place.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def move_and_modify_in_the_same_revision_dump(sbox):
"dump: move parent & modify child file in same rev"
run_dump_test(sbox, "move-and-modify.dump")
def move_and_modify_in_the_same_revision_load(sbox):
"load: move parent & modify child file in same rev"
run_load_test(sbox, "move-and-modify.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def tag_empty_trunk_dump(sbox):
"dump: tag empty trunk"
run_dump_test(sbox, "tag-empty-trunk.dump")
def tag_empty_trunk_load(sbox):
"load: tag empty trunk"
run_load_test(sbox, "tag-empty-trunk.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def tag_trunk_with_file_dump(sbox):
"dump: tag trunk containing a file"
run_dump_test(sbox, "tag-trunk-with-file.dump")
def tag_trunk_with_file_load(sbox):
"load: tag trunk containing a file"
run_load_test(sbox, "tag-trunk-with-file.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def tag_trunk_with_file2_dump(sbox):
"dump: tag trunk containing a file (#2)"
run_dump_test(sbox, "tag-trunk-with-file2.dump")
def tag_trunk_with_file2_load(sbox):
"load: tag trunk containing a file (#2)"
run_load_test(sbox, "tag-trunk-with-file2.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def dir_prop_change_dump(sbox):
"dump: directory property changes"
run_dump_test(sbox, "dir-prop-change.dump")
def dir_prop_change_load(sbox):
"load: directory property changes"
run_load_test(sbox, "dir-prop-change.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def copy_parent_modify_prop_dump(sbox):
"dump: copy parent and modify prop"
run_dump_test(sbox, "copy-parent-modify-prop.dump")
def copy_parent_modify_prop_load(sbox):
"load: copy parent and modify prop"
run_load_test(sbox, "copy-parent-modify-prop.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def copy_revprops_dump(sbox):
"dump: copy revprops other than svn:*"
run_dump_test(sbox, "revprops.dump")
def copy_revprops_load(sbox):
"load: copy revprops other than svn:*"
run_load_test(sbox, "revprops.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def only_trunk_dump(sbox):
"dump: subdirectory"
run_dump_test(sbox, "trunk-only.dump", subdir="/trunk",
expected_dumpfile_name="trunk-only.expected.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def only_trunk_A_with_changes_dump(sbox):
"dump: subdirectory with changes on root"
run_dump_test(sbox, "trunk-A-changes.dump", subdir="/trunk/A",
expected_dumpfile_name="trunk-A-changes.expected.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def url_encoding_dump(sbox):
"dump: url encoding issues"
run_dump_test(sbox, "url-encoding-bug.dump")
def url_encoding_load(sbox):
"load: url encoding issues"
run_load_test(sbox, "url-encoding-bug.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def copy_bad_line_endings_dump(sbox):
"dump: inconsistent line endings in svn:* props"
run_dump_test(sbox, "copy-bad-line-endings.dump",
expected_dumpfile_name="copy-bad-line-endings.expected.dump",
bypass_prop_validation=True)
@Issue(4263)
def copy_bad_line_endings_load(sbox):
"load: inconsistent line endings in svn:* props"
run_load_test(sbox, "copy-bad-line-endings.dump",
expected_dumpfile_name="copy-bad-line-endings.expected.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def copy_bad_line_endings2_dump(sbox):
"dump: non-LF line endings in svn:* props"
run_dump_test(sbox, "copy-bad-line-endings2.dump",
expected_dumpfile_name="copy-bad-line-endings2.expected.dump",
bypass_prop_validation=True, ignore_base_checksums=True)
@Skip(svntest.main.is_ra_type_dav_serf)
def commit_a_copy_of_root_dump(sbox):
"dump: commit a copy of root"
run_dump_test(sbox, "repo-with-copy-of-root-dir.dump")
def commit_a_copy_of_root_load(sbox):
"load: commit a copy of root"
run_load_test(sbox, "repo-with-copy-of-root-dir.dump")
@Skip(svntest.main.is_ra_type_dav_serf)
def descend_into_replace_dump(sbox):
"dump: descending into replaced dir looks in src"
run_dump_test(sbox, "descend-into-replace.dump", subdir='/trunk/H',
expected_dumpfile_name = "descend-into-replace.expected.dump")
def descend_into_replace_load(sbox):
"load: descending into replaced dir looks in src"
run_load_test(sbox, "descend-into-replace.dump")
@Issue(3847)
@Skip(svntest.main.is_ra_type_dav_serf)
def add_multi_prop_dump(sbox):
"dump: add with multiple props"
run_dump_test(sbox, "add-multi-prop.dump")
@Issue(3844)
def multi_prop_edit_load(sbox):
"load: multiple prop edits on a file"
run_load_test(sbox, "multi-prop-edits.dump", None, False)
@Issue(3890)
@Skip(svntest.main.is_ra_type_dav_serf)
def reflect_dropped_renumbered_revs(sbox):
"svnrdump renumbers dropped revs in mergeinfo"
build_repos(sbox)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
dump_file = open(os.path.join(os.path.dirname(sys.argv[0]),
'svnrdump_tests_data',
'with_merges.dump'),
'rb')
svnrdump_dumpfile = dump_file.readlines()
dump_file.close()
svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile,
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
svntest.actions.run_and_verify_svn(None, ['\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,
svntest.verify.AnyOutput,
[], 0, 'load',
sbox.repo_url + "/toplevel")
url = sbox.repo_url
expected_output = svntest.verify.UnorderedOutput([
url + "/trunk - /branch1:4-8\n",
url + "/toplevel/trunk - /toplevel/branch1:14-18\n",
])
svntest.actions.run_and_verify_svn(None, expected_output, [],
'propget', 'svn:mergeinfo', '-R',
sbox.repo_url)
@Issue(3890)
@Skip(svntest.main.is_ra_type_dav_serf)
def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox):
"don't drop mergeinfo revs in incremental svnrdump"
test_create(sbox)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
dump_fp = open(os.path.join(os.path.dirname(sys.argv[0]),
'svnrdump_tests_data',
'mergeinfo_included_full.dump'),
'rb')
dumpfile_full = dump_fp.readlines()
dump_fp.close()
svntest.actions.run_and_verify_svnrdump(dumpfile_full,
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
url = sbox.repo_url + '/branches/'
expected_output = svntest.verify.UnorderedOutput([
url + "B1 - /branches/B2:11-12\n",
"/trunk:6,9\n",
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, [],
'propget', 'svn:mergeinfo', '-R',
sbox.repo_url)
dump_file_r1_10 = svntest.main.temp_dir + "-r1-10.dump"
output = svntest.actions.run_and_verify_svnrdump(None,
svntest.verify.AnyOutput,
[], 0, '-q', 'dump', '-r1:10',
sbox.repo_url)
dump_fp = open(dump_file_r1_10, 'wb')
dump_fp.writelines(output)
dump_fp.close()
dump_file_r11_13 = svntest.main.temp_dir + "-r11-13.dump"
output = svntest.actions.run_and_verify_svnrdump(None,
svntest.verify.AnyOutput,
[], 0, '-q', 'dump',
'--incremental', '-r11:13',
sbox.repo_url)
dump_fp = open(dump_file_r11_13, 'wb')
dump_fp.writelines(output)
dump_fp.close()
dump_file_r14_15 = svntest.main.temp_dir + "-r14-15.dump"
output = svntest.actions.run_and_verify_svnrdump(None,
svntest.verify.AnyOutput,
[], 0, '-q', 'dump',
'--incremental', '-r14:15',
sbox.repo_url)
dump_fp = open(dump_file_r14_15, 'wb')
dump_fp.writelines(output)
dump_fp.close()
test_create(sbox)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
dump_fp = open(dump_file_r1_10, 'rb')
svntest.actions.run_and_verify_svnrdump(dump_fp.readlines(),
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
dump_fp.close()
dump_fp = open(dump_file_r11_13, 'rb')
svntest.actions.run_and_verify_svnrdump(dump_fp.readlines(),
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
dump_fp.close()
dump_fp = open(dump_file_r14_15, 'rb')
svntest.actions.run_and_verify_svnrdump(dump_fp.readlines(),
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
dump_fp.close()
svntest.actions.run_and_verify_svn(None, expected_output, [],
'propget', 'svn:mergeinfo', '-R',
sbox.repo_url)
test_create(sbox)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
dump_fp = open(os.path.join(os.path.dirname(sys.argv[0]),
'svnrdump_tests_data',
'skeleton.dump'),
'rb')
dumpfile_skeleton = dump_fp.readlines()
dump_fp.close()
svntest.actions.run_and_verify_svnrdump(dumpfile_skeleton,
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
svntest.actions.run_and_verify_svnrdump(dumpfile_full,
svntest.verify.AnyOutput,
[], 0, 'load',
sbox.repo_url + '/Projects/Project-X')
url = sbox.repo_url + '/Projects/Project-X/branches/'
expected_output = svntest.verify.UnorderedOutput([
url + "B1 - /Projects/Project-X/branches/B2:17-18\n",
"/Projects/Project-X/trunk:12,15\n",
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, [],
'propget', 'svn:mergeinfo', '-R',
sbox.repo_url)
test_create(sbox)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
svntest.actions.run_and_verify_svnrdump(dumpfile_skeleton,
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
dump_fp = open(dump_file_r1_10, 'rb')
svntest.actions.run_and_verify_svnrdump(dump_fp.readlines(),
svntest.verify.AnyOutput,
[], 0, 'load',
sbox.repo_url + '/Projects/Project-X')
dump_fp.close()
dump_fp = open(dump_file_r11_13, 'rb')
svntest.actions.run_and_verify_svnrdump(dump_fp.readlines(),
svntest.verify.AnyOutput,
[], 0, 'load',
sbox.repo_url + '/Projects/Project-X')
dump_fp.close()
dump_fp = open(dump_file_r14_15, 'rb')
svntest.actions.run_and_verify_svnrdump(dump_fp.readlines(),
svntest.verify.AnyOutput,
[], 0, 'load',
sbox.repo_url + '/Projects/Project-X')
dump_fp.close()
svntest.actions.run_and_verify_svn(None, expected_output, [],
'propget', 'svn:mergeinfo', '-R',
sbox.repo_url)
@Issue(3890)
def svnrdump_load_partial_incremental_dump(sbox):
"svnrdump load partial incremental dump"
build_repos(sbox)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 1.\n'],
[], "mkdir", sbox.repo_url + "/A",
"-m", "Create toplevel dir to load into")
dump_file = open(os.path.join(os.path.dirname(sys.argv[0]),
'svnrdump_tests_data',
'partial_incremental.dump'),
'rb')
svnrdump_dumpfile = dump_file.readlines()
dump_file.close()
svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile,
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
test_list = [ None,
basic_dump,
revision_0_dump,
revision_0_load,
skeleton_dump,
skeleton_load,
sparse_propchanges_dump,
sparse_propchanges_load,
copy_and_modify_dump,
copy_and_modify_load,
copy_from_previous_version_and_modify_dump,
copy_from_previous_version_and_modify_load,
modified_in_place_dump,
modified_in_place_load,
tag_empty_trunk_dump,
tag_empty_trunk_load,
tag_trunk_with_file_dump,
tag_trunk_with_file_load,
tag_trunk_with_file2_dump,
tag_trunk_with_file2_load,
dir_prop_change_dump,
dir_prop_change_load,
copy_parent_modify_prop_dump,
copy_parent_modify_prop_load,
url_encoding_dump,
url_encoding_load,
copy_revprops_dump,
copy_revprops_load,
only_trunk_dump,
only_trunk_A_with_changes_dump,
no_author_dump,
no_author_load,
move_and_modify_in_the_same_revision_dump,
move_and_modify_in_the_same_revision_load,
copy_bad_line_endings_dump,
copy_bad_line_endings_load,
copy_bad_line_endings2_dump,
commit_a_copy_of_root_dump,
commit_a_copy_of_root_load,
descend_into_replace_dump,
descend_into_replace_load,
add_multi_prop_dump,
multi_prop_edit_load,
reflect_dropped_renumbered_revs,
dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads,
svnrdump_load_partial_incremental_dump,
]
if __name__ == '__main__':
svntest.main.run_tests(test_list)