You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/03/30 22:58:01 UTC
svn commit: r929279 [20/20] - in
/subversion/branches/svn-patch-improvements: ./ build/ac-macros/
build/generator/ build/generator/templates/ contrib/client-side/emacs/
notes/feedback/ notes/meetings/ notes/wc-ng/ subversion/
subversion/bindings/javahl...
Modified: subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svnadmin_tests.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svnadmin_tests.py Tue Mar 30 20:57:53 2010
@@ -33,6 +33,7 @@ import sys
import svntest
from svntest.verify import SVNExpectedStdout, SVNExpectedStderr
from svntest.verify import SVNUnexpectedStderr
+from svntest.main import SVN_PROP_MERGEINFO
# (abbreviation)
Skip = svntest.testcase.Skip
@@ -812,22 +813,22 @@ def reflect_dropped_renumbered_revs(sbox
'/toplevel')
# Verify the svn:mergeinfo properties
- svntest.actions.run_and_verify_svn(None, ["/trunk:1-4\n"],
+ svntest.actions.run_and_verify_svn(None, ["/trunk:2-4\n"],
[], 'propget', 'svn:mergeinfo',
sbox.repo_url + '/branch2')
svntest.actions.run_and_verify_svn(None, ["/branch1:5-9\n"],
[], 'propget', 'svn:mergeinfo',
sbox.repo_url + '/trunk')
- svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:1-13\n"],
+ svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:11-13\n"],
[], 'propget', 'svn:mergeinfo',
sbox.repo_url + '/toplevel/branch2')
svntest.actions.run_and_verify_svn(None, ["/toplevel/branch1:14-18\n"],
[], 'propget', 'svn:mergeinfo',
sbox.repo_url + '/toplevel/trunk')
- svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:1-12\n"],
+ svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:11-12\n"],
[], 'propget', 'svn:mergeinfo',
sbox.repo_url + '/toplevel/branch1')
- svntest.actions.run_and_verify_svn(None, ["/trunk:1-3\n"],
+ svntest.actions.run_and_verify_svn(None, ["/trunk:2-3\n"],
[], 'propget', 'svn:mergeinfo',
sbox.repo_url + '/branch1')
@@ -958,6 +959,152 @@ def verify_with_invalid_revprops(sbox):
".*Malformed file"):
raise svntest.Failure
+#----------------------------------------------------------------------
+# More testing for issue #3020 'Reflect dropped/renumbered revisions in
+# svn:mergeinfo data during svnadmin load'
+#
+# Specifically, test that loading a partial dump file filters out
+# mergeinfo that refers to revisions that are older than the oldest
+# loaded revisions -- See
+# http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc10.
+def drop_mergeinfo_outside_of_dump_stream(sbox):
+ "filter mergeinfo revs outside of dump stream"
+
+ test_create(sbox)
+
+ # Load a partial dump into an existing repository.
+ #
+ # Picture == 1k words:
+ #
+ # The existing repos loaded from skeleton_repos.dump looks like this:
+ #
+ # Projects/ (Added r1)
+ # README (Added r2)
+ # Project-X (Added r3)
+ # Project-Y (Added r4)
+ # Project-Z (Added r5)
+ # docs/ (Added r6)
+ # README (Added r6)
+ #
+ # The dump file 'mergeinfo_included_partial.dump' is a dump of r6:HEAD of
+ # the following repos:
+ # __________________________________________
+ # | |
+ # | ____________________________|_____
+ # | | | |
+ # trunk---r2---r3-----r5---r6-------r8---r9---------------> | |
+ # r1 | | | | | |
+ # intial | | | |______ | |
+ # import copy | copy | merge merge
+ # | | | merge (r5) (r8)
+ # | | | (r9) | |
+ # | | | | | |
+ # | | V V | |
+ # | | branches/B2-------r11---r12----> | |
+ # | | r7 |____| | |
+ # | | | | |
+ # | merge |___ | |
+ # | (r6) | | |
+ # | |_________________ | | |
+ # | | merge | |
+ # | | (r11-12) | |
+ # | | | | |
+ # V V V | |
+ # branches/B1-------------------r10--------r13--> | |
+ # r4 | |
+ # | V V
+ # branches/B1/B/E------------------------------r14---r15->
+ #
+ #
+ # The mergeinfo on the complete repos in the preceeding repos looks like:
+ #
+ # Properties on 'branches/B1':
+ # svn:mergeinfo
+ # /branches/B2:11-12
+ # /trunk:6,9
+ # Properties on 'branches/B1/B/E':
+ # svn:mergeinfo
+ # /branches/B2/B/E:11-12
+ # /trunk/B/E:5-6,8-9
+ # Properties on 'branches/B2':
+ # svn:mergeinfo
+ # /trunk:9
+ #
+ # If we were to load the dump of r6:HEAD into an empty repository, we'd
+ # expect any references to revisions <r6 to be removed entirely (since
+ # that history no longer exists) and the the remaining mergeinfo should
+ # have its revisions offset by -5. The resulting mergeinfo should look
+ # like this:
+ #
+ # Properties on 'branches/B1':
+ # svn:mergeinfo
+ # /branches/B2:6-7
+ # /trunk:1,4
+ # Properties on 'branches/B1/B/E':
+ # svn:mergeinfo
+ # /branches/B2/B/E:6-7
+ # /trunk/B/E:1,3-4
+ # Properties on 'branches/B2':
+ # svn:mergeinfo
+ # /trunk:4
+ #
+ # But here we will load it into the existing skeleton repository in the
+ # Projects/Project-X directory. Since we are loading the dump into a
+ # subtree, all the merge sources should be prefixed with the path to
+ # that subtree, i.e. 'Projects/Project-X', compared to the mergeinfo above.
+ # In addition, since the skeleton repos already has 6 revisions, we expect
+ # all the remaining revisions to be offset +6 from the above. That should
+ # result in this mergeinfo:
+ #
+ # Properties on 'Projects/Project-X/branches/B1':
+ # svn:mergeinfo
+ # /Projects/Project-X/branches/B2:12-13
+ # /Projects/Project-X/trunk:7,10
+ # Properties on 'Projects/Project-X/branches/B1/B/E':
+ # svn:mergeinfo
+ # /Projects/Project-X/branches/B2/B/E:12-13
+ # /Projects/Project-X/trunk/B/E:7,9-10
+ # Properties on 'Projects/Project-X/branches/B2':
+ # svn:mergeinfo
+ # /Projects/Project-X/trunk:10
+
+ # Load the skeleton dump:
+ dumpfile1 = svntest.main.file_read(
+ os.path.join(os.path.dirname(sys.argv[0]),
+ 'svnadmin_tests_data',
+ 'skeleton_repos.dump'))
+ load_and_verify_dumpstream(sbox, [], [], None, dumpfile1, '--ignore-uuid')
+
+ # Load the partial repository with mergeinfo dump:
+ dumpfile2 = svntest.main.file_read(
+ os.path.join(os.path.dirname(sys.argv[0]),
+ 'svnadmin_tests_data',
+ 'mergeinfo_included_partial.dump'))
+ load_and_verify_dumpstream(sbox, [], [], None, dumpfile2, '--ignore-uuid',
+ '--parent-dir', '/Projects/Project-X')
+
+ # Check the resulting mergeinfo.
+ #
+ # TODO: Use pg -vR, which would make the expected output easier on the eyes.
+ # Not using it because pg -vR on windows is outputting <CR><CR><LF>
+ # after the first line of multiline mergeinfo, which breaks the
+ # comparison, e.g.:
+ #
+ # Properties on 'Projects/Project-X/branches/B1/B/E':<CR><LF>
+ # svn:mergeinfo<CR><LF>
+ # /Projects/Project-X/branches/B2:12-13<CR><CR><LF>
+ # ^^^
+ # /Projects/Project-X/trunk:7,10<CR><LF>
+ url = sbox.repo_url + '/Projects/Project-X/branches/'
+ expected_output = svntest.verify.UnorderedOutput([
+ url + "B1 - /Projects/Project-X/branches/B2:12-13\n",
+ "/Projects/Project-X/trunk:7,10\n",
+ url + "B2 - /Projects/Project-X/trunk:10\n",
+ url + "B1/B/E - /Projects/Project-X/branches/B2/B/E:12-13\n",
+ "/Projects/Project-X/trunk/B/E:7,9-10\n"])
+ svntest.actions.run_and_verify_svn(None, expected_output, [],
+ 'propget', 'svn:mergeinfo', '-R',
+ sbox.repo_url)
########################################################################
# Run the tests
@@ -986,6 +1133,7 @@ test_list = [ None,
create_in_repo_subdir,
SkipUnless(verify_with_invalid_revprops,
svntest.main.is_fs_type_fsfs),
+ drop_mergeinfo_outside_of_dump_stream,
]
if __name__ == '__main__':
Modified: subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/actions.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/actions.py Tue Mar 30 20:57:53 2010
@@ -213,8 +213,12 @@ def run_and_verify_svn(message, expected
be 0 if no output is expected on stderr, and 1 otherwise."""
expected_exit = 0
- if expected_stderr is not None and expected_stderr != []:
- expected_exit = 1
+ if expected_stderr is not None:
+ if isinstance(expected_stderr, verify.ExpectedOutput):
+ if not expected_stderr.matches([]):
+ expected_exit = 1
+ elif expected_stderr != []:
+ expected_exit = 1
return run_and_verify_svn2(message, expected_stdout, expected_stderr,
expected_exit, *varargs)
@@ -248,7 +252,10 @@ def run_and_verify_svn2(message, expecte
raise verify.SVNIncorrectDatatype("expected_stderr must not be None")
want_err = None
- if expected_stderr != []:
+ if isinstance(expected_stderr, verify.ExpectedOutput):
+ if not expected_stderr.matches([]):
+ want_err = True
+ elif expected_stderr != []:
want_err = True
exit_code, out, err = main.run_svn(want_err, *varargs)
@@ -2172,13 +2179,13 @@ class DeepTreesTestCase:
expected_info = {
'F/alpha' : {
'Revision' : '3',
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .file.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .dir.*/DF/D1@3$',
Modified: subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/verify.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/verify.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/verify.py (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/cmdline/svntest/verify.py Tue Mar 30 20:57:53 2010
@@ -79,7 +79,7 @@ def createExpectedOutput(expected, outpu
expected = ExpectedOutput(expected)
elif isinstance(expected, str):
expected = RegexOutput(expected, match_all)
- elif expected == AnyOutput:
+ elif expected is AnyOutput:
expected = AnyOutput()
elif expected is not None and not isinstance(expected, ExpectedOutput):
raise SVNIncorrectDatatype("Unexpected type for '%s' data" % output_type)
@@ -87,6 +87,10 @@ def createExpectedOutput(expected, outpu
class ExpectedOutput:
"""Contains expected output, and performs comparisons."""
+
+ is_regex = False
+ is_unordered = False
+
def __init__(self, output, match_all=True):
"""Initialize the expected output to OUTPUT which is a string, or a list
of strings, or None meaning an empty list. If MATCH_ALL is True, the
@@ -96,12 +100,14 @@ class ExpectedOutput:
strings among the matching ones."""
self.output = output
self.match_all = match_all
- self.is_reg_exp = False
def __str__(self):
return str(self.output)
def __cmp__(self, other):
+ raise 'badness'
+
+ def matches(self, other):
"""Return whether SELF.output matches OTHER (which may be a list
of newline-terminated lines, or a single string). Either value
may be None."""
@@ -114,77 +120,64 @@ class ExpectedOutput:
else:
actual = other
- if isinstance(actual, list):
- if isinstance(expected, str):
- expected = [expected]
- is_match = self.is_equivalent_list(expected, actual)
- elif isinstance(actual, str):
- is_match = self.is_equivalent_line(expected, actual)
- else: # unhandled type
- is_match = False
+ if not isinstance(actual, list):
+ actual = [actual]
+ if not isinstance(expected, list):
+ expected = [expected]
- if is_match:
- return 0
- else:
- return 1
+ return self.is_equivalent_list(expected, actual)
def is_equivalent_list(self, expected, actual):
"Return whether EXPECTED and ACTUAL are equivalent."
- if not self.is_reg_exp:
+ if not self.is_regex:
if self.match_all:
# The EXPECTED lines must match the ACTUAL lines, one-to-one, in
# the same order.
- if len(expected) != len(actual):
- return False
- for i in range(0, len(actual)):
- if not self.is_equivalent_line(expected[i], actual[i]):
- return False
- return True
- else:
- # The EXPECTED lines must match a subset of the ACTUAL lines,
- # one-to-one, in the same order, with zero or more other ACTUAL
- # lines interspersed among the matching ACTUAL lines.
- i_expected = 0
- for actual_line in actual:
- if self.is_equivalent_line(expected[i_expected], actual_line):
- i_expected += 1
- if i_expected == len(expected):
- return True
- return False
+ return expected == actual
+
+ # The EXPECTED lines must match a subset of the ACTUAL lines,
+ # one-to-one, in the same order, with zero or more other ACTUAL
+ # lines interspersed among the matching ACTUAL lines.
+ i_expected = 0
+ for actual_line in actual:
+ if expected[i_expected] == actual_line:
+ i_expected += 1
+ if i_expected == len(expected):
+ return True
+ return False
+
+ expected_re = expected[0]
+ # If we want to check that every line matches the regexp
+ # assume they all match and look for any that don't. If
+ # only one line matching the regexp is enough, assume none
+ # match and look for even one that does.
+ if self.match_all:
+ all_lines_match_re = True
else:
- expected_re = expected[0]
- # If we want to check that every line matches the regexp
- # assume they all match and look for any that don't. If
- # only one line matching the regexp is enough, assume none
- # match and look for even one that does.
- if self.match_all:
- all_lines_match_re = True
- else:
- all_lines_match_re = False
+ all_lines_match_re = False
- # If a regex was provided assume that we actually require
- # some output. Fail if we don't have any.
- if len(actual) == 0:
- return False
+ # If a regex was provided assume that we actually require
+ # some output. Fail if we don't have any.
+ if len(actual) == 0:
+ return False
- for i in range(0, len(actual)):
- if self.match_all:
- if not self.is_equivalent_line(expected_re, actual[i]):
- all_lines_match_re = False
- break
- else:
- if self.is_equivalent_line(expected_re, actual[i]):
- return True
- return all_lines_match_re
+ for actual_line in actual:
+ if self.match_all:
+ if not re.match(expected_re, actual_line):
+ return False
+ else:
+ # As soon an actual_line matches something, then we're good.
+ if re.match(expected_re, actual_line):
+ return True
- def is_equivalent_line(self, expected, actual):
- "Return whether EXPECTED and ACTUAL are equal."
- return expected == actual
+ return all_lines_match_re
def display_differences(self, message, label, actual):
"""Delegate to the display_lines() routine with the appropriate
args. MESSAGE is ignored if None."""
- display_lines(message, label, self.output, actual, False, False)
+ display_lines(message, label, self.output, actual,
+ self.is_regex, self.is_unordered)
+
class AnyOutput(ExpectedOutput):
def __init__(self):
@@ -192,86 +185,72 @@ class AnyOutput(ExpectedOutput):
def is_equivalent_list(self, ignored, actual):
if len(actual) == 0:
- # Empty text or empty list -- either way, no output!
- return False
- elif isinstance(actual, list):
- for line in actual:
- if self.is_equivalent_line(None, line):
- return True
+ # No actual output. No match.
return False
- else:
- return True
- def is_equivalent_line(self, ignored, actual):
- return len(actual) > 0
+ for line in actual:
+ # If any line has some text, then there is output, so we match.
+ if line:
+ return True
+
+ # We did not find a line with text. No match.
+ return False
def display_differences(self, message, label, actual):
if message:
print(message)
-class RegexOutput(ExpectedOutput):
- def __init__(self, output, match_all=True, is_reg_exp=True):
- self.output = output
- self.match_all = match_all
- self.is_reg_exp = is_reg_exp
- def is_equivalent_line(self, expected, actual):
- "Return whether the regex EXPECTED matches the ACTUAL text."
- return re.match(expected, actual) is not None
+class RegexOutput(ExpectedOutput):
+ is_regex = True
- def display_differences(self, message, label, actual):
- display_lines(message, label, self.output, actual, True, False)
class UnorderedOutput(ExpectedOutput):
"""Marks unordered output, and performs comparisons."""
+ is_unordered = True
+
def __cmp__(self, other):
- "Handle ValueError."
- try:
- return ExpectedOutput.__cmp__(self, other)
- except ValueError:
- return 1
+ raise 'badness'
def is_equivalent_list(self, expected, actual):
"Disregard the order of ACTUAL lines during comparison."
+
+ e_set = set(expected)
+ a_set = set(actual)
+
if self.match_all:
- if len(expected) != len(actual):
+ if len(e_set) != len(a_set):
return False
- expected = list(expected)
- for actual_line in actual:
- try:
- i = self.is_equivalent_line(expected, actual_line)
- expected.pop(i)
- except ValueError:
- return False
- return True
- else:
- for actual_line in actual:
- try:
- self.is_equivalent_line(expected, actual_line)
- return True
- except ValueError:
- pass
+ if self.is_regex:
+ for expect_re in e_set:
+ for actual_line in a_set:
+ if re.match(expect_re, actual_line):
+ a_set.remove(actual_line)
+ break
+ else:
+ # One of the regexes was not found
+ return False
+ return True
+
+ # All expected lines must be in the output.
+ return e_set == a_set
+
+ if self.is_regex:
+ # If any of the expected regexes are in the output, then we match.
+ for expect_re in e_set:
+ for actual_line in a_set:
+ if re.match(expect_re, actual_line):
+ return True
return False
- def is_equivalent_line(self, expected, actual):
- """Return the index into the EXPECTED lines of the line ACTUAL.
- Raise ValueError if not found."""
- return expected.index(actual)
+ # If any of the expected lines are in the output, then we match.
+ return len(e_set.intersection(a_set)) > 0
- def display_differences(self, message, label, actual):
- display_lines(message, label, self.output, actual, False, True)
class UnorderedRegexOutput(UnorderedOutput, RegexOutput):
- def is_equivalent_line(self, expected, actual):
- for i in range(0, len(expected)):
- if RegexOutput.is_equivalent_line(self, expected[i], actual):
- return i
- else:
- raise ValueError("'%s' not found" % actual)
-
- def display_differences(self, message, label, actual):
- display_lines(message, label, self.output, actual, True, True)
+ is_regex = True
+ is_unordered = True
######################################################################
@@ -331,7 +310,7 @@ def compare_and_display_lines(message, l
actual = [actual]
actual = [line for line in actual if not line.startswith('DBG:')]
- if expected != actual:
+ if not expected.matches(actual):
expected.display_differences(message, label, actual)
raise raisable
Modified: subversion/branches/svn-patch-improvements/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/cmdline/switch_tests.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/cmdline/switch_tests.py Tue Mar 30 20:57:53 2010
@@ -2334,37 +2334,37 @@ def tree_conflicts_on_switch_1_1(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .file.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .dir.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .dir.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .dir.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .dir.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .dir.*/DDD/D1@3$',
@@ -2426,37 +2426,37 @@ def tree_conflicts_on_switch_1_2(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .dir.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .dir.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .dir.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon switch'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .dir.*/DDD/D1@3$',
@@ -2508,37 +2508,37 @@ def tree_conflicts_on_switch_2_1(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon switch'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon switch'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .none.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon switch'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .none.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon switch'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon switch'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .none.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon switch'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .none.*/DDD/D1@3$',
@@ -2602,37 +2602,37 @@ def tree_conflicts_on_switch_2_2(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .none.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .none.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .none.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .none.*/DDD/D1@3$',
@@ -2691,37 +2691,37 @@ def tree_conflicts_on_switch_3(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .none.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .none.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .none.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon switch'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .none.*/DDD/D1@3$',
Modified: subversion/branches/svn-patch-improvements/subversion/tests/cmdline/tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/cmdline/tree_conflict_tests.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/cmdline/tree_conflict_tests.py Tue Mar 30 20:57:53 2010
@@ -1130,6 +1130,67 @@ def query_absent_tree_conflicted_dir(sbo
# using info:
run_and_verify_svn(None, None, [], 'info', C_C_path)
+#----------------------------------------------------------------------
+
+def up_add_onto_add_revert(sbox):
+ "issue #3608: reverting an add onto add conflict"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ wc2_dir = sbox.add_wc_path('wc2')
+ svntest.actions.run_and_verify_svn(None, None, [], 'checkout',
+ sbox.repo_url, wc2_dir)
+
+ file1 = os.path.join(wc_dir, 'newfile')
+ file2 = os.path.join(wc2_dir, 'newfile')
+
+ dir1 = os.path.join(wc_dir, 'NewDir')
+ dir2 = os.path.join(wc2_dir, 'NewDir')
+
+ main.run_svn(None, 'cp', os.path.join(wc_dir, 'iota'), file1)
+ main.run_svn(None, 'cp', os.path.join(wc2_dir, 'iota'), file2)
+
+ main.run_svn(None, 'cp', os.path.join(wc_dir, 'A/C'), dir1)
+ main.run_svn(None, 'cp', os.path.join(wc2_dir, 'A/C'), dir2)
+
+ main.run_svn(None, 'ci', wc_dir, '-m', 'Added file')
+
+ expected_disk = main.greek_state.copy()
+ expected_disk.add({
+ 'newfile' : Item(contents="This is the file 'iota'.\n"),
+ 'NewDir' : Item(),
+ })
+
+ expected_status = get_virginal_state(wc2_dir, 2)
+ expected_status.add({
+ 'newfile' : Item(status='A ', copied='+', treeconflict='C', wc_rev='-'),
+ 'NewDir' : Item(status='A ', copied='+', treeconflict='C', wc_rev='-'),
+ })
+
+ run_and_verify_update(wc2_dir,
+ None, expected_disk, expected_status,
+ None, None, None, None, None, 1,
+ wc2_dir)
+
+ # Currently (r927086), this removes dir2 and file2 in a way that
+ # they don't reappear after update.
+ main.run_svn(None, 'revert', file2)
+ main.run_svn(None, 'revert', dir2)
+
+ expected_status = get_virginal_state(wc2_dir, 2)
+ expected_status.add({
+ 'newfile' : Item(status=' ', wc_rev='2'),
+ 'NewDir' : Item(status=' ', wc_rev='2'),
+ })
+
+ # Expected behavior is that after revert + update the tree matches
+ # the repository
+ run_and_verify_update(wc2_dir,
+ None, expected_disk, expected_status,
+ None, None, None, None, None, 1,
+ wc2_dir)
+
+
#######################################################################
# Run the tests
@@ -1159,6 +1220,7 @@ test_list = [ None,
XFail(keep_local_del_tc_is_target),
XFail(force_del_tc_is_target),
XFail(query_absent_tree_conflicted_dir),
+ XFail(up_add_onto_add_revert),
]
if __name__ == '__main__':
Modified: subversion/branches/svn-patch-improvements/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/cmdline/update_tests.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/cmdline/update_tests.py Tue Mar 30 20:57:53 2010
@@ -2208,10 +2208,18 @@ def update_wc_on_windows_drive(sbox):
if not drive + ':\\' in drives:
return drive
except ImportError:
- return None
+ # In ActiveState python x64 win32api is not available
+ for d in range(ord('G'), ord('Z')+1):
+ drive = chr(d)
+ if not os.path.isdir(drive + ':\\'):
+ return drive
return None
+ # Skip the test if not on Windows
+ if not svntest.main.windows:
+ raise svntest.Skip
+
# just create an empty folder, we'll checkout later.
sbox.build(create_wc = False)
svntest.main.safe_rmtree(sbox.wc_dir)
@@ -4324,37 +4332,37 @@ def tree_conflicts_on_update_1_1(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .file.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .dir.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .dir.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .dir.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .dir.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .dir.*/DDD/D1@3$',
@@ -4408,7 +4416,7 @@ def tree_conflicts_on_update_1_2(sbox):
'DDD/D1/D2/D3',
'DDF/D1/D2/gamma',
'DF/D1/beta')
-
+
### Why does the deep trees state not include files?
expected_disk.remove('D/D1',
'DD/D1/D2',
@@ -4416,37 +4424,37 @@ def tree_conflicts_on_update_1_2(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .dir.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .dir.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .dir.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming edit upon update'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .dir.*/DDD/D1@3$',
@@ -4499,37 +4507,37 @@ def tree_conflicts_on_update_2_1(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon update'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon update'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .none.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon update'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .none.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon update'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon update'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .none.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local edit, incoming delete upon update'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .none.*/DDD/D1@3$',
@@ -4602,37 +4610,37 @@ def tree_conflicts_on_update_2_2(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .none.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .none.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .none.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .none.*/DDD/D1@3$',
@@ -4763,37 +4771,37 @@ def tree_conflicts_on_update_3(sbox):
expected_info = {
'F/alpha' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .file.*/F/alpha@2'
+ ' Source right: .none.*/F/alpha@3$',
},
'DF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DF/D1@2'
+ ' Source right: .none.*/DF/D1@3$',
},
'DDF/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DDF/D1@2'
+ ' Source right: .none.*/DDF/D1@3$',
},
'D/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/D/D1@2'
+ ' Source right: .none.*/D/D1@3$',
},
'DD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DD/D1@2'
+ ' Source right: .none.*/DD/D1@3$',
},
'DDD/D1' : {
- 'Tree conflict' :
+ 'Tree conflict' :
'^local delete, incoming delete upon update'
+ ' Source left: .dir.*/DDD/D1@2'
+ ' Source right: .none.*/DDD/D1@3$',
@@ -5210,21 +5218,21 @@ def set_deep_depth_on_target_with_shallo
'A/D/H/omega' : Item(status='D '),
'A/D/H/psi' : Item(status='D '),
})
-
+
expected_status.remove('A/D/G/pi',
'A/D/G/rho',
'A/D/G/tau',
'A/D/H/chi',
'A/D/H/omega',
'A/D/H/psi')
-
+
expected_disk.remove('A/D/G/pi',
'A/D/G/rho',
'A/D/G/tau',
'A/D/H/chi',
'A/D/H/omega',
'A/D/H/psi')
-
+
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
@@ -5249,11 +5257,11 @@ def set_deep_depth_on_target_with_shallo
'A/D/H/omega' : Item(status='A '),
'A/D/H/psi' : Item(status='A '),
})
-
+
expected_disk = svntest.main.greek_state.copy()
-
+
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
-
+
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
@@ -5303,7 +5311,7 @@ def update_deleted_locked_files(sbox):
svntest.main.run_svn(None, 'delete', E)#iota, E)
expected_output = svntest.wc.State(wc_dir, {})
-
+
expected_disk = svntest.main.greek_state.copy()
expected_disk.remove('iota',
'A/B/E/alpha',
@@ -5384,7 +5392,7 @@ def update_empty_hides_entries(sbox):
wc_dir)
# Now update the rest back to head
-
+
# This operation is currently a NO-OP, because the WC-Crawler
# tells the repository that it contains a full tree of the HEAD
# revision.
@@ -5440,7 +5448,7 @@ def mergeinfo_updates_merge_with_local_m
sbox.repo_url + '/A', A_COPY_path)
svntest.actions.run_and_verify_svn(None, [A_COPY_path + " - /A:3\n"], [],
'pg', SVN_PROP_MERGEINFO, '-R',
- A_COPY_path)
+ A_COPY_path)
# Update the WC (to r8), the mergeinfo on A_COPY should now have both
# the local mod from the uncommitted merge (/A:3* --> /A:3) and the change
Modified: subversion/branches/svn-patch-improvements/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/cmdline/upgrade_tests.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/cmdline/upgrade_tests.py Tue Mar 30 20:57:53 2010
@@ -141,6 +141,23 @@ def basic_upgrade(sbox):
expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
run_and_verify_status_no_server(sbox.wc_dir, expected_status)
+def upgrade_with_externals(sbox):
+ "upgrade with externals"
+
+ # Create wc from tarfile, uses the same structure of the wc as the tests
+ # in externals_tests.py.
+ replace_sbox_with_tarfile(sbox, 'upgrade_with_externals.tar.bz2')
+
+ # Attempt to use the working copy, this should give an error
+ expected_stderr = wc_is_too_old_regex
+ svntest.actions.run_and_verify_svn(None, None, expected_stderr,
+ 'info', sbox.wc_dir)
+ # Now upgrade the working copy
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'upgrade', sbox.wc_dir)
+
+ # Actually check the format number of the upgraded working copy
+ check_format(sbox, get_current_format())
def upgrade_1_5_body(sbox, subcommand):
replace_sbox_with_tarfile(sbox, 'upgrade_1_5.tar.bz2')
@@ -262,8 +279,8 @@ def basic_upgrade_1_0(sbox):
# Now check the contents of the working copy
# #### This working copy is not just a basic tree,
# fix with the right data once we get here
- expected_status = svntest.wc.State(sbox.wc_dir,
- {
+ expected_status = svntest.wc.State(sbox.wc_dir,
+ {
'' : Item(status=' ', wc_rev=7),
'B' : Item(status=' ', wc_rev='7'),
'B/mu' : Item(status=' ', wc_rev='7'),
@@ -328,6 +345,7 @@ def basic_upgrade_1_0(sbox):
# list all tests here, starting with None:
test_list = [ None,
basic_upgrade,
+ upgrade_with_externals,
upgrade_1_5,
update_1_5,
logs_left_1_5,
Propchange: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_client/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Mar 30 20:57:53 2010
@@ -1,3 +1,4 @@
.libs
client-test
*.lo
+test-patch*
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_client/client-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_client/client-test.c Tue Mar 30 20:57:53 2010
@@ -22,12 +22,17 @@
*/
+
+#include <limits.h>
#include "svn_mergeinfo.h"
#include "../../libsvn_client/mergeinfo.h"
#include "svn_pools.h"
#include "svn_client.h"
+#include "svn_repos.h"
+#include "svn_subst.h"
#include "../svn_test.h"
+#include "../svn_test_fs.h"
typedef struct {
const char *path;
@@ -199,6 +204,171 @@ test_args_to_target_array(apr_pool_t *po
return SVN_NO_ERROR;
}
+
+/* A helper function for test_patch().
+ * It compares a patched or reject file against expected content.
+ * It also deletes the file if the check was successful. */
+static svn_error_t *
+check_patch_result(const char *path, const char **expected_lines,
+ int num_expected_lines, apr_pool_t *pool)
+{
+ svn_stream_t *stream;
+ apr_pool_t *iterpool;
+ int i;
+
+ SVN_ERR(svn_stream_open_readonly(&stream, path, pool, pool));
+ i = 0;
+ iterpool = svn_pool_create(pool);
+ while (TRUE)
+ {
+ svn_boolean_t eof;
+ svn_stringbuf_t *line;
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_stream_readline(stream, &line, APR_EOL_STR, &eof, pool));
+ if (i < num_expected_lines)
+ if (strcmp(expected_lines[i++], line->data) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "%s line %d didn't match the expected line "
+ "(strlen=%d vs strlen=%d)", path, i,
+ (int)strlen(expected_lines[i-1]),
+ (int)strlen(line->data));
+
+ if (eof)
+ break;
+ }
+ svn_pool_destroy(iterpool);
+
+ SVN_ERR_ASSERT(i == num_expected_lines);
+ SVN_ERR(svn_io_remove_file2(path, FALSE, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_patch(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;
+ apr_hash_t *patched_tempfiles;
+ apr_hash_t *reject_tempfiles;
+ const char *repos_url;
+ const char *wc_path;
+ const char *cwd;
+ svn_revnum_t committed_rev;
+ svn_opt_revision_t rev;
+ svn_opt_revision_t peg_rev;
+ svn_client_ctx_t *ctx;
+ apr_file_t *patch_file;
+ const char *patch_file_path;
+ const char *patched_tempfile_path;
+ const char *reject_tempfile_path;
+ const char *key;
+ int i;
+#define NL APR_EOL_STR
+#define UNIDIFF_LINES 7
+ const char *unidiff_patch[UNIDIFF_LINES] = {
+ "Index: A/D/gamma" NL,
+ "===================================================================\n",
+ "--- A/D/gamma\t(revision 1)" NL,
+ "+++ A/D/gamma\t(working copy)" NL,
+ "@@ -1 +1 @@" NL,
+ "-This is really the file 'gamma'." NL,
+ "+It is really the file 'gamma'." NL
+ };
+#define EXPECTED_GAMMA_LINES 1
+ const char *expected_gamma[EXPECTED_GAMMA_LINES] = {
+ "This is the file 'gamma'."
+ };
+#define EXPECTED_GAMMA_REJECT_LINES 5
+ const char *expected_gamma_reject[EXPECTED_GAMMA_REJECT_LINES] = {
+ "--- A/D/gamma",
+ "+++ A/D/gamma",
+ "@@ -1,1 +1,1 @@",
+ "-This is really the file 'gamma'.",
+ "+It is really the file 'gamma'."
+ };
+
+ /* Create a filesytem and repository. */
+ SVN_ERR(svn_test__create_repos(&repos, "test-patch-repos",
+ opts, pool));
+ fs = svn_repos_fs(repos);
+
+ /* Prepare a txn to receive the greek tree. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 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, &committed_rev, txn, pool));
+
+ /* Check out the HEAD revision */
+ SVN_ERR(svn_dirent_get_absolute(&cwd, "", pool));
+
+ if (cwd[0] == '/')
+ repos_url = apr_pstrcat(pool, "file://", cwd,
+ "/test-patch-repos", NULL);
+ else
+ /* On Windows CWD is always in "X:/..." style */
+ repos_url = apr_pstrcat(pool, "file:///", cwd,
+ "/test-patch-repos", NULL);
+
+ repos_url = svn_uri_canonicalize(repos_url, pool);
+
+ /* Put wc inside an unversioned directory. Checking out a 1.7 wc
+ directly inside a 1.6 wc doesn't work reliably, an intervening
+ unversioned directory prevents the problems. */
+ wc_path = svn_dirent_join(cwd, "test-patch", pool);
+ SVN_ERR(svn_io_make_dir_recursively(wc_path, pool));
+ svn_test_add_dir_cleanup(wc_path);
+
+ wc_path = svn_dirent_join(wc_path, "test-patch-wc", pool);
+ SVN_ERR(svn_io_remove_dir2(wc_path, TRUE, NULL, NULL, pool));
+ rev.kind = svn_opt_revision_head;
+ peg_rev.kind = svn_opt_revision_unspecified;
+ SVN_ERR(svn_client_create_context(&ctx, pool));
+ SVN_ERR(svn_client_checkout3(NULL, repos_url, wc_path,
+ &peg_rev, &rev, svn_depth_infinity,
+ TRUE, FALSE, ctx, pool));
+
+ /* Create the patch file. */
+ patch_file_path = svn_dirent_join_many(pool, cwd,
+ "test-patch", "test-patch.diff", NULL);
+ SVN_ERR(svn_io_file_open(&patch_file, patch_file_path,
+ (APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE),
+ APR_OS_DEFAULT, pool));
+ for (i = 0; i < UNIDIFF_LINES; i++)
+ {
+ apr_size_t len = strlen(unidiff_patch[i]);
+ SVN_ERR(svn_io_file_write(patch_file, unidiff_patch[i], &len, pool));
+ SVN_ERR_ASSERT(len == strlen(unidiff_patch[i]));
+ }
+ SVN_ERR(svn_io_file_flush_to_disk(patch_file, pool));
+
+ /* Apply the patch. */
+ SVN_ERR(svn_client_patch(patch_file_path, wc_path, FALSE, 0, FALSE,
+ NULL, NULL, &patched_tempfiles, &reject_tempfiles,
+ ctx, pool, pool));
+ SVN_ERR(svn_io_file_close(patch_file, pool));
+
+ SVN_ERR_ASSERT(apr_hash_count(patched_tempfiles) == 1);
+ key = "A/D/gamma";
+ patched_tempfile_path = apr_hash_get(patched_tempfiles, key,
+ APR_HASH_KEY_STRING);
+ SVN_ERR(check_patch_result(patched_tempfile_path, expected_gamma,
+ EXPECTED_GAMMA_LINES, pool));
+ SVN_ERR_ASSERT(apr_hash_count(reject_tempfiles) == 1);
+ key = "A/D/gamma";
+ reject_tempfile_path = apr_hash_get(reject_tempfiles, key,
+ APR_HASH_KEY_STRING);
+ SVN_ERR(check_patch_result(reject_tempfile_path, expected_gamma_reject,
+ EXPECTED_GAMMA_REJECT_LINES, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ========================================================================== */
struct svn_test_descriptor_t test_funcs[] =
@@ -208,5 +378,6 @@ struct svn_test_descriptor_t test_funcs[
"test svn_client__elide_mergeinfo_catalog"),
SVN_TEST_PASS2(test_args_to_target_array,
"test svn_client_args_to_target_array"),
+ SVN_TEST_OPTS_PASS(test_patch, "test svn_client_patch"),
SVN_TEST_NULL
};
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/diff-diff3-test.c Tue Mar 30 20:57:53 2010
@@ -567,20 +567,20 @@ test_two_way_unified(apr_pool_t *pool)
SVN_ERR(two_way_diff("foo5d", "bar5d",
"Aa\r\n"
- "\r\n"
+ "\r\n"
"Bb\r\n"
- "\r\n"
+ "\r\n"
"Cc\r\n"
- "\r\n",
+ "\r\n",
"Aa\n"
- "\n"
+ "\n"
"Bb\n"
- "\n"
+ "\n"
"Cc\n"
- "\n",
+ "\n",
- "",
+ "",
diff_opts, pool));
diff_opts->ignore_eol_style = FALSE;
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/parse-diff-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/parse-diff-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/parse-diff-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_diff/parse-diff-test.c Tue Mar 30 20:57:53 2010
@@ -25,7 +25,6 @@
#include "../svn_test.h"
#include "svn_diff.h"
-#include "private/svn_diff_private.h"
#include "svn_pools.h"
#include "svn_utf.h"
@@ -101,8 +100,8 @@ test_parse_unidiff(apr_pool_t *pool)
/* We have two patches with one hunk each.
* Parse the first patch. */
- SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, reverse,
- iterpool, iterpool));
+ SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file, reverse,
+ iterpool, iterpool));
SVN_ERR_ASSERT(patch);
SVN_ERR_ASSERT(! strcmp(patch->old_filename, "A/C/gamma"));
SVN_ERR_ASSERT(! strcmp(patch->new_filename, "A/C/gamma"));
@@ -144,7 +143,7 @@ test_parse_unidiff(apr_pool_t *pool)
SVN_ERR_ASSERT(buf->len == 0);
/* Parse the second patch. */
- SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, reverse, pool, pool));
+ SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file, reverse, pool, pool));
SVN_ERR_ASSERT(patch);
if (reverse)
{
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_base/changes-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_base/changes-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_base/changes-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_base/changes-test.c Tue Mar 30 20:57:53 2010
@@ -698,6 +698,204 @@ changes_fetch_ordering(const svn_test_op
}
+static svn_error_t *
+changes_bad_sequences(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ svn_error_t *err;
+
+ /* Create a new fs and repos */
+ SVN_ERR(svn_test__create_bdb_fs
+ (&fs, "test-repo-changes-bad-sequences", opts,
+ pool));
+
+ /* Test changes bogus because a path's node-rev-ID changed
+ unexpectedly. */
+ svn_pool_clear(subpool);
+ {
+ static const char *bogus_changes[][6]
+ /* KEY PATH NODEREVID KIND TEXT PROP */
+ = { { "x", "/foo", "1.0.0", "add", 0 , 0 },
+ { "x", "/foo", "1.0.0", "modify", 0 , "1" },
+ { "x", "/foo", "2.0.0", "modify", "1", "1" } };
+ int num_changes = sizeof(bogus_changes) / sizeof(const char *) / 6;
+ struct changes_args args;
+ int i;
+
+ for (i = 0; i < num_changes; i++)
+ {
+ change_t change;
+
+ /* Set up the current change item. */
+ change.path = bogus_changes[i][1];
+ change.noderev_id = svn_fs_parse_id(bogus_changes[i][2],
+ strlen(bogus_changes[i][2]),
+ subpool);
+ change.kind = string_to_kind(bogus_changes[i][3]);
+ change.text_mod = bogus_changes[i][4] ? 1 : 0;
+ change.prop_mod = bogus_changes[i][5] ? 1 : 0;
+
+ /* Set up transaction baton. */
+ args.fs = fs;
+ args.key = "x";
+ args.change = &change;
+
+ /* Write new changes to the changes table. */
+ SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_add, &args,
+ TRUE, subpool));
+ }
+
+ /* Now read 'em back, looking for an error. */
+ args.fs = fs;
+ args.key = "x";
+ err = svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch, &args,
+ TRUE, subpool);
+ if (!err)
+ {
+ return svn_error_create(SVN_ERR_TEST_FAILED, 0,
+ "Expected SVN_ERR_FS_CORRUPT, got no error.");
+ }
+ else if (err->apr_err != SVN_ERR_FS_CORRUPT)
+ {
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Expected SVN_ERR_FS_CORRUPT, got a different error.");
+ }
+ else
+ {
+ svn_error_clear(err);
+ }
+
+ /* Post-test cleanup. */
+ SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_delete, &args,
+ TRUE, subpool));
+ }
+
+ /* Test changes bogus because there's a change other than an
+ add-type changes on a deleted path. */
+ svn_pool_clear(subpool);
+ {
+ static const char *bogus_changes[][6]
+ /* KEY PATH NODEREVID KIND TEXT PROP */
+ = { { "x", "/foo", "1.0.0", "delete", 0 , 0 },
+ { "x", "/foo", "1.0.0", "modify", "1", 0 } };
+ int num_changes = sizeof(bogus_changes) / sizeof(const char *) / 6;
+ struct changes_args args;
+ int i;
+
+ for (i = 0; i < num_changes; i++)
+ {
+ change_t change;
+
+ /* Set up the current change item. */
+ change.path = bogus_changes[i][1];
+ change.noderev_id = svn_fs_parse_id(bogus_changes[i][2],
+ strlen(bogus_changes[i][2]),
+ subpool);
+ change.kind = string_to_kind(bogus_changes[i][3]);
+ change.text_mod = bogus_changes[i][4] ? 1 : 0;
+ change.prop_mod = bogus_changes[i][5] ? 1 : 0;
+
+ /* Set up transaction baton. */
+ args.fs = fs;
+ args.key = "x";
+ args.change = &change;
+
+ /* Write new changes to the changes table. */
+ SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_add, &args,
+ TRUE, subpool));
+ }
+
+ /* Now read 'em back, looking for an error. */
+ args.fs = fs;
+ args.key = "x";
+ err = svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch, &args,
+ TRUE, subpool);
+ if (!err)
+ {
+ return svn_error_create(SVN_ERR_TEST_FAILED, 0,
+ "Expected SVN_ERR_FS_CORRUPT, got no error.");
+ }
+ else if (err->apr_err != SVN_ERR_FS_CORRUPT)
+ {
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Expected SVN_ERR_FS_CORRUPT, got a different error.");
+ }
+ else
+ {
+ svn_error_clear(err);
+ }
+
+ /* Post-test cleanup. */
+ SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_delete, &args,
+ TRUE, subpool));
+ }
+
+ /* Test changes bogus because there's an add on a path that's got
+ previous non-delete changes on it. */
+ svn_pool_clear(subpool);
+ {
+ static const char *bogus_changes[][6]
+ /* KEY PATH NODEREVID KIND TEXT PROP */
+ = { { "x", "/foo", "1.0.0", "modify", "1", 0 },
+ { "x", "/foo", "1.0.0", "add", "1", 0 } };
+ int num_changes = sizeof(bogus_changes) / sizeof(const char *) / 6;
+ struct changes_args args;
+ int i;
+
+ for (i = 0; i < num_changes; i++)
+ {
+ change_t change;
+
+ /* Set up the current change item. */
+ change.path = bogus_changes[i][1];
+ change.noderev_id = svn_fs_parse_id(bogus_changes[i][2],
+ strlen(bogus_changes[i][2]),
+ subpool);
+ change.kind = string_to_kind(bogus_changes[i][3]);
+ change.text_mod = bogus_changes[i][4] ? 1 : 0;
+ change.prop_mod = bogus_changes[i][5] ? 1 : 0;
+
+ /* Set up transaction baton. */
+ args.fs = fs;
+ args.key = "x";
+ args.change = &change;
+
+ /* Write new changes to the changes table. */
+ SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_add, &args,
+ TRUE, subpool));
+ }
+
+ /* Now read 'em back, looking for an error. */
+ args.fs = fs;
+ args.key = "x";
+ err = svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch, &args,
+ TRUE, subpool);
+ if (!err)
+ {
+ return svn_error_create(SVN_ERR_TEST_FAILED, 0,
+ "Expected SVN_ERR_FS_CORRUPT, got no error.");
+ }
+ else if (err->apr_err != SVN_ERR_FS_CORRUPT)
+ {
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Expected SVN_ERR_FS_CORRUPT, got a different error.");
+ }
+ else
+ {
+ svn_error_clear(err);
+ }
+
+ /* Post-test cleanup. */
+ SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_delete, &args,
+ TRUE, subpool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
/* The test table. */
@@ -714,5 +912,7 @@ struct svn_test_descriptor_t test_funcs[
"fetch compressed changes from the changes table"),
SVN_TEST_OPTS_PASS(changes_fetch_ordering,
"verify ordered-ness of fetched compressed changes"),
+ SVN_TEST_OPTS_PASS(changes_bad_sequences,
+ "verify that bad change sequences raise errors"),
SVN_TEST_NULL
};
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_fs/fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_fs/fs-pack-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_fs/fs-pack-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_fs/fs-pack-test.c Tue Mar 30 20:57:53 2010
@@ -380,7 +380,7 @@ get_set_revprop_packed_fs(const svn_test
/* Try to get revprop for revision 0. */
SVN_ERR(svn_fs_revision_prop(&prop_value, fs, 0, SVN_PROP_REVISION_AUTHOR, pool));
-
+
/* Try to change revprop for revision 0. */
SVN_ERR(svn_fs_change_rev_prop(fs, 0, SVN_PROP_REVISION_AUTHOR,
svn_string_create("tweaked-author", pool), pool));
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_repos/repos-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_repos/repos-test.c Tue Mar 30 20:57:53 2010
@@ -2152,13 +2152,12 @@ prop_validation_commit_with_revprop(cons
APR_HASH_KEY_STRING,
svn_string_create("plato", pool));
}
- else
- if (strcmp(prop_key, SVN_PROP_REVISION_LOG) != 0)
- {
- apr_hash_set(revprop_table, SVN_PROP_REVISION_LOG,
- APR_HASH_KEY_STRING,
- svn_string_create("revision log", pool));
- }
+ else if (strcmp(prop_key, SVN_PROP_REVISION_LOG) != 0)
+ {
+ apr_hash_set(revprop_table, SVN_PROP_REVISION_LOG,
+ APR_HASH_KEY_STRING,
+ svn_string_create("revision log", pool));
+ }
/* Make an arbitrary change and commit using above values... */
@@ -2213,12 +2212,11 @@ prop_validation(const svn_test_opts_t *o
return svn_error_create(SVN_ERR_TEST_FAILED, err,
"Failed to reject a log with invalid "
"UTF-8");
- else
- if (err->apr_err != SVN_ERR_BAD_PROPERTY_VALUE)
- return svn_error_create(SVN_ERR_TEST_FAILED, err,
- "Expected SVN_ERR_BAD_PROPERTY_VALUE for "
- "a log with invalid UTF-8, "
- "got another error.");
+ else if (err->apr_err != SVN_ERR_BAD_PROPERTY_VALUE)
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Expected SVN_ERR_BAD_PROPERTY_VALUE for "
+ "a log with invalid UTF-8, "
+ "got another error.");
svn_error_clear(err);
@@ -2233,12 +2231,11 @@ prop_validation(const svn_test_opts_t *o
return svn_error_create(SVN_ERR_TEST_FAILED, err,
"Failed to reject a log with inconsistent "
"line ending style");
- else
- if (err->apr_err != SVN_ERR_BAD_PROPERTY_VALUE)
- return svn_error_create(SVN_ERR_TEST_FAILED, err,
- "Expected SVN_ERR_BAD_PROPERTY_VALUE for "
- "a log with inconsistent line ending style, "
- "got another error.");
+ else if (err->apr_err != SVN_ERR_BAD_PROPERTY_VALUE)
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Expected SVN_ERR_BAD_PROPERTY_VALUE for "
+ "a log with inconsistent line ending style, "
+ "got another error.");
svn_error_clear(err);
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/dirent_uri-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/dirent_uri-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/dirent_uri-test.c Tue Mar 30 20:57:53 2010
@@ -1227,6 +1227,9 @@ test_uri_is_canonical(apr_pool_t *pool)
{ "http://hst/", FALSE },
{ "http://HST/", FALSE },
{ "http://HST/FOO/BaR", FALSE },
+ { "http://hst/foo/./bar", FALSE },
+ { "hTTp://hst/foo/bar", FALSE },
+ { "http://hst/foo/bar/", FALSE },
{ "svn+ssh://jens@10.0.1.1", TRUE },
{ "svn+ssh://j.raNDom@HST/BaR", FALSE },
{ "svn+SSH://j.random:jRaY@HST/BaR", FALSE },
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/mergeinfo-test.c Tue Mar 30 20:57:53 2010
@@ -159,7 +159,7 @@ static const char * const mergeinfo_path
"/patch-common::netasq-bpf.c",
"/patch-common_netasq-bpf.c:",
"/:patch:common:netasq:bpf.c",
-
+
"/trunk",
"/trunk",
"/trunk",
@@ -382,7 +382,7 @@ range_to_string(svn_merge_range_t *range
verified (e.g. "svn_rangelist_intersect"), while TYPE is a word
describing what the ranges being examined represent. */
static svn_error_t *
-verify_ranges_match(apr_array_header_t *actual_rangelist,
+verify_ranges_match(const apr_array_header_t *actual_rangelist,
svn_merge_range_t *expected_ranges, int nbr_expected,
const char *func_verified, const char *type,
apr_pool_t *pool)
@@ -479,21 +479,68 @@ static svn_error_t *
test_rangelist_intersect(apr_pool_t *pool)
{
apr_array_header_t *rangelist1, *rangelist2, *intersection;
- svn_merge_range_t expected_intersection[] =
- { {0, 1, TRUE}, {2, 4, TRUE}, {11, 12, TRUE}, {30, 32, TRUE},
+
+ /* Expected intersection when considering inheritance. */
+ svn_merge_range_t intersection_consider_inheritance[] =
+ { {0, 1, TRUE}, {11, 12, TRUE}, {30, 32, FALSE}, {39, 42, TRUE} };
+
+ /* Expected intersection when ignoring inheritance. */
+ svn_merge_range_t intersection_ignore_inheritance[] =
+ { {0, 1, TRUE}, {2, 4, TRUE}, {11, 12, TRUE}, {30, 32, FALSE},
{39, 42, TRUE} };
- SVN_ERR(svn_mergeinfo_parse(&info1, "/trunk: 1-6,12-16,30-32,40-42", pool));
- SVN_ERR(svn_mergeinfo_parse(&info2, "/trunk: 1,3-4,7,9,11-12,31-34,38-44",
+ SVN_ERR(svn_mergeinfo_parse(&info1, "/trunk: 1-6,12-16,30-32*,40-42", pool));
+ SVN_ERR(svn_mergeinfo_parse(&info2, "/trunk: 1,3-4*,7,9,11-12,31-34*,38-44",
pool));
rangelist1 = apr_hash_get(info1, "/trunk", APR_HASH_KEY_STRING);
rangelist2 = apr_hash_get(info2, "/trunk", APR_HASH_KEY_STRING);
+ /* Check the intersection while considering inheritance twice, reversing
+ the order of the rangelist arguments on the second call to
+ svn_rangelist_intersection. The order *should* have no effect on
+ the result -- see http://svn.haxx.se/dev/archive-2010-03/0351.shtml.
+
+ '3-4*' has different inheritance than '1-6', so no intersection is
+ expected. '30-32*' and '31-34*' have the same inheritance, so intersect
+ at '31-32*'. Per the svn_rangelist_intersect API, since both ranges
+ are non-inheritable, so is the result. */
SVN_ERR(svn_rangelist_intersect(&intersection, rangelist1, rangelist2,
TRUE, pool));
- return verify_ranges_match(intersection, expected_intersection, 5,
- "svn_rangelist_intersect", "intersect", pool);
+ SVN_ERR(verify_ranges_match(intersection,
+ intersection_consider_inheritance,
+ 4, "svn_rangelist_intersect", "intersect",
+ pool));
+
+ SVN_ERR(svn_rangelist_intersect(&intersection, rangelist2, rangelist1,
+ TRUE, pool));
+
+ SVN_ERR(verify_ranges_match(intersection,
+ intersection_consider_inheritance,
+ 4, "svn_rangelist_intersect", "intersect",
+ pool));
+
+ /* Check the intersection while ignoring inheritance. The one difference
+ from when we consider inheritance is that '3-4*' and '1-6' now intersect,
+ since we don't care about inheritability, just the start and end ranges.
+ Per the svn_rangelist_intersect API, since only one range is
+ non-inheritable the result is inheritable. */
+ SVN_ERR(svn_rangelist_intersect(&intersection, rangelist1, rangelist2,
+ FALSE, pool));
+
+ SVN_ERR(verify_ranges_match(intersection,
+ intersection_ignore_inheritance,
+ 5, "svn_rangelist_intersect", "intersect",
+ pool));
+
+ SVN_ERR(svn_rangelist_intersect(&intersection, rangelist2, rangelist1,
+ FALSE, pool));
+
+ SVN_ERR(verify_ranges_match(intersection,
+ intersection_ignore_inheritance,
+ 5, "svn_rangelist_intersect", "intersect",
+ pool));
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -880,7 +927,8 @@ test_remove_rangelist(apr_pool_t *pool)
/* Random number seed. */
static apr_uint32_t random_rev_array_seed;
-/* Fill 3/4 of the array with 1s. */
+/* Set a random 3/4-ish of the elements of array REVS[RANDOM_REV_ARRAY_LENGTH]
+ * to TRUE and the rest to FALSE. */
static void
randomly_fill_rev_array(svn_boolean_t *revs)
{
@@ -892,6 +940,8 @@ randomly_fill_rev_array(svn_boolean_t *r
}
}
+/* Set *RANGELIST to a rangelist representing the revisions that are marked
+ * with TRUE in the array REVS[RANDOM_REV_ARRAY_LENGTH]. */
static svn_error_t *
rev_array_to_rangelist(apr_array_header_t **rangelist,
svn_boolean_t *revs,
@@ -946,6 +996,9 @@ test_rangelist_remove_randomly(apr_pool_
randomly_fill_rev_array(first_revs);
randomly_fill_rev_array(second_revs);
+ /* There is no change numbered "r0" */
+ first_revs[0] = FALSE;
+ second_revs[0] = FALSE;
for (j = 0; j < RANDOM_REV_ARRAY_LENGTH; j++)
expected_revs[j] = second_revs[j] && !first_revs[j];
@@ -1001,6 +1054,9 @@ test_rangelist_intersect_randomly(apr_po
randomly_fill_rev_array(first_revs);
randomly_fill_rev_array(second_revs);
+ /* There is no change numbered "r0" */
+ first_revs[0] = FALSE;
+ second_revs[0] = FALSE;
for (j = 0; j < RANDOM_REV_ARRAY_LENGTH; j++)
expected_revs[j] = second_revs[j] && first_revs[j];
@@ -1098,7 +1154,7 @@ test_mergeinfo_to_string(apr_pool_t *poo
APR_HASH_KEY_STRING,
apr_hash_get(info1, "/trunk", APR_HASH_KEY_STRING));
SVN_ERR(svn_mergeinfo_to_string(&output, info2, pool));
-
+
if (svn_string_compare(expected, output) != TRUE)
return fail(pool, "Mergeinfo string not what we expected");
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/stream-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/stream-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/stream-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_subr/stream-test.c Tue Mar 30 20:57:53 2010
@@ -266,20 +266,20 @@ test_stream_range(apr_pool_t *pool)
/* Even when requesting more data than contained in the range,
* we should only receive data from the range. */
- len = strlen(now) + strlen(after);
-
for (i = 0; i < 2; i++)
{
- /* Read the range. */
+ /* Try to read from "Now", up to and past the end of the range. */
+ len = strlen(now) + 1;
SVN_ERR(svn_stream_read(stream, buf, &len));
- if (len > strlen(now))
+ if (len != strlen(now))
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
- "Read past range");
+ "Read past (or not all of) range");
if (strcmp(buf, now))
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
"Unexpected data");
- /* Reading past the end of the range should be impossible. */
+ /* Try to read from the end of the range - should be impossible. */
+ len = 1;
SVN_ERR(svn_stream_read(stream, buf, &len));
if (len != 0)
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/db-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/db-test.c Tue Mar 30 20:57:53 2010
@@ -649,10 +649,6 @@ validate_node(svn_wc__db_t *db,
value = apr_hash_get(props, "p999", APR_HASH_KEY_STRING);
SVN_TEST_ASSERT(value != NULL && strcmp(value->data, "v1") == 0);
- if (status == svn_wc__db_status_normal)
- SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, path, props, FALSE,
- scratch_pool));
-
return SVN_NO_ERROR;
}
@@ -1328,6 +1324,11 @@ test_upgrading_to_f15(apr_pool_t *pool)
static int
detect_work_item(const svn_skel_t *work_item)
{
+ /* Test work items are a list with one integer atom as operation */
+ if (!work_item->children)
+ return -1;
+ work_item = work_item->children;
+
if (!work_item->is_atom || work_item->len != 1)
return -1;
return work_item->data[0] - '0';
@@ -1347,13 +1348,16 @@ test_work_queue(apr_pool_t *pool)
svn_wc__db_openmode_readwrite, pool));
/* Create three work items. */
- work_item = svn_skel__str_atom("0", pool);
+ work_item = svn_skel__make_empty_list(pool);
+ svn_skel__prepend_int(0, work_item, pool);
SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
- work_item = svn_skel__str_atom("1", pool);
+ work_item = svn_skel__make_empty_list(pool);
+ svn_skel__prepend_int(1, work_item, pool);
SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
- work_item = svn_skel__str_atom("2", pool);
+ work_item = svn_skel__make_empty_list(pool);
+ svn_skel__prepend_int(2, work_item, pool);
SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
while (TRUE)
Modified: subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/tree-conflict-data-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/tree-conflict-data-test.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/tree-conflict-data-test.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/tests/libsvn_wc/tree-conflict-data-test.c Tue Mar 30 20:57:53 2010
@@ -74,7 +74,7 @@ test_read_tree_conflict(apr_pool_t *pool
pool));
hi = apr_hash_first(pool, conflicts);
- conflict = svn_apr_hash_index_val(hi);
+ conflict = svn__apr_hash_index_val(hi);
if ((conflict->node_kind != exp_conflict->node_kind) ||
(conflict->action != exp_conflict->action) ||
@@ -120,7 +120,7 @@ test_read_2_tree_conflicts(apr_pool_t *p
pool));
hi = apr_hash_first(pool, conflicts);
- conflict1 = svn_apr_hash_index_val(hi);
+ conflict1 = svn__apr_hash_index_val(hi);
if ((conflict1->node_kind != exp_conflict1->node_kind) ||
(conflict1->action != exp_conflict1->action) ||
(conflict1->reason != exp_conflict1->reason) ||
@@ -129,7 +129,7 @@ test_read_2_tree_conflicts(apr_pool_t *p
return fail(pool, "Tree conflict struct #1 has bad data");
hi = apr_hash_next(hi);
- conflict2 = svn_apr_hash_index_val(hi);
+ conflict2 = svn__apr_hash_index_val(hi);
if ((conflict2->node_kind != exp_conflict2->node_kind) ||
(conflict2->action != exp_conflict2->action) ||
(conflict2->reason != exp_conflict2->reason) ||
Modified: subversion/branches/svn-patch-improvements/tools/dev/analyze-svnlogs.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/tools/dev/analyze-svnlogs.py?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/tools/dev/analyze-svnlogs.py (original)
+++ subversion/branches/svn-patch-improvements/tools/dev/analyze-svnlogs.py Tue Mar 30 20:57:53 2010
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
#
#
# Licensed to the Apache Software Foundation (ASF) under one
Modified: subversion/branches/svn-patch-improvements/tools/dev/unix-build/Makefile.svn
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/tools/dev/unix-build/Makefile.svn?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/tools/dev/unix-build/Makefile.svn (original)
+++ subversion/branches/svn-patch-improvements/tools/dev/unix-build/Makefile.svn Tue Mar 30 20:57:53 2010
@@ -31,6 +31,7 @@
ENABLE_PYTHON_BINDINGS ?= yes
ENABLE_RUBY_BINDINGS ?= yes
ENABLE_PERL_BINDINGS ?= yes
+ENABLE_JAVA_BINDINGS ?= no # they don't build with thread-less APR...
PWD = $(shell pwd)
@@ -614,8 +615,21 @@ else
BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER)
endif
+ifeq ($(ENABLE_JAVA_BINDINGS),yes)
+ JAVAHL_FLAG=--enable-javahl=yes --with-jdk --with-jikes=no \
+ --with-junit=$(PWD)/junit.jar
+else
+ JAVAHL_FLAG=--enable-javahl=no
+endif
+
# configure svn
$(SVN_OBJDIR)/.configured: $(SVN_OBJDIR)/.retrieved
+ @if [ $(ENABLE_JAVA_BINDINGS) = yes ]; then \
+ if [ ! -e $(PWD)/junit.jar ]; then \
+ echo "Please provide $(PWD)/junit.jar"; \
+ exit 1; \
+ fi; \
+ fi
cd $(SVN_SRCDIR) && ./autogen.sh
cd $(svn_builddir) && \
env LDFLAGS="-L$(PREFIX)/neon/lib -L$(PREFIX)/apr/lib" \
@@ -634,7 +648,8 @@ $(SVN_OBJDIR)/.configured: $(SVN_OBJDIR)
--with-berkeley-db="$(BDB_FLAG)" \
--with-sasl="no" \
--with-ruby-sitedir="$(SVN_PREFIX)/lib/ruby/site_ruby" \
- --disable-mod-activation
+ --disable-mod-activation \
+ $(JAVAHL_FLAG)
touch $@
# compile svn
@@ -662,6 +677,10 @@ $(SVN_OBJDIR)/.bindings-compiled: $(SVN_
cd $(svn_builddir) \
&& make swig-pl; \
fi
+ if [ $(ENABLE_JAVA_BINDINGS) = yes ]; then \
+ cd $(svn_builddir) \
+ && make javahl; \
+ fi
touch $@
$(SVN_OBJDIR)/.bindings-installed: $(SVN_OBJDIR)/.bindings-compiled
@@ -680,6 +699,10 @@ $(SVN_OBJDIR)/.bindings-installed: $(SVN
&& perl Makefile.PL PREFIX="$(SVN_PREFIX)" \
&& make install; \
fi
+ if [ $(ENABLE_JAVA_BINDINGS) = yes ]; then \
+ cd $(svn_builddir) \
+ && make install-javahl; \
+ fi
touch $@
# run svn regression tests
@@ -786,8 +809,9 @@ svn-check-svn:
cd $(svn_builddir) && make check FS_TYPE=bdb BASE_URL=svn://127.0.0.1
$(SVNSERVE_STOP_CMD)
-.PHONY: svn-check-swig-pl svn-check-swig-py svn-check-swig-rb
-svn-check-swig: svn-check-swig-pl svn-check-swig-py svn-check-swig-rb
+.PHONY: svn-check-swig-pl svn-check-swig-py svn-check-swig-rb svn-check-javahl
+svn-check-bindings: svn-check-swig-pl svn-check-swig-py svn-check-swig-rb \
+ svn-check-javahl
RUBYLIB=$(SVN_PREFIX)/lib/ruby/site_ruby$(shell grep \
^svn_cv_ruby_sitedir_archsuffix $(svn_builddir)/config.log | \
@@ -803,5 +827,9 @@ svn-check-swig-rb:
env RUBYLIB=$(RUBYLIB) \
LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
ruby run-test.rb --verbose=verbose
+svn-check-javahl:
+ cd $(svn_builddir) && \
+ env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
+ make check-javahl
-svn-check: svn-check-local svn-check-svn svn-check-neon svn-check-serf svn-check-swig
+svn-check: svn-check-local svn-check-svn svn-check-neon svn-check-serf svn-check-bindings
Modified: subversion/branches/svn-patch-improvements/tools/dist/construct-rolling-environment.sh
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/tools/dist/construct-rolling-environment.sh?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/tools/dist/construct-rolling-environment.sh (original)
+++ subversion/branches/svn-patch-improvements/tools/dist/construct-rolling-environment.sh Tue Mar 30 20:57:53 2010
@@ -29,7 +29,7 @@ APR=apr-1.3.8
APR_UTIL=apr-util-1.3.9
NEON=neon-0.29.0
SERF=serf-0.3.0
-ZLIB=zlib-1.2.3
+ZLIB=zlib-1.2.4
SQLITE_VERSION=3.6.20
SQLITE=sqlite-amalgamation-$SQLITE_VERSION
Modified: subversion/branches/svn-patch-improvements/tools/dist/dist.sh
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/tools/dist/dist.sh?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/tools/dist/dist.sh (original)
+++ subversion/branches/svn-patch-improvements/tools/dist/dist.sh Tue Mar 30 20:57:53 2010
@@ -238,7 +238,12 @@ rm -rf "$DISTPATH/contrib"
rm -rf "$DISTPATH/packages"
# Check for a recent enough Python
-PYTHON="`$DISTPATH/build/find_python.sh`"
+# Instead of attempting to deal with various line ending issues, just export
+# the find_python script manually.
+${svn:-svn} export -q -r "$REVISION" \
+ "http://svn.apache.org/repos/asf/subversion/$REPOS_PATH/build/find_python.sh" \
+ --username none --password none "$DIST_SANDBOX/find_python.sh"
+PYTHON="`$DIST_SANDBOX/find_python.sh`"
if test -z "$PYTHON"; then
echo "Python 2.4 or later is required to run dist.sh"
echo "If you have a suitable Python installed, but not on the"
Modified: subversion/branches/svn-patch-improvements/tools/server-side/svn-rep-sharing-stats.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/tools/server-side/svn-rep-sharing-stats.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/tools/server-side/svn-rep-sharing-stats.c (original)
+++ subversion/branches/svn-patch-improvements/tools/server-side/svn-rep-sharing-stats.c Tue Mar 30 20:57:53 2010
@@ -275,8 +275,8 @@ process_one_revision(svn_fs_t *fs,
node_revision_t *node_rev;
- path = svn_apr_hash_index_key(hi);
- change = svn_apr_hash_index_val(hi);
+ path = svn__apr_hash_index_key(hi);
+ change = svn__apr_hash_index_val(hi);
if (! quiet)
SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
"processing r%ld:%s\n", revnum, path));
@@ -334,8 +334,8 @@ pretty_print(const char *name,
SVN_ERR(cancel_func(NULL));
- key = svn_apr_hash_index_key(hi);
- value = svn_apr_hash_index_val(hi);
+ key = svn__apr_hash_index_key(hi);
+ value = svn__apr_hash_index_val(hi);
SVN_ERR(svn_cmdline_printf(scratch_pool, "%s %" APR_UINT64_T_FMT " %s\n",
name, value->refcount,
svn_checksum_to_cstring_display(