You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/12/19 19:49:43 UTC
svn commit: r1220893 [17/19] - in /subversion/branches/fs-py: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/ build/win32/
contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/
subversion/bindings/javahl/native/ s...
Modified: subversion/branches/fs-py/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/patch_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/patch_tests.py Mon Dec 19 18:49:34 2011
@@ -3427,7 +3427,6 @@ def patch_strip_cwd(sbox):
"patch --strip propchanges cwd"
return patch_one_property(sbox, True)
-@XFail()
@Issue(3814)
def patch_set_prop_no_eol(sbox):
"patch doesn't append newline to properties"
@@ -3615,7 +3614,6 @@ def patch_moved_away(sbox):
1, # check-props
1) # dry-run
-@XFail()
@Issue(3991)
def patch_lacking_trailing_eol(sbox):
"patch file lacking trailing eol"
@@ -3650,12 +3648,11 @@ def patch_lacking_trailing_eol(sbox):
expected_output = [
'U %s\n' % os.path.join(wc_dir, 'iota'),
- 'svn: W[0-9]+: .*', # warning about appending a newline to iota's last line
]
# Expect a newline to be appended
expected_disk = svntest.main.greek_state.copy()
- expected_disk.tweak('iota', contents=iota_contents+"Some more bytes\n")
+ expected_disk.tweak('iota', contents=iota_contents + "Some more bytes")
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.tweak('iota', status='M ')
@@ -3858,6 +3855,196 @@ def patch_reversed_add_with_props2(sbox)
1, # dry-run
'--reverse-diff')
+def patch_dev_null(sbox):
+ "patch with /dev/null filenames"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+
+ # Git (and maybe other tools) use '/dev/null' as the old path for
+ # newly added files, and as the new path for deleted files.
+ # The path selection algorithm in 'svn patch' must detect this and
+ # avoid using '/dev/null' as a patch target.
+ unidiff_patch = [
+ "Index: new\n",
+ "===================================================================\n",
+ "--- /dev/null\n",
+ "+++ new (revision 0)\n",
+ "@@ -0,0 +1 @@\n",
+ "+new\n",
+ "\n",
+ "Index: A/B/E/beta\n",
+ "===================================================================\n",
+ "--- A/B/E/beta (revision 1)\n",
+ "+++ /dev/null\n",
+ "@@ -1 +0,0 @@\n",
+ "-This is the file 'beta'.\n",
+ ]
+
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ new_contents = "new\n"
+ expected_output = [
+ 'A %s\n' % os.path.join(wc_dir, 'new'),
+ 'D %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
+ ]
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({'new' : Item(contents=new_contents)})
+ expected_disk.remove('A/B/E/beta')
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({'new' : Item(status='A ', wc_rev=0)})
+ expected_status.tweak('A/B/E/beta', status='D ')
+
+ expected_skip = wc.State('', { })
+
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, # expected err
+ 1, # check-props
+ 1) # dry-run
+
+@Issue(4049)
+def patch_delete_and_skip(sbox):
+ "patch that deletes and skips"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+
+ os.chdir(wc_dir)
+
+ # We need to use abspaths to trigger the segmentation fault.
+ abs = os.path.abspath('.')
+ if sys.platform == 'win32':
+ abs = abs.replace("\\", "/")
+
+ outside_wc = os.path.join(os.pardir, 'X')
+ if sys.platform == 'win32':
+ outside_wc = outside_wc.replace("\\", "/")
+
+ unidiff_patch = [
+ "Index: %s/A/B/E/alpha\n" % abs,
+ "===================================================================\n",
+ "--- %s/A/B/E/alpha\t(revision 1)\n" % abs,
+ "+++ %s/A/B/E/alpha\t(working copy)\n" % abs,
+ "@@ -1 +0,0 @@\n",
+ "-This is the file 'alpha'.\n",
+ "Index: %s/A/B/E/beta\n" % abs,
+ "===================================================================\n",
+ "--- %s/A/B/E/beta\t(revision 1)\n" % abs,
+ "+++ %s/A/B/E/beta\t(working copy)\n" % abs,
+ "@@ -1 +0,0 @@\n",
+ "-This is the file 'beta'.\n",
+ "Index: %s/A/B/E/out-of-reach\n" % abs,
+ "===================================================================\n",
+ "--- %s/iota\t(revision 1)\n" % outside_wc,
+ "+++ %s/iota\t(working copy)\n" % outside_wc,
+ "\n",
+ "Property changes on: iota\n",
+ "___________________________________________________________________\n",
+ "Added: propname\n",
+ "## -0,0 +1 ##\n",
+ "+propvalue\n",
+ ]
+
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ skipped_path = os.path.join(os.pardir, 'X', 'iota')
+ expected_output = [
+ 'D %s\n' % os.path.join('A', 'B', 'E', 'alpha'),
+ 'D %s\n' % os.path.join('A', 'B', 'E', 'beta'),
+ 'Skipped missing target: \'%s\'\n' % skipped_path,
+ 'D %s\n' % os.path.join('A', 'B', 'E'),
+ 'Summary of conflicts:\n',
+ ' Skipped paths: 1\n'
+ ]
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha')
+ expected_disk.remove('A/B/E/beta')
+ expected_disk.remove('A/B/E')
+
+ expected_status = svntest.actions.get_virginal_state('.', 1)
+ expected_status.tweak('A/B/E', status='D ')
+ expected_status.tweak('A/B/E/alpha', status='D ')
+ expected_status.tweak('A/B/E/beta', status='D ')
+
+ expected_skip = wc.State('', {skipped_path: Item()})
+
+ svntest.actions.run_and_verify_patch('.', os.path.abspath(patch_file_path),
+ expected_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, # expected err
+ 1, # check-props
+ 1) # dry-run
+
+def patch_target_no_eol_at_eof(sbox):
+ "patch target with no eol at eof"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+ iota_path = os.path.join(wc_dir, 'iota')
+
+ iota_contents = [
+ "This is the file iota."
+ ]
+
+ svntest.main.file_write(iota_path, ''.join(iota_contents))
+ expected_output = svntest.wc.State(wc_dir, {
+ 'iota' : Item(verb='Sending'),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('iota', wc_rev=2)
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ expected_status, None, wc_dir)
+ unidiff_patch = [
+ "--- iota\t(revision 1)\n",
+ "+++ iota\t(working copy)\n",
+ "@@ -1,7 +1,7 @@\n",
+ "-This is the file iota.\n"
+ "\\ No newline at end of file\n",
+ "+It is really the file 'iota'.\n",
+ "\\ No newline at end of file\n",
+ ]
+
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ iota_contents = [
+ "It is really the file 'iota'."
+ ]
+ expected_output = [
+ 'U %s\n' % os.path.join(wc_dir, 'iota'),
+ ]
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('iota', contents=''.join(iota_contents))
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('iota', status='M ', wc_rev=2)
+
+ expected_skip = wc.State('', { })
+
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, # expected err
+ 1, # check-props
+ 1) # dry-run
+
########################################################################
#Run the tests
@@ -3898,6 +4085,9 @@ test_list = [ None,
patch_deletes_prop,
patch_reversed_add_with_props,
patch_reversed_add_with_props2,
+ patch_dev_null,
+ patch_delete_and_skip,
+ patch_target_no_eol_at_eof,
]
if __name__ == '__main__':
Modified: subversion/branches/fs-py/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/prop_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/prop_tests.py Mon Dec 19 18:49:34 2011
@@ -893,8 +893,7 @@ def prop_value_conversions(sbox):
svntest.actions.set_prop('svn:executable', '*', lambda_path)
for pval in (' ', '', 'no', 'off', 'false'):
svntest.actions.set_prop('svn:executable', pval, mu_path,
- ["svn: warning: To turn off the svn:executable property, use 'svn propdel';\n",
- "setting the property to '" + pval + "' will not turn it off.\n"])
+ "svn: warning: W125005.*use 'svn propdel'")
# Anything else should be untouched
svntest.actions.set_prop('svn:some-prop', 'bar', lambda_path)
Modified: subversion/branches/fs-py/subversion/tests/cmdline/resolve_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/resolve_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/resolve_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/resolve_tests.py Mon Dec 19 18:49:34 2011
@@ -42,6 +42,7 @@ Issue = svntest.testcase.Issue_deco
Wimp = svntest.testcase.Wimp_deco
from merge_tests import set_up_branch
+from merge_tests import expected_merge_output
# 'svn resolve --accept [ base | mine-full | theirs-full ]' was segfaulting
# on 1.6.x. Prior to this test, the bug was only caught by the Ruby binding
@@ -69,12 +70,10 @@ def automatic_conflict_resolution(sbox):
'revert', '--recursive', A_COPY_path)
svntest.actions.run_and_verify_svn(
None,
- "(--- Merging r3 into .*A_COPY':\n)|"
- "(C .*psi\n)|"
- "(--- Recording mergeinfo for merge of r3 into .*A_COPY':\n)|"
- "( U .*A_COPY\n)|"
- "(Summary of conflicts:\n)|"
- "( Text conflicts: 1\n)",
+ expected_merge_output([[3]], [
+ "C %s\n" % psi_COPY_path,
+ " U %s\n" % A_COPY_path],
+ target=A_COPY_path, text_conflicts=1),
[], 'merge', '-c3', '--allow-mixed-revisions',
sbox.repo_url + '/A',
A_COPY_path)
Modified: subversion/branches/fs-py/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/special_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/special_tests.py Mon Dec 19 18:49:34 2011
@@ -551,7 +551,9 @@ def diff_symlink_to_dir(sbox):
"___________________________________________________________________\n",
"Added: svn:special\n",
"## -0,0 +1 ##\n",
- "+*\n" ]
+ "+*\n",
+ "\\ No newline at end of property\n"
+ ]
svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
'.')
# We should get the same output if we the diff the symlink itself.
@@ -860,6 +862,49 @@ def symlink_to_wc_svnversion(sbox):
symlink_path, sbox.repo_url,
[ "1\n" ], [])
+# Regression in 1.7.0: Update fails to change a symlink
+@SkipUnless(svntest.main.is_posix_os)
+def update_symlink(sbox):
+ "update a symlink"
+
+ svntest.actions.do_sleep_for_timestamps()
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ mu_path = sbox.ospath('A/mu')
+ iota_path = sbox.ospath('iota')
+ symlink_path = sbox.ospath('symlink')
+
+ # create a symlink to /A/mu
+ os.symlink("A/mu", symlink_path)
+ sbox.simple_add('symlink')
+ sbox.simple_commit()
+
+ # change the symlink to /iota
+ os.remove(symlink_path)
+ os.symlink("iota", symlink_path)
+ sbox.simple_commit()
+
+ # update back to r2
+ svntest.main.run_svn(False, 'update', '-r', '2', wc_dir)
+
+ # now update to head; 1.7.0 throws an assertion here
+ expected_output = svntest.wc.State(wc_dir, {
+ 'symlink' : Item(status='U '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({'symlink': Item(contents="This is the file 'iota'.\n",
+ props={'svn:special' : '*'})})
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+ expected_status.add({
+ 'symlink' : Item(status=' ', wc_rev='3'),
+ })
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
########################################################################
# Run the tests
@@ -887,6 +932,7 @@ test_list = [ None,
merge_foreign_symlink,
symlink_to_wc_basic,
symlink_to_wc_svnversion,
+ update_symlink,
]
if __name__ == '__main__':
Modified: subversion/branches/fs-py/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/stat_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/stat_tests.py Mon Dec 19 18:49:34 2011
@@ -1924,6 +1924,31 @@ def wclock_status(sbox):
'status', wc_dir)
+@Issue(4072)
+@XFail()
+def modified_modulo_translation(sbox):
+ "modified before translation, unmodified after"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # iota is a shell script.
+ sbox.simple_propset('svn:eol-style', 'LF', 'iota')
+ sbox.simple_commit()
+
+ # CRLF it.
+ open(sbox.ospath('iota'), 'wb').write("This is the file 'iota'.\r\n")
+
+ # Run status. Expect some output.
+ # TODO: decide how such files should show in the output; whether they
+ # always show, or only with some --flag; and adjust this accordingly.
+ svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
+ 'status', wc_dir)
+
+ # Expect the file to be renormalized (to LF) after a revert.
+ sbox.simple_revert('iota')
+ svntest.actions.run_and_verify_svn(None, [], [], 'status', wc_dir)
+
########################################################################
# Run the tests
@@ -1965,6 +1990,7 @@ test_list = [ None,
status_locked_deleted,
wc_wc_copy_timestamp,
wclock_status,
+ modified_modulo_translation,
]
if __name__ == '__main__':
Modified: subversion/branches/fs-py/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/svnadmin_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/svnadmin_tests.py Mon Dec 19 18:49:34 2011
@@ -1478,6 +1478,68 @@ def test_lslocks_and_rmlocks(sbox):
"Unexpected output while running 'svnadmin rmlocks'.",
output, [], expected_output, None)
+#----------------------------------------------------------------------
+@Issue(3734)
+def load_ranges(sbox):
+ "'svnadmin load --revision X:Y'"
+
+ ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3734. ##
+ test_create(sbox)
+
+ dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
+ 'svnadmin_tests_data',
+ 'skeleton_repos.dump')
+ dumplines = open(dumpfile_location).readlines()
+ dumpdata = "".join(dumplines)
+
+ # Load our dumpfile, 2 revisions at a time, verifying that we have
+ # the correct youngest revision after each load.
+ load_and_verify_dumpstream(sbox, [], [], None, dumpdata, '-r0:2')
+ svntest.actions.run_and_verify_svnlook("Unexpected output", ['2\n'],
+ None, 'youngest', sbox.repo_dir)
+ load_and_verify_dumpstream(sbox, [], [], None, dumpdata, '-r3:4')
+ svntest.actions.run_and_verify_svnlook("Unexpected output", ['4\n'],
+ None, 'youngest', sbox.repo_dir)
+ load_and_verify_dumpstream(sbox, [], [], None, dumpdata, '-r5:6')
+ svntest.actions.run_and_verify_svnlook("Unexpected output", ['6\n'],
+ None, 'youngest', sbox.repo_dir)
+
+ # There are ordering differences in the property blocks.
+ expected_dump = UnorderedOutput(dumplines)
+ new_dumpdata = svntest.actions.run_and_verify_dump(sbox.repo_dir)
+ svntest.verify.compare_and_display_lines("Dump files", "DUMP",
+ expected_dump, new_dumpdata)
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def hotcopy_incremental(sbox):
+ "'svnadmin hotcopy --incremental PATH .'"
+ sbox.build()
+
+ backup_dir, backup_url = sbox.add_repo_path('backup')
+ os.mkdir(backup_dir)
+ cwd = os.getcwd()
+
+ for i in [1, 2, 3]:
+ os.chdir(backup_dir)
+ svntest.actions.run_and_verify_svnadmin(
+ None, None, [],
+ "hotcopy", "--incremental", os.path.join(cwd, sbox.repo_dir), '.')
+
+ os.chdir(cwd)
+
+ exit_code, origout, origerr = svntest.main.run_svnadmin("dump",
+ sbox.repo_dir,
+ '--quiet')
+ exit_code, backout, backerr = svntest.main.run_svnadmin("dump",
+ backup_dir,
+ '--quiet')
+ if origerr or backerr or origout != backout:
+ raise svntest.Failure
+
+ if i < 3:
+ sbox.simple_mkdir("newdir-%i" % i)
+ sbox.simple_commit()
+
########################################################################
# Run the tests
@@ -1508,6 +1570,8 @@ test_list = [ None,
load_bad_props,
verify_non_utf8_paths,
test_lslocks_and_rmlocks,
+ load_ranges,
+ hotcopy_incremental,
]
if __name__ == '__main__':
Modified: subversion/branches/fs-py/subversion/tests/cmdline/svnmucc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/svnmucc_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/svnmucc_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/svnmucc_tests.py Mon Dec 19 18:49:34 2011
@@ -25,6 +25,7 @@
######################################################################
import svntest
+import re
XFail = svntest.testcase.XFail_deco
Issues = svntest.testcase.Issues_deco
@@ -46,10 +47,276 @@ def reject_bogus_mergeinfo(sbox):
'propset', 'svn:mergeinfo', '/B:0',
sbox.repo_url + '/A')
+_svnmucc_re = re.compile('^(r[0-9]+) committed by jrandom at (.*)$')
+_log_re = re.compile('^ ([ADRM] /[^\(]+($| \(from .*:[0-9]+\)$))')
+_err_re = re.compile('^svnmucc: (.*)$')
+
+def test_svnmucc(repo_url, expected_path_changes, *varargs):
+ """Run svnmucc with the list of SVNMUCC_ARGS arguments. Verify that
+ its run results in a new commit with 'svn log -rHEAD' changed paths
+ that match the list of EXPECTED_PATH_CHANGES."""
+
+ # First, run svnmucc.
+ exit_code, outlines, errlines = svntest.main.run_svnmucc('-U', repo_url,
+ *varargs)
+ if errlines:
+ raise svntest.main.SVNCommitFailure(str(errlines))
+ if len(outlines) != 1 or not _svnmucc_re.match(outlines[0]):
+ raise svntest.main.SVNLineUnequal(str(outlines))
+
+ # Now, run 'svn log -vq -rHEAD'
+ changed_paths = []
+ exit_code, outlines, errlines = \
+ svntest.main.run_svn(None, 'log', '-vqrHEAD', repo_url)
+ if errlines:
+ raise svntest.Failure("Unable to verify commit with 'svn log': %s"
+ % (str(errlines)))
+ for line in outlines:
+ match = _log_re.match(line)
+ if match:
+ changed_paths.append(match.group(1).rstrip('\n\r'))
+
+ expected_path_changes.sort()
+ changed_paths.sort()
+ if changed_paths != expected_path_changes:
+ raise svntest.Failure("Logged path changes differ from expectations\n"
+ " expected: %s\n"
+ " actual: %s" % (str(expected_path_changes),
+ str(changed_paths)))
+
+def xtest_svnmucc(repo_url, expected_errors, *varargs):
+ """Run svnmucc with the list of SVNMUCC_ARGS arguments. Verify that
+ its run results match the list of EXPECTED_ERRORS."""
+
+ # First, run svnmucc.
+ exit_code, outlines, errlines = svntest.main.run_svnmucc('-U', repo_url,
+ *varargs)
+ errors = []
+ for line in errlines:
+ match = _err_re.match(line)
+ if match:
+ errors.append(line.rstrip('\n\r'))
+ if errors != expected_errors:
+ raise svntest.main.SVNUnmatchedError(str(errors))
+
+
+def basic_svnmucc(sbox):
+ "basic svnmucc tests"
+
+ sbox.build()
+ empty_file = sbox.ospath('empty')
+ svntest.main.file_append(empty_file, '')
+
+ # revision 2
+ test_svnmucc(sbox.repo_url,
+ ['A /foo'
+ ], # ---------
+ 'mkdir', 'foo')
+
+ # revision 3
+ test_svnmucc(sbox.repo_url,
+ ['A /z.c',
+ ], # ---------
+ 'put', empty_file, 'z.c')
+
+ # revision 4
+ test_svnmucc(sbox.repo_url,
+ ['A /foo/z.c (from /z.c:3)',
+ 'A /foo/bar (from /foo:3)',
+ ], # ---------
+ 'cp', '3', 'z.c', 'foo/z.c',
+ 'cp', '3', 'foo', 'foo/bar')
+
+ # revision 5
+ test_svnmucc(sbox.repo_url,
+ ['A /zig (from /foo:4)',
+ 'D /zig/bar',
+ 'D /foo',
+ 'A /zig/zag (from /foo:4)',
+ ], # ---------
+ 'cp', '4', 'foo', 'zig',
+ 'rm', 'zig/bar',
+ 'mv', 'foo', 'zig/zag')
+
+ # revision 6
+ test_svnmucc(sbox.repo_url,
+ ['D /z.c',
+ 'A /zig/zag/bar/y.c (from /z.c:5)',
+ 'A /zig/zag/bar/x.c (from /z.c:3)',
+ ], # ---------
+ 'mv', 'z.c', 'zig/zag/bar/y.c',
+ 'cp', '3', 'z.c', 'zig/zag/bar/x.c')
+
+ # revision 7
+ test_svnmucc(sbox.repo_url,
+ ['D /zig/zag/bar/y.c',
+ 'A /zig/zag/bar/y y.c (from /zig/zag/bar/y.c:6)',
+ 'A /zig/zag/bar/y%20y.c (from /zig/zag/bar/y.c:6)',
+ ], # ---------
+ 'mv', 'zig/zag/bar/y.c', 'zig/zag/bar/y%20y.c',
+ 'cp', 'HEAD', 'zig/zag/bar/y.c', 'zig/zag/bar/y%2520y.c')
+
+ # revision 8
+ test_svnmucc(sbox.repo_url,
+ ['D /zig/zag/bar/y y.c',
+ 'A /zig/zag/bar/z z1.c (from /zig/zag/bar/y y.c:7)',
+ 'A /zig/zag/bar/z%20z.c (from /zig/zag/bar/y%20y.c:7)',
+ 'A /zig/zag/bar/z z2.c (from /zig/zag/bar/y y.c:7)',
+ ], #---------
+ 'mv', 'zig/zag/bar/y%20y.c', 'zig/zag/bar/z z1.c',
+ 'cp', 'HEAD', 'zig/zag/bar/y%2520y.c', 'zig/zag/bar/z%2520z.c',
+ 'cp', 'HEAD', 'zig/zag/bar/y y.c', 'zig/zag/bar/z z2.c')
+
+
+ # revision 9
+ test_svnmucc(sbox.repo_url,
+ ['D /zig/zag',
+ 'A /zig/foo (from /zig/zag:8)',
+ 'D /zig/foo/bar/z%20z.c',
+ 'D /zig/foo/bar/z z2.c',
+ 'R /zig/foo/bar/z z1.c (from /zig/zag/bar/x.c:6)',
+ ], #---------
+ 'mv', 'zig/zag', 'zig/foo',
+ 'rm', 'zig/foo/bar/z z1.c',
+ 'rm', 'zig/foo/bar/z%20z2.c',
+ 'rm', 'zig/foo/bar/z%2520z.c',
+ 'cp', '6', 'zig/zag/bar/x.c', 'zig/foo/bar/z%20z1.c')
+
+ # revision 10
+ test_svnmucc(sbox.repo_url,
+ ['R /zig/foo/bar (from /zig/z.c:9)',
+ ], #---------
+ 'rm', 'zig/foo/bar',
+ 'cp', '9', 'zig/z.c', 'zig/foo/bar')
+
+ # revision 11
+ test_svnmucc(sbox.repo_url,
+ ['R /zig/foo/bar (from /zig/foo/bar:9)',
+ 'D /zig/foo/bar/z z1.c',
+ ], #---------
+ 'rm', 'zig/foo/bar',
+ 'cp', '9', 'zig/foo/bar', 'zig/foo/bar',
+ 'rm', 'zig/foo/bar/z%20z1.c')
+
+ # revision 12
+ test_svnmucc(sbox.repo_url,
+ ['R /zig/foo (from /zig/foo/bar:11)',
+ ], #---------
+ 'rm', 'zig/foo',
+ 'cp', 'head', 'zig/foo/bar', 'zig/foo')
+
+ # revision 13
+ test_svnmucc(sbox.repo_url,
+ ['D /zig',
+ 'A /foo (from /foo:4)',
+ 'A /foo/foo (from /foo:4)',
+ 'A /foo/foo/foo (from /foo:4)',
+ 'D /foo/foo/bar',
+ 'R /foo/foo/foo/bar (from /foo:4)',
+ ], #---------
+ 'rm', 'zig',
+ 'cp', '4', 'foo', 'foo',
+ 'cp', '4', 'foo', 'foo/foo',
+ 'cp', '4', 'foo', 'foo/foo/foo',
+ 'rm', 'foo/foo/bar',
+ 'rm', 'foo/foo/foo/bar',
+ 'cp', '4', 'foo', 'foo/foo/foo/bar')
+
+ # revision 14
+ test_svnmucc(sbox.repo_url,
+ ['A /boozle (from /foo:4)',
+ 'A /boozle/buz',
+ 'A /boozle/buz/nuz',
+ ], #---------
+ 'cp', '4', 'foo', 'boozle',
+ 'mkdir', 'boozle/buz',
+ 'mkdir', 'boozle/buz/nuz')
+
+ # revision 15
+ test_svnmucc(sbox.repo_url,
+ ['A /boozle/buz/svnmucc-test.py',
+ 'A /boozle/guz (from /boozle/buz:14)',
+ 'A /boozle/guz/svnmucc-test.py',
+ ], #---------
+ 'put', empty_file, 'boozle/buz/svnmucc-test.py',
+ 'cp', '14', 'boozle/buz', 'boozle/guz',
+ 'put', empty_file, 'boozle/guz/svnmucc-test.py')
+
+ # revision 16
+ test_svnmucc(sbox.repo_url,
+ ['M /boozle/buz/svnmucc-test.py',
+ 'R /boozle/guz/svnmucc-test.py',
+ ], #---------
+ 'put', empty_file, 'boozle/buz/svnmucc-test.py',
+ 'rm', 'boozle/guz/svnmucc-test.py',
+ 'put', empty_file, 'boozle/guz/svnmucc-test.py')
+
+ # revision 17
+ test_svnmucc(sbox.repo_url,
+ ['R /foo/bar (from /foo/foo:16)'], #---------
+ 'rm', 'foo/bar',
+ 'cp', '16', 'foo/foo', 'foo/bar',
+ 'propset', 'testprop', 'true', 'foo/bar')
+
+ # revision 18
+ test_svnmucc(sbox.repo_url,
+ ['M /foo/bar'], #---------
+ 'propdel', 'testprop', 'foo/bar')
+
+ # revision 19
+ test_svnmucc(sbox.repo_url,
+ ['M /foo/z.c',
+ 'M /foo/foo',
+ ], #---------
+ 'propset', 'testprop', 'true', 'foo/z.c',
+ 'propset', 'testprop', 'true', 'foo/foo')
+
+ # revision 20
+ test_svnmucc(sbox.repo_url,
+ ['M /foo/z.c',
+ 'M /foo/foo',
+ ], #---------
+ 'propsetf', 'testprop', empty_file, 'foo/z.c',
+ 'propsetf', 'testprop', empty_file, 'foo/foo')
+
+ # Expected missing revision error
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E200004: 'a' is not a revision"
+ ], #---------
+ 'cp', 'a', 'b')
+
+ # Expected cannot be younger error
+ xtest_svnmucc(sbox.repo_url,
+ ['svnmucc: E205000: Copy source revision cannot be younger ' +
+ 'than base revision',
+ ], #---------
+ 'cp', '42', 'a', 'b')
+
+ # Expected already exists error
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E125002: 'foo' already exists",
+ ], #---------
+ 'cp', '17', 'a', 'foo')
+
+ # Expected copy_src already exists error
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E125002: 'a/bar' (from 'foo/bar:17') already exists",
+ ], #---------
+ 'cp', '17', 'foo', 'a',
+ 'cp', '17', 'foo/foo', 'a/bar')
+
+ # Expected not found error
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E125002: 'a' not found",
+ ], #---------
+ 'cp', '17', 'a', 'b')
+
+
######################################################################
test_list = [ None,
reject_bogus_mergeinfo,
+ basic_svnmucc,
]
if __name__ == '__main__':
Modified: subversion/branches/fs-py/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/svntest/actions.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/svntest/actions.py Mon Dec 19 18:49:34 2011
@@ -1258,7 +1258,7 @@ def run_and_verify_mergeinfo(error_re_st
verify.verify_outputs(None, None, err, None, expected_err)
return
- out = sorted([_f for _f in [x.rstrip()[1:] for x in out] if _f])
+ out = [_f for _f in [x.rstrip()[1:] for x in out] if _f]
expected_output.sort()
extra_out = []
if out != expected_output:
@@ -1748,6 +1748,11 @@ def lock_admin_dir(wc_dir, recursive=Fal
svntest.main.run_wc_lock_tester(recursive, wc_dir)
+def set_incomplete(wc_dir, revision):
+ "Make wc_dir incomplete at revision"
+
+ svntest.main.run_wc_incomplete_tester(wc_dir, revision)
+
def get_wc_uuid(wc_dir):
"Return the UUID of the working copy at WC_DIR."
return run_and_parse_info(wc_dir)[0]['Repository UUID']
@@ -1818,7 +1823,7 @@ def create_failing_post_commit_hook(repo
# set_prop can be used for properties with NULL characters which are not
# handled correctly when passed to subprocess.Popen() and values like "*"
# which are not handled correctly on Windows.
-def set_prop(name, value, path, expected_err=None):
+def set_prop(name, value, path, expected_re_string=None):
"""Set a property with specified value"""
if value and (value[0] == '-' or '\x00' in value or sys.platform == 'win32'):
from tempfile import mkstemp
@@ -1828,10 +1833,17 @@ def set_prop(name, value, path, expected
value_file.write(value)
value_file.flush()
value_file.close()
- main.run_svn(expected_err, 'propset', '-F', value_file_path, name, path)
+ exit_code, out, err = main.run_svn(expected_re_string, 'propset',
+ '-F', value_file_path, name, path)
os.remove(value_file_path)
else:
- main.run_svn(expected_err, 'propset', name, value, path)
+ exit_code, out, err = main.run_svn(expected_re_string, 'propset',
+ name, value, path)
+ if expected_re_string:
+ if not expected_re_string.startswith(".*"):
+ expected_re_string = ".*(" + expected_re_string + ")"
+ expected_err = verify.RegexOutput(expected_re_string, match_all=False)
+ verify.verify_outputs(None, None, err, None, expected_err)
def check_prop(name, path, exp_out, revprop=None):
"""Verify that property NAME on PATH has a value of EXP_OUT.
Modified: subversion/branches/fs-py/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/svntest/main.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/svntest/main.py Mon Dec 19 18:49:34 2011
@@ -165,6 +165,7 @@ entriesdump_binary = os.path.abspath('en
atomic_ra_revprop_change_binary = os.path.abspath('atomic-ra-revprop-change' + \
_exe)
wc_lock_tester_binary = os.path.abspath('../libsvn_wc/wc-lock-tester' + _exe)
+wc_incomplete_tester_binary = os.path.abspath('../libsvn_wc/wc-incomplete-tester' + _exe)
svnmucc_binary=os.path.abspath('../../../tools/client-side/svnmucc/svnmucc' + \
_exe)
@@ -683,6 +684,10 @@ def run_wc_lock_tester(recursive, path):
option = "-1"
return run_command(wc_lock_tester_binary, False, False, option, path)
+def run_wc_incomplete_tester(wc_dir, revision):
+ "Run the wc-incomplete tool, returning its exit code, stdout and stderr"
+ return run_command(wc_incomplete_tester_binary, False, False,
+ wc_dir, revision)
def youngest(repos_path):
"run 'svnlook youngest' on REPOS_PATH, returns revision as int"
@@ -993,51 +998,60 @@ def use_editor(func):
os.environ['SVNTEST_EDITOR_FUNC'] = func
os.environ['SVN_TEST_PYTHON'] = sys.executable
-def mergeinfo_notify_line(revstart, revend):
+def mergeinfo_notify_line(revstart, revend, target=None):
"""Return an expected output line that describes the beginning of a
mergeinfo recording notification on revisions REVSTART through REVEND."""
+ if target:
+ target_re = re.escape(target)
+ else:
+ target_re = ".+"
if (revend is None):
if (revstart < 0):
revstart = abs(revstart)
- return "--- Recording mergeinfo for reverse merge of r%ld .*:\n" \
- % (revstart)
+ return "--- Recording mergeinfo for reverse merge of r%ld into '%s':\n" \
+ % (revstart, target_re)
else:
- return "--- Recording mergeinfo for merge of r%ld .*:\n" % (revstart)
+ return "--- Recording mergeinfo for merge of r%ld into '%s':\n" \
+ % (revstart, target_re)
elif (revstart < revend):
- return "--- Recording mergeinfo for merge of r%ld through r%ld .*:\n" \
- % (revstart, revend)
+ return "--- Recording mergeinfo for merge of r%ld through r%ld into '%s':\n" \
+ % (revstart, revend, target_re)
else:
return "--- Recording mergeinfo for reverse merge of r%ld through " \
- "r%ld .*:\n" % (revstart, revend)
+ "r%ld into '%s':\n" % (revstart, revend, target_re)
def merge_notify_line(revstart=None, revend=None, same_URL=True,
- foreign=False):
+ foreign=False, target=None):
"""Return an expected output line that describes the beginning of a
merge operation on revisions REVSTART through REVEND. Omit both
REVSTART and REVEND for the case where the left and right sides of
the merge are from different URLs."""
from_foreign_phrase = foreign and "\(from foreign repository\) " or ""
+ if target:
+ target_re = re.escape(target)
+ else:
+ target_re = ".+"
if not same_URL:
- return "--- Merging differences between %srepository URLs into '.+':\n" \
- % (foreign and "foreign " or "")
+ return "--- Merging differences between %srepository URLs into '%s':\n" \
+ % (foreign and "foreign " or "", target_re)
if revend is None:
if revstart is None:
# The left and right sides of the merge are from different URLs.
- return "--- Merging differences between %srepository URLs into '.+':\n" \
- % (foreign and "foreign " or "")
+ return "--- Merging differences between %srepository URLs into '%s':\n" \
+ % (foreign and "foreign " or "", target_re)
elif revstart < 0:
- return "--- Reverse-merging %sr%ld into '.+':\n" \
- % (from_foreign_phrase, abs(revstart))
+ return "--- Reverse-merging %sr%ld into '%s':\n" \
+ % (from_foreign_phrase, abs(revstart), target_re)
else:
- return "--- Merging %sr%ld into '.+':\n" \
- % (from_foreign_phrase, revstart)
+ return "--- Merging %sr%ld into '%s':\n" \
+ % (from_foreign_phrase, revstart, target_re)
else:
if revstart > revend:
- return "--- Reverse-merging %sr%ld through r%ld into '.+':\n" \
- % (from_foreign_phrase, revstart, revend)
+ return "--- Reverse-merging %sr%ld through r%ld into '%s':\n" \
+ % (from_foreign_phrase, revstart, revend, target_re)
else:
- return "--- Merging %sr%ld through r%ld into '.+':\n" \
- % (from_foreign_phrase, revstart, revend)
+ return "--- Merging %sr%ld through r%ld into '%s':\n" \
+ % (from_foreign_phrase, revstart, revend, target_re)
def make_log_msg():
Modified: subversion/branches/fs-py/subversion/tests/cmdline/tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/tree_conflict_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/tree_conflict_tests.py Mon Dec 19 18:49:34 2011
@@ -278,6 +278,9 @@ f_moves = [
d_dels = [
( create_d, ['dD'] ),
+]
+
+d_moves = [
( create_d, ['dM'] ),
]
@@ -604,12 +607,12 @@ def up_sw_dir_mod_onto_del(sbox):
def up_sw_dir_del_onto_mod(sbox):
"up/sw dir: del/rpl/mv onto modify"
# WC state: any (D necessarily exists; children may have any state)
- test_tc_up_sw(sbox, d_dels + d_rpls, d_mods)
+ test_tc_up_sw(sbox, d_dels + d_moves + d_rpls, d_mods)
def up_sw_dir_del_onto_del(sbox):
"up/sw dir: del/rpl/mv onto del/rpl/mv"
# WC state: any (D necessarily exists; children may have any state)
- test_tc_up_sw(sbox, d_dels + d_rpls, d_dels + d_rpls)
+ test_tc_up_sw(sbox, d_dels + d_moves + d_rpls, d_dels + d_rpls)
# This is currently set as XFail over ra_dav because it hits
# issue #3314 'DAV can overwrite directories during copy'
@@ -690,8 +693,8 @@ def merge_file_add_onto_not_none(sbox):
def merge_dir_mod_onto_not_dir(sbox):
"merge dir: modify onto not-dir"
sbox2 = sbox.clone_dependent()
- test_tc_merge(sbox, d_mods, br_scen = d_dels + d_rpl_f)
- test_tc_merge(sbox2, d_mods, wc_scen = d_dels)
+ test_tc_merge(sbox, d_mods, br_scen = d_dels + d_moves + d_rpl_f)
+ test_tc_merge(sbox2, d_mods, wc_scen = d_dels + d_moves)
# Test for issue #3150 'tree conflicts with directories as victims'.
@XFail()
@@ -699,14 +702,14 @@ def merge_dir_mod_onto_not_dir(sbox):
def merge_dir_del_onto_not_same(sbox):
"merge dir: del/rpl/mv onto not-same"
sbox2 = sbox.clone_dependent()
- test_tc_merge(sbox, d_dels + d_rpls, br_scen = d_mods)
- test_tc_merge(sbox2, d_dels + d_rpls, wc_scen = d_mods)
+ test_tc_merge(sbox, d_dels + d_moves + d_rpls, br_scen = d_mods)
+ test_tc_merge(sbox2, d_dels + d_moves + d_rpls, wc_scen = d_mods)
def merge_dir_del_onto_not_dir(sbox):
"merge dir: del/rpl/mv onto not-dir"
sbox2 = sbox.clone_dependent()
- test_tc_merge(sbox, d_dels + d_rpls, br_scen = d_dels + d_rpl_f)
- test_tc_merge(sbox2, d_dels + d_rpls, wc_scen = d_dels)
+ test_tc_merge(sbox, d_dels + d_moves + d_rpls, br_scen = d_dels + d_moves + d_rpl_f)
+ test_tc_merge(sbox2, d_dels + d_moves + d_rpls, wc_scen = d_dels + d_moves)
def merge_dir_add_onto_not_none(sbox):
"merge dir: add onto not-none"
Modified: subversion/branches/fs-py/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/update_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/update_tests.py Mon Dec 19 18:49:34 2011
@@ -5404,6 +5404,212 @@ def update_to_HEAD_plus_1(sbox):
None, None,
None, None, None, wc_dir, '-r', '2')
+def update_moved_dir_leaf_del(sbox):
+ "update locally moved dir with leaf del"
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ svntest.main.run_svn(False, 'rm', '-m', 'remove /A/B/E/alpha',
+ sbox.repo_url + "/A/B/E/alpha")
+ sbox.simple_move("A/B/E", "A/B/E2")
+
+ # since alpha isn't locally modified, the incoming delete should auto-merge
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/B/E2/alpha' : Item(status='D '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+ expected_disk.add({
+ 'A/B/E2' : Item(),
+ 'A/B/E2/beta' : Item(contents="This is the file 'beta'.\n"),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.add({
+ 'A/B/E2' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/B/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/B/E2/alpha' : Item(status='D ', copied='+', wc_rev='-'),
+ })
+ expected_status.remove('A/B/E/alpha')
+ expected_status.tweak('A/B/E', 'A/B/E/beta', status='D ')
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
+
+def update_moved_dir_edited_leaf_del(sbox):
+ "update locally moved dir with edited leaf del"
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ svntest.main.run_svn(False, 'rm', '-m', 'remove /A/B/E/alpha',
+ sbox.repo_url + "/A/B/E/alpha")
+ sbox.simple_move("A/B/E", "A/B/E2")
+ svntest.main.file_write(sbox.ospath('A/B/E2/alpha'),
+ "This is a changed 'alpha'.\n")
+
+ # since alpha was modified post-move, the incoming delete should conflict
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/B/E/alpha' : Item(status=' ', treeconflict='C'),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+ expected_disk.add({
+ 'A/B/E2' : Item(),
+ 'A/B/E2/alpha' : Item(contents="This is a changed 'alpha'.\n"),
+ 'A/B/E2/beta' : Item(contents="This is the file 'beta'.\n"),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.tweak('A/B/E', 'A/B/E/beta', status='D ')
+ expected_status.remove('A/B/E/alpha')
+ expected_status.add({
+ 'A/B/E/alpha' : Item(status='! ', treeconflict='C'),
+ 'A/B/E2' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/B/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/B/E2/alpha' : Item(status='M ', copied='+', wc_rev='-'),
+ })
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
+
+def update_moved_dir_file_add(sbox):
+ "update locally moved dir with incoming file"
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ foo_path = "A/B/E/foo"
+ foo_content = "This is the file 'foo'.\n"
+
+ svntest.main.file_write(sbox.ospath(foo_path), foo_content, 'wb')
+ sbox.simple_add(foo_path)
+ sbox.simple_commit()
+ # update to go back in time, before the last commit
+ svntest.main.run_svn(False, 'update', '-r', '1', wc_dir)
+ sbox.simple_move("A/B/E", "A/B/E2")
+
+ # the incoming file should auto-merge
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/B/E2/foo' : Item(status='A '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+ expected_disk.add({
+ 'A/B/E2' : Item(),
+ 'A/B/E2/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'A/B/E2/beta' : Item(contents="This is the file 'beta'.\n"),
+ 'A/B/E2/foo' : Item(contents=foo_content),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+ expected_status.add({
+ 'A/B/E/foo' : Item(status='D ', wc_rev='2'),
+ 'A/B/E2' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/B/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/B/E2/alpha' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/B/E2/foo' : Item(status='A ', copied='+', wc_rev='-'),
+ })
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
+
+def update_moved_dir_dir_add(sbox):
+ "update locally moved dir with incoming dir"
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ foo_path = "A/B/E/foo"
+ bar_path = "A/B/E/foo/bar"
+ bar_content = "This is the file 'bar'.\n"
+
+ sbox.simple_mkdir(foo_path)
+ svntest.main.file_write(sbox.ospath(bar_path), bar_content, 'wb')
+ sbox.simple_add(bar_path)
+ sbox.simple_commit()
+ # update to go back in time, before the last commit
+ svntest.main.run_svn(False, 'update', '-r', '1', wc_dir)
+ sbox.simple_move("A/B/E", "A/B/E2")
+
+ # the incoming file should auto-merge
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/B/E2/foo' : Item(status='A '),
+ 'A/B/E2/foo/bar' : Item(status='A '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+ expected_disk.add({
+ 'A/B/E2' : Item(),
+ 'A/B/E2/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'A/B/E2/beta' : Item(contents="This is the file 'beta'.\n"),
+ 'A/B/E2/foo' : Item(),
+ 'A/B/E2/foo/bar' : Item(contents=bar_content),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+ expected_status.add({
+ 'A/B/E/foo' : Item(status='D ', wc_rev='2'),
+ 'A/B/E/foo/bar' : Item(status='D ', wc_rev='2'),
+ 'A/B/E2' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/B/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/B/E2/alpha' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/B/E2/foo' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/B/E2/foo/bar' : Item(status='A ', copied='+', wc_rev='-'),
+ })
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
+
+@XFail()
+@Issue(4037)
+def update_moved_dir_file_move(sbox):
+ "update locally moved dir with incoming file move"
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_move("A/B/E/alpha", "A/B/F/alpha")
+ sbox.simple_commit()
+ # update to go back in time, before the previous commit
+ svntest.main.run_svn(False, 'update', '-r', '1', wc_dir)
+ sbox.simple_move("A/B/E", "A/B/E2")
+
+ # The incoming move should auto-merge such that A/B/F/alpha appears
+ # as moved to A/B/E2/alpha -- this strategy prefers the local user's
+ # change as the solution to the conflict.
+ # ### Ideally, the user should be offered a set of alternative solutions.
+ # ### E.g. the user might prefer if A/B/E2/alpha disappeared and A/B/E/alpha
+ # ### appeared as moved to A/B/F/alpha. But the --accept option does not yet
+ # ### support tree conflicts.
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/B/E2/alpha' : Item(status='A '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+ expected_disk.add({
+ 'A/B/E2' : Item(),
+ 'A/B/E2/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'A/B/E2/beta' : Item(contents="This is the file 'beta'.\n"),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+ expected_status.add({
+ 'A/B/F/alpha' : Item(status='D '),
+ 'A/B/E2' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/B/E2/alpha' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/B/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ })
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
#######################################################################
# Run the tests
@@ -5471,6 +5677,11 @@ test_list = [ None,
revive_children_of_copy,
skip_access_denied,
update_to_HEAD_plus_1,
+ update_moved_dir_leaf_del,
+ update_moved_dir_edited_leaf_del,
+ update_moved_dir_file_add,
+ update_moved_dir_dir_add,
+ update_moved_dir_file_move,
]
if __name__ == '__main__':
Modified: subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests.py?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests.py Mon Dec 19 18:49:34 2011
@@ -75,6 +75,23 @@ def replace_sbox_with_tarfile(sbox, tar_
shutil.move(os.path.join(extract_dir, dir), sbox.wc_dir)
+def replace_sbox_repo_with_tarfile(sbox, tar_filename, dir=None):
+ try:
+ svntest.main.safe_rmtree(sbox.repo_dir)
+ except OSError, e:
+ pass
+
+ if not dir:
+ dir = tar_filename.split('.')[0]
+
+ tarpath = os.path.join(os.path.dirname(sys.argv[0]), 'upgrade_tests_data',
+ tar_filename)
+ t = tarfile.open(tarpath, 'r:bz2')
+ extract_dir = tempfile.mkdtemp(dir=svntest.main.temp_dir)
+ for member in t.getmembers():
+ t.extract(member, extract_dir)
+
+ shutil.move(os.path.join(extract_dir, dir), sbox.repo_dir)
def check_format(sbox, expected_format):
dot_svn = svntest.main.get_admin_name()
@@ -1181,6 +1198,61 @@ def upgrade_file_externals(sbox):
'alpha' : {'pname3' : 'pvalue3' },
})
+
+@Issue(4035)
+def upgrade_missing_replaced(sbox):
+ "upgrade with missing replaced dir"
+
+ sbox.build(create_wc=False)
+ replace_sbox_with_tarfile(sbox, 'upgrade_missing_replaced.tar.bz2')
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir)
+ svntest.main.run_svnadmin('setuuid', sbox.repo_dir,
+ 'd7130b12-92f6-45c9-9217-b9f0472c3fab')
+ svntest.actions.run_and_verify_svn(None, None, [], 'relocate',
+ 'file:///tmp/repo', sbox.repo_url,
+ sbox.wc_dir)
+
+ expected_output = svntest.wc.State(sbox.wc_dir, {
+ 'A/B/E' : Item(status=' ', treeconflict='C'),
+ 'A/B/E/alpha' : Item(status=' ', treeconflict='A'),
+ 'A/B/E/beta' : Item(status=' ', treeconflict='A'),
+ })
+ expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+ expected_status.tweak('A/B/E', status='! ', treeconflict='C', wc_rev='-')
+ expected_status.tweak('A/B/E/alpha', 'A/B/E/beta', status='D ')
+ svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output,
+ None, expected_status)
+
+ svntest.actions.run_and_verify_svn(None, 'Reverted.*', [], 'revert', '-R',
+ sbox.wc_dir)
+ expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+ svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status)
+
+@Issue(4033)
+def upgrade_not_present_replaced(sbox):
+ "upgrade with not-present replaced nodes"
+
+ sbox.build(create_wc=False)
+ replace_sbox_with_tarfile(sbox, 'upgrade_not_present_replaced.tar.bz2')
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir)
+ svntest.main.run_svnadmin('setuuid', sbox.repo_dir,
+ 'd7130b12-92f6-45c9-9217-b9f0472c3fab')
+ svntest.actions.run_and_verify_svn(None, None, [], 'relocate',
+ 'file:///tmp/repo', sbox.repo_url,
+ sbox.wc_dir)
+
+ expected_output = svntest.wc.State(sbox.wc_dir, {
+ 'A/B/E' : Item(status='E '),
+ 'A/B/E/alpha' : Item(status='A '),
+ 'A/B/E/beta' : Item(status='A '),
+ 'A/B/lambda' : Item(status='E '),
+ })
+ expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+ svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output,
+ None, expected_status)
+
########################################################################
# Run the tests
@@ -1230,6 +1302,8 @@ test_list = [ None,
upgrade_with_missing_subdir,
upgrade_locked,
upgrade_file_externals,
+ upgrade_missing_replaced,
+ upgrade_not_present_replaced,
]
Modified: subversion/branches/fs-py/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_client/client-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_client/client-test.c Mon Dec 19 18:49:34 2011
@@ -28,6 +28,7 @@
#include <limits.h>
#include "svn_mergeinfo.h"
#include "../../libsvn_client/mergeinfo.h"
+#include "../../libsvn_client/client.h"
#include "svn_pools.h"
#include "svn_client.h"
#include "svn_repos.h"
@@ -102,26 +103,28 @@ test_elide_mergeinfo_catalog(apr_pool_t
i < sizeof(elide_testcases) / sizeof(elide_testcases[0]);
i++)
{
- apr_hash_t *catalog;
+ svn_mergeinfo_catalog_t mergeinfo_catalog;
mergeinfo_catalog_item *item;
svn_pool_clear(iterpool);
- catalog = apr_hash_make(iterpool);
+ mergeinfo_catalog = apr_hash_make(iterpool);
for (item = elide_testcases[i]; item->path; item++)
{
- apr_hash_t *mergeinfo;
+ svn_mergeinfo_t mergeinfo;
SVN_ERR(svn_mergeinfo_parse(&mergeinfo, item->unparsed_mergeinfo,
iterpool));
- apr_hash_set(catalog, item->path, APR_HASH_KEY_STRING, mergeinfo);
+ apr_hash_set(mergeinfo_catalog, item->path, APR_HASH_KEY_STRING,
+ mergeinfo);
}
- SVN_ERR(svn_client__elide_mergeinfo_catalog(catalog, iterpool));
+ SVN_ERR(svn_client__elide_mergeinfo_catalog(mergeinfo_catalog,
+ iterpool));
for (item = elide_testcases[i]; item->path; item++)
{
- apr_hash_t *mergeinfo = apr_hash_get(catalog, item->path,
+ apr_hash_t *mergeinfo = apr_hash_get(mergeinfo_catalog, item->path,
APR_HASH_KEY_STRING);
if (item->remains && !mergeinfo)
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
@@ -648,6 +651,71 @@ test_16k_add(const svn_test_opts_t *opts
}
#endif
+static svn_error_t *
+test_youngest_common_ancestor(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ const char *repos_url;
+ svn_client_ctx_t *ctx;
+ svn_opt_revision_t head_rev = { svn_opt_revision_head, { 0 } };
+ svn_opt_revision_t zero_rev = { svn_opt_revision_number, { 0 } };
+ svn_client_copy_source_t source;
+ apr_array_header_t *sources;
+ const char *dest;
+ const char *yc_ancestor_relpath;
+ svn_revnum_t yc_ancestor_rev;
+
+ /* Create a filesytem and repository containing the Greek tree. */
+ SVN_ERR(create_greek_repos(&repos_url, "test-youngest-common-ancestor", opts, pool));
+
+ svn_client_create_context(&ctx, pool);
+
+ /* Copy a file into dir 'A', keeping its own basename. */
+ sources = apr_array_make(pool, 1, sizeof(svn_client_copy_source_t *));
+ source.path = svn_path_url_add_component2(repos_url, "iota", pool);
+ source.peg_revision = &head_rev;
+ source.revision = &head_rev;
+ APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = &source;
+ dest = svn_path_url_add_component2(repos_url, "A", pool);
+ SVN_ERR(svn_client_copy6(sources, dest, TRUE /* copy_as_child */,
+ FALSE /* make_parents */,
+ FALSE /* ignore_externals */,
+ NULL, NULL, NULL, ctx, pool));
+
+ /* Test: YCA(iota@2, A/iota@2) is iota@1. */
+ SVN_ERR(svn_client__get_youngest_common_ancestor(
+ &yc_ancestor_relpath, NULL, &yc_ancestor_rev,
+ svn_path_url_add_component2(repos_url, "iota", pool), 2,
+ svn_path_url_add_component2(repos_url, "A/iota", pool), 2,
+ ctx, pool));
+ SVN_TEST_STRING_ASSERT(yc_ancestor_relpath, "iota");
+ SVN_TEST_ASSERT(yc_ancestor_rev == 1);
+
+ /* Copy the root directory (at revision 0) into A as 'ROOT'. */
+ sources = apr_array_make(pool, 1, sizeof(svn_client_copy_source_t *));
+ source.path = repos_url;
+ source.peg_revision = &zero_rev;
+ source.revision = &zero_rev;
+ APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = &source;
+ dest = svn_path_url_add_component2(repos_url, "A/ROOT", pool);
+ SVN_ERR(svn_client_copy6(sources, dest, FALSE /* copy_as_child */,
+ FALSE /* make_parents */,
+ FALSE /* ignore_externals */,
+ NULL, NULL, NULL, ctx, pool));
+
+ /* Test: YCA(''@0, A/ROOT@3) is ''@0 (handled as a special case). */
+ SVN_ERR(svn_client__get_youngest_common_ancestor(
+ &yc_ancestor_relpath, NULL, &yc_ancestor_rev,
+ svn_path_url_add_component2(repos_url, "", pool), 0,
+ svn_path_url_add_component2(repos_url, "A/ROOT", pool), 3,
+ ctx, pool));
+ SVN_TEST_STRING_ASSERT(yc_ancestor_relpath, "");
+ SVN_TEST_ASSERT(yc_ancestor_rev == 0);
+
+ return SVN_NO_ERROR;
+}
+
+
/* ========================================================================== */
struct svn_test_descriptor_t test_funcs[] =
@@ -663,5 +731,6 @@ struct svn_test_descriptor_t test_funcs[
#ifdef TEST16K_ADD
SVN_TEST_OPTS_PASS(test_16k_add, "test adding 16k files"),
#endif
+ SVN_TEST_OPTS_PASS(test_youngest_common_ancestor, "test youngest_common_ancestor"),
SVN_TEST_NULL
};
Modified: subversion/branches/fs-py/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_diff/diff-diff3-test.c Mon Dec 19 18:49:34 2011
@@ -175,7 +175,7 @@ three_way_merge(const char *filename1,
SVN_ERR(svn_diff_mem_string_diff3(&diff,
original, modified, latest, options, pool));
- actual = svn_stringbuf_create("", pool);
+ actual = svn_stringbuf_create_empty(pool);
ostream = svn_stream_from_stringbuf(actual, pool);
SVN_ERR(svn_diff_mem_string_output_merge2
@@ -265,7 +265,7 @@ two_way_diff(const char *filename1,
SVN_ERR(svn_diff_mem_string_diff(&diff, original, modified, options, pool));
- actual = svn_stringbuf_create("", pool);
+ actual = svn_stringbuf_create_empty(pool);
ostream = svn_stream_from_stringbuf(actual, pool);
SVN_ERR(svn_diff_mem_string_output_unified(ostream, diff,
Modified: subversion/branches/fs-py/subversion/tests/libsvn_diff/parse-diff-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_diff/parse-diff-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_diff/parse-diff-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_diff/parse-diff-test.c Mon Dec 19 18:49:34 2011
@@ -314,7 +314,8 @@ check_content(svn_diff_hunk_t *hunk, svn
SVN_TEST_STRING_ASSERT(exp_buf->data, hunk_buf->data);
}
- SVN_TEST_ASSERT(hunk_buf->len == 0);
+ if (!hunk_eof)
+ SVN_TEST_ASSERT(hunk_buf->len == 0);
return SVN_NO_ERROR;
}
@@ -946,11 +947,9 @@ test_parse_unidiff_lacking_trailing_eol(
"This is the file 'gamma'." NL,
pool));
- /* Verify that the contents are as expected, with a NL appended.
- TODO: test for notification about the NL silently appended */
SVN_ERR(check_content(hunk, reverse,
"This is the file 'gamma'." NL
- "some more bytes to 'gamma'" NL,
+ "some more bytes to 'gamma'",
pool));
reverse = !reverse;
@@ -981,7 +980,7 @@ struct svn_test_descriptor_t test_funcs[
"test property diffs with odd symbols"),
SVN_TEST_PASS2(test_git_diffs_with_spaces_diff,
"test git diffs with spaces in paths"),
- SVN_TEST_XFAIL2(test_parse_unidiff_lacking_trailing_eol,
+ SVN_TEST_PASS2(test_parse_unidiff_lacking_trailing_eol,
"test parsing unidiffs lacking trailing eol"),
SVN_TEST_NULL
};
Modified: subversion/branches/fs-py/subversion/tests/libsvn_fs/locks-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_fs/locks-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_fs/locks-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_fs/locks-test.c Mon Dec 19 18:49:34 2011
@@ -358,6 +358,18 @@ get_locks(const svn_test_opts_t *opts,
num_expected_paths, pool));
}
+ /* A path that is longer and alphabetically earlier than some locked
+ paths, this exercises the r1205848 BDB lock code. */
+ {
+ static const char *expected_paths[] = { 0 };
+ num_expected_paths = 0;
+ get_locks_baton = make_get_locks_baton(pool);
+ SVN_ERR(svn_fs_get_locks(fs, "A/D/H/ABCDEFGHIJKLMNOPQR", get_locks_callback,
+ get_locks_baton, pool));
+ SVN_ERR(verify_matching_lock_paths(get_locks_baton, expected_paths,
+ num_expected_paths, pool));
+ }
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/fs-py/subversion/tests/libsvn_fs_base/strings-reps-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_fs_base/strings-reps-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_fs_base/strings-reps-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_fs_base/strings-reps-test.c Mon Dec 19 18:49:34 2011
@@ -360,7 +360,7 @@ verify_expected_record(svn_fs_t *fs,
size, expected_len);
/* Read the string back in 100-byte chunks. */
- text = svn_stringbuf_create("", trail->pool);
+ text = svn_stringbuf_create_empty(trail->pool);
while (1)
{
size = sizeof(buf);
Modified: subversion/branches/fs-py/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_repos/repos-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_repos/repos-test.c Mon Dec 19 18:49:34 2011
@@ -1348,6 +1348,149 @@ commit_authz_cb(svn_repos_authz_access_t
+enum action_t {
+ A_DELETE,
+ A_ADD_FILE,
+ A_ADD_DIR,
+ A_CHANGE_FILE_PROP
+};
+struct authz_path_action_t
+{
+ enum action_t action;
+ const char *path;
+ svn_boolean_t authz_error_expected;
+ const char *copyfrom_path;
+};
+
+/* Return the appropriate dir baton for the parent of PATH in *DIR_BATON,
+ allocated in POOL. */
+static svn_error_t *
+get_dir_baton(void **dir_baton,
+ const char *path,
+ const svn_delta_editor_t *editor,
+ void *root_baton,
+ apr_pool_t *pool)
+{
+ int i;
+ apr_array_header_t *path_bits = svn_path_decompose(path, pool);
+ const char *path_so_far = "";
+
+ *dir_baton = root_baton;
+ for (i = 0; i < (path_bits->nelts - 1); i++)
+ {
+ const char *path_bit = APR_ARRAY_IDX(path_bits, i, const char *);
+ path_so_far = svn_path_join(path_so_far, path_bit, pool);
+ SVN_ERR(editor->open_directory(path_so_far, *dir_baton,
+ SVN_INVALID_REVNUM, pool, dir_baton));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Return the appropriate file baton for PATH in *FILE_BATON, allocated in
+ POOL. */
+static svn_error_t *
+get_file_baton(void **file_baton,
+ const char *path,
+ const svn_delta_editor_t *editor,
+ void *root_baton,
+ apr_pool_t *pool)
+{
+ void *dir_baton;
+
+ SVN_ERR(get_dir_baton(&dir_baton, path, editor, root_baton, pool));
+
+ SVN_ERR(editor->open_file(path, dir_baton, SVN_INVALID_REVNUM, pool,
+ file_baton));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_path_authz(svn_repos_t *repos,
+ struct authz_path_action_t *path_action,
+ svn_authz_t *authz_file,
+ svn_revnum_t youngest_rev,
+ apr_pool_t *scratch_pool)
+{
+ void *edit_baton;
+ void *root_baton;
+ void *dir_baton;
+ void *file_baton;
+ void *out_baton;
+ const svn_delta_editor_t *editor;
+ svn_error_t *err;
+ svn_error_t *err2;
+
+ /* Create a new commit editor in which we're going to play with
+ authz */
+ SVN_ERR(svn_repos_get_commit_editor4(&editor, &edit_baton, repos,
+ NULL, "file://test", "/",
+ "plato", "test commit", NULL,
+ NULL, commit_authz_cb, authz_file,
+ scratch_pool));
+
+ /* Start fiddling. First get the root, which is readonly. */
+ SVN_ERR(editor->open_root(edit_baton, 1, scratch_pool, &root_baton));
+
+ /* Fetch the appropriate baton for our action. This may involve opening
+ intermediate batons, but we only care about the final one for the
+ cooresponding action. */
+ if (path_action->action == A_CHANGE_FILE_PROP)
+ SVN_ERR(get_file_baton(&file_baton, path_action->path, editor, root_baton,
+ scratch_pool));
+ else
+ SVN_ERR(get_dir_baton(&dir_baton, path_action->path, editor, root_baton,
+ scratch_pool));
+
+ /* Test the appropriate action. */
+ switch (path_action->action)
+ {
+ case A_DELETE:
+ err = editor->delete_entry(path_action->path, SVN_INVALID_REVNUM,
+ dir_baton, scratch_pool);
+ break;
+
+ case A_CHANGE_FILE_PROP:
+ err = editor->change_file_prop(file_baton, "svn:test",
+ svn_string_create("test", scratch_pool),
+ scratch_pool);
+ break;
+
+ case A_ADD_FILE:
+ err = editor->add_file(path_action->path, dir_baton,
+ path_action->copyfrom_path, youngest_rev,
+ scratch_pool, &out_baton);
+ break;
+
+ case A_ADD_DIR:
+ err = editor->add_directory(path_action->path, dir_baton,
+ path_action->copyfrom_path, youngest_rev,
+ scratch_pool, &out_baton);
+ break;
+ }
+
+ /* Don't worry about closing batons, just abort the edit. Since errors
+ may be delayed, we need to capture results of the abort as well. */
+ err2 = editor->abort_edit(edit_baton, scratch_pool);
+ if (!err)
+ err = err2;
+ else
+ svn_error_clear(err2);
+
+ /* Check for potential errors. */
+ if (path_action->authz_error_expected)
+ {
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_AUTHZ_UNWRITABLE);
+ svn_error_clear(err);
+ }
+ else
+ SVN_ERR(err);
+
+ return SVN_NO_ERROR;
+}
+
+
/* Test that the commit editor is taking authz into account
properly */
static svn_error_t *
@@ -1359,13 +1502,26 @@ commit_editor_authz(const svn_test_opts_
svn_fs_txn_t *txn;
svn_fs_root_t *txn_root;
svn_revnum_t youngest_rev;
- void *edit_baton;
- void *root_baton, *dir_baton, *dir2_baton, *file_baton;
- svn_error_t *err;
- const svn_delta_editor_t *editor;
svn_authz_t *authz_file;
- apr_pool_t *subpool = svn_pool_create(pool);
+ apr_pool_t *iterpool;
const char *authz_contents;
+ int i;
+ struct authz_path_action_t path_actions[] = {
+ { A_DELETE, "/iota", TRUE },
+ { A_CHANGE_FILE_PROP, "/iota", TRUE },
+ { A_ADD_FILE, "/alpha", TRUE },
+ { A_ADD_FILE, "/alpha", TRUE, "file://test/A/B/lambda" },
+ { A_ADD_DIR, "/I", TRUE },
+ { A_ADD_DIR, "/J", TRUE, "file://test/A/D" },
+ { A_ADD_FILE, "/A/alpha", TRUE },
+ { A_ADD_FILE, "/A/B/theta", FALSE },
+ { A_DELETE, "/A/mu", FALSE },
+ { A_ADD_DIR, "/A/E", FALSE },
+ { A_ADD_DIR, "/A/J", FALSE, "file://test/A/D" },
+ { A_DELETE, "A/D/G", TRUE },
+ { A_DELETE, "A/D/H", FALSE },
+ { A_CHANGE_FILE_PROP, "A/D/gamma", FALSE }
+ };
/* The Test Plan
*
@@ -1375,25 +1531,24 @@ commit_editor_authz(const svn_test_opts_
* authorized/denied when necessary. We don't try to be exhaustive
* in the kinds of authz lookups. We just make sure that the editor
* replies to the calls in a way that proves it is doing authz
- * lookups.
+ * lookups. Some actions are tested implicitly (such as open_file being
+ * required for change_file_props).
*
- * Note that this use of the commit editor is not kosher according
- * to the generic editor API (we aren't allowed to continue editing
- * after an error, nor are we allowed to assume that errors are
- * returned by the operations which caused them). But it should
- * work fine with this particular editor implementation.
+ * Note that because of the error handling requirements of the generic
+ * editor API, each operation needs its own editor, which is handled by
+ * a helper function above.
*/
/* Create a filesystem and repository. */
SVN_ERR(svn_test__create_repos(&repos, "test-repo-commit-authz",
- opts, subpool));
+ opts, pool));
fs = svn_repos_fs(repos);
/* Prepare a txn to receive the greek tree. */
- SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, subpool));
- SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
- SVN_ERR(svn_test__create_greek_tree(txn_root, subpool));
- SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, subpool));
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
/* Load the authz rules for the greek tree. */
@@ -1419,147 +1574,18 @@ commit_editor_authz(const svn_test_opts_
"[/A/D/G]" NL
"plato = r"; /* No newline at end of file. */
- SVN_ERR(authz_get_handle(&authz_file, authz_contents, subpool));
+ SVN_ERR(authz_get_handle(&authz_file, authz_contents, pool));
- /* Create a new commit editor in which we're going to play with
- authz */
- SVN_ERR(svn_repos_get_commit_editor4(&editor, &edit_baton, repos,
- NULL, "file://test", "/",
- "plato", "test commit", NULL,
- NULL, commit_authz_cb, authz_file,
- subpool));
-
- /* Start fiddling. First get the root, which is readonly. All
- write operations fail because of the root's permissions. */
- SVN_ERR(editor->open_root(edit_baton, 1, subpool, &root_baton));
-
- /* Test denied file deletion. */
- err = editor->delete_entry("/iota", SVN_INVALID_REVNUM, root_baton, subpool);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Test authorized file open. */
- SVN_ERR(editor->open_file("/iota", root_baton, SVN_INVALID_REVNUM,
- subpool, &file_baton));
-
- /* Test unauthorized file prop set. */
- err = editor->change_file_prop(file_baton, "svn:test",
- svn_string_create("test", subpool),
- subpool);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Test denied file addition. */
- err = editor->add_file("/alpha", root_baton, NULL, SVN_INVALID_REVNUM,
- subpool, &file_baton);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Test denied file copy. */
- err = editor->add_file("/alpha", root_baton, "file://test/A/B/lambda",
- youngest_rev, subpool, &file_baton);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Test denied directory addition. */
- err = editor->add_directory("/I", root_baton, NULL,
- SVN_INVALID_REVNUM, subpool, &dir_baton);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Test denied directory copy. */
- err = editor->add_directory("/J", root_baton, "file://test/A/D",
- youngest_rev, subpool, &dir_baton);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Open directory /A, to which we have read/write access. */
- SVN_ERR(editor->open_directory("/A", root_baton,
- SVN_INVALID_REVNUM,
- subpool, &dir_baton));
-
- /* Test denied file addition. Denied because of a conflicting rule
- on the file path itself. */
- err = editor->add_file("/A/alpha", dir_baton, NULL,
- SVN_INVALID_REVNUM, subpool, &file_baton);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Test authorized file addition. */
- SVN_ERR(editor->add_file("/A/B/theta", dir_baton, NULL,
- SVN_INVALID_REVNUM, subpool,
- &file_baton));
-
- /* Test authorized file deletion. */
- SVN_ERR(editor->delete_entry("/A/mu", SVN_INVALID_REVNUM, dir_baton,
- subpool));
-
- /* Test authorized directory creation. */
- SVN_ERR(editor->add_directory("/A/E", dir_baton, NULL,
- SVN_INVALID_REVNUM, subpool,
- &dir2_baton));
-
- /* Test authorized copy of a tree. */
- SVN_ERR(editor->add_directory("/A/J", dir_baton, "file://test/A/D",
- youngest_rev, subpool,
- &dir2_baton));
-
- /* Open /A/D. This should be granted. */
- SVN_ERR(editor->open_directory("/A/D", dir_baton, SVN_INVALID_REVNUM,
- subpool, &dir_baton));
-
- /* Test denied recursive deletion. */
- err = editor->delete_entry("/A/D/G", SVN_INVALID_REVNUM, dir_baton,
- subpool);
- if (err == SVN_NO_ERROR || err->apr_err != SVN_ERR_AUTHZ_UNWRITABLE)
- return svn_error_createf(SVN_ERR_TEST_FAILED, err,
- "Got %s error instead of expected "
- "SVN_ERR_AUTHZ_UNWRITABLE",
- err ? "unexpected" : "no");
- svn_error_clear(err);
-
- /* Test authorized recursive deletion. */
- SVN_ERR(editor->delete_entry("/A/D/H", SVN_INVALID_REVNUM,
- dir_baton, subpool));
-
- /* Test authorized propset (open the file first). */
- SVN_ERR(editor->open_file("/A/D/gamma", dir_baton, SVN_INVALID_REVNUM,
- subpool, &file_baton));
- SVN_ERR(editor->change_file_prop(file_baton, "svn:test",
- svn_string_create("test", subpool),
- subpool));
+ iterpool = svn_pool_create(pool);
+ for (i = 0; i < (sizeof(path_actions) / sizeof(struct authz_path_action_t));
+ i++)
+ {
+ svn_pool_clear(iterpool);
+ SVN_ERR(test_path_authz(repos, &path_actions[i], authz_file,
+ youngest_rev, iterpool));
+ }
- /* Done. */
- SVN_ERR(editor->abort_edit(edit_baton, subpool));
- svn_pool_destroy(subpool);
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
@@ -2495,6 +2521,45 @@ test_get_file_revs(const svn_test_opts_t
return SVN_NO_ERROR;
}
+static svn_error_t *
+issue_4060(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ apr_pool_t *subpool = svn_pool_create(pool);
+ svn_authz_t *authz_cfg;
+ svn_boolean_t allowed;
+ const char *authz_contents =
+ "[/A/B]" NL
+ "ozymandias = rw" NL
+ "[/]" NL
+ "ozymandias = r" NL
+ "" NL;
+
+ SVN_ERR(authz_get_handle(&authz_cfg, authz_contents, subpool));
+
+ SVN_ERR(svn_repos_authz_check_access(authz_cfg, "babylon",
+ "/A/B/C", "ozymandias",
+ svn_authz_write | svn_authz_recursive,
+ &allowed, subpool));
+ SVN_TEST_ASSERT(allowed);
+
+ SVN_ERR(svn_repos_authz_check_access(authz_cfg, "",
+ "/A/B/C", "ozymandias",
+ svn_authz_write | svn_authz_recursive,
+ &allowed, subpool));
+ SVN_TEST_ASSERT(allowed);
+
+ SVN_ERR(svn_repos_authz_check_access(authz_cfg, NULL,
+ "/A/B/C", "ozymandias",
+ svn_authz_write | svn_authz_recursive,
+ &allowed, subpool));
+ SVN_TEST_ASSERT(allowed);
+
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
@@ -2529,5 +2594,7 @@ struct svn_test_descriptor_t test_funcs[
"test svn_repos_get_logs ranges and limits"),
SVN_TEST_OPTS_PASS(test_get_file_revs,
"test svn_repos_get_file_revsN"),
+ SVN_TEST_OPTS_PASS(issue_4060,
+ "test issue 4060"),
SVN_TEST_NULL
};
Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/cache-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/cache-test.c Mon Dec 19 18:49:34 2011
@@ -135,7 +135,7 @@ test_inprocess_cache_basic(apr_pool_t *p
APR_HASH_KEY_STRING,
1,
1,
- APR_HAS_THREADS,
+ TRUE,
"",
pool));
@@ -182,16 +182,9 @@ test_membuffer_cache_basic(apr_pool_t *p
{
svn_cache__t *cache;
svn_membuffer_t *membuffer;
- svn_boolean_t thread_safe;
-
-#if APR_HAS_THREADS
- thread_safe = TRUE;
-#else
- thread_safe = FALSE;
-#endif
SVN_ERR(svn_cache__membuffer_cache_create(&membuffer, 10*1024, 1,
- thread_safe, pool));
+ TRUE, pool));
/* Create a cache with just one entry. */
SVN_ERR(svn_cache__create_membuffer_cache(&cache,
@@ -200,6 +193,7 @@ test_membuffer_cache_basic(apr_pool_t *p
deserialize_revnum,
APR_HASH_KEY_STRING,
"cache:",
+ FALSE,
pool));
return basic_cache_test(cache, FALSE, pool);
Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.c Mon Dec 19 18:49:34 2011
@@ -211,7 +211,7 @@ test_boolean_retrieval(apr_pool_t *pool)
}
static svn_error_t *
-test_has_section(apr_pool_t *pool)
+test_has_section_case_insensitive(apr_pool_t *pool)
{
svn_config_t *cfg;
const char *cfg_file;
@@ -225,12 +225,50 @@ test_has_section(apr_pool_t *pool)
if (! svn_config_has_section(cfg, "section1"))
return fail(pool, "Failed to find section1");
+ if (! svn_config_has_section(cfg, "SECTION1"))
+ return fail(pool, "Failed to find SECTION1");
+
+ if (! svn_config_has_section(cfg, "UpperCaseSection"))
+ return fail(pool, "Failed to find UpperCaseSection");
+
+ if (! svn_config_has_section(cfg, "uppercasesection"))
+ return fail(pool, "Failed to find UpperCaseSection");
+
if (svn_config_has_section(cfg, "notthere"))
return fail(pool, "Returned true on missing section");
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_has_section_case_sensitive(apr_pool_t *pool)
+{
+ svn_config_t *cfg;
+ const char *cfg_file;
+
+ if (!srcdir)
+ SVN_ERR(init_params(pool));
+
+ cfg_file = apr_pstrcat(pool, srcdir, "/", "config-test.cfg", (char *)NULL);
+ SVN_ERR(svn_config_read2(&cfg, cfg_file, TRUE, TRUE, pool));
+
+ if (! svn_config_has_section(cfg, "section1"))
+ return fail(pool, "Failed to find section1");
+
+ if (svn_config_has_section(cfg, "SECTION1"))
+ return fail(pool, "Returned true on missing section");
+
+ if (! svn_config_has_section(cfg, "UpperCaseSection"))
+ return fail(pool, "Failed to find UpperCaseSection");
+
+ if (svn_config_has_section(cfg, "uppercasesection"))
+ return fail(pool, "Returned true on missing section");
+
+ if (svn_config_has_section(cfg, "notthere"))
+ return fail(pool, "Returned true on missing section");
+
+ return SVN_NO_ERROR;
+}
/*
====================================================================
If you add a new test to this file, update this array.
@@ -246,7 +284,9 @@ struct svn_test_descriptor_t test_funcs[
"test svn_config"),
SVN_TEST_PASS2(test_boolean_retrieval,
"test svn_config boolean conversion"),
- SVN_TEST_PASS2(test_has_section,
- "test svn_config_has_section"),
+ SVN_TEST_PASS2(test_has_section_case_insensitive,
+ "test svn_config_has_section (case insensitive)"),
+ SVN_TEST_PASS2(test_has_section_case_sensitive,
+ "test svn_config_has_section (case sensitive)"),
SVN_TEST_NULL
};