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 2022/01/14 14:01:51 UTC

svn commit: r1897034 [30/37] - in /subversion/branches/multi-wc-format: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/client-side/svn_load_dirs/ contrib/hook-scripts/ contrib/s...

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/move_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/move_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/move_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/move_tests.py Fri Jan 14 14:01:45 2022
@@ -125,7 +125,7 @@ def move_file_test(sbox, source, dest, m
   start_disk: validate the on disk state after the start update against this.
   start_status: validate the wc status after the start update against this.
   end_rev: revision to update to, bringing in some update you want to test.
-  up_output: validate the output of the end update agianst this.
+  up_output: validate the output of the end update against this.
   up_disk: validate the on disk state after the end update against this.
   up_status: validate the wc status after the end update against this.
   revert_paths: validate the paths reverted.
@@ -793,7 +793,7 @@ def build_simple_file_move_tests(sbox, s
 
   # move and update with incoming identical move (r16-17)
   # XXX: It'd be really nice if we actually recognized this and the wc
-  # showed no conflict at all on udpate.
+  # showed no conflict at all on update.
   test = {}
   test['start_rev'] = 16
   test['end_rev'] = 17
@@ -883,7 +883,7 @@ def build_simple_file_move_func(sbox, so
 #
 #   Each test must return on success or raise on failure.
 #
-# See http://wiki.apache.org/subversion/LocalMoves
+# See https://cwiki.apache.org/confluence/display/SVN/LocalMoves
 
 def lateral_move_file_test(sbox):
   "lateral (rename) move of a file test"
@@ -1755,7 +1755,7 @@ def move_conflict_markers(sbox):
   })
   expected_disk.remove('iota', 'iota.prej',
                        'A/B/E', 'A/B/E/alpha', 'A/B/E/beta',
-                       'A/B/E/dir_conflicts.prej', 
+                       'A/B/E/dir_conflicts.prej',
                        'A/B/E/beta.prej')
   expected_disk.add({
     'A/iotb'  : Item(contents="This is the file 'iota'.\n"),

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/patch_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/patch_tests.py Fri Jan 14 14:01:45 2022
@@ -1574,15 +1574,7 @@ def patch_no_svn_eol_style(sbox):
   patch_file_path = sbox.get_tempname('my.patch')
   mu_path = sbox.ospath('A/mu')
 
-  # CRLF is a string that will match a CRLF sequence read from a text file.
-  # ### On Windows, we assume CRLF will be read as LF, so it's a poor test.
-  if os.name == 'nt':
-    crlf = '\n'
-  else:
-    crlf = '\r\n'
-
-  # Strict EOL style matching breaks Windows tests at least with Python 2
-  keep_eol_style = not svntest.main.is_os_windows()
+  crlf = '\r\n'
 
   eols = [crlf, '\015', '\n', '\012']
   for target_eol in eols:
@@ -1603,7 +1595,7 @@ def patch_no_svn_eol_style(sbox):
       ]
 
       # Set mu contents
-      svntest.main.file_write(mu_path, ''.join(mu_contents))
+      svntest.main.file_write(mu_path, ''.join(mu_contents), mode='wb')
 
       unidiff_patch = [
         "Index: mu",
@@ -1647,7 +1639,8 @@ def patch_no_svn_eol_style(sbox):
         target_eol,
       ]
 
-      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch),
+                              mode='wb')
 
       expected_output = wc.State(wc_dir, {
         'A/mu' : Item(status='U '),
@@ -1666,7 +1659,8 @@ def patch_no_svn_eol_style(sbox):
                                             expected_disk,
                                             expected_status,
                                             expected_skip,
-                                            [], True, True, keep_eol_style)
+                                            [], True, True,
+                                            keep_eol_style=True)
 
       expected_output = ["Reverted '" + mu_path + "'\n"]
       svntest.actions.run_and_verify_svn(expected_output, [],
@@ -1681,17 +1675,13 @@ def patch_with_svn_eol_style(sbox):
   patch_file_path = sbox.get_tempname('my.patch')
   mu_path = sbox.ospath('A/mu')
 
-  # CRLF is a string that will match a CRLF sequence read from a text file.
-  # ### On Windows, we assume CRLF will be read as LF, so it's a poor test.
   if os.name == 'nt':
-    crlf = '\n'
+    native_nl = '\r\n'
   else:
-    crlf = '\r\n'
-
-  # Strict EOL style matching breaks Windows tests at least with Python 2
-  keep_eol_style = not svntest.main.is_os_windows()
+    native_nl = '\n'
+  crlf = '\r\n'
 
-  eols = [crlf, '\015', '\n', '\012']
+  eols = [crlf, '\015', native_nl, '\012']
   eol_styles = ['CRLF', 'CR', 'native', 'LF']
   rev = 1
   for target_eol, target_eol_style in zip(eols, eol_styles):
@@ -1714,7 +1704,7 @@ def patch_with_svn_eol_style(sbox):
       # Set mu contents
       svntest.main.run_svn(None, 'rm', mu_path)
       svntest.main.run_svn(None, 'commit', '-m', 'delete mu', mu_path)
-      svntest.main.file_write(mu_path, ''.join(mu_contents))
+      svntest.main.file_write(mu_path, ''.join(mu_contents), mode='wb')
       svntest.main.run_svn(None, 'add', mu_path)
       svntest.main.run_svn(None, 'propset', 'svn:eol-style', target_eol_style,
                            mu_path)
@@ -1762,7 +1752,8 @@ def patch_with_svn_eol_style(sbox):
         target_eol,
       ]
 
-      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch),
+                              mode='wb')
 
       expected_output = [
         'U         %s\n' % sbox.ospath('A/mu'),
@@ -1786,7 +1777,7 @@ def patch_with_svn_eol_style(sbox):
                                             None, # expected err
                                             1, # check-props
                                             1, # dry-run
-                                            keep_eol_style) # keep-eol-style
+                                            keep_eol_style=True)
 
       expected_output = ["Reverted '" + mu_path + "'\n"]
       svntest.actions.run_and_verify_svn(expected_output, [], 'revert', '-R', wc_dir)
@@ -1800,17 +1791,13 @@ def patch_with_svn_eol_style_uncommitted
   patch_file_path = sbox.get_tempname('my.patch')
   mu_path = sbox.ospath('A/mu')
 
-  # CRLF is a string that will match a CRLF sequence read from a text file.
-  # ### On Windows, we assume CRLF will be read as LF, so it's a poor test.
   if os.name == 'nt':
-    crlf = '\n'
+    native_nl = '\r\n'
   else:
-    crlf = '\r\n'
-
-  # Strict EOL style matching breaks Windows tests at least with Python 2
-  keep_eol_style = not svntest.main.is_os_windows()
+    native_nl = '\n'
+  crlf = '\r\n'
 
-  eols = [crlf, '\015', '\n', '\012']
+  eols = [crlf, '\015', native_nl, '\012']
   eol_styles = ['CRLF', 'CR', 'native', 'LF']
   for target_eol, target_eol_style in zip(eols, eol_styles):
     for patch_eol in eols:
@@ -1830,7 +1817,7 @@ def patch_with_svn_eol_style_uncommitted
       ]
 
       # Set mu contents
-      svntest.main.file_write(mu_path, ''.join(mu_contents))
+      svntest.main.file_write(mu_path, ''.join(mu_contents), mode='wb')
       svntest.main.run_svn(None, 'propset', 'svn:eol-style', target_eol_style,
                            mu_path)
 
@@ -1876,7 +1863,8 @@ def patch_with_svn_eol_style_uncommitted
         target_eol,
       ]
 
-      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch),
+                              mode='wb')
 
       expected_output = wc.State(wc_dir, {
         'A/mu' : Item(status='U '),
@@ -1899,7 +1887,7 @@ def patch_with_svn_eol_style_uncommitted
                                             None, # expected err
                                             1, # check-props
                                             1, # dry-run
-                                            keep_eol_style) # keep-eol-style
+                                            keep_eol_style=True)
 
       expected_output = ["Reverted '" + mu_path + "'\n"]
       svntest.actions.run_and_verify_svn(expected_output, [], 'revert', '-R', wc_dir)

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/prop_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/prop_tests.py Fri Jan 14 14:01:45 2022
@@ -2829,6 +2829,38 @@ def prop_conflict_root(sbox):
                                         expected_status,
                                         extra_files=extra_files)
 
+
+# Test that editing a regular property creates a temporary file named
+# "svn-prop.tmp" whereas editing a revprop results in a temporary file
+# named "svn-revprop-rN.tmp" (where "N" is the number of the revision
+# whose revprop would be edited).
+def tmpfile_name_matches_prop_type(sbox):
+  "propedit tmpfile name matches property type"
+
+  sbox.build(read_only=True)
+
+  # We want the editor invocation to fail -- all we care about is the
+  # name of the tmpfile left over after that failure.  I'm guessing
+  # you don't have a editor named this on your system:
+  non_editor = 'af968da2ce9'
+
+  svntest.actions.run_and_verify_svn(
+    None,
+    '.*' + re.escape(non_editor) + r'.*svn-revprop-r1\.tmp.*',
+    'propedit', '--revprop', 
+    '--editor-cmd', non_editor,
+    '-r1', 'svn:log',
+    sbox.repo_url)
+
+  svntest.actions.run_and_verify_svn(
+    None,
+    '.*' + re.escape(non_editor) + r'.*svn-prop\.tmp.*',
+    'propedit', 
+    '--editor-cmd', non_editor,
+    'ignored-propname',
+    sbox.ospath('A/mu'))
+
+
 ########################################################################
 # Run the tests
 
@@ -2880,6 +2912,7 @@ test_list = [ None,
               iprops_list_abspath,
               wc_propop_on_url,
               prop_conflict_root,
+              tmpfile_name_matches_prop_type,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/relocate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/relocate_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/relocate_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/relocate_tests.py Fri Jan 14 14:01:45 2022
@@ -417,8 +417,8 @@ def prefix_partial_component(sbox):
                                      wc_dir)
   svntest.actions.run_and_verify_info([{ 'URL' : '.*.yyyother$' }],
                                       wc_dir)
-  
-  
+
+
 ########################################################################
 # Run the tests
 

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/revert_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/revert_tests.py Fri Jan 14 14:01:45 2022
@@ -46,6 +46,23 @@ Item = svntest.wc.StateItem
 ######################################################################
 # Helpers
 
+def expected_output_revert(reverted_paths, skipped_paths=[]):
+  return svntest.verify.UnorderedRegexListOutput(
+    ["Reverted '%s'\n" % re.escape(path) for path in reverted_paths] +
+    ["Skipped '%s'.*\n" % re.escape(path) for path in skipped_paths])
+
+def run_and_verify_revert(targets, options=[],
+                          reverted_paths=None, skipped_paths=[]):
+  """Run 'svn revert OPTIONS TARGETS'. Verify that the printed output matches
+     REVERTED_PATHS and SKIPPED_PATHS. If REVERTED_PATHS is None, it defaults
+     to TARGETS.
+  """
+  if reverted_paths is None:
+    reverted_paths = targets
+  expected_output = expected_output_revert(reverted_paths, skipped_paths)
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     *(['revert'] + options + targets))
+
 def revert_replacement_with_props(sbox, wc_copy):
   """Helper implementing the core of
   revert_{repos,wc}_to_wc_replace_with_props().
@@ -129,9 +146,7 @@ def revert_replacement_with_props(sbox,
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   expected_status.tweak('A/D/G/rho', status='  ', copied=None, wc_rev='2')
-  expected_output = ["Reverted '" + rho_path + "'\n"]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '-R', wc_dir)
+  run_and_verify_revert([wc_dir], ['-R'], [rho_path])
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Check disk status
@@ -356,8 +371,7 @@ def revert_replaced_file_without_props(s
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # revert file1
-  svntest.actions.run_and_verify_svn(["Reverted '" + file1_path + "'\n"],
-                                     [], 'revert', file1_path)
+  run_and_verify_revert([file1_path])
 
   # test that file1 really was reverted
   expected_status.tweak('file1', status='  ', wc_rev=2)
@@ -402,10 +416,7 @@ def revert_moved_file(sbox):
   actions.run_and_verify_unquiet_status(wc_dir, expected_status)
 
   # svn revert iota
-  expected_stdout = ["Reverted '" + iota + "'\n"]
-
-  actions.run_and_verify_svn2(expected_stdout, [], 0, 'revert',
-    iota)
+  run_and_verify_revert([iota])
 
   # svn st
   expected_status.tweak('iota', status='  ', moved_to=None)
@@ -644,9 +655,7 @@ def revert_propset__dir(sbox):
   wc_dir = sbox.wc_dir
   a_path = os.path.join(wc_dir, 'A')
   svntest.main.run_svn(None, 'propset', 'foo', 'x', a_path)
-  expected_output = re.escape("Reverted '" + a_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     a_path)
+  run_and_verify_revert([a_path])
 
 def revert_propset__file(sbox):
   "revert a simple propset on a file"
@@ -655,9 +664,7 @@ def revert_propset__file(sbox):
   wc_dir = sbox.wc_dir
   iota_path = os.path.join(wc_dir, 'iota')
   svntest.main.run_svn(None, 'propset', 'foo', 'x', iota_path)
-  expected_output = re.escape("Reverted '" + iota_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     iota_path)
+  run_and_verify_revert([iota_path])
 
 def revert_propdel__dir(sbox):
   "revert a simple propdel on a dir"
@@ -669,9 +676,7 @@ def revert_propdel__dir(sbox):
   svntest.main.run_svn(None,
                        'commit', '-m', 'ps', a_path)
   svntest.main.run_svn(None, 'propdel', 'foo', a_path)
-  expected_output = re.escape("Reverted '" + a_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     a_path)
+  run_and_verify_revert([a_path])
 
 def revert_propdel__file(sbox):
   "revert a simple propdel on a file"
@@ -683,9 +688,7 @@ def revert_propdel__file(sbox):
   svntest.main.run_svn(None,
                        'commit', '-m', 'ps', iota_path)
   svntest.main.run_svn(None, 'propdel', 'foo', iota_path)
-  expected_output = re.escape("Reverted '" + iota_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     iota_path)
+  run_and_verify_revert([iota_path])
 
 def revert_replaced_with_history_file_1(sbox):
   "revert a committed replace-with-history == no-op"
@@ -776,9 +779,7 @@ def status_of_missing_dir_after_revert(s
   A_D_G_path = os.path.join(wc_dir, "A", "D", "G")
 
   svntest.actions.run_and_verify_svn(None, [], "rm", A_D_G_path)
-  expected_output = re.escape("Reverted '" + A_D_G_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     A_D_G_path)
+  run_and_verify_revert([A_D_G_path])
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/D/G/rho', 'A/D/G/pi', 'A/D/G/tau',
@@ -877,11 +878,7 @@ def status_of_missing_dir_after_revert_r
   revert_paths = [G_path] + [os.path.join(G_path, child)
                              for child in ['alpha', 'beta', 'pi', 'rho', 'tau']]
 
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % path for path in revert_paths])
-
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert", "-R",
-                                     G_path)
+  run_and_verify_revert([G_path], ["-R"], revert_paths)
 
   svntest.actions.run_and_verify_svn([], [],
                                      "status", wc_dir)
@@ -947,12 +944,6 @@ def revert_tree_conflicts_in_updated_fil
   G2_tau = os.path.join(G2, 'tau')
 
   # Expectations
-  expected_output = svntest.verify.UnorderedOutput(
-   ["Reverted '%s'\n" % G_pi,
-    "Reverted '%s'\n" % G_rho,
-    "Reverted '%s'\n" % G_tau,
-    ])
-
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   expected_status.tweak('A/D/G/pi',  status='  ')
   expected_status.remove('A/D/G/rho')
@@ -965,23 +956,15 @@ def revert_tree_conflicts_in_updated_fil
   expected_disk.remove('A/D/G/tau')
 
   # Revert individually in wc
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', G_pi, G_rho, G_tau)
+  run_and_verify_revert([G_pi, G_rho, G_tau])
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
   svntest.actions.verify_disk(wc_dir, expected_disk)
 
   # Expectations
-  expected_output = svntest.verify.UnorderedOutput(
-   ["Reverted '%s'\n" % G2_pi,
-    "Reverted '%s'\n" % G2_rho,
-    "Reverted '%s'\n" % G2_tau,
-    ])
-
   expected_status.wc_dir = wc_dir_2
 
   # Revert recursively in wc 2
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '-R', G2)
+  run_and_verify_revert([G2], ['-R'], [G2_pi, G2_rho, G2_tau])
   svntest.actions.run_and_verify_status(wc_dir_2, expected_status)
   svntest.actions.verify_disk(wc_dir_2, expected_disk)
 
@@ -1049,9 +1032,7 @@ def revert_child_of_copy(sbox):
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # First revert removes text change, child is still copied
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E2/beta')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E2/beta'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E2/beta']))
   expected_status.tweak('A/B/E2/beta', status='  ')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
@@ -1074,9 +1055,7 @@ def revert_non_recusive_after_delete(sbo
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # This appears to work but gets the op-depth wrong
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B'))
+  run_and_verify_revert(sbox.ospaths(['A/B']))
   expected_status.tweak('A/B', status='  ')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
@@ -1086,9 +1065,7 @@ def revert_non_recusive_after_delete(sbo
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Since the op-depth was wrong A/B/E erroneously remains deleted
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E']))
   expected_status.tweak('A/B/E', status='  ')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
@@ -1134,17 +1111,13 @@ def revert_permissions_only(sbox):
 
   os.chmod(sbox.ospath('A/B/E/alpha'), svntest.main.S_ALL_READ)  # read-only
   is_readonly(sbox.ospath('A/B/E/alpha'))
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/alpha')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E/alpha'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']))
   is_writable(sbox.ospath('A/B/E/alpha'))
 
   if svntest.main.is_posix_os():
     os.chmod(sbox.ospath('A/B/E/beta'), svntest.main.S_ALL_RWX)   # executable
     is_executable(sbox.ospath('A/B/E/beta'))
-    expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/beta')]
-    svntest.actions.run_and_verify_svn(expected_output, [],
-                                       'revert', sbox.ospath('A/B/E/beta'))
+    run_and_verify_revert(sbox.ospaths(['A/B/E/beta']))
     is_non_executable(sbox.ospath('A/B/E/beta'))
 
   svntest.actions.run_and_verify_svn(None, [],
@@ -1167,17 +1140,13 @@ def revert_permissions_only(sbox):
 
   os.chmod(sbox.ospath('A/B/E/alpha'), svntest.main.S_ALL_RW)  # not read-only
   is_writable(sbox.ospath('A/B/E/alpha'))
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/alpha')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E/alpha'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']))
   is_readonly(sbox.ospath('A/B/E/alpha'))
 
   if svntest.main.is_posix_os():
     os.chmod(sbox.ospath('A/B/E/beta'), svntest.main.S_ALL_RW)   # not executable
     is_non_executable(sbox.ospath('A/B/E/beta'))
-    expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/beta')]
-    svntest.actions.run_and_verify_svn(expected_output, [],
-                                       'revert', sbox.ospath('A/B/E/beta'))
+    run_and_verify_revert(sbox.ospaths(['A/B/E/beta']))
     is_executable(sbox.ospath('A/B/E/beta'))
 
   # copied file is always writeable
@@ -1212,14 +1181,8 @@ def revert_copy_depth_files(sbox):
     })
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % sbox.ospath(path) for path in ['A/B/E2',
-                                                       'A/B/E2/alpha',
-                                                       'A/B/E2/beta']])
-
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '--depth', 'files',
-                                     sbox.ospath('A/B/E2'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E2']), ['--depth', 'files'],
+                        sbox.ospaths(['A/B/E2', 'A/B/E2/alpha', 'A/B/E2/beta']))
 
   expected_status.remove('A/B/E2', 'A/B/E2/alpha', 'A/B/E2/beta')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1242,12 +1205,8 @@ def revert_nested_add_depth_immediates(s
     })
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % sbox.ospath(path) for path in ['A/X', 'A/X/Y']])
-
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '--depth', 'immediates',
-                                     sbox.ospath('A/X'))
+  run_and_verify_revert(sbox.ospaths(['A/X']), ['--depth', 'immediates'],
+                        sbox.ospaths(['A/X', 'A/X/Y']))
 
   expected_status.remove('A/X', 'A/X/Y')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1299,9 +1258,7 @@ def revert_empty_actual(sbox):
   wc_dir = sbox.wc_dir
 
   # Non-recursive code path works
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n" % sbox.ospath('alpha')],
-                                     [],
-                                     'revert', sbox.ospath('alpha'))
+  run_and_verify_revert(sbox.ospaths(['alpha']))
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1316,9 +1273,7 @@ def revert_empty_actual_recursive(sbox):
 
   # Recursive code path fails, the superfluous actual node suppresses the
   # notification
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n" % sbox.ospath('alpha')],
-                                     [],
-                                     'revert', '-R', sbox.ospath('alpha'))
+  run_and_verify_revert(sbox.ospaths(['alpha']), ['-R'])
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1433,7 +1388,7 @@ def revert_tree_conflicts_with_replaceme
   cd_and_status_u('A/D/H')
 
   # Revert everything (i.e., accept "theirs-full").
-  svntest.actions.run_and_verify_revert([
+  reverted_paths = [
     wc('A/B/E'),
     wc('A/B/E/alpha'),   # incoming & local
     wc('A/B/E/beta'),
@@ -1450,7 +1405,8 @@ def revert_tree_conflicts_with_replaceme
     wc('A/D/H/loc_psi'),
     wc('A/D/gamma'),
     wc('A/mu'),
-    ], '-R', wc_dir)
+    ]
+  run_and_verify_revert([wc_dir], ['-R'], reverted_paths)
 
   # Remove a few unversioned files that revert left behind.
   os.remove(wc('A/B/E/loc_beta'))
@@ -1511,10 +1467,7 @@ def revert_no_text_change_conflict(sbox)
   create_no_text_change_conflict(sbox)
   wc_dir = sbox.wc_dir
 
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n"
-                                      % sbox.ospath('A/B/E/alpha')],
-                                     [],
-                                     'revert', sbox.ospath('A/B/E/alpha'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']))
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1526,10 +1479,7 @@ def revert_no_text_change_conflict_recur
   create_no_text_change_conflict(sbox)
   wc_dir = sbox.wc_dir
 
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n"
-                                      % sbox.ospath('A/B/E/alpha')],
-                                     [],
-                                     'revert', '-R', wc_dir)
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']), ['-R'])
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1560,13 +1510,8 @@ def revert_with_unversioned_targets(sbox
     f.write(psi_contents)
 
   # revert
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % sbox.ospath('A/D/H/chi'),
-    "Skipped '%s'\n" % sbox.ospath('A/D/H/delta'),
-    "Reverted '%s'\n" % sbox.ospath('A/D/H/psi'),
-  ])
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', chi_path, delta_path, psi_path)
+  run_and_verify_revert([chi_path, delta_path, psi_path], [],
+                        [chi_path, psi_path], [delta_path])
 
   # verify status
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
@@ -1585,8 +1530,8 @@ def revert_with_unversioned_targets(sbox
 def revert_nonexistent(sbox):
   'svn revert -R nonexistent'
   sbox.build(read_only=True)
-  svntest.actions.run_and_verify_svn('Skipped.*nonexistent', [],
-                                     'revert', '-R', sbox.ospath('nonexistent'))
+  run_and_verify_revert(sbox.ospaths(['nonexistent']), ['-R'],
+                        [], sbox.ospaths(['nonexistent']))
 
 @Issue(4168)
 def revert_obstructing_wc(sbox):
@@ -1641,6 +1586,33 @@ def revert_moved_dir_partial(sbox):
   sbox.simple_move('A', 'A_')
   svntest.actions.run_and_verify_svn(None, [], 'revert', sbox.ospath('A'))
 
+@XFail()
+@Issue(4798)
+def revert_remove_added(sbox):
+  "revert_remove_added"
+
+  sbox.build(empty=True, read_only=True)
+
+  # We'll test the items named with a '1' as direct targets to 'revert',
+  # and items named with a '2' as items found by recursion.
+  sbox.simple_mkdir('D1', 'D2')
+  sbox.simple_add_text('This is a new file.',
+                       'D1/file', 'file1',
+                       'D2/file', 'file2')
+
+  run_and_verify_revert(sbox.ospaths(['D1']), ['--remove-added', '-R'],
+                        sbox.ospaths(['D1/file', 'D1']))
+  assert(not os.path.exists(sbox.ospath('D1')))
+
+  run_and_verify_revert(sbox.ospaths(['file1']), ['--remove-added'],
+                        sbox.ospaths(['file1']))
+  assert(not os.path.exists(sbox.ospath('file1')))
+
+  run_and_verify_revert(sbox.ospaths(['.']), ['--remove-added', '-R'],
+                        sbox.ospaths(['D2/file', 'D2', 'file2']))
+  assert(not os.path.exists(sbox.ospath('file2')))
+  assert(not os.path.exists(sbox.ospath('D2')))
+
 
 ########################################################################
 # Run the tests
@@ -1683,6 +1655,7 @@ test_list = [ None,
               revert_nonexistent,
               revert_obstructing_wc,
               revert_moved_dir_partial,
+              revert_remove_added,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/shelf_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/shelf_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/shelf_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/shelf_tests.py Fri Jan 14 14:01:45 2022
@@ -46,6 +46,10 @@ Issue = svntest.testcase.Issue_deco
 Wimp = svntest.testcase.Wimp_deco
 Item = wc.StateItem
 
+def shelf3_enabled():
+  v = os.getenv('SVN_EXPERIMENTAL_COMMANDS')
+  return v is not None and v.find('shelf3') >= 0
+
 #----------------------------------------------------------------------
 
 def state_from_status(wc_dir,
@@ -126,6 +130,12 @@ def shelve_unshelve_verify(sbox, modifie
     ])
   svntest.actions.run_and_verify_svn(expected_output, [], 'x-shelves')
 
+  # Diff; ensure something comes out and it doesn't crash
+  svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [],
+                                     'x-shelf-diff', 'foo')
+  svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [],
+                                     'x-shelf-diff', '--summarize', 'foo')
+
   # Unshelve; check the original modifications are here again
   svntest.actions.run_and_verify_svn(None, [],
                                      'x-unshelve', 'foo')
@@ -153,6 +163,7 @@ def shelve_unshelve(sbox, modifier, cann
 #
 #   Each test must return on success or raise on failure.
 
+@SkipUnless(shelf3_enabled)
 def shelve_text_mods(sbox):
   "shelve text mods"
 
@@ -163,6 +174,7 @@ def shelve_text_mods(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_prop_changes(sbox):
   "shelve prop changes"
 
@@ -174,6 +186,7 @@ def shelve_prop_changes(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_adds(sbox):
   "shelve adds"
 
@@ -187,6 +200,7 @@ def shelve_adds(sbox):
 #----------------------------------------------------------------------
 
 @Issue(4709)
+@SkipUnless(shelf3_enabled)
 def shelve_deletes(sbox):
   "shelve deletes"
 
@@ -197,6 +211,7 @@ def shelve_deletes(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_replace(sbox):
   "shelve replace"
 
@@ -209,6 +224,7 @@ def shelve_replace(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_empty_adds(sbox):
   "shelve empty adds"
   sbox.build(empty=True)
@@ -222,6 +238,7 @@ def shelve_empty_adds(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_empty_deletes(sbox):
   "shelve empty deletes"
   sbox.build(empty=True)
@@ -237,6 +254,7 @@ def shelve_empty_deletes(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_from_inner_path(sbox):
   "shelve from inner path"
 
@@ -297,6 +315,7 @@ def save_revert_restore(sbox, modifier1,
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def checkpoint_basic(sbox):
   "checkpoint basic"
 
@@ -312,6 +331,7 @@ def checkpoint_basic(sbox):
 #----------------------------------------------------------------------
 
 @Issue(3747)
+@SkipUnless(shelf3_enabled)
 def shelve_mergeinfo(sbox):
   "shelve mergeinfo"
 
@@ -323,6 +343,7 @@ def shelve_mergeinfo(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def unshelve_refuses_if_conflicts(sbox):
   "unshelve refuses if conflicts"
 
@@ -366,6 +387,7 @@ def unshelve_refuses_if_conflicts(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_binary_file_mod(sbox):
   "shelve binary file mod"
 
@@ -387,6 +409,7 @@ def shelve_binary_file_mod(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_binary_file_add(sbox):
   "shelve binary file add"
 
@@ -408,6 +431,7 @@ def shelve_binary_file_add(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_binary_file_del(sbox):
   "shelve binary file del"
 
@@ -429,6 +453,7 @@ def shelve_binary_file_del(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_binary_file_replace(sbox):
   "shelve binary file replace"
 
@@ -451,6 +476,7 @@ def shelve_binary_file_replace(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_with_log_message(sbox):
   "shelve with log message"
 
@@ -500,6 +526,7 @@ def run_and_verify_shelf_status(wc_dir,
   run_and_verify_status(wc_dir, expected_status,
                         changelists=['svn:shelf:' + shelf])
 
+@SkipUnless(shelf3_enabled)
 def shelf_status(sbox):
   "shelf status"
 
@@ -525,6 +552,8 @@ def shelf_status(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
+@SkipUnless(shelf3_enabled)
 def shelve_mkdir(sbox):
   "shelve mkdir"
 
@@ -534,10 +563,11 @@ def shelve_mkdir(sbox):
     sbox.simple_mkdir('D', 'D/D2')
     sbox.simple_propset('p', 'v', 'D', 'D/D2')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_rmdir(sbox):
   "shelve rmdir"
 
@@ -548,10 +578,12 @@ def shelve_rmdir(sbox):
   def modifier(sbox):
     sbox.simple_rm('A/C', 'A/D/G')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
+@XFail()
+@SkipUnless(shelf3_enabled)
 def shelve_replace_dir(sbox):
   "shelve replace dir"
 
@@ -563,10 +595,11 @@ def shelve_replace_dir(sbox):
     sbox.simple_rm('A/C', 'A/D/G')
     sbox.simple_mkdir('A/C', 'A/C/D2')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_file_copy(sbox):
   "shelve file copy"
 
@@ -576,10 +609,11 @@ def shelve_file_copy(sbox):
     sbox.simple_copy('iota', 'A/ii')
     sbox.simple_propset('p', 'v', 'A/ii')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def shelve_dir_copy(sbox):
   "shelve dir copy"
 
@@ -589,10 +623,11 @@ def shelve_dir_copy(sbox):
     sbox.simple_copy('A/B', 'BB')
     sbox.simple_propset('p', 'v', 'BB')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def list_shelves(sbox):
   "list_shelves"
 
@@ -635,6 +670,7 @@ def list_shelves(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def refuse_to_shelve_conflict(sbox):
   "refuse to shelve conflict"
 
@@ -643,31 +679,21 @@ def refuse_to_shelve_conflict(sbox):
   os.chdir(sbox.wc_dir)
   sbox.wc_dir = ''
 
-  # create a tree conflict victim at an unversioned path
+  # create a conflict
   sbox.simple_mkdir('topdir')
   sbox.simple_commit()
-  sbox.simple_mkdir('topdir/subdir')
-  sbox.simple_commit()
-  sbox.simple_update()
-  sbox.simple_rm('topdir')
-  sbox.simple_commit()
   sbox.simple_update()
   svntest.actions.run_and_verify_svn(
     None, [],
-    'merge', '-c2', '.', '--ignore-ancestry', '--accept', 'postpone')
+    'merge', '-c1', '.', '--ignore-ancestry', '--accept', 'postpone')
+  # check that we did create a conflict
   svntest.actions.run_and_verify_svn(
-    None, 'svn: E155015:.*existing.*conflict.*',
+    None, 'svn: E155035:.*conflict.*',
     'merge', '-c1', '.', '--ignore-ancestry', '--accept', 'postpone')
 
   # attempt to shelve
-  expected_out = svntest.verify.RegexListOutput([
-    r'--- .*',
-    r'--- .*',
-    r'\?     C topdir',
-    r'      > .*',
-    r'      >   not shelved'])
-  svntest.actions.run_and_verify_svn(expected_out,
-                                     '.* 1 path could not be shelved',
+  expected_err = "svn: E155015: .* '.*topdir' remains in conflict"
+  svntest.actions.run_and_verify_svn(None, expected_err,
                                      'x-shelf-save', 'foo')
 
   os.chdir(was_cwd)
@@ -711,6 +737,8 @@ def unshelve_with_merge(sbox, setup, mod
 
   os.chdir(was_cwd)
 
+@XFail()
+@SkipUnless(shelf3_enabled)
 def unshelve_text_mod_merge(sbox):
   "unshelve text mod merge"
 
@@ -735,6 +763,8 @@ def unshelve_text_mod_merge(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
+@SkipUnless(shelf3_enabled)
 def unshelve_text_mod_conflict(sbox):
   "unshelve text mod conflict"
 
@@ -765,6 +795,8 @@ def unshelve_text_mod_conflict(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
+@SkipUnless(shelf3_enabled)
 def unshelve_undeclared_binary_mod_conflict(sbox):
   "unshelve undeclared binary mod conflict"
 
@@ -795,6 +827,8 @@ def unshelve_undeclared_binary_mod_confl
 
 #----------------------------------------------------------------------
 
+@XFail()
+@SkipUnless(shelf3_enabled)
 def unshelve_binary_mod_conflict(sbox):
   "unshelve binary mod conflict"
 
@@ -824,6 +858,7 @@ def unshelve_binary_mod_conflict(sbox):
 
 #----------------------------------------------------------------------
 
+@SkipUnless(shelf3_enabled)
 def unshelve_text_prop_merge(sbox):
   "unshelve text prop merge"
 
@@ -845,6 +880,8 @@ def unshelve_text_prop_merge(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
+@SkipUnless(shelf3_enabled)
 def unshelve_text_prop_conflict(sbox):
   "unshelve text prop conflict"
 
@@ -903,7 +940,10 @@ def run_and_verify_shelf_diff_summarize(
     svntest.verify.display_trees(None, 'DIFF OUTPUT TREE', output_tree, actual)
     raise
 
+#----------------------------------------------------------------------
+
 # Exercise a very basic case of shelf-diff.
+@SkipUnless(shelf3_enabled)
 def shelf_diff_simple(sbox):
   "shelf diff simple"
 
@@ -918,6 +958,8 @@ def shelf_diff_simple(sbox):
     sbox.simple_propset('p2', 'v', 'A/mu')
 
   def modifier1(sbox):
+    sbox.simple_rm('A/B/lambda')
+    sbox.simple_add_text('This is a new file.\n', 'A/B/new')
     sbox.simple_append('A/mu', 'New line.\n')
     sbox.simple_propset('p1', 'changed', 'A/mu')
 
@@ -933,7 +975,15 @@ def shelf_diff_simple(sbox):
                                      'x-shelf-save', 'foo')
 
   # basic svn-style diff
-  expected_output = make_diff_header('A/mu', 'revision 2', 'working copy') + [
+  expected_output = make_diff_header('A/B/lambda', 'revision 2', 'nonexistent') + [
+                      "@@ -1 +0,0 @@\n",
+                      "-This is the file 'lambda'.\n"
+                    ]
+  expected_output += make_diff_header('A/B/new', 'nonexistent', 'working copy') + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is a new file.\n"
+                    ]
+  expected_output += make_diff_header('A/mu', 'revision 2', 'working copy') + [
                       "@@ -1 +1,2 @@\n",
                       " This is the file 'mu'.\n",
                       "+New line.\n",
@@ -944,10 +994,30 @@ def shelf_diff_simple(sbox):
 
   # basic summary diff
   expected_diff = svntest.wc.State(wc_dir, {
+    'A/B/lambda':     Item(status='D '),
+    'A/B/new':        Item(status='A '),
     'A/mu':           Item(status='MM'),
   })
   run_and_verify_shelf_diff_summarize(expected_diff, 'foo')
 
+#----------------------------------------------------------------------
+
+@XFail()
+@Issue(4827)
+@SkipUnless(shelf3_enabled)
+def shelve_with_kw_translation(sbox):
+  "shelve with kw translation"
+  sbox.build(empty=True)
+  sbox.simple_add_text('$Rev$\n', 'file')
+  sbox.simple_propset('svn:keywords', 'rev', 'file')
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  def modifier(sbox):
+    sbox.simple_append('file', 'New line\n')
+
+  shelve_unshelve(sbox, modifier)
+
 
 ########################################################################
 # Run the tests
@@ -985,6 +1055,7 @@ test_list = [ None,
               unshelve_text_prop_merge,
               unshelve_text_prop_conflict,
               shelf_diff_simple,
+              shelve_with_kw_translation,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/stat_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/stat_tests.py Fri Jan 14 14:01:45 2022
@@ -1606,7 +1606,7 @@ def status_dash_u_deleted_directories(sb
                                         os.path.join("B", "E", "alpha"),
           "D                1        1 jrandom      %s\n" % \
                                         os.path.join("B", "E", "beta"),
-          "D                1        1 jrandom      %s\n" % 
+          "D                1        1 jrandom      %s\n" %
           os.path.join("B", "F"),
           "Status against revision:      1\n" ])
   svntest.actions.run_and_verify_svn(expected,

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svnadmin_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svnadmin_tests.py Fri Jan 14 14:01:45 2022
@@ -1726,7 +1726,7 @@ def verify_non_utf8_paths(sbox):
       # also fix up the 'created path' field
       fp_new.write(b"cpath: /\xE6\n")
     elif line == b"_0.0.t0-0 add-file true true /A\n":
-      # and another occurrance
+      # and another occurrence
       fp_new.write(b"_0.0.t0-0 add-file true true /\xE6\n")
     else:
       fp_new.write(line)
@@ -3177,7 +3177,7 @@ def load_txdelta(sbox):
 
   sbox.build(empty=True)
 
-  # This dumpfile produced a BDB repository that generated cheksum
+  # This dumpfile produced a BDB repository that generated checksum
   # mismatches on read caused by the improper handling of
   # svn_txdelta_target ops.  The bug was fixed by r1640832.
 
@@ -3220,7 +3220,7 @@ def load_no_svndate_r0(sbox):
               b"Content-length: 10\n", b"\n",
               b"PROPS-END\n", b"\n"]
   svntest.actions.run_and_verify_load(sbox.repo_dir, dump_old)
-  
+
   # svn:date should have been removed
   svntest.actions.run_and_verify_svnlook([], [],
                                          'proplist', '--revprop', '-r0',
@@ -3859,7 +3859,7 @@ def dump_no_canonicalize_svndate(sbox):
                                      sbox.repo_url)
 
   dump_lines = svntest.actions.run_and_verify_dump(sbox.repo_dir)
-  assert propval + '\n' in dump_lines
+  assert propval.encode() + b'\n' in dump_lines
 
 def check_recover_prunes_rep_cache(sbox, enable_rep_sharing):
   """Check 'recover' prunes the rep-cache while enable-rep-sharing is
@@ -3920,6 +3920,145 @@ def recover_prunes_rep_cache_when_disabl
 
   check_recover_prunes_rep_cache(sbox, enable_rep_sharing=False)
 
+@Issue(4760)
+def dump_include_copied_directory(sbox):
+  "include copied directory with nested nodes"
+
+  sbox.build(create_wc=False)
+
+  svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "copy",
+                                     sbox.repo_url + '/A/D',
+                                     sbox.repo_url + '/COPY',
+                                     "-m", "Create branch.")
+
+  # Dump repository with only /COPY path included.
+  _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [],
+                                                       'dump', '-q',
+                                                       '--include', '/COPY',
+                                                       sbox.repo_dir)
+
+  # Load repository from dump.
+  sbox2 = sbox.clone_dependent()
+  sbox2.build(create_wc=False, empty=True)
+  load_and_verify_dumpstream(sbox2, None, [], None, False, dump)
+
+  # Check log.
+  expected_output = svntest.verify.RegexListOutput([
+    '-+\\n',
+    'r2\ .*\n',
+    # Only '/COPY' is added
+    re.escape('Changed paths:\n'),
+    re.escape('   A /COPY'),
+    re.escape('   A /COPY/G'),
+    re.escape('   A /COPY/G/pi'),
+    re.escape('   A /COPY/G/rho'),
+    re.escape('   A /COPY/G/tau'),
+    re.escape('   A /COPY/H'),
+    re.escape('   A /COPY/H/chi'),
+    re.escape('   A /COPY/H/omega'),
+    re.escape('   A /COPY/H/psi'),
+    re.escape('   A /COPY/gamma'),
+    '-+\\n',
+    'r1\ .*\n',
+    '-+\\n'
+  ])
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', '-v', '-q', sbox2.repo_url)
+
+def load_normalize_node_props(sbox):
+  "svnadmin load --normalize node props"
+
+  dump_str = b"""SVN-fs-dump-format-version: 2
+
+UUID: dc40867b-38f6-0310-9f5f-f81aa277e06f
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2005-05-03T19:09:41.129900Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 99
+Content-length: 99
+
+K 7
+svn:log
+V 0
+
+K 10
+svn:author
+V 2
+pl
+K 8
+svn:date
+V 27
+2005-05-03T19:10:19.975578Z
+PROPS-END
+
+Node-path:\x20
+Node-kind: dir
+Node-action: change
+Prop-content-length: 32
+Content-length: 32
+
+K 10
+svn:ignore
+V 3
+\n\r\n
+PROPS-END
+
+
+"""
+  sbox.build(empty=True)
+
+  # Try to load the dumpstream, expecting a failure (because of mixed
+  # EOLs in the svn:ignore property value).
+  exp_err = svntest.verify.RegexListOutput(['svnadmin: E125005:.*',
+                                            'svnadmin: E125017:.*'],
+                                           match_all=False)
+  load_and_verify_dumpstream(sbox, [], exp_err, dumpfile_revisions,
+                             False, dump_str, '--ignore-uuid')
+
+  # Now try it again with prop normalization.
+  svntest.actions.load_repo(sbox, dump_str=dump_str,
+                            bypass_prop_validation=False,
+                            normalize_props=True)
+  # We should get the normalized property value.
+  exit_code, output, _ = svntest.main.run_svn(None, 'pg', 'svn:ignore',
+                                              '--no-newline',
+                                              sbox.repo_url)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
+  if output != ['\n', '\n']:
+    raise svntest.Failure("Unexpected property value %s" % output)
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+@SkipUnless(svntest.main.fs_has_rep_sharing)
+@SkipUnless(svntest.main.python_sqlite_can_read_without_rowid)
+def build_repcache(sbox):
+  "svnadmin build-repcache"
+
+  sbox.build(create_wc = False)
+
+  # Remember and remove the existing rep-cache.
+  rep_cache = read_rep_cache(sbox.repo_dir)
+  rep_cache_path = os.path.join(sbox.repo_dir, 'db', 'rep-cache.db')
+  os.remove(rep_cache_path)
+
+  # Build a new rep-cache and compare with the original one.
+  expected_output = ["* Processed revision 1.\n"]
+  svntest.actions.run_and_verify_svnadmin(expected_output, [],
+                                          "build-repcache", sbox.repo_dir)
+
+  new_rep_cache = read_rep_cache(sbox.repo_dir)
+  if new_rep_cache != rep_cache:
+    raise svntest.Failure
+
+
 ########################################################################
 # Run the tests
 
@@ -3997,6 +4136,9 @@ test_list = [ None,
               dump_no_canonicalize_svndate,
               recover_prunes_rep_cache_when_enabled,
               recover_prunes_rep_cache_when_disabled,
+              dump_include_copied_directory,
+              load_normalize_node_props,
+              build_repcache,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svnauthz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svnauthz_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svnauthz_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svnauthz_tests.py Fri Jan 14 14:01:45 2022
@@ -896,6 +896,105 @@ def svnauthz_compat_mode_repo_test(sbox)
       repo_url + "/zilch"
   )
 
+
+@Issue(4793)
+def svnauthz_inverted_selector_test(sbox):
+  "test inverted selector rights"
+
+  # build an authz file
+  authz_content = ("[groups]\n"
+                   "grouped = grouper\n"
+
+                   "[aliases]\n"
+                   "aliased = aliaser\n"
+
+                   "[A:/]\n"
+                   "@grouped = r\n"
+                   "~@grouped = rw\n"
+
+                   "[B:/]\n"
+                   "&aliased = r\n"
+                   "~&aliased = rw\n"
+
+                   "[C:/]\n"
+                   "user = r\n"
+                   "~user = rw\n"
+
+                   "[D:/]\n"
+                   "~@grouped = rw\n"
+                   "not-grouper = r\n"
+
+                   "[E:/]\n"
+                   "~&aliased = rw\n"
+                   "not-aliaser = r\n"
+
+                   "[F:/]\n"
+                   "~user = rw\n"
+                   "not-user = r\n")
+
+  (authz_fd, authz_path) = tempfile.mkstemp()
+  svntest.main.file_write(authz_path, authz_content)
+
+  def accessof(repos, user, expected_stdout):
+    return svntest.actions.run_and_verify_svnauthz(
+      expected_stdout, None, 0, False, 'accessof',
+      '--repository', repos, '--username', user, authz_path)
+
+  accessof('A', 'grouper', 'r')
+  accessof('A', 'not-grouper', 'rw')
+
+  accessof('B', 'aliaser', 'r')
+  accessof('B', 'not-aliaser', 'rw')
+
+  accessof('C', 'user', 'r')
+  accessof('C', 'not-user', 'rw')
+
+  accessof('D', 'grouper', 'no')
+  accessof('D', 'not-grouper', 'r')
+  accessof('D', 'other', 'rw')
+
+  accessof('E', 'aliaser', 'no')
+  accessof('E', 'not-aliaser', 'r')
+  accessof('E', 'other', 'rw')
+
+  accessof('F', 'user', 'no')
+  accessof('F', 'not-user', 'r')
+  accessof('F', 'other', 'rw')
+
+  os.close(authz_fd)
+  os.remove(authz_path)
+
+
+@Issues(4802, 4803)
+def svnauthz_empty_group_test(sbox):
+  "test empty group definition"
+
+  # build an authz file
+  authz_content = ("[groups]\n"
+                   "group1 =\n"
+                   "group2 = @group1\n"
+                   "group3 = @group2, user\n"
+
+
+                   "[A:/]\n"
+                   "@group1 = rw\n"
+                   "@group2 = rw\n"
+                   "@group3 = r\n")
+
+  (authz_fd, authz_path) = tempfile.mkstemp()
+  svntest.main.file_write(authz_path, authz_content)
+
+  expected_stderr = svntest.verify.RegexOutput(
+    r".*warning: W220003:.*", match_all=False)
+
+  svntest.actions.run_and_verify_svnauthz(
+    [], expected_stderr, 0, False, 'validate', authz_path)
+
+  svntest.actions.run_and_verify_svnauthz(
+    'r', expected_stderr, 0, False, 'accessof',
+    '--repository', 'A', '--username', 'user', authz_path)
+
+
 ########################################################################
 # Run the tests
 
@@ -914,6 +1013,8 @@ test_list = [ None,
               svnauthz_accessof_txn_test,
               svnauthz_compat_mode_file_test,
               svnauthz_compat_mode_repo_test,
+              svnauthz_inverted_selector_test,
+              svnauthz_empty_group_test,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svndumpfilter_tests.py Fri Jan 14 14:01:45 2022
@@ -71,7 +71,7 @@ def filter_and_return_output(dump, bufsi
   # Since we call svntest.main.run_command_stdin() in binary mode,
   # normalize the stderr line endings on Windows ourselves.
   if sys.platform == 'win32':
-    errput = map(lambda x : x.replace('\r\n', '\n'), errput)
+    errput = [x.replace('\r\n', '\n') for x in errput]
 
   return output, errput
 
@@ -608,7 +608,7 @@ def match_empty_prefix(sbox):
                                                              '--quiet',
                                                              *dumpargs)
     if filtered_err:
-      raise verify.UnexpectedStderr(filtered_err)
+      raise SVNExpectedStderr(filtered_err)
 
     # Load the filtered dump into a repo and check the result
     sbox.build(empty=True)

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svneditor.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svneditor.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svneditor.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svneditor.py Fri Jan 14 14:01:45 2022
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 #
 #  svneditor.py: a mock $SVN_EDITOR for the Subversion test suite
 #

Propchange: subversion/branches/multi-wc-format/subversion/tests/cmdline/svneditor.py
            ('svn:executable' removed)

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svnfsfs_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svnfsfs_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svnfsfs_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svnfsfs_tests.py Fri Jan 14 14:01:45 2022
@@ -185,7 +185,7 @@ def test_stats(sbox):
                            '.*\d+ bytes in .*\d+ file property representations',
                            '.*\d+ average delta chain length',
                            '.*\d+ bytes in header & footer overhead' ],
-    '.* representation statistics:' : 
+    '.* representation statistics:' :
                           ['.*\d+ bytes in .*\d+ reps',
                            '.*\d+ bytes in .*\d+ shared reps',
                            '.*\d+ bytes expanded size',

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmover_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmover_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmover_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmover_tests.py Fri Jan 14 14:01:45 2022
@@ -1545,7 +1545,7 @@ def replace_via_rm_cp(sbox):
   """replace by deleting and copying"""
 
   sbox_build_svnmover(sbox)
-                 
+
   expected_eids = svntest.wc.State('', {
     'B0'     : Item(eid=0),
     'B0/X'   : Item(eid=1),
@@ -1572,7 +1572,7 @@ def replace_via_rm_cp(sbox):
   test_svnmover_verify_log(sbox.repo_url,
                            ['D /top0/X/A',
                             'A /top0/X/A (from /top0/X/A:1)'])
-                 
+
 @XFail()
 # After making a commit, svnmover currently can't (within the same execution)
 # look up paths in the revision it just committed.

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmucc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmucc_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmucc_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svnmucc_tests.py Fri Jan 14 14:01:45 2022
@@ -534,7 +534,8 @@ def svnmucc_type_errors(sbox):
                 'put', sbox.ospath('file'), 'A')
 
   xtest_svnmucc(sbox.repo_url,
-                ["svnmucc: E160020: Path 'Z' already exists"],
+                ["svnmucc: E160020: Path 'Z' already exists, or was created "
+                 "by an earlier operation"],
                 '-m', '',
                 'mkdir', 'A/Z',
                 'put', sbox.ospath('file'), 'A/Z')
@@ -576,7 +577,8 @@ def svnmucc_propset_and_put(sbox):
 
   # Put same file twice (non existing)
   xtest_svnmucc(sbox.repo_url,
-                ["svnmucc: E160020: Path 't3' already exists"],
+                ["svnmucc: E160020: Path 't3' already exists, or was created "
+                 "by an earlier operation"],
                 '-m', '',
                 'put', sbox.ospath('file'), 't3',
                 'put', sbox.ospath('file'), 't3')

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svnrdump_tests.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svnrdump_tests.py Fri Jan 14 14:01:45 2022
@@ -991,6 +991,36 @@ def load_non_deltas_with_props(sbox):
     actual = map(str.strip, out)
     svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual)
 
+def load_invalid_svn_date_revprop_in_r0(sbox):
+  "load: invalid svn:date revprop in r0"
+  svnrdump_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
+                                    'svnrdump_tests_data')
+  sbox.build(create_wc=False, empty=True)
+  svntest.actions.enable_revprop_changes(sbox.repo_dir)
+  expected_err = svntest.verify.RegexListOutput(
+                   ['.* E125005: Wrong or unexpected property value.*'],
+                   match_all=False)
+  dumpfile = "bad-date-r0.dump"
+  dumpfile_path = os.path.join(svnrdump_tests_dir, dumpfile)
+  run_and_verify_svnrdump_load(dumpfile_path,
+                               [], expected_err, 1,
+                               sbox.repo_url)
+
+def load_invalid_svn_date_revprop_in_r1(sbox):
+  "load: invalid svn:date revprop in r1"
+  svnrdump_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
+                                    'svnrdump_tests_data')
+  sbox.build(create_wc=False, empty=True)
+  svntest.actions.enable_revprop_changes(sbox.repo_dir)
+  expected_err = svntest.verify.RegexListOutput(
+                   ['.* E125005: Wrong or unexpected property value.*'],
+                   match_all=False)
+  dumpfile = "bad-date-r0.dump"
+  dumpfile_path = os.path.join(svnrdump_tests_dir, dumpfile)
+  run_and_verify_svnrdump_load(dumpfile_path,
+                               [], expected_err, 1,
+                               sbox.repo_url)
+
 ########################################################################
 # Run the tests
 
@@ -1052,6 +1082,8 @@ test_list = [ None,
               load_non_deltas_replace_copy_with_props,
               dump_replace_with_copy,
               load_non_deltas_with_props,
+              load_invalid_svn_date_revprop_in_r0,
+              load_invalid_svn_date_revprop_in_r1,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svnserveautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svnserveautocheck.sh?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svnserveautocheck.sh (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svnserveautocheck.sh Fri Jan 14 14:01:45 2022
@@ -74,6 +74,28 @@ fail() {
   exit 1
 }
 
+query() {
+    printf "%s" "$SCRIPT: $1 (y/n)? [$2] "
+    if [ -n "$BASH_VERSION" ]; then
+        read -n 1 -t 32
+    else
+        #
+        prog="
+import select as s
+import sys
+import tty, termios
+tty.setcbreak(sys.stdin.fileno(), termios.TCSANOW)
+if s.select([sys.stdin.fileno()], [], [], 32)[0]:
+  sys.stdout.write(sys.stdin.read(1))
+"
+        stty_state=`stty -g`
+        REPLY=`$PYTHON -u -c "$prog" "$@"`
+        stty $stty_state
+    fi
+    echo
+    [ "${REPLY:-$2}" = 'y' ]
+}
+
 # Compute ABS_BUILDDIR and ABS_SRCDIR.
 if [ -x subversion/svn/svn ]; then
   # cwd is build tree root
@@ -92,19 +114,27 @@ if [ ! -e $ABS_SRCDIR/subversion/include
   fail "Run this script from the root of Subversion's build tree!"
 fi
 
+# Create a directory for the PID and log files. If you change this, also make
+# sure to change the svn:ignore entry for it and "make check-clean".
+SVNSERVE_ROOT="$ABS_BUILDDIR/subversion/tests/cmdline/svnserve-$(date '+%Y%m%d-%H%M%S')"
+mkdir "$SVNSERVE_ROOT" \
+    || fail "couldn't create temporary directory '$SVNSERVE_ROOT'"
+
 # If you change this, also make sure to change the svn:ignore entry
 # for it and "make check-clean".
-SVNSERVE_PID=$ABS_BUILDDIR/subversion/tests/svnserveautocheck.pid
+SVNSERVE_PID=$SVNSERVE_ROOT/svnserve.pid
+SVNSERVE_LOG=$SVNSERVE_ROOT/svnserve.log
 
 SERVER_CMD="$ABS_BUILDDIR/subversion/svnserve/svnserve"
 
 rm -f $SVNSERVE_PID
+rm -f $SVNSERVE_LOG
 
 random_port() {
   if [ -n "$BASH_VERSION" ]; then
     echo $(($RANDOM+1024))
   else
-    $PYTHON -c 'import random; print random.randint(1024, 2**16-1)'
+    $PYTHON -c 'import random; print(random.randint(1024, 2**16-1))'
   fi
 }
 
@@ -140,6 +170,7 @@ fi
             --listen-host 127.0.0.1 \
             --listen-port $SVNSERVE_PORT \
             --pid-file $SVNSERVE_PID \
+            --log-file $SVNSERVE_LOG \
             $SVNSERVE_ARGS &
 
 BASE_URL=svn://127.0.0.1:$SVNSERVE_PORT
@@ -155,5 +186,11 @@ else
   cd - > /dev/null
 fi
 
+query 'Browse server log' n \
+    && less "$SVNSERVE_LOG"
+
+query 'Delete svnserve root directory' y \
+    && rm -fr "$SVNSERVE_ROOT/"
+
 really_cleanup
 exit $r

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/actions.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/actions.py Fri Jan 14 14:01:45 2022
@@ -64,27 +64,15 @@ def no_relocate_validation():
 def do_relocate_validation():
   os.environ['SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_RELOCATE_VALIDATION'] = 'no'
 
-def setup_pristine_greek_repository():
-  """Create the pristine repository and 'svn import' the greek tree"""
-
-  # these directories don't exist out of the box, so we may have to create them
-  if not os.path.exists(main.general_wc_dir):
-    os.makedirs(main.general_wc_dir)
-
-  if not os.path.exists(main.general_repo_dir):
-    os.makedirs(main.general_repo_dir) # this also creates all the intermediate dirs
-
-  if not os.path.exists(main.other_dav_root_dir):
-    os.makedirs(main.other_dav_root_dir)
-  if not os.path.exists(main.non_dav_root_dir):
-    os.makedirs(main.non_dav_root_dir)
-
+def _setup_pristine_repo(tree_state,
+                         repos_dir, dump_dir, repos_url,
+                         use_precooked=True):
   # If there's no pristine repos, create one.
-  if not os.path.exists(main.pristine_greek_repos_dir):
-    if main.options.fsfs_version is not None:
-      main.unpack_greek_repos(main.pristine_greek_repos_dir)
+  if not os.path.exists(repos_dir):
+    if use_precooked and main.options.fsfs_version is not None:
+      main.unpack_greek_repos(repos_dir)
     else:
-      main.create_repos(main.pristine_greek_repos_dir)
+      main.create_repos(repos_dir)
 
       # if this is dav, gives us access rights to import the greek tree.
       if main.is_ra_type_dav():
@@ -92,15 +80,14 @@ def setup_pristine_greek_repository():
         main.file_write(authz_file, "[/]\n* = rw\n")
 
       # dump the greek tree to disk.
-      main.greek_state.write_to_disk(main.greek_dump_dir)
+      tree_state.write_to_disk(dump_dir)
 
       # 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
       _, output, _ = main.run_svn(None, 'import', '-m',
                                   'Log message for revision 1.',
-                                  main.greek_dump_dir,
-                                  main.pristine_greek_repos_url)
+                                  dump_dir, repos_url)
 
       # verify the printed output of 'svn import'.
       lastline = output.pop().strip()
@@ -112,7 +99,7 @@ def setup_pristine_greek_repository():
         sys.exit(1)
       output_tree = wc.State.from_commit(output)
 
-      expected_output_tree = main.greek_state.copy(main.greek_dump_dir)
+      expected_output_tree = tree_state.copy(dump_dir)
       expected_output_tree.tweak(verb='Adding',
                                  contents=None)
 
@@ -127,9 +114,36 @@ def setup_pristine_greek_repository():
 
     # Finally, disallow any changes to the "pristine" repos.
     error_msg = "Don't modify the pristine repository"
-    create_failing_hook(main.pristine_greek_repos_dir, 'start-commit', error_msg)
-    create_failing_hook(main.pristine_greek_repos_dir, 'pre-lock', error_msg)
-    create_failing_hook(main.pristine_greek_repos_dir, 'pre-revprop-change', error_msg)
+    create_failing_hook(repos_dir, 'start-commit', error_msg)
+    create_failing_hook(repos_dir, 'pre-lock', error_msg)
+    create_failing_hook(repos_dir, 'pre-revprop-change', error_msg)
+
+def setup_pristine_repositories():
+  """Create the pristine repository and 'svn import' the greek tree"""
+
+  # these directories don't exist out of the box, so we may have to create them
+  if not os.path.exists(main.general_wc_dir):
+    os.makedirs(main.general_wc_dir)
+
+  if not os.path.exists(main.general_repo_dir):
+    os.makedirs(main.general_repo_dir) # this also creates all the intermediate dirs
+
+  if not os.path.exists(main.other_dav_root_dir):
+    os.makedirs(main.other_dav_root_dir)
+  if not os.path.exists(main.non_dav_root_dir):
+    os.makedirs(main.non_dav_root_dir)
+
+  _setup_pristine_repo(main.greek_state,
+                       main.pristine_greek_repos_dir,
+                       main.greek_dump_dir,
+                       main.pristine_greek_repos_url)
+
+  # NOTE: We don't use precooked trojan repositories.
+  _setup_pristine_repo(main.trojan_state,
+                       main.pristine_trojan_repos_dir,
+                       main.trojan_dump_dir,
+                       main.pristine_trojan_repos_url,
+                       use_precooked=False)
 
 
 ######################################################################
@@ -149,23 +163,19 @@ def guarantee_empty_repository(path, min
 # Used by every test, so that they can run independently of  one
 # another. Every time this routine is called, it recursively copies
 # 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, minor_version):
-  """Guarantee that a local svn repository exists at PATH, containing
-  nothing but the greek-tree at revision 1."""
-
-  if path == main.pristine_greek_repos_dir:
+# Note: make sure setup_pristine_repositories was called once before
+# using these functions.
+def _guarantee_repos(path, repos_dir, minor_version, use_precooked=True):
+  if path == repos_dir:
     logger.error("attempt to overwrite the pristine repos!  Aborting.")
     sys.exit(1)
 
   # copy the pristine repository to PATH.
   main.safe_rmtree(path)
-  if (main.options.fsfs_version is not None):
+  if (use_precooked and main.options.fsfs_version is not None):
     failed = main.unpack_greek_repos(path)
   else:
-    failed = main.copy_repos(main.pristine_greek_repos_dir,
-                             path, 1, 1, minor_version)
+    failed = main.copy_repos(repos_dir, path, 1, 1, minor_version)
   if failed:
     logger.error("copying repository failed.")
     sys.exit(1)
@@ -176,6 +186,18 @@ def guarantee_greek_repository(path, min
   # give the repository a unique UUID
   run_and_verify_svnadmin([], [], 'setuuid', 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."""
+
+  _guarantee_repos(path, main.pristine_greek_repos_dir, minor_version)
+
+def guarantee_trojan_repository(path, minor_version):
+  """Guarantee that a local svn repository exists at PATH, containing
+  nothing but the trojan-tree at revision 1."""
+
+  _guarantee_repos(path, main.pristine_trojan_repos_dir, minor_version, False)
+
 def run_and_verify_atomic_ra_revprop_change(expected_stdout,
                                             expected_stderr,
                                             expected_exit,
@@ -396,7 +418,7 @@ def run_and_verify_svnrdump(dumpfile_con
   # Since main.run_svnrdump() uses binary mode, normalize the stderr
   # line endings on Windows ourselves.
   if sys.platform == 'win32':
-    err = map(lambda x : x.replace('\r\n', '\n'), err)
+    err = [x.replace('\r\n', '\n') for x in err]
 
   # Ignore "consider upgrade" warnings to allow regression tests to pass
   # when run against a 1.6 mod_dav_svn.
@@ -464,7 +486,7 @@ def run_and_verify_svnsync(expected_stdo
 
 def run_and_verify_svnsync2(expected_stdout, expected_stderr,
                             expected_exit, *varargs):
-  """Run svnmucc command and check its output and exit code."""
+  """Run svnsync command and check its output and exit code."""
 
   exit_code, out, err = main.run_svnsync(*varargs)
 
@@ -485,7 +507,8 @@ def load_repo(sbox, dumpfile_path = None
               normalize_props = False):
   "Loads the dumpfile into sbox"
   if not dump_str:
-    dump_str = open(dumpfile_path, "rb").read()
+    with open(dumpfile_path, "rb") as fp:
+      dump_str = fp.read()
 
   # Create a virgin repos and working copy
   main.safe_rmtree(sbox.repo_dir, 1)
@@ -1901,7 +1924,7 @@ def _run_and_verify_resolve(cmd, expecte
         "Merge conflicts in '" + path + "' marked as resolved.\n" for path in
         expected_paths]),
       verify.UnorderedRegexListOutput([
-        "Conflict in property.*at '" + path + "' marked as resolved.\n" \
+        "Conflict in property.*at '" + re.escape(path) + "' marked as resolved.\n" \
         for path in expected_paths]),
       verify.UnorderedOutput([
         "Tree conflict at '" + path + "' marked as resolved.\n" for path in
@@ -1942,7 +1965,7 @@ 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, empty=False,
-                     minor_version=None):
+                     minor_version=None, tree=None):
   """Create a fresh repository and check out a WC from it.  If EMPTY is
   True, the repository and WC will be empty and at revision 0,
   otherwise they will contain the 'Greek Tree' at revision 1.
@@ -1967,9 +1990,17 @@ def make_repo_and_wc(sbox, create_wc=Tru
     guarantee_empty_repository(sbox.repo_dir, minor_version)
     expected_state = svntest.wc.State('', {})
   else:
-    if not read_only:
-      guarantee_greek_repository(sbox.repo_dir, minor_version)
-    expected_state = main.greek_state
+    if tree == 'greek':
+      if not read_only:
+        guarantee_greek_repository(sbox.repo_dir, minor_version)
+      expected_state = main.greek_state
+    elif tree == 'trojan':
+      if not read_only:
+        guarantee_trojan_repository(sbox.repo_dir, minor_version)
+      expected_state = main.trojan_state
+    else:
+      raise ValueError("'tree' must be 'greek' or 'trojan'"
+                       " but was '%s'" % str(tree))
 
   if create_wc:
     # Generate the expected output tree.
@@ -2003,14 +2034,21 @@ def duplicate_dir(wc_name, wc_copy_name)
 
 
 
-def get_virginal_state(wc_dir, rev):
+def get_virginal_state(wc_dir, rev, tree='greek'):
   "Return a virginal greek tree state for a WC and repos at revision REV."
 
   rev = str(rev) ### maybe switch rev to an integer?
 
   # copy the greek tree, shift it to the new wc_dir, insert a root elem,
   # then tweak all values
-  state = main.greek_state.copy()
+  if tree == 'greek':
+    state = main.greek_state.copy()
+  elif tree == 'trojan':
+    state = main.trojan_state.copy()
+  else:
+    raise ValueError("'tree' must be 'greek' or 'trojan'"
+                     " but was '%s'" % str(tree))
+
   state.wc_dir = wc_dir
   state.desc[''] = wc.StateItem()
   state.tweak(contents=None, status='  ', wc_rev=rev)
@@ -2039,7 +2077,9 @@ def get_wc_base_rev(wc_dir):
 
 def load_dumpfile(filename):
   "Return the contents of the FILENAME assuming that it is a dump file"
-  return open(filename, "rb").readlines()
+  with open(filename, "rb") as fp:
+    dump_str = fp.readlines()
+  return dump_str
 
 def hook_failure_message(hook_name):
   """Return the error message that the client prints for failure of the
@@ -2144,7 +2184,7 @@ def set_prop(name, value, path, expected
       file = None
   else:
     raise TypeError(value)
- 
+
   if file is None:
     propset += (name, value, path)
   else:

Modified: subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/main.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/multi-wc-format/subversion/tests/cmdline/svntest/main.py Fri Jan 14 14:01:45 2022
@@ -55,8 +55,9 @@ except ImportError:
 import svntest
 from svntest import Failure
 from svntest import Skip
+from svntest.wc import StateItem as Item
 
-SVN_VER_MINOR = 12
+SVN_VER_MINOR = 15
 
 ######################################################################
 #
@@ -128,7 +129,10 @@ else:
 if windows:
   svneditor_script = os.path.join(sys.path[0], 'svneditor.bat')
 else:
-  svneditor_script = os.path.join(sys.path[0], 'svneditor.py')
+  # This script is in the build tree, not in the source tree.  
+  svneditor_script = os.path.join(os.path.dirname(
+                                      os.path.dirname(os.path.abspath('.'))),
+                                  'tests/cmdline/svneditor.sh')
 
 # Username and password used by the working copies
 wc_author = 'jrandom'
@@ -199,6 +203,7 @@ svnmover_binary = os.path.abspath('../..
 # Location to the pristine repository, will be calculated from test_area_url
 # when we know what the user specified for --url.
 pristine_greek_repos_url = None
+pristine_trojan_repos_url = None
 
 # Global variable to track all of our options
 options = None
@@ -235,7 +240,9 @@ temp_dir = os.path.join(work_dir, 'local
 
 # (derivatives of the tmp dir.)
 pristine_greek_repos_dir = os.path.join(temp_dir, "repos")
+pristine_trojan_repos_dir = os.path.join(temp_dir, "trojan")
 greek_dump_dir = os.path.join(temp_dir, "greekfiles")
+trojan_dump_dir = os.path.join(temp_dir, "trojanfiles")
 default_config_dir = os.path.abspath(os.path.join(temp_dir, "config"))
 
 #
@@ -245,28 +252,57 @@ default_config_dir = os.path.abspath(os.
 # call main.greek_state.copy().  That method will return a copy of this
 # State object which can then be edited.
 #
-_item = svntest.wc.StateItem
 greek_state = svntest.wc.State('', {
-  'iota'        : _item("This is the file 'iota'.\n"),
-  'A'           : _item(),
-  'A/mu'        : _item("This is the file 'mu'.\n"),
-  'A/B'         : _item(),
-  'A/B/lambda'  : _item("This is the file 'lambda'.\n"),
-  'A/B/E'       : _item(),
-  'A/B/E/alpha' : _item("This is the file 'alpha'.\n"),
-  'A/B/E/beta'  : _item("This is the file 'beta'.\n"),
-  'A/B/F'       : _item(),
-  'A/C'         : _item(),
-  'A/D'         : _item(),
-  'A/D/gamma'   : _item("This is the file 'gamma'.\n"),
-  'A/D/G'       : _item(),
-  'A/D/G/pi'    : _item("This is the file 'pi'.\n"),
-  'A/D/G/rho'   : _item("This is the file 'rho'.\n"),
-  'A/D/G/tau'   : _item("This is the file 'tau'.\n"),
-  'A/D/H'       : _item(),
-  'A/D/H/chi'   : _item("This is the file 'chi'.\n"),
-  'A/D/H/psi'   : _item("This is the file 'psi'.\n"),
-  'A/D/H/omega' : _item("This is the file 'omega'.\n"),
+  'iota'        : Item("This is the file 'iota'.\n"),
+  'A'           : Item(),
+  'A/mu'        : Item("This is the file 'mu'.\n"),
+  'A/B'         : Item(),
+  'A/B/lambda'  : Item("This is the file 'lambda'.\n"),
+  'A/B/E'       : Item(),
+  'A/B/E/alpha' : Item("This is the file 'alpha'.\n"),
+  'A/B/E/beta'  : Item("This is the file 'beta'.\n"),
+  'A/B/F'       : Item(),
+  'A/C'         : Item(),
+  'A/D'         : Item(),
+  'A/D/gamma'   : Item("This is the file 'gamma'.\n"),
+  'A/D/G'       : Item(),
+  'A/D/G/pi'    : Item("This is the file 'pi'.\n"),
+  'A/D/G/rho'   : Item("This is the file 'rho'.\n"),
+  'A/D/G/tau'   : Item("This is the file 'tau'.\n"),
+  'A/D/H'       : Item(),
+  'A/D/H/chi'   : Item("This is the file 'chi'.\n"),
+  'A/D/H/psi'   : Item("This is the file 'psi'.\n"),
+  'A/D/H/omega' : Item("This is the file 'omega'.\n"),
+  })
+
+# Likewise our pristine trojan-tree state (for peg revision parsing tests)
+# NOTE: We don't use precooked trojan repositories.
+trojan_state = svntest.wc.State('', {
+  'iota'        : Item("This is the file 'iota'.\n"),
+  '@zeta'       : Item("This is the file 'zeta'.\n"),
+  '_@theta'     : Item("This is the file 'theta'.\n"),
+  '.@kappa'     : Item("This is the file 'kappa'.\n"),
+  'lambda@'     : Item("This is the file 'lambda'.\n"),
+  '@omicron@'   : Item("This is the file 'omicron'.\n"),
+  '@'           : Item(),
+  '@@'          : Item(),
+  '_@'          : Item(),
+  '.@'          : Item(),
+  'A'           : Item(),
+  'A/@@'        : Item("This is the file 'A/@@'.\n"),
+  'A/alpha'     : Item("This is the file 'alpha'.\n"),
+  'A/@omega@'   : Item("This is the file 'omega'.\n"),
+  'B'           : Item(),
+  'B/@'         : Item("This is the file 'B/@'.\n"),
+  'B/@beta'     : Item("This is the file 'beta'.\n"),
+  'B/pi@'       : Item("This is the file 'pi'.\n"),
+  'G'           : Item(),
+  'G/_@'        : Item("This is the file 'G/_@'.\n"),
+  'G/_@gamma'   : Item("This is the file 'gamma'.\n"),
+  'D'           : Item(),
+  'D/.@'        : Item("This is the file 'D/.@'.\n"),
+  'D/.@delta'   : Item("This is the file 'delta'.\n"),
+  'E'           : Item(),
   })
 
 
@@ -494,10 +530,10 @@ def wait_on_pipe(waiter, binary_mode, st
 
   # We always expect STDERR to be strings, not byte-arrays.
   if not isinstance(stderr, str):
-    stderr = stderr.decode("utf-8")
+    stderr = stderr.decode("utf-8", 'surrogateescape')
   if not binary_mode:
     if not isinstance(stdout, str):
-      stdout = stdout.decode("utf-8")
+      stdout = stdout.decode("utf-8", 'surrogateescape')
 
     # Normalize Windows line endings if in text mode.
     if windows:
@@ -709,9 +745,9 @@ def trust_ssl_cert(cfgdir, ssl_cert, ssl
   """
 
   cert_rep = ''
-  fp = open(ssl_cert, 'r')
-  for line in fp.readlines()[1:-1]:
-    cert_rep = cert_rep + line.strip()
+  with open(ssl_cert, 'r') as fp:
+    for line in fp.readlines()[1:-1]:
+      cert_rep = cert_rep + line.strip()
 
   parsed_url = urlparse(ssl_url)
   netloc_url = '%s://%s' % (parsed_url.scheme, parsed_url.netloc)
@@ -869,8 +905,6 @@ def run_entriesdump(path):
     ### report on this? or continue to just skip it?
     return None
 
-  class Entry(object):
-    pass
   entries = { }
   exec(''.join(filter_dbg(stdout_lines)))
   return entries
@@ -894,8 +928,6 @@ def run_entriesdump_tree(path):
     ### report on this? or continue to just skip it?
     return None
 
-  class Entry(object):
-    pass
   dirs = { }
   exec(''.join(filter_dbg(stdout_lines)))
   return dirs
@@ -1318,30 +1350,29 @@ def create_http_connection(url, debuglev
   h.set_debuglevel(debuglevel)
   return h
 
-def write_restrictive_svnserve_conf(repo_dir, anon_access="none"):
+def write_restrictive_svnserve_conf(repo_dir, anon_access="none",
+                                    separate_groups_db=False):
   "Create a restrictive authz file ( no anynomous access )."
 
   fp = open(get_svnserve_conf_file_path(repo_dir), 'w')
-  fp.write("[general]\nanon-access = %s\nauth-access = write\n"
-           "authz-db = authz\n" % anon_access)
+  fp.write("[general]\n"
+           "anon-access = %s\n"
+           "auth-access = write\n"
+           "authz-db = authz\n" % anon_access);
+  if separate_groups_db:
+    fp.write("groups-db = groups\n")
   if options.enable_sasl:
-    fp.write("realm = svntest\n[sasl]\nuse-sasl = true\n");
+    fp.write("realm = svntest\n"
+             "[sasl]\n",
+             "use-sasl = true\n");
   else:
     fp.write("password-db = passwd\n")
   fp.close()
 
-def write_restrictive_svnserve_conf_with_groups(repo_dir,
-                                                anon_access="none"):
+def write_restrictive_svnserve_conf_with_groups(repo_dir, anon_access="none"):
   "Create a restrictive configuration with groups stored in a separate file."
 
-  fp = open(get_svnserve_conf_file_path(repo_dir), 'w')
-  fp.write("[general]\nanon-access = %s\nauth-access = write\n"
-           "authz-db = authz\ngroups-db = groups\n" % anon_access)
-  if options.enable_sasl:
-    fp.write("realm = svntest\n[sasl]\nuse-sasl = true\n");
-  else:
-    fp.write("password-db = passwd\n")
-  fp.close()
+  return write_restrictive_svnserve_conf(repo_dir, anon_access, True)
 
 # Warning: because mod_dav_svn uses one shared authz file for all
 # repositories, you *cannot* use write_authz_file in any test that
@@ -1662,7 +1693,6 @@ def is_plaintext_password_storage_disabl
     return False
   return True
 
-
 # https://issues.apache.org/bugzilla/show_bug.cgi?id=56480
 # https://issues.apache.org/bugzilla/show_bug.cgi?id=55397
 __mod_dav_url_quoting_broken_versions = frozenset([
@@ -1686,6 +1716,10 @@ def is_httpd_authz_provider_enabled():
       return (v[0] == '2' and int(v[1]) >= 3) or int(v[0]) > 2
     return None
 
+def is_remote_http_connection_allowed():
+  return options.allow_remote_http_connection
+
+
 ######################################################################
 
 
@@ -1766,6 +1800,8 @@ class TestSpawningThread(threading.Threa
       args.append('--fsfs-compression=' + options.fsfs_compression)
     if options.fsfs_dir_deltification:
       args.append('--fsfs-dir-deltification=' + options.fsfs_dir_deltification)
+    if options.allow_remote_http_connection:
+      args.append('--allow-remote-http-connection')
     if options.svn_bin:
       args.append('--bin=' + options.svn_bin)
 
@@ -2047,6 +2083,23 @@ class AbbreviatedFormatter(logging.Forma
     record.levelshort = self._level_short[record.levelno]
     return logging.Formatter.format(self, record)
 
+
+class LoggingStdoutHandler(logging.StreamHandler):
+  """
+  The handler is always writing using sys.stdout at call time rather than the
+  value of sys.stdout at construction time.
+
+  Inspired by logging._StderrHandler on Python 3.
+  """
+
+  def __init__(self, level=logging.NOTSET):
+    logging.Handler.__init__(self, level)
+
+  @property
+  def stream(self):
+    return sys.stdout
+
+
 def _create_parser(usage=None):
   """Return a parser for our test suite."""
 
@@ -2184,6 +2237,8 @@ def _create_parser(usage=None):
                     help='Set compression type (for fsfs)')
   parser.add_option('--fsfs-dir-deltification', action='store', type='str',
                     help='Set directory deltification option (for fsfs)')
+  parser.add_option('--allow-remote-http-connection', action='store_true',
+                    help='Run tests that connect to remote HTTP(S) servers')
 
   # most of the defaults are None, but some are other values, set them here
   parser.set_defaults(
@@ -2237,7 +2292,7 @@ def parse_options(arglist=sys.argv[1:],
                                        datefmt='%Y-%m-%d %H:%M:%S')
     else:
       formatter = AbbreviatedFormatter('%(levelshort)s: %(message)s')
-    handler = logging.StreamHandler(sys.stdout)
+    handler = LoggingStdoutHandler()
     handler.setFormatter(formatter)
     logger.addHandler(handler)
 
@@ -2353,6 +2408,7 @@ def execute_tests(test_list, serial_only
 
   global pristine_url
   global pristine_greek_repos_url
+  global pristine_trojan_repos_url
   global other_dav_root_url
   global non_dav_root_url
   global svn_binary
@@ -2434,6 +2490,12 @@ def execute_tests(test_list, serial_only
                                   pristine_greek_repos_dir.replace(
                                       os.path.sep, '/'))
 
+  # Calculate pristine_trojan_repos_url from test_area_url.
+  pristine_trojan_repos_url = options.test_area_url + '/' + \
+                                svntest.wc.svn_uri_quote(
+                                  pristine_trojan_repos_dir.replace(
+                                      os.path.sep, '/'))
+
   other_dav_root_url = options.test_area_url + '/fsdavroot'
   non_dav_root_url = options.test_area_url + '/nodavroot'
 
@@ -2530,8 +2592,8 @@ def execute_tests(test_list, serial_only
                         http_proxy=options.http_proxy,
                         exclusive_wc_locks=options.exclusive_wc_locks)
 
-      # Setup the pristine repository
-      svntest.actions.setup_pristine_greek_repository()
+      # Setup the pristine repositories
+      svntest.actions.setup_pristine_repositories()
 
     # Run the tests.
     exit_code = _internal_run_tests(test_list, testnums, options.parallel,