You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/01/21 17:22:22 UTC

svn commit: r1653578 [18/18] - in /subversion/branches/pin-externals: ./ notes/ subversion/bindings/swig/ subversion/bindings/swig/include/ subversion/bindings/swig/perl/native/ subversion/bindings/swig/perl/native/t/ subversion/bindings/swig/python/te...

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/patch_tests.py?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/patch_tests.py Wed Jan 21 16:22:19 2015
@@ -4689,6 +4689,757 @@ def patch_git_rename(sbox):
                                        expected_output, expected_disk,
                                        expected_status, expected_skip)
 
+@Issue(4533)
+def patch_hunk_avoid_reorder(sbox):
+  """avoid reordering hunks"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_append('A/mu',
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+                     'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+                     'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     'MM\n' 'NN\n' 'OO\n' 'PP\n' 'QQ\n' 'RR\n'
+                     'SS\n' 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n'
+                     'YY\n' 'ZZ\n', truncate=True)
+  sbox.simple_commit()
+
+  # two hunks, first matches at offset +18, second matches at both -13
+  # and +18 but we want the second match as it is after the first
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 1)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -13,6 +13,7 @@\n",
+    " MM\n",
+    " NN\n",
+    " OO\n",
+    "+11111\n",
+    " PP\n",
+    " QQ\n",
+    " RR\n",
+    "@@ -20,6 +20,7 @@\n",
+    " TT\n",
+    " UU\n",
+    " VV\n",
+    "+22222\n",
+    " WW\n",
+    " XX\n",
+    " YY\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+    '>         applied hunk @@ -20,6 +20,7 @@ with offset 18\n'
+    ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+                     'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+                     'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+                     'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+                     'YY\n' 'ZZ\n')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  sbox.simple_revert('A/mu')
+
+  # change patch so second hunk matches at both -14 and +17, we still
+  # want the second match
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 1)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -13,6 +13,7 @@\n",
+    " MM\n",
+    " NN\n",
+    " OO\n",
+    "+11111\n",
+    " PP\n",
+    " QQ\n",
+    " RR\n",
+    "@@ -21,6 +21,7 @@\n",
+    " TT\n",
+    " UU\n",
+    " VV\n",
+    "+22222\n",
+    " WW\n",
+    " XX\n",
+    " YY\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+    '>         applied hunk @@ -21,6 +21,7 @@ with offset 17\n'
+    ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+                     'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+                     'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+                     'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+                     'YY\n' 'ZZ\n')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  sbox.simple_revert('A/mu')
+
+@Issue(4533)
+def patch_hunk_avoid_reorder2(sbox):
+  """avoid reordering hunks 2"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_append('A/mu',
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+                     'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+                     'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     'MM\n' 'NN\n' 'OO\n' 'PP\n' 'QQ\n' 'RR\n'
+                     'SS\n' 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n'
+                     'YY\n' 'ZZ\n', truncate=True)
+  sbox.simple_commit()
+
+  # two hunks, first matches at offset +18, second matches at both -13
+  # change patch so second hunk matches at both -12 and +19, we still
+  # want the second match
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 1)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -13,6 +13,7 @@\n",
+    " MM\n",
+    " NN\n",
+    " OO\n",
+    "+11111\n",
+    " PP\n",
+    " QQ\n",
+    " RR\n",
+    "@@ -19,6 +19,7 @@\n",
+    " TT\n",
+    " UU\n",
+    " VV\n",
+    "+22222\n",
+    " WW\n",
+    " XX\n",
+    " YY\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+    '>         applied hunk @@ -19,6 +19,7 @@ with offset 19\n'
+    ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+                     'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+                     'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     '33333\n' '33333\n' '33333\n'
+                     'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+                     'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+                     'YY\n' 'ZZ\n')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+@Issue(4533)
+def patch_hunk_reorder(sbox):
+  """hunks that reorder"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_append('A/mu',
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n' 'GG\n'
+                     'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n' 'MM\n' 'NN\n',
+                     truncate=True)
+  sbox.simple_commit()
+
+  # Two hunks match in opposite order
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 1)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -2,6 +2,7 @@\n",
+    " II\n",
+    " JJ\n",
+    " KK\n",
+    "+11111\n",
+    " LL\n",
+    " MM\n",
+    " NN\n",
+    "@@ -9,6 +10,7 @@\n",
+    " BB\n",
+    " CC\n",
+    " DD\n",
+    "+22222\n",
+    " EE\n",
+    " FF\n",
+    " GG\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -9,6 +10,7 @@ with offset -7\n',
+    '>         applied hunk @@ -2,6 +2,7 @@ with offset 7\n',
+    ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' '22222\n' 'EE\n' 'FF\n' 'GG\n'
+                     'HH\n' 'II\n' 'JJ\n' 'KK\n' '11111\n' 'LL\n' 'MM\n' 'NN\n')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # In the following case the reordered hunk2 is smaller offset
+  # magnitude than hunk2 at the end and the reorder is preferred.
+  sbox.simple_revert('A/mu')
+  sbox.simple_append('A/mu',
+                     'x\n' * 2  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 2  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10  +
+                     '1\n' '2\n' '3\n' 'hunk1\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 100  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n',
+                     truncate=True)
+  sbox.simple_commit()
+
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 2)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -28,7 +28,7 @@\n",
+    " 1\n",
+    " 2\n",
+    " 3\n",
+    "-hunk1\n",
+    "+hunk1-mod\n",
+    " 4\n",
+    " 5\n",
+    " 6\n",
+    "@@ -44,7 +44,7 @@\n",
+    " 1\n",
+    " 2\n",
+    " 3\n",
+    "-hunk2\n",
+    "+hunk2-mod\n",
+    " 4\n",
+    " 5\n",
+    " 6\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -44,7 +44,7 @@ with offset -32\n',
+    '>         applied hunk @@ -28,7 +28,7 @@ with offset 1\n',
+    ]
+  expected_disk.tweak('A/mu', contents=
+                      'x\n' * 2  +
+                      '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                      'x\n' * 2  +
+                      '1\n' '2\n' '3\n' 'hunk2-mod\n' '4\n' '5\n' '6\n' +
+                      'x\n' * 10  +
+                      '1\n' '2\n' '3\n' 'hunk1-mod\n' '4\n' '5\n' '6\n' +
+                      'x\n' * 100  +
+                      '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n')
+
+  expected_status.tweak('A/mu', status='M ', wc_rev=3)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+  sbox.simple_revert('A/mu')
+
+  # In this case the reordered hunk2 is further than hunk2 at the end
+  # and the reordered is not preferred.
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 2)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -28,7 +28,7 @@\n",
+    " 1\n",
+    " 2\n",
+    " 3\n",
+    "-hunk1\n",
+    "+hunk1-mod\n",
+    " 4\n",
+    " 5\n",
+    " 6\n",
+    "@@ -110,7 +110,7 @@\n",
+    " 1\n",
+    " 2\n",
+    " 3\n",
+    "-hunk2\n",
+    "+hunk2-mod\n",
+    " 4\n",
+    " 5\n",
+    " 6\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -28,7 +28,7 @@ with offset 1\n',
+    '>         applied hunk @@ -110,7 +110,7 @@ with offset 26\n',
+    ]
+  expected_disk.tweak('A/mu', contents=
+                      'x\n' * 2  +
+                      '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                      'x\n' * 2  +
+                      '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                      'x\n' * 10  +
+                      '1\n' '2\n' '3\n' 'hunk1-mod\n' '4\n' '5\n' '6\n' +
+                      'x\n' * 100  +
+                      '1\n' '2\n' '3\n' 'hunk2-mod\n' '4\n' '5\n' '6\n')
+
+  expected_status.tweak('A/mu', status='M ', wc_rev=3)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+@XFail()
+def patch_hunk_overlap(sbox):
+  """hunks that overlap"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_append('A/mu',
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+                     'GG\n' 'HH\n' 'II\n', truncate=True)
+  sbox.simple_commit()
+
+  # Two hunks that overlap when applied, GNU patch can apply both hunks.
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 1)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -2,6 +2,7 @@\n",
+    " BB\n",
+    " CC\n",
+    " DD\n",
+    "+11111\n",
+    " EE\n",
+    " FF\n",
+    " GG\n",
+    "@@ -9,6 +10,7 @@\n",
+    " DD\n",
+    " EE\n",
+    " FF\n",
+    "+22222\n",
+    " GG\n",
+    " HH\n",
+    " II\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -9,6 +10,7 @@ with offset -5\n',
+    ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=
+                     'AA\n' 'BB\n' 'CC\n' 'DD\n' '11111\n' 'EE\n' 'FF\n'
+                     '22222\n' 'GG\n' 'HH\n' 'II\n')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+def patch_delete_modified(sbox):
+  """patch delete modified"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # A patch that deletes beta.
+  unidiff_patch = [
+    "Index: A/B/E/beta\n",
+    "===================================================================\n",
+    "--- A/B/E/beta	(revision 1)\n",
+    "+++ A/B/E/beta	(working copy)\n",
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'beta'.\n",
+    ]
+
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  # First application deletes beta
+  expected_output = [
+    'D         %s\n' % sbox.ospath('A/B/E/beta'),
+    ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/beta')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/B/E/beta', status='D ')
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # Second application skips
+  expected_output = [
+    'Skipped \'%s\'\n' % sbox.ospath('A/B/E/beta'),
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
+  expected_skip = wc.State('', {
+    sbox.ospath('A/B/E/beta') :  Item(verb='Skipped'),
+  })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # Third application, with file present even though state is 'D', also skips
+  sbox.simple_append('A/B/E/beta', 'Modified', truncate=True)
+  expected_disk.add({'A/B/E/beta' : Item(contents='Modified')})
+  expected_output = [
+    'Skipped \'%s\'\n' % sbox.ospath('A/B/E/beta'),
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
+  expected_skip = wc.State('', {
+    sbox.ospath('A/B/E/beta') :  Item(verb='Skipped'),
+  })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # Revert and modify beta, fourth application gives a text conflict.
+  sbox.simple_revert('A/B/E/beta')
+  sbox.simple_append('A/B/E/beta', 'Modified', truncate=True)
+
+  expected_output = [
+    'C         %s\n' % sbox.ospath('A/B/E/beta'),
+    '>         rejected hunk @@ -1,1 +0,0 @@\n',
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+  expected_skip = wc.State('', { })
+  reject_file_contents = [
+    "--- A/B/E/beta\n",
+    "+++ A/B/E/beta\n",
+    "@@ -1,1 +0,0 @@\n",
+    "-This is the file 'beta'.\n",
+  ]
+  expected_disk.add({'A/B/E/beta.svnpatch.rej'
+                     : Item(contents=''.join(reject_file_contents))
+                     })
+  expected_status.tweak('A/B/E/beta', status='M ')
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+def patch_closest(sbox):
+  "find closest hunk"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  unidiff_patch = [
+    "Index: A/mu\n"
+    "===================================================================\n",
+    "--- A/mu\t(revision 2)\n",
+    "+++ A/mu\t(working copy)\n",
+    "@@ -47,7 +47,7 @@\n",
+    " 1\n",
+    " 2\n",
+    " 3\n",
+    "-hunk1\n",
+    "+hunk1-mod\n",
+    " 4\n",
+    " 5\n",
+    " 6\n",
+    "@@ -66,7 +66,7 @@\n",
+    " 1\n",
+    " 2\n",
+    " 3\n",
+    "-rejected-hunk2-\n",
+    "+rejected-hunk2-mod\n",
+    " 4\n",
+    " 5\n",
+    " 6\n",
+    "@@ -180,7 +180,7 @@\n",
+    " 1\n",
+    " 2\n",
+    " 3\n",
+    "-hunk3\n",
+    "+hunk3-mod\n",
+    " 4\n",
+    " 5\n",
+    " 6\n",
+    ]
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  # Previous offset for hunk3 is +4, hunk3 matches at relative offsets
+  # of -19 and +18, prefer +18 gives final offset +22
+  sbox.simple_append('A/mu',
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk1\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 30  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10,
+                     truncate=True)
+  sbox.simple_commit()
+
+  expected_output = [
+    'C         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
+    '>         applied hunk @@ -180,7 +180,7 @@ with offset 22\n',
+    '>         rejected hunk @@ -66,7 +66,7 @@\n',
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({'A/mu.svnpatch.rej' : Item(contents=
+    "--- A/mu\n" +
+    "+++ A/mu\n" +
+    "@@ -66,7 +66,7 @@\n" +
+    " 1\n" +
+    " 2\n" +
+    " 3\n" +
+    "-rejected-hunk2-\n" +
+    "+rejected-hunk2-mod\n" +
+    " 4\n" +
+    " 5\n" +
+    " 6\n")})
+  expected_disk.tweak('A/mu', contents=
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk1-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 30  +
+                     '1\n' '2\n' '3\n' 'hunk3-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10)
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # Previous offset for hunk3 is +4, hunk3 matches at relative offsets
+  # of -19 and +20, prefer -19 gives final offset -15
+  sbox.simple_append('A/mu',
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk1\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 32  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10,
+                     truncate=True)
+  sbox.simple_commit()
+
+  expected_output = [
+    'C         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
+    '>         applied hunk @@ -180,7 +180,7 @@ with offset -15\n',
+    '>         rejected hunk @@ -66,7 +66,7 @@\n',
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+  expected_disk.tweak('A/mu', contents=
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk1-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk3-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 32  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10)
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=3)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # Previous offset for hunk3 is +4, hunk3 matches at relative offsets
+  # of -19 and +19, prefer -19 gives final offset -15
+  sbox.simple_append('A/mu',
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk1\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 31  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10,
+                     truncate=True)
+  sbox.simple_commit()
+
+  expected_output = [
+    'C         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
+    '>         applied hunk @@ -180,7 +180,7 @@ with offset -15\n',
+    '>         rejected hunk @@ -66,7 +66,7 @@\n',
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+  expected_disk.tweak('A/mu', contents=
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk1-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk3-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 31  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10)
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=4)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # Previous offset for hunk3 is +4, hunk3 matches at relative offsets
+  # of +173 and -173, prefer +173 gives final offset +177
+  sbox.simple_append('A/mu',
+                     'x\n' * 10  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 33 +
+                     '1\n' '2\n' '3\n' 'hunk1\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 242  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10,
+                     truncate=True)
+  sbox.simple_commit()
+
+  expected_output = [
+    'C         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
+    '>         applied hunk @@ -180,7 +180,7 @@ with offset 177\n',
+    '>         rejected hunk @@ -66,7 +66,7 @@\n',
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+  expected_disk.tweak('A/mu', contents=
+                     'x\n' * 10  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 33  +
+                     '1\n' '2\n' '3\n' 'hunk1-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 242  +
+                     '1\n' '2\n' '3\n' 'hunk3-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10)
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=5)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+  # Previous offset for hunk3 is +4, hunk3 matches at relative offsets
+  # of +174 and -173, prefer -173 gives final offset -169
+  sbox.simple_append('A/mu',
+                     'x\n' * 10  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 33 +
+                     '1\n' '2\n' '3\n' 'hunk1\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 243  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10,
+                     truncate=True)
+  sbox.simple_commit()
+
+  expected_output = [
+    'C         %s\n' % sbox.ospath('A/mu'),
+    '>         applied hunk @@ -180,7 +180,7 @@ with offset -169\n',
+    '>         applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
+    '>         rejected hunk @@ -66,7 +66,7 @@\n',
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+  expected_disk.tweak('A/mu', contents=
+                     'x\n' * 10  +
+                     '1\n' '2\n' '3\n' 'hunk3-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 33  +
+                     '1\n' '2\n' '3\n' 'hunk1-mod\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 50  +
+                     '1\n' '2\n' '3\n' 'hunk2\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 243  +
+                     '1\n' '2\n' '3\n' 'hunk3\n' '4\n' '5\n' '6\n' +
+                     'x\n' * 10)
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=6)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
 ########################################################################
 #Run the tests
 
@@ -4741,7 +5492,13 @@ test_list = [ None,
               patch_apply_no_fuz,
               patch_lacking_trailing_eol_on_context,
               patch_with_custom_keywords,
-              patch_git_rename
+              patch_git_rename,
+              patch_hunk_avoid_reorder,
+              patch_hunk_avoid_reorder2,
+              patch_hunk_reorder,
+              patch_hunk_overlap,
+              patch_delete_modified,
+              patch_closest,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py Wed Jan 21 16:22:19 2015
@@ -60,15 +60,10 @@ def filter_and_return_output(dump, bufsi
     dump = [ dump ]
 
   # Does the caller want the stderr?
-  try:
-      varargs.index('-q')
+  if '-q' in varargs or '--quiet' in varargs:
       expected_errput = None # Stderr with -q or --quiet is a real error!
-  except:
-      try:
-          varargs.index('--quiet')
-          expected_errput = None
-      except:
-          expected_errput = svntest.verify.AnyOutput
+  else:
+      expected_errput = svntest.verify.AnyOutput
   ## TODO: Should we handle exit_code?
   exit_code, output, errput = svntest.main.run_command_stdin(
     svntest.main.svndumpfilter_binary, expected_errput, bufsize, True,
@@ -323,9 +318,9 @@ def filter_mergeinfo_revs_outside_of_dum
   # --skip-missing-merge-soruces which should strip out any revisions < 6.
   # Then we'll load the filtered result into an empty repository.  This
   # should offset the incoming mergeinfo by -5.  In addition, any mergeinfo
-  # revisions that are adjusted to r1 should be removed because that implies
-  # a merge of -r0:1, which is impossible.  The resulting mergeinfo should
-  # look like this:
+  # referring to the initial revision in the dump file (r6) should be
+  # removed because the change it refers to (r5:6) is not wholly within the
+  # dumpfile.  The resulting mergeinfo should look like this:
   #
   #   Properties on 'branches/B1':
   #     svn:mergeinfo

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py Wed Jan 21 16:22:19 2015
@@ -70,27 +70,28 @@ def build_repos(sbox):
   # Create an empty repository.
   svntest.main.create_repos(sbox.repo_dir)
 
-def compare_repos_dumps(svnrdump_sbox, svnadmin_dumpfile):
-  """Compare two dumpfiles, one created from SVNRDUMP_SBOX, and other given
-  by SVNADMIN_DUMPFILE.  The dumpfiles do not need to match linewise, as the
-  SVNADMIN_DUMPFILE contents will first be loaded into a repository and then
+def compare_repos_dumps(sbox, other_dumpfile,
+                        bypass_prop_validation=False):
+  """Compare two dumpfiles, one created from SBOX, and other given
+  by OTHER_DUMPFILE.  The dumpfiles do not need to match linewise, as the
+  OTHER_DUMPFILE contents will first be loaded into a repository and then
   re-dumped to do the match, which should generate the same dumpfile as
-  dumping SVNRDUMP_SBOX."""
+  dumping SBOX."""
 
-  svnrdump_contents = svntest.actions.run_and_verify_dump(
-                                                    svnrdump_sbox.repo_dir)
 
-  svnadmin_sbox = svnrdump_sbox.clone_dependent()
-  svntest.main.safe_rmtree(svnadmin_sbox.repo_dir)
-  svntest.main.create_repos(svnadmin_sbox.repo_dir)
+  sbox_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir)
 
-  svntest.actions.run_and_verify_load(svnadmin_sbox.repo_dir, svnadmin_dumpfile)
-
-  svnadmin_contents = svntest.actions.run_and_verify_dump(
-                                                    svnadmin_sbox.repo_dir)
+  # Load and dump the other dumpfile (using svnadmin)
+  other_sbox = sbox.clone_dependent()
+  svntest.main.safe_rmtree(other_sbox.repo_dir)
+  svntest.main.create_repos(other_sbox.repo_dir)
+  svntest.actions.run_and_verify_load(other_sbox.repo_dir, other_dumpfile,
+                                      bypass_prop_validation)
+  other_dumpfile = svntest.actions.run_and_verify_dump(other_sbox.repo_dir)
 
+  ### This call kind-of assumes EXPECTED is first and ACTUAL is second.
   svntest.verify.compare_dump_files(
-    "Dump files", "DUMP", svnadmin_contents, svnrdump_contents)
+    "Dump files", "DUMP", other_dumpfile, sbox_dumpfile)
 
 def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None,
                   subdir = None, bypass_prop_validation = False,
@@ -111,11 +112,10 @@ def run_dump_test(sbox, dumpfile_name, e
 
   # Load the specified dump file into the sbox repository using
   # svnadmin load
-  svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
+  original_dumpfile = open(os.path.join(svnrdump_tests_dir,
                                         dumpfile_name),
                            'rb').readlines()
-
-  svntest.actions.run_and_verify_load(sbox.repo_dir, svnadmin_dumpfile,
+  svntest.actions.run_and_verify_load(sbox.repo_dir, original_dumpfile,
                                       bypass_prop_validation)
 
   repo_url = sbox.repo_url
@@ -129,28 +129,29 @@ def run_dump_test(sbox, dumpfile_name, e
                                               [], 0, *opts)
 
   if expected_dumpfile_name:
-    svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
+    expected_dumpfile = open(os.path.join(svnrdump_tests_dir,
                                           expected_dumpfile_name),
                              'rb').readlines()
     # Compare the output from stdout
     if ignore_base_checksums:
-      svnadmin_dumpfile = [l for l in svnadmin_dumpfile
+      expected_dumpfile = [l for l in expected_dumpfile
                                     if not l.startswith('Text-delta-base-md5')]
       svnrdump_dumpfile = [l for l in svnrdump_dumpfile
                                     if not l.startswith('Text-delta-base-md5')]
-    svnadmin_dumpfile = [l for l in svnadmin_dumpfile
+    expected_dumpfile = [l for l in expected_dumpfile
                                   if not mismatched_headers_re.match(l)]
     svnrdump_dumpfile = [l for l in svnrdump_dumpfile
                                   if not mismatched_headers_re.match(l)]
 
-    svnadmin_dumpfile = svntest.verify.UnorderedOutput(svnadmin_dumpfile)
+    expected_dumpfile = svntest.verify.UnorderedOutput(expected_dumpfile)
 
     svntest.verify.compare_and_display_lines(
-      "Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile,
+      "Dump files", "DUMP", expected_dumpfile, svnrdump_dumpfile,
       None)
 
   else:
-    compare_repos_dumps(sbox, svnadmin_dumpfile)
+    # The expected dumpfile is the result of dumping SBOX.
+    compare_repos_dumps(sbox, svnrdump_dumpfile, bypass_prop_validation)
 
 def run_load_test(sbox, dumpfile_name, expected_dumpfile_name = None,
                   expect_deltas = True):
@@ -169,36 +170,37 @@ def run_load_test(sbox, dumpfile_name, e
 
   # Load the specified dump file into the sbox repository using
   # svnrdump load
-  svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir,
+  original_dumpfile = open(os.path.join(svnrdump_tests_dir,
                                         dumpfile_name),
                            'rb').readlines()
 
   # Set the UUID of the sbox repository to the UUID specified in the
   # dumpfile ### RA layer doesn't have a set_uuid functionality
-  uuid = svnrdump_dumpfile[2].split(' ')[1][:-1]
+  uuid = original_dumpfile[2].split(' ')[1][:-1]
   svntest.actions.run_and_verify_svnadmin2("Setting UUID", None, None, 0,
                                            'setuuid', sbox.repo_dir,
                                            uuid)
 
-  svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile,
+  svntest.actions.run_and_verify_svnrdump(original_dumpfile,
                                           svntest.verify.AnyOutput,
                                           [], 0, 'load', sbox.repo_url)
 
-  # Create a dump file using svnadmin dump
-  svnadmin_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir,
+  # Re-dump the rdump-loaded repo using svnadmin dump
+  resulted_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir,
                                                           expect_deltas)
 
   if expected_dumpfile_name:
-    svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir,
+    expected_dumpfile = open(os.path.join(svnrdump_tests_dir,
                                           expected_dumpfile_name),
                              'rb').readlines()
 
     # Compare the output from stdout
     svntest.verify.compare_and_display_lines(
-      "Dump files", "DUMP", svnrdump_dumpfile, svnadmin_dumpfile)
+      "Dump files", "DUMP", expected_dumpfile, resulted_dumpfile)
 
   else:
-    compare_repos_dumps(sbox, svnrdump_dumpfile)
+    expected_dumpfile = original_dumpfile
+    compare_repos_dumps(sbox, expected_dumpfile)
 
 ######################################################################
 # Tests
@@ -799,6 +801,129 @@ def load_prop_change_in_non_deltas_dump(
                                           [], [], 0,
                                           '-q', 'load', sbox.repo_url)
 
+#----------------------------------------------------------------------
+
+@Issue(4476)
+def dump_mergeinfo_contains_r0(sbox):
+  "dump: mergeinfo that contains r0"
+  ### We pass the original dump file name as 'expected_dumpfile_name' because
+  ### run_dump_test is currently broken when we don't.
+  run_dump_test(sbox, "mergeinfo-contains-r0.dump",
+                bypass_prop_validation=True)
+
+#----------------------------------------------------------------------
+
+@XFail()
+@Issue(4476)
+def load_mergeinfo_contains_r0(sbox):
+  "load: mergeinfo that contains r0"
+  run_load_test(sbox, "mergeinfo-contains-r0.dump",
+                expected_dumpfile_name="mergeinfo-contains-r0.expected.dump")
+
+#----------------------------------------------------------------------
+
+# Regression test for issue 4551 "svnrdump load commits wrong properties,
+# or fails, on a non-deltas dumpfile". In this test, the copy source does
+# not exist and the failure mode is to error out.
+@XFail()
+@Issue(4551)
+def load_non_deltas_copy_with_props(sbox):
+  "load non-deltas copy with props"
+  sbox.build()
+
+  # Set props on a file and on a dir and on a child of the dir to be copied
+  sbox.simple_propset('p', 'v', 'A/mu', 'A/B', 'A/B/E')
+  sbox.simple_commit()
+  sbox.simple_update()  # avoid mixed-rev
+
+  # Case (1): Copy file/dir, not replacing anything; the copy target path
+  # at (new rev - 1) does not exist
+  sbox.simple_copy('A/mu@2', 'A/mu_COPY')
+  sbox.simple_copy('A/B@2', 'A/B_COPY')
+  # On the copy, delete a prop
+  sbox.simple_propdel('p', 'A/mu_COPY', 'A/B_COPY', 'A/B_COPY/E')
+
+  sbox.simple_commit()
+
+  # Dump with 'svnadmin' (non-deltas mode)
+  dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
+
+  # Load with 'svnrdump'
+  new_repo_dir, new_repo_url = sbox.add_repo_path('new_repo')
+  svntest.main.create_repos(new_repo_dir)
+  svntest.actions.enable_revprop_changes(new_repo_dir)
+  svntest.actions.run_and_verify_svnrdump(dumpfile,
+                                          svntest.verify.AnyOutput,
+                                          [], 0, 'load', new_repo_url)
+  # For regression test purposes, all we require is that the 'load'
+  # doesn't throw an error
+
+# Regression test for issue 4551 "svnrdump load commits wrong properties,
+# or fails, on a non-deltas dumpfile". In this test, the copy source does
+# exist and the failure mode is to fail to delete a property.
+@XFail()
+@Issue(4551)
+def load_non_deltas_replace_copy_with_props(sbox):
+  "load non-deltas replace&copy with props"
+  sbox.build()
+
+  # Set props on a file and on a dir
+  sbox.simple_propset('p', 'v', 'A/mu', 'A/B')
+  sbox.simple_commit()
+  sbox.simple_update()  # avoid mixed-rev
+
+  # Case (2): Copy file/dir, replacing something; the copy target path
+  # at (new rev - 1) exists and has no property named 'p'
+  sbox.simple_rm('A/D/gamma', 'A/C')
+  sbox.simple_copy('A/mu@2', 'A/D/gamma')
+  sbox.simple_copy('A/B@2', 'A/C')
+  # On the copy, delete a prop that isn't present on the replaced node
+  sbox.simple_propdel('p', 'A/D/gamma', 'A/C')
+
+  sbox.simple_commit()
+
+  # Dump with 'svnadmin' (non-deltas mode)
+  dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
+
+  # Load with 'svnrdump'
+  new_repo_dir, new_repo_url = sbox.add_repo_path('new_repo')
+  svntest.main.create_repos(new_repo_dir)
+  svntest.actions.enable_revprop_changes(new_repo_dir)
+  svntest.actions.run_and_verify_svnrdump(dumpfile,
+                                          svntest.verify.AnyOutput,
+                                          [], 0, 'load', new_repo_url)
+
+  # Check that property 'p' really was deleted on each copied node
+  for tgt_path in ['A/D/gamma', 'A/C']:
+    _, out, _ = svntest.main.run_svn(None, 'proplist',
+                                     new_repo_url + '/' + tgt_path)
+    expected = []
+    actual = out[1:]
+    svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual)
+
+# Regression test for issue #4552 "svnrdump writes duplicate headers for a
+# replace-with-copy". 'svnrdump dump' wrote the Node-path and Node-kind
+# headers twice for the 'delete' record of a replace-with-copy.
+@Issue(4552)
+def dump_replace_with_copy(sbox):
+  "dump replace with copy"
+  sbox.build()
+
+  # Copy file/dir, replacing something
+  sbox.simple_rm('A/D/gamma', 'A/C')
+  sbox.simple_copy('A/mu@1', 'A/D/gamma')
+  sbox.simple_copy('A/B@1', 'A/C')
+  sbox.simple_commit()
+
+  # Dump with 'svnrdump'
+  dumpfile = svntest.actions.run_and_verify_svnrdump(
+                               None, svntest.verify.AnyOutput, [], 0,
+                               'dump', '--quiet', '--incremental', '-r2',
+                               sbox.repo_url)
+
+  # Check the 'delete' record headers: expect this parse to fail if headers
+  # are duplicated
+  svntest.verify.DumpParser(dumpfile).parse()
 
 ########################################################################
 # Run the tests
@@ -855,6 +980,11 @@ test_list = [ None,
               only_trunk_range_dump,
               only_trunk_A_range_dump,
               load_prop_change_in_non_deltas_dump,
+              dump_mergeinfo_contains_r0,
+              load_mergeinfo_contains_r0,
+              load_non_deltas_copy_with_props,
+              load_non_deltas_replace_copy_with_props,
+              dump_replace_with_copy,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py Wed Jan 21 16:22:19 2015
@@ -209,8 +209,12 @@ def setup_and_sync(sbox, dump_file_conte
 
   return dest_sbox
 
-def verify_mirror(dest_sbox, src_sbox):
-  """Compare the contents of the DEST_SBOX repository with EXP_DUMP_FILE_CONTENTS."""
+def verify_mirror(dest_sbox, exp_dump_file_contents):
+  """Compare the contents of the mirror repository in DEST_SBOX with
+     EXP_DUMP_FILE_CONTENTS, by comparing the parsed dump stream content.
+
+     First remove svnsync rev-props from the DEST_SBOX repository.
+  """
 
   # Remove some SVNSync-specific housekeeping properties from the
   # mirror repository in preparation for the comparison dump.
@@ -222,10 +226,9 @@ def verify_mirror(dest_sbox, src_sbox):
 
   # Create a dump file from the mirror repository.
   dest_dump = svntest.actions.run_and_verify_dump(dest_sbox.repo_dir)
-  src_dump = svntest.actions.run_and_verify_dump(src_sbox.repo_dir)
 
   svntest.verify.compare_dump_files(
-    "Dump files", "DUMP", src_dump, dest_dump)
+    "Dump files", "DUMP", exp_dump_file_contents, dest_dump)
 
 def run_test(sbox, dump_file_name, subdir=None, exp_dump_file_name=None,
              bypass_prop_validation=False, source_prop_encoding=None,
@@ -251,16 +254,12 @@ or another dump file."""
   # dump file (used to create the master repository) or another specified dump
   # file.
   if exp_dump_file_name:
-    build_repos(sbox)
-    svntest.actions.run_and_verify_load(sbox.repo_dir,
-                                        open(os.path.join(svnsync_tests_dir,
-                                                          exp_dump_file_name),
-                                             'rb').readlines())
-    src_sbox = sbox
+    exp_dump_file_contents = open(os.path.join(svnsync_tests_dir,
+                                  exp_dump_file_name), 'rb').readlines()
   else:
-    src_sbox = sbox
+    exp_dump_file_contents = master_dumpfile_contents
 
-  verify_mirror(dest_sbox, sbox)
+  verify_mirror(dest_sbox, exp_dump_file_contents)
 
 
 
@@ -564,9 +563,7 @@ def delete_revprops(sbox):
   run_copy_revprops(dest_sbox.repo_url, sbox.repo_url)
 
   # Does the result look as we expected?
-  build_repos(sbox)
-  svntest.actions.run_and_verify_load(sbox.repo_dir, expected_contents)
-  verify_mirror(dest_sbox, sbox)
+  verify_mirror(dest_sbox, expected_contents)
 
 @Issue(3870)
 @SkipUnless(svntest.main.is_posix_os)
@@ -576,6 +573,15 @@ def fd_leak_sync_from_serf_to_local(sbox
   resource.setrlimit(resource.RLIMIT_NOFILE, (128, 128))
   run_test(sbox, "largemods.dump", is_src_ra_local=None, is_dest_ra_local=True)
 
+#----------------------------------------------------------------------
+
+@Issue(4476)
+def mergeinfo_contains_r0(sbox):
+  "mergeinfo contains r0"
+  run_test(sbox, "mergeinfo-contains-r0.dump",
+           exp_dump_file_name="mergeinfo-contains-r0.expected.dump",
+           bypass_prop_validation=True)
+
 
 ########################################################################
 # Run the tests
@@ -612,6 +618,7 @@ test_list = [ None,
               descend_into_replace,
               delete_revprops,
               fd_leak_sync_from_serf_to_local, # calls setrlimit
+              mergeinfo_contains_r0,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py Wed Jan 21 16:22:19 2015
@@ -544,6 +544,15 @@ def run_command_stdin(command, error_exp
        and not any(map(lambda arg: 'prop_tests-12' in arg, varargs)):
       raise Failure("Repository diskpath in %s: %r" % (name, lines))
 
+  valgrind_diagnostic = False
+  # A valgrind diagnostic will raise a failure if the command is
+  # expected to run without error.  When an error is expected any
+  # subsequent error pattern matching is usually lenient and will not
+  # detect the diagnostic so make sure a failure is raised here.
+  if error_expected and stderr_lines:
+    if any(map(lambda arg: re.match('==[0-9]+==', arg), stderr_lines)):
+      valgrind_diagnostic = True
+
   stop = time.time()
   logger.info('<TIME = %.6f>' % (stop - start))
   for x in stdout_lines:
@@ -551,7 +560,8 @@ def run_command_stdin(command, error_exp
   for x in stderr_lines:
     logger.info(x.rstrip())
 
-  if (not error_expected) and ((stderr_lines) or (exit_code != 0)):
+  if (((not error_expected) and ((stderr_lines) or (exit_code != 0)))
+      or valgrind_diagnostic):
     for x in stderr_lines:
       logger.warning(x.rstrip())
     if len(varargs) <= 5:

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/update_tests.py?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/update_tests.py Wed Jan 21 16:22:19 2015
@@ -6517,7 +6517,6 @@ def windows_update_backslash(sbox):
     expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
     svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
-@XFail() # Tries to modify unlocked part of working copy; found via r1561425
 def update_moved_away(sbox):
   "update subtree of moved away"
 

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_fs/fs-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_fs/fs-test.c Wed Jan 21 16:22:19 2015
@@ -6640,6 +6640,62 @@ test_txn_pool_lifetime(const svn_test_op
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_modify_txn_being_written(const svn_test_opts_t *opts,
+                              apr_pool_t *pool)
+{
+  /* FSFS has a limitation (and check) that only one file can be
+   * modified in TXN at time: see r861812 and svn_fs_apply_text() docstring.
+   * This is regression test for this behavior. */
+  svn_fs_t *fs;
+  svn_fs_txn_t *txn;
+  const char *txn_name;
+  svn_fs_root_t *txn_root;
+  svn_stream_t *foo_contents;
+  svn_stream_t *bar_contents;
+
+  /* Bail (with success) on known-untestable scenarios */
+  if (strcmp(opts->fs_type, SVN_FS_TYPE_FSFS) != 0)
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+                            "this will test FSFS repositories only");
+
+  /* Create a new repo. */
+  SVN_ERR(svn_test__create_fs(&fs, "test-modify-txn-being-written",
+                              opts, pool));
+
+  /* Create a TXN_ROOT referencing FS. */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+  /* Make file /foo and open for writing.*/
+  SVN_ERR(svn_fs_make_file(txn_root, "/foo", pool));
+  SVN_ERR(svn_fs_apply_text(&foo_contents, txn_root, "/foo", NULL, pool));
+
+  /* Attempt to modify another file '/bar' -- FSFS doesn't allow this. */
+  SVN_ERR(svn_fs_make_file(txn_root, "/bar", pool));
+  SVN_TEST_ASSERT_ERROR(
+      svn_fs_apply_text(&bar_contents, txn_root, "/bar", NULL, pool),
+      SVN_ERR_FS_REP_BEING_WRITTEN);
+
+  /* *Reopen TXN. */
+  SVN_ERR(svn_fs_open_txn(&txn, fs, txn_name, pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+  /* Check that file '/bar' still cannot be modified */
+  SVN_TEST_ASSERT_ERROR(
+      svn_fs_apply_text(&bar_contents, txn_root, "/bar", NULL, pool),
+      SVN_ERR_FS_REP_BEING_WRITTEN);
+
+  /* Close file '/foo'. */
+  SVN_ERR(svn_stream_close(foo_contents));
+
+  /* Now file '/bar' can be modified. */
+  SVN_ERR(svn_fs_apply_text(&bar_contents, txn_root, "/bar", NULL, pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* ------------------------------------------------------------------------ */
 
 /* The test table.  */
@@ -6767,6 +6823,8 @@ static struct svn_test_descriptor_t test
                        "test creating FSFS repository with different opts"),
     SVN_TEST_OPTS_PASS(test_txn_pool_lifetime,
                        "test pool lifetime dependencies with txn roots"),
+    SVN_TEST_OPTS_PASS(test_modify_txn_being_written,
+                       "test modify txn being written in FSFS"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c Wed Jan 21 16:22:19 2015
@@ -133,7 +133,7 @@ fuzzing_1_byte_1_rev(const char *repo_na
               /* Let us know where we were too strict ... */
               printf("Detected case change in checksum digest at offset 0x%"
                      APR_UINT64_T_HEX_FMT " (%" APR_OFF_T_FMT ") in r%ld: "
-                     "%c -> %c\n", i, i, revision, c_old, c_new);
+                     "%c -> %c\n", (apr_uint64_t)i, i, revision, c_old, c_new);
 
               SVN_ERR(err);
             }
@@ -143,7 +143,7 @@ fuzzing_1_byte_1_rev(const char *repo_na
           /* Let us know where we miss changes ... */
           printf("Undetected mod at offset 0x%"APR_UINT64_T_HEX_FMT
                 " (%"APR_OFF_T_FMT") in r%ld: 0x%02x -> 0x%02x\n",
-                i, i, revision, c_old, c_new);
+                (apr_uint64_t)i, i, revision, c_old, c_new);
 
           SVN_TEST_ASSERT(err);
         }

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c Wed Jan 21 16:22:19 2015
@@ -1079,7 +1079,7 @@ metadata_checksumming(const svn_test_opt
   SVN_ERR(svn_stringbuf_from_file2(&r0, r0_path, pool));
   r0->data[21] = '1';
   SVN_ERR(svn_io_remove_file2(r0_path, FALSE, pool));
-  SVN_ERR(svn_io_file_create_binary(r0_path, r0->data, r0->len, pool));
+  SVN_ERR(svn_io_file_create_bytes(r0_path, r0->data, r0->len, pool));
 
   /* Reading the corrupted data on the normal code path triggers no error.
    * Use a separate namespace to avoid simply reading data from cache. */

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c Wed Jan 21 16:22:19 2015
@@ -79,7 +79,7 @@ create_greek_repo(svn_repos_t **repos,
 
 static svn_error_t *
 verify_representation_stats(const svn_fs_fs__representation_stats_t *stats,
-                            apr_int64_t expected_count)
+                            apr_uint64_t expected_count)
 {
   /* Small items, no packing (but inefficiency due to packing attempt). */
   SVN_TEST_ASSERT(stats->total.count == expected_count);
@@ -110,7 +110,7 @@ verify_representation_stats(const svn_fs
 
 static svn_error_t *
 verify_node_stats(const svn_fs_fs__node_stats_t *node_stats,
-                  apr_int64_t expected_count)
+                  apr_uint64_t expected_count)
 {
   SVN_TEST_ASSERT(node_stats->count == expected_count);
   SVN_TEST_ASSERT(   node_stats->size > 100 * node_stats->count
@@ -162,8 +162,8 @@ verify_large_change(const svn_fs_fs__lar
 static svn_error_t *
 verify_histogram(const svn_fs_fs__histogram_t *histogram)
 {
-  apr_int64_t sum_count = 0;
-  apr_int64_t sum_size = 0;
+  apr_uint64_t sum_count = 0;
+  apr_uint64_t sum_size = 0;
 
   int i;
   for (i = 0; i < 64; ++i)

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_subr/cache-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_subr/cache-test.c Wed Jan 21 16:22:19 2015
@@ -201,6 +201,102 @@ test_membuffer_cache_basic(apr_pool_t *p
   return basic_cache_test(cache, FALSE, pool);
 }
 
+/* Implements svn_cache__deserialize_func_t */
+static svn_error_t *
+raise_error_deserialize_func(void **out,
+                             void *data,
+                             apr_size_t data_len,
+                             apr_pool_t *pool)
+{
+  return svn_error_create(APR_EGENERAL, NULL, NULL);
+}
+
+/* Implements svn_cache__partial_getter_func_t */
+static svn_error_t *
+raise_error_partial_getter_func(void **out,
+                                const void *data,
+                                apr_size_t data_len,
+                                void *baton,
+                                apr_pool_t *result_pool)
+{
+  return svn_error_create(APR_EGENERAL, NULL, NULL);
+}
+
+/* Implements svn_cache__partial_setter_func_t */
+static svn_error_t *
+raise_error_partial_setter_func(void **data,
+                                apr_size_t *data_len,
+                                void *baton,
+                                apr_pool_t *result_pool)
+{
+  return svn_error_create(APR_EGENERAL, NULL, NULL);
+}
+
+static svn_error_t *
+test_membuffer_serializer_error_handling(apr_pool_t *pool)
+{
+  svn_cache__t *cache;
+  svn_membuffer_t *membuffer;
+  svn_revnum_t twenty = 20;
+  svn_boolean_t found;
+  void *val;
+
+  SVN_ERR(svn_cache__membuffer_cache_create(&membuffer, 10*1024, 1, 0,
+                                            TRUE, TRUE, pool));
+
+  /* Create a cache with just one entry. */
+  SVN_ERR(svn_cache__create_membuffer_cache(&cache,
+                                            membuffer,
+                                            serialize_revnum,
+                                            raise_error_deserialize_func,
+                                            APR_HASH_KEY_STRING,
+                                            "cache:",
+                                            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                                            FALSE,
+                                            pool, pool));
+
+  SVN_ERR(svn_cache__set(cache, "twenty", &twenty, pool));
+
+  /* Test retrieving data from cache using full getter that
+     always raises an error. */
+  SVN_TEST_ASSERT_ERROR(
+    svn_cache__get(&val, &found, cache, "twenty", pool),
+    APR_EGENERAL);
+
+  /* Test retrieving data from cache using partial getter that
+     always raises an error. */
+  SVN_TEST_ASSERT_ERROR(
+    svn_cache__get_partial(&val, &found, cache, "twenty",
+                           raise_error_partial_getter_func,
+                           NULL, pool),
+    APR_EGENERAL);
+
+  /* Create a new cache. */
+  SVN_ERR(svn_cache__membuffer_cache_create(&membuffer, 10*1024, 1, 0,
+                                            TRUE, TRUE, pool));
+  SVN_ERR(svn_cache__create_membuffer_cache(&cache,
+                                            membuffer,
+                                            serialize_revnum,
+                                            deserialize_revnum,
+                                            APR_HASH_KEY_STRING,
+                                            "cache:",
+                                            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                                            FALSE,
+                                            pool, pool));
+
+  /* Store one entry in cache. */
+  SVN_ERR(svn_cache__set(cache, "twenty", &twenty, pool));
+
+  /* Test setting data in cache using partial setter that
+     always raises an error. */
+  SVN_TEST_ASSERT_ERROR(
+    svn_cache__set_partial(cache, "twenty", 
+                           raise_error_partial_setter_func,
+                           NULL, pool),
+    APR_EGENERAL);
+
+  return SVN_NO_ERROR;
+}
 
 static svn_error_t *
 test_memcache_long_key(const svn_test_opts_t *opts,
@@ -274,6 +370,8 @@ static struct svn_test_descriptor_t test
                        "memcache svn_cache with very long keys"),
     SVN_TEST_PASS2(test_membuffer_cache_basic,
                    "basic membuffer svn_cache test"),
+    SVN_TEST_PASS2(test_membuffer_serializer_error_handling,
+                   "test for error handling in membuffer svn_cache"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_subr/config-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_subr/config-test.c Wed Jan 21 16:22:19 2015
@@ -347,6 +347,29 @@ test_read_only_mode(const svn_test_opts_
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_expand(const svn_test_opts_t *opts,
+            apr_pool_t *pool)
+{
+  svn_config_t *cfg;
+  const char *cfg_file, *val;
+
+  SVN_ERR(get_config_file_path(&cfg_file, opts, pool));
+  SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, TRUE, FALSE, pool));
+
+  /* Get expanded "g" which requires expanding "c". */
+  svn_config_get(cfg, &val, "section1", "g", NULL);
+
+  /* Get expanded "c". */
+  svn_config_get(cfg, &val, "section1", "c", NULL);
+
+  /* With pool debugging enabled this ensures that the expanded value 
+     of "c" was not created in a temporary pool when expanding "g". */
+  SVN_TEST_STRING_ASSERT(val, "bar");
+
+  return SVN_NO_ERROR;
+}
+
 /*
    ====================================================================
    If you add a new test to this file, update this array.
@@ -377,6 +400,8 @@ static struct svn_test_descriptor_t test
                    "test parsing config file with BOM"),
     SVN_TEST_OPTS_PASS(test_read_only_mode,
                        "test r/o mode"),
+    SVN_TEST_OPTS_PASS(test_expand,
+                       "test variable expansion"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_subr/mergeinfo-test.c Wed Jan 21 16:22:19 2015
@@ -104,7 +104,7 @@ verify_mergeinfo_parse(const char *input
 
       /* Were we expecting any more ranges? */
       if (j < MAX_NBR_RANGES - 1
-          && !expected_ranges[j].end == 0)
+          && expected_ranges[j].end != 0)
         return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
                                  "svn_mergeinfo_parse (%s) failed to "
                                  "produce the expected number of ranges",
@@ -114,7 +114,7 @@ verify_mergeinfo_parse(const char *input
 }
 
 
-#define NBR_MERGEINFO_VALS 24
+#define NBR_MERGEINFO_VALS 25
 
 /* Valid mergeinfo values. */
 static const char * const mergeinfo_vals[NBR_MERGEINFO_VALS] =
@@ -148,7 +148,8 @@ static const char * const mergeinfo_vals
     "/A/:7-8",
     "/A///:7-8",
     "/A/.:7-8",
-    "/A/./B:7-8"
+    "/A/./B:7-8",
+    ":7-8",
   };
 /* Paths corresponding to mergeinfo_vals. */
 static const char * const mergeinfo_paths[NBR_MERGEINFO_VALS] =
@@ -181,7 +182,8 @@ static const char * const mergeinfo_path
     "/A",
     "/A",
     "/A",
-    "/A/B"
+    "/A/B",
+    "/",
   };
 /* First ranges from the paths identified by mergeinfo_paths. */
 static svn_merge_range_t mergeinfo_ranges[NBR_MERGEINFO_VALS][MAX_NBR_RANGES] =
@@ -212,6 +214,7 @@ static svn_merge_range_t mergeinfo_range
     { {6, 8, TRUE} },
     { {6, 8, TRUE} },
     { {6, 8, TRUE} },
+    { {6, 8, TRUE} },
   };
 
 static svn_error_t *
@@ -298,7 +301,7 @@ test_parse_combine_rangeinfo(apr_pool_t
 }
 
 
-#define NBR_BROKEN_MERGEINFO_VALS 27
+#define NBR_BROKEN_MERGEINFO_VALS 26
 /* Invalid mergeinfo values. */
 static const char * const broken_mergeinfo_vals[NBR_BROKEN_MERGEINFO_VALS] =
   {
@@ -330,8 +333,6 @@ static const char * const broken_mergein
     "/trunk:",
     "/trunk:2-9\n/branch:",
     "::",
-    /* No path */
-    ":1-3",
     /* Invalid revisions */
     "trunk:a-3",
     "branch:3-four",

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_subr/string-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_subr/string-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_subr/string-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_subr/string-test.c Wed Jan 21 16:22:19 2015
@@ -604,7 +604,19 @@ test_stringbuf_insert(apr_pool_t *pool)
   SVN_TEST_STRING_ASSERT(a->data, "test hello, world");
 
   svn_stringbuf_insert(a, 1200, "!", 1);
-  return expect_stringbuf_equal(a, "test hello, world!", pool);
+  SVN_TEST_STRING_ASSERT(a->data, "test hello, world!");
+
+  svn_stringbuf_insert(a, 4, "\0-\0", 3);
+  SVN_TEST_ASSERT(svn_stringbuf_compare(a,
+                    svn_stringbuf_ncreate("test\0-\0 hello, world!",
+                                          21, pool)));
+
+  svn_stringbuf_insert(a, 14, a->data + 4, 3);
+  SVN_TEST_ASSERT(svn_stringbuf_compare(a,
+                    svn_stringbuf_ncreate("test\0-\0 hello,\0-\0 world!",
+                                          24, pool)));
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -643,8 +655,24 @@ test_stringbuf_replace(apr_pool_t *pool)
   SVN_TEST_STRING_ASSERT(a->data, "test hello, world!");
 
   svn_stringbuf_replace(a, 1200, 199, "!!", 2);
+  SVN_TEST_STRING_ASSERT(a->data, "test hello, world!!!");
+
+  svn_stringbuf_replace(a, 10, 2, "\0-\0", 3);
+  SVN_TEST_ASSERT(svn_stringbuf_compare(a,
+                    svn_stringbuf_ncreate("test hello\0-\0world!!!",
+                                          21, pool)));
+
+  svn_stringbuf_replace(a, 10, 3, a->data + 10, 3);
+  SVN_TEST_ASSERT(svn_stringbuf_compare(a,
+                    svn_stringbuf_ncreate("test hello\0-\0world!!!",
+                                          21, pool)));
+
+  svn_stringbuf_replace(a, 19, 1, a->data + 10, 3);
+  SVN_TEST_ASSERT(svn_stringbuf_compare(a,
+                    svn_stringbuf_ncreate("test hello\0-\0world!\0-\0!",
+                                          23, pool)));
 
-  return expect_stringbuf_equal(a, "test hello, world!!!", pool);
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *

Modified: subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c Wed Jan 21 16:22:19 2015
@@ -9296,14 +9296,42 @@ move4_update_delself_AAA(const svn_test_
     /* Update and resolve via mine strategy */
     SVN_ERR(sbox_wc_update(&b, "", 2));
 
+    {
+      nodes_row_t nodes[] = {
+
+        {1, "A_moved",        "normal",       1, "A", MOVED_HERE},
+        {1, "A_moved/A",      "normal",       1, "A/A", MOVED_HERE},
+        {1, "A_moved/A/A",    "normal",       1, "A/A/A", MOVED_HERE},
+        {3, "A_moved/A/A",    "base-deleted", NO_COPY_FROM, "AAA_1"},
+        {1, "A_moved/A/A/A",  "normal",       1, "A/A/A/A", MOVED_HERE},
+        {3, "A_moved/A/A/A",  "base-deleted", NO_COPY_FROM},
+
+        { 0 },
+      };
+        SVN_ERR(check_db_rows(&b, "A_moved", nodes));
+    }
+
     /* Resolve a few conflicts manually */
     SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
         svn_wc_conflict_choose_mine_conflict));
+
+    {
+      nodes_row_t nodes[] = {
+
+        {1, "A_moved",        "normal",       2, "A", MOVED_HERE},
+        {1, "A_moved/A",      "normal",       2, "A/A", MOVED_HERE},
+
+        { 0 },
+      };
+        SVN_ERR(check_db_rows(&b, "A_moved", nodes));
+    }
+
     SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
         svn_wc_conflict_choose_mine_conflict));
     SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
         svn_wc_conflict_choose_mine_conflict));
 
+
     /* ### These can currently only be resolved to merged ???? */
     SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty,
                             svn_wc_conflict_choose_merged));
@@ -9319,6 +9347,55 @@ move4_update_delself_AAA(const svn_test_
     SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
     /* Go back to start position */
     SVN_ERR(sbox_wc_update(&b, "", 1));
+    {
+      nodes_row_t nodes[] = {
+        {0, "",               "normal",       1, ""},
+        {0, "A",              "normal",       1, "A"},
+        {1, "A",              "normal",       2, "B", FALSE, "A_moved", TRUE},
+        {0, "A/A",            "normal",       1, "A/A"},
+        {1, "A/A",            "normal",       2, "B/A", MOVED_HERE},
+        {2, "A/A",            "normal",       2, "C/A", FALSE, "BA_moved", TRUE},
+        {1, "A/A/A",          "base-deleted", NO_COPY_FROM},
+        {0, "A/A/A",          "normal",       1, "A/A/A"},
+        {3, "A/A/A",          "normal",       1, "D/A/A"},
+        {1, "A/A/A/A",        "base-deleted", NO_COPY_FROM},
+        {0, "A/A/A/A",        "normal",       1, "A/A/A/A"},
+        {3, "A/A/A/A",        "normal",       1, "D/A/A/A"},
+        {1, "AAA_1",          "normal",       1, "A/A/A"},
+        {1, "AAA_1/A",        "normal",       1, "A/A/A/A"},
+        {1, "AAA_2",          "normal",       1, "B/A/A"},
+        {1, "AAA_2/A",        "normal",       1, "B/A/A/A"},
+        {1, "AAA_3",          "normal",       1, "C/A/A"},
+        {1, "AAA_3/A",        "normal",       1, "C/A/A/A"},
+        {1, "A_moved",        "normal",       2, "A", MOVED_HERE},
+        {1, "A_moved/A",      "normal",       2, "A/A", MOVED_HERE},
+        {1, "B",              "base-deleted", NO_COPY_FROM, "A"},
+        {0, "B",              "normal",       1, "B"},
+        {1, "B/A",            "base-deleted", NO_COPY_FROM},
+        {0, "B/A",            "normal",       1, "B/A"},
+        {1, "B/A/A",          "base-deleted", NO_COPY_FROM},
+        {0, "B/A/A",          "normal",       1, "B/A/A"},
+        {1, "B/A/A/A",        "base-deleted", NO_COPY_FROM},
+        {0, "B/A/A/A",        "normal",       1, "B/A/A/A"},
+        {1, "BA_moved",       "normal",       1, "A/A", MOVED_HERE},
+        {1, "BA_moved/A",     "normal",       1, "A/A/A", MOVED_HERE},
+        {1, "BA_moved/A/A",   "normal",       1, "A/A/A/A", MOVED_HERE},
+        {0, "C",              "normal",       1, "C"},
+        {2, "C/A",            "base-deleted", NO_COPY_FROM, "A/A"},
+        {0, "C/A",            "normal",       1, "C/A"},
+        {2, "C/A/A",          "base-deleted", NO_COPY_FROM},
+        {0, "C/A/A",          "normal",       1, "C/A/A"},
+        {2, "C/A/A/A",        "base-deleted", NO_COPY_FROM},
+        {0, "C/A/A/A",        "normal",       1, "C/A/A/A"},
+        {0, "D",              "normal",       1, "D"},
+        {0, "D/A",            "normal",       1, "D/A"},
+        {0, "D/A/A",          "normal",       1, "D/A/A"},
+        {0, "D/A/A/A",        "normal",       1, "D/A/A/A"},
+
+        { 0 },
+      };
+        SVN_ERR(check_db_rows(&b, "", nodes));
+    }
     SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
     /* Update and resolve via their strategy */
     SVN_ERR(sbox_wc_update(&b, "", 2));
@@ -9733,6 +9810,127 @@ break_move_in_delete(const svn_test_opts
 }
 
 
+static svn_error_t *
+nested_move_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "nested_move_delete", opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "A/Z"));
+  SVN_ERR(sbox_wc_move(&b, "A/B/lambda", "A/Z/lambda"));
+
+  SVN_ERR(sbox_wc_delete(&b, "A/B"));
+
+  {
+    nodes_row_t nodes_AB[] = {
+      {0, "A/B",          "normal",       1, "A/B"},
+      {2, "A/B",          "base-deleted", NO_COPY_FROM},
+      {0, "A/B/E",        "normal",       1, "A/B/E"},
+      {2, "A/B/E",        "base-deleted", NO_COPY_FROM},
+      {0, "A/B/E/alpha",  "normal",       1, "A/B/E/alpha"},
+      {2, "A/B/E/alpha",  "base-deleted", NO_COPY_FROM},
+      {0, "A/B/E/beta",   "normal",       1, "A/B/E/beta"},
+      {2, "A/B/E/beta",   "base-deleted", NO_COPY_FROM},
+      {0, "A/B/F",        "normal",       1, "A/B/F"},
+      {2, "A/B/F",        "base-deleted", NO_COPY_FROM},
+      {0, "A/B/lambda",   "normal",       1, "A/B/lambda"},
+      {2, "A/B/lambda",   "base-deleted", NO_COPY_FROM, "A/Z/lambda"},
+      {0}
+    };
+    nodes_row_t nodes_AZ[] = {
+      {2, "A/Z",          "normal",       NO_COPY_FROM},
+      {3, "A/Z/lambda",   "normal",       1, "A/B/lambda", MOVED_HERE },
+      {0}
+    };
+
+    SVN_ERR(check_db_rows(&b, "A/B", nodes_AB));
+    SVN_ERR(check_db_rows(&b, "A/Z", nodes_AZ));
+  }
+
+  SVN_ERR(sbox_wc_move(&b, "A", "A_moved"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",                   "normal",       0, ""},
+      {0, "A",                  "normal",       1, "A"},
+      {1, "A",                  "base-deleted", NO_COPY_FROM, "A_moved"},
+      {0, "A/B",                "normal",       1, "A/B"},
+      {1, "A/B",                "base-deleted", NO_COPY_FROM},
+      {0, "A/B/E",              "normal",       1, "A/B/E"},
+      {1, "A/B/E",              "base-deleted", NO_COPY_FROM},
+      {0, "A/B/E/alpha",        "normal",       1, "A/B/E/alpha"},
+      {1, "A/B/E/alpha",        "base-deleted", NO_COPY_FROM},
+      {0, "A/B/E/beta",         "normal",       1, "A/B/E/beta"},
+      {1, "A/B/E/beta",         "base-deleted", NO_COPY_FROM},
+      {0, "A/B/F",              "normal",       1, "A/B/F"},
+      {1, "A/B/F",              "base-deleted", NO_COPY_FROM},
+      {0, "A/B/lambda",         "normal",       1, "A/B/lambda"},
+      {1, "A/B/lambda",         "base-deleted", NO_COPY_FROM},
+      {0, "A/C",                "normal",       1, "A/C"},
+      {1, "A/C",                "base-deleted", NO_COPY_FROM},
+      {0, "A/D",                "normal",       1, "A/D"},
+      {1, "A/D",                "base-deleted", NO_COPY_FROM},
+      {0, "A/D/G",              "normal",       1, "A/D/G"},
+      {1, "A/D/G",              "base-deleted", NO_COPY_FROM},
+      {0, "A/D/G/pi",           "normal",       1, "A/D/G/pi"},
+      {1, "A/D/G/pi",           "base-deleted", NO_COPY_FROM},
+      {0, "A/D/G/rho",          "normal",       1, "A/D/G/rho"},
+      {1, "A/D/G/rho",          "base-deleted", NO_COPY_FROM},
+      {0, "A/D/G/tau",          "normal",       1, "A/D/G/tau"},
+      {1, "A/D/G/tau",          "base-deleted", NO_COPY_FROM},
+      {0, "A/D/H",              "normal",       1, "A/D/H"},
+      {1, "A/D/H",              "base-deleted", NO_COPY_FROM},
+      {0, "A/D/H/chi",          "normal",       1, "A/D/H/chi"},
+      {1, "A/D/H/chi",          "base-deleted", NO_COPY_FROM},
+      {0, "A/D/H/omega",        "normal",       1, "A/D/H/omega"},
+      {1, "A/D/H/omega",        "base-deleted", NO_COPY_FROM},
+      {0, "A/D/H/psi",          "normal",       1, "A/D/H/psi"},
+      {1, "A/D/H/psi",          "base-deleted", NO_COPY_FROM},
+      {0, "A/D/gamma",          "normal",       1, "A/D/gamma"},
+      {1, "A/D/gamma",          "base-deleted", NO_COPY_FROM},
+      {0, "A/mu",               "normal",       1, "A/mu"},
+      {1, "A/mu",               "base-deleted", NO_COPY_FROM},
+      {1, "A_moved",            "normal",       1, "A", MOVED_HERE},
+      {1, "A_moved/B",          "normal",       1, "A/B", MOVED_HERE},
+      {2, "A_moved/B",          "base-deleted", NO_COPY_FROM},
+      {2, "A_moved/B/E",        "base-deleted", NO_COPY_FROM},
+      {1, "A_moved/B/E",        "normal",       1, "A/B/E", MOVED_HERE},
+      {1, "A_moved/B/E/alpha",  "normal",       1, "A/B/E/alpha", MOVED_HERE},
+      {2, "A_moved/B/E/alpha",  "base-deleted", NO_COPY_FROM},
+      {1, "A_moved/B/E/beta",   "normal",       1, "A/B/E/beta", MOVED_HERE},
+      {2, "A_moved/B/E/beta",   "base-deleted", NO_COPY_FROM},
+      {1, "A_moved/B/F",        "normal",       1, "A/B/F", MOVED_HERE},
+      {2, "A_moved/B/F",        "base-deleted", NO_COPY_FROM},
+      {1, "A_moved/B/lambda",   "normal",       1, "A/B/lambda", MOVED_HERE},
+      {2, "A_moved/B/lambda",   "base-deleted", NO_COPY_FROM, "A_moved/Z/lambda"},
+      {1, "A_moved/C",          "normal",       1, "A/C", MOVED_HERE},
+      {1, "A_moved/D",          "normal",       1, "A/D", MOVED_HERE},
+      {1, "A_moved/D/G",        "normal",       1, "A/D/G", MOVED_HERE},
+      {1, "A_moved/D/G/pi",     "normal",       1, "A/D/G/pi", MOVED_HERE},
+      {1, "A_moved/D/G/rho",    "normal",       1, "A/D/G/rho", MOVED_HERE},
+      {1, "A_moved/D/G/tau",    "normal",       1, "A/D/G/tau", MOVED_HERE},
+      {1, "A_moved/D/H",        "normal",       1, "A/D/H", MOVED_HERE},
+      {1, "A_moved/D/H/chi",    "normal",       1, "A/D/H/chi", MOVED_HERE},
+      {1, "A_moved/D/H/omega",  "normal",       1, "A/D/H/omega", MOVED_HERE},
+      {1, "A_moved/D/H/psi",    "normal",       1, "A/D/H/psi", MOVED_HERE},
+      {1, "A_moved/D/gamma",    "normal",       1, "A/D/gamma", MOVED_HERE},
+      {2, "A_moved/Z",          "normal",       NO_COPY_FROM},
+      {3, "A_moved/Z/lambda",   "normal",       1, "A/B/lambda", MOVED_HERE},
+      {1, "A_moved/mu",         "normal",       1, "A/mu", MOVED_HERE},
+      {0, "iota", "normal",  1, "iota"},
+
+      {0}
+    };
+
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
@@ -9854,7 +10052,7 @@ static struct svn_test_descriptor_t test
                        "move_replace"),
     SVN_TEST_OPTS_PASS(layered_moved_to,
                        "layered_moved_to"),
-    SVN_TEST_OPTS_XFAIL(update_within_move,
+    SVN_TEST_OPTS_PASS(update_within_move,
                        "update_within_move"),
     SVN_TEST_OPTS_PASS(commit_moved_descendant,
                        "commit_moved_descendant"),
@@ -9876,7 +10074,7 @@ static struct svn_test_descriptor_t test
                        "new_basemove"),
     SVN_TEST_OPTS_PASS(move_back,
                        "move_back (issue 4302)"),
-    SVN_TEST_OPTS_XFAIL(move_update_subtree,
+    SVN_TEST_OPTS_PASS(move_update_subtree,
                        "move_update_subtree (issue 4232)"),
     SVN_TEST_OPTS_PASS(move_parent_into_child,
                        "move_parent_into_child (issue 4333)"),
@@ -9886,7 +10084,7 @@ static struct svn_test_descriptor_t test
                        "move retract (issue 4336)"),
     SVN_TEST_OPTS_PASS(move_delete_file_externals,
                        "move/delete file externals (issue 4293)"),
-    SVN_TEST_OPTS_XFAIL(update_with_tree_conflict,
+    SVN_TEST_OPTS_PASS(update_with_tree_conflict,
                        "update with tree conflict (issue 4347)"),
     SVN_TEST_OPTS_PASS(move_update_parent_replace,
                        "move update with replaced parent (issue 4388)"),
@@ -9916,7 +10114,7 @@ static struct svn_test_descriptor_t test
                        "move4: delete AAA"),
     SVN_TEST_OPTS_PASS(move4_update_add_AAA,
                        "move4: add AAA"),
-    SVN_TEST_OPTS_XFAIL(move4_update_delself_AAA,
+    SVN_TEST_OPTS_PASS(move4_update_delself_AAA,
                        "move4: delete self AAA"),
     SVN_TEST_OPTS_PASS(simple_move_bump,
                        "simple move bump"),
@@ -9924,8 +10122,10 @@ static struct svn_test_descriptor_t test
                        "movedhere extract retract"),
     SVN_TEST_OPTS_PASS(repo_wc_copy,
                        "repo_wc_copy"),
-    SVN_TEST_OPTS_XFAIL(break_move_in_delete,
+    SVN_TEST_OPTS_PASS(break_move_in_delete,
                        "break move in delete (issue 4491)"),
+    SVN_TEST_OPTS_PASS(nested_move_delete,
+                       "nested move delete"),
     SVN_TEST_NULL
   };