You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2013/01/27 01:01:59 UTC
svn commit: r1438999 [6/7] - in /subversion/branches/windows-build-update:
./ build/generator/ subversion/include/ subversion/include/private/
subversion/libsvn_client/ subversion/libsvn_diff/
subversion/libsvn_ra_serf/ subversion/libsvn_repos/ subvers...
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/patch_tests.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/patch_tests.py Sun Jan 27 00:01:57 2013
@@ -34,6 +34,7 @@ import tempfile
import textwrap
import zlib
import posixpath
+import filecmp
# Our testing module
import svntest
@@ -4222,7 +4223,7 @@ def patch_change_symlink_target(sbox):
"@@ -1 +1 @@",
"-link foo",
"\\ No newline at end of file",
- "+link bar",
+ "+link bardame",
"\\ No newline at end of file",
"",
]))
@@ -4230,24 +4231,37 @@ def patch_change_symlink_target(sbox):
# r2 - Try as plain text with how we encode the symlink
svntest.main.file_write(sbox.ospath('link'), 'link foo')
sbox.simple_add('link')
- sbox.simple_commit()
- expected_output = [
+ expected_output = svntest.wc.State(wc_dir, {
+ 'link' : Item(verb='Adding'),
+ })
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ None, None, wc_dir)
+
+ patch_output = [
'U %s\n' % sbox.ospath('link'),
]
- svntest.actions.run_and_verify_svn(None, expected_output, [],
+ svntest.actions.run_and_verify_svn(None, patch_output, [],
'patch', patch_file_path, wc_dir)
# r3 - Store result
- sbox.simple_commit()
+ expected_output = svntest.wc.State(wc_dir, {
+ 'link' : Item(verb='Sending'),
+ })
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ None, None, wc_dir)
# r4 - Now as symlink
sbox.simple_rm('link')
sbox.simple_add_symlink('foo', 'link')
- sbox.simple_commit()
+ expected_output = svntest.wc.State(wc_dir, {
+ 'link' : Item(verb='Replacing'),
+ })
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ None, None, wc_dir)
- svntest.actions.run_and_verify_svn(None, expected_output, [],
+ svntest.actions.run_and_verify_svn(None, patch_output, [],
'patch', patch_file_path, wc_dir)
# TODO: when it passes, verify that the on-disk 'link' is correct ---
@@ -4395,6 +4409,174 @@ def single_line_mismatch(sbox):
svntest.actions.run_and_verify_svn(None, expected_output, [],
'patch', patch_file_path, wc_dir)
+@Issue(3644)
+def patch_empty_file(sbox):
+ "apply a patch to an empty file"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join([
+ # patch a file containing just '\n' to 'replacement\n'
+ "Index: lf.txt\n",
+ "===================================================================\n",
+ "--- lf.txt\t(revision 2)\n",
+ "+++ lf.txt\t(working copy)\n",
+ "@@ -1 +1 @@\n",
+ "\n"
+ "+replacement\n",
+
+ # patch a new file 'new.txt\n'
+ "Index: new.txt\n",
+ "===================================================================\n",
+ "--- new.txt\t(revision 0)\n",
+ "+++ new.txt\t(working copy)\n",
+ "@@ -0,0 +1 @@\n",
+ "+new file\n",
+
+ # patch a file containing 0 bytes to 'replacement\n'
+ "Index: empty.txt\n",
+ "===================================================================\n",
+ "--- empty.txt\t(revision 2)\n",
+ "+++ empty.txt\t(working copy)\n",
+ "@@ -0,0 +1 @@\n",
+ "+replacement\n",
+ ]))
+
+ sbox.simple_add_text('', 'empty.txt')
+ sbox.simple_add_text('\n', 'lf.txt')
+ sbox.simple_commit()
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('lf.txt'),
+ 'A %s\n' % sbox.ospath('new.txt'),
+ 'U %s\n' % sbox.ospath('empty.txt'),
+ # Not sure if this line is necessary, but it doesn't hurt
+ '> applied hunk @@ -0,0 +1,1 @@ with offset 0\n',
+ ]
+
+ # Current result: lf.txt patched ok, new created, empty succeeds with offset.
+ svntest.actions.run_and_verify_svn(None, expected_output, [],
+ 'patch', patch_file_path, wc_dir)
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({
+ 'lf.txt' : Item(contents="\n"),
+ 'new.txt' : Item(contents="new file\n"),
+ 'empty.txt' : Item(contents="replacement\n"),
+ })
+
+ svntest.actions.verify_disk(wc_dir, expected_disk)
+
+@Issue(3362)
+def patch_apply_no_fuz(sbox):
+ "svn diff created patch should apply without fuz"
+
+ sbox.build(read_only=True)
+ wc_dir = sbox.wc_dir
+
+ svntest.main.file_write(sbox.ospath('test.txt'), '\n'.join([
+ "line_1",
+ "line_2",
+ "line_3",
+ "line_4",
+ "line_5",
+ "line_6",
+ "line_7",
+ "line_8",
+ "line_9",
+ "line_10",
+ "line_11",
+ "line_12",
+ "line_13",
+ "line_14",
+ "line_15",
+ "line_16",
+ "line_17",
+ "line_18",
+ "line_19",
+ "line_20",
+ "line_21",
+ "line_22",
+ "line_23",
+ "line_24",
+ "line_25",
+ "line_26",
+ "line_27",
+ "line_28",
+ "line_29",
+ "line_30",
+ ""
+ ]))
+ svntest.main.file_write(sbox.ospath('test_v2.txt'), '\n'.join([
+ "line_1a",
+ "line_1b",
+ "line_1c",
+ "line_1",
+ "line_2",
+ "line_3",
+ "line_4",
+ "line_5a",
+ "line_5b",
+ "line_5c",
+ "line_6",
+ "line_7",
+ "line_8",
+ "line_9",
+ "line_10",
+ "line_11a",
+ "line_11b",
+ "line_11c",
+ "line_12",
+ "line_13",
+ "line_14",
+ "line_15",
+ "line_16",
+ "line_17",
+ "line_18",
+ "line_19a",
+ "line_19b",
+ "line_19c",
+ "line_20",
+ "line_21",
+ "line_22",
+ "line_23",
+ "line_24",
+ "line_25",
+ "line_26",
+ "line_27a",
+ "line_27b",
+ "line_27c",
+ "line_28",
+ "line_29",
+ "line_30",
+ ""
+ ]))
+
+ sbox.simple_add('test.txt', 'test_v2.txt')
+
+ result, out_text, err_text = svntest.main.run_svn(None,
+ 'diff',
+ '--old',
+ sbox.ospath('test.txt'),
+ '--new',
+ sbox.ospath('test_v2.txt'))
+
+ patch_path = sbox.ospath('patch.diff')
+ svntest.main.file_write(patch_path, ''.join(out_text))
+
+ expected_output = [
+ 'G %s\n' % sbox.ospath('test.txt'),
+ ]
+
+ # Current result: lf.txt patched ok, new created, empty succeeds with offset.
+ svntest.actions.run_and_verify_svn(None, expected_output, [],
+ 'patch', patch_path, wc_dir)
+
+ if not filecmp.cmp(sbox.ospath('test.txt'), sbox.ospath('test_v2.txt')):
+ raise svntest.Failure("Patch result not identical")
+
########################################################################
#Run the tests
@@ -4444,6 +4626,8 @@ test_list = [ None,
patch_change_symlink_target,
patch_replace_dir_with_file_and_vv,
single_line_mismatch,
+ patch_empty_file,
+ patch_apply_no_fuz,
]
if __name__ == '__main__':
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/svnadmin_tests.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/svnadmin_tests.py Sun Jan 27 00:01:57 2013
@@ -548,12 +548,22 @@ def verify_windows_paths_in_repos(sbox):
exit_code, output, errput = svntest.main.run_svnadmin("verify",
sbox.repo_dir)
- svntest.verify.compare_and_display_lines(
- "Error while running 'svnadmin verify'.",
- 'STDERR', ["* Verifying global structure ...\n",
- "* Verified revision 0.\n",
- "* Verified revision 1.\n",
- "* Verified revision 2.\n"], errput)
+
+ # unfortunately, FSFS needs to do more checks than BDB resulting in
+ # different progress output
+ if svntest.main.is_fs_type_fsfs():
+ svntest.verify.compare_and_display_lines(
+ "Error while running 'svnadmin verify'.",
+ 'STDERR', ["* Verifying global structure ...\n",
+ "* Verified revision 0.\n",
+ "* Verified revision 1.\n",
+ "* Verified revision 2.\n"], errput)
+ else:
+ svntest.verify.compare_and_display_lines(
+ "Error while running 'svnadmin verify'.",
+ 'STDERR', ["* Verified revision 0.\n",
+ "* Verified revision 1.\n",
+ "* Verified revision 2.\n"], errput)
#----------------------------------------------------------------------
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/actions.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/actions.py Sun Jan 27 00:01:57 2013
@@ -424,6 +424,22 @@ def expected_noop_update_output(rev):
% (rev),
"no-op update")
+def run_and_verify_svnauthz(message, expected_stdout, expected_stderr,
+ expected_exit, compat_mode, *varargs):
+ """Run svnauthz command and check its output and exit code.
+ If COMPAT_MODE is True then run the command in pre-1.8
+ compatibility mode"""
+
+ if compat_mode:
+ exit_code, out, err = main.run_svnauthz_validate(*varargs)
+ else:
+ exit_code, out, err = main.run_svnauthz(*varargs)
+
+ verify.verify_outputs("Unexpected output", out, err,
+ expected_stdout, expected_stderr)
+ verify.verify_exit_code(message, exit_code, expected_exit)
+ return exit_code, out, err
+
######################################################################
# Subversion Actions
#
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/main.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/main.py Sun Jan 27 00:01:57 2013
@@ -157,6 +157,15 @@ atomic_ra_revprop_change_binary = os.pat
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)
+######################################################################
+# The location of svnauthz binary, relative to the only scripts that
+# import this file right now (they live in ../).
+# Use --tools to overide these defaults.
+svnauthz_binary = os.path.abspath('../../../tools/server-side/svnauthz' + _exe)
+svnauthz_validate_binary = os.path.abspath(
+ '../../../tools/server-side/svnauthz-validate' + _exe
+)
+
# Location to the pristine repository, will be calculated from test_area_url
# when we know what the user specified for --url.
pristine_greek_repos_url = None
@@ -703,6 +712,16 @@ def run_svnmucc(*varargs):
return run_command(svnmucc_binary, 1, True,
*(_with_auth(_with_config_dir(varargs))))
+def run_svnauthz(*varargs):
+ """Run svnauthz with VARARGS, returns exit code as int; stdout, stderr
+ as list of lines (including line terminators)."""
+ return run_command(svnauthz_binary, 1, False, *varargs)
+
+def run_svnauthz_validate(*varargs):
+ """Run svnauthz-validate with VARARGS, returns exit code as int; stdout,
+ stderr as list of lines (including line terminators)."""
+ return run_command(svnauthz_validate_binary, 1, False, *varargs)
+
def run_entriesdump(path):
"""Run the entries-dump helper, returning a dict of Entry objects."""
# use spawn_process rather than run_command to avoid copying all the data
@@ -727,6 +746,23 @@ def run_entriesdump_subdirs(path):
0, False, None, '--subdirs', path)
return map(lambda line: line.strip(), filter_dbg(stdout_lines))
+def run_entriesdump_tree(path):
+ """Run the entries-dump helper, returning a dict of a dict of Entry objects."""
+ # use spawn_process rather than run_command to avoid copying all the data
+ # to stdout in verbose mode.
+ exit_code, stdout_lines, stderr_lines = spawn_process(entriesdump_binary,
+ 0, False, None,
+ '--tree-dump', path)
+ if exit_code or stderr_lines:
+ ### report on this? or continue to just skip it?
+ return None
+
+ class Entry(object):
+ pass
+ dirs = { }
+ exec(''.join(filter_dbg(stdout_lines)))
+ return dirs
+
def run_atomic_ra_revprop_change(url, revision, propname, skel, want_error):
"""Run the atomic-ra-revprop-change helper, returning its exit code, stdout,
and stderr. For HTTP, default HTTP library is used."""
@@ -1029,6 +1065,19 @@ def write_restrictive_svnserve_conf(repo
fp.write("password-db = passwd\n")
fp.close()
+def write_restrictive_svnserve_conf_with_groups(repo_dir,
+ anon_access="none"):
+ "Create a restrictive configuration with groups stored in a separate file."
+
+ fp = open(get_svnserve_conf_file_path(repo_dir), 'w')
+ fp.write("[general]\nanon-access = %s\nauth-access = write\n"
+ "authz-db = authz\ngroups-db = groups\n" % anon_access)
+ if options.enable_sasl:
+ fp.write("realm = svntest\n[sasl]\nuse-sasl = true\n");
+ else:
+ fp.write("password-db = passwd\n")
+ fp.close()
+
# Warning: because mod_dav_svn uses one shared authz file for all
# repositories, you *cannot* use write_authz_file in any test that
# might be run in parallel.
@@ -1064,6 +1113,18 @@ an appropriate list of mappings.
fp.write("[%s%s]\n%s\n" % (prefix, p, r))
fp.close()
+# See the warning about parallel test execution in write_authz_file
+# method description.
+def write_groups_file(sbox, groups):
+ """Write a groups file to SBOX, appropriate for the RA method used,
+with group contents set to GROUPS."""
+ fp = open(sbox.groups_file, 'w')
+ fp.write("[groups]\n")
+ if groups:
+ for p, r in groups.items():
+ fp.write("%s = %s\n" % (p, r))
+ fp.close()
+
def use_editor(func):
os.environ['SVN_EDITOR'] = svneditor_script
os.environ['SVN_MERGE'] = svneditor_script
@@ -1643,6 +1704,8 @@ def _create_parser():
help='Path to SSL server certificate.')
parser.add_option('--http-proxy', action='store',
help='Use the HTTP Proxy at hostname:port.')
+ parser.add_option('--tools-bin', action='store', dest='tools_bin',
+ help='Use the svn tools installed in this path')
# most of the defaults are None, but some are other values, set them here
parser.set_defaults(
@@ -1783,6 +1846,8 @@ def execute_tests(test_list, serial_only
global svndumpfilter_binary
global svnversion_binary
global svnmucc_binary
+ global svnauthz_binary
+ global svnauthz_validate_binary
global options
if test_name:
@@ -1900,6 +1965,11 @@ def execute_tests(test_list, serial_only
svnversion_binary = os.path.join(options.svn_bin, 'svnversion' + _exe)
svnmucc_binary = os.path.join(options.svn_bin, 'svnmucc' + _exe)
+ if options.tools_bin:
+ svnauthz_binary = os.path.join(options.tools_bin, 'svnauthz' + _exe)
+ svnauthz_validate_binary = os.path.join(options.tools_bin,
+ 'svnauthz-validate' + _exe)
+
######################################################################
# Cleanup: if a previous run crashed or interrupted the python
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/sandbox.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/sandbox.py Sun Jan 27 00:01:57 2013
@@ -78,12 +78,14 @@ class Sandbox:
tmp_authz_file = os.path.join(svntest.main.work_dir, "authz-" + self.name)
open(tmp_authz_file, 'w').write("[/]\n* = rw\n")
shutil.move(tmp_authz_file, self.authz_file)
+ self.groups_file = os.path.join(svntest.main.work_dir, "groups")
# For svnserve tests we have a per-repository authz file, and it
# doesn't need to be there in order for things to work, so we don't
# have any default contents.
elif self.repo_url.startswith("svn"):
self.authz_file = os.path.join(self.repo_dir, "conf", "authz")
+ self.groups_file = os.path.join(self.repo_dir, "conf", "groups")
def clone_dependent(self, copy_wc=False):
"""A convenience method for creating a near-duplicate of this
@@ -231,8 +233,8 @@ class Sandbox:
target = self.ospath(target)
if message is None:
message = svntest.main.make_log_msg()
- svntest.main.run_svn(False, 'commit', '-m', message,
- target)
+ svntest.actions.run_and_verify_commit(self.wc_dir, None, None, [],
+ '-m', message, target)
def simple_rm(self, *targets):
"""Schedule TARGETS for deletion.
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/verify.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/verify.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/verify.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/verify.py Sun Jan 27 00:01:57 2013
@@ -215,6 +215,7 @@ class ExpectedOutput:
class AnyOutput(ExpectedOutput):
+ """Matches any non-empty output."""
def __init__(self):
ExpectedOutput.__init__(self, None, False)
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/wc.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/svntest/wc.py Sun Jan 27 00:01:57 2013
@@ -337,7 +337,8 @@ class State:
if item.status:
# If this is an unversioned tree-conflict, remove it.
# These are only in their parents' THIS_DIR, they don't have entries.
- if item.status[0] in '!?' and item.treeconflict == 'C':
+ if item.status[0] in '!?' and item.treeconflict == 'C' and \
+ item.entry_status is None:
del self.desc[path]
# Normal externals are not stored in the parent wc, drop the root
# and everything in these working copies
@@ -663,21 +664,14 @@ class State:
desc = { }
dot_svn = svntest.main.get_admin_name()
- for dirpath in svntest.main.run_entriesdump_subdirs(base):
+ dump_data = svntest.main.run_entriesdump_tree(base)
- if base == '.' and dirpath != '.':
- dirpath = '.' + os.path.sep + dirpath
+ if not dump_data:
+ # Probably 'svn status' run on an actual only node
+ # ### Improve!
+ return cls('', desc)
- entries = svntest.main.run_entriesdump(dirpath)
- if entries is None:
- continue
-
- if dirpath == '.':
- parent = ''
- elif dirpath.startswith('.' + os.sep):
- parent = to_relpath(dirpath[2:])
- else:
- parent = to_relpath(dirpath)
+ for parent, entries in sorted(dump_data.items()):
parent_url = entries[''].url
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/switch_tests.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/switch_tests.py Sun Jan 27 00:01:57 2013
@@ -2906,6 +2906,33 @@ def different_node_kind(sbox):
switch_to_file(sbox, 'iota', 'A/C')
switch_to_file(sbox, 'A/D/gamma', 'A/D/G')
+@Issue(3332, 3333)
+def switch_to_spaces(sbox):
+ "switch to a directory with spaces in its name"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ repo_url = sbox.repo_url
+
+ # Paths are normalized in the command processing, so %20 is equivalent to ' '
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'cp', repo_url + '/A',
+ repo_url + '/A%20with space',
+ '-m', '')
+
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'mv', repo_url + '/A%20with space',
+ repo_url + '/A with%20more spaces',
+ '-m', '')
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+ expected_status.tweak('A', switched='S')
+ expected_status.tweak('', 'iota', wc_rev=1)
+
+ svntest.actions.run_and_verify_switch(sbox.wc_dir, sbox.ospath('A'),
+ repo_url + '/A%20with more%20spaces',
+ None, None, expected_status)
+
########################################################################
# Run the tests
@@ -2946,6 +2973,7 @@ test_list = [ None,
copy_with_switched_subdir,
up_to_old_rev_with_subtree_switched_to_root,
different_node_kind,
+ switch_to_spaces,
]
if __name__ == '__main__':
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/update_tests.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/update_tests.py Sun Jan 27 00:01:57 2013
@@ -3943,6 +3943,11 @@ def update_accept_conflicts(sbox):
# WC update editor flush and run incomplete logs and lead to WC
# corruption, detectable by another update command.
+# FIXME: With issue #4280 fixed and this test using --force-interactive,
+# the test driver can no longer redirect terminal input to cause
+# an EOF. Consequently, skip this test so that it does not hang
+# the test suite.
+@Skip()
def eof_in_interactive_conflict_resolver(sbox):
"eof in interactive resolution can't break wc"
@@ -3995,11 +4000,11 @@ interactive-conflicts = true
# Modify iota differently and try to update *with the interactive
# resolver*. ### The parser won't go so well with the output
svntest.main.file_append(iota_path, "Local mods to r1 text.\n")
- svntest.actions.run_and_verify_update(wc_dir, None, None, None,
- "Can't read stdin: End of file found",
- None, None, None, None, 1,
- wc_dir, '--force-interactive',
- '--config-dir', config_dir)
+ svntest.actions.run_and_verify_update(
+ wc_dir, None, None, None,
+ "End of file while reading from terminal",
+ None, None, None, None, 1,
+ wc_dir, '--force-interactive', '--config-dir', config_dir)
# Now update -r1 again. Hopefully we don't get a checksum error!
expected_output = svntest.wc.State(wc_dir, {
@@ -5464,14 +5469,13 @@ def update_moved_dir_leaf_del(sbox):
None, None, 1)
# Now resolve the conflict, using --accept=mine-conflict applying
- # the update to A/B/E2 causing a delete-delete conflict
+ # the update to A/B/E2
svntest.actions.run_and_verify_svn("resolve failed", None, [],
'resolve',
'--accept=mine-conflict',
sbox.ospath('A/B/E'))
expected_status.tweak('A/B/E', treeconflict=None)
- expected_status.tweak('A/B/E2/alpha', status='? ', treeconflict='C',
- copied=None, wc_rev=None)
+ expected_status.remove('A/B/E2/alpha')
svntest.actions.run_and_verify_status(wc_dir, expected_status)
@XFail()
@@ -5699,15 +5703,14 @@ def update_moved_dir_file_move(sbox):
# The incoming change is a delete as we don't yet track server-side
# moves. Resolving the tree-conflict as "mine-conflict" applies the
- # delete to the move destination creating a delete-delete conflict.
+ # delete to the move destination.
svntest.actions.run_and_verify_svn("resolve failed", None, [],
'resolve',
'--accept=mine-conflict',
sbox.ospath('A/B/E'))
expected_status.tweak('A/B/E', treeconflict=None)
- expected_status.tweak('A/B/E2/alpha', status='? ', treeconflict='C',
- copied=None, wc_rev=None)
+ expected_status.remove('A/B/E2/alpha')
svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -6358,6 +6361,71 @@ def incomplete_overcomplete(sbox):
True,
wc_dir, '-r', 3)
+@Issue(4300)
+def update_swapped_depth_dirs(sbox):
+ "text mod to file in swapped depth dir"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ svntest.main.file_append(sbox.ospath('A/B/E/alpha'), "modified\n")
+ sbox.simple_commit()
+ sbox.simple_update(revision=1)
+
+ sbox.simple_move("A/B/E", "A/E")
+ sbox.simple_move("A/B", "A/E/B")
+ # This is almost certainly not the right status but it's what
+ # is currently being output so we're using it here so we
+ # can get to the deeper problem.
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak("A/B", "A/B/lambda", "A/B/F", "A/B/E",
+ "A/B/E/alpha", "A/B/E/beta", status="D ")
+ expected_status.tweak("A/B", moved_to="A/E/B")
+ expected_status.add({
+ 'A/E' : Item(status='A ', copied='+', wc_rev='-',
+ moved_from='A/E/B/E'),
+ 'A/E/B' : Item(status='A ', copied='+', wc_rev='-',
+ moved_from='A/B'),
+ 'A/E/B/E' : Item(status='D ', copied='+', wc_rev='-',
+ moved_to='A/E'),
+ 'A/E/B/F' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/E/B/lambda' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/E/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/E/B/E/alpha': Item(status='D ', copied='+', wc_rev='-'),
+ 'A/E/B/E/beta' : Item(status='D ', copied='+', wc_rev='-'),
+ })
+
+ svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/B' : Item(status=' ', treeconflict='C'),
+ 'A/B/E' : Item(status=' ', treeconflict='U'),
+ 'A/B/E/alpha' : Item(status=' ', treeconflict='U'),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B', 'A/B/lambda', 'A/B/F', 'A/B/E',
+ 'A/B/E/alpha', 'A/B/E/beta')
+ expected_disk.add({
+ 'A/E' : Item(),
+ 'A/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'A/E/beta' : Item(contents="This is the file 'beta'.\n"),
+ 'A/E/B' : Item(),
+ 'A/E/B/lambda' : Item(contents="This is the file 'lambda'.\n"),
+ 'A/E/B/F' : Item(),
+ })
+ expected_status.tweak(wc_rev=2)
+ expected_status.tweak('A/B', treeconflict='C')
+ expected_status.tweak('A/E', 'A/E/alpha', 'A/E/beta', 'A/E/B',
+ 'A/E/B/E', 'A/E/B/E/alpha', 'A/E/B/E/beta',
+ 'A/E/B/lambda', 'A/E/B/F', wc_rev='-')
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
#######################################################################
@@ -6440,6 +6508,7 @@ test_list = [ None,
break_moved_replaced_dir,
update_removes_switched,
incomplete_overcomplete,
+ update_swapped_depth_dirs,
]
if __name__ == '__main__':
Modified: subversion/branches/windows-build-update/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/cmdline/upgrade_tests.py?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/windows-build-update/subversion/tests/cmdline/upgrade_tests.py Sun Jan 27 00:01:57 2013
@@ -1206,7 +1206,7 @@ def upgrade_file_externals(sbox):
@Issue(4035)
-@XFail()
+@Wimp('Fails in maintainer mode')
def upgrade_missing_replaced(sbox):
"upgrade with missing replaced dir"
@@ -1221,12 +1221,14 @@ def upgrade_missing_replaced(sbox):
sbox.wc_dir)
expected_output = svntest.wc.State(sbox.wc_dir, {
- 'A/B/E' : Item(status=' ', treeconflict='C', prev_verb='Restored'),
+ 'A/B/E' : Item(status=' ', treeconflict='C',
+ prev_verb='Restored'),
'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', status='! ', treeconflict='C', wc_rev='-',
+ entry_status='R ', entry_rev='1')
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)
Modified: subversion/branches/windows-build-update/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/libsvn_client/client-test.c?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/windows-build-update/subversion/tests/libsvn_client/client-test.c Sun Jan 27 00:01:57 2013
@@ -721,6 +721,53 @@ test_youngest_common_ancestor(const svn_
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_foreign_repos_copy(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_opt_revision_t rev;
+ svn_opt_revision_t peg_rev;
+ const char *repos_url;
+ const char *repos2_url;
+ const char *wc_path;
+ svn_client_ctx_t *ctx;
+/* Create a filesytem and repository containing the Greek tree. */
+ SVN_ERR(create_greek_repos(&repos_url, "foreign-copy1", opts, pool));
+ SVN_ERR(create_greek_repos(&repos2_url, "foreign-copy2", opts, pool));
+
+ SVN_ERR(svn_dirent_get_absolute(&wc_path, "test-wc-add", pool));
+
+ wc_path = svn_dirent_join(wc_path, "foreign-wc", pool);
+
+ /* Remove old test data from the previous run */
+ SVN_ERR(svn_io_remove_dir2(wc_path, TRUE, NULL, NULL, pool));
+
+ SVN_ERR(svn_io_make_dir_recursively(wc_path, pool));
+ svn_test_add_dir_cleanup(wc_path);
+
+ rev.kind = svn_opt_revision_head;
+ peg_rev.kind = svn_opt_revision_unspecified;
+ SVN_ERR(svn_client_create_context(&ctx, pool));
+ /* Checkout greek tree as wc_path */
+ SVN_ERR(svn_client_checkout3(NULL, repos_url, wc_path, &peg_rev, &rev,
+ svn_depth_infinity, FALSE, FALSE, ctx, pool));
+
+ SVN_ERR(svn_client__copy_foreign(svn_path_url_add_component2(repos2_url, "A",
+ pool),
+ svn_dirent_join(wc_path, "A-copied", pool),
+ &peg_rev, &rev, svn_depth_infinity, FALSE, FALSE,
+ ctx, pool));
+
+
+ SVN_ERR(svn_client__copy_foreign(svn_path_url_add_component2(repos2_url,
+ "iota",
+ pool),
+ svn_dirent_join(wc_path, "iota-copied", pool),
+ &peg_rev, &rev, svn_depth_infinity, FALSE, FALSE,
+ ctx, pool));
+
+ return SVN_NO_ERROR;
+}
/* ========================================================================== */
@@ -738,5 +785,6 @@ struct svn_test_descriptor_t test_funcs[
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_OPTS_PASS(test_foreign_repos_copy, "test foreign repository copy"),
SVN_TEST_NULL
};
Modified: subversion/branches/windows-build-update/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/windows-build-update/subversion/tests/libsvn_diff/diff-diff3-test.c Sun Jan 27 00:01:57 2013
@@ -76,16 +76,14 @@ make_random_file(const char *filename,
apr_pool_t *pool)
{
apr_file_t *file;
- apr_status_t status;
int num_lines;
num_lines = range_rand(min_lines, max_lines);
- status = apr_file_open(&file, filename,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", filename);
+ SVN_ERR(svn_io_file_open(&file, filename,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT,
+ pool));
while (num_lines--)
{
@@ -100,9 +98,7 @@ make_random_file(const char *filename,
apr_file_printf(file, "line %d line %d line %d", x, x, x);
}
- status = apr_file_close(file);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", filename);
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -117,19 +113,15 @@ make_file(const char *filename,
apr_file_t *file;
apr_status_t status;
- status = apr_file_open(&file, filename,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", filename);
+ SVN_ERR(svn_io_file_open(&file, filename,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
status = apr_file_write_full(file, contents, strlen(contents), NULL);
if (status)
return svn_error_createf(status, NULL, "failed to write '%s'", filename);
- status = apr_file_close(file);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", filename);
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -159,7 +151,6 @@ three_way_merge(const char *filename1,
svn_diff_t *diff;
apr_file_t *output;
svn_stream_t *ostream;
- apr_status_t status;
svn_stringbuf_t *actual;
char *merge_name = apr_psprintf(pool, "merge-%s-%s-%s",
filename1, filename2, filename3);
@@ -199,34 +190,29 @@ three_way_merge(const char *filename1,
SVN_ERR(svn_diff_file_diff3_2(&diff, filename1, filename2, filename3,
options, pool));
- status = apr_file_open(&output, merge_name,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", merge_name);
+ SVN_ERR(svn_io_file_open(&output, merge_name,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
- ostream = svn_stream_from_aprfile(output, pool);
+ ostream = svn_stream_from_aprfile2(output, FALSE, pool);
SVN_ERR(svn_diff_file_output_merge2(ostream, diff,
filename1, filename2, filename3,
NULL, NULL, NULL, NULL,
style,
pool));
SVN_ERR(svn_stream_close(ostream));
- status = apr_file_close(output);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", merge_name);
- SVN_ERR(svn_stringbuf_from_file(&actual, merge_name, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&actual, merge_name, pool));
if (strcmp(actual->data, expected))
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
"failed merging diff '%s' to '%s' into '%s'",
filename1, filename2, filename3);
- SVN_ERR(svn_io_remove_file(filename1, pool));
+ SVN_ERR(svn_io_remove_file2(filename1, TRUE, pool));
if (strcmp(filename1, filename2))
- SVN_ERR(svn_io_remove_file(filename2, pool));
+ SVN_ERR(svn_io_remove_file2(filename2, TRUE, pool));
if (strcmp(filename1, filename3) && strcmp(filename2, filename3))
- SVN_ERR(svn_io_remove_file(filename3, pool));
- SVN_ERR(svn_io_remove_file(merge_name, pool));
+ SVN_ERR(svn_io_remove_file2(filename3, TRUE, pool));
+ SVN_ERR(svn_io_remove_file2(merge_name, TRUE, pool));
return SVN_NO_ERROR;
}
@@ -252,7 +238,6 @@ two_way_diff(const char *filename1,
svn_diff_t *diff;
apr_file_t *output;
svn_stream_t *ostream;
- apr_status_t status;
svn_stringbuf_t *actual;
char *diff_name = apr_psprintf(pool, "diff-%s-%s", filename1, filename2);
@@ -285,27 +270,42 @@ two_way_diff(const char *filename1,
/* Check that two-way diff between contents1 and contents2 produces
expected output. */
SVN_ERR(svn_diff_file_diff_2(&diff, filename1, filename2, options, pool));
- status = apr_file_open(&output, diff_name,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", diff_name);
- ostream = svn_stream_from_aprfile(output, pool);
+ SVN_ERR(svn_io_file_open(&output, diff_name,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
+
+ ostream = svn_stream_from_aprfile2(output, FALSE, pool);
SVN_ERR(svn_diff_file_output_unified2(ostream, diff,
filename1, filename2,
filename1, filename2,
SVN_APR_LOCALE_CHARSET, pool));
SVN_ERR(svn_stream_close(ostream));
- status = apr_file_close(output);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", diff_name);
- SVN_ERR(svn_stringbuf_from_file(&actual, diff_name, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&actual, diff_name, pool));
if (strcmp(actual->data, expected))
- return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
- "failed comparing '%s' and '%s'",
- filename1, filename2);
+ {
+ /*svn_stringbuf_t *dump_actual;
+ svn_stream_t *dump_ostream;
+ dump_actual = svn_stringbuf_create_empty(pool);
+ dump_ostream = svn_stream_from_stringbuf(dump_actual, pool);
+
+ SVN_ERR(svn_diff_mem_string_output_unified(dump_ostream, diff,
+ "expected", "actual",
+ SVN_APR_LOCALE_CHARSET,
+ svn_string_create(expected, pool),
+ svn_string_create(actual->data, pool),
+ pool));
+ SVN_ERR(svn_stream_close(ostream));
+
+ SVN_DBG(("%s\n", dump_actual->data));
+
+ SVN_ERR(make_file("memory", expected, pool));*/
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "failed comparing '%s' and '%s'"
+ " (memory and file results are different)",
+ filename1, filename2);
+ }
/* May as well do the trivial merges while we are here */
SVN_ERR(three_way_merge(filename1, filename2, filename1,
@@ -317,7 +317,7 @@ two_way_diff(const char *filename1,
svn_diff_conflict_display_modified_latest,
pool));
- SVN_ERR(svn_io_remove_file(diff_name, pool));
+ SVN_ERR(svn_io_remove_file2(diff_name, TRUE, pool));
return SVN_NO_ERROR;
}
@@ -373,14 +373,11 @@ make_random_merge_file(const char *filen
apr_pool_t *pool)
{
apr_file_t *file;
- apr_status_t status;
int i;
- status = apr_file_open(&file, filename,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", filename);
+ SVN_ERR(svn_io_file_open(&file, filename,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
for (i = 0; i < num_lines; ++i)
{
@@ -413,9 +410,7 @@ make_random_merge_file(const char *filen
}
}
- status = apr_file_close(file);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", filename);
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -2193,8 +2188,8 @@ random_trivial_merge(apr_pool_t *pool)
min_lines, max_lines, var_lines, block_lines,
i % 2, subpool));
- SVN_ERR(svn_stringbuf_from_file(&contents1, filename1, subpool));
- SVN_ERR(svn_stringbuf_from_file(&contents2, filename2, subpool));
+ SVN_ERR(svn_stringbuf_from_file2(&contents1, filename1, subpool));
+ SVN_ERR(svn_stringbuf_from_file2(&contents2, filename2, subpool));
SVN_ERR(three_way_merge(filename1, filename2, filename1,
contents1->data, contents2->data,
@@ -2262,10 +2257,10 @@ random_three_way_merge(apr_pool_t *pool)
SVN_ERR(make_random_merge_file(filename4, num_lines, mrg_lines,
num_src + num_dst, pool));
- SVN_ERR(svn_stringbuf_from_file(&original, filename1, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified1, filename2, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified2, filename3, pool));
- SVN_ERR(svn_stringbuf_from_file(&combined, filename4, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&original, filename1, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified1, filename2, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified2, filename3, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&combined, filename4, pool));
SVN_ERR(three_way_merge(filename1, filename2, filename3,
original->data, modified1->data,
@@ -2278,7 +2273,7 @@ random_three_way_merge(apr_pool_t *pool)
svn_diff_conflict_display_modified_latest,
subpool));
- SVN_ERR(svn_io_remove_file(filename4, pool));
+ SVN_ERR(svn_io_remove_file2(filename4, TRUE, pool));
svn_pool_clear(subpool);
}
@@ -2335,10 +2330,10 @@ merge_with_part_already_present(apr_pool
SVN_ERR(make_random_merge_file(filename4, num_lines, mrg_lines,
num_src + num_dst / 2, pool));
- SVN_ERR(svn_stringbuf_from_file(&original, filename1, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified1, filename2, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified2, filename3, pool));
- SVN_ERR(svn_stringbuf_from_file(&combined, filename4, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&original, filename1, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified1, filename2, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified2, filename3, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&combined, filename4, pool));
SVN_ERR(three_way_merge(filename1, filename2, filename3,
original->data, modified1->data,
@@ -2351,7 +2346,7 @@ merge_with_part_already_present(apr_pool
svn_diff_conflict_display_modified_latest,
subpool));
- SVN_ERR(svn_io_remove_file(filename4, pool));
+ SVN_ERR(svn_io_remove_file2(filename4, TRUE, pool));
svn_pool_clear(subpool);
}
@@ -2617,6 +2612,265 @@ test_token_compare(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+two_way_issue_3362_v1(apr_pool_t *pool)
+{
+ svn_diff_file_options_t *diff_opts = svn_diff_file_options_create(pool);
+
+ SVN_ERR(two_way_diff("issue-3362-1-v1",
+ "issue-3362-2-v1",
+ /* File 1 */
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5\n"
+ "line_6\n"
+ "line_7\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27\n"
+ "line_28\n"
+ "line_29\n"
+ "line_30\n",
+ /* File 2 */
+ "line_1a\n"
+ "line_2a\n"
+ "line_3a\n"
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5a\n"
+ "line_6b\n"
+ "line_7c\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11a\n"
+ "line_11b\n"
+ "line_11c\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19a\n"
+ "line_19b\n"
+ "line_19c\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27\n"
+ "line_27a\n",
+ /* Expected */
+ "--- issue-3362-1-v1" APR_EOL_STR
+ "+++ issue-3362-2-v1" APR_EOL_STR
+ "@@ -1,14 +1,19 @@" APR_EOL_STR
+ "+line_1a\n"
+ "+line_2a\n"
+ "+line_3a\n"
+ " line_1\n" /* 1.7 mem diff: line missing */
+ " line_2\n"
+ " line_3\n"
+ " line_4\n"
+ "-line_5\n"
+ "-line_6\n"
+ "-line_7\n"
+ "+line_5a\n"
+ "+line_6b\n"
+ "+line_7c\n"
+ " line_8\n"
+ " line_9\n"
+ " line_10\n"
+ "-line_11\n"
+ "+line_11a\n"
+ "+line_11b\n"
+ "+line_11c\n"
+ " line_12\n"
+ " line_13\n"
+ " line_14\n" /* 1.7 mem diff: line missing */
+ "@@ -16,7 +21,9 @@" APR_EOL_STR
+ " line_16\n"
+ " line_17\n"
+ " line_18\n"
+ "-line_19\n"
+ "+line_19a\n"
+ "+line_19b\n"
+ "+line_19c\n"
+ " line_20\n"
+ " line_21\n"
+ " line_22\n"
+ "@@ -25,6 +32,4 @@" APR_EOL_STR
+ " line_25\n"
+ " line_26\n"
+ " line_27\n"
+ "-line_28\n"
+ "-line_29\n"
+ "-line_30\n"
+ "+line_27a\n",
+ diff_opts, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+two_way_issue_3362_v2(apr_pool_t *pool)
+{
+ svn_diff_file_options_t *diff_opts = svn_diff_file_options_create(pool);
+
+ SVN_ERR(two_way_diff("issue-3362-1-v2",
+ "issue-3362-2-v2",
+ /* File 1 */
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5\n"
+ "line_6\n"
+ "line_7\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27\n"
+ "line_28\n"
+ "line_29\n"
+ "line_30\n",
+ /* File 2 */
+ "line_1a\n"
+ "line_1b\n"
+ "line_1c\n"
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5a\n"
+ "line_5b\n"
+ "line_5c\n"
+ "line_6\n"
+ "line_7\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11a\n"
+ "line_11b\n"
+ "line_11c\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19a\n"
+ "line_19b\n"
+ "line_19c\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27a\n"
+ "line_27b\n"
+ "line_27c\n"
+ "line_28\n"
+ "line_29\n"
+ "line_30\n",
+ /* Expected */
+ "--- issue-3362-1-v2" APR_EOL_STR
+ "+++ issue-3362-2-v2" APR_EOL_STR
+ "@@ -1,14 +1,21 @@" APR_EOL_STR
+ "+line_1a\n"
+ "+line_1b\n"
+ "+line_1c\n"
+ " line_1\n" /* 1.7 mem diff: line missing */
+ " line_2\n"
+ " line_3\n"
+ " line_4\n"
+ "-line_5\n"
+ "+line_5a\n"
+ "+line_5b\n"
+ "+line_5c\n"
+ " line_6\n"
+ " line_7\n"
+ " line_8\n"
+ " line_9\n"
+ " line_10\n"
+ "-line_11\n"
+ "+line_11a\n"
+ "+line_11b\n"
+ "+line_11c\n"
+ " line_12\n"
+ " line_13\n"
+ " line_14\n" /* 1.7 mem diff: line missing */
+ "@@ -16,7 +23,9 @@" APR_EOL_STR
+ " line_16\n"
+ " line_17\n"
+ " line_18\n"
+ "-line_19\n"
+ "+line_19a\n"
+ "+line_19b\n"
+ "+line_19c\n"
+ " line_20\n"
+ " line_21\n"
+ " line_22\n"
+ "@@ -24,7 +33,9 @@" APR_EOL_STR
+ " line_24\n"
+ " line_25\n"
+ " line_26\n"
+ "-line_27\n"
+ "+line_27a\n"
+ "+line_27b\n"
+ "+line_27c\n"
+ " line_28\n"
+ " line_29\n"
+ " line_30\n",
+ diff_opts, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ========================================================================== */
struct svn_test_descriptor_t test_funcs[] =
@@ -2652,5 +2906,9 @@ struct svn_test_descriptor_t test_funcs[
"identical suffix starts at the boundary of a chunk"),
SVN_TEST_PASS2(test_token_compare,
"compare tokes at the chunk boundary"),
+ SVN_TEST_PASS2(two_way_issue_3362_v1,
+ "2-way issue #3362 test v1"),
+ SVN_TEST_PASS2(two_way_issue_3362_v2,
+ "2-way issue #3362 test v2"),
SVN_TEST_NULL
};
Modified: subversion/branches/windows-build-update/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/windows-build-update/subversion/tests/libsvn_repos/repos-test.c?rev=1438999&r1=1438998&r2=1438999&view=diff
==============================================================================
--- subversion/branches/windows-build-update/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/windows-build-update/subversion/tests/libsvn_repos/repos-test.c Sun Jan 27 00:01:57 2013
@@ -1157,7 +1157,7 @@ authz_get_handle(svn_authz_t **authz_p,
SVN_ERR_W(svn_stream_puts(stream, authz_contents),
"Writing authz contents to stream");
- SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, pool),
+ SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, NULL, pool),
"Parsing the authz contents");
SVN_ERR_W(svn_stream_close(stream),
@@ -1451,24 +1451,25 @@ in_repo_authz(const svn_test_opts_t *opt
/* repos relative URL */
repos_root = svn_repos_path(repos, pool);
- SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", TRUE, repos_root,
- pool));
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", NULL, TRUE,
+ repos_root, pool));
SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
/* absolute file URL, repos_root is NULL to validate the contract that it
* is not needed except when a repos relative URL is passed. */
SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_root, pool));
authz_url = apr_pstrcat(pool, repos_url, "/authz", (char *)NULL);
- SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, TRUE, NULL, pool));
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, NULL, TRUE,
+ NULL, pool));
SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
/* Non-existant path in the repo with must_exist set to FALSE */
- SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz", FALSE, repos_root,
- pool));
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz", NULL, FALSE,
+ repos_root, pool));
/* Non-existant path in the repo with must_exist set to TRUE */
- err = svn_repos_authz_read2(&authz_cfg, "^/A/authz", TRUE, repos_root,
- pool);
+ err = svn_repos_authz_read2(&authz_cfg, "^/A/authz", NULL, TRUE,
+ repos_root, pool);
if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
return svn_error_createf(SVN_ERR_TEST_FAILED, err,
"Got %s error instead of expected "
@@ -1478,7 +1479,7 @@ in_repo_authz(const svn_test_opts_t *opt
/* http:// URL which is unsupported */
err = svn_repos_authz_read2(&authz_cfg, "http://example.com/repo/authz",
- TRUE, repos_root, pool);
+ NULL, TRUE, repos_root, pool);
if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
return svn_error_createf(SVN_ERR_TEST_FAILED, err,
"Got %s error instead of expected "
@@ -1488,6 +1489,160 @@ in_repo_authz(const svn_test_opts_t *opt
/* svn:// URL which is unsupported */
err = svn_repos_authz_read2(&authz_cfg, "svn://example.com/repo/authz",
+ NULL, TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_RA_ILLEGAL_URL",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Test in-repo authz with global groups. */
+static svn_error_t *
+in_repo_groups_authz(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos;
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_revnum_t youngest_rev;
+ svn_authz_t *authz_cfg;
+ const char *groups_contents;
+ const char *authz_contents;
+ const char *repos_root;
+ const char *repos_url;
+ const char *groups_url;
+ const char *authz_url;
+ svn_error_t *err;
+ struct check_access_tests test_set[] = {
+ /* reads */
+ { "/A", NULL, NULL, svn_authz_read, FALSE },
+ { "/A", NULL, "plato", svn_authz_read, TRUE },
+ { "/A", NULL, "socrates", svn_authz_read, TRUE },
+ { "/A", NULL, "solon", svn_authz_read, TRUE },
+ { "/A", NULL, "ephialtes", svn_authz_read, TRUE },
+ /* writes */
+ { "/A", NULL, NULL, svn_authz_write, FALSE },
+ { "/A", NULL, "plato", svn_authz_write, FALSE },
+ { "/A", NULL, "socrates", svn_authz_write, FALSE },
+ { "/A", NULL, "solon", svn_authz_write, TRUE },
+ { "/A", NULL, "ephialtes", svn_authz_write, TRUE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Test plan:
+ * 1. Create an authz file, a global groups file and an empty authz file,
+ * put all these files in the repository. The empty authz file is
+ * required to perform the non-existent path checks (4-7) --
+ * otherwise we would get the authz validation error due to undefined
+ * groups.
+ * 2. Verify that the groups file can be read with an relative URL.
+ * 3. Verify that the groups file can be read with an absolute URL.
+ * 4. Verify that non-existent groups file path does not error out when
+ * must_exist is FALSE.
+ * 5. Same as (4), but when both authz and groups file paths do
+ * not exist.
+ * 6. Verify that non-existent path for the groups file does error out when
+ * must_exist is TRUE.
+ * 7. Verify that an http:// URL produces an error.
+ * 8. Verify that an svn:// URL produces an error.
+ */
+
+ /* What we'll put in the authz and groups files, it's simple since
+ * we're not testing the parsing, just that we got what we expected. */
+
+ groups_contents =
+ "[groups]" NL
+ "philosophers = plato, socrates" NL
+ "senate = solon, ephialtes" NL
+ "" NL;
+
+ authz_contents =
+ "[/]" NL
+ "@senate = rw" NL
+ "@philosophers = r" NL
+ "" NL;
+
+ /* Create a filesystem and repository. */
+ SVN_ERR(svn_test__create_repos(&repos,
+ "test-repo-in-repo-global-groups-authz",
+ opts, pool));
+ fs = svn_repos_fs(repos);
+
+ /* Commit the authz, empty authz and groups files to the repo. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "groups", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "authz", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "empty-authz", pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "groups",
+ groups_contents, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "authz",
+ authz_contents, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "empty-authz", "", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+ SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+
+ /* repos relative URLs */
+ repos_root = svn_repos_path(repos, pool);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", "^/groups",
+ TRUE, repos_root, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* absolute file URLs, repos_root is NULL to validate the contract that it
+ * is not needed except when a repos relative URLs are passed. */
+ SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_root, pool));
+ authz_url = apr_pstrcat(pool, repos_url, "/authz", (char *)NULL);
+ groups_url = apr_pstrcat(pool, repos_url, "/groups", (char *)NULL);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, groups_url,
+ TRUE, NULL, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* Non-existent path for the groups file with must_exist
+ * set to TRUE */
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "^/A/groups", FALSE,
+ repos_root, pool));
+
+ /* Non-existent paths for both the authz and the groups files
+ * with must_exist set to TRUE */
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz",
+ "^/A/groups", FALSE,
+ repos_root, pool));
+
+ /* Non-existent path for the groups file with must_exist
+ * set to TRUE */
+ err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "^/A/groups", TRUE,
+ repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* http:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "http://example.com/repo/groups",
+ TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_RA_ILLEGAL_URL",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* svn:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "http://example.com/repo/groups",
TRUE, repos_root, pool);
if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
return svn_error_createf(SVN_ERR_TEST_FAILED, err,
@@ -1500,6 +1655,249 @@ in_repo_authz(const svn_test_opts_t *opt
return SVN_NO_ERROR;
}
+
+/* Helper for the groups_authz test. Set *AUTHZ_P to a representation of
+ AUTHZ_CONTENTS in conjuction with GROUPS_CONTENTS, using POOL for
+ temporary allocation. If DISK is TRUE then write the contents to
+ temporary files and use svn_repos_authz_read2() to get the data if FALSE
+ write the data to a buffered stream and use svn_repos_authz_parse(). */
+static svn_error_t *
+authz_groups_get_handle(svn_authz_t **authz_p,
+ const char *authz_contents,
+ const char *groups_contents,
+ svn_boolean_t disk,
+ apr_pool_t *pool)
+{
+ if (disk)
+ {
+ const char *authz_file_path;
+ const char *groups_file_path;
+
+ /* Create temporary files. */
+ SVN_ERR_W(svn_io_write_unique(&authz_file_path, NULL,
+ authz_contents,
+ strlen(authz_contents),
+ svn_io_file_del_on_pool_cleanup, pool),
+ "Writing temporary authz file");
+ SVN_ERR_W(svn_io_write_unique(&groups_file_path, NULL,
+ groups_contents,
+ strlen(groups_contents),
+ svn_io_file_del_on_pool_cleanup, pool),
+ "Writing temporary groups file");
+
+ /* Read the authz configuration back and start testing. */
+ SVN_ERR_W(svn_repos_authz_read2(authz_p, authz_file_path,
+ groups_file_path, TRUE, NULL, pool),
+ "Opening test authz and groups files");
+
+ /* Done with the files. */
+ SVN_ERR_W(svn_io_remove_file(authz_file_path, pool),
+ "Removing test authz file");
+ SVN_ERR_W(svn_io_remove_file(groups_file_path, pool),
+ "Removing test groups file");
+ }
+ else
+ {
+ svn_stream_t *stream;
+ svn_stream_t *groups_stream;
+
+ /* Create the streams. */
+ stream = svn_stream_buffered(pool);
+ groups_stream = svn_stream_buffered(pool);
+
+ SVN_ERR_W(svn_stream_puts(stream, authz_contents),
+ "Writing authz contents to stream");
+ SVN_ERR_W(svn_stream_puts(groups_stream, groups_contents),
+ "Writing groups contents to stream");
+
+ /* Read the authz configuration from the streams and start testing. */
+ SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, groups_stream, pool),
+ "Parsing the authz and groups contents");
+
+ /* Done with the streams. */
+ SVN_ERR_W(svn_stream_close(stream),
+ "Closing the authz stream");
+ SVN_ERR_W(svn_stream_close(groups_stream),
+ "Closing the groups stream");
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Test authz with global groups. */
+static svn_error_t *
+groups_authz(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_authz_t *authz_cfg;
+ const char *authz_contents;
+ const char *groups_contents;
+ svn_error_t *err;
+
+ struct check_access_tests test_set1[] = {
+ /* reads */
+ { "/A", "greek", NULL, svn_authz_read, FALSE },
+ { "/A", "greek", "plato", svn_authz_read, TRUE },
+ { "/A", "greek", "demetrius", svn_authz_read, TRUE },
+ { "/A", "greek", "galenos", svn_authz_read, TRUE },
+ { "/A", "greek", "pamphilos", svn_authz_read, FALSE },
+ /* writes */
+ { "/A", "greek", NULL, svn_authz_write, FALSE },
+ { "/A", "greek", "plato", svn_authz_write, TRUE },
+ { "/A", "greek", "demetrius", svn_authz_write, FALSE },
+ { "/A", "greek", "galenos", svn_authz_write, FALSE },
+ { "/A", "greek", "pamphilos", svn_authz_write, FALSE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ struct check_access_tests test_set2[] = {
+ /* reads */
+ { "/A", "greek", NULL, svn_authz_read, FALSE },
+ { "/A", "greek", "socrates", svn_authz_read, FALSE },
+ { "/B", "greek", NULL, svn_authz_read, FALSE},
+ { "/B", "greek", "socrates", svn_authz_read, TRUE },
+ /* writes */
+ { "/A", "greek", NULL, svn_authz_write, FALSE },
+ { "/A", "greek", "socrates", svn_authz_write, FALSE },
+ { "/B", "greek", NULL, svn_authz_write, FALSE},
+ { "/B", "greek", "socrates", svn_authz_write, TRUE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Test plan:
+ * 1. Ensure that a simple setup with global groups and access rights in
+ * two separate files works as expected.
+ * 2. Verify that access rights written in the global groups file are
+ * discarded and affect nothing in authorization terms.
+ * 3. Verify that local groups in the authz file are prohibited in
+ * conjuction with global groups (and that a configuration error is
+ * reported in this scenario).
+ * 4. Ensure that group cycles in the global groups file are reported.
+ *
+ * All checks are performed twice -- for the configurations stored on disk
+ * and in memory. See authz_groups_get_handle.
+ */
+
+ groups_contents =
+ "[groups]" NL
+ "slaves = pamphilos,@gladiators" NL
+ "gladiators = demetrius,galenos" NL
+ "philosophers = plato" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/A]" NL
+ "@slaves = " NL
+ "@gladiators = r" NL
+ "@philosophers = rw" NL
+ "" NL;
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set1, pool));
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set1, pool));
+
+ /* Access rights in the global groups file are discarded. */
+ groups_contents =
+ "[groups]" NL
+ "philosophers = socrates" NL
+ "" NL
+ "[greek:/A]" NL
+ "@philosophers = rw" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/B]" NL
+ "@philosophers = rw" NL
+ "" NL;
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set2, pool));
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set2, pool));
+
+ /* Local groups cannot be used in conjuction with global groups. */
+ groups_contents =
+ "[groups]" NL
+ "slaves = maximus" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/A]" NL
+ "@slaves = " NL
+ "@kings = rw" NL
+ "" NL
+ "[groups]" NL
+ /* That's an epic story of the slave who tried to become a king. */
+ "kings = maximus" NL
+ "" NL;
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* Ensure that group cycles are reported. */
+ groups_contents =
+ "[groups]" NL
+ "slaves = cooks,scribes,@gladiators" NL
+ "gladiators = equites,thraces,@slaves" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/A]" NL
+ "@slaves = r" NL
+ "" NL;
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ return SVN_NO_ERROR;
+}
/* Callback for the commit editor tests that relays requests to
authz. */
@@ -2423,7 +2821,7 @@ prop_validation(const svn_test_opts_t *o
{
svn_error_t *err;
svn_repos_t *repos;
- const char non_utf8_string[5] = { 'a', (char)0xff, 'b', '\n', 0 };
+ const char non_utf8_string[5] = { 'a', '\xff', 'b', '\n', 0 };
const char *non_lf_string = "a\r\nb\n\rc\rd\n";
apr_pool_t *subpool = svn_pool_create(pool);
@@ -2723,6 +3121,36 @@ issue_4060(const svn_test_opts_t *opts,
return SVN_NO_ERROR;
}
+/* Test svn_repos_delete(). */
+static svn_error_t *
+test_delete_repos(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ const char *path;
+ svn_node_kind_t kind;
+
+ /* We have to use a subpool to close the svn_repos_t before calling
+ svn_repos_delete. */
+ {
+ svn_repos_t *repos;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ SVN_ERR(svn_test__create_repos(&repos, "test-repo-delete-repos", opts,
+ subpool));
+ path = svn_repos_path(repos, pool);
+ svn_pool_destroy(subpool);
+ }
+
+ SVN_ERR(svn_io_check_path(path, &kind, pool));
+ SVN_TEST_ASSERT(kind != svn_node_none);
+ SVN_ERR(svn_repos_delete(path, pool));
+ SVN_ERR(svn_io_check_path(path, &kind, pool));
+ SVN_TEST_ASSERT(kind == svn_node_none);
+
+ /* Recreate dir so that test cleanup doesn't fail. */
+ SVN_ERR(svn_io_dir_make(path, APR_OS_DEFAULT, pool));
+
+ return SVN_NO_ERROR;
+}
/* The test table. */
@@ -2745,6 +3173,10 @@ struct svn_test_descriptor_t test_funcs[
"test authz access control"),
SVN_TEST_OPTS_PASS(in_repo_authz,
"test authz stored in the repo"),
+ SVN_TEST_OPTS_PASS(in_repo_groups_authz,
+ "test authz and global groups stored in the repo"),
+ SVN_TEST_OPTS_PASS(groups_authz,
+ "test authz with global groups"),
SVN_TEST_OPTS_PASS(commit_editor_authz,
"test authz in the commit editor"),
SVN_TEST_OPTS_PASS(commit_continue_txn,
@@ -2761,5 +3193,7 @@ struct svn_test_descriptor_t test_funcs[
"test svn_repos_get_file_revsN"),
SVN_TEST_OPTS_PASS(issue_4060,
"test issue 4060"),
+ SVN_TEST_OPTS_PASS(test_delete_repos,
+ "test svn_repos_delete"),
SVN_TEST_NULL
};