You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2012/03/06 18:50:31 UTC

svn commit: r1297604 [11/12] - in /subversion/branches/reintegrate-keep-alive: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ notes/ notes/api-errata/1.7/ subversion/bindings/javahl/native/ subversion/bindings/javah...

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/externals_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/externals_tests.py Tue Mar  6 17:50:23 2012
@@ -1888,7 +1888,7 @@ def exclude_externals(sbox):
                                         None, None, None, None, False,
                                         '--set-depth', 'infinity', wc_dir)
 
-def file_externals_different_repos(sbox):
+def file_externals_different_url(sbox):
   "update file externals via different url"
 
   sbox.build()
@@ -1907,30 +1907,52 @@ def file_externals_different_repos(sbox)
                       r2_url + '/iota  r2-e-2\n' +
                       '^/iota  rr-e-1\n', '')
 
+  # All file externals appear in the working copy, with normalised URLs.
   expected_output = svntest.wc.State(wc_dir, {
     'r1-e-1'            : Item(status='A '),
     'r1-e-2'            : Item(status='A '),
+    'r2-e-1'            : Item(status='A '),
+    'r2-e-2'            : Item(status='A '),
     'rr-e-1'            : Item(status='A '),
   })
 
-  # The externals from r2 should fail, but currently pass.
-  # This creates a wc.db inconsistency
+  expected_status = actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('', status=' M')
+  expected_status.add({
+    'r2-e-1'            : Item(status='  ', wc_rev='1', switched='X'),
+    'r1-e-1'            : Item(status='  ', wc_rev='1', switched='X'),
+    'r1-e-2'            : Item(status='  ', wc_rev='1', switched='X'),
+    'rr-e-1'            : Item(status='  ', wc_rev='1', switched='X'),
+    'r2-e-2'            : Item(status='  ', wc_rev='1', switched='X'),
+  })
+
   svntest.actions.run_and_verify_update(wc_dir,
-                                        expected_output, None, None,
-                                        'svn: warning: W200007: Unsupported.*')
+                                        expected_output, None,
+                                        expected_status, None)
+
+  # Verify that all file external URLs are descendants of r1_url
+  for e in ['r1-e-1', 'r1-e-2', 'r2-e-1', 'r2-e-2', 'rr-e-1']:
+    actions.run_and_verify_info([{'Repository Root' : r1_url}],
+                                os.path.join(sbox.wc_dir, e))
+
 
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'relocate', r1_url, r2_url, wc_dir)
 
 
+  # URLs of existing file externals are silently rewritten
   expected_output = svntest.wc.State(wc_dir, {
-    'r2-e-1'            : Item(status='A '),
-    'r2-e-2'            : Item(status='A '),
   })
 
   svntest.actions.run_and_verify_update(wc_dir,
-                                        expected_output, None, None,
-                                        'svn: warning: W200007: Unsupported.*')
+                                        expected_output, None,
+                                        expected_status, None)
+
+  # Verify that all file external URLs are descendants of r2_url
+  for e in ['r1-e-1', 'r1-e-2', 'r2-e-1', 'r2-e-2', 'rr-e-1']:
+    actions.run_and_verify_info([{'Repository Root' : r2_url}],
+                                os.path.join(sbox.wc_dir, e))
+
 
 def file_external_in_unversioned(sbox):
   "file external in unversioned dir"
@@ -2544,10 +2566,10 @@ def include_immediate_dir_externals(sbox
   #     svn ps svn:externals "^/A/B/E X/XE" wc_dir
   #     svn ci
   #     svn up
-  # 
+  #
   #     svn ps some change X/XE
   #     echo mod >> X/XE/alpha
-  # 
+  #
   #     svn st X/XE
   #     # Expect only the propset on X/XE to be committed.
   #     # Should be like 'svn commit --include-externals --depth=empty X/XE'.
@@ -2775,6 +2797,73 @@ def dir_external_with_dash_r_only(sbox):
   expected_info = { 'Revision': '1' }
   actions.run_and_verify_info([expected_info], E_ext)
 
+# Test for issue #4123 'URL-to-WC copy of externals fails on Windows'
+@Issue(4123)
+def url_to_wc_copy_of_externals(sbox):
+  "url-to-wc copy of externals"
+
+  sbox.build()
+
+  wc_dir = sbox.wc_dir
+  repo_url = sbox.repo_url
+
+  # Create an external A/C/external pointing to ^/A/D/G.
+  svntest.actions.run_and_verify_svn(None, None, [], 'ps',
+                                     'svn:externals', '^/A/D/G external',
+                                     os.path.join(wc_dir, 'A', 'C'))
+  svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
+                                     'create an external', wc_dir)
+  svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
+
+  # Copy ^/A/C to External-WC-to-URL-Copy.
+  #
+  # Previously this failed with:
+  #   >svn copy ^^/A/C External-WC-to-URL-Copy
+  #    U   External-WC-to-URL-Copy
+  #
+  #   Fetching external item into 'External-WC-to-URL-Copy\external':
+  #   A    External-WC-to-URL-Copy\external\pi
+  #   A    External-WC-to-URL-Copy\external\rho
+  #   A    External-WC-to-URL-Copy\external\tau
+  #   Checked out external at revision 2.
+  #
+  #   Checked out revision 2.
+  #   ..\..\..\subversion\libsvn_client\copy.c:2249: (apr_err=720005)
+  #   ..\..\..\subversion\libsvn_client\copy.c:1857: (apr_err=720005)
+  #   ..\..\..\subversion\libsvn_client\copy.c:1857: (apr_err=720005)
+  #   ..\..\..\subversion\libsvn_client\copy.c:1737: (apr_err=720005)
+  #   ..\..\..\subversion\libsvn_client\copy.c:1737: (apr_err=720005)
+  #   ..\..\..\subversion\libsvn_client\copy.c:1537: (apr_err=720005)
+  #   ..\..\..\subversion\libsvn_subr\io.c:3416: (apr_err=720005)
+  #   svn: E720005: Can't move 'C:\SVN\src-trunk-3\Debug\subversion\tests\
+  #   cmdline\svn-test-work\working_copies\externals_tests-41\.svn\tmp\
+  #   svn-F9E2C0EC' to 'C:\SVN\src-trunk-3\Debug\subversion\tests\cmdline\
+  #   svn-test-work\working_copies\externals_tests-41\External-WC-to-URL-Copy':
+  #   Access is denied.
+  external_root_path = os.path.join(wc_dir, "External-WC-to-URL-Copy")
+  external_ex_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
+                                  "external")
+  external_pi_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
+                                  "external", "pi")
+  external_rho_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
+                                   "external", "rho")
+  external_tau_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
+                                   "external", "tau")
+  expected_stdout = verify.UnorderedOutput([
+    "\n",
+    " U   " + external_root_path + "\n",
+    "Fetching external item into '" + external_ex_path + "':\n",
+    "A    " + external_pi_path + "\n",
+    "A    " + external_rho_path + "\n",
+    "A    " + external_tau_path + "\n",
+    "Checked out external at revision 2.\n",
+    "Checked out revision 2.\n",
+    "A         " + external_root_path + "\n"
+  ])
+  exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+    "OUTPUT", expected_stdout, [], 0, 'copy', repo_url + '/A/C',
+    os.path.join(wc_dir, 'External-WC-to-URL-Copy'))
+
 ########################################################################
 # Run the tests
 
@@ -2813,7 +2902,7 @@ test_list = [ None,
               incoming_file_on_file_external,
               incoming_file_external_on_file,
               exclude_externals,
-              file_externals_different_repos,
+              file_externals_different_url,
               file_external_in_unversioned,
               copy_file_externals,
               include_externals,
@@ -2821,6 +2910,7 @@ test_list = [ None,
               shadowing,
               remap_file_external_with_prop_del,
               dir_external_with_dash_r_only,
+              url_to_wc_copy_of_externals,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/info_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/info_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/info_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/info_tests.py Tue Mar  6 17:50:23 2012
@@ -469,7 +469,7 @@ def info_show_exclude(sbox):
 
   sbox.simple_rm('iota')
   sbox.simple_commit()
-  
+
   expected_error = 'svn: E200009: Could not display info for all targets.*'
 
   # Expect error on iota (status = not-present)

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/lock_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/lock_tests.py Tue Mar  6 17:50:23 2012
@@ -1172,6 +1172,8 @@ def repos_lock_with_info(sbox):
 
 
 #----------------------------------------------------------------------
+@Issue(4126)
+@Skip(svntest.main.is_ra_type_dav_serf) # Issue 4126 unpredictable result
 def unlock_already_unlocked_files(sbox):
   "(un)lock set of files, one already (un)locked"
 

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/log_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/log_tests.py Tue Mar  6 17:50:23 2012
@@ -2190,6 +2190,25 @@ def log_diff(sbox):
   compare_diff_output(r9diff, log_chain[1]['diff_lines'])
   compare_diff_output(r8diff, log_chain[2]['diff_lines'])
 
+def log_xml_old(sbox):
+  "log --xml shows kind for old style repository"
+
+  sbox.build(minor_version=5)
+
+  sbox.simple_copy('A/B', 'A/B2')
+  sbox.simple_rm('A/B/lambda', 'A/B/E', 'A/B2/lambda', 'A/B2/E')
+  sbox.simple_commit()
+
+  os.chdir(sbox.wc_dir)
+  paths=[{'/A/B/E'       : [{'kind':'dir',  'action':'D'}],
+          '/A/B/lambda'  : [{'kind':'file', 'action':'D'}],
+          '/A/B2'        : [{'kind':'dir',  'action':'A'}],
+          '/A/B2/E'      : [{'kind':'dir',  'action':'D'}],
+          '/A/B2/lambda' : [{'kind':'file', 'action':'D'}]}]
+  svntest.actions.run_and_verify_log_xml(args=['-r', '2', '-v'],
+                                         expected_paths=paths)
+
+
 
 ########################################################################
 # Run the tests
@@ -2232,6 +2251,7 @@ test_list = [ None,
               log_on_nonexistent_path_and_valid_rev,
               merge_sensitive_log_copied_path_inherited_mergeinfo,
               log_diff,
+              log_xml_old,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_authz_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_authz_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_authz_tests.py Tue Mar  6 17:50:23 2012
@@ -443,7 +443,7 @@ def mergeinfo_and_skipped_paths(sbox):
   # and skipped). 'A_COPY_2/D/H/zeta' must therefore get its own explicit
   # mergeinfo from this merge.
   svntest.actions.run_and_verify_svn(None, None, [], 'revert', '--recursive',
-                                     wc_restricted)  
+                                     wc_restricted)
   expected_output = wc.State(A_COPY_2_H_path, {
     'omega' : Item(status='U '),
     'zeta'  : Item(status='A '),

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_reintegrate_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_reintegrate_tests.py Tue Mar  6 17:50:23 2012
@@ -2430,7 +2430,7 @@ def reintegrate_replaced_source(sbox):
   A_path         = os.path.join(sbox.wc_dir, "A")
   A_COPY_path    = os.path.join(sbox.wc_dir, "A_COPY")
   beta_COPY_path = os.path.join(sbox.wc_dir, "A_COPY", "B", "E", "beta")
-  mu_COPY_path   = os.path.join(sbox.wc_dir, "A_COPY", "mu")  
+  mu_COPY_path   = os.path.join(sbox.wc_dir, "A_COPY", "mu")
 
   # Using cherrypick merges, simulate a series of sync merges from A to
   # A_COPY with a replace of A_COPY along the way.
@@ -2470,7 +2470,7 @@ def reintegrate_replaced_source(sbox):
                        wc_dir)
 
   # r12 - Do a final sync merge of A to A_COPY in preparation for
-  # reintegration.  
+  # reintegration.
   svntest.main.run_svn(None, 'up', wc_dir)
   svntest.main.run_svn(None, 'merge', sbox.repo_url + '/A', A_COPY_path)
   svntest.main.run_svn(None, 'ci', '-m', 'Sycn A_COPY with A', wc_dir)
@@ -2543,6 +2543,45 @@ def reintegrate_replaced_source(sbox):
                                        '--reintegrate', A_path)
 
 #----------------------------------------------------------------------
+@SkipUnless(svntest.main.is_posix_os)
+@Issue(4052)
+def reintegrate_symlink_deletion(sbox):
+  "reintegrate symlink deletion"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  ## path vars
+  A_path = sbox.ospath('A')
+  A_omicron_path = sbox.ospath('A/omicron')
+  mu_path = sbox.ospath('A/mu')
+  A_COPY_path = sbox.ospath('A_COPY')
+  A_COPY_omicron_path = sbox.ospath('A_COPY/omicron')
+  A_url = sbox.repo_url + "/A"
+  A_COPY_url = sbox.repo_url + "/A_COPY"
+
+  ## add symlink
+  os.symlink(mu_path, A_omicron_path)
+  sbox.simple_add('A/omicron')
+  sbox.simple_commit(message='add symlink')
+
+  ## branch
+  sbox.simple_repo_copy('A', 'A_COPY')
+  sbox.simple_update()
+
+  ## branch rm
+  sbox.simple_rm('A_COPY/omicron')
+  sbox.simple_commit(message='remove symlink on branch')
+
+  ## Note: running update at this point avoids the bug.
+
+  ## reintegrate
+  # ### TODO: verify something here
+  svntest.main.run_svn(None, 'merge', '--reintegrate',
+                       A_COPY_url, A_path)
+
+
+#----------------------------------------------------------------------
 
 def simple_reintegrate(sbox, source, target_wcpath):
   """"""
@@ -2787,6 +2826,7 @@ test_list = [ None,
               reintegrate_creates_bogus_mergeinfo,
               no_source_subtree_mergeinfo,
               reintegrate_replaced_source,
+              reintegrate_symlink_deletion,
               reintegrate_keep_alive1,
               reintegrate_keep_alive2,
               reintegrate_keep_alive3,

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/merge_tests.py Tue Mar  6 17:50:23 2012
@@ -14124,11 +14124,13 @@ def merge_range_prior_to_rename_source_e
                                      'move', sbox.repo_url + '/A/D/H/nu',
                                      sbox.repo_url + '/A/D/H/nu_moved',
                                      '-m', 'Move nu to nu_moved')
-  svntest.actions.run_and_verify_svn(None,
-                                     ["Updating '%s':\n" % (wc_dir),
-                                      "D    " + nu_path + "\n",
-                                      "A    " + nu_moved_path + "\n",
-                                      "Updated to revision 12.\n"],
+  expected_output = svntest.verify.UnorderedOutput(
+    ["Updating '%s':\n" % (wc_dir),
+     "D    " + nu_path + "\n",
+     "A    " + nu_moved_path + "\n",
+     "Updated to revision 12.\n"],
+    )
+  svntest.actions.run_and_verify_svn(None, expected_output,
                                      [], 'up', wc_dir)
 
   # Now merge -r7:12 from A to A_COPY.
@@ -17018,7 +17020,7 @@ def merged_deletion_causes_tree_conflict
                                      '-m', 'Copy ^/A to ^/branch')
   svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
 
-  # r4 - Delete A/D/H/psi 
+  # r4 - Delete A/D/H/psi
   svntest.actions.run_and_verify_svn(None, None, [], 'delete', psi_path)
   svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
                                      'Delete a a path with native eol-style',
@@ -17213,7 +17215,7 @@ def unnecessary_noninheritable_mergeinfo
 
   B_branch_path = os.path.join(sbox.wc_dir, 'branch', 'B')
 
-  # Setup a simple branch to which 
+  # Setup a simple branch to which
   expected_output, expected_mergeinfo_output, expected_elision_output, \
     expected_status, expected_disk, expected_skip = \
     noninheritable_mergeinfo_test_set_up(sbox)
@@ -17258,7 +17260,7 @@ def unnecessary_noninheritable_mergeinfo
   B_branch_path = os.path.join(sbox.wc_dir, 'branch', 'B')
   E_path        = os.path.join(sbox.wc_dir, 'A', 'B', 'E')
 
-  # Setup a simple branch to which 
+  # Setup a simple branch to which
   expected_output, expected_mergeinfo_output, expected_elision_output, \
     expected_status, expected_disk, expected_skip = \
     noninheritable_mergeinfo_test_set_up(sbox)
@@ -17316,7 +17318,7 @@ def unnecessary_noninheritable_mergeinfo
   #       /A/B:4* <-- Should be inheritable
   #   Properties on 'branch\B\E':
   #     svn:mergeinfo
-  #       /A/B/E:4 <-- Not necessary 
+  #       /A/B/E:4 <-- Not necessary
   expected_output = wc.State(B_branch_path, {
     'E' : Item(status=' U'),
     })
@@ -17355,6 +17357,116 @@ def unnecessary_noninheritable_mergeinfo
                                        None, None, None, None, None, 1, 1,
                                        '--depth', 'immediates', B_branch_path)
 
+#----------------------------------------------------------------------
+# Test for issue #4132, "merge of replaced source asserts".
+# The original use-case is the following merges, which both asserted:
+#    svn merge -cr1295005 ^/subversion/trunk@1295000 ../src
+#    svn merge -cr1295004 ^/subversion/trunk/@r1295004 ../src
+@Issue(4132)
+@XFail()
+def svnmucc_abuse_1(sbox):
+  "svnmucc: merge a replacement"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  ## Using A/ as our trunk, since one cannot replace the root.
+
+  ## r2: open a branch
+  sbox.simple_repo_copy('A', 'A_COPY')
+
+  ## r3: padding (to make the revnums-mod-10 match)
+  sbox.simple_repo_copy('iota', 'padding')
+
+  ## r4: trunk: accidental change
+  sbox.simple_append('A/mu', 'accidental change')
+  sbox.simple_commit()
+
+  ## r5: fail to revert it
+  svntest.actions.run_and_verify_svnmucc(None, None, [],
+                                         '-m', 'r5',
+                                         '-U', sbox.repo_url,
+                                         'rm', 'A',
+                                         'cp', 'HEAD', 'A', 'A')
+
+  ## r6: really revert it
+  svntest.actions.run_and_verify_svnmucc(None, None, [],
+                                         '-m', 'r6',
+                                         '-U', sbox.repo_url,
+                                         'rm', 'A',
+                                         'cp', '3', 'A', 'A')
+
+  ## Attempt to merge that.
+  # This used to assert:
+  #   --- Recording mergeinfo for merge of r5 into 'svn-test-work/working_copies/merge_tests-125/A_COPY':
+  #   subversion/libsvn_subr/mergeinfo.c:1172: (apr_err=235000)
+  #   svn: E235000: In file 'subversion/libsvn_subr/mergeinfo.c' line 1172: assertion failed (IS_VALID_FORWARD_RANGE(first))
+  sbox.simple_update()
+  svntest.main.run_svn(None, 'merge', '-c', 'r5', '^/A@r5',
+                             sbox.ospath('A_COPY'))
+
+#----------------------------------------------------------------------
+# Test for issue #4138 'replacement in merge source not notified correctly'.
+@SkipUnless(server_has_mergeinfo)
+@XFail()
+@Issue(4138)
+def merge_source_with_replacement(sbox):
+  "replacement in merge source not notified correctly"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Some paths we'll care about.
+  A_path          = os.path.join(sbox.wc_dir, 'A')
+  omega_path      = os.path.join(sbox.wc_dir, 'A', 'D', 'H', 'omega')
+  A_COPY_path     = os.path.join(sbox.wc_dir, 'A_COPY')
+  beta_COPY_path  = os.path.join(sbox.wc_dir, 'A_COPY', 'B', 'E', 'beta')
+  psi_COPY_path   = os.path.join(sbox.wc_dir, 'A_COPY', 'D', 'H', 'psi')
+  rho_COPY_path   = os.path.join(sbox.wc_dir, 'A_COPY', 'D', 'G', 'rho')
+  omega_COPY_path = os.path.join(sbox.wc_dir, 'A_COPY', 'D', 'H', 'omega')
+  
+  # branch A@1 to A_COPY in r2, then make a few edits under A in r3-6:  
+  wc_disk, wc_status = set_up_branch(sbox)
+
+  # r7 Delete A, replace it with A@5, effectively reverting the change
+  # made to A/D/H/omega in r6:
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'del', A_path)
+  svntest.main.run_svn(None, 'copy', sbox.repo_url + '/A@5', A_path)
+  svntest.main.run_svn(None, 'ci', '-m',
+                       'Replace A with older version of itself', wc_dir)
+
+  # r8: Make an edit to A/D/H/omega:
+  svntest.main.file_write(omega_path, "New content for 'omega'.\n")
+  svntest.main.run_svn(None, 'ci', '-m', 'file edit', wc_dir)
+
+  # Update and sync merge ^/A to A_COPY.
+  svntest.main.run_svn(None, 'up', wc_dir)
+  # This currently fails because the merge notifications make it look like
+  # r6 from ^/A was merged and recorded:
+  #
+  #   >svn merge ^^/A A_COPY
+  #   --- Merging r2 through r5 into 'A_COPY':
+  #   U    A_COPY\B\E\beta
+  #   U    A_COPY\D\G\rho
+  #   U    A_COPY\D\H\psi
+  #   --- Recording mergeinfo for merge of r2 through r5 into 'A_COPY':
+  #    U   A_COPY
+  #   --- Merging r6 through r8 into 'A_COPY':
+  #   U    A_COPY\D\H\omega
+  #   --- Recording mergeinfo for merge of r6 through r8 into 'A_COPY':
+  #   G   A_COPY
+  expected_output = expected_merge_output([[2,5],[7,8]],
+                          ['U    ' + beta_COPY_path  + '\n',
+                           'U    ' + rho_COPY_path   + '\n',
+                           'U    ' + omega_COPY_path + '\n',
+                           'U    ' + psi_COPY_path   + '\n',
+                           ' U   ' + A_COPY_path     + '\n',
+                           ' G   ' + A_COPY_path     + '\n',])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge', sbox.repo_url + '/A',
+                                     A_COPY_path)
+
 ########################################################################
 # Run the tests
 
@@ -17485,6 +17597,8 @@ test_list = [ None,
               record_only_merge_adds_new_subtree_mergeinfo,
               unnecessary_noninheritable_mergeinfo_missing_subtrees,
               unnecessary_noninheritable_mergeinfo_shallow_merge,
+              svnmucc_abuse_1,
+              merge_source_with_replacement,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/mergeinfo_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/mergeinfo_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/mergeinfo_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/mergeinfo_tests.py Tue Mar  6 17:50:23 2012
@@ -532,7 +532,7 @@ def wc_target_inherits_mergeinfo_from_re
   gamma_2_path  = os.path.join(wc_dir, 'A_COPY_2', 'D', 'gamma')
   tau_path      = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
   D_COPY_path   = os.path.join(wc_dir, 'A_COPY', 'D')
-  
+
   # Merge -c5 ^/A/D/G/rho A_COPY\D\G\rho
   # Merge -c7 ^/A A_COPY
   # Commit as r8
@@ -565,7 +565,7 @@ def wc_target_inherits_mergeinfo_from_re
   # Check the merged and eligible revisions both recursively and
   # non-recursively.
 
-  # Eligible : Non-recursive  
+  # Eligible : Non-recursive
   svntest.actions.run_and_verify_mergeinfo(
     adjust_error_for_server_version(''),
     ['4','5'], sbox.repo_url + '/A/D', subtree_wc,
@@ -618,7 +618,7 @@ def wc_target_inherits_mergeinfo_from_re
   svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
                                      'Merge r8 from A_COPY_2 to A_COPY',
                                      wc_dir)
- 
+
   def test_svn_mergeinfo_4_way(wc_target):
     # Eligible : Non-recursive
     svntest.actions.run_and_verify_mergeinfo(
@@ -738,7 +738,7 @@ def noninheritabled_mergeinfo_not_always
   # unconditionally set for merges with shallow operational depths.
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'propset', SVN_PROP_MERGEINFO,
-                                     '/A:3*\n', branch_path)  
+                                     '/A:3*\n', branch_path)
   svntest.main.run_svn(None, 'commit', '-m', 'shallow merge', wc_dir)
 
   # Now check that r3 is reported as fully merged from ^/A to ^/branch

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/patch_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/patch_tests.py Tue Mar  6 17:50:23 2012
@@ -2822,12 +2822,13 @@ def patch_prop_offset(sbox):
 
   os.chdir(wc_dir)
 
-  expected_output = [
+  # Changing two properties so output order not well defined.
+  expected_output = svntest.verify.UnorderedOutput([
     ' U        iota\n',
     '>         applied hunk ## -6,6 +6,9 ## with offset -1 (prop1)\n',
     '>         applied hunk ## -14,11 +17,8 ## with offset 4 (prop1)\n',
     '>         applied hunk ## -5,6 +5,7 ## with offset -3 (prop2)\n',
-  ]
+  ])
 
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.tweak('iota', props = {'prop1' : prop1_content,
@@ -3726,7 +3727,7 @@ def patch_deletes_prop(sbox):
   # *adds* the property.
   svntest.main.run_svn(None, 'revert', iota_path)
 
-  # Apply patch 
+  # Apply patch
   unidiff_patch = [
     "Index: iota\n",
     "===================================================================\n",
@@ -3749,7 +3750,7 @@ def patch_deletes_prop(sbox):
                                        None, # expected err
                                        1, # check-props
                                        1, # dry-run
-                                       '--reverse-diff') 
+                                       '--reverse-diff')
 
 @Issue(4004)
 def patch_reversed_add_with_props(sbox):
@@ -3798,7 +3799,7 @@ def patch_reversed_add_with_props(sbox):
                                        None, # expected err
                                        1, # check-props
                                        1, # dry-run
-                                       '--reverse-diff') 
+                                       '--reverse-diff')
 
 @Issue(4004)
 def patch_reversed_add_with_props2(sbox):
@@ -3853,7 +3854,7 @@ def patch_reversed_add_with_props2(sbox)
                                        None, # expected err
                                        1, # check-props
                                        1, # dry-run
-                                       '--reverse-diff') 
+                                       '--reverse-diff')
 
 def patch_dev_null(sbox):
   "patch with /dev/null filenames"

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/special_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/special_tests.py Tue Mar  6 17:50:23 2012
@@ -998,7 +998,7 @@ def replace_symlinks(sbox):
   os.symlink('../iota', wc('A/mu.sh'))
   sbox.simple_add('A/mu',
                   'A/mu.sh')
- 
+
   # Ditto, without the Subversion replacement.  Failing git-svn test
   # 'executable file becomes a symlink to bar/zzz (file)'.
   os.remove(wc('Ax/mu'))
@@ -1009,7 +1009,7 @@ def replace_symlinks(sbox):
                       'Ax/mu',
                       'Ax/mu.sh')
   sbox.simple_propdel('svn:executable', 'Ax/mu.sh')
-  
+
   ### TODO Replace a normal {file, exec, dir, dir} with a symlink to
   ### {dir, dir, file, exec}.  And the same symlink-to-normal.
 
@@ -1023,7 +1023,6 @@ def replace_symlinks(sbox):
   sbox.simple_update()
 
 
-@XFail()
 @Issue(4102)
 @SkipUnless(svntest.main.is_posix_os)
 def externals_as_symlink_targets(sbox):
@@ -1053,7 +1052,20 @@ def externals_as_symlink_targets(sbox):
   sbox.simple_add('sym_ext_E')
 
   sbox.simple_commit()
-    
+
+@XFail()
+@Issue(4119)
+@SkipUnless(svntest.main.is_posix_os)
+def cat_added_symlink(sbox):
+  "cat added symlink"
+
+  sbox.build(read_only = True)
+
+  kappa_path = sbox.ospath('kappa')
+  os.symlink('iota', kappa_path)
+  sbox.simple_add('kappa')
+  svntest.actions.run_and_verify_svn(None, "link iota", [],
+                                     "cat", kappa_path)
 
 ########################################################################
 # Run the tests
@@ -1084,6 +1096,7 @@ test_list = [ None,
               update_symlink,
               replace_symlinks,
               externals_as_symlink_targets,
+              cat_added_symlink,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/stat_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/stat_tests.py Tue Mar  6 17:50:23 2012
@@ -924,76 +924,27 @@ def status_in_xml(sbox):
   else:
     raise svntest.Failure
 
-  template = ['<?xml version="1.0" encoding="UTF-8"?>\n',
-              "<status>\n",
-              "<target\n",
-              "   path=\"%s\">\n" % (file_path),
-              "<entry\n",
-              "   path=\"%s\">\n" % (file_path),
-              "<wc-status\n",
-              "   props=\"none\"\n",
-              "   item=\"modified\"\n",
-              "   revision=\"1\">\n",
-              "<commit\n",
-              "   revision=\"1\">\n",
-              "<author>%s</author>\n" % svntest.main.wc_author,
-              time_str,
-              "</commit>\n",
-              "</wc-status>\n",
-              "</entry>\n",
-              "<against\n",
-              "   revision=\"1\"/>\n",
-              "</target>\n",
-              "</status>\n",
-             ]
+  expected_entries = {file_path : {'wcprops' : 'none',
+                                   'wcitem' : 'modified',
+                                   'wcrev' : '1',
+                                   'crev' : '1',
+                                   'author' : svntest.main.wc_author}}
 
-  exit_code, output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                                'status',
-                                                                file_path,
-                                                                '--xml', '-u')
-
-  for i in range(0, len(output)):
-    if output[i] != template[i]:
-      print("ERROR: expected: %s actual: %s" % (template[i], output[i]))
-      raise svntest.Failure
+  svntest.actions.run_and_verify_status_xml(expected_entries, file_path, '-u')
 
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'cp', '-m', 'repo-to-repo copy',
                                      sbox.repo_url + '/iota',
                                      sbox.repo_url + '/iota2')
-  
+
   file_path = sbox.ospath('iota2')
 
-  template = ['<?xml version="1.0" encoding="UTF-8"?>\n',
-              "<status>\n",
-              "<target\n",
-              "   path=\"%s\">\n" % (file_path),
-              "<entry\n",
-              "   path=\"%s\">\n" % (file_path),
-              "<wc-status\n",
-              "   props=\"none\"\n",
-              "   item=\"none\">\n",
-              "</wc-status>\n",
-              "<repos-status\n",
-              "   props=\"none\"\n",
-              "   item=\"added\">\n",
-              "</repos-status>\n",
-              "</entry>\n",
-              "<against\n",
-              "   revision=\"2\"/>\n",
-              "</target>\n",
-              "</status>\n",
-             ]
+  expected_entries = {file_path : {'wcprops' : 'none',
+                                   'wcitem' : 'none',
+                                   'rprops' : 'none',
+                                   'ritem' : 'added'}}
 
-  exit_code, output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                                'status',
-                                                                file_path,
-                                                                '--xml', '-u')
-
-  for i in range(0, len(output)):
-    if output[i] != template[i]:
-      print("ERROR: expected: %s actual: %s" % (template[i], output[i]))
-      raise svntest.Failure
+  svntest.actions.run_and_verify_status_xml(expected_entries, file_path, '-u')
 
 #----------------------------------------------------------------------
 
@@ -1269,53 +1220,23 @@ def status_update_with_incoming_props(sb
   else:
     raise svntest.Failure
 
-  xout = ['<?xml version="1.0" encoding="UTF-8"?>\n',
-          "<status>\n",
-          "<target\n",
-          "   path=\"%s\">\n" % (wc_dir),
-          "<entry\n",
-          "   path=\"%s\">\n" % (A_path),
-          "<wc-status\n",
-          "   props=\"none\"\n",
-          "   item=\"normal\"\n",
-          "   revision=\"1\">\n",
-          "<commit\n",
-          "   revision=\"1\">\n",
-          "<author>%s</author>\n" % svntest.main.wc_author,
-          time_str,
-          "</commit>\n",
-          "</wc-status>\n",
-          "<repos-status\n",
-          "   props=\"modified\"\n",
-          "   item=\"none\">\n",
-          "</repos-status>\n",
-          "</entry>\n",
-          "<entry\n",
-          "   path=\"%s\">\n" % (wc_dir),
-          "<wc-status\n",
-          "   props=\"none\"\n",
-          "   item=\"normal\"\n",
-          "   revision=\"1\">\n",
-          "<commit\n",
-          "   revision=\"1\">\n",
-          "<author>%s</author>\n" % svntest.main.wc_author,
-          time_str,
-          "</commit>\n",
-          "</wc-status>\n",
-          "<repos-status\n",
-          "   props=\"modified\"\n",
-          "   item=\"none\">\n",
-          "</repos-status>\n",
-          "</entry>\n",
-          "<against\n",
-          "   revision=\"2\"/>\n",
-          "</target>\n",
-          "</status>\n",]
-
-  exit_code, output, error = svntest.actions.run_and_verify_svn(None, xout, [],
-                                                                'status',
-                                                                wc_dir,
-                                                                '--xml', '-uN')
+  expected_entries ={wc_dir : {'wcprops' : 'none',
+                               'wcitem' : 'normal',
+                               'wcrev' : '1',
+                               'crev' : '1',
+                               'author' : svntest.main.wc_author,
+                               'rprops' : 'modified',
+                               'ritem' : 'none'},
+                     A_path : {'wcprops' : 'none',
+                               'wcitem' : 'normal',
+                               'wcrev' : '1',
+                               'crev' : '1',
+                               'author' : svntest.main.wc_author,
+                               'rprops' : 'modified',
+                               'ritem' : 'none'},
+                     }
+
+  svntest.actions.run_and_verify_status_xml(expected_entries, wc_dir, '-uN')
 
 # more incoming prop updates.
 def status_update_verbose_with_incoming_props(sbox):
@@ -2004,7 +1925,7 @@ def status_not_present(sbox):
   svntest.main.run_svn(None, 'up', '--set-depth', 'exclude',
                        sbox.ospath('A/mu'), sbox.ospath('A/B'))
   sbox.simple_commit()
-  
+
   svntest.actions.run_and_verify_svn(None, [], [],'status',
                                      sbox.ospath('iota'),
                                      sbox.ospath('A/B'),

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnadmin_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnadmin_tests.py Tue Mar  6 17:50:23 2012
@@ -111,10 +111,10 @@ def check_hotcopy_fsfs(src, dst):
               # both at EOF
               break
             elif buf1:
-              raise svntest.Failure("%s differs at offset %i" % 
+              raise svntest.Failure("%s differs at offset %i" %
                                     (dst_path, offset))
             elif buf2:
-              raise svntest.Failure("%s differs at offset %i" % 
+              raise svntest.Failure("%s differs at offset %i" %
                                     (dst_path, offset))
           if len(buf1) != len(buf2):
             raise svntest.Failure("%s differs in length" % dst_path)
@@ -1422,9 +1422,12 @@ def verify_non_utf8_paths(sbox):
     if line == "A\n":
       # replace 'A' with a latin1 character -- the new path is not valid UTF-8
       fp_new.write("\xE6\n")
-    elif line == "text: 1 279 32 32 d63ecce65d8c428b86f4f8b0920921fe\n":
+    elif line == "text: 1 279 32 0 d63ecce65d8c428b86f4f8b0920921fe\n":
       # fix up the representation checksum
-      fp_new.write("text: 1 279 32 32 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
+      fp_new.write("text: 1 279 32 0 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
+    elif line == "text: 1 292 44 32 a6be7b4cf075fd39e6a99eb69a31232b\n":
+      # fix up the representation checksum
+      fp_new.write("text: 1 292 44 32 f2e93e73272cac0f18fccf16f224eb93\n")
     elif line == "cpath: /A\n":
       # also fix up the 'created path' field
       fp_new.write("cpath: /\xE6\n")
@@ -1463,7 +1466,7 @@ def verify_non_utf8_paths(sbox):
 
 def test_lslocks_and_rmlocks(sbox):
   "test 'svnadmin lslocks' and 'svnadmin rmlocks'"
-  
+
   sbox.build(create_wc=False)
   iota_url = sbox.repo_url + '/iota'
   lambda_url = sbox.repo_url + '/A/B/lambda'
@@ -1477,7 +1480,7 @@ def test_lslocks_and_rmlocks(sbox):
   expected_output = UnorderedOutput(
     ["'A/B/lambda' locked by user 'jrandom'.\n",
      "'iota' locked by user 'jrandom'.\n"])
-  
+
   # Lock iota and A/B/lambda using svn client
   svntest.actions.run_and_verify_svn(None, expected_output,
                                      [], "lock", "-m", "Locking files",
@@ -1492,18 +1495,18 @@ def test_lslocks_and_rmlocks(sbox):
       "Comment \(1 line\):",
       "Locking files",
       "Path: /iota",
-      "UUID Token: opaquelocktoken.*",      
-      "\n", # empty line    
+      "UUID Token: opaquelocktoken.*",
+      "\n", # empty line
       ]
 
   # List all locks
   exit_code, output, errput = svntest.main.run_svnadmin("lslocks",
                                                         sbox.repo_dir)
-  
+
   if errput:
     raise SVNUnexpectedStderr(errput)
   svntest.verify.verify_exit_code(None, exit_code, 0)
-    
+
   try:
     expected_output = svntest.verify.UnorderedRegexOutput(expected_output_list)
     svntest.verify.compare_and_display_lines('lslocks output mismatch',
@@ -1537,7 +1540,7 @@ def test_lslocks_and_rmlocks(sbox):
     "Expires:",
     "Comment \(1 line\):",
     "Locking files",
-    "\n", # empty line    
+    "\n", # empty line
     ])
 
   svntest.verify.compare_and_display_lines('message', 'label',
@@ -1551,7 +1554,7 @@ def test_lslocks_and_rmlocks(sbox):
                                                         "A/B/lambda")
   expected_output = UnorderedOutput(["Removed lock on '/iota'.\n",
                                      "Removed lock on '/A/B/lambda'.\n"])
-  
+
   svntest.verify.verify_outputs(
     "Unexpected output while running 'svnadmin rmlocks'.",
     output, [], expected_output, None)
@@ -1649,7 +1652,7 @@ def hotcopy_incremental_packed(sbox):
 def locking(sbox):
   "svnadmin lock tests"
   sbox.build(create_wc=False)
-  
+
   comment_path = os.path.join(svntest.main.temp_dir, "comment")
   svntest.main.file_write(comment_path, "dummy comment")
 
@@ -1659,15 +1662,15 @@ def locking(sbox):
   # Test illegal character in comment file.
   expected_error = ".*svnadmin: E130004:.*"
   svntest.actions.run_and_verify_svnadmin(None, None,
-                                          expected_error, "lock", 
+                                          expected_error, "lock",
                                           sbox.repo_dir,
                                           "iota", "jrandom",
                                           invalid_comment_path)
-  
+
   # Test locking path with --bypass-hooks
   expected_output = "'iota' locked by user 'jrandom'."
   svntest.actions.run_and_verify_svnadmin(None, expected_output,
-                                          None, "lock", 
+                                          None, "lock",
                                           sbox.repo_dir,
                                           "iota", "jrandom",
                                           comment_path,
@@ -1675,13 +1678,13 @@ def locking(sbox):
 
   # Remove lock
   svntest.actions.run_and_verify_svnadmin(None, None,
-                                          None, "rmlocks", 
+                                          None, "rmlocks",
                                           sbox.repo_dir, "iota")
-  
+
   # Test locking path without --bypass-hooks
   expected_output = "'iota' locked by user 'jrandom'."
   svntest.actions.run_and_verify_svnadmin(None, expected_output,
-                                          None, "lock", 
+                                          None, "lock",
                                           sbox.repo_dir,
                                           "iota", "jrandom",
                                           comment_path)
@@ -1689,7 +1692,7 @@ def locking(sbox):
   # Test locking already locked path.
   expected_error = ".*svnadmin: E160035:.*"
   svntest.actions.run_and_verify_svnadmin(None, None,
-                                          expected_error, "lock", 
+                                          expected_error, "lock",
                                           sbox.repo_dir,
                                           "iota", "jrandom",
                                           comment_path)
@@ -1697,7 +1700,7 @@ def locking(sbox):
   # Test locking non-existent path.
   expected_error = ".*svnadmin: E160013:.*"
   svntest.actions.run_and_verify_svnadmin(None, None,
-                                          expected_error, "lock", 
+                                          expected_error, "lock",
                                           sbox.repo_dir,
                                           "non-existent", "jrandom",
                                           comment_path)
@@ -1706,7 +1709,7 @@ def locking(sbox):
   expected_output = "'A/D/G/rho' locked by user 'jrandom'."
   lock_token = "opaquelocktoken:01234567-89ab-cdef-89ab-cdef01234567"
   svntest.actions.run_and_verify_svnadmin(None, expected_output,
-                                          None, "lock", 
+                                          None, "lock",
                                           sbox.repo_dir,
                                           "A/D/G/rho", "jrandom",
                                           comment_path, lock_token)
@@ -1715,11 +1718,11 @@ def locking(sbox):
   expected_error = ".*svnadmin: E160040:.*"
   wrong_lock_token = "opaquelocktoken:12345670-9ab8-defc-9ab8-def01234567c"
   svntest.actions.run_and_verify_svnadmin(None, None,
-                                          expected_error, "unlock", 
+                                          expected_error, "unlock",
                                           sbox.repo_dir,
                                           "A/D/G/rho", "jrandom",
                                           wrong_lock_token)
-  
+
   # Test unlocking the path again, but this time provide the correct
   # lock token.
   expected_output = "'A/D/G/rho' unlocked."
@@ -1734,12 +1737,12 @@ def locking(sbox):
   svntest.main.create_python_hook_script(hook_path, 'import sys; sys.exit(1)')
   hook_path = svntest.main.get_pre_unlock_hook_path(sbox.repo_dir)
   svntest.main.create_python_hook_script(hook_path, 'import sys; sys.exit(1)')
-  
+
   # Test locking a path.  Don't use --bypass-hooks, though, as we wish
   # to verify that hook script is really getting executed.
   expected_error = ".*svnadmin: E165001:.*"
   svntest.actions.run_and_verify_svnadmin(None, None,
-                                          expected_error, "lock", 
+                                          expected_error, "lock",
                                           sbox.repo_dir,
                                           "iota", "jrandom",
                                           comment_path)
@@ -1761,7 +1764,7 @@ def locking(sbox):
   # with a preventative hook in place.
   expected_error = ".*svnadmin: E165001:.*"
   svntest.actions.run_and_verify_svnadmin(None, None,
-                                          expected_error, "unlock", 
+                                          expected_error, "unlock",
                                           sbox.repo_dir,
                                           "iota", "jrandom",
                                           iota_token)

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svndumpfilter_tests.py Tue Mar  6 17:50:23 2012
@@ -164,6 +164,9 @@ def svndumpfilter_loses_mergeinfo(sbox):
 
 
 def _simple_dumpfilter_test(sbox, dumpfile, *dumpargs):
+  """Run svndumpfilter with arguments DUMPARGS, taking input from DUMPFILE.
+     Check that the output consists of the standard Greek tree excluding
+     all paths that start with 'A/B/E', 'A/D/G' or 'A/D/H'."""
   wc_dir = sbox.wc_dir
 
   filtered_output, filtered_err = filter_and_return_output(dumpfile, 0,
@@ -596,6 +599,58 @@ def dropped_but_not_renumbered_empty_rev
                                      'propget', 'svn:mergeinfo', '-R',
                                      sbox.repo_url)
 
+#----------------------------------------------------------------------
+def match_empty_prefix(sbox):
+  "svndumpfilter with an empty prefix"
+
+  dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
+                                   'svndumpfilter_tests_data',
+                                   'greek_tree.dump')
+  dumpfile = open(dumpfile_location).read()
+
+  def test(sbox, dumpfile, *dumpargs):
+    """Run svndumpfilter with DUMPFILE as the input lines, load
+       the result and check it matches EXPECTED_DISK, EXPECTED_OUTPUT,
+       EXPECTED_STATUS."""
+
+    # Filter the Greek tree dump
+    filtered_output, filtered_err = filter_and_return_output(dumpfile, 0,
+                                                             '--quiet',
+                                                             *dumpargs)
+    if filtered_err:
+      raise verify.UnexpectedStderr(filtered_err)
+
+    # Load the filtered dump into a repo and check the result
+    test_create(sbox)
+    load_and_verify_dumpstream(sbox, [], [], None, filtered_output,
+                               '--ignore-uuid')
+    svntest.actions.run_and_verify_update(sbox.wc_dir,
+                                          expected_output,
+                                          expected_disk,
+                                          expected_status)
+
+  # Test excluding everything
+  expected_disk = svntest.wc.State(sbox.wc_dir, {})
+  expected_output = svntest.wc.State(sbox.wc_dir, {})
+  expected_status = svntest.wc.State(sbox.wc_dir, {
+                      '': Item(status='  ', wc_rev=1) })
+
+  test(sbox, dumpfile, 'exclude', '')
+
+  # Test including everything
+  expected_disk = svntest.main.greek_state.copy()
+  expected_output = svntest.main.greek_state.copy().tweak(status='A ')
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+
+  test(sbox, dumpfile, 'include', '', '/A/D/G')
+
+  # Note: We also ought to test the '--pattern' option, including or
+  # excluding a pattern of '*'.  However, passing a wildcard parameter
+  # is troublesome on Windows: it may be expanded, depending on whether
+  # the svndumpfilter executable was linked with 'setargv.obj', and there
+  # doesn't seem to be a consistent way to quote such an argument to
+  # prevent expansion.
+
 ########################################################################
 # Run the tests
 
@@ -608,6 +663,7 @@ test_list = [ None,
               dumpfilter_with_patterns,
               filter_mergeinfo_revs_outside_of_dump_stream,
               dropped_but_not_renumbered_empty_revs,
+              match_empty_prefix,
               ]
 
 if __name__ == '__main__':

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnlook_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnlook_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnlook_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnlook_tests.py Tue Mar  6 17:50:23 2012
@@ -117,35 +117,39 @@ def test_misc(sbox):
   # the 'svnlook tree --full-paths' output if demanding the whole repository
   treelist = run_svnlook('tree', repo_dir)
   treelistfull = run_svnlook('tree', '--full-paths', repo_dir)
+
   path = ''
-  n = 0
+  treelistexpand = []
   for entry in treelist:
     len1 = len(entry)
     len2 = len(entry.lstrip())
-    path = path[0:2*(len1-len2)-1] + entry.strip()
-    test = treelistfull[n].rstrip()
-    if n != 0:
-      test = "/" + test
-    if not path == test:
-      print("Unexpected result from tree with --full-paths:")
-      print("  entry            : %s" % entry.rstrip())
-      print("  with --full-paths: %s" % treelistfull[n].rstrip())
-      raise svntest.Failure
-    n = n + 1
+    path = path[0:2*(len1-len2)-1] + entry.strip() + '\n'
+    if path == '/\n':
+      treelistexpand.append(path)
+    else:
+      treelistexpand.append(path[1:])
+
+  treelistexpand = svntest.verify.UnorderedOutput(treelistexpand)
+  svntest.verify.compare_and_display_lines('Unexpected result from tree', '',
+                                           treelistexpand, treelistfull)
 
   # check if the 'svnlook tree' output is the ending of
   # the 'svnlook tree --full-paths' output if demanding
   # any part of the repository
-  n = 0
   treelist = run_svnlook('tree', repo_dir, '/A/B')
   treelistfull = run_svnlook('tree', '--full-paths', repo_dir, '/A/B')
+
+  path = ''
+  treelistexpand = []
   for entry in treelist:
-    if not treelistfull[n].endswith(entry.lstrip()):
-      print("Unexpected result from tree with --full-paths:")
-      print("  entry            : %s" % entry.rstrip())
-      print("  with --full-paths: %s" % treelistfull[n].rstrip())
-      raise svntest.Failure
-    n = n + 1
+    len1 = len(entry)
+    len2 = len(entry.lstrip())
+    path = path[0:2*(len1-len2)] + entry.strip() + '\n'
+    treelistexpand.append('/A/' + path)
+
+  treelistexpand = svntest.verify.UnorderedOutput(treelistexpand)
+  svntest.verify.compare_and_display_lines('Unexpected result from tree', '',
+                                           treelistexpand, treelistfull)
 
   treelist = run_svnlook('tree', repo_dir, '/')
   if treelist[0] != '/\n':
@@ -695,7 +699,7 @@ fp.close()"""
                     #  internal property, not really expected
                     '  svn:check-locks\n',
                     '  bogus_rev_prop\n', '  svn:date\n']
-  verify_logfile(logfilepath, expected_data)
+  verify_logfile(logfilepath, svntest.verify.UnorderedOutput(expected_data))
 
 ########################################################################
 # Run the tests

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnrdump_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnrdump_tests.py Tue Mar  6 17:50:23 2012
@@ -89,11 +89,12 @@ def compare_repos_dumps(svnrdump_sbox, s
   svnadmin_contents = svntest.actions.run_and_verify_dump(
                                                     svnadmin_sbox.repo_dir)
 
-  svntest.verify.compare_and_display_lines(
+  svntest.verify.compare_dump_files(
     "Dump files", "DUMP", svnadmin_contents, svnrdump_contents)
 
 def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None,
-                  subdir = None, bypass_prop_validation = False):
+                  subdir = None, bypass_prop_validation = False,
+                  ignore_base_checksums = False):
   """Load a dumpfile using 'svnadmin load', dump it with 'svnrdump
   dump' and check that the same dumpfile is produced or that
   expected_dumpfile_name is produced if provided. Additionally, the
@@ -129,12 +130,19 @@ def run_dump_test(sbox, dumpfile_name, e
     svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
                                           expected_dumpfile_name),
                              'rb').readlines()
-    svnadmin_dumpfile = svntest.verify.UnorderedOutput(svnadmin_dumpfile)
     # Compare the output from stdout
+    if ignore_base_checksums:
+      svnadmin_dumpfile = [l for l in svnadmin_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 = svntest.verify.UnorderedOutput(svnadmin_dumpfile)
+
     svntest.verify.compare_and_display_lines(
       "Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile,
       None, mismatched_headers_re)
-    
+
   else:
     compare_repos_dumps(sbox, svnadmin_dumpfile)
 
@@ -189,6 +197,7 @@ def run_load_test(sbox, dumpfile_name, e
 ######################################################################
 # Tests
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def basic_dump(sbox):
   "dump: standard sbox repos"
   sbox.build(read_only = True, create_wc = False)
@@ -201,6 +210,7 @@ def basic_dump(sbox):
   if not out[0].startswith('SVN-fs-dump-format-version:'):
     raise svntest.Failure('No valid output')
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def revision_0_dump(sbox):
   "dump: revision zero"
   run_dump_test(sbox, "revision-0.dump")
@@ -219,6 +229,7 @@ def revision_0_load(sbox):
 #     docs/         (Added r6)
 #       README      (Added r6)
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def skeleton_dump(sbox):
   "dump: skeleton repository"
   run_dump_test(sbox, "skeleton.dump")
@@ -227,6 +238,7 @@ def skeleton_load(sbox):
   "load: skeleton repository"
   run_load_test(sbox, "skeleton.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def sparse_propchanges_dump(sbox):
   "dump: sparse file/dir propchanges"
   run_dump_test(sbox, "sparse-propchanges.dump")
@@ -236,6 +248,7 @@ def sparse_propchanges_load(sbox):
   "load: sparse file/dir propchanges"
   run_load_test(sbox, "sparse-propchanges.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def copy_and_modify_dump(sbox):
   "dump: copy and modify"
   run_dump_test(sbox, "copy-and-modify.dump")
@@ -244,6 +257,7 @@ def copy_and_modify_load(sbox):
   "load: copy and modify"
   run_load_test(sbox, "copy-and-modify.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def no_author_dump(sbox):
   "dump: copy revs with no svn:author revprops"
   run_dump_test(sbox, "no-author.dump")
@@ -252,6 +266,7 @@ def no_author_load(sbox):
   "load: copy revs with no svn:author revprops"
   run_load_test(sbox, "no-author.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def copy_from_previous_version_and_modify_dump(sbox):
   "dump: copy from previous version and modify"
   run_dump_test(sbox, "copy-from-previous-version-and-modify.dump")
@@ -260,6 +275,7 @@ def copy_from_previous_version_and_modif
   "load: copy from previous version and modify"
   run_load_test(sbox, "copy-from-previous-version-and-modify.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def modified_in_place_dump(sbox):
   "dump: modified in place"
   run_dump_test(sbox, "modified-in-place.dump")
@@ -268,6 +284,7 @@ def modified_in_place_load(sbox):
   "load: modified in place"
   run_load_test(sbox, "modified-in-place.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def move_and_modify_in_the_same_revision_dump(sbox):
   "dump: move parent & modify child file in same rev"
   run_dump_test(sbox, "move-and-modify.dump")
@@ -276,6 +293,7 @@ def move_and_modify_in_the_same_revision
   "load: move parent & modify child file in same rev"
   run_load_test(sbox, "move-and-modify.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def tag_empty_trunk_dump(sbox):
   "dump: tag empty trunk"
   run_dump_test(sbox, "tag-empty-trunk.dump")
@@ -284,6 +302,7 @@ def tag_empty_trunk_load(sbox):
   "load: tag empty trunk"
   run_load_test(sbox, "tag-empty-trunk.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def tag_trunk_with_file_dump(sbox):
   "dump: tag trunk containing a file"
   run_dump_test(sbox, "tag-trunk-with-file.dump")
@@ -292,6 +311,7 @@ def tag_trunk_with_file_load(sbox):
   "load: tag trunk containing a file"
   run_load_test(sbox, "tag-trunk-with-file.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def tag_trunk_with_file2_dump(sbox):
   "dump: tag trunk containing a file (#2)"
   run_dump_test(sbox, "tag-trunk-with-file2.dump")
@@ -300,6 +320,7 @@ def tag_trunk_with_file2_load(sbox):
   "load: tag trunk containing a file (#2)"
   run_load_test(sbox, "tag-trunk-with-file2.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def dir_prop_change_dump(sbox):
   "dump: directory property changes"
   run_dump_test(sbox, "dir-prop-change.dump")
@@ -308,6 +329,7 @@ def dir_prop_change_load(sbox):
   "load: directory property changes"
   run_load_test(sbox, "dir-prop-change.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def copy_parent_modify_prop_dump(sbox):
   "dump: copy parent and modify prop"
   run_dump_test(sbox, "copy-parent-modify-prop.dump")
@@ -316,6 +338,7 @@ def copy_parent_modify_prop_load(sbox):
   "load: copy parent and modify prop"
   run_load_test(sbox, "copy-parent-modify-prop.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def copy_revprops_dump(sbox):
   "dump: copy revprops other than svn:*"
   run_dump_test(sbox, "revprops.dump")
@@ -325,17 +348,20 @@ def copy_revprops_load(sbox):
   run_load_test(sbox, "revprops.dump")
 
 @XFail()
+@Skip(svntest.main.is_ra_type_dav_serf)
 def only_trunk_dump(sbox):
   "dump: subdirectory"
   run_dump_test(sbox, "trunk-only.dump", subdir="/trunk",
                 expected_dumpfile_name="trunk-only.expected.dump")
 
 @XFail()
+@Skip(svntest.main.is_ra_type_dav_serf)
 def only_trunk_A_with_changes_dump(sbox):
   "dump: subdirectory with changes on root"
   run_dump_test(sbox, "trunk-A-changes.dump", subdir="/trunk/A",
            expected_dumpfile_name="trunk-A-changes.expected.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def url_encoding_dump(sbox):
   "dump: url encoding issues"
   run_dump_test(sbox, "url-encoding-bug.dump")
@@ -344,18 +370,21 @@ def url_encoding_load(sbox):
   "load: url encoding issues"
   run_load_test(sbox, "url-encoding-bug.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def copy_bad_line_endings_dump(sbox):
   "dump: inconsistent line endings in svn:* props"
   run_dump_test(sbox, "copy-bad-line-endings.dump",
                 expected_dumpfile_name="copy-bad-line-endings.expected.dump",
                 bypass_prop_validation=True)
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def copy_bad_line_endings2_dump(sbox):
   "dump: non-LF line endings in svn:* props"
   run_dump_test(sbox, "copy-bad-line-endings2.dump",
                 expected_dumpfile_name="copy-bad-line-endings2.expected.dump",
-                bypass_prop_validation=True)
+                bypass_prop_validation=True, ignore_base_checksums=True)
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def commit_a_copy_of_root_dump(sbox):
   "dump: commit a copy of root"
   run_dump_test(sbox, "repo-with-copy-of-root-dir.dump")
@@ -364,6 +393,7 @@ def commit_a_copy_of_root_load(sbox):
   "load: commit a copy of root"
   run_load_test(sbox, "repo-with-copy-of-root-dir.dump")
 
+@Skip(svntest.main.is_ra_type_dav_serf)
 def descend_into_replace_dump(sbox):
   "dump: descending into replaced dir looks in src"
   run_dump_test(sbox, "descend-into-replace.dump", subdir='/trunk/H',
@@ -374,6 +404,7 @@ def descend_into_replace_load(sbox):
   run_load_test(sbox, "descend-into-replace.dump")
 
 @Issue(3847)
+@Skip(svntest.main.is_ra_type_dav_serf)
 def add_multi_prop_dump(sbox):
   "dump: add with multiple props"
   run_dump_test(sbox, "add-multi-prop.dump")
@@ -388,6 +419,7 @@ def multi_prop_edit_load(sbox):
 # revs in svn:mergeinfo' but uses 'svnrdump load' in place of
 # 'svnadmin load'.
 @Issue(3890)
+@Skip(svntest.main.is_ra_type_dav_serf)
 def reflect_dropped_renumbered_revs(sbox):
   "svnrdump renumbers dropped revs in mergeinfo"
 
@@ -451,6 +483,7 @@ def reflect_dropped_renumbered_revs(sbox
 # from incremental dump' but uses 'svnrdump [dump|load]' in place of
 # 'svnadmin [dump|load]'.
 @Issue(3890)
+@Skip(svntest.main.is_ra_type_dav_serf)
 def dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads(sbox):
   "don't drop mergeinfo revs in incremental svnrdump"
 

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnsync_tests.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svnsync_tests.py Tue Mar  6 17:50:23 2012
@@ -223,7 +223,7 @@ def verify_mirror(dest_sbox, src_sbox):
   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_and_display_lines(
+  svntest.verify.compare_dump_files(
     "Dump files", "DUMP", src_dump, dest_dump)
 
 def run_test(sbox, dump_file_name, subdir=None, exp_dump_file_name=None,
@@ -251,7 +251,7 @@ or another dump file."""
   # file.
   if exp_dump_file_name:
     build_repos(sbox)
-    svntest.actions.run_and_verify_load(sbox.repo_dir, 
+    svntest.actions.run_and_verify_load(sbox.repo_dir,
                                         open(os.path.join(svnsync_tests_dir,
                                                           exp_dump_file_name),
                                              'rb').readlines())
@@ -399,25 +399,32 @@ def basic_authz(sbox):
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
+  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
   svntest.main.file_write(sbox.authz_file,
-                          "[svnsync-basic-authz:/]\n"
+                          "[%s:/]\n"
                           "* = r\n"
                           "\n"
-                          "[svnsync-basic-authz:/A/B]\n"
+                          "[%s:/A/B]\n"
                           "* = \n"
                           "\n"
-                          "[svnsync-basic-authz-1:/]\n"
-                          "* = rw\n")
+                          "[%s:/]\n"
+                          "* = rw\n" % args)
 
   run_sync(dest_sbox.repo_url)
 
   lambda_url = dest_sbox.repo_url + '/A/B/lambda'
+  iota_url = dest_sbox.repo_url + '/iota'
 
   # this file should have been blocked by authz
   svntest.actions.run_and_verify_svn(None,
                                      [], svntest.verify.AnyOutput,
                                      'cat',
                                      lambda_url)
+  # this file should have been synced
+  svntest.actions.run_and_verify_svn(None,
+                                     svntest.verify.AnyOutput, [],
+                                     'cat',
+                                     iota_url)
 
 #----------------------------------------------------------------------
 @Skip(svntest.main.is_ra_type_file)
@@ -470,29 +477,17 @@ def copy_from_unreadable_dir(sbox):
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
-  fp = open(sbox.authz_file, 'w')
-
-  # For mod_dav_svn's parent path setup we need per-repos permissions in
-  # the authz file...
-  if sbox.repo_url.startswith('http'):
-    fp.write("[svnsync-copy-from-unreadable-dir:/]\n" +
-             "* = r\n" +
-             "\n" +
-             "[svnsync-copy-from-unreadable-dir:/A/B]\n" +
-             "* = \n" +
-             "\n" +
-             "[svnsync-copy-from-unreadable-dir-1:/]\n" +
-             "* = rw")
-
-  # Otherwise we can just go with the permissions needed for the source
-  # repository.
-  else:
-    fp.write("[/]\n" +
-             "* = r\n" +
-             "\n" +
-             "[/A/B]\n" +
-             "* =\n")
-  fp.close()
+  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
+  open(sbox.authz_file, 'w').write(
+             "[%s:/]\n"
+             "* = r\n"
+             "\n"
+             "[%s:/A/B]\n"
+             "* = \n"
+             "\n"
+             "[%s:/]\n"
+             "* = rw"
+             % args)
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
@@ -596,29 +591,17 @@ def copy_with_mod_from_unreadable_dir(sb
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
-  fp = open(sbox.authz_file, 'w')
-
-  # For mod_dav_svn's parent path setup we need per-repos permissions in
-  # the authz file...
-  if sbox.repo_url.startswith('http'):
-    fp.write("[svnsync-copy-with-mod-from-unreadable-dir:/]\n" +
-             "* = r\n" +
-             "\n" +
-             "[svnsync-copy-with-mod-from-unreadable-dir:/A/B]\n" +
-             "* = \n" +
-             "\n" +
-             "[svnsync-copy-with-mod-from-unreadable-dir-1:/]\n" +
-             "* = rw")
-
-  # Otherwise we can just go with the permissions needed for the source
-  # repository.
-  else:
-    fp.write("[/]\n" +
-             "* = r\n" +
-             "\n" +
-             "[/A/B]\n" +
-             "* =\n")
-  fp.close()
+  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
+  open(sbox.authz_file, 'w').write(
+             "[%s:/]\n"
+             "* = r\n"
+             "\n"
+             "[%s:/A/B]\n"
+             "* = \n"
+             "\n"
+             "[%s:/]\n"
+             "* = rw"
+             % args)
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
@@ -700,29 +683,17 @@ def copy_with_mod_from_unreadable_dir_an
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
-  fp = open(sbox.authz_file, 'w')
-
-  # For mod_dav_svn's parent path setup we need per-repos permissions in
-  # the authz file...
-  if sbox.repo_url.startswith('http'):
-    fp.write("[svnsync-copy-with-mod-from-unreadable-dir-and-copy:/]\n" +
-             "* = r\n" +
-             "\n" +
-             "[svnsync-copy-with-mod-from-unreadable-dir-and-copy:/A/B]\n" +
-             "* = \n" +
-             "\n" +
-             "[svnsync-copy-with-mod-from-unreadable-dir-and-copy-1:/]\n" +
-             "* = rw")
-
-  # Otherwise we can just go with the permissions needed for the source
-  # repository.
-  else:
-    fp.write("[/]\n" +
-             "* = r\n" +
-             "\n" +
-             "[/A/B]\n" +
-             "* =\n")
-  fp.close()
+  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
+  open(sbox.authz_file, 'w').write(
+             "[%s:/]\n"
+             "* = r\n"
+             "\n"
+             "[%s:/A/B]\n"
+             "* = \n"
+             "\n"
+             "[%s:/]\n"
+             "* = rw"
+             % args)
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
@@ -1028,6 +999,46 @@ def fd_leak_sync_from_serf_to_local(sbox
   import resource
   resource.setrlimit(resource.RLIMIT_NOFILE, (128, 128))
   run_test(sbox, "largemods.dump", is_src_ra_local=None, is_dest_ra_local=True)
+
+@Issue(4121)
+@Skip(svntest.main.is_ra_type_file)
+def copy_delete_unreadable_child(sbox):
+  "copy, then rm at-src-unreadable child"
+
+  # Prepare the source: Greek tree (r1), cp+rm (r2).
+  sbox.build("copy-delete-unreadable-child")
+  svntest.actions.run_and_verify_svnmucc(None, None, [],
+                                         '-m', 'r2',
+                                         '-U', sbox.repo_url,
+                                         'cp', 'HEAD', '/', 'branch',
+                                         'rm', 'branch/A')
+
+  # Create the destination.
+  dest_sbox = sbox.clone_dependent()
+  build_repos(dest_sbox)
+  svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
+
+  # Lock down the source.
+  authz = sbox.authz_name()
+  write_restrictive_svnserve_conf(sbox.repo_dir, anon_access='read')
+  svntest.main.file_write(sbox.authz_file,
+      "[%s:/]\n"
+      "* = r\n"
+      "[%s:/A]\n"
+      "* =  \n"
+      % (authz, authz))
+
+  dest_url = svntest.main.file_scheme_prefix \
+             + svntest.main.pathname2url(os.path.abspath(dest_sbox.repo_dir))
+  run_init(dest_url, sbox.repo_url)
+  run_sync(dest_url)
+
+  # sanity check
+  svntest.actions.run_and_verify_svn(None,
+                                     ["iota\n"], [],
+                                     'ls', dest_url+'/branch@2')
+
+
 ########################################################################
 # Run the tests
 
@@ -1068,7 +1079,8 @@ test_list = [ None,
               specific_deny_authz,
               descend_into_replace,
               delete_revprops,
-              fd_leak_sync_from_serf_to_local,
+              fd_leak_sync_from_serf_to_local, # calls setrlimit
+              copy_delete_unreadable_child,
              ]
 serial_only = True
 

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/__init__.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/__init__.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/__init__.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/__init__.py Tue Mar  6 17:50:23 2012
@@ -23,11 +23,11 @@
 __all__ = [ ]
 
 import sys
-if sys.hexversion < 0x2040000:
-  sys.stderr.write('[SKIPPED] at least Python 2.4 is required\n')
+if sys.hexversion < 0x2050000:
+  sys.stderr.write('[SKIPPED] at least Python 2.5 is required\n')
 
   # note: exiting is a bit harsh for a library module, but we really do
-  # require Python 2.4. this package isn't going to work otherwise.
+  # require Python 2.5. this package isn't going to work otherwise.
 
   # we're skipping this test, not failing, so exit with 0
   sys.exit(0)

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/actions.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/actions.py Tue Mar  6 17:50:23 2012
@@ -129,7 +129,7 @@ def guarantee_empty_repository(path):
 # the `pristine repos' to a new location.
 # Note: make sure setup_pristine_greek_repository was called once before
 # using this function.
-def guarantee_greek_repository(path):
+def guarantee_greek_repository(path, minor_version):
   """Guarantee that a local svn repository exists at PATH, containing
   nothing but the greek-tree at revision 1."""
 
@@ -139,7 +139,7 @@ def guarantee_greek_repository(path):
 
   # copy the pristine repository to PATH.
   main.safe_rmtree(path)
-  if main.copy_repos(main.pristine_greek_repos_dir, path, 1):
+  if main.copy_repos(main.pristine_greek_repos_dir, path, 1, 1, minor_version):
     print("ERROR:  copying repository failed.")
     sys.exit(1)
 
@@ -556,9 +556,13 @@ class LogEntry:
       self.revprops = revprops
 
   def assert_changed_paths(self, changed_paths):
-    """Not implemented, so just raises svntest.Failure.
+    """Assert that changed_paths is the same as this entry's changed_paths
+    Raises svntest.Failure if not.
     """
-    raise Failure('NOT IMPLEMENTED')
+    if self.changed_paths != changed_paths:
+      raise Failure('\n' + '\n'.join(difflib.ndiff(
+            pprint.pformat(changed_paths).splitlines(),
+            pprint.pformat(self.changed_paths).splitlines())))
 
   def assert_revprops(self, revprops):
     """Assert that the dict revprops is the same as this entry's revprops.
@@ -591,11 +595,13 @@ class LogParser:
     self.parser.EndElementHandler = self.handle_end_element
     self.parser.CharacterDataHandler = self.handle_character_data
     # Ignore some things.
-    self.ignore_elements('log', 'paths', 'path', 'revprops')
+    self.ignore_elements('log', 'paths', 'revprops')
     self.ignore_tags('logentry_end', 'author_start', 'date_start', 'msg_start')
     # internal state
     self.cdata = []
     self.property = None
+    self.kind = None
+    self.action = None
     # the result
     self.entries = []
 
@@ -639,6 +645,12 @@ class LogParser:
     self.property = attrs['name']
   def property_end(self):
     self.entries[-1].revprops[self.property] = self.use_cdata()
+  def path_start(self, attrs):
+    self.kind = attrs['kind']
+    self.action = attrs['action']
+  def path_end(self):
+    self.entries[-1].changed_paths[self.use_cdata()] = [{'kind': self.kind,
+                                                         'action': self.action}]
 
 def run_and_verify_log_xml(message=None, expected_paths=None,
                            expected_revprops=None, expected_stdout=None,
@@ -1079,13 +1091,21 @@ def run_and_verify_merge(dir, rev1, rev2
   if dry_run and merge_diff_out != out_dry:
     # Due to the way ra_serf works, it's possible that the dry-run and
     # real merge operations did the same thing, but the output came in
-    # a different order.  Let's see if maybe that's the case.
+    # a different order.  Let's see if maybe that's the case by comparing
+    # the outputs as unordered sets rather than as lists.
+    #
+    # This now happens for other RA layers with modern APR because the
+    # hash order now varies.
     #
-    # NOTE:  Would be nice to limit this dance to serf tests only, but...
-    out_copy = merge_diff_out[:]
-    out_dry_copy = out_dry[:]
-    out_copy.sort()
-    out_dry_copy.sort()
+    # The different orders of the real and dry-run merges may cause
+    # the "Merging rX through rY into" lines to be duplicated a
+    # different number of times in the two outputs.  The list-set
+    # conversion removes duplicates so these differences are ignored.
+    # It also removes "U some/path" duplicate lines.  Perhaps we
+    # should avoid that?
+    out_copy = set(merge_diff_out[:])
+    out_dry_copy = set(out_dry[:])
+
     if out_copy != out_dry_copy:
       print("=============================================================")
       print("Merge outputs differ")
@@ -1198,16 +1218,11 @@ def run_and_verify_patch(dir, patch_path
     raise verify.SVNUnexpectedStderr
 
   if dry_run and out != out_dry:
-    print("=============================================================")
-    print("Outputs differ")
-    print("'svn patch --dry-run' output:")
-    for x in out_dry:
-      sys.stdout.write(x)
-    print("'svn patch' output:")
-    for x in out:
-      sys.stdout.write(x)
-    print("=============================================================")
-    raise main.SVNUnmatchedError
+    # APR hash order means the output order can vary, assume everything is OK
+    # if only the order changes.
+    out_dry_expected = svntest.verify.UnorderedOutput(out)
+    verify.compare_and_display_lines('dry-run patch output not as expected',
+                                     '', out_dry_expected, out_dry)
 
   def missing_skip(a, b):
     print("=============================================================")
@@ -1230,7 +1245,8 @@ def run_and_verify_patch(dir, patch_path
 
   # when the expected output is a list, we want a line-by-line
   # comparison to happen instead of a tree comparison
-  if isinstance(output_tree, list):
+  if (isinstance(output_tree, list)
+      or isinstance(output_tree, verify.UnorderedOutput)):
     verify.verify_outputs(None, out, err, output_tree, error_re_string)
     output_tree = None
 
@@ -1503,6 +1519,56 @@ def run_and_verify_unquiet_status(wc_dir
     tree.dump_tree_script(actual, wc_dir_name + os.sep)
     raise
 
+def run_and_verify_status_xml(expected_entries = [],
+                              *args):
+  """ Run 'status --xml' with arguments *ARGS.  If successful the output
+  is parsed into an XML document and will be verified by comparing against
+  EXPECTED_ENTRIES.
+  """
+
+  exit_code, output, errput = run_and_verify_svn(None, None, [],
+                                                 'status', '--xml', *args)
+
+  if len(errput) > 0:
+    raise Failure
+
+  doc = parseString(''.join(output))
+  entries = doc.getElementsByTagName('entry')
+
+  def getText(nodelist):
+    rc = []
+    for node in nodelist:
+        if node.nodeType == node.TEXT_NODE:
+            rc.append(node.data)
+    return ''.join(rc)
+
+  actual_entries = {}
+  for entry in entries:
+    wcstatus = entry.getElementsByTagName('wc-status')[0]
+    commit = entry.getElementsByTagName('commit')
+    author = entry.getElementsByTagName('author')
+    rstatus = entry.getElementsByTagName('repos-status')
+
+    actual_entry = {'wcprops' : wcstatus.getAttribute('props'),
+                    'wcitem' : wcstatus.getAttribute('item'),
+                    }
+    if wcstatus.hasAttribute('revision'):
+      actual_entry['wcrev'] = wcstatus.getAttribute('revision')
+    if (commit):
+      actual_entry['crev'] = commit[0].getAttribute('revision')
+    if (author):
+      actual_entry['author'] = getText(author[0].childNodes)
+    if (rstatus):
+      actual_entry['rprops'] = rstatus[0].getAttribute('props')
+      actual_entry['ritem'] = rstatus[0].getAttribute('item')
+
+    actual_entries[entry.getAttribute('path')] = actual_entry
+
+  if expected_entries != actual_entries:
+    raise Failure('\n' + '\n'.join(difflib.ndiff(
+          pprint.pformat(expected_entries).splitlines(),
+          pprint.pformat(actual_entries).splitlines())))
+
 def run_and_verify_diff_summarize_xml(error_re_string = [],
                                       expected_prefix = None,
                                       expected_paths = [],
@@ -1678,7 +1744,8 @@ def run_and_verify_revert(expected_paths
 
 
 # This allows a test to *quickly* bootstrap itself.
-def make_repo_and_wc(sbox, create_wc = True, read_only = False):
+def make_repo_and_wc(sbox, create_wc = True, read_only = False,
+                     minor_version = None):
   """Create a fresh 'Greek Tree' repository and check out a WC from it.
 
   If READ_ONLY is False, a dedicated repository will be created, at the path
@@ -1693,7 +1760,7 @@ def make_repo_and_wc(sbox, create_wc = T
 
   # Create (or copy afresh) a new repos with a greek tree in it.
   if not read_only:
-    guarantee_greek_repository(sbox.repo_dir)
+    guarantee_greek_repository(sbox.repo_dir, minor_version)
 
   if create_wc:
     # Generate the expected output tree.

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/main.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/main.py Tue Mar  6 17:50:23 2012
@@ -302,13 +302,11 @@ def get_start_commit_hook_path(repo_dir)
 
   return os.path.join(repo_dir, "hooks", "start-commit")
 
-
 def get_pre_commit_hook_path(repo_dir):
   "Return the path of the pre-commit-hook conf file in REPO_DIR."
 
   return os.path.join(repo_dir, "hooks", "pre-commit")
 
-
 def get_post_commit_hook_path(repo_dir):
   "Return the path of the post-commit-hook conf file in REPO_DIR."
 
@@ -768,7 +766,7 @@ def file_substitute(path, contents, new_
   open(path, 'w').write(fcontent)
 
 # For creating blank new repositories
-def create_repos(path):
+def create_repos(path, minor_version = None):
   """Create a brand-new SVN repository at PATH.  If PATH does not yet
   exist, create it."""
 
@@ -776,11 +774,13 @@ def create_repos(path):
     os.makedirs(path) # this creates all the intermediate dirs, if neccessary
 
   opts = ("--bdb-txn-nosync",)
-  if options.server_minor_version < 4:
+  if not minor_version or minor_version > options.server_minor_version:
+    minor_version = options.server_minor_version
+  if minor_version < 4:
     opts += ("--pre-1.4-compatible",)
-  elif options.server_minor_version < 5:
+  elif minor_version < 5:
     opts += ("--pre-1.5-compatible",)
-  elif options.server_minor_version < 6:
+  elif minor_version < 6:
     opts += ("--pre-1.6-compatible",)
   if options.fs_type is not None:
     opts += ("--fs-type=" + options.fs_type,)
@@ -804,6 +804,9 @@ def create_repos(path):
                 "realm = svntest\n[sasl]\nuse-sasl = true\n")
   else:
     file_append(get_svnserve_conf_file_path(path), "password-db = passwd\n")
+    # This actually creates TWO [users] sections in the file (one of them is
+    # uncommented in `svnadmin create`'s template), so we exercise the .ini
+    # files reading code's handling of duplicates, too. :-)
     file_append(os.path.join(path, "conf", "passwd"),
                 "[users]\njrandom = rayjandom\njconstant = rayjandom\n");
 
@@ -854,7 +857,8 @@ def create_repos(path):
   chmod_tree(path, 0666, 0666)
 
 # For copying a repository
-def copy_repos(src_path, dst_path, head_revision, ignore_uuid = 1):
+def copy_repos(src_path, dst_path, head_revision, ignore_uuid = 1,
+               minor_version = None):
   "Copy the repository SRC_PATH, with head revision HEAD_REVISION, to DST_PATH"
 
   # Save any previous value of SVN_DBG_QUIET
@@ -863,7 +867,7 @@ def copy_repos(src_path, dst_path, head_
 
   # Do an svnadmin dump|svnadmin load cycle. Print a fake pipe command so that
   # the displayed CMDs can be run by hand
-  create_repos(dst_path)
+  create_repos(dst_path, minor_version)
   dump_args = ['dump', src_path]
   load_args = ['load', dst_path]
 

Modified: subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/sandbox.py?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/tests/cmdline/svntest/sandbox.py Tue Mar  6 17:50:23 2012
@@ -93,14 +93,23 @@ class Sandbox:
       shutil.copytree(self.wc_dir, clone.wc_dir, symlinks=True)
     return clone
 
-  def build(self, name=None, create_wc=True, read_only=False):
+  def build(self, name=None, create_wc=True, read_only=False,
+            minor_version=None):
     """Make a 'Greek Tree' repo (or refer to the central one if READ_ONLY),
        and check out a WC from it (unless CREATE_WC is false). Change the
        sandbox's name to NAME. See actions.make_repo_and_wc() for details."""
     self._set_name(name, read_only)
-    svntest.actions.make_repo_and_wc(self, create_wc, read_only)
+    svntest.actions.make_repo_and_wc(self, create_wc, read_only, minor_version)
     self._is_built = True
 
+  def authz_name(self, repo_dir=None):
+    "return this sandbox's name for use in an authz file"
+    repo_dir = repo_dir or self.repo_dir
+    if self.repo_url.startswith("http"):
+      return os.path.basename(repo_dir)
+    else:
+      return repo_dir.replace('\\', '/')
+
   def add_test_path(self, path, remove=True):
     self.test_paths.append(path)
     if remove:
@@ -272,6 +281,10 @@ class Sandbox:
                          self.repo_url + '/' + source,
                          self.repo_url + '/' + dest)
 
+  def simple_append(self, dest, contents, truncate=False):
+    """Append CONTENTS to file DEST, optionally truncating it first."""
+    open(self.ospath(dest), truncate and 'w' or 'a').write(contents)
+
 
 def is_url(target):
   return (target.startswith('^/')