You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/11/30 11:24:23 UTC
svn commit: r1717223 [46/50] - in /subversion/branches/ra-git: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/
contrib/hook-scripts/ notes/ notes/api-errata/1.9/ notes/move-tracking/
subversion/ subversion/bindings/ctypes-python/...
Modified: subversion/branches/ra-git/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/prop_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/prop_tests.py Mon Nov 30 10:24:16 2015
@@ -2666,13 +2666,37 @@ def xml_unsafe_author2(sbox):
else:
expected_author = 'foo\bbar'
- expected_output = svntest.verify.UnorderedOutput([
- ' 1 %-8s Jan 01 2000 ./\n' % expected_author,
- ' 1 %-8s Jan 01 2000 A/\n' % expected_author,
- ' 1 %-8s 25 Jan 01 2000 iota\n' % expected_author
- ])
+ # Use svn ls in --xml mode to test locale independent output.
+ expected_output = [
+ '<?xml version="1.0" encoding="UTF-8"?>\n',
+ '<lists>\n',
+ '<list\n',
+ ' path="%s">\n' % sbox.repo_url,
+ '<entry\n',
+ ' kind="dir">\n',
+ '<name>A</name>\n',
+ '<commit\n',
+ ' revision="1">\n',
+ '<author>%s</author>\n' % expected_author,
+ '<date>2000-01-01T12:00:00.000000Z</date>\n',
+ '</commit>\n',
+ '</entry>\n',
+ '<entry\n',
+ ' kind="file">\n',
+ '<name>iota</name>\n',
+ '<size>25</size>\n',
+ '<commit\n',
+ ' revision="1">\n',
+ '<author>%s</author>\n' % expected_author,
+ '<date>2000-01-01T12:00:00.000000Z</date>\n',
+ '</commit>\n',
+ '</entry>\n',
+ '</list>\n',
+ '</lists>\n'
+ ]
+
svntest.actions.run_and_verify_svn(expected_output, [],
- 'ls', '-v', repo_url)
+ 'ls', '--xml', repo_url)
expected_info = [{
'Repository Root' : sbox.repo_url,
@@ -2716,11 +2740,8 @@ def dir_prop_conflict_details(sbox):
None,
expected_status,
check_props=True)
-
- # The conflict properties file line was shown for previous versions, but the
- # conflict source urls are new since 1.8.
expected_info = {
- 'Conflict Properties File' : re.escape(sbox.ospath('A/dir_conflicts.prej')),
+ 'Conflicted Properties' : 'my-prop',
'Conflict Details': re.escape('incoming dir edit upon update'
+ ' Source left: (dir) ^/A@1'
+ ' Source right: (dir) ^/A@2')
@@ -2783,6 +2804,31 @@ def wc_propop_on_url(sbox):
'pg', 'my:Q', '-r', 'PREV',
sbox.repo_url)
+def prop_conflict_root(sbox):
+ """property conflict on wc root"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_propset('propname', 'propval1', '')
+ sbox.simple_commit()
+ sbox.simple_propset('propname', 'propval2', '')
+ sbox.simple_commit()
+ sbox.simple_update(revision=2)
+ sbox.simple_propset('propname', 'propvalconflict', '')
+
+ expected_output = svntest.wc.State(wc_dir, {
+ '' : Item(status=' C'),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+ expected_status.tweak('', status=' C')
+ extra_files = ['dir_conflicts.prej']
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ extra_files=extra_files)
########################################################################
# Run the tests
@@ -2834,6 +2880,7 @@ test_list = [ None,
dir_prop_conflict_details,
iprops_list_abspath,
wc_propop_on_url,
+ prop_conflict_root,
]
if __name__ == '__main__':
Modified: subversion/branches/ra-git/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/revert_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/revert_tests.py Mon Nov 30 10:24:16 2015
@@ -1630,7 +1630,13 @@ def revert_obstructing_wc(sbox):
svntest.actions.run_and_verify_svn("Skipped '.*A' -- .*obstruct.*", [],
'revert', '-R', wc_dir)
+def revert_moved_dir_partial(sbox):
+ "partial revert moved_dir"
+ sbox.build(read_only = True)
+
+ sbox.simple_move('A', 'A_')
+ svntest.actions.run_and_verify_svn(None, [], 'revert', sbox.ospath('A'))
########################################################################
@@ -1673,6 +1679,7 @@ test_list = [ None,
revert_with_unversioned_targets,
revert_nonexistent,
revert_obstructing_wc,
+ revert_moved_dir_partial,
]
if __name__ == '__main__':
Modified: subversion/branches/ra-git/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/stat_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/stat_tests.py Mon Nov 30 10:24:16 2015
@@ -1598,44 +1598,81 @@ def status_dash_u_deleted_directories(sb
# check status -u of B
expected = svntest.verify.UnorderedOutput(
- ["D 1 %s\n" % "B",
- "D 1 %s\n" % os.path.join("B", "lambda"),
- "D 1 %s\n" % os.path.join("B", "E"),
- "D 1 %s\n" % os.path.join("B", "E", "alpha"),
- "D 1 %s\n" % os.path.join("B", "E", "beta"),
- "D 1 %s\n" % os.path.join("B", "F"),
+ ["D 1 1 jrandom %s\n" % \
+ "B",
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("B", "lambda"),
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("B", "E"),
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("B", "E", "alpha"),
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("B", "E", "beta"),
+ "D 1 1 jrandom %s\n" %
+ os.path.join("B", "F"),
"Status against revision: 1\n" ])
svntest.actions.run_and_verify_svn(expected,
[],
+ "status", "-u", "-v", "B")
+
+ expected = \
+ ["D 1 %s\n" % "B",
+ "Status against revision: 1\n" ]
+ svntest.actions.run_and_verify_svn(expected,
+ [],
"status", "-u", "B")
+
# again, but now from inside B, should give the same output
if not os.path.exists('B'):
os.mkdir('B')
os.chdir("B")
expected = svntest.verify.UnorderedOutput(
- ["D 1 %s\n" % ".",
- "D 1 %s\n" % "lambda",
- "D 1 %s\n" % "E",
- "D 1 %s\n" % os.path.join("E", "alpha"),
- "D 1 %s\n" % os.path.join("E", "beta"),
- "D 1 %s\n" % "F",
+ ["D 1 1 jrandom %s\n" % \
+ ".",
+ "D 1 1 jrandom %s\n" % \
+ "lambda",
+ "D 1 1 jrandom %s\n" % \
+ "E",
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("E", "alpha"),
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("E", "beta"),
+ "D 1 1 jrandom %s\n" % \
+ "F",
"Status against revision: 1\n" ])
svntest.actions.run_and_verify_svn(expected,
[],
+ "status", "-u", "-v", ".")
+
+ expected = \
+ ["D 1 %s\n" % ".",
+ "Status against revision: 1\n" ]
+ svntest.actions.run_and_verify_svn(expected,
+ [],
"status", "-u", ".")
# check status -u of B/E
expected = svntest.verify.UnorderedOutput(
- ["D 1 %s\n" % os.path.join("B", "E"),
- "D 1 %s\n" % os.path.join("B", "E", "alpha"),
- "D 1 %s\n" % os.path.join("B", "E", "beta"),
+ ["D 1 1 jrandom %s\n" % \
+ os.path.join("B", "E"),
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("B", "E", "alpha"),
+ "D 1 1 jrandom %s\n" % \
+ os.path.join("B", "E", "beta"),
"Status against revision: 1\n" ])
os.chdir(was_cwd)
os.chdir(A_path)
svntest.actions.run_and_verify_svn(expected,
[],
+ "status", "-u", "-v",
+ os.path.join("B", "E"))
+
+
+ expected = [ "Status against revision: 1\n" ]
+ svntest.actions.run_and_verify_svn(expected,
+ [],
"status", "-u",
os.path.join("B", "E"))
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svnadmin_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svnadmin_tests.py Mon Nov 30 10:24:16 2015
@@ -147,7 +147,7 @@ def check_hotcopy_fsfs_fsx(src, dst):
# the hotcopy destination (i.e. a fresh cache generation)
if src_file == 'revprop-generation':
f2 = open(dst_path, 'r')
- revprop_gen = int(f2.read().strip().split()[1])
+ revprop_gen = int(f2.read().strip())
if revprop_gen != 0:
raise svntest.Failure("Hotcopy destination has non-zero " +
"revprop generation")
@@ -249,6 +249,18 @@ def patch_format(repo_dir, shard_size):
os.chmod(format_path, 0666)
open(format_path, 'wb').write(new_contents)
+def is_sharded(repo_dir):
+ """Return whether the FSFS repository REPO_DIR is sharded."""
+
+ format_path = os.path.join(repo_dir, "db", "format")
+ contents = open(format_path, 'rb').read()
+
+ for line in contents.split("\n"):
+ if line.startswith("layout sharded"):
+ return True
+
+ return False
+
def load_and_verify_dumpstream(sbox, expected_stdout, expected_stderr,
revs, check_props, dump, *varargs):
"""Load the array of lines passed in DUMP into the current tests'
@@ -589,8 +601,8 @@ def dump_quiet(sbox):
sbox.build(create_wc = False)
- exit_code, output, errput = svntest.main.run_svnadmin("dump", sbox.repo_dir,
- '--quiet')
+ exit_code, dump, errput = svntest.main.run_svnadmin("dump", sbox.repo_dir,
+ '--quiet')
svntest.verify.compare_and_display_lines(
"Output of 'svnadmin dump --quiet' is unexpected.",
'STDERR', [], errput)
@@ -792,7 +804,7 @@ def verify_incremental_fsfs(sbox):
# the listing itself is valid.
r2 = fsfs_file(sbox.repo_dir, 'revs', '2')
if r2.endswith('pack'):
- raise svntest.Skip
+ raise svntest.Skip('Test doesn\'t handle packed revisions')
fp = open(r2, 'wb')
fp.write("""id: 0-2.0.r2/0
@@ -1215,7 +1227,7 @@ def fsfs_recover_handle_missing_revs_or_
#----------------------------------------------------------------------
-@Skip(svntest.main.tests_use_prepacakaged_repository)
+@Skip(svntest.main.tests_use_prepackaged_repository)
def create_in_repo_subdir(sbox):
"'svnadmin create /path/to/repo/subdir'"
@@ -1371,21 +1383,21 @@ def dont_drop_valid_mergeinfo_during_inc
# PART 2: Load a a series of incremental dumps to an empty repository.
#
# Incrementally dump the repository into three dump files:
- dump_file_r1_10 = svntest.main.temp_dir + "-r1-10.dump"
+ dump_file_r1_10 = sbox.get_tempname("r1-10-dump")
exit_code, output, errput = svntest.main.run_svnadmin(
'dump', sbox.repo_dir, '-r1:10')
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"
+ dump_file_r11_13 = sbox.get_tempname("r11-13-dump")
exit_code, output, errput = svntest.main.run_svnadmin(
'dump', sbox.repo_dir, '--incremental', '-r11:13')
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"
+ dump_file_r14_15 = sbox.get_tempname("r14-15-dump")
exit_code, output, errput = svntest.main.run_svnadmin(
'dump', sbox.repo_dir, '--incremental', '-r14:15')
dump_fp = open(dump_file_r14_15, 'wb')
@@ -2000,6 +2012,14 @@ def mergeinfo_race(sbox):
"concurrent mergeinfo commits invalidate pred-count"
sbox.build()
+ # This test exercises two commit-time race condition bugs:
+ #
+ # (a) metadata corruption when concurrent commits change svn:mergeinfo (issue #4129)
+ # (b) false positive SVN_ERR_FS_CONFLICT error with httpv1 commits
+ # https://mail-archives.apache.org/mod_mbox/subversion-dev/201507.mbox/%3C20150731234536.GA5395@tarsus.local2%3E
+ #
+ # Both bugs are timing-dependent and might not reproduce 100% of the time.
+
wc_dir = sbox.wc_dir
wc2_dir = sbox.add_wc_path('2')
@@ -2046,6 +2066,10 @@ def recover_old_empty(sbox):
def verify_keep_going(sbox):
"svnadmin verify --keep-going test"
+ # No support for modifying pack files
+ if svntest.main.options.fsfs_packing:
+ raise svntest.Skip('fsfs packing set')
+
sbox.build(create_wc = False)
repo_url = sbox.repo_url
B_url = sbox.repo_url + '/B'
@@ -2070,20 +2094,28 @@ def verify_keep_going(sbox):
exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
".*Verified revision 1.",
- ".*Error verifying revision 2.",
- ".*Error verifying revision 3.",
".*",
".*Summary.*",
".*r2: E160004:.*",
".*r2: E160004:.*",
".*r3: E160004:.*",
".*r3: E160004:.*"])
- exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*",
- "svnadmin: E165011:.*"], False)
if (svntest.main.fs_has_rep_sharing()):
exp_out.insert(0, ".*Verifying.*metadata.*")
+ exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
+ "svnadmin: E160004:.*",
+ "svnadmin: E160004:.*",
+ ".*Error verifying revision 3.",
+ "svnadmin: E160004:.*",
+ "svnadmin: E160004:.*",
+ "svnadmin: E205012:.*"], False)
+
+ if (svntest.main.is_fs_log_addressing()):
+ exp_err.insert(0, ".*Error verifying repository metadata.")
+ exp_err.insert(1, "svnadmin: E160004:.*")
+
if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
output, errput, exp_out, exp_err):
raise svntest.Failure
@@ -2095,11 +2127,19 @@ def verify_keep_going(sbox):
exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision 0"])
else:
exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
- ".*Verified revision 1.",
- ".*Error verifying revision 2."])
+ ".*Verified revision 1."])
if (svntest.main.fs_has_rep_sharing()):
exp_out.insert(0, ".*Verifying repository metadata.*")
+ if (svntest.main.is_fs_log_addressing()):
+ exp_err = svntest.verify.RegexListOutput([
+ ".*Error verifying repository metadata.",
+ "svnadmin: E160004:.*"], False)
+ else:
+ exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
+ "svnadmin: E160004:.*",
+ "svnadmin: E160004:.*"], False)
+
if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
output, errput, exp_out, exp_err):
raise svntest.Failure
@@ -2109,17 +2149,85 @@ def verify_keep_going(sbox):
"--quiet",
sbox.repo_dir)
+ if (svntest.main.is_fs_log_addressing()):
+ exp_err = svntest.verify.RegexListOutput([
+ ".*Error verifying repository metadata.",
+ "svnadmin: E160004:.*"], False)
+ else:
+ exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
+ "svnadmin: E160004:.*",
+ "svnadmin: E160004:.*"], False)
+
if svntest.verify.verify_outputs("Output of 'svnadmin verify' is unexpected.",
- None, errput, None, "svnadmin: E165011:.*"):
+ None, errput, None, exp_err):
raise svntest.Failure
# Don't leave a corrupt repository
svntest.main.safe_rmtree(sbox.repo_dir, True)
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def verify_keep_going_quiet(sbox):
+ "svnadmin verify --keep-going --quiet test"
+
+ # No support for modifying pack files
+ if svntest.main.options.fsfs_packing:
+ raise svntest.Skip('fsfs packing set')
+
+ sbox.build(create_wc = False)
+ repo_url = sbox.repo_url
+ B_url = sbox.repo_url + '/B'
+ C_url = sbox.repo_url + '/C'
+
+ # Create A/B/E/bravo in r2.
+ svntest.actions.run_and_verify_svn(None, [],
+ 'mkdir', '-m', 'log_msg',
+ B_url)
+
+ svntest.actions.run_and_verify_svn(None, [],
+ 'mkdir', '-m', 'log_msg',
+ C_url)
+
+ r2 = fsfs_file(sbox.repo_dir, 'revs', '2')
+ fp = open(r2, 'r+b')
+ fp.write("""inserting junk to corrupt the rev""")
+ fp.close()
+
+ exit_code, output, errput = svntest.main.run_svnadmin("verify",
+ "--keep-going",
+ "--quiet",
+ sbox.repo_dir)
+
+ exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
+ "svnadmin: E160004:.*",
+ "svnadmin: E160004:.*",
+ ".*Error verifying revision 3.",
+ "svnadmin: E160004:.*",
+ "svnadmin: E160004:.*",
+ "svnadmin: E205012:.*"], False)
+
+ # Insert another expected error from checksum verification
+ if (svntest.main.is_fs_log_addressing()):
+ exp_err.insert(0, ".*Error verifying repository metadata.")
+ exp_err.insert(1, "svnadmin: E160004:.*")
+
+ if svntest.verify.verify_outputs(
+ "Unexpected error while running 'svnadmin verify'.",
+ output, errput, None, exp_err):
+ raise svntest.Failure
+
+ # Don't leave a corrupt repository
+ svntest.main.safe_rmtree(sbox.repo_dir, True)
+
+
@SkipUnless(svntest.main.is_fs_type_fsfs)
def verify_invalid_path_changes(sbox):
"detect invalid changed path list entries"
+ # No support for modifying pack files
+ if svntest.main.options.fsfs_packing:
+ raise svntest.Skip('fsfs packing set')
+
sbox.build(create_wc = False)
repo_url = sbox.repo_url
@@ -2180,23 +2288,15 @@ def verify_invalid_path_changes(sbox):
exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
".*Verified revision 1.",
- ".*Error verifying revision 2.",
".*Verified revision 3.",
- ".*Error verifying revision 4.",
".*Verified revision 5.",
- ".*Error verifying revision 6.",
".*Verified revision 7.",
".*Verified revision 8.",
".*Verified revision 9.",
- ".*Error verifying revision 10.",
".*Verified revision 11.",
- ".*Error verifying revision 12.",
".*Verified revision 13.",
- ".*Error verifying revision 14.",
".*Verified revision 15.",
- ".*Error verifying revision 16.",
".*Verified revision 17.",
- ".*Error verifying revision 18.",
".*Verified revision 19.",
".*",
".*Summary.*",
@@ -2217,12 +2317,36 @@ def verify_invalid_path_changes(sbox):
".*r18: E160013:.*"])
if (svntest.main.fs_has_rep_sharing()):
exp_out.insert(0, ".*Verifying.*metadata.*")
- if svntest.main.is_fs_log_addressing():
- exp_out.insert(1, ".*Verifying.*metadata.*")
+ if svntest.main.options.fsfs_sharding is not None:
+ for x in range(0, 19 / svntest.main.options.fsfs_sharding):
+ exp_out.insert(0, ".*Verifying.*metadata.*")
+ if svntest.main.is_fs_log_addressing():
+ exp_out.insert(0, ".*Verifying.*metadata.*")
- exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*",
+ exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
+ "svnadmin: E160020:.*",
+ "svnadmin: E160020:.*",
+ ".*Error verifying revision 4.",
+ "svnadmin: E160013:.*",
+ ".*Error verifying revision 6.",
+ "svnadmin: E160013:.*",
+ "svnadmin: E160013:.*",
+ ".*Error verifying revision 10.",
+ "svnadmin: E160013:.*",
+ "svnadmin: E160013:.*",
+ ".*Error verifying revision 12.",
+ "svnadmin: E145001:.*",
+ "svnadmin: E145001:.*",
+ ".*Error verifying revision 14.",
+ "svnadmin: E160013:.*",
+ "svnadmin: E160013:.*",
+ ".*Error verifying revision 16.",
"svnadmin: E145001:.*",
- "svnadmin: E160013:.*"], False)
+ "svnadmin: E145001:.*",
+ ".*Error verifying revision 18.",
+ "svnadmin: E160013:.*",
+ "svnadmin: E160013:.*",
+ "svnadmin: E205012:.*"], False)
if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
@@ -2233,15 +2357,19 @@ def verify_invalid_path_changes(sbox):
sbox.repo_dir)
exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
- ".*Verified revision 1.",
- ".*Error verifying revision 2."])
- exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*",
- "svnadmin: E165011:.*"], False)
+ ".*Verified revision 1."])
+ exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
+ "svnadmin: E160020:.*",
+ "svnadmin: E160020:.*"], False)
if (svntest.main.fs_has_rep_sharing()):
exp_out.insert(0, ".*Verifying.*metadata.*")
- if svntest.main.is_fs_log_addressing():
- exp_out.insert(1, ".*Verifying.*metadata.*")
+ if svntest.main.options.fsfs_sharding is not None:
+ for x in range(0, 19 / svntest.main.options.fsfs_sharding):
+ exp_out.insert(0, ".*Verifying.*metadata.*")
+ if svntest.main.is_fs_log_addressing():
+ exp_out.insert(0, ".*Verifying.*metadata.*")
+
if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
output, errput, exp_out, exp_err):
raise svntest.Failure
@@ -2251,8 +2379,13 @@ def verify_invalid_path_changes(sbox):
"--quiet",
sbox.repo_dir)
+ exp_out = []
+ exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
+ "svnadmin: E160020:.*",
+ "svnadmin: E160020:.*"], False)
+
if svntest.verify.verify_outputs("Output of 'svnadmin verify' is unexpected.",
- None, errput, None, "svnadmin: E165011:.*"):
+ output, errput, exp_out, exp_err):
raise svntest.Failure
# Don't leave a corrupt repository
@@ -2292,6 +2425,10 @@ def verify_denormalized_names(sbox):
if (svntest.main.fs_has_rep_sharing()):
expected_output_regex_list.insert(0, ".*Verifying repository metadata.*")
+ if svntest.main.options.fsfs_sharding is not None:
+ for x in range(0, 7 / svntest.main.options.fsfs_sharding):
+ expected_output_regex_list.insert(0, ".*Verifying.*metadata.*")
+
if svntest.main.is_fs_log_addressing():
expected_output_regex_list.insert(0, ".* Verifying metadata at revision 0.*")
@@ -2606,7 +2743,10 @@ def verify_quickly(sbox):
"verify quickly using metadata"
sbox.build(create_wc = False)
- rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
+ if svntest.main.is_fs_type_fsfs():
+ rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
+ else:
+ rev_file = open(fsfs_file(sbox.repo_dir, 'revs', 'r1'), 'r+b')
# set new contents
rev_file.seek(8)
@@ -2621,8 +2761,7 @@ def verify_quickly(sbox):
# resulting in different progress output
if svntest.main.is_fs_log_addressing():
exp_out = svntest.verify.RegexListOutput([])
- exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*",
- "svnadmin: E165011:.*"], False)
+ exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*"], False)
else:
exp_out = svntest.verify.RegexListOutput([])
exp_err = svntest.verify.RegexListOutput([])
@@ -2646,7 +2785,7 @@ def fsfs_hotcopy_progress(sbox):
# and incremental scenarios. The progress output can be affected by
# the --fsfs-packing option, so skip the test if that is the case.
if svntest.main.options.fsfs_packing:
- raise svntest.Skip
+ raise svntest.Skip('fsfs packing set')
# Create an empty repository, configure three files per shard.
sbox.build(create_wc=False, empty=True)
@@ -2760,7 +2899,7 @@ def fsfs_hotcopy_progress_with_revprop_c
# The progress output can be affected by the --fsfs-packing
# option, so skip the test if that is the case.
if svntest.main.options.fsfs_packing:
- raise svntest.Skip
+ raise svntest.Skip('fsfs packing set')
# Create an empty repository, commit several revisions and hotcopy it.
sbox.build(create_wc=False, empty=True)
@@ -2954,6 +3093,206 @@ def load_no_svndate_r0(sbox):
'proplist', '--revprop', '-r0',
sbox.repo_dir)
+# This is only supported for FSFS
+# The port to FSX is still pending, BDB won't support it.
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def hotcopy_read_only(sbox):
+ "'svnadmin hotcopy' a read-only source repository"
+ sbox.build()
+ svntest.main.chmod_tree(sbox.repo_dir, 0, 0222)
+
+ backup_dir, backup_url = sbox.add_repo_path('backup')
+ exit_code, output, errput = svntest.main.run_svnadmin("hotcopy",
+ sbox.repo_dir,
+ backup_dir)
+
+ # r/o repos are hard to clean up. Make it writable again.
+ svntest.main.chmod_tree(sbox.repo_dir, 0222, 0222)
+ if errput:
+ logger.warn("Error: hotcopy failed")
+ raise SVNUnexpectedStderr(errput)
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+@SkipUnless(svntest.main.fs_has_pack)
+def fsfs_pack_non_sharded(sbox):
+ "'svnadmin pack' on a non-sharded repository"
+
+ # Configure two files per shard to trigger packing.
+ sbox.build(create_wc = False,
+ minor_version = min(svntest.main.options.server_minor_version,3))
+
+ # Skip for pre-cooked sharded repositories
+ if is_sharded(sbox.repo_dir):
+ raise svntest.Skip('sharded pre-cooked repository')
+
+ svntest.actions.run_and_verify_svnadmin(
+ None, [], "upgrade", sbox.repo_dir)
+ svntest.actions.run_and_verify_svnadmin(
+ ['svnadmin: Warning - this repository is not sharded. Packing has no effect.\n'],
+ [], "pack", sbox.repo_dir)
+
+def load_revprops(sbox):
+ "svnadmin load-revprops"
+
+ sbox.build(create_wc=False, empty=True)
+
+ dump_path = os.path.join(os.path.dirname(sys.argv[0]),
+ 'svnadmin_tests_data',
+ 'skeleton_repos.dump')
+ dump_contents = open(dump_path, 'rb').readlines()
+ load_and_verify_dumpstream(sbox, None, [], None, False, dump_contents)
+
+ svntest.actions.run_and_verify_svnlook(['Initial setup...\n', '\n'],
+ [], 'log', '-r1', sbox.repo_dir)
+
+ # After loading the dump, amend one of the log message in the repository.
+ input_file = sbox.get_tempname()
+ svntest.main.file_write(input_file, 'Modified log message...\n')
+
+ svntest.actions.run_and_verify_svnadmin([], [], 'setlog', '--bypass-hooks',
+ '-r1', sbox.repo_dir, input_file)
+ svntest.actions.run_and_verify_svnlook(['Modified log message...\n', '\n'],
+ [], 'log', '-r1', sbox.repo_dir)
+
+ # Load the same dump, but with 'svnadmin load-revprops'. Doing so should
+ # restore the log message to its original state.
+ svntest.main.run_command_stdin(svntest.main.svnadmin_binary, None, 0,
+ True, dump_contents, 'load-revprops',
+ sbox.repo_dir)
+
+ svntest.actions.run_and_verify_svnlook(['Initial setup...\n', '\n'],
+ [], 'log', '-r1', sbox.repo_dir)
+
+def dump_revprops(sbox):
+ "svnadmin dump-revprops"
+
+ sbox.build(create_wc=False)
+
+ # Dump revprops only.
+ exit_code, dump_contents, errput = \
+ svntest.actions.run_and_verify_svnadmin(None, [], "dump-revprops", "-q",
+ sbox.repo_dir)
+
+ # We expect the dump to contain no path changes
+ for line in dump_contents:
+ if line.find("Node-path: ") > -1:
+ logger.warn("Error: path change found in revprops-only dump.")
+ raise svntest.Failure
+
+ # Remember the current log message for r1
+ exit_code, log_msg, errput = \
+ svntest.actions.run_and_verify_svnlook(None, [], 'log', '-r1',
+ sbox.repo_dir)
+
+ # Now, change the log message in the repository.
+ input_file = sbox.get_tempname()
+ svntest.main.file_write(input_file, 'Modified log message...\n')
+
+ svntest.actions.run_and_verify_svnadmin([], [], 'setlog', '--bypass-hooks',
+ '-r1', sbox.repo_dir, input_file)
+ svntest.actions.run_and_verify_svnlook(['Modified log message...\n', '\n'],
+ [], 'log', '-r1', sbox.repo_dir)
+
+ # Load the same dump with 'svnadmin load-revprops'. Doing so should
+ # restore the log message to its original state.
+ svntest.main.run_command_stdin(svntest.main.svnadmin_binary, None, 0,
+ True, dump_contents, 'load-revprops',
+ sbox.repo_dir)
+
+ svntest.actions.run_and_verify_svnlook(log_msg, [], 'log', '-r1',
+ sbox.repo_dir)
+
+@XFail(svntest.main.is_fs_type_fsx)
+@Issue(4598)
+def dump_no_op_change(sbox):
+ "svnadmin dump with no-op changes"
+
+ sbox.build(create_wc=False, empty=True)
+ empty_file = sbox.get_tempname()
+ svntest.main.file_write(empty_file, '')
+
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', svntest.main.make_log_msg(),
+ 'put', empty_file, 'bar')
+ # Commit a no-op change.
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', svntest.main.make_log_msg(),
+ 'put', empty_file, 'bar')
+ # Dump and load the repository.
+ _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [],
+ 'dump', '-q',
+ sbox.repo_dir)
+ sbox2 = sbox.clone_dependent()
+ sbox2.build(create_wc=False, empty=True)
+ load_and_verify_dumpstream(sbox2, None, [], None, False, dump)
+
+ # We expect svn log -v to yield identical results for both original and
+ # reconstructed repositories. This used to fail as described in the
+ # Issue 4598 (https://issues.apache.org/jira/browse/SVN-4598), at least
+ # around r1706415.
+ #
+ # Test svn log -v for r2:
+ _, expected, _ = svntest.actions.run_and_verify_svn(None, [], 'log', '-v',
+ '-r2', sbox.repo_url)
+ found = [True for line in expected if line.find('M /bar\n') != -1]
+ if not found:
+ raise svntest.Failure
+ svntest.actions.run_and_verify_svn(expected, [], 'log', '-v',
+ '-r2', sbox2.repo_url)
+ # Test svn log -v for /bar:
+ _, expected, _ = svntest.actions.run_and_verify_svn(None, [], 'log', '-v',
+ sbox.repo_url + '/bar')
+ found = [True for line in expected if line.find('M /bar\n') != -1]
+ if not found:
+ raise svntest.Failure
+ svntest.actions.run_and_verify_svn(expected, [], 'log', '-v',
+ sbox2.repo_url + '/bar')
+
+@XFail()
+def dump_no_op_prop_change(sbox):
+ "svnadmin dump with no-op property change"
+
+ sbox.build(create_wc=False, empty=True)
+ empty_file = sbox.get_tempname()
+ svntest.main.file_write(empty_file, '')
+
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', svntest.main.make_log_msg(),
+ 'put', empty_file, 'bar',
+ 'propset', 'pname', 'pval', 'bar')
+ # Commit a no-op property change.
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', svntest.main.make_log_msg(),
+ 'propset', 'pname', 'pval', 'bar')
+ # Dump and load the repository.
+ _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [],
+ 'dump', '-q',
+ sbox.repo_dir)
+ sbox2 = sbox.clone_dependent()
+ sbox2.build(create_wc=False, empty=True)
+ load_and_verify_dumpstream(sbox2, None, [], None, False, dump)
+
+ # Test svn log -v for r2:
+ _, expected, _ = svntest.actions.run_and_verify_svn(None, [], 'log', '-v',
+ '-r2', sbox.repo_url)
+ found = [True for line in expected if line.find('M /bar\n') != -1]
+ if not found:
+ raise svntest.Failure
+ svntest.actions.run_and_verify_svn(expected, [], 'log', '-v',
+ '-r2', sbox2.repo_url)
+ # Test svn log -v for /bar:
+ _, expected, _ = svntest.actions.run_and_verify_svn(None, [], 'log', '-v',
+ sbox.repo_url + '/bar')
+ found = [True for line in expected if line.find('M /bar\n') != -1]
+ if not found:
+ raise svntest.Failure
+ svntest.actions.run_and_verify_svn(expected, [], 'log', '-v',
+ sbox2.repo_url + '/bar')
+
########################################################################
# Run the tests
@@ -2992,6 +3331,7 @@ test_list = [ None,
mergeinfo_race,
recover_old_empty,
verify_keep_going,
+ verify_keep_going_quiet,
verify_invalid_path_changes,
verify_denormalized_names,
fsfs_recover_old_non_empty,
@@ -3009,6 +3349,12 @@ test_list = [ None,
upgrade,
load_txdelta,
load_no_svndate_r0,
+ hotcopy_read_only,
+ fsfs_pack_non_sharded,
+ load_revprops,
+ dump_revprops,
+ dump_no_op_change,
+ dump_no_op_prop_change
]
if __name__ == '__main__':
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svnmucc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svnmucc_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svnmucc_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svnmucc_tests.py Mon Nov 30 10:24:16 2015
@@ -106,7 +106,9 @@ def basic_svnmucc(sbox):
sbox.build()
empty_file = sbox.ospath('empty')
+ file = sbox.ospath('file')
svntest.main.file_append(empty_file, '')
+ svntest.main.file_append(file, 'file')
# revision 2
test_svnmucc(sbox.repo_url,
@@ -301,6 +303,14 @@ def basic_svnmucc(sbox):
'propsetf', 'testprop', empty_file, 'foo/z.c',
'propsetf', 'testprop', empty_file, 'foo/foo')
+ # revision 21
+ test_svnmucc(sbox.repo_url,
+ ['M /foo/z.c',
+ ], #---------
+ '-m', 'log msg',
+ 'propset', 'testprop', 'false', 'foo/z.c',
+ 'put', file, 'foo/z.c')
+
# Expected missing revision error
xtest_svnmucc(sbox.repo_url,
["svnmucc: E200004: 'a' is not a revision"
@@ -453,6 +463,132 @@ rm A/B/C/Y
'log', '-qvr3', repo_url)
+def prohibited_deletes_and_moves(sbox):
+ "test prohibited delete and move operations"
+
+ # These action sequences were allowed in 1.8.13, but are prohibited in 1.9.x
+ # and later. Most of them probably indicate an inadvertent user mistake.
+ # See dev@, 2015-05-11, "Re: Issue 4579 / svnmucc fails to process certain
+ # deletes", <http://svn.haxx.se/dev/archive-2015-05/0038.shtml>
+
+ sbox.build(read_only = True)
+ svntest.main.file_write(sbox.ospath('file'), "New contents")
+
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't delete node at 'iota'",
+ ], #---------
+ '-m', 'r2: modify and delete /iota',
+ 'put', sbox.ospath('file'), 'iota',
+ 'rm', 'iota')
+
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't delete node at 'iota'",
+ ], #---------
+ '-m', 'r2: propset and delete /iota',
+ 'propset', 'prop', 'val', 'iota',
+ 'rm', 'iota')
+
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E160013: Can't delete node at 'iota' as it does "
+ "not exist",
+ ], #---------
+ '-m', 'r2: delete and delete /iota',
+ 'rm', 'iota',
+ 'rm', 'iota')
+
+ # Subversion 1.8.13 used to move /iota without applying the text change.
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't delete node at 'iota'",
+ ], #---------
+ '-m', 'r2: modify and move /iota',
+ 'put', sbox.ospath('file'), 'iota',
+ 'mv', 'iota', 'iota2')
+
+ # Subversion 1.8.13 used to move /A without applying the inner remove.
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't delete node at 'A'",
+ ], #---------
+ '-m', 'r2: delete /A/B and move /A',
+ 'rm', 'A/B',
+ 'mv', 'A', 'A1')
+
+def svnmucc_type_errors(sbox):
+ "test type errors"
+
+ sbox.build(read_only=True)
+
+ sbox.simple_append('file', 'New contents')
+
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E160016: Can't operate on 'B' "
+ "because 'A' is not a directory"],
+ '-m', '',
+ 'put', sbox.ospath('file'), 'A',
+ 'mkdir', 'A/B',
+ 'propset', 'iota', 'iota', 'iota')
+
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't delete node at 'A'"],
+ '-m', '',
+ 'mkdir', 'A/Z',
+ 'put', sbox.ospath('file'), 'A')
+
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E160020: Path 'Z' already exists"],
+ '-m', '',
+ 'mkdir', 'A/Z',
+ 'put', sbox.ospath('file'), 'A/Z')
+
+def svnmucc_propset_and_put(sbox):
+ "propset and put"
+
+ sbox.build()
+
+ sbox.simple_append('file', 'New contents')
+
+ # First in the sane order: put, then propset
+ xtest_svnmucc(sbox.repo_url,
+ [],
+ '-m', '',
+ 'put', sbox.ospath('file'), 't1',
+ 'propset', 't1', 't1', 't1')
+
+ # And now in an impossible order: propset, then put
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't set properties at not existing 't2'"],
+ '-m', '',
+ 'propset', 't2', 't2', 't2',
+ 'put', sbox.ospath('file'), 't2')
+
+ # And if the target already exists (dir)
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't delete node at 'A'"],
+ '-m', '',
+ 'propset', 'A', 'A', 'A',
+ 'put', sbox.ospath('file'), 'A')
+
+ # And if the target already exists (file) # fixed in r1702467
+ xtest_svnmucc(sbox.repo_url,
+ [],
+ '-m', '',
+ 'propset', 'iota', 'iota', 'iota',
+ 'put', sbox.ospath('file'), 'iota')
+
+ # Put same file twice (non existing)
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E160020: Path 't3' already exists"],
+ '-m', '',
+ 'put', sbox.ospath('file'), 't3',
+ 'put', sbox.ospath('file'), 't3')
+
+ # Put same file twice (existing)
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200009: Can't update file at 't1'"],
+ '-m', '',
+ 'put', sbox.ospath('file'), 't1',
+ 'put', sbox.ospath('file'), 't1')
+
+
######################################################################
test_list = [ None,
@@ -462,6 +598,9 @@ test_list = [ None,
too_many_log_messages,
no_log_msg_non_interactive,
nested_replaces,
+ prohibited_deletes_and_moves,
+ svnmucc_type_errors,
+ svnmucc_propset_and_put,
]
if __name__ == '__main__':
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svnrdump_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svnrdump_tests.py Mon Nov 30 10:24:16 2015
@@ -541,7 +541,7 @@ def dont_drop_valid_mergeinfo_during_inc
# PART 2: Load a series of incremental dumps to an empty repository.
#
# Incrementally dump the repository into three dump files:
- dump_file_r1_10 = svntest.main.temp_dir + "-r1-10.dump"
+ dump_file_r1_10 = sbox.get_tempname("r1-10-dump")
output = svntest.actions.run_and_verify_svnrdump(None,
svntest.verify.AnyOutput,
[], 0, '-q', 'dump', '-r1:10',
@@ -550,7 +550,7 @@ def dont_drop_valid_mergeinfo_during_inc
dump_fp.writelines(output)
dump_fp.close()
- dump_file_r11_13 = svntest.main.temp_dir + "-r11-13.dump"
+ dump_file_r11_13 = sbox.get_tempname("r11-13-dump")
output = svntest.actions.run_and_verify_svnrdump(None,
svntest.verify.AnyOutput,
[], 0, '-q', 'dump',
@@ -560,7 +560,7 @@ def dont_drop_valid_mergeinfo_during_inc
dump_fp.writelines(output)
dump_fp.close()
- dump_file_r14_15 = svntest.main.temp_dir + "-r14-15.dump"
+ dump_file_r14_15 = sbox.get_tempname("r14-15-dump")
output = svntest.actions.run_and_verify_svnrdump(None,
svntest.verify.AnyOutput,
[], 0, '-q', 'dump',
@@ -571,6 +571,7 @@ def dont_drop_valid_mergeinfo_during_inc
dump_fp.close()
# Blow away the current repos and create an empty one in its place.
+ 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
@@ -606,6 +607,7 @@ def dont_drop_valid_mergeinfo_during_inc
# PART 3: Load a full dump to an non-empty repository.
#
# Reset our sandbox.
+ 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
@@ -667,6 +669,7 @@ def dont_drop_valid_mergeinfo_during_inc
# PART 4: Load a a series of incremental dumps to an non-empty repository.
#
# Reset our sandbox.
+ 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
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svnserveautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svnserveautocheck.sh?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svnserveautocheck.sh (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svnserveautocheck.sh Mon Nov 30 10:24:16 2015
@@ -92,16 +92,19 @@ random_port() {
fi
}
-if type time > /dev/null; then
- TIME_CMD=time
-else
- TIME_CMD=""
-fi
+if type time > /dev/null ; then TIME_CMD() { time "$@"; } ; else TIME_CMD() { "$@"; } ; fi
MAKE=${MAKE:-make}
+PATH="$PATH:/usr/sbin/:/usr/local/sbin/"
+
+ss > /dev/null 2>&1 || netstat > /dev/null 2>&1 || fail "unable to find ss or netstat required to find a free port"
SVNSERVE_PORT=$(random_port)
-while netstat -an | grep $SVNSERVE_PORT | grep 'LISTEN'; do
+while \
+ (ss -ltn sport = :$SVNSERVE_PORT 2>&1 | grep :$SVNSERVE_PORT > /dev/null ) \
+ || \
+ (netstat -an 2>&1 | grep $SVNSERVE_PORT | grep 'LISTEN' > /dev/null ) \
+ do
SVNSERVE_PORT=$(random_port)
done
@@ -121,13 +124,13 @@ fi
BASE_URL=svn://127.0.0.1:$SVNSERVE_PORT
if [ $# = 0 ]; then
- $TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL"
+ TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL"
r=$?
else
cd "$ABS_BUILDDIR/subversion/tests/cmdline/"
TEST="$1"
shift
- $TIME_CMD "./${TEST}_tests.py" "--url=$BASE_URL" $*
+ TIME_CMD "./${TEST}_tests.py" "--url=$BASE_URL" $*
r=$?
cd - > /dev/null
fi
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svnsync_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svnsync_authz_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svnsync_authz_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svnsync_authz_tests.py Mon Nov 30 10:24:16 2015
@@ -30,7 +30,7 @@
import sys, os
# Test suite-specific modules
-import locale, re, urllib
+import locale, re
# Our testing module
import svntest
@@ -383,7 +383,7 @@ def identity_copy(sbox):
except:
pass
if locale.setlocale(locale.LC_ALL) != other_locale:
- raise svntest.Skip
+ raise svntest.Skip('Setting test locale failed')
try:
run_test(sbox, "copy-bad-encoding.expected.dump",
@@ -471,8 +471,7 @@ def copy_delete_unreadable_child(sbox):
src_authz + ':/A': '* =',
})
- dest_url = svntest.main.file_scheme_prefix \
- + urllib.pathname2url(os.path.abspath(dest_sbox.repo_dir))
+ dest_url = dest_sbox.file_protocol_repo_url()
run_init(dest_url, sbox.repo_url)
run_sync(dest_url)
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svnsync_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svnsync_tests.py Mon Nov 30 10:24:16 2015
@@ -28,7 +28,7 @@
import sys, os
# Test suite-specific modules
-import re, urllib
+import re
# Our testing module
import svntest
@@ -131,16 +131,14 @@ def setup_and_sync(sbox, dump_file_conte
repo_url = sbox.repo_url
cwd = os.getcwd()
if is_src_ra_local:
- repo_url = svntest.main.file_scheme_prefix + \
- urllib.pathname2url(os.path.join(cwd, sbox.repo_dir))
+ repo_url = sbox.file_protocol_repo_url()
if subdir:
repo_url = repo_url + subdir
dest_repo_url = dest_sbox.repo_url
if is_dest_ra_local:
- dest_repo_url = svntest.main.file_scheme_prefix + \
- urllib.pathname2url(os.path.join(cwd, dest_sbox.repo_dir))
+ dest_repo_url = dest_sbox.file_protocol_repo_url()
run_init(dest_repo_url, repo_url, source_prop_encoding)
run_sync(dest_repo_url, repo_url,
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/__init__.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/__init__.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/__init__.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/__init__.py Mon Nov 30 10:24:16 2015
@@ -23,11 +23,11 @@
__all__ = [ ]
import sys
-if sys.hexversion < 0x2050000:
- sys.stderr.write('[SKIPPED] at least Python 2.5 is required\n')
+if sys.hexversion < 0x2070000:
+ sys.stderr.write('[SKIPPED] at least Python 2.7 is required\n')
# note: exiting is a bit harsh for a library module, but we really do
- # require Python 2.5. this package isn't going to work otherwise.
+ # require Python 2.7. this package isn't going to work otherwise.
# we're skipping this test, not failing, so exit with 0
sys.exit(0)
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/actions.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/actions.py Mon Nov 30 10:24:16 2015
@@ -249,6 +249,28 @@ def run_and_verify_svnadmin2(expected_st
return exit_code, out, err
+def run_and_verify_svnfsfs(expected_stdout,
+ expected_stderr, *varargs):
+ """Like run_and_verify_svnfsfs2, but the expected exit code is
+ assumed to be 0 if no output is expected on stderr, and 1 otherwise."""
+
+ expected_exit = 0
+ if expected_stderr is not None and expected_stderr != []:
+ expected_exit = 1
+ return run_and_verify_svnfsfs2(expected_stdout, expected_stderr,
+ expected_exit, *varargs)
+
+def run_and_verify_svnfsfs2(expected_stdout, expected_stderr,
+ expected_exit, *varargs):
+ """Run svnfsfs command and check its output and exit code."""
+
+ exit_code, out, err = main.run_svnfsfs(*varargs)
+ verify.verify_outputs("Unexpected output", out, err,
+ expected_stdout, expected_stderr)
+ verify.verify_exit_code("Unexpected return code", exit_code, expected_exit)
+ return exit_code, out, err
+
+
def run_and_verify_svnversion(wc_dir, trail_url,
expected_stdout, expected_stderr, *varargs):
"""like run_and_verify_svnversion2, but the expected exit code is
@@ -380,6 +402,27 @@ def run_and_verify_svnrdump(dumpfile_con
return output
+def run_and_verify_svnmover(expected_stdout, expected_stderr,
+ *varargs):
+ """Run svnmover command and check its output"""
+
+ expected_exit = 0
+ if expected_stderr is not None and expected_stderr != []:
+ expected_exit = 1
+ return run_and_verify_svnmover2(expected_stdout, expected_stderr,
+ expected_exit, *varargs)
+
+def run_and_verify_svnmover2(expected_stdout, expected_stderr,
+ expected_exit, *varargs):
+ """Run svnmover command and check its output and exit code."""
+
+ exit_code, out, err = main.run_svnmover(*varargs)
+ verify.verify_outputs("Unexpected output", out, err,
+ expected_stdout, expected_stderr)
+ verify.verify_exit_code("Unexpected return code", exit_code, expected_exit)
+ return exit_code, out, err
+
+
def run_and_verify_svnmucc(expected_stdout, expected_stderr,
*varargs):
"""Run svnmucc command and check its output"""
@@ -1646,7 +1689,7 @@ def run_and_verify_diff_summarize_xml(er
for path in paths:
modified_path = path.childNodes[0].data
- if (expected_prefix is not None
+ if (expected_prefix
and modified_path.find(expected_prefix) == 0):
modified_path = modified_path.replace(expected_prefix, '')[1:].strip()
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/main.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/main.py Mon Nov 30 10:24:16 2015
@@ -112,7 +112,7 @@ class SVNRepositoryCreateFailure(Failure
# Windows specifics
if sys.platform == 'win32':
windows = True
- file_scheme_prefix = 'file:'
+ file_scheme_prefix = 'file:///'
_exe = '.exe'
_bat = '.bat'
os.environ['SVN_DBG_STACKTRACES_TO_STDERR'] = 'y'
@@ -179,6 +179,7 @@ svnauthz_binary = os.path.abspath('../..
svnauthz_validate_binary = os.path.abspath(
'../../../tools/server-side/svnauthz-validate' + _exe
)
+svnmover_binary = os.path.abspath('../../../tools/dev/svnmover/svnmover' + _exe)
# Location to the pristine repository, will be calculated from test_area_url
# when we know what the user specified for --url.
@@ -680,8 +681,7 @@ V %d
%s
END
""" % (len(cert_rep), cert_rep, len(netloc_url), netloc_url)
-
- file_write(md5_file, md5_file_contents)
+ file_write(md5_file, md5_file_contents, mode='wb')
def copy_trust(dst_cfgdir, src_cfgdir):
"""Copy svn.ssl.server files from one config dir to another.
@@ -774,6 +774,12 @@ def run_svnversion(*varargs):
as list of lines (including line terminators)."""
return run_command(svnversion_binary, 1, False, *varargs)
+def run_svnmover(*varargs):
+ """Run svnmover with VARARGS, returns exit code as int; stdout, stderr as
+ list of lines (including line terminators)."""
+ return run_command(svnmover_binary, 1, False,
+ *(_with_auth(_with_config_dir(varargs))))
+
def run_svnmucc(*varargs):
"""Run svnmucc with VARARGS, returns exit code as int; stdout, stderr as
list of lines (including line terminators). Use binary mode for output."""
@@ -881,6 +887,8 @@ def youngest(repos_path):
# Chmod recursively on a whole subtree
def chmod_tree(path, mode, mask):
+ """For each node in the OS filesystem tree PATH, subtract MASK from its
+ permissions and add MODE to them."""
for dirpath, dirs, files in os.walk(path):
for name in dirs + files:
fullname = os.path.join(dirpath, name)
@@ -1192,6 +1200,30 @@ def create_python_hook_script(hook_path,
file_write(hook_path, "#!%s\n%s" % (sys.executable, hook_script_code))
os.chmod(hook_path, 0755)
+def create_http_connection(url, debuglevel=9):
+ """Create an http(s) connection to the host specified by URL.
+ Set the debugging level (the amount of debugging output printed when
+ working with this connection) to DEBUGLEVEL. By default, all debugging
+ output is printed. """
+
+ import httplib
+ from urlparse import urlparse
+
+ loc = urlparse(url)
+ if loc.scheme == 'http':
+ h = httplib.HTTPConnection(loc.hostname, loc.port)
+ else:
+ try:
+ import ssl # new in python 2.6
+ c = ssl.create_default_context()
+ c.check_hostname = False
+ c.verify_mode = ssl.CERT_NONE
+ h = httplib.HTTPSConnection(loc.hostname, loc.port, context=c)
+ except:
+ h = httplib.HTTPSConnection(loc.hostname, loc.port)
+ h.set_debuglevel(debuglevel)
+ return h
+
def write_restrictive_svnserve_conf(repo_dir, anon_access="none"):
"Create a restrictive authz file ( no anynomous access )."
@@ -1414,7 +1446,7 @@ def make_log_msg():
# Functions which check the test configuration
# (useful for conditional XFails)
-def tests_use_prepacakaged_repository():
+def tests_use_prepackaged_repository():
return options.fsfs_version is not None
def tests_verify_dump_load_cross_check():
@@ -1527,15 +1559,28 @@ def is_plaintext_password_storage_disabl
# https://issues.apache.org/bugzilla/show_bug.cgi?id=56480
+# https://issues.apache.org/bugzilla/show_bug.cgi?id=55397
__mod_dav_url_quoting_broken_versions = frozenset([
+ '2.2.27',
'2.2.26',
+ '2.2.25',
'2.4.9',
+ '2.4.8',
+ '2.4.7',
+ '2.4.6',
+ '2.4.5',
])
def is_mod_dav_url_quoting_broken():
if is_ra_type_dav():
return (options.httpd_version in __mod_dav_url_quoting_broken_versions)
return None
+def is_httpd_authz_provider_enabled():
+ if is_ra_type_dav():
+ v = options.httpd_version.split('.')
+ return (v[0] == '2' and int(v[1]) >= 3) or int(v[0]) > 2
+ return None
+
######################################################################
@@ -1570,13 +1615,12 @@ class TestSpawningThread(threading.Threa
args = []
args.append(str(index))
args.append('-c')
+ args.append('--set-log-level=%s' % logger.getEffectiveLevel())
# add some startup arguments from this process
if options.fs_type:
args.append('--fs-type=' + options.fs_type)
if options.test_area_url:
args.append('--url=' + options.test_area_url)
- if logger.getEffectiveLevel() <= logging.DEBUG:
- args.append('-v')
if options.cleanup:
args.append('--cleanup')
if options.enable_sasl:
@@ -1870,14 +1914,48 @@ def _internal_run_tests(test_list, testn
return exit_code
-def create_default_options():
- """Set the global options to the defaults, as provided by the argument
- parser."""
- _parse_options([])
+class AbbreviatedFormatter(logging.Formatter):
+ """A formatter with abbreviated loglevel indicators in the output.
+
+ Use %(levelshort)s in the format string to get a single character
+ representing the loglevel..
+ """
+
+ _level_short = {
+ logging.CRITICAL : 'C',
+ logging.ERROR : 'E',
+ logging.WARNING : 'W',
+ logging.INFO : 'I',
+ logging.DEBUG : 'D',
+ logging.NOTSET : '-',
+ }
+ def format(self, record):
+ record.levelshort = self._level_short[record.levelno]
+ return logging.Formatter.format(self, record)
-def _create_parser():
+def _create_parser(usage=None):
"""Return a parser for our test suite."""
+
+ global logger
+
+ # Initialize the LOGGER global variable so the option parsing can set
+ # its loglevel, as appropriate.
+ logger = logging.getLogger()
+
+ # Did some chucklehead log something before we configured it? If they
+ # did, then a default handler/formatter would get installed. We want
+ # to be the one to install the first (and only) handler.
+ for handler in logger.handlers:
+ if not isinstance(handler.formatter, AbbreviatedFormatter):
+ raise Exception('Logging occurred before configuration. Some code'
+ ' path needs to be fixed. Examine the log output'
+ ' to find what/where logged something.')
+
+ # Set a sane default log level
+ if logger.getEffectiveLevel() == logging.NOTSET:
+ logger.setLevel(logging.WARN)
+
def set_log_level(option, opt, value, parser, level=None):
if level:
# called from --verbose
@@ -1886,9 +1964,18 @@ def _create_parser():
# called from --set-log-level
logger.setLevel(getattr(logging, value, None) or int(value))
- # set up the parser
+ # Set up the parser.
+ # If you add new options, consider adding them in
+ #
+ # .../build/run_tests.py:main()
+ #
+ # and handling them in
+ #
+ # .../build/run_tests.py:TestHarness._init_py_tests()
+ #
_default_http_library = 'serf'
- usage = 'usage: %prog [options] [<test> ...]'
+ if usage is None:
+ usage = 'usage: %prog [options] [<test> ...]'
parser = optparse.OptionParser(usage=usage)
parser.add_option('-l', '--list', action='store_true', dest='list_tests',
help='Print test doc strings instead of running them')
@@ -1903,6 +1990,9 @@ def _create_parser():
parser.add_option('-p', '--parallel', action='store_const',
const=default_num_threads, dest='parallel',
help='Run the tests in parallel')
+ parser.add_option('--parallel-instances', action='store',
+ type='int', dest='parallel',
+ help='Run the given number of tests in parallel')
parser.add_option('-c', action='store_true', dest='is_child_process',
help='Flag if we are running this python test as a ' +
'child process')
@@ -1980,37 +2070,54 @@ def _create_parser():
parser.set_defaults(
server_minor_version=SVN_VER_MINOR,
url=file_scheme_prefix + \
- urllib.pathname2url(os.path.abspath(os.getcwd())),
+ svntest.wc.svn_uri_quote(
+ os.path.abspath(
+ os.getcwd()).replace(os.path.sep, '/')),
http_library=_default_http_library)
return parser
-def _parse_options(arglist=sys.argv[1:]):
+def parse_options(arglist=sys.argv[1:], usage=None):
"""Parse the arguments in arg_list, and set the global options object with
the results"""
global options
- parser = _create_parser()
+ parser = _create_parser(usage)
(options, args) = parser.parse_args(arglist)
- # some sanity checking
+ # If there are no logging handlers registered yet, then install our
+ # own with our custom formatter. (anything currently installed *is*
+ # our handler as tested above, in _create_parser)
+ if not logger.handlers:
+ # Now that we have some options, let's get the logger configured before
+ # doing anything more
+ if options.log_with_timestamps:
+ formatter = AbbreviatedFormatter('%(levelshort)s:'
+ ' [%(asctime)s] %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S')
+ else:
+ formatter = AbbreviatedFormatter('%(levelshort)s: %(message)s')
+ handler = logging.StreamHandler(sys.stdout)
+ handler.setFormatter(formatter)
+ logger.addHandler(handler)
+
+ # Normalize url to have no trailing slash
+ if options.url:
+ if options.url[-1:] == '/':
+ options.test_area_url = options.url[:-1]
+ else:
+ options.test_area_url = options.url
+
+ # Some sanity checking
if options.fsfs_packing and not options.fsfs_sharding:
parser.error("--fsfs-packing requires --fsfs-sharding")
- # If you change the below condition then change
- # ../../../../build/run_tests.py too.
if options.server_minor_version not in range(3, SVN_VER_MINOR+1):
parser.error("test harness only supports server minor versions 3-%d"
% SVN_VER_MINOR)
- if options.url:
- if options.url[-1:] == '/': # Normalize url to have no trailing slash
- options.test_area_url = options.url[:-1]
- else:
- options.test_area_url = options.url
-
# Make sure the server-minor-version matches the fsfs-version parameter.
if options.fsfs_version:
if options.fsfs_version == 6:
@@ -2093,27 +2200,6 @@ def get_issue_details(issue_numbers):
return issue_dict
-class AbbreviatedFormatter(logging.Formatter):
- """A formatter with abbreviated loglevel indicators in the output.
-
- Use %(levelshort)s in the format string to get a single character
- representing the loglevel..
- """
-
- _level_short = {
- logging.CRITICAL : 'C',
- logging.ERROR : 'E',
- logging.WARNING : 'W',
- logging.INFO : 'I',
- logging.DEBUG : 'D',
- logging.NOTSET : '-',
- }
-
- def format(self, record):
- record.levelshort = self._level_short[record.levelno]
- return logging.Formatter.format(self, record)
-
-
# Main func. This is the "entry point" that all the test scripts call
# to run their list of tests.
#
@@ -2124,7 +2210,6 @@ def execute_tests(test_list, serial_only
exiting the process. This function can be used when a caller doesn't
want the process to die."""
- global logger
global pristine_url
global pristine_greek_repos_url
global svn_binary
@@ -2134,6 +2219,7 @@ def execute_tests(test_list, serial_only
global svnsync_binary
global svndumpfilter_binary
global svnversion_binary
+ global svnmover_binary
global svnmucc_binary
global svnauthz_binary
global svnauthz_validate_binary
@@ -2144,42 +2230,13 @@ def execute_tests(test_list, serial_only
testnums = []
- # Initialize the LOGGER global variable so the option parsing can set
- # its loglevel, as appropriate.
- logger = logging.getLogger()
-
- # Did some chucklehead log something before we configured it? If they
- # did, then a default handler/formatter would get installed. We want
- # to be the one to install the first (and only) handler.
- for handler in logger.handlers:
- if not isinstance(handler.formatter, AbbreviatedFormatter):
- raise Exception('Logging occurred before configuration. Some code'
- ' path needs to be fixed. Examine the log output'
- ' to find what/where logged something.')
-
if not options:
# Override which tests to run from the commandline
- (parser, args) = _parse_options()
+ (parser, args) = parse_options()
test_selection = args
else:
parser = _create_parser()
- # If there are no handlers registered yet, then install our own with
- # our custom formatter. (anything currently installed *is* our handler
- # as tested above)
- if not logger.handlers:
- # Now that we have some options, let's get the logger configured before
- # doing anything more
- if options.log_with_timestamps:
- formatter = AbbreviatedFormatter('%(levelshort)s:'
- ' [%(asctime)s] %(message)s',
- datefmt='%Y-%m-%d %H:%M:%S')
- else:
- formatter = AbbreviatedFormatter('%(levelshort)s: %(message)s')
- handler = logging.StreamHandler(sys.stdout)
- handler.setFormatter(formatter)
- logger.addHandler(handler)
-
# parse the positional arguments (test nums, names)
for arg in test_selection:
appended = False
@@ -2229,7 +2286,9 @@ def execute_tests(test_list, serial_only
# Calculate pristine_greek_repos_url from test_area_url.
pristine_greek_repos_url = options.test_area_url + '/' + \
- urllib.pathname2url(pristine_greek_repos_dir)
+ svntest.wc.svn_uri_quote(
+ pristine_greek_repos_dir.replace(
+ os.path.sep, '/'))
if options.use_jsvn:
if options.svn_bin is None:
@@ -2259,6 +2318,7 @@ def execute_tests(test_list, serial_only
svnauthz_binary = os.path.join(options.tools_bin, 'svnauthz' + _exe)
svnauthz_validate_binary = os.path.join(options.tools_bin,
'svnauthz-validate' + _exe)
+ svnmover_binary = os.path.join(options.tools_bin, 'svnmover' + _exe)
######################################################################
@@ -2307,25 +2367,29 @@ def execute_tests(test_list, serial_only
# We are simply listing the tests so always exit with success.
return 0
- # don't run tests in parallel when the tests don't support it or there
- # are only a few tests to run.
+ # don't run tests in parallel when the tests don't support it or
+ # there are only a few tests to run.
+ options_parallel = options.parallel
if serial_only or len(testnums) < 2:
options.parallel = 0
- if not options.is_child_process:
- # Build out the default configuration directory
- create_config_dir(default_config_dir,
- ssl_cert=options.ssl_cert,
- ssl_url=options.test_area_url,
- http_proxy=options.http_proxy,
- exclusive_wc_locks=options.exclusive_wc_locks)
-
- # Setup the pristine repository
- svntest.actions.setup_pristine_greek_repository()
-
- # Run the tests.
- exit_code = _internal_run_tests(test_list, testnums, options.parallel,
- options.srcdir, progress_func)
+ try:
+ if not options.is_child_process:
+ # Build out the default configuration directory
+ create_config_dir(default_config_dir,
+ ssl_cert=options.ssl_cert,
+ ssl_url=options.test_area_url,
+ http_proxy=options.http_proxy,
+ exclusive_wc_locks=options.exclusive_wc_locks)
+
+ # Setup the pristine repository
+ svntest.actions.setup_pristine_greek_repository()
+
+ # Run the tests.
+ exit_code = _internal_run_tests(test_list, testnums, options.parallel,
+ options.srcdir, progress_func)
+ finally:
+ options.parallel = options_parallel
# Remove all scratchwork: the 'pristine' repository, greek tree, etc.
# This ensures that an 'import' will happen the next time we run.
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py Mon Nov 30 10:24:16 2015
@@ -24,7 +24,6 @@
import os
import shutil
import copy
-import urllib
import logging
import re
@@ -114,7 +113,8 @@ class Sandbox:
if empty or not read_only: # use a local repo
self.repo_dir = os.path.join(svntest.main.general_repo_dir, self.name)
self.repo_url = (svntest.main.options.test_area_url + '/'
- + urllib.pathname2url(self.repo_dir))
+ + svntest.wc.svn_uri_quote(
+ self.repo_dir.replace(os.path.sep, '/')))
self.add_test_path(self.repo_dir)
else:
self.repo_dir = svntest.main.pristine_greek_repos_dir
@@ -195,7 +195,8 @@ class Sandbox:
path = (os.path.join(svntest.main.general_repo_dir, self.name)
+ '.' + suffix)
url = svntest.main.options.test_area_url + \
- '/' + urllib.pathname2url(path)
+ '/' + svntest.wc.svn_uri_quote(
+ path.replace(os.path.sep, '/'))
self.add_test_path(path, remove)
return path, url
@@ -276,6 +277,12 @@ class Sandbox:
temporary and 'TEMP' or 'PERM',
parts[1])
+ def file_protocol_repo_url(self):
+ """get a file:// url pointing to the repository"""
+ return svntest.main.file_scheme_prefix + \
+ svntest.wc.svn_uri_quote(
+ os.path.abspath(self.repo_dir).replace(os.path.sep, '/'))
+
def simple_update(self, target=None, revision='HEAD'):
"""Update the WC or TARGET.
TARGET is a relpath relative to the WC."""
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py Mon Nov 30 10:24:16 2015
@@ -285,16 +285,7 @@ class SVNTreeNode:
if self.props:
if comma:
line += ", "
- line += "props={"
- comma = False
-
- for name in self.props:
- if comma:
- line += ", "
- line += "'%s':'%s'" % (name, self.props[name])
- comma = True
-
- line += "}"
+ line += ("props=%s" % self.props)
comma = True
for name in self.atts:
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py Mon Nov 30 10:24:16 2015
@@ -853,7 +853,7 @@ def make_git_diff_header(target_path, re
if add:
output.extend([
"diff --git a/" + repos_relpath + " b/" + repos_relpath + "\n",
- "new file mode 10644\n",
+ "new file mode 100644\n",
])
if text_changes:
output.extend([
@@ -863,7 +863,7 @@ def make_git_diff_header(target_path, re
elif delete:
output.extend([
"diff --git a/" + repos_relpath + " b/" + repos_relpath + "\n",
- "deleted file mode 10644\n",
+ "deleted file mode 100644\n",
])
if text_changes:
output.extend([
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py Mon Nov 30 10:24:16 2015
@@ -116,6 +116,15 @@ _re_parse_co_restored = re.compile('^(Re
_re_parse_commit_ext = re.compile('^(([A-Za-z]+( [a-z]+)*)) \'(.+)\'( --.*)?')
_re_parse_commit = re.compile('^(\w+( \(bin\))?)\s+(.+)')
+#rN: eids 0 15 branches 4
+_re_parse_eid_header = re.compile('^r(-1|[0-9]+): eids ([0-9]+) ([0-9]+) '
+ 'branches ([0-9]+)$')
+# B0.2 root-eid 3
+_re_parse_eid_branch = re.compile('^(B[0-9.]+) root-eid ([0-9]+) num-eids ([0-9]+)( from [^ ]*)?$')
+_re_parse_eid_merge_history = re.compile('merge-history: merge-ancestors ([0-9]+)')
+# e4: normal 6 C
+_re_parse_eid_ele = re.compile('^e([0-9]+): (none|normal|subbranch) '
+ '(-1|[0-9]+) (.*)$')
class State:
"""Describes an existing or expected state of a working copy.
@@ -206,6 +215,30 @@ class State:
if list(filter(path, item)):
item.tweak(**kw)
+ def rename(self, moves):
+ """Change the path of some items.
+
+ MOVES is a dictionary mapping source path to destination
+ path. Children move with moved parents. All subtrees are moved in
+ reverse depth order to temporary storage before being moved in
+ depth order to the final location. This allows nested moves.
+
+ """
+ temp = {}
+ for src, dst in sorted(moves.items(), key=lambda (src, dst): src)[::-1]:
+ temp[src] = {}
+ for path, item in self.desc.items():
+ if path == src or path[:len(src) + 1] == src + '/':
+ temp[src][path] = item;
+ del self.desc[path]
+ for src, dst in sorted(moves.items(), key=lambda (src, dst): dst):
+ for path, item in temp[src].items():
+ if path == src:
+ new_path = dst
+ else:
+ new_path = dst + path[len(src):]
+ self.desc[new_path] = item
+
def subtree(self, subtree_path):
"""Return a State object which is a deep copy of the sub-tree
beneath SUBTREE_PATH (which is assumed to be rooted at the tree of
@@ -750,6 +783,63 @@ class State:
return cls('', desc)
+ @classmethod
+ def from_eids(cls, lines):
+
+ # Need to read all elements in a branch before we can construct
+ # the full path to an element.
+ # For the full path we use <branch-id>/<path-within-branch>.
+
+ def eid_path(eids, eid):
+ ele = eids[eid]
+ if ele[0] == '-1':
+ return ele[1]
+ parent_path = eid_path(eids, ele[0])
+ if parent_path == '':
+ return ele[1]
+ return parent_path + '/' + ele[1]
+
+ def eid_full_path(eids, eid, branch_id):
+ path = eid_path(eids, eid)
+ if path == '':
+ return branch_id
+ return branch_id + '/' + path
+
+ def add_to_desc(eids, desc, branch_id):
+ for k, v in eids.items():
+ desc[eid_full_path(eids, k, branch_id)] = StateItem(eid=k)
+
+ branch_id = None
+ eids = {}
+ desc = {}
+ for line in lines:
+
+ match = _re_parse_eid_ele.search(line)
+ if match and match.group(2) != 'none':
+ eid = match.group(1)
+ parent_eid = match.group(3)
+ path = match.group(4)
+ if path == '.':
+ path = ''
+ eids[eid] = [parent_eid, path]
+
+ match = _re_parse_eid_branch.search(line)
+ if match:
+ if branch_id:
+ add_to_desc(eids, desc, branch_id)
+ eids = {}
+ branch_id = match.group(1)
+ root_eid = match.group(2)
+
+ match = _re_parse_eid_merge_history.search(line)
+ if match:
+ ### TODO: store the merge history
+ pass
+
+ add_to_desc(eids, desc, branch_id)
+
+ return cls('', desc)
+
class StateItem:
"""Describes an individual item within a working copy.
@@ -764,7 +854,8 @@ class StateItem:
entry_rev=None, entry_status=None, entry_copied=None,
locked=None, copied=None, switched=None, writelocked=None,
treeconflict=None, moved_from=None, moved_to=None,
- prev_status=None, prev_verb=None, prev_treeconflict=None):
+ prev_status=None, prev_verb=None, prev_treeconflict=None,
+ eid=None):
# provide an empty prop dict if it wasn't provided
if props is None:
props = { }
@@ -772,6 +863,8 @@ class StateItem:
### keep/make these ints one day?
if wc_rev is not None:
wc_rev = str(wc_rev)
+ if eid is not None:
+ eid = str(eid)
# Any attribute can be None if not relevant, unless otherwise stated.
@@ -807,6 +900,7 @@ class StateItem:
# Relative paths to the move locations
self.moved_from = moved_from
self.moved_to = moved_to
+ self.eid = eid
def copy(self):
"Make a deep copy of self."
@@ -820,6 +914,8 @@ class StateItem:
# Refine the revision args (for now) to ensure they are strings.
if value is not None and name == 'wc_rev':
value = str(value)
+ if value is not None and name == 'eid':
+ value = str(value)
setattr(self, name, value)
def __eq__(self, other):
@@ -867,6 +963,8 @@ class StateItem:
atts['moved_from'] = self.moved_from
if self.moved_to is not None:
atts['moved_to'] = self.moved_to
+ if self.eid is not None:
+ atts['eid'] = self.eid
return (os.path.normpath(path), self.contents, self.props, atts)
@@ -980,6 +1078,20 @@ def svn_uri_quote(url):
# ------------
+def python_sqlite_can_read_wc():
+ """Check if the Python builtin is capable enough to peek into wc.db"""
+
+ try:
+ db = svntest.sqlite3.connect('')
+
+ c = db.cursor()
+ c.execute('select sqlite_version()')
+ ver = tuple(map(int, c.fetchall()[0][0].split('.')))
+
+ return ver >= (3, 6, 18) # Currently enough (1.7-1.9)
+ except:
+ return False
+
def open_wc_db(local_path):
"""Open the SQLite DB for the WC path LOCAL_PATH.
Return (DB object, WC root path, WC relpath of LOCAL_PATH)."""
@@ -1035,6 +1147,16 @@ def sqlite_stmt(wc_root_path, stmt):
c.execute(stmt)
return c.fetchall()
+def sqlite_exec(wc_root_path, stmt):
+ """Execute STMT on the SQLite wc.db in WC_ROOT_PATH and return the
+ results."""
+
+ db = open_wc_db(wc_root_path)[0]
+ c = db.cursor()
+ c.execute(stmt)
+ db.commit()
+
+
# ------------
### probably toss these at some point. or major rework. or something.
### just bootstrapping some changes for now.
Modified: subversion/branches/ra-git/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/switch_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/switch_tests.py Mon Nov 30 10:24:16 2015
@@ -771,7 +771,7 @@ def refresh_read_only_attribute(sbox):
# behavior, just skip the test.
if os.name == 'posix':
if os.geteuid() == 0:
- raise svntest.Skip
+ raise svntest.Skip('Test doesn\'t work as uid 0')
sbox.build()
wc_dir = sbox.wc_dir