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 2013/02/13 07:37:56 UTC

svn commit: r1445479 [10/11] - in /subversion/branches/fsfs-format7: ./ build/generator/ build/generator/swig/ build/generator/templates/ notes/api-errata/1.7/ packages/ subversion/bindings/swig/include/ subversion/bindings/swig/perl/libsvn_swig_perl/ ...

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py Wed Feb 13 06:37:54 2013
@@ -30,7 +30,7 @@ import time
 
 # Our testing module
 import svntest
-from svntest import main, wc, verify, actions
+from svntest import main, wc, verify, actions, deeptrees
 
 # (abbreviation)
 Item = wc.StateItem
@@ -789,21 +789,21 @@ def tree_conflicts_and_obstructions(sbox
 # parent directory.
 
 # convenience definitions
-leaf_edit = svntest.actions.deep_trees_leaf_edit
-tree_del = svntest.actions.deep_trees_tree_del
-leaf_del = svntest.actions.deep_trees_leaf_del
-
-disk_after_leaf_edit = svntest.actions.deep_trees_after_leaf_edit
-disk_after_leaf_del = svntest.actions.deep_trees_after_leaf_del
-disk_after_tree_del = svntest.actions.deep_trees_after_tree_del
-disk_after_leaf_del_no_ci = svntest.actions.deep_trees_after_leaf_del_no_ci
-disk_after_tree_del_no_ci = svntest.actions.deep_trees_after_tree_del_no_ci
+leaf_edit = svntest.deeptrees.deep_trees_leaf_edit
+tree_del = svntest.deeptrees.deep_trees_tree_del
+leaf_del = svntest.deeptrees.deep_trees_leaf_del
+
+disk_after_leaf_edit = svntest.deeptrees.deep_trees_after_leaf_edit
+disk_after_leaf_del = svntest.deeptrees.deep_trees_after_leaf_del
+disk_after_tree_del = svntest.deeptrees.deep_trees_after_tree_del
+disk_after_leaf_del_no_ci = svntest.deeptrees.deep_trees_after_leaf_del_no_ci
+disk_after_tree_del_no_ci = svntest.deeptrees.deep_trees_after_tree_del_no_ci
 
-deep_trees_conflict_output = svntest.actions.deep_trees_conflict_output
+deep_trees_conflict_output = svntest.deeptrees.deep_trees_conflict_output
 
 j = os.path.join
 
-DeepTreesTestCase = svntest.actions.DeepTreesTestCase
+DeepTreesTestCase = svntest.deeptrees.DeepTreesTestCase
 
 alpha_beta_gamma = svntest.wc.State('', {
   'F/alpha'           : Item(),
@@ -840,7 +840,7 @@ def tree_conflicts_on_merge_local_ci_4_1
 
   expected_skip = svntest.wc.State('', { })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase("local_tree_del_incoming_leaf_edit",
                         tree_del,
                         leaf_edit,
@@ -878,7 +878,7 @@ def tree_conflicts_on_merge_local_ci_4_2
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase("local_tree_del_incoming_leaf_del",
                         tree_del,
                         leaf_del,
@@ -888,7 +888,6 @@ def tree_conflicts_on_merge_local_ci_4_2
                         expected_skip) ], True)
 
 #----------------------------------------------------------------------
-@XFail()
 @Issue(2282)
 def tree_conflicts_on_merge_local_ci_5_1(sbox):
   "tree conflicts 5.1: leaf edit, tree del"
@@ -906,23 +905,23 @@ def tree_conflicts_on_merge_local_ci_5_1
     ''                  : Item(status=' M', wc_rev='3'),
     'D'                 : Item(status='  ', wc_rev='3'),
     'D/D1'              : Item(status='  ', treeconflict='C', wc_rev='4'),
-    'D/D1/delta'        : Item(status='D ', wc_rev='4'),
+    'D/D1/delta'        : Item(status='  ', wc_rev='4'),
     'DD'                : Item(status='  ', wc_rev='3'),
-    'DD/D1'             : Item(status='  ', treeconflict='C', wc_rev='4'),
-    'DD/D1/D2'          : Item(status='D ', wc_rev='3'),
-    'DD/D1/D2/epsilon'  : Item(status='D ', wc_rev='4'),
+    'DD/D1'             : Item(status='  ', treeconflict='C', wc_rev='3'),
+    'DD/D1/D2'          : Item(status='  ', wc_rev='4'),
+    'DD/D1/D2/epsilon'  : Item(status='  ', wc_rev='4'),
     'DDD'               : Item(status='  ', wc_rev='3'),
-    'DDD/D1'            : Item(status='  ', treeconflict='C', wc_rev='4'),
-    'DDD/D1/D2'         : Item(status='D ', wc_rev='3'),
-    'DDD/D1/D2/D3'      : Item(status='D ', wc_rev='3'),
-    'DDD/D1/D2/D3/zeta' : Item(status='D ', wc_rev='4'),
+    'DDD/D1'            : Item(status='  ', treeconflict='C', wc_rev='3'),
+    'DDD/D1/D2'         : Item(status='  ', wc_rev='3'),
+    'DDD/D1/D2/D3'      : Item(status='  ', wc_rev='4'),
+    'DDD/D1/D2/D3/zeta' : Item(status='  ', wc_rev='4'),
     'DDF'               : Item(status='  ', wc_rev='3'),
-    'DDF/D1'            : Item(status='  ', treeconflict='C', wc_rev='4'),
-    'DDF/D1/D2'         : Item(status='D ', wc_rev='3'),
-    'DDF/D1/D2/gamma'   : Item(status='D ', wc_rev='4'),
+    'DDF/D1'            : Item(status='  ', treeconflict='C', wc_rev='3'),
+    'DDF/D1/D2'         : Item(status='  ', wc_rev='3'),
+    'DDF/D1/D2/gamma'   : Item(status='  ', wc_rev='4'),
     'DF'                : Item(status='  ', wc_rev='3'),
-    'DF/D1'             : Item(status='  ', treeconflict='C', wc_rev='4'),
-    'DF/D1/beta'        : Item(status='D ', wc_rev='4'),
+    'DF/D1'             : Item(status='  ', treeconflict='C', wc_rev='3'),
+    'DF/D1/beta'        : Item(status='  ', wc_rev='4'),
     'F'                 : Item(status='  ', wc_rev='3'),
     'F/alpha'           : Item(status='  ', treeconflict='C', wc_rev='4'),
 
@@ -931,7 +930,7 @@ def tree_conflicts_on_merge_local_ci_5_1
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase("local_leaf_edit_incoming_tree_del",
                         leaf_edit,
                         tree_del,
@@ -941,7 +940,6 @@ def tree_conflicts_on_merge_local_ci_5_1
                         expected_skip) ], True)
 
 #----------------------------------------------------------------------
-@XFail()
 @Issue(2282)
 def tree_conflicts_on_merge_local_ci_5_2(sbox):
   "tree conflicts 5.2: leaf del, tree del"
@@ -957,15 +955,15 @@ def tree_conflicts_on_merge_local_ci_5_2
     'D'                 : Item(status='  ', wc_rev='3'),
     'F'                 : Item(status='  ', wc_rev='3'),
     'DD'                : Item(status='  ', wc_rev='3'),
-    'DD/D1'             : Item(status='! ', treeconflict='C'),
+    'DD/D1'             : Item(status='  ', wc_rev='3', treeconflict='C'),
     'DF'                : Item(status='  ', wc_rev='3'),
-    'DF/D1'             : Item(status='! ', treeconflict='C'),
+    'DF/D1'             : Item(status='  ', wc_rev='3', treeconflict='C'),
     'DDD'               : Item(status='  ', wc_rev='3'),
-    'DDD/D1'            : Item(status='! ', treeconflict='C'),
-    'DDD/D1/D2'         : Item(status='D ', wc_rev='3'),
+    'DDD/D1'            : Item(status='  ', wc_rev='3', treeconflict='C'),
+    'DDD/D1/D2'         : Item(status='  ', wc_rev='3'),
     'DDF'               : Item(status='  ', wc_rev='3'),
-    'DDF/D1'            : Item(status='! ', treeconflict='C'),
-    'DDF/D1/D2'         : Item(status='D ', wc_rev='3'),
+    'DDF/D1'            : Item(status='  ', wc_rev='3', treeconflict='C'),
+    'DDF/D1/D2'         : Item(status='  ', wc_rev='3'),
     'D/D1'              : Item(status='! ', treeconflict='C'),
     'F/alpha'           : Item(status='! ', treeconflict='C'),
     })
@@ -973,7 +971,7 @@ def tree_conflicts_on_merge_local_ci_5_2
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase("local_leaf_del_incoming_tree_del",
                         leaf_del,
                         tree_del,
@@ -1012,7 +1010,7 @@ def tree_conflicts_on_merge_local_ci_6(s
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase("local_tree_del_incoming_tree_del",
                         tree_del,
                         tree_del,
@@ -1059,7 +1057,7 @@ def tree_conflicts_on_merge_no_local_ci_
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase(
                "local_tree_del_incoming_leaf_edit",
                tree_del,
@@ -1107,7 +1105,7 @@ def tree_conflicts_on_merge_no_local_ci_
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase(
                "local_tree_del_incoming_leaf_del",
                tree_del,
@@ -1158,7 +1156,7 @@ def tree_conflicts_on_merge_no_local_ci_
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase(
                "local_leaf_edit_incoming_tree_del",
                leaf_edit,
@@ -1170,7 +1168,6 @@ def tree_conflicts_on_merge_no_local_ci_
              ) ], False)
 
 #----------------------------------------------------------------------
-@XFail()
 @Issue(2282)
 def tree_conflicts_on_merge_no_local_ci_5_2(sbox):
   "tree conflicts 5.2: leaf del (no ci), tree del"
@@ -1188,25 +1185,25 @@ def tree_conflicts_on_merge_no_local_ci_
     'F'                 : Item(status='  ', wc_rev='3'),
     'F/alpha'           : Item(status='D ', wc_rev='3', treeconflict='C'),
     'DD'                : Item(status='  ', wc_rev='3'),
-    'DD/D1'             : Item(status='D ', wc_rev='3', treeconflict='C'),
+    'DD/D1'             : Item(status='  ', wc_rev='3', treeconflict='C'),
     'DD/D1/D2'          : Item(status='D ', wc_rev='3'),
     'DF'                : Item(status='  ', wc_rev='3'),
-    'DF/D1'             : Item(status='D ', wc_rev='3', treeconflict='C'),
+    'DF/D1'             : Item(status='  ', wc_rev='3', treeconflict='C'),
     'DF/D1/beta'        : Item(status='D ', wc_rev='3'),
     'DDD'               : Item(status='  ', wc_rev='3'),
-    'DDD/D1'            : Item(status='D ', wc_rev='3', treeconflict='C'),
-    'DDD/D1/D2'         : Item(status='D ', wc_rev='3'),
+    'DDD/D1'            : Item(status='  ', wc_rev='3', treeconflict='C'),
+    'DDD/D1/D2'         : Item(status='  ', wc_rev='3'),
     'DDD/D1/D2/D3'      : Item(status='D ', wc_rev='3'),
     'DDF'               : Item(status='  ', wc_rev='3'),
-    'DDF/D1'            : Item(status='D ', wc_rev='3', treeconflict='C'),
-    'DDF/D1/D2'         : Item(status='D ', wc_rev='3'),
+    'DDF/D1'            : Item(status='  ', wc_rev='3', treeconflict='C'),
+    'DDF/D1/D2'         : Item(status='  ', wc_rev='3'),
     'DDF/D1/D2/gamma'   : Item(status='D ', wc_rev='3'),
     })
 
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase(
                "local_leaf_del_incoming_tree_del",
                leaf_del,
@@ -1255,7 +1252,7 @@ def tree_conflicts_on_merge_no_local_ci_
   expected_skip = svntest.wc.State('', {
     })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase(
                "local_tree_del_incoming_tree_del",
                tree_del,
@@ -1333,10 +1330,10 @@ def tree_conflicts_merge_edit_onto_missi
 
   # Currently this test fails because some parts of the merge
   # start succeeding. 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase(
                "local_tree_missing_incoming_leaf_edit",
-               svntest.actions.deep_trees_rmtree,
+               svntest.deeptrees.deep_trees_rmtree,
                leaf_edit,
                expected_output,
                expected_disk,
@@ -1405,10 +1402,10 @@ def tree_conflicts_merge_del_onto_missin
     'DF/D1'             : Item(verb='Skipped missing target'),
   })
 
-  svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+  svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
     [ DeepTreesTestCase(
                "local_tree_missing_incoming_leaf_del",
-               svntest.actions.deep_trees_rmtree,
+               svntest.deeptrees.deep_trees_rmtree,
                leaf_del,
                expected_output,
                expected_disk,
@@ -1724,7 +1721,6 @@ def merge_replace_causes_tree_conflict(s
   actions.run_and_verify_status(wc_dir, expected_status)
 
 #----------------------------------------------------------------------
-@XFail()
 @Issue(3806)
 def merge_replace_causes_tree_conflict2(sbox):
   "replace vs. delete tree-conflicts"
@@ -1785,13 +1781,18 @@ def merge_replace_causes_tree_conflict2(
                         'A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi',
                         status='D ')
 
+  # H is now a file. This hides the status of the descendants.
+  expected_status.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
+
   # Merge them one by one to see all the errors.
 
   ### A file-with-file replacement onto a deleted file.
   # svn merge $URL/A/mu $URL/branch/mu A/mu
   expected_stdout = expected_merge_output(None, [
     '   C ' + A_mu + '\n',  # merge
+    'A    ' + A_mu + '\n',  # merge
     " U   " + A + "\n",     # mergeinfo
+    " U   " + A_mu + "\n",  # mergeinfo -> 'RM' status
   ], target=A, two_url=True, tree_conflicts=1)
 
   actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'merge',
@@ -1803,13 +1804,14 @@ def merge_replace_causes_tree_conflict2(
   #
   #  D     C merge_tree_conflict_tests-23\A\mu
   #      >   local delete, incoming replace upon merge
-  expected_status.tweak('A/mu', status='R ', wc_rev='-', copied='+',
+  expected_status.tweak('A/mu', status='RM', wc_rev='-', copied='+',
                         treeconflict='C')
 
   ### A dir-with-dir replacement onto a deleted directory.
   # svn merge $URL/A/B $URL/branch/B A/B
   expected_stdout = expected_merge_output(None, [
     '   C ' + A_B_E + '\n',   # merge
+    'A    ' + A_B_E + '\n',   # merge
     " U   " + A_B + "\n",     # mergeinfo
   ], target=A_B, two_url=True, tree_conflicts=1)
 
@@ -1829,8 +1831,8 @@ def merge_replace_causes_tree_conflict2(
   # svn merge --depth=immediates $URL/A/D $URL/branch/D A/D
   expected_stdout = expected_merge_output(None, [
     '   C ' + A_D_H + '\n',   # merge
+    'A    ' + A_D_H + '\n',   # merge
     " U   " + A_D + "\n",     # mergeinfo
-    " U   " + A_D_G + "\n",
   ], target=A_D, two_url=True, tree_conflicts=1)
 
   actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'merge',
@@ -1849,7 +1851,9 @@ def merge_replace_causes_tree_conflict2(
   # svn merge $URL/A/D/G $URL/branch/D/G A/D/G
   expected_stdout = expected_merge_output(None, [
     '   C ' + A_D_G_pi + '\n',  # merge
-  ], target=A_D_G, elides=[A_D_G_pi, A_D_G], two_url=True, tree_conflicts=1)
+    'A    ' + A_D_G_pi + '\n',  # merge
+    " U   " + A_D_G + "\n",     # mergeinfo
+  ], target=A_D_G, two_url=True, tree_conflicts=1)
 
   actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'merge',
     url_A_D_G, url_branch_D_G, A_D_G)
@@ -1868,7 +1872,8 @@ def merge_replace_causes_tree_conflict2(
 
   # Check the tree conflict types:
   expected_stdout = '(R.*)|(Summary of conflicts.*)|(  Tree conflicts.*)' \
-                    '|(.*local delete, incoming replace upon merge.*)'
+                    '|(.*local delete, incoming replace upon merge.*)' \
+                    '|(      \>.*)'
   tree_conflicted_path = [A_B_E, A_mu, A_D_G_pi, A_D_H]
   for path in tree_conflicted_path:
     actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'st',
@@ -1878,7 +1883,6 @@ def merge_replace_causes_tree_conflict2(
 # Test for issue #4011 'merge of replacement on local delete fails'
 @SkipUnless(server_has_mergeinfo)
 @Issue(4011)
-@XFail()
 def merge_replace_on_del_fails(sbox):
   "merge replace on local delete fails"
 

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py Wed Feb 13 06:37:54 2013
@@ -266,9 +266,7 @@ def patch_absolute_paths(sbox):
   expected_output = [
     'U         %s\n' % os.path.join('A', 'B', 'E', 'alpha'),
     'Skipped missing target: \'%s\'\n' % lambda_path,
-    'Summary of conflicts:\n',
-    '  Skipped paths: 1\n'
-  ]
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
 
   alpha_contents = "This is the file 'alpha'.\nWhoooo whooooo whoooooooo!\n"
 
@@ -988,9 +986,7 @@ def patch_add_new_dir(sbox):
     'Skipped missing target: \'%s\'\n' % A_B_E_Y_new_path,
     'Skipped missing target: \'%s\'\n' % A_C_new_path,
     'Skipped missing target: \'%s\'\n' % A_Z_new_path,
-    'Summary of conflicts:\n',
-    '  Skipped paths: 3\n',
-  ]
+  ] + svntest.main.summary_of_conflicts(skipped_paths=3)
 
   # Create the unversioned obstructing directory
   os.mkdir(os.path.dirname(A_Z_new_path))
@@ -1174,9 +1170,7 @@ def patch_reject(sbox):
   expected_output = [
     'C         %s\n' % sbox.ospath('A/D/gamma'),
     '>         rejected hunk @@ -1,1 +1,1 @@\n',
-    'Summary of conflicts:\n',
-    '  Text conflicts: 1\n',
-  ]
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
 
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.tweak('A/D/gamma', contents=gamma_contents)
@@ -2456,9 +2450,7 @@ def patch_same_twice(sbox):
     '>         hunk @@ -6,6 +6,9 @@ already applied\n',
     '>         hunk @@ -14,11 +17,8 @@ already applied\n',
     'Skipped \'%s\'\n' % beta_path,
-    'Summary of conflicts:\n',
-    '  Skipped paths: 1\n',
-  ]
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
 
   expected_skip = wc.State('', {beta_path : Item(verb='Skipped')})
 
@@ -2543,9 +2535,7 @@ def patch_dir_properties(sbox):
   expected_output = [
     ' U        %s\n' % wc_dir,
     ' C        %s\n' % sbox.ospath('A/B'),
-    'Summary of conflicts:\n',
-    '  Property conflicts: 1\n',
-  ]
+  ] + svntest.main.summary_of_conflicts(prop_conflicts=1)
 
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.add({
@@ -3969,9 +3959,7 @@ def patch_delete_and_skip(sbox):
     'D         %s\n' % os.path.join('A', 'B', 'E', 'beta'),
     'D         %s\n' % os.path.join('A', 'B', 'E'),
     'Skipped missing target: \'%s\'\n' % skipped_path,
-    'Summary of conflicts:\n',
-    '  Skipped paths: 1\n'
-  ]
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
 
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.remove('A/B/E/alpha')
@@ -4402,9 +4390,7 @@ def single_line_mismatch(sbox):
   expected_output = [
     'C         %s\n' % sbox.ospath('test'),
     '>         rejected hunk @@ -1,1 +1,1 @@\n',
-    'Summary of conflicts:\n',
-    '  Text conflicts: 1\n',
-  ]
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
 
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'patch', patch_file_path, wc_dir)
@@ -4577,6 +4563,61 @@ def patch_apply_no_fuz(sbox):
   if not filecmp.cmp(sbox.ospath('test.txt'), sbox.ospath('test_v2.txt')):
     raise svntest.Failure("Patch result not identical")
 
+@XFail()
+def patch_lacking_trailing_eol_on_context(sbox):
+  "patch file lacking trailing eol on context"
+
+  # Apply a patch where a hunk (the only hunk, in this case) ends with a
+  # context line that has no EOL, where this context line is going to
+  # match an existing line that *does* have an EOL.
+  #
+  # Around trunk@1443700, 'svn patch' wrongly removed an EOL from the
+  # target file at that position.
+
+  sbox.build(read_only = True)
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = make_patch_path(sbox)
+
+  # Prepare
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_disk = svntest.main.greek_state.copy()
+
+  # Prepare the patch
+  unidiff_patch = [
+    "Index: iota\n",
+    "===================================================================\n",
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    # TODO: -1 +1
+    "@@ -1 +1,2 @@\n",
+    "+Some more bytes\n",
+    " This is the file 'iota'.", # No trailing \n on this context line!
+  ]
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  iota_contents = "This is the file 'iota'.\n"
+
+  expected_output = [ 'U         %s\n' % sbox.ospath('iota') ]
+
+  # Test where the no-EOL context line is the last line in the target.
+  expected_disk.tweak('iota', contents="Some more bytes\n" + iota_contents)
+  expected_status.tweak('iota', status='M ')
+  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)
+
+  # Test where the no-EOL context line is a non-last line in the target.
+  sbox.simple_revert('iota')
+  sbox.simple_append('iota', "Another line.\n")
+  expected_disk.tweak('iota', contents="Some more bytes\n" + iota_contents +
+                                       "Another line.\n")
+  expected_output = [ 'G         %s\n' % sbox.ospath('iota') ]
+  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
@@ -4628,6 +4669,7 @@ test_list = [ None,
               single_line_mismatch,
               patch_empty_file,
               patch_apply_no_fuz,
+              patch_lacking_trailing_eol_on_context,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py Wed Feb 13 06:37:54 2013
@@ -1796,7 +1796,7 @@ def rm_of_replaced_file(sbox):
   exit_code, output, errput = svntest.main.run_svn(None,
                                                    'proplist', '-v',
                                                    mu_path + '@base')
-  expected_output = svntest.verify.UnorderedRegexOutput([
+  expected_output = svntest.verify.UnorderedRegexListOutput([
       'Properties on',
       '  yellow',
       '    submarine',
@@ -2130,6 +2130,8 @@ def propget_redirection(sbox):
   # it refers to non-existent path-revs, but that is not relevant to
   # this test.  What matters is that it is a realistic 'big' mergeinfo
   # value (it is from Subversion's own 1.6.x branch in fact).
+  # Also, the syntax is wrong: every path should start with '/';
+  # Subversion currently silently corrects this.
   big_prop_val = "subversion/branches/1.5.x:872364-874936\n"           + \
   "subversion/branches/1.5.x-34184:874657-874741\n"                    + \
   "subversion/branches/1.5.x-34432:874744-874798\n"                    + \
@@ -2269,131 +2271,26 @@ def propget_redirection(sbox):
 
   # Check if the redirected output of svn pg -vR on the root of the WC
   # is what we expect.
+  expected_mergeinfo_displayed = [
+    '    /' + line for line in big_prop_val.splitlines(True) ]
   expected_output = [
     "Properties on '" + B_path +  "':\n", # Should ocur only once!
+    "  svn:mergeinfo\n",
+    ] + expected_mergeinfo_displayed + [
     "Properties on '" + C_path +  "':\n", # Should ocur only once!
+    "  svn:mergeinfo\n",
+    ] + expected_mergeinfo_displayed + [
     "Properties on '" + D_path +  "':\n", # Should ocur only once!
-    # Everything below should appear three times since this same
-    # mergeinfo value is set on three paths in the WC.
     "  svn:mergeinfo\n",
-    "    /subversion/branches/1.5.x:872364-874936\n",
-    "    /subversion/branches/1.5.x-34184:874657-874741\n",
-    "    /subversion/branches/1.5.x-34432:874744-874798\n",
-    "    /subversion/branches/1.5.x-issue3067:872184-872314\n",
-    "    /subversion/branches/1.5.x-issue3157:872165-872175\n",
-    "    /subversion/branches/1.5.x-issue3174:872178-872348\n",
-    "    /subversion/branches/1.5.x-r30215:870310,870312,870319,870362\n",
-    "    /subversion/branches/1.5.x-r30756:874853-874870\n",
-    "    /subversion/branches/1.5.x-r30868:870951-870970\n",
-    "    /subversion/branches/1.5.x-r31314:874476-874605\n",
-    "    /subversion/branches/1.5.x-r31516:871592-871649\n",
-    "    /subversion/branches/1.5.x-r32470:872546-872676\n",
-    "    /subversion/branches/1.5.x-r32968:873773-873872\n",
-    "    /subversion/branches/1.5.x-r33447:873527-873547\n",
-    "    /subversion/branches/1.5.x-r33465:873541-873549\n",
-    "    /subversion/branches/1.5.x-r33641:873880-873883\n",
-    "    /subversion/branches/1.5.x-r34050-followups:874639-874686\n",
-    "    /subversion/branches/1.5.x-r34487:874562-874581\n",
-    "    /subversion/branches/1.5.x-ra_serf-backports:872354-872626\n",
-    "    /subversion/branches/1.5.x-rb-test-fix:874916-874919\n",
-    "    /subversion/branches/1.5.x-reintegrate-improvements:874586-874922\n",
-    "    /subversion/branches/1.5.x-tests-pass:870925-870973\n",
-    "    /subversion/branches/dont-save-plaintext-passwords-by-default:"
-    "870728-871118\n",
-    "    /subversion/branches/gnome-keyring:870558-871410\n",
-    "    /subversion/branches/issue-3220-dev:872210-872226\n",
-    "    /subversion/branches/kwallet:870785-871314\n",
-    "    /subversion/branches/log-g-performance:870941-871032\n",
-    "    /subversion/branches/r30963-1.5.x:871056-871076\n",
-    "    /subversion/branches/reintegrate-improvements:873853-874164\n",
-    "    /subversion/branches/svn-mergeinfo-enhancements:870196\n",
-    "    /subversion/branches/svnpatch-diff:871905\n",
-    "    /subversion/trunk:869159-869165,869168-869181,869185,869188,869191,"
-    "869200-869201,869203-869207,869209-869224,869227-869238,869240-869244,"
-    "869248,869250-869260,869262-869263,869265,869267-869268,869272-869280,"
-    "869282-869325,869328-869330,869335,869341-869347,869351,869354-869355,"
-    "869358,869361-869377,869379-869381,869383-869417,869419-869422,869432-"
-    "869453,869455-869466,869471-869473,869475,869483,869486,869488-869489,"
-    "869491-869497,869499-869500,869503,869506-869508,869510-869521,869523-"
-    "869540,869542-869552,869556,869558,869560-869561,869563,869565,869567,"
-    "869570,869572,869582,869601-869602,869605,869607,869613-869614,869616,"
-    "869618,869620,869625,869627,869630,869633,869639,869641-869643,869645-"
-    "869652,869655,869657,869665,869668,869674,869677,869681,869685,869687-"
-    "869688,869693,869697,869699-869700,869704-869708,869716,869719,869722,"
-    "869724,869730,869733-869734,869737-869740,869745-869746,869751-869754,"
-    "869766,869812-869813,869815-869818,869820,869825,869837,869841,869843-"
-    "869844,869858,869860-869861,869871,869875,869889,869895,869898,869902,"
-    "869907,869909,869926,869928-869929,869931-869933,869942-869943,869950,"
-    "869952,869957-869958,869969,869972,869974,869988,869994,869996,869999,"
-    "870004,870013-870014,870016,870024,870032,870036,870039,870041-870043,"
-    "870054,870060,870068-870071,870078,870083,870094,870104,870124,870127-"
-    "870128,870133,870135-870136,870141,870144,870148,870160,870172,870175,"
-    "870191,870198,870203-870204,870211,870219,870225,870233,870235-870236,"
-    "870254-870255,870259,870307,870311,870313,870320,870323,870330-870331,"
-    "870352-870353,870355,870359-870360,870371,870373,870378,870393-870395,"
-    "870402,870409-870410,870414,870416,870421,870436,870442,870447,870449,"
-    "870452,870454,870466,870476,870481-870483,870486,870500,870502,870505,"
-    "870513-870518,870522-870523,870527,870529,870534,870536-870538,870540-"
-    "870541,870543-870548,870554,870556,870561,870563,870584,870590-870592,"
-    "870594-870595,870597,870618,870620,870622,870625-870626,870641,870647,"
-    "870657,870665,870671,870681,870702-870703,870706-870708,870717-870718,"
-    "870727,870730,870737,870740,870742,870752,870758,870800,870809,870815,"
-    "870817,870820-870825,870830,870834-870836,870850-870851,870853,870859,"
-    "870861,870886,870894,870916-870918,870942,870945,870957,870962,870970,"
-    "870979,870981,870989,870996,871003,871005,871009,871011,871023,871033,"
-    "871035-871038,871041,871060,871078,871080,871092,871097,871099,871105,"
-    "871107,871120,871123-871127,871130,871133-871135,871140,871149,871155-"
-    "871156,871160,871162,871164,871181,871191,871199-871200,871205,871211-"
-    "871212,871215,871219,871225,871227,871229,871231,871236,871270,871273,"
-    "871277,871283,871297,871302,871306,871308,871315-871320,871323-871325,"
-    "871333-871335,871345,871347-871350,871354,871357,871361,871363-871366,"
-    "871374-871375,871377,871382,871385-871388,871391,871408,871411,871422,"
-    "871435,871441,871443-871444,871465,871470,871472-871476,871481,871489,"
-    "871499,871501-871502,871505,871508,871520,871523,871525-871527,871538,"
-    "871542,871544,871547-871549,871556,871559,871562-871563,871578,871581,"
-    "871587,871589-871597,871608,871613,871616-871617,871620,871624,871649,"
-    "871668,871675,871677,871693-871694,871696,871704,871732-871733,871744,"
-    "871747,871759,871762,871766,871769,871793,871796,871799,871801,871811,"
-    "871813,871821-871826,871831,871843,871860,871880,871891,871894,871899,"
-    "871907,871911,871926,871928,871933,871935,871941-871942,871947-871949,"
-    "871958,871974,872000-872001,872003,872005,872018,872022,872038,872065,"
-    "872068,872086,872091,872093,872097,872103,872112,872130,872154,872157,"
-    "872206,872216,872218-872219,872227,872234,872238,872243,872253,872255,"
-    "872259,872261,872278-872279,872281,872310-872311,872362,872404,872416-"
-    "872417,872429,872431,872434,872439,872450-872453,872468,872470,872477-"
-    "872478,872483,872490-872491,872495,872515-872516,872518-872519,872537,"
-    "872541,872544,872565,872568,872571-872573,872584,872596-872597,872612,"
-    "872619,872624,872632,872656,872670,872706,872710,872713,872717,872746-"
-    "872748,872777,872780-872782,872791,872804,872813,872845,872864,872870,"
-    "872872,872947-872948,872961,872974,872981,872985-872987,873004,873042,"
-    "873049,873051,873076,873087,873090,873096,873098,873100,873183,873186,"
-    "873192,873195,873210-873211,873247,873252,873256,873259,873275,873286,"
-    "873288,873343,873379-873381,873443,873521,873538-873539,873714-873715,"
-    "873718,873733,873745,873751,873767,873778,873781,873849,873856,873862,"
-    "873914,873940,873947-873948,873975-873976,873987,873998,874026-874027,"
-    "874075,874077-874078,874124-874125,874127,874156,874159,874161,874165,"
-    "874168,874170,874184,874189,874204,874223-874224,874245,874258,874262,"
-    "874270,874292-874297,874300-874301,874303,874305,874316-874318,874330,"
-    "874363,874380,874405,874421,874441,874459,874467,874473,874497,874506,"
-    "874545-874546,874561,874566,874568,874580,874619,874621,874634,874636,"
-    "874659,874673,874681,874727,874730,874743,874765-874767,874806,874816,"
-    "874848,874868,874888,874896,874909,874912,874996,875051,875069,875129,"
-    "875132,875134,875137,875151-875153,875186-875188,875190,875235-875237,"
-    "875242-875243,875249,875388,875393,875406,875411\n"]
+    ] + expected_mergeinfo_displayed
   svntest.verify.verify_outputs(
     "Redirected pg -vR doesn't match pg -vR stdout",
     pg_stdout_redir, None,
     svntest.verify.UnorderedOutput(expected_output), None)
-  # Because we are using UnorderedOutput above, this test would spuriously
-  # pass if the redirected pg output contained duplicates.  This hasn't been
-  # observed as part of issue #3721, but we might as well be thorough...
-  #
-  # ...Since we've set the same mergeinfo prop on A/B, A/C, and A/D, this
-  # means the number of lines in the redirected output of svn pg -vR should
-  # be three times the number of lines in EXPECTED_OUTPUT, adjusted for the
-  # fact the "Properties on '[A/B | A/C | A/D]'" headers  appear only once.
-  if ((len(expected_output) * 3) - 6) != len(pg_stdout_redir):
-    raise svntest.Failure("Redirected pg -vR has unexpected duplicates")
+  # (We want this check to fail if the redirected pg output contains
+  # unexpected duplicate lines, although this hasn't been observed as
+  # part of issue #3721.  We used to check separately here because the old
+  # UnorderedOutput class ignored duplicates but now it detects them.)
 
 @Issue(3852)
 def file_matching_dir_prop_reject(sbox):

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py Wed Feb 13 06:37:54 2013
@@ -1444,7 +1444,7 @@ def revert_tree_conflicts_with_replaceme
   # Revert everything (i.e., accept "theirs-full").
   svntest.actions.run_and_verify_revert([
     wc('A/B/E'),
-    wc('A/B/E/alpha'),   # incoming
+    wc('A/B/E/alpha'),   # incoming & local
     wc('A/B/E/beta'),
     wc('A/B/E/loc_beta'),
     wc('A/B/lambda'),
@@ -1459,7 +1459,6 @@ def revert_tree_conflicts_with_replaceme
     wc('A/D/H/loc_psi'),
     wc('A/D/gamma'),
     wc('A/mu'),
-    wc('A/B/E/alpha'),
     ], '-R', wc_dir)
 
   # Remove a few unversioned files that revert left behind.

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py Wed Feb 13 06:37:54 2013
@@ -1073,9 +1073,7 @@ def status_add_plus_conflict(sbox):
     "?       " + sbox.ospath('trunk/file.merge-right.r5') + "\n",
     "?       " + sbox.ospath('trunk/file.working') + "\n",
     "C  +    " + sbox.ospath('trunk/file') + "\n",
-    "Summary of conflicts:\n",
-    "  Text conflicts: 1\n",
-  ]
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
   if svntest.main.server_has_mergeinfo():
     lines.append(" M      " + sbox.ospath('trunk') + "\n")
 
@@ -1745,9 +1743,7 @@ def status_with_tree_conflicts(sbox):
           "      >   local file delete, incoming file edit upon update\n",
           "!     C %s\n" % tau,
           "      >   local file delete, incoming file delete upon update\n",
-          "Summary of conflicts:\n",
-          "  Tree conflicts: 3\n",
-          ])
+         ] + svntest.main.summary_of_conflicts(tree_conflicts=3))
 
   svntest.actions.run_and_verify_svn(None,
                                      expected,
@@ -1763,10 +1759,7 @@ def status_with_tree_conflicts(sbox):
           "      >   local file edit, incoming file delete upon update\n",
           "!     C                                  %s\n" % tau,
           "      >   local file delete, incoming file delete upon update\n",
-          "Summary of conflicts:\n",
-          "  Tree conflicts: 3\n",
-          ])
-
+         ] + svntest.main.summary_of_conflicts(tree_conflicts=3))
 
   svntest.actions.run_and_verify_svn(None,
                                      expected,

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py Wed Feb 13 06:37:54 2013
@@ -1499,44 +1499,31 @@ def test_lslocks_and_rmlocks(sbox):
                                      [], "lock", "-m", "Locking files",
                                      iota_url, lambda_url)
 
-  expected_output_list = [
-      "Path: /A/B/lambda",
+  def expected_output_list(path):
+    return [
+      "Path: " + path,
       "UUID Token: opaquelocktoken",
       "Owner: jrandom",
       "Created:",
       "Expires:",
       "Comment \(1 line\):",
       "Locking files",
-      "Path: /iota",
-      "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',
-                                             'output',
-                                             expected_output, output)
-  except:
-    # Usually both locks have the same timestamp but if the clock
-    # ticks between creating the two locks then the timestamps will
-    # differ.  When the output has two identical "Created" lines
-    # UnorderedRegexOutput must have one matching regex, when the
-    # output has two different "Created" lines UnorderedRegexOutput
-    # must have two regex.
-    expected_output_list.append("Created:.*")
-    expected_output = svntest.verify.UnorderedRegexOutput(expected_output_list)
-    svntest.verify.compare_and_display_lines('lslocks output mismatch',
-                                             'output',
-                                             expected_output, output)
+  expected_output = svntest.verify.UnorderedRegexListOutput(
+                                     expected_output_list('/A/B/lambda') +
+                                     expected_output_list('/iota'))
+  svntest.verify.compare_and_display_lines('lslocks output mismatch',
+                                           'output',
+                                           expected_output, output)
 
   # List lock in path /A
   exit_code, output, errput = svntest.main.run_svnadmin("lslocks",
@@ -1545,18 +1532,10 @@ def test_lslocks_and_rmlocks(sbox):
   if errput:
     raise SVNUnexpectedStderr(errput)
 
-  expected_output = svntest.verify.UnorderedRegexOutput([
-    "Path: /A/B/lambda",
-    "UUID Token: opaquelocktoken",
-    "Owner: jrandom",
-    "Created:",
-    "Expires:",
-    "Comment \(1 line\):",
-    "Locking files",
-    "\n", # empty line
-    ])
-
-  svntest.verify.compare_and_display_lines('message', 'label',
+  expected_output = svntest.verify.RegexListOutput(
+                                     expected_output_list('/A/B/lambda'))
+  svntest.verify.compare_and_display_lines('lslocks output mismatch',
+                                           'output',
                                            expected_output, output)
   svntest.verify.verify_exit_code(None, exit_code, 0)
 

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py Wed Feb 13 06:37:54 2013
@@ -138,12 +138,16 @@ def run_dump_test(sbox, dumpfile_name, e
                                     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
+                                  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)
 
     svntest.verify.compare_and_display_lines(
       "Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile,
-      None, mismatched_headers_re)
+      None)
 
   else:
     compare_repos_dumps(sbox, svnadmin_dumpfile)

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py Wed Feb 13 06:37:54 2013
@@ -40,6 +40,9 @@ from svntest import Failure
 
 logger = logging.getLogger()
 
+# (abbreviation)
+Item = svntest.wc.StateItem
+
 def _log_tree_state(msg, actual, subtree=""):
   if subtree:
     subtree += os.sep
@@ -86,16 +89,10 @@ def setup_pristine_greek_repository():
     # import the greek tree, using l:foo/p:bar
     ### todo: svn should not be prompting for auth info when using
     ### repositories with no auth/auth requirements
-    exit_code, output, errput = main.run_svn(None, 'import', '-m',
-                                             'Log message for revision 1.',
-                                             main.greek_dump_dir,
-                                             main.pristine_greek_repos_url)
-
-    # check for any errors from the import
-    if len(errput):
-      display_lines("Errors during initial 'svn import':",
-                    'STDERR', None, errput)
-      sys.exit(1)
+    _, output, _ = main.run_svn(None, 'import', '-m',
+                                'Log message for revision 1.',
+                                main.greek_dump_dir,
+                                main.pristine_greek_repos_url)
 
     # verify the printed output of 'svn import'.
     lastline = output.pop().strip()
@@ -1461,47 +1458,50 @@ def run_and_verify_commit(wc_dir_name, o
 
 # This function always passes '-q' to the status command, which
 # suppresses the printing of any unversioned or nonexistent items.
-def run_and_verify_status(wc_dir_name, output_tree,
+def run_and_verify_status(wc_dir_name, status_tree,
                           singleton_handler_a = None,
                           a_baton = None,
                           singleton_handler_b = None,
                           b_baton = None):
   """Run 'status' on WC_DIR_NAME and compare it with the
-  expected OUTPUT_TREE.  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will
+  expected STATUS_TREE.  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will
   be passed to tree.compare_trees - see that function's doc string for
   more details.
   Returns on success, raises on failure."""
 
-  if isinstance(output_tree, wc.State):
-    output_state = output_tree
-    output_tree = output_tree.old_tree()
-  else:
-    output_state = None
-
   exit_code, output, errput = main.run_svn(None, 'status', '-v', '-u', '-q',
                                            wc_dir_name)
 
-  actual = tree.build_tree_from_status(output, wc_dir_name=wc_dir_name)
+  actual_status = svntest.wc.State.from_status(output)
 
   # Verify actual output against expected output.
-  try:
-    tree.compare_trees("status", actual, output_tree,
-                       singleton_handler_a, a_baton,
-                       singleton_handler_b, b_baton)
-  except tree.SVNTreeError:
-    verify.display_trees(None, 'STATUS OUTPUT TREE', output_tree, actual)
-    _log_tree_state("ACTUAL STATUS TREE:", actual, wc_dir_name)
-    raise
+  if isinstance(status_tree, wc.State):
+    try:
+      status_tree.compare_and_display('status', actual_status)
+    except tree.SVNTreeError:
+      _log_tree_state("ACTUAL STATUS TREE:", actual_status.old_tree(),
+                                             wc_dir_name)
+      raise
+  else:
+    actual_status = actual_status.old_tree()
+    try:
+      tree.compare_trees("status", actual_status, status_tree,
+                         singleton_handler_a, a_baton,
+                         singleton_handler_b, b_baton)
+    except tree.SVNTreeError:
+      verify.display_trees(None, 'STATUS OUTPUT TREE', status_tree, actual_status)
+      _log_tree_state("ACTUAL STATUS TREE:", actual_status, wc_dir_name)
+      raise
 
   # if we have an output State, and we can/are-allowed to create an
   # entries-based State, then compare the two.
-  if output_state:
-    entries_state = wc.State.from_entries(wc_dir_name)
-    if entries_state:
-      tweaked = output_state.copy()
+  if isinstance(status_tree, wc.State):
+    actual_entries = wc.State.from_entries(wc_dir_name)
+    if actual_entries:
+      tweaked = status_tree.copy()
       tweaked.tweak_for_entries_compare()
       try:
-        tweaked.compare_and_display('entries', entries_state)
+        tweaked.compare_and_display('entries', actual_entries)
       except tree.SVNTreeUnequal:
         ### do something more
         raise
@@ -1514,20 +1514,27 @@ def run_and_verify_unquiet_status(wc_dir
   expected STATUS_TREE.
   Returns on success, raises on failure."""
 
-  if isinstance(status_tree, wc.State):
-    status_tree = status_tree.old_tree()
-
   exit_code, output, errput = main.run_svn(None, 'status', '-v',
                                            '-u', wc_dir_name)
 
-  actual = tree.build_tree_from_status(output, wc_dir_name=wc_dir_name)
+  actual_status = svntest.wc.State.from_status(output)
 
   # Verify actual output against expected output.
-  try:
-    tree.compare_trees("UNQUIET STATUS", actual, status_tree)
-  except tree.SVNTreeError:
-    _log_tree_state("ACTUAL UNQUIET STATUS TREE:", actual, wc_dir_name)
-    raise
+  if isinstance(status_tree, wc.State):
+    try:
+      status_tree.compare_and_display('unquiet status', actual_status)
+    except tree.SVNTreeError:
+      _log_tree_state("ACTUAL STATUS TREE:",
+                      actual_status.normalize().old_tree(), wc_dir_name)
+      raise
+  else:
+    actual_status = actual_status.old_tree()
+    try:
+      tree.compare_trees("UNQUIET STATUS", actual_status, status_tree)
+    except tree.SVNTreeError:
+      _log_tree_state("ACTUAL UNQUIET STATUS TREE:", actual_status,
+                                                     wc_dir_name)
+      raise
 
 def run_and_verify_status_xml(expected_entries = [],
                               *args):
@@ -2213,980 +2220,3 @@ def build_greek_tree_conflicts(sbox):
   run_and_verify_svn(None, verify.AnyOutput, [], 'update', wc_dir)
 
 
-def make_deep_trees(base):
-  """Helper function for deep trees conflicts. Create a set of trees,
-  each in its own "container" dir. Any conflicts can be tested separately
-  in each container.
-  """
-  j = os.path.join
-  # Create the container dirs.
-  F   = j(base, 'F')
-  D   = j(base, 'D')
-  DF  = j(base, 'DF')
-  DD  = j(base, 'DD')
-  DDF = j(base, 'DDF')
-  DDD = j(base, 'DDD')
-  os.makedirs(F)
-  os.makedirs(j(D, 'D1'))
-  os.makedirs(j(DF, 'D1'))
-  os.makedirs(j(DD, 'D1', 'D2'))
-  os.makedirs(j(DDF, 'D1', 'D2'))
-  os.makedirs(j(DDD, 'D1', 'D2', 'D3'))
-
-  # Create their files.
-  alpha = j(F, 'alpha')
-  beta  = j(DF, 'D1', 'beta')
-  gamma = j(DDF, 'D1', 'D2', 'gamma')
-  main.file_append(alpha, "This is the file 'alpha'.\n")
-  main.file_append(beta, "This is the file 'beta'.\n")
-  main.file_append(gamma, "This is the file 'gamma'.\n")
-
-
-def add_deep_trees(sbox, base_dir_name):
-  """Prepare a "deep_trees" within a given directory.
-
-  The directory <sbox.wc_dir>/<base_dir_name> is created and a deep_tree
-  is created within. The items are only added, a commit has to be
-  called separately, if needed.
-
-  <base_dir_name> will thus be a container for the set of containers
-  mentioned in make_deep_trees().
-  """
-  j = os.path.join
-  base = j(sbox.wc_dir, base_dir_name)
-  make_deep_trees(base)
-  main.run_svn(None, 'add', base)
-
-
-Item = wc.StateItem
-
-# initial deep trees state
-deep_trees_virginal_state = wc.State('', {
-  'F'               : Item(),
-  'F/alpha'         : Item("This is the file 'alpha'.\n"),
-  'D'               : Item(),
-  'D/D1'            : Item(),
-  'DF'              : Item(),
-  'DF/D1'           : Item(),
-  'DF/D1/beta'      : Item("This is the file 'beta'.\n"),
-  'DD'              : Item(),
-  'DD/D1'           : Item(),
-  'DD/D1/D2'        : Item(),
-  'DDF'             : Item(),
-  'DDF/D1'          : Item(),
-  'DDF/D1/D2'       : Item(),
-  'DDF/D1/D2/gamma' : Item("This is the file 'gamma'.\n"),
-  'DDD'             : Item(),
-  'DDD/D1'          : Item(),
-  'DDD/D1/D2'       : Item(),
-  'DDD/D1/D2/D3'    : Item(),
-  })
-
-
-# Many actions on deep trees and their resulting states...
-
-def deep_trees_leaf_edit(base):
-  """Helper function for deep trees test cases. Append text to files,
-  create new files in empty directories, and change leaf node properties."""
-  j = os.path.join
-  F   = j(base, 'F', 'alpha')
-  DF  = j(base, 'DF', 'D1', 'beta')
-  DDF = j(base, 'DDF', 'D1', 'D2', 'gamma')
-  main.file_append(F, "More text for file alpha.\n")
-  main.file_append(DF, "More text for file beta.\n")
-  main.file_append(DDF, "More text for file gamma.\n")
-  run_and_verify_svn(None, verify.AnyOutput, [],
-                     'propset', 'prop1', '1', F, DF, DDF)
-
-  D   = j(base, 'D', 'D1')
-  DD  = j(base, 'DD', 'D1', 'D2')
-  DDD = j(base, 'DDD', 'D1', 'D2', 'D3')
-  run_and_verify_svn(None, verify.AnyOutput, [],
-                     'propset', 'prop1', '1', D, DD, DDD)
-  D   = j(base, 'D', 'D1', 'delta')
-  DD  = j(base, 'DD', 'D1', 'D2', 'epsilon')
-  DDD = j(base, 'DDD', 'D1', 'D2', 'D3', 'zeta')
-  main.file_append(D, "This is the file 'delta'.\n")
-  main.file_append(DD, "This is the file 'epsilon'.\n")
-  main.file_append(DDD, "This is the file 'zeta'.\n")
-  run_and_verify_svn(None, verify.AnyOutput, [],
-                     'add', D, DD, DDD)
-
-# deep trees state after a call to deep_trees_leaf_edit
-deep_trees_after_leaf_edit = wc.State('', {
-  'F'                 : Item(),
-  'F/alpha'           : Item("This is the file 'alpha'.\nMore text for file alpha.\n"),
-  'D'                 : Item(),
-  'D/D1'              : Item(),
-  'D/D1/delta'        : Item("This is the file 'delta'.\n"),
-  'DF'                : Item(),
-  'DF/D1'             : Item(),
-  'DF/D1/beta'        : Item("This is the file 'beta'.\nMore text for file beta.\n"),
-  'DD'                : Item(),
-  'DD/D1'             : Item(),
-  'DD/D1/D2'          : Item(),
-  'DD/D1/D2/epsilon'  : Item("This is the file 'epsilon'.\n"),
-  'DDF'               : Item(),
-  'DDF/D1'            : Item(),
-  'DDF/D1/D2'         : Item(),
-  'DDF/D1/D2/gamma'   : Item("This is the file 'gamma'.\nMore text for file gamma.\n"),
-  'DDD'               : Item(),
-  'DDD/D1'            : Item(),
-  'DDD/D1/D2'         : Item(),
-  'DDD/D1/D2/D3'      : Item(),
-  'DDD/D1/D2/D3/zeta' : Item("This is the file 'zeta'.\n"),
-  })
-
-
-def deep_trees_leaf_del(base):
-  """Helper function for deep trees test cases. Delete files and empty
-  dirs."""
-  j = os.path.join
-  F   = j(base, 'F', 'alpha')
-  D   = j(base, 'D', 'D1')
-  DF  = j(base, 'DF', 'D1', 'beta')
-  DD  = j(base, 'DD', 'D1', 'D2')
-  DDF = j(base, 'DDF', 'D1', 'D2', 'gamma')
-  DDD = j(base, 'DDD', 'D1', 'D2', 'D3')
-  main.run_svn(None, 'rm', F, D, DF, DD, DDF, DDD)
-
-# deep trees state after a call to deep_trees_leaf_del
-deep_trees_after_leaf_del = wc.State('', {
-  'F'               : Item(),
-  'D'               : Item(),
-  'DF'              : Item(),
-  'DF/D1'           : Item(),
-  'DD'              : Item(),
-  'DD/D1'           : Item(),
-  'DDF'             : Item(),
-  'DDF/D1'          : Item(),
-  'DDF/D1/D2'       : Item(),
-  'DDD'             : Item(),
-  'DDD/D1'          : Item(),
-  'DDD/D1/D2'       : Item(),
-  })
-
-# deep trees state after a call to deep_trees_leaf_del with no commit
-def deep_trees_after_leaf_del_no_ci(wc_dir):
-  if svntest.main.wc_is_singledb(wc_dir):
-    return deep_trees_after_leaf_del
-  else:
-    return deep_trees_empty_dirs
-
-
-def deep_trees_tree_del(base):
-  """Helper function for deep trees test cases.  Delete top-level dirs."""
-  j = os.path.join
-  F   = j(base, 'F', 'alpha')
-  D   = j(base, 'D', 'D1')
-  DF  = j(base, 'DF', 'D1')
-  DD  = j(base, 'DD', 'D1')
-  DDF = j(base, 'DDF', 'D1')
-  DDD = j(base, 'DDD', 'D1')
-  main.run_svn(None, 'rm', F, D, DF, DD, DDF, DDD)
-
-def deep_trees_rmtree(base):
-  """Helper function for deep trees test cases.  Delete top-level dirs
-     with rmtree instead of svn del."""
-  j = os.path.join
-  F   = j(base, 'F', 'alpha')
-  D   = j(base, 'D', 'D1')
-  DF  = j(base, 'DF', 'D1')
-  DD  = j(base, 'DD', 'D1')
-  DDF = j(base, 'DDF', 'D1')
-  DDD = j(base, 'DDD', 'D1')
-  os.unlink(F)
-  main.safe_rmtree(D)
-  main.safe_rmtree(DF)
-  main.safe_rmtree(DD)
-  main.safe_rmtree(DDF)
-  main.safe_rmtree(DDD)
-
-# deep trees state after a call to deep_trees_tree_del
-deep_trees_after_tree_del = wc.State('', {
-  'F'                 : Item(),
-  'D'                 : Item(),
-  'DF'                : Item(),
-  'DD'                : Item(),
-  'DDF'               : Item(),
-  'DDD'               : Item(),
-  })
-
-# deep trees state without any files
-deep_trees_empty_dirs = wc.State('', {
-  'F'               : Item(),
-  'D'               : Item(),
-  'D/D1'            : Item(),
-  'DF'              : Item(),
-  'DF/D1'           : Item(),
-  'DD'              : Item(),
-  'DD/D1'           : Item(),
-  'DD/D1/D2'        : Item(),
-  'DDF'             : Item(),
-  'DDF/D1'          : Item(),
-  'DDF/D1/D2'       : Item(),
-  'DDD'             : Item(),
-  'DDD/D1'          : Item(),
-  'DDD/D1/D2'       : Item(),
-  'DDD/D1/D2/D3'    : Item(),
-  })
-
-# deep trees state after a call to deep_trees_tree_del with no commit
-def deep_trees_after_tree_del_no_ci(wc_dir):
-  if svntest.main.wc_is_singledb(wc_dir):
-    return deep_trees_after_tree_del
-  else:
-    return deep_trees_empty_dirs
-
-def deep_trees_tree_del_repos(base):
-  """Helper function for deep trees test cases.  Delete top-level dirs,
-  directly in the repository."""
-  j = '/'.join
-  F   = j([base, 'F', 'alpha'])
-  D   = j([base, 'D', 'D1'])
-  DF  = j([base, 'DF', 'D1'])
-  DD  = j([base, 'DD', 'D1'])
-  DDF = j([base, 'DDF', 'D1'])
-  DDD = j([base, 'DDD', 'D1'])
-  main.run_svn(None, 'mkdir', '-m', '', F, D, DF, DD, DDF, DDD)
-
-# Expected merge/update/switch output.
-
-deep_trees_conflict_output = wc.State('', {
-  'F/alpha'           : Item(status='  ', treeconflict='C'),
-  'D/D1'              : Item(status='  ', treeconflict='C'),
-  'DF/D1'             : Item(status='  ', treeconflict='C'),
-  'DD/D1'             : Item(status='  ', treeconflict='C'),
-  'DDF/D1'            : Item(status='  ', treeconflict='C'),
-  'DDD/D1'            : Item(status='  ', treeconflict='C'),
-  })
-
-deep_trees_conflict_output_skipped = wc.State('', {
-  'D/D1'              : Item(verb='Skipped'),
-  'F/alpha'           : Item(verb='Skipped'),
-  'DD/D1'             : Item(verb='Skipped'),
-  'DF/D1'             : Item(verb='Skipped'),
-  'DDD/D1'            : Item(verb='Skipped'),
-  'DDF/D1'            : Item(verb='Skipped'),
-  })
-
-# Expected status output after merge/update/switch.
-
-deep_trees_status_local_tree_del = wc.State('', {
-  ''                  : Item(status='  ', wc_rev=3),
-  'D'                 : Item(status='  ', wc_rev=3),
-  'D/D1'              : Item(status='D ', wc_rev=2, treeconflict='C'),
-  'DD'                : Item(status='  ', wc_rev=3),
-  'DD/D1'             : Item(status='D ', wc_rev=2, treeconflict='C'),
-  'DD/D1/D2'          : Item(status='D ', wc_rev=2),
-  'DDD'               : Item(status='  ', wc_rev=3),
-  'DDD/D1'            : Item(status='D ', wc_rev=2, treeconflict='C'),
-  'DDD/D1/D2'         : Item(status='D ', wc_rev=2),
-  'DDD/D1/D2/D3'      : Item(status='D ', wc_rev=2),
-  'DDF'               : Item(status='  ', wc_rev=3),
-  'DDF/D1'            : Item(status='D ', wc_rev=2, treeconflict='C'),
-  'DDF/D1/D2'         : Item(status='D ', wc_rev=2),
-  'DDF/D1/D2/gamma'   : Item(status='D ', wc_rev=2),
-  'DF'                : Item(status='  ', wc_rev=3),
-  'DF/D1'             : Item(status='D ', wc_rev=2, treeconflict='C'),
-  'DF/D1/beta'        : Item(status='D ', wc_rev=2),
-  'F'                 : Item(status='  ', wc_rev=3),
-  'F/alpha'           : Item(status='D ', wc_rev=2, treeconflict='C'),
-  })
-
-deep_trees_status_local_leaf_edit = wc.State('', {
-  ''                  : Item(status='  ', wc_rev=3),
-  'D'                 : Item(status='  ', wc_rev=3),
-  'D/D1'              : Item(status=' M', wc_rev=2, treeconflict='C'),
-  'D/D1/delta'        : Item(status='A ', wc_rev=0),
-  'DD'                : Item(status='  ', wc_rev=3),
-  'DD/D1'             : Item(status='  ', wc_rev=2, treeconflict='C'),
-  'DD/D1/D2'          : Item(status=' M', wc_rev=2),
-  'DD/D1/D2/epsilon'  : Item(status='A ', wc_rev=0),
-  'DDD'               : Item(status='  ', wc_rev=3),
-  'DDD/D1'            : Item(status='  ', wc_rev=2, treeconflict='C'),
-  'DDD/D1/D2'         : Item(status='  ', wc_rev=2),
-  'DDD/D1/D2/D3'      : Item(status=' M', wc_rev=2),
-  'DDD/D1/D2/D3/zeta' : Item(status='A ', wc_rev=0),
-  'DDF'               : Item(status='  ', wc_rev=3),
-  'DDF/D1'            : Item(status='  ', wc_rev=2, treeconflict='C'),
-  'DDF/D1/D2'         : Item(status='  ', wc_rev=2),
-  'DDF/D1/D2/gamma'   : Item(status='MM', wc_rev=2),
-  'DF'                : Item(status='  ', wc_rev=3),
-  'DF/D1'             : Item(status='  ', wc_rev=2, treeconflict='C'),
-  'DF/D1/beta'        : Item(status='MM', wc_rev=2),
-  'F'                 : Item(status='  ', wc_rev=3),
-  'F/alpha'           : Item(status='MM', wc_rev=2, treeconflict='C'),
-  })
-
-
-class DeepTreesTestCase:
-  """Describes one tree-conflicts test case.
-  See deep_trees_run_tests_scheme_for_update(), ..._switch(), ..._merge().
-
-  The name field is the subdirectory name in which the test should be run.
-
-  The local_action and incoming_action are the functions to run
-  to construct the local changes and incoming changes, respectively.
-  See deep_trees_leaf_edit, deep_trees_tree_del, etc.
-
-  The expected_* and error_re_string arguments are described in functions
-  run_and_verify_[update|switch|merge]
-  except expected_info, which is a dict that has path keys with values
-  that are dicts as passed to run_and_verify_info():
-    expected_info = {
-      'F/alpha' : {
-        'Revision' : '3',
-        'Tree conflict' :
-          '^local delete, incoming edit upon update'
-          + ' Source  left: .file.*/F/alpha@2'
-          + ' Source right: .file.*/F/alpha@3$',
-      },
-      'DF/D1' : {
-        'Tree conflict' :
-          '^local delete, incoming edit upon update'
-          + ' Source  left: .dir.*/DF/D1@2'
-          + ' Source right: .dir.*/DF/D1@3$',
-      },
-      ...
-    }
-
-  Note: expected_skip is only used in merge, i.e. using
-  deep_trees_run_tests_scheme_for_merge.
-  """
-
-  def __init__(self, name, local_action, incoming_action,
-                expected_output = None, expected_disk = None,
-                expected_status = None, expected_skip = None,
-                error_re_string = None,
-                commit_block_string = ".*remains in conflict.*",
-                expected_info = None):
-    self.name = name
-    self.local_action = local_action
-    self.incoming_action = incoming_action
-    self.expected_output = expected_output
-    self.expected_disk = expected_disk
-    self.expected_status = expected_status
-    self.expected_skip = expected_skip
-    self.error_re_string = error_re_string
-    self.commit_block_string = commit_block_string
-    self.expected_info = expected_info
-
-
-
-def deep_trees_run_tests_scheme_for_update(sbox, greater_scheme):
-  """
-  Runs a given list of tests for conflicts occuring at an update operation.
-
-  This function wants to save time and perform a number of different
-  test cases using just a single repository and performing just one commit
-  for all test cases instead of one for each test case.
-
-   1) Each test case is initialized in a separate subdir. Each subdir
-      again contains one set of "deep_trees", being separate container
-      dirs for different depths of trees (F, D, DF, DD, DDF, DDD).
-
-   2) A commit is performed across all test cases and depths.
-      (our initial state, -r2)
-
-   3) In each test case subdir (e.g. "local_tree_del_incoming_leaf_edit"),
-      its *incoming* action is performed (e.g. "deep_trees_leaf_edit"), in
-      each of the different depth trees (F, D, DF, ... DDD).
-
-   4) A commit is performed across all test cases and depths:
-      our "incoming" state is "stored away in the repository for now",
-      -r3.
-
-   5) All test case dirs and contained deep_trees are time-warped
-      (updated) back to -r2, the initial state containing deep_trees.
-
-   6) In each test case subdir (e.g. "local_tree_del_incoming_leaf_edit"),
-      its *local* action is performed (e.g. "deep_trees_leaf_del"), in
-      each of the different depth trees (F, D, DF, ... DDD).
-
-   7) An update to -r3 is performed across all test cases and depths.
-      This causes tree-conflicts between the "local" state in the working
-      copy and the "incoming" state from the repository, -r3.
-
-   8) A commit is performed in each separate container, to verify
-      that each tree-conflict indeed blocks a commit.
-
-  The sbox parameter is just the sbox passed to a test function. No need
-  to call sbox.build(), since it is called (once) within this function.
-
-  The "table" greater_scheme models all of the different test cases
-  that should be run using a single repository.
-
-  greater_scheme is a list of DeepTreesTestCase items, which define complete
-  test setups, so that they can be performed as described above.
-  """
-
-  j = os.path.join
-
-  if not sbox.is_built():
-    sbox.build()
-  wc_dir = sbox.wc_dir
-
-
-  # 1) create directories
-
-  for test_case in greater_scheme:
-    try:
-      add_deep_trees(sbox, test_case.name)
-    except:
-      logger.warn("ERROR IN: Tests scheme for update: "
-          + "while setting up deep trees in '%s'", test_case.name)
-      raise
-
-
-  # 2) commit initial state
-
-  main.run_svn(None, 'commit', '-m', 'initial state', wc_dir)
-
-
-  # 3) apply incoming changes
-
-  for test_case in greater_scheme:
-    try:
-      test_case.incoming_action(j(sbox.wc_dir, test_case.name))
-    except:
-      logger.warn("ERROR IN: Tests scheme for update: "
-          + "while performing incoming action in '%s'", test_case.name)
-      raise
-
-
-  # 4) commit incoming changes
-
-  main.run_svn(None, 'commit', '-m', 'incoming changes', wc_dir)
-
-
-  # 5) time-warp back to -r2
-
-  main.run_svn(None, 'update', '-r2', wc_dir)
-
-
-  # 6) apply local changes
-
-  for test_case in greater_scheme:
-    try:
-      test_case.local_action(j(wc_dir, test_case.name))
-    except:
-      logger.warn("ERROR IN: Tests scheme for update: "
-          + "while performing local action in '%s'", test_case.name)
-      raise
-
-
-  # 7) update to -r3, conflicting with incoming changes.
-  #    A lot of different things are expected.
-  #    Do separate update operations for each test case.
-
-  for test_case in greater_scheme:
-    try:
-      base = j(wc_dir, test_case.name)
-
-      x_out = test_case.expected_output
-      if x_out != None:
-        x_out = x_out.copy()
-        x_out.wc_dir = base
-
-      x_disk = test_case.expected_disk
-
-      x_status = test_case.expected_status
-      if x_status != None:
-        x_status.copy()
-        x_status.wc_dir = base
-
-      run_and_verify_update(base, x_out, x_disk, None,
-                            error_re_string = test_case.error_re_string)
-      if x_status:
-        run_and_verify_unquiet_status(base, x_status)
-
-      x_info = test_case.expected_info or {}
-      for path in x_info:
-        run_and_verify_info([x_info[path]], j(base, path))
-
-    except:
-      logger.warn("ERROR IN: Tests scheme for update: "
-          + "while verifying in '%s'", test_case.name)
-      raise
-
-
-  # 8) Verify that commit fails.
-
-  for test_case in greater_scheme:
-    try:
-      base = j(wc_dir, test_case.name)
-
-      x_status = test_case.expected_status
-      if x_status != None:
-        x_status.copy()
-        x_status.wc_dir = base
-
-      run_and_verify_commit(base, None, x_status,
-                            test_case.commit_block_string,
-                            base)
-    except:
-      logger.warn("ERROR IN: Tests scheme for update: "
-          + "while checking commit-blocking in '%s'", test_case.name)
-      raise
-
-
-
-def deep_trees_skipping_on_update(sbox, test_case, skip_paths,
-                                  chdir_skip_paths):
-  """
-  Create tree conflicts, then update again, expecting the existing tree
-  conflicts to be skipped.
-  SKIP_PATHS is a list of paths, relative to the "base dir", for which
-  "update" on the "base dir" should report as skipped.
-  CHDIR_SKIP_PATHS is a list of (target-path, skipped-path) pairs for which
-  an update of "target-path" (relative to the "base dir") should result in
-  "skipped-path" (relative to "target-path") being reported as skipped.
-  """
-
-  """FURTHER_ACTION is a function that will make a further modification to
-  each target, this being the modification that we expect to be skipped. The
-  function takes the "base dir" (the WC path to the test case directory) as
-  its only argument."""
-  further_action = deep_trees_tree_del_repos
-
-  j = os.path.join
-  wc_dir = sbox.wc_dir
-  base = j(wc_dir, test_case.name)
-
-  # Initialize: generate conflicts. (We do not check anything here.)
-  setup_case = DeepTreesTestCase(test_case.name,
-                                 test_case.local_action,
-                                 test_case.incoming_action,
-                                 None,
-                                 None,
-                                 None)
-  deep_trees_run_tests_scheme_for_update(sbox, [setup_case])
-
-  # Make a further change to each target in the repository so there is a new
-  # revision to update to. (This is r4.)
-  further_action(sbox.repo_url + '/' + test_case.name)
-
-  # Update whole working copy, expecting the nodes still in conflict to be
-  # skipped.
-
-  x_out = test_case.expected_output
-  if x_out != None:
-    x_out = x_out.copy()
-    x_out.wc_dir = base
-
-  x_disk = test_case.expected_disk
-
-  x_status = test_case.expected_status
-  if x_status != None:
-    x_status = x_status.copy()
-    x_status.wc_dir = base
-    # Account for nodes that were updated by further_action
-    x_status.tweak('', 'D', 'F', 'DD', 'DF', 'DDD', 'DDF', wc_rev=4)
-
-  run_and_verify_update(base, x_out, x_disk, None,
-                        error_re_string = test_case.error_re_string)
-
-  run_and_verify_unquiet_status(base, x_status)
-
-  # Try to update each in-conflict subtree. Expect a 'Skipped' output for
-  # each, and the WC status to be unchanged.
-  for path in skip_paths:
-    run_and_verify_update(j(base, path),
-                          wc.State(base, {path : Item(verb='Skipped')}),
-                          None, None)
-
-  run_and_verify_unquiet_status(base, x_status)
-
-  # Try to update each in-conflict subtree. Expect a 'Skipped' output for
-  # each, and the WC status to be unchanged.
-  # This time, cd to the subdir before updating it.
-  was_cwd = os.getcwd()
-  for path, skipped in chdir_skip_paths:
-    if isinstance(skipped, list):
-      expected_skip = {}
-      for p in skipped:
-        expected_skip[p] = Item(verb='Skipped')
-    else:
-      expected_skip = {skipped : Item(verb='Skipped')}
-    p = j(base, path)
-    run_and_verify_update(p,
-                          wc.State(p, expected_skip),
-                          None, None)
-  os.chdir(was_cwd)
-
-  run_and_verify_unquiet_status(base, x_status)
-
-  # Verify that commit still fails.
-  for path, skipped in chdir_skip_paths:
-
-    run_and_verify_commit(j(base, path), None, None,
-                          test_case.commit_block_string,
-                          base)
-
-  run_and_verify_unquiet_status(base, x_status)
-
-
-def deep_trees_run_tests_scheme_for_switch(sbox, greater_scheme):
-  """
-  Runs a given list of tests for conflicts occuring at a switch operation.
-
-  This function wants to save time and perform a number of different
-  test cases using just a single repository and performing just one commit
-  for all test cases instead of one for each test case.
-
-   1) Each test case is initialized in a separate subdir. Each subdir
-      again contains two subdirs: one "local" and one "incoming" for
-      the switch operation. These contain a set of deep_trees each.
-
-   2) A commit is performed across all test cases and depths.
-      (our initial state, -r2)
-
-   3) In each test case subdir's incoming subdir, the
-      incoming actions are performed.
-
-   4) A commit is performed across all test cases and depths. (-r3)
-
-   5) In each test case subdir's local subdir, the local actions are
-      performed. They remain uncommitted in the working copy.
-
-   6) In each test case subdir's local dir, a switch is performed to its
-      corresponding incoming dir.
-      This causes conflicts between the "local" state in the working
-      copy and the "incoming" state from the incoming subdir (still -r3).
-
-   7) A commit is performed in each separate container, to verify
-      that each tree-conflict indeed blocks a commit.
-
-  The sbox parameter is just the sbox passed to a test function. No need
-  to call sbox.build(), since it is called (once) within this function.
-
-  The "table" greater_scheme models all of the different test cases
-  that should be run using a single repository.
-
-  greater_scheme is a list of DeepTreesTestCase items, which define complete
-  test setups, so that they can be performed as described above.
-  """
-
-  j = os.path.join
-
-  if not sbox.is_built():
-    sbox.build()
-  wc_dir = sbox.wc_dir
-
-
-  # 1) Create directories.
-
-  for test_case in greater_scheme:
-    try:
-      base = j(sbox.wc_dir, test_case.name)
-      os.makedirs(base)
-      make_deep_trees(j(base, "local"))
-      make_deep_trees(j(base, "incoming"))
-      main.run_svn(None, 'add', base)
-    except:
-      logger.warn("ERROR IN: Tests scheme for switch: "
-          + "while setting up deep trees in '%s'", test_case.name)
-      raise
-
-
-  # 2) Commit initial state (-r2).
-
-  main.run_svn(None, 'commit', '-m', 'initial state', wc_dir)
-
-
-  # 3) Apply incoming changes
-
-  for test_case in greater_scheme:
-    try:
-      test_case.incoming_action(j(sbox.wc_dir, test_case.name, "incoming"))
-    except:
-      logger.warn("ERROR IN: Tests scheme for switch: "
-          + "while performing incoming action in '%s'", test_case.name)
-      raise
-
-
-  # 4) Commit all changes (-r3).
-
-  main.run_svn(None, 'commit', '-m', 'incoming changes', wc_dir)
-
-
-  # 5) Apply local changes in their according subdirs.
-
-  for test_case in greater_scheme:
-    try:
-      test_case.local_action(j(sbox.wc_dir, test_case.name, "local"))
-    except:
-      logger.warn("ERROR IN: Tests scheme for switch: "
-          + "while performing local action in '%s'", test_case.name)
-      raise
-
-
-  # 6) switch the local dir to the incoming url, conflicting with incoming
-  #    changes. A lot of different things are expected.
-  #    Do separate switch operations for each test case.
-
-  for test_case in greater_scheme:
-    try:
-      local = j(wc_dir, test_case.name, "local")
-      incoming = sbox.repo_url + "/" + test_case.name + "/incoming"
-
-      x_out = test_case.expected_output
-      if x_out != None:
-        x_out = x_out.copy()
-        x_out.wc_dir = local
-
-      x_disk = test_case.expected_disk
-
-      x_status = test_case.expected_status
-      if x_status != None:
-        x_status.copy()
-        x_status.wc_dir = local
-
-      run_and_verify_switch(local, local, incoming, x_out, x_disk, None,
-                            test_case.error_re_string, None, None, None,
-                            None, False, '--ignore-ancestry')
-      run_and_verify_unquiet_status(local, x_status)
-
-      x_info = test_case.expected_info or {}
-      for path in x_info:
-        run_and_verify_info([x_info[path]], j(local, path))
-    except:
-      logger.warn("ERROR IN: Tests scheme for switch: "
-          + "while verifying in '%s'", test_case.name)
-      raise
-
-
-  # 7) Verify that commit fails.
-
-  for test_case in greater_scheme:
-    try:
-      local = j(wc_dir, test_case.name, 'local')
-
-      x_status = test_case.expected_status
-      if x_status != None:
-        x_status.copy()
-        x_status.wc_dir = local
-
-      run_and_verify_commit(local, None, x_status,
-                            test_case.commit_block_string,
-                            local)
-    except:
-      logger.warn("ERROR IN: Tests scheme for switch: "
-          + "while checking commit-blocking in '%s'", test_case.name)
-      raise
-
-
-def deep_trees_run_tests_scheme_for_merge(sbox, greater_scheme,
-                                          do_commit_local_changes,
-                                          do_commit_conflicts=True,
-                                          ignore_ancestry=False):
-  """
-  Runs a given list of tests for conflicts occuring at a merge operation.
-
-  This function wants to save time and perform a number of different
-  test cases using just a single repository and performing just one commit
-  for all test cases instead of one for each test case.
-
-   1) Each test case is initialized in a separate subdir. Each subdir
-      initially contains another subdir, called "incoming", which
-      contains a set of deep_trees.
-
-   2) A commit is performed across all test cases and depths.
-      (a pre-initial state)
-
-   3) In each test case subdir, the "incoming" subdir is copied to "local",
-      via the `svn copy' command. Each test case's subdir now has two sub-
-      dirs: "local" and "incoming", initial states for the merge operation.
-
-   4) An update is performed across all test cases and depths, so that the
-      copies made in 3) are pulled into the wc.
-
-   5) In each test case's "incoming" subdir, the incoming action is
-      performed.
-
-   6) A commit is performed across all test cases and depths, to commit
-      the incoming changes.
-      If do_commit_local_changes is True, this becomes step 7 (swap steps).
-
-   7) In each test case's "local" subdir, the local_action is performed.
-      If do_commit_local_changes is True, this becomes step 6 (swap steps).
-      Then, in effect, the local changes are committed as well.
-
-   8) In each test case subdir, the "incoming" subdir is merged into the
-      "local" subdir.  If ignore_ancestry is True, then the merge is done
-      with the --ignore-ancestry option, so mergeinfo is neither considered
-      nor recorded.  This causes conflicts between the "local" state in the
-      working copy and the "incoming" state from the incoming subdir.
-
-   9) If do_commit_conflicts is True, then a commit is performed in each
-      separate container, to verify that each tree-conflict indeed blocks
-      a commit.
-
-  The sbox parameter is just the sbox passed to a test function. No need
-  to call sbox.build(), since it is called (once) within this function.
-
-  The "table" greater_scheme models all of the different test cases
-  that should be run using a single repository.
-
-  greater_scheme is a list of DeepTreesTestCase items, which define complete
-  test setups, so that they can be performed as described above.
-  """
-
-  j = os.path.join
-
-  if not sbox.is_built():
-    sbox.build()
-  wc_dir = sbox.wc_dir
-
-  # 1) Create directories.
-  for test_case in greater_scheme:
-    try:
-      base = j(sbox.wc_dir, test_case.name)
-      os.makedirs(base)
-      make_deep_trees(j(base, "incoming"))
-      main.run_svn(None, 'add', base)
-    except:
-      logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while setting up deep trees in '%s'", test_case.name)
-      raise
-
-
-  # 2) Commit pre-initial state (-r2).
-
-  main.run_svn(None, 'commit', '-m', 'pre-initial state', wc_dir)
-
-
-  # 3) Copy "incoming" to "local".
-
-  for test_case in greater_scheme:
-    try:
-      base_url = sbox.repo_url + "/" + test_case.name
-      incoming_url = base_url + "/incoming"
-      local_url = base_url + "/local"
-      main.run_svn(None, 'cp', incoming_url, local_url, '-m',
-                   'copy incoming to local')
-    except:
-      logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while copying deep trees in '%s'", test_case.name)
-      raise
-
-  # 4) Update to load all of the "/local" subdirs into the working copies.
-
-  try:
-    main.run_svn(None, 'up', sbox.wc_dir)
-  except:
-    logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while updating local subdirs")
-    raise
-
-
-  # 5) Perform incoming actions
-
-  for test_case in greater_scheme:
-    try:
-      test_case.incoming_action(j(sbox.wc_dir, test_case.name, "incoming"))
-    except:
-      logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while performing incoming action in '%s'", test_case.name)
-      raise
-
-
-  # 6) or 7) Commit all incoming actions
-
-  if not do_commit_local_changes:
-    try:
-      main.run_svn(None, 'ci', '-m', 'Committing incoming actions',
-                   sbox.wc_dir)
-    except:
-      logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while committing incoming actions")
-      raise
-
-
-  # 7) or 6) Perform all local actions.
-
-  for test_case in greater_scheme:
-    try:
-      test_case.local_action(j(sbox.wc_dir, test_case.name, "local"))
-    except:
-      logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while performing local action in '%s'", test_case.name)
-      raise
-
-
-  # 6) or 7) Commit all incoming actions
-
-  if do_commit_local_changes:
-    try:
-      main.run_svn(None, 'ci', '-m', 'Committing incoming and local actions',
-                   sbox.wc_dir)
-    except:
-      logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while committing incoming and local actions")
-      raise
-
-
-  # 8) Merge all "incoming" subdirs to their respective "local" subdirs.
-  #    This creates conflicts between the local changes in the "local" wc
-  #    subdirs and the incoming states committed in the "incoming" subdirs.
-
-  for test_case in greater_scheme:
-    try:
-      local = j(sbox.wc_dir, test_case.name, "local")
-      incoming = sbox.repo_url + "/" + test_case.name + "/incoming"
-
-      x_out = test_case.expected_output
-      if x_out != None:
-        x_out = x_out.copy()
-        x_out.wc_dir = local
-
-      x_disk = test_case.expected_disk
-
-      x_status = test_case.expected_status
-      if x_status != None:
-        x_status.copy()
-        x_status.wc_dir = local
-
-      x_skip = test_case.expected_skip
-      if x_skip != None:
-        x_skip.copy()
-        x_skip.wc_dir = local
-
-      varargs = (local,)
-      if ignore_ancestry:
-        varargs = varargs + ('--ignore-ancestry',)
-
-      run_and_verify_merge(local, None, None, incoming, None,
-                           x_out, None, None, x_disk, None, x_skip,
-                           test_case.error_re_string,
-                           None, None, None, None,
-                           False, False, *varargs)
-      run_and_verify_unquiet_status(local, x_status)
-    except:
-      logger.warn("ERROR IN: Tests scheme for merge: "
-          + "while verifying in '%s'", test_case.name)
-      raise
-
-
-  # 9) Verify that commit fails.
-
-  if do_commit_conflicts:
-    for test_case in greater_scheme:
-      try:
-        local = j(wc_dir, test_case.name, 'local')
-
-        x_status = test_case.expected_status
-        if x_status != None:
-          x_status.copy()
-          x_status.wc_dir = local
-
-        run_and_verify_commit(local, None, x_status,
-                              test_case.commit_block_string,
-                              local)
-      except:
-        logger.warn("ERROR IN: Tests scheme for merge: "
-            + "while checking commit-blocking in '%s'", test_case.name)
-        raise
-
-

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py Wed Feb 13 06:37:54 2013
@@ -1186,6 +1186,26 @@ def merge_notify_line(revstart=None, rev
       return "--- Merging %sr%ld through r%ld into '%s':\n" \
              % (from_foreign_phrase, revstart, revend, target_re)
 
+def summary_of_conflicts(text_conflicts=0, prop_conflicts=0,
+                         tree_conflicts=0, skipped_paths=0):
+  """Return a list of lines corresponding to the summary of conflicts and
+     skipped paths that is printed by merge and update and switch.  If all
+     parameters are zero, return an empty list.
+  """
+  lines = []
+  if text_conflicts or prop_conflicts or tree_conflicts or skipped_paths:
+    lines.append("Summary of conflicts:\n")
+    if text_conflicts:
+      lines.append("  Text conflicts: %d\n" % text_conflicts)
+    if prop_conflicts:
+      lines.append("  Property conflicts: %d\n" % prop_conflicts)
+    if tree_conflicts:
+      lines.append("  Tree conflicts: %d\n" % tree_conflicts)
+    if skipped_paths:
+      lines.append("  Skipped paths: %d\n" % skipped_paths)
+
+  return lines
+
 
 def make_log_msg():
   "Conjure up a log message based on the calling test."

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py Wed Feb 13 06:37:54 2013
@@ -191,6 +191,12 @@ class Sandbox:
        path WC_DIR if supplied."""
     return [self.ospath(rp, wc_dir) for rp in relpaths]
 
+  def path(self, relpath, wc_dir=None):
+    """Return RELPATH converted to an path relative to the WC dir
+       of this sbox, or relative to WC_DIR if supplied, but always
+       using '/' as directory separator."""
+    return self.ospath(relpath, wc_dir=wc_dir).replace(os.path.sep, '/')
+
   def redirected_root_url(self, temporary=False):
     """If TEMPORARY is set, return the URL which should be configured
        to temporarily redirect to the root of this repository;

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py Wed Feb 13 06:37:54 2013
@@ -838,11 +838,10 @@ def build_tree_from_commit(lines):
 #             IFF columns non-empty.
 #
 
-def build_tree_from_status(lines, wc_dir_name=None):
+def build_tree_from_status(lines):
   "Return a tree derived by parsing the output LINES from 'st -vuq'."
 
-  return svntest.wc.State.from_status(lines,
-                                       wc_dir_name=wc_dir_name).old_tree()
+  return svntest.wc.State.from_status(lines).old_tree()
 
 
 # Parse merge "skipped" output