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 2011/10/11 21:52:46 UTC

svn commit: r1182053 [28/30] - in /subversion/branches/svn_mutex: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/hook-scripts/enforcer/ contrib/server-side/ notes/ notes/merge-t...

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/main.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/main.py Tue Oct 11 19:52:34 2011
@@ -51,6 +51,7 @@ import svntest
 from svntest import Failure
 from svntest import Skip
 
+SVN_VER_MINOR = 8
 
 ######################################################################
 #
@@ -164,6 +165,8 @@ entriesdump_binary = os.path.abspath('en
 atomic_ra_revprop_change_binary = os.path.abspath('atomic-ra-revprop-change' + \
                                                   _exe)
 wc_lock_tester_binary = os.path.abspath('../libsvn_wc/wc-lock-tester' + _exe)
+svnmucc_binary=os.path.abspath('../../../tools/client-side/svnmucc/svnmucc' + \
+                               _exe)
 
 # Location to the pristine repository, will be calculated from test_area_url
 # when we know what the user specified for --url.
@@ -579,6 +582,13 @@ def _with_auth(args):
   else:
     return args + ('--username', wc_author )
 
+def _with_log_message(args):
+
+  if '-m' in args or '--message' in args or '-F' in args:
+    return args
+  else:
+    return args + ('--message', 'default log message')
+
 # For running subversion and returning the output
 def run_svn(error_expected, *varargs):
   """Run svn with VARARGS; return exit code as int; stdout, stderr as
@@ -606,7 +616,7 @@ def run_svnrdump(stdin_input, *varargs):
   """Run svnrdump with VARARGS, returns exit code as int; stdout, stderr as
   list of lines (including line terminators).  Use binary mode for output."""
   if stdin_input:
-    return run_command_stdin(svnrdump_binary, 0, 1, 1, stdin_input,
+    return run_command_stdin(svnrdump_binary, 1, 1, 1, stdin_input,
                              *(_with_auth(_with_config_dir(varargs))))
   else:
     return run_command(svnrdump_binary, 1, 1,
@@ -622,6 +632,12 @@ def run_svnversion(*varargs):
   as list of lines (including line terminators)."""
   return run_command(svnversion_binary, 1, 0, *varargs)
 
+def run_svnmucc(*varargs):
+  """Run svnmucc with VARARGS, returns exit code as int; stdout, stderr as
+  list of lines (including line terminators).  Use binary mode for output."""
+  return run_command(svnmucc_binary, 1, 1,
+                     *(_with_auth(_with_config_dir(_with_log_message(varargs)))))
+
 def run_entriesdump(path):
   """Run the entries-dump helper, returning a dict of Entry objects."""
   # use spawn_process rather than run_command to avoid copying all the data
@@ -689,11 +705,16 @@ def chmod_tree(path, mode, mask):
 
 # For clearing away working copies
 def safe_rmtree(dirname, retry=0):
-  "Remove the tree at DIRNAME, making it writable first"
+  """Remove the tree at DIRNAME, making it writable first.
+     If DIRNAME is a symlink, only remove the symlink, not its target."""
   def rmtree(dirname):
     chmod_tree(dirname, 0666, 0666)
     shutil.rmtree(dirname)
 
+  if os.path.islink(dirname):
+    os.unlink(dirname)
+    return
+
   if not os.path.exists(dirname):
     return
 
@@ -740,12 +761,12 @@ def create_repos(path):
     os.makedirs(path) # this creates all the intermediate dirs, if neccessary
 
   opts = ("--bdb-txn-nosync",)
-  if options.server_minor_version < 5:
+  if options.server_minor_version < 4:
+    opts += ("--pre-1.4-compatible",)
+  elif options.server_minor_version < 5:
     opts += ("--pre-1.5-compatible",)
   elif options.server_minor_version < 6:
     opts += ("--pre-1.6-compatible",)
-  elif options.server_minor_version < 7:
-    opts += ("--pre-1.7-compatible",)
   if options.fs_type is not None:
     opts += ("--fs-type=" + options.fs_type,)
   exit_code, stdout, stderr = run_command(svnadmin_binary, 1, 0, "create",
@@ -1111,6 +1132,9 @@ def server_gets_client_capabilities():
 def server_has_partial_replay():
   return options.server_minor_version >= 5
 
+def server_enforces_UTF8_fspaths_in_verify():
+  return options.server_minor_version >= 6
+
 def server_enforces_date_syntax():
   return options.server_minor_version >= 5
 
@@ -1477,8 +1501,8 @@ def _create_parser():
                          "it supports both, else assume it's using this " +
                          "one; the default is " + _default_http_library)
   parser.add_option('--server-minor-version', type='int', action='store',
-                    help="Set the minor version for the server ('4', " +
-                         "'5', or '6').")
+                    help="Set the minor version for the server ('3'..'%d')."
+                    % SVN_VER_MINOR)
   parser.add_option('--fsfs-packing', action='store_true',
                     help="Run 'svnadmin pack' automatically")
   parser.add_option('--fsfs-sharding', action='store', type='int',
@@ -1498,7 +1522,7 @@ def _create_parser():
 
   # most of the defaults are None, but some are other values, set them here
   parser.set_defaults(
-        server_minor_version=7,
+        server_minor_version=SVN_VER_MINOR,
         url=file_scheme_prefix + pathname2url(os.path.abspath(os.getcwd())),
         http_library=_default_http_library)
 
@@ -1519,8 +1543,12 @@ def _parse_options(arglist=sys.argv[1:])
     parser.error("'verbose' and 'quiet' are incompatible")
   if options.fsfs_packing and not options.fsfs_sharding:
     parser.error("--fsfs-packing requires --fsfs-sharding")
-  if options.server_minor_version < 4 or options.server_minor_version > 7:
-    parser.error("test harness only supports server minor versions 4-7")
+
+  # If you change the below condition then change
+  # ../../../../build/run_tests.py too.
+  if options.server_minor_version not in range(3, SVN_VER_MINOR+1):
+    parser.error("test harness only supports server minor versions 3-%d"
+                 % SVN_VER_MINOR)
 
   if options.url:
     if options.url[-1:] == '/': # Normalize url to have no trailing slash
@@ -1600,6 +1628,7 @@ def execute_tests(test_list, serial_only
   global svnsync_binary
   global svndumpfilter_binary
   global svnversion_binary
+  global svnmucc_binary
   global options
 
   if test_name:
@@ -1675,6 +1704,7 @@ def execute_tests(test_list, serial_only
                                         'jsvndumpfilter' + _bat)
     svnversion_binary = os.path.join(options.svn_bin,
                                      'jsvnversion' + _bat)
+    svnversion_binary = os.path.join(options.svn_bin, 'jsvnmucc' + _bat)
   else:
     if options.svn_bin:
       svn_binary = os.path.join(options.svn_bin, 'svn' + _exe)
@@ -1684,6 +1714,7 @@ def execute_tests(test_list, serial_only
       svndumpfilter_binary = os.path.join(options.svn_bin,
                                           'svndumpfilter' + _exe)
       svnversion_binary = os.path.join(options.svn_bin, 'svnversion' + _exe)
+      svnmucc_binary = os.path.join(options.svn_bin, 'svnmucc' + _exe)
 
   ######################################################################
 

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/sandbox.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/sandbox.py Tue Oct 11 19:52:34 2011
@@ -204,16 +204,18 @@ class Sandbox:
       target = self.ospath(target)
     svntest.main.run_svn(False, 'switch', url, target, '--ignore-ancestry')
 
-  def simple_commit(self, target=None):
-    """Commit the WC or TARGET with a default log message.
+  def simple_commit(self, target=None, message=None):
+    """Commit the WC or TARGET, with a default or supplied log message.
+       Raise if the exit code is non-zero or there is output on stderr.
        TARGET is a relpath relative to the WC."""
     assert not self.read_only
     if target is None:
       target = self.wc_dir
     else:
       target = self.ospath(target)
-    svntest.main.run_svn(False, 'commit',
-                         '-m', svntest.main.make_log_msg(),
+    if message is None:
+      message = svntest.main.make_log_msg()
+    svntest.main.run_svn(False, 'commit', '-m', message,
                          target)
 
   def simple_rm(self, *targets):

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/wc.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/svntest/wc.py Tue Oct 11 19:52:34 2011
@@ -135,10 +135,18 @@ class State:
       self.desc[path] = item
 
   def remove(self, *paths):
-    "Remove a path from the state (the path must exist)."
+    "Remove PATHS from the state (the paths must exist)."
     for path in paths:
       del self.desc[to_relpath(path)]
 
+  def remove_subtree(self, *paths):
+    "Remove PATHS recursively from the state (the paths must exist)."
+    for subtree_path in paths:
+      subtree_path = to_relpath(subtree_path)
+      for path, item in self.desc.items():
+        if path == subtree_path or path[:len(subtree_path) + 1] == subtree_path + '/':
+          del self.desc[path]
+
   def copy(self, new_root=None):
     """Make a deep copy of self.  If NEW_ROOT is not None, then set the
     copy's wc_dir NEW_ROOT instead of to self's wc_dir."""
@@ -180,13 +188,12 @@ class State:
 
   def subtree(self, subtree_path):
     """Return a State object which is a deep copy of the sub-tree
-    identified by SUBTREE_PATH (which is assumed to contain only one
-    element rooted at the tree of this State object's WC_DIR)."""
+    beneath SUBTREE_PATH (which is assumed to be rooted at the tree of
+    this State object's WC_DIR).  Exclude SUBTREE_PATH itself."""
     desc = { }
     for path, item in self.desc.items():
-      path_elements = path.split("/")
-      if len(path_elements) > 1 and path_elements[0] == subtree_path:
-        desc["/".join(path_elements[1:])] = item.copy()
+      if path[:len(subtree_path) + 1] == subtree_path + '/':
+        desc[path[len(subtree_path) + 1:]] = item.copy()
     return State(self.wc_dir, desc)
 
   def write_to_disk(self, target_dir):

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/svnversion_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/svnversion_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/svnversion_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/svnversion_tests.py Tue Oct 11 19:52:34 2011
@@ -147,7 +147,8 @@ def svnversion_test(sbox):
   X_path = os.path.join(wc_dir, 'Q', 'X')
   svntest.actions.run_and_verify_svnversion("Nonexistent file or directory",
                                             X_path, repo_url,
-                                            None, [ "'%s' doesn't exist\n" % X_path ])
+                                            None, [ "'%s' doesn't exist\n"
+                                                   % os.path.abspath(X_path) ])
 
   # Perform a sparse checkout of under the existing WC, and confirm that
   # svnversion detects it as a "partial" WC.
@@ -287,9 +288,8 @@ def svnversion_with_structural_changes(s
   svntest.actions.run_and_verify_svnversion("Deleted file",
                                             sbox.ospath('iota'),
                                             repo_url + '/iota',
+                                            ["1M\n"],
                                             [],
-                                            [ "'%s' doesn't exist\n" % \
-                                              sbox.ospath('iota')],
                                             )
   svntest.actions.run_and_verify_svnversion("Deleted file", wc_dir, repo_url,
                                             [ "1:2M\n" ], [])

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/switch_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/switch_tests.py Tue Oct 11 19:52:34 2011
@@ -2856,6 +2856,56 @@ def up_to_old_rev_with_subtree_switched_
   # Now update the WC to r1.
   svntest.actions.run_and_verify_svn(None, None, [], 'up', '-r1', wc_dir)
 
+def different_node_kind(sbox):
+  "switch to a different node kind"
+  sbox.build(read_only = True)
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+
+  pristine_disk = svntest.main.greek_state
+  pristine_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+  expected_disk = pristine_disk.copy()
+  expected_status = pristine_status.copy()
+
+  def switch_to_dir(sbox, rel_url, rel_path):
+    full_url = sbox.repo_url + '/' + rel_url
+    full_path = sbox.ospath(rel_path)
+    expected_disk.remove(rel_path)
+    expected_disk.add({ rel_path : pristine_disk.desc[rel_url] })
+    expected_disk.add_state(rel_path, pristine_disk.subtree(rel_url))
+    expected_status.tweak(rel_path, switched='S')
+    expected_status.add_state(rel_path, pristine_status.subtree(rel_url))
+    svntest.actions.run_and_verify_switch(sbox.wc_dir, full_path, full_url,
+                                          None, expected_disk, expected_status,
+                                          None, None, None, None, None, False,
+                                          '--ignore-ancestry')
+    svntest.actions.run_and_verify_svn(None, None, [], 'info', full_path)
+    if not os.path.isdir(full_path):
+      raise svntest.Failure
+
+  def switch_to_file(sbox, rel_url, rel_path):
+    full_url = sbox.repo_url + '/' + rel_url
+    full_path = sbox.ospath(rel_path)
+    expected_disk.remove_subtree(rel_path)
+    expected_disk.add({ rel_path : pristine_disk.desc[rel_url] })
+    expected_status.remove_subtree(rel_path)
+    expected_status.add({ rel_path : pristine_status.desc[rel_url] })
+    expected_status.tweak(rel_path, switched='S')
+    svntest.actions.run_and_verify_switch(sbox.wc_dir, full_path, full_url,
+                                          None, expected_disk, expected_status,
+                                          None, None, None, None, None, False,
+                                          '--ignore-ancestry')
+    svntest.actions.run_and_verify_svn(None, None, [], 'info', full_path)
+    if not os.path.isfile(full_path):
+      raise svntest.Failure
+
+  # Switch two files to dirs and two dirs to files.
+  # 'A/C' is an empty dir; 'A/D/G' is a non-empty dir.
+  switch_to_dir(sbox, 'A/C', 'iota')
+  switch_to_dir(sbox, 'A/D/G', 'A/D/gamma')
+  switch_to_file(sbox, 'iota', 'A/C')
+  switch_to_file(sbox, 'A/D/gamma', 'A/D/G')
+
 ########################################################################
 # Run the tests
 
@@ -2895,6 +2945,7 @@ test_list = [ None,
               tree_conflicts_on_switch_3,
               copy_with_switched_subdir,
               up_to_old_rev_with_subtree_switched_to_root,
+              different_node_kind,
               ]
 
 if __name__ == '__main__':

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/tree_conflict_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/tree_conflict_tests.py Tue Oct 11 19:52:34 2011
@@ -254,8 +254,10 @@ d_adds = [
 # Scenarios that start with an existing versioned item
 #
 # GO-AWAY: node is no longer at the path where it was.
-# file-del(F) = del(F) or move(F,F2)
+# file-del(F) = del(F)
+# file-move(F) = move(F,F2)
 # dir-del(D)  = del(D) or move(D,D2)
+# Note: file-move(F) does not conflict with incoming edit
 #
 # REPLACE: node is no longer at the path where it was, but another node is.
 # file-rpl(F) = file-del(F) + file-add(F)
@@ -268,8 +270,12 @@ d_adds = [
 
 f_dels = [
   ( create_f, ['fD'] ),
+]
+
+f_moves = [
   ( create_f, ['fM'] ),
 ]
+
 d_dels = [
   ( create_d, ['dD'] ),
   ( create_d, ['dM'] ),
@@ -479,7 +485,7 @@ def ensure_tree_conflict(sbox, operation
         incoming_right_rev = source_right_rev
       else:
         incoming_right_rev = head_rev
-      expected_info = { 'Tree conflict' : operation +
+      expected_info = { 'Tree conflict' : '.* upon ' + operation +
           r'.* \((none|(file|dir).*' +
             re.escape(victim_name + '@' + str(incoming_left_rev)) + r')' +
           r'.* \((none|(file|dir).*' +
@@ -562,7 +568,7 @@ def test_tc_merge(sbox, incoming_scen, b
 # WC state: as scheduled (no obstruction)
 
 def up_sw_file_mod_onto_del(sbox):
-  "up/sw file: modify onto del/rpl/mv"
+  "up/sw file: modify onto del/rpl"
   test_tc_up_sw(sbox, f_mods, f_dels + f_rpls)
   # Note: See UC1 in notes/tree-conflicts/use-cases.txt.
 
@@ -573,12 +579,12 @@ def up_sw_file_del_onto_mod(sbox):
   #          ### OR (see Nico's email <>):
   #          schedule-delete but leave F on disk (can only apply with
   #            text-mod; prop-mod can't be preserved in this way)
-  test_tc_up_sw(sbox, f_dels + f_rpls, f_mods)
+  test_tc_up_sw(sbox, f_dels + f_moves + f_rpls, f_mods)
   # Note: See UC2 in notes/tree-conflicts/use-cases.txt.
 
 def up_sw_file_del_onto_del(sbox):
   "up/sw file: del/rpl/mv onto del/rpl/mv"
-  test_tc_up_sw(sbox, f_dels + f_rpls, f_dels + f_rpls)
+  test_tc_up_sw(sbox, f_dels + f_moves + f_rpls, f_dels + f_rpls)
   # Note: See UC3 in notes/tree-conflicts/use-cases.txt.
 
 def up_sw_file_add_onto_add(sbox):
@@ -650,22 +656,24 @@ def up_sw_dir_add_onto_add(sbox):
 def merge_file_mod_onto_not_file(sbox):
   "merge file: modify onto not-file"
   sbox2 = sbox.clone_dependent()
-  test_tc_merge(sbox, f_mods, br_scen = f_dels + f_rpl_d)
+  test_tc_merge(sbox, f_mods, br_scen = f_dels + f_moves + f_rpl_d)
   test_tc_merge(sbox2, f_mods, wc_scen = f_dels)
   # Note: See UC4 in notes/tree-conflicts/use-cases.txt.
 
 def merge_file_del_onto_not_same(sbox):
   "merge file: del/rpl/mv onto not-same"
   sbox2 = sbox.clone_dependent()
-  test_tc_merge(sbox, f_dels + f_rpls, br_scen = f_mods)
-  test_tc_merge(sbox2, f_dels + f_rpls, wc_scen = f_mods)
+  test_tc_merge(sbox, f_dels + f_moves + f_rpls, br_scen = f_mods)
+  test_tc_merge(sbox2, f_dels + f_moves + f_rpls, wc_scen = f_mods)
   # Note: See UC5 in notes/tree-conflicts/use-cases.txt.
 
 def merge_file_del_onto_not_file(sbox):
   "merge file: del/rpl/mv onto not-file"
   sbox2 = sbox.clone_dependent()
-  test_tc_merge(sbox, f_dels + f_rpls, br_scen = f_dels + f_rpl_d)
-  test_tc_merge(sbox2, f_dels + f_rpls, wc_scen = f_dels)
+  test_tc_merge(sbox, f_dels + f_moves + f_rpls,
+                br_scen = f_dels + f_moves + f_rpl_d)
+  test_tc_merge(sbox2, f_dels + f_moves + f_rpls,
+                wc_scen = f_dels + f_moves)
   # Note: See UC6 in notes/tree-conflicts/use-cases.txt.
 
 def merge_file_add_onto_not_none(sbox):
@@ -1164,10 +1172,8 @@ def actual_only_node_behaviour(sbox):
   run_and_verify_svn(None, expected_stdout, expected_stderr,
                      "cat", "-r", "BASE", foo_path)
   # changelist (cl)
-  ### this does not error out -- needs review
-  ### the item does not end up in the changelist so this is a cosmetic problem
   expected_stdout = None
-  expected_stderr = []
+  expected_stderr = ".*svn: warning: W155010: The node '.*foo' was not found."
   run_and_verify_svn(None, expected_stdout, expected_stderr,
                      "changelist", "my_changelist", foo_path)
 
@@ -1226,8 +1232,6 @@ def actual_only_node_behaviour(sbox):
     'Name': 'foo',
     'Schedule': 'normal',
     'Node Kind': 'none',
-    'Depth': 'empty', ### is this right?
-    'Copied From Rev': '0',
     'Path': re.escape(sbox.ospath('A/foo')),
   }
   run_and_verify_info([expected_info], foo_path)
@@ -1303,11 +1307,10 @@ def actual_only_node_behaviour(sbox):
                      "propget", "svn:eol-style", foo_path)
 
   # proplist (plist, pl)
-  ### proplist does exit(0) -- is that expected?
   expected_stdout = None
   expected_stderr = ".*foo.*is not under version control.*"
-  svntest.actions.run_and_verify_svn2(None, expected_stdout, expected_stderr,
-                                      0, "proplist", foo_path)
+  svntest.actions.run_and_verify_svn(None, expected_stdout, expected_stderr,
+                                     "proplist", foo_path)
 
   # propset (pset, ps)
   expected_stdout = None
@@ -1365,7 +1368,7 @@ def actual_only_node_behaviour(sbox):
 
   # update (up)
   expected_stdout = [
-   "Skipped '%s'\n" % sbox.ospath('A/foo'),
+   "Skipped '%s' -- Node remains in conflict\n" % sbox.ospath('A/foo'),
    "Summary of conflicts:\n",
    "  Skipped paths: 1\n",
   ]

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/update_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/update_tests.py Tue Oct 11 19:52:34 2011
@@ -5342,6 +5342,68 @@ def revive_children_of_copy(sbox):
   if not os.path.exists(psi2_path):
     raise svntest.Failure('psi unexpectedly non-existent')
 
+@SkipUnless(svntest.main.is_os_windows)
+def skip_access_denied(sbox):
+  """access denied paths should be skipped"""
+
+  # We need something to lock the file. 'msvcrt' looks common on Windows
+  try:
+    import msvcrt
+  except ImportError:
+    raise svntest.Skip
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  iota = sbox.ospath('iota')
+
+  svntest.main.file_write(iota, 'Q')
+  sbox.simple_commit()
+  sbox.simple_update() # Update to r2
+
+  # Open iota for writing to keep an handle open
+  f = open(iota, 'w')
+
+  # Write new text of exactly the same size to avoid the early out
+  # on a different size without properties.
+  f.write('R')
+  f.flush()
+
+  # And lock the first byte of the file
+  msvcrt.locking(f.fileno(), 1, 1)
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota' : Item(verb='Skipped'),
+    })
+
+  # Create expected status tree: iota isn't updated
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', status='M ', wc_rev=2)
+
+  # And now check that update skips the path
+  # *and* status shows the path as modified.
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None,
+                                        None, None,
+                                        None, None, None, wc_dir, '-r', '1')
+
+  f.close()
+
+def update_to_HEAD_plus_1(sbox):
+  "updating to HEAD+1 should fail"
+
+  sbox.build(read_only = True)
+  wc_dir = sbox.wc_dir
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        None, None, None,
+                                        ".*No such revision",
+                                        None, None,
+                                        None, None, None, wc_dir, '-r', '2')
+
 
 #######################################################################
 # Run the tests
@@ -5407,6 +5469,8 @@ test_list = [ None,
               update_with_file_lock_and_keywords_property_set,
               update_nonexistent_child_of_copy,
               revive_children_of_copy,
+              skip_access_denied,
+              update_to_HEAD_plus_1,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/upgrade_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/upgrade_tests.py Tue Oct 11 19:52:34 2011
@@ -1093,6 +1093,93 @@ def upgrade_with_missing_subdir(sbox):
                                         expected_disk,
                                         expected_status)
 
+@Issue(3994)
+def upgrade_locked(sbox):
+  "upgrade working copy with locked files"
+
+  replace_sbox_with_tarfile(sbox, 'upgrade_locked.tar.bz2')
+
+  svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir)
+
+  expected_status = svntest.wc.State(sbox.wc_dir,
+    {
+      ''                  : Item(status='  ', wc_rev=1),
+      'A'                 : Item(status='D ', wc_rev=2),
+      'A/third'           : Item(status='D ', writelocked='K', wc_rev=2),
+      'other'             : Item(status='D ', writelocked='K', wc_rev=4),
+      'iota'              : Item(status='  ', writelocked='K', wc_rev=3),
+    })
+
+  run_and_verify_status_no_server(sbox.wc_dir, expected_status)
+
+@Issue(4015)
+def upgrade_file_externals(sbox):
+  "upgrade with file externals"
+
+  sbox.build()
+  replace_sbox_with_tarfile(sbox, 'upgrade_file_externals.tar.bz2')
+  svntest.main.run_svnadmin('setuuid', sbox.repo_dir,
+                            '07146bbd-0b64-4aaf-ab70-cd76a0df2d41')
+
+  expected_output = svntest.verify.RegexOutput('r2 committed.*')
+  svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+                                         'propset', 'svn:externals',
+                                         '^/A/B/E EX\n^/A/mu muX',
+                                         sbox.repo_url + '/A/B/F')
+
+  expected_output = svntest.verify.RegexOutput('r3 committed.*')
+  svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+                                         'propset', 'svn:externals',
+                                         '^/A/B/F FX\n^/A/B/lambda lambdaX',
+                                         sbox.repo_url + '/A/C')
+
+  expected_output = svntest.verify.RegexOutput('r4 committed.*')
+  svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+                                         'propset', 'pname1', 'pvalue1',
+                                         sbox.repo_url + '/A/mu',
+                                         'propset', 'pname2', 'pvalue2',
+                                         sbox.repo_url + '/A/B/lambda',
+                                         'propset', 'pname3', 'pvalue3',
+                                         sbox.repo_url + '/A/B/E/alpha')
+
+  svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir)
+  svntest.actions.run_and_verify_svn(None, None, [], 'relocate',
+                                     'file:///tmp/repo', sbox.repo_url,
+                                     sbox.wc_dir)
+  
+  expected_output = svntest.wc.State(sbox.wc_dir, {
+      'A/mu'            : Item(status=' U'),
+      'A/B/lambda'      : Item(status=' U'),
+      'A/B/E/alpha'     : Item(status=' U'),
+      'A/C/FX/EX/alpha' : Item(status=' U'),
+      'A/C/FX/muX'      : Item(status=' U'),
+      'A/C/lambdaX'     : Item(status=' U'),
+      'A/B/F/EX/alpha'  : Item(status=' U'),
+      'A/B/F/muX'       : Item(status=' U'),
+      })
+  svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output,
+                                        None, None)
+
+  ### simple_property_verify only sees last line of multi-line
+  ### property values such as svn:externals
+  simple_property_verify(sbox.wc_dir, {
+      'A/mu'          : {'pname1' : 'pvalue1' },
+      'A/B/lambda'    : {'pname2' : 'pvalue2' },
+      'A/B/E/alpha'   : {'pname3' : 'pvalue3' },
+      'A/B/F'         : {'svn:externals' : '^/A/mu muX'},
+      'A/C'           : {'svn:externals' : '^/A/B/lambda lambdaX'},
+      'A/B/F/muX'     : {'pname1' : 'pvalue1' },
+      'A/C/lambdaX'   : {'pname2' : 'pvalue2' },
+      })
+
+  simple_property_verify(sbox.ospath('A/C/FX'), {
+      ''    : {'svn:externals' : '^/A/mu muX'},
+      'muX' : {'pname1' : 'pvalue1' },
+      })
+
+  simple_property_verify(sbox.ospath('A/C/FX/EX'), {
+      'alpha' : {'pname3' : 'pvalue3' },
+      })
 
 ########################################################################
 # Run the tests
@@ -1141,6 +1228,8 @@ test_list = [ None,
               add_add_del_del_tc,
               add_add_x2,
               upgrade_with_missing_subdir,
+              upgrade_locked,
+              upgrade_file_externals,
              ]
 
 

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_client/client-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_client/client-test.c Tue Oct 11 19:52:34 2011
@@ -36,6 +36,40 @@
 #include "../svn_test.h"
 #include "../svn_test_fs.h"
 
+
+/* Create a repository with a filesystem based on OPTS in a subdir NAME,
+ * commit the standard Greek tree as revision 1, and set *REPOS_URL to
+ * the URL we will use to access it.
+ *
+ * ### This always returns a file: URL. We should upgrade this to use the
+ *     test suite's specified URL scheme instead. */
+static svn_error_t *
+create_greek_repos(const char **repos_url,
+                   const char *name,
+                   const svn_test_opts_t *opts,
+                   apr_pool_t *pool)
+{
+  svn_repos_t *repos;
+  svn_revnum_t committed_rev;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *txn_root;
+
+  /* Create a filesytem and repository. */
+  SVN_ERR(svn_test__create_repos(&repos, name, opts, pool));
+
+  /* Prepare and commit a txn containing the Greek tree. */
+  SVN_ERR(svn_fs_begin_txn2(&txn, svn_repos_fs(repos), 0 /* rev */,
+                            0 /* flags */, pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &committed_rev, txn, pool));
+  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(committed_rev));
+
+  SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, name, pool));
+  return SVN_NO_ERROR;
+}
+
+
 typedef struct mergeinfo_catalog_item {
   const char *path;
   const char *unparsed_mergeinfo;
@@ -244,6 +278,7 @@ check_patch_result(const char *path, con
   svn_pool_destroy(iterpool);
 
   SVN_TEST_ASSERT(i == num_expected_lines);
+  SVN_ERR(svn_stream_close(stream));
   SVN_ERR(svn_io_remove_file2(path, FALSE, pool));
 
   return SVN_NO_ERROR;
@@ -290,14 +325,9 @@ static svn_error_t *
 test_patch(const svn_test_opts_t *opts,
            apr_pool_t *pool)
 {
-  svn_repos_t *repos;
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  svn_fs_root_t *txn_root;
   const char *repos_url;
   const char *wc_path;
   const char *cwd;
-  svn_revnum_t committed_rev;
   svn_opt_revision_t rev;
   svn_opt_revision_t peg_rev;
   svn_client_ctx_t *ctx;
@@ -332,22 +362,11 @@ test_patch(const svn_test_opts_t *opts,
     "+It is really the file 'gamma'."
   };
 
-  /* Create a filesytem and repository. */
-  SVN_ERR(svn_test__create_repos(&repos, "test-patch-repos",
-                                 opts, pool));
-  fs = svn_repos_fs(repos);
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &committed_rev, txn, pool));
-  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(committed_rev));
+  /* Create a filesytem and repository containing the Greek tree. */
+  SVN_ERR(create_greek_repos(&repos_url, "test-patch-repos", opts, pool));
 
   /* Check out the HEAD revision */
   SVN_ERR(svn_dirent_get_absolute(&cwd, "", pool));
-  SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, "test-patch-repos",
-                                           pool));
 
   /* Put wc inside an unversioned directory.  Checking out a 1.7 wc
      directly inside a 1.6 wc doesn't work reliably, an intervening
@@ -408,10 +427,6 @@ static svn_error_t *
 test_wc_add_scenarios(const svn_test_opts_t *opts,
                       apr_pool_t *pool)
 {
-  svn_repos_t *repos;
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  svn_fs_root_t *txn_root;
   const char *repos_url;
   const char *wc_path;
   svn_revnum_t committed_rev;
@@ -422,20 +437,9 @@ test_wc_add_scenarios(const svn_test_opt
   const char *ex_dir_path;
   const char *ex2_dir_path;
 
-  /* Create a filesytem and repository. */
-  SVN_ERR(svn_test__create_repos(&repos, "test-wc-add-repos",
-                                 opts, pool));
-  fs = svn_repos_fs(repos);
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &committed_rev, txn, pool));
-  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(committed_rev));
-
-  SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, "test-wc-add-repos",
-                                           pool));
+  /* Create a filesytem and repository containing the Greek tree. */
+  SVN_ERR(create_greek_repos(&repos_url, "test-wc-add-repos", opts, pool));
+  committed_rev = 1;
 
   SVN_ERR(svn_dirent_get_absolute(&wc_path, "test-wc-add", pool));
 
@@ -555,32 +559,15 @@ static svn_error_t *
 test_copy_crash(const svn_test_opts_t *opts,
                 apr_pool_t *pool)
 {
-  svn_repos_t *repos;
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  svn_fs_root_t *txn_root;
   apr_array_header_t *sources;
-  svn_revnum_t committed_rev;
   svn_opt_revision_t rev;
   svn_client_copy_source_t source;
   svn_client_ctx_t *ctx;
   const char *dest;
   const char *repos_url;
 
-  /* Create a filesytem and repository. */
-  SVN_ERR(svn_test__create_repos(&repos, "test-copy-crash",
-                                 opts, pool));
-  fs = svn_repos_fs(repos);
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &committed_rev, txn, pool));
-  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(committed_rev));
-
-  SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, "test-copy-crash",
-                                           pool));
+  /* Create a filesytem and repository containing the Greek tree. */
+  SVN_ERR(create_greek_repos(&repos_url, "test-copy-crash", opts, pool));
 
   svn_client_create_context(&ctx, pool);
 
@@ -604,11 +591,6 @@ static svn_error_t *
 test_16k_add(const svn_test_opts_t *opts,
                 apr_pool_t *pool)
 {
-  svn_repos_t *repos;
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  svn_fs_root_t *txn_root;
-  svn_revnum_t committed_rev;
   svn_opt_revision_t rev;
   svn_client_ctx_t *ctx;
   const char *repos_url;
@@ -618,22 +600,11 @@ test_16k_add(const svn_test_opts_t *opts
   apr_pool_t *iterpool = svn_pool_create(pool);
   int i;
 
-  /* Create a filesytem and repository. */
-  SVN_ERR(svn_test__create_repos(&repos, "test-16k-repos",
-                                 opts, pool));
-  fs = svn_repos_fs(repos);
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &committed_rev, txn, pool));
-  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(committed_rev));
+  /* Create a filesytem and repository containing the Greek tree. */
+  SVN_ERR(create_greek_repos(&repos_url, "test-16k-repos", opts, pool));
 
   /* Check out the HEAD revision */
   SVN_ERR(svn_dirent_get_absolute(&cwd, "", pool));
-  SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, "test-16k-repos",
-                                           pool));
 
   /* Put wc inside an unversioned directory.  Checking out a 1.7 wc
      directly inside a 1.6 wc doesn't work reliably, an intervening

Propchange: subversion/branches/svn_mutex/subversion/tests/libsvn_delta/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Oct 11 19:52:34 2011
@@ -1,6 +1,7 @@
 Debug
 Release
 .libs
+ev2-from-delta-editor-test
 deltaparse-test
 delta-combine-test
 vdelta-test
@@ -8,6 +9,7 @@ random-test
 xml-output-test
 svndiff-test
 window-test
+editor-test
 combined
 *.o
 *.lo

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_diff/parse-diff-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_diff/parse-diff-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_diff/parse-diff-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_diff/parse-diff-test.c Tue Oct 11 19:52:34 2011
@@ -246,29 +246,38 @@ static const char *bad_git_diff_header =
   "diff --git a/ b/path 1 b/ b/path 1"                                  NL
   "new file mode 100644"                                                NL;
 
+static const char *unidiff_lacking_trailing_eol =
+  "Index: A/C/gamma"                                                    NL
+  "===================================================================" NL
+  "--- A/C/gamma\t(revision 2)"                                         NL
+  "+++ A/C/gamma\t(working copy)"                                       NL
+  "@@ -1 +1,2 @@"                                                       NL
+  " This is the file 'gamma'."                                          NL
+  "+some more bytes to 'gamma'"; /* Don't add NL after this line */
 
-/* Create a PATCH_FILE with name FNAME containing the contents of DIFF. */
+
+/* Create a PATCH_FILE containing the contents of DIFF. */
 static svn_error_t *
-create_patch_file(svn_patch_file_t **patch_file, const char *fname,
+create_patch_file(svn_patch_file_t **patch_file,
                   const char *diff, apr_pool_t *pool)
 {
+  apr_size_t bytes;
   apr_size_t len;
-  apr_status_t status;
+  const char *path;
   apr_file_t *apr_file;
 
   /* Create a patch file. */
-  status = apr_file_open(&apr_file, fname,
-                        (APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE |
-                         APR_DELONCLOSE), APR_OS_DEFAULT, pool);
-  if (status != APR_SUCCESS)
-    return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "Cannot open '%s'",
-                             fname);
-  len = strlen(diff);
-  status = apr_file_write_full(apr_file, diff, len, &len);
-  if (status || len != strlen(diff))
+  SVN_ERR(svn_io_open_unique_file3(&apr_file, &path, NULL,
+                                   svn_io_file_del_on_pool_cleanup,
+                                   pool, pool));
+
+  bytes = strlen(diff);
+  SVN_ERR(svn_io_file_write_full(apr_file, diff, bytes, &len, pool));
+  if (len != bytes)
     return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
-                             "Cannot write to '%s'", fname);
-  SVN_ERR(svn_diff_open_patch_file(patch_file, fname, pool));
+                             "Cannot write to '%s'", path);
+  SVN_ERR(svn_io_file_close(apr_file, pool));
+  SVN_ERR(svn_diff_open_patch_file(patch_file, path, pool));
 
   return SVN_NO_ERROR;
 }
@@ -314,7 +323,6 @@ static svn_error_t *
 test_parse_unidiff(apr_pool_t *pool)
 {
   svn_patch_file_t *patch_file;
-  const char *fname = "test_parse_unidiff.patch";
   svn_boolean_t reverse;
   svn_boolean_t ignore_whitespace;
   int i;
@@ -330,7 +338,7 @@ test_parse_unidiff(apr_pool_t *pool)
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(create_patch_file(&patch_file, fname, unidiff, pool));
+      SVN_ERR(create_patch_file(&patch_file, unidiff, pool));
 
       /* We have two patches with one hunk each.
        * Parse the first patch. */
@@ -393,9 +401,8 @@ test_parse_git_diff(apr_pool_t *pool)
   svn_patch_file_t *patch_file;
   svn_patch_t *patch;
   svn_diff_hunk_t *hunk;
-  const char *fname = "test_parse_git_diff.patch";
 
-  SVN_ERR(create_patch_file(&patch_file, fname, git_unidiff, pool));
+  SVN_ERR(create_patch_file(&patch_file, git_unidiff, pool));
 
   /* Parse a deleted empty file */
   SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
@@ -467,10 +474,8 @@ test_parse_git_tree_and_text_diff(apr_po
   svn_patch_file_t *patch_file;
   svn_patch_t *patch;
   svn_diff_hunk_t *hunk;
-  const char *fname = "test_parse_git_tree_and_text_diff.patch";
 
-  SVN_ERR(create_patch_file(&patch_file, fname, git_tree_and_text_unidiff,
-                            pool));
+  SVN_ERR(create_patch_file(&patch_file, git_tree_and_text_unidiff, pool));
 
   /* Parse a copied file with text modifications. */
   SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
@@ -567,10 +572,8 @@ test_bad_git_diff_headers(apr_pool_t *po
   svn_patch_file_t *patch_file;
   svn_patch_t *patch;
   svn_diff_hunk_t *hunk;
-  const char *fname = "test_bad_git_diff_header.patch";
 
-  SVN_ERR(create_patch_file(&patch_file, fname, bad_git_diff_header,
-                            pool));
+  SVN_ERR(create_patch_file(&patch_file, bad_git_diff_header, pool));
 
   SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
                                     FALSE, /* reverse */
@@ -607,9 +610,8 @@ test_parse_property_diff(apr_pool_t *poo
   svn_prop_patch_t *prop_patch;
   svn_diff_hunk_t *hunk;
   apr_array_header_t *hunks;
-  const char *fname = "test_parse_property_diff.patch";
 
-  SVN_ERR(create_patch_file(&patch_file, fname, property_unidiff, pool));
+  SVN_ERR(create_patch_file(&patch_file, property_unidiff, pool));
 
   SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
                                     FALSE, /* reverse */
@@ -710,10 +712,8 @@ test_parse_property_and_text_diff(apr_po
   svn_prop_patch_t *prop_patch;
   svn_diff_hunk_t *hunk;
   apr_array_header_t *hunks;
-  const char *fname = "test_parse_property_and_text_diff.patch";
 
-  SVN_ERR(create_patch_file(&patch_file, fname, property_and_text_unidiff,
-                            pool));
+  SVN_ERR(create_patch_file(&patch_file, property_and_text_unidiff, pool));
 
   SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
                                     FALSE, /* reverse */
@@ -766,10 +766,8 @@ test_parse_diff_symbols_in_prop_unidiff(
   svn_prop_patch_t *prop_patch;
   svn_diff_hunk_t *hunk;
   apr_array_header_t *hunks;
-  const char *fname = "test_parse_diff_symbols_in_prop_unidiff.patch";
 
-  SVN_ERR(create_patch_file(&patch_file, fname, diff_symbols_in_prop_unidiff,
-                            pool));
+  SVN_ERR(create_patch_file(&patch_file, diff_symbols_in_prop_unidiff, pool));
 
   SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
                                     FALSE, /* reverse */
@@ -865,10 +863,8 @@ test_git_diffs_with_spaces_diff(apr_pool
 {
   svn_patch_file_t *patch_file;
   svn_patch_t *patch;
-  const char *fname = "test_git_diffs_with_spaces_diff.patch";
 
-  SVN_ERR(create_patch_file(&patch_file, fname, path_with_spaces_unidiff,
-                            pool));
+  SVN_ERR(create_patch_file(&patch_file, path_with_spaces_unidiff, pool));
 
   SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
                                     FALSE, /* reverse */
@@ -913,6 +909,57 @@ test_git_diffs_with_spaces_diff(apr_pool
   SVN_ERR(svn_diff_close_patch_file(patch_file, pool));
   return SVN_NO_ERROR;
 }
+
+static svn_error_t *
+test_parse_unidiff_lacking_trailing_eol(apr_pool_t *pool)
+{
+  svn_patch_file_t *patch_file;
+  svn_boolean_t reverse;
+  svn_boolean_t ignore_whitespace;
+  int i;
+  apr_pool_t *iterpool;
+
+  reverse = FALSE;
+  ignore_whitespace = FALSE;
+  iterpool = svn_pool_create(pool);
+  for (i = 0; i < 2; i++)
+    {
+      svn_patch_t *patch;
+      svn_diff_hunk_t *hunk;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(create_patch_file(&patch_file, unidiff_lacking_trailing_eol,
+                                pool));
+
+      /* We have one patch with one hunk. Parse it. */
+      SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file, reverse,
+                                        ignore_whitespace, iterpool,
+                                        iterpool));
+      SVN_TEST_ASSERT(patch);
+      SVN_TEST_STRING_ASSERT(patch->old_filename, "A/C/gamma");
+      SVN_TEST_STRING_ASSERT(patch->new_filename, "A/C/gamma");
+      SVN_TEST_ASSERT(patch->hunks->nelts == 1);
+
+      hunk = APR_ARRAY_IDX(patch->hunks, 0, svn_diff_hunk_t *);
+      SVN_ERR(check_content(hunk, ! reverse,
+                            "This is the file 'gamma'." NL,
+                            pool));
+
+      /* Verify that the contents are as expected, with a NL appended.
+         TODO: test for notification about the NL silently appended */
+      SVN_ERR(check_content(hunk, reverse,
+                            "This is the file 'gamma'." NL
+                            "some more bytes to 'gamma'" NL,
+                            pool));
+
+      reverse = !reverse;
+      SVN_ERR(svn_diff_close_patch_file(patch_file, pool));
+    }
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
 /* ========================================================================== */
 
 struct svn_test_descriptor_t test_funcs[] =
@@ -934,5 +981,7 @@ struct svn_test_descriptor_t test_funcs[
                    "test property diffs with odd symbols"),
     SVN_TEST_PASS2(test_git_diffs_with_spaces_diff,
                    "test git diffs with spaces in paths"),
+    SVN_TEST_XFAIL2(test_parse_unidiff_lacking_trailing_eol,
+                   "test parsing unidiffs lacking trailing eol"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_fs/fs-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_fs/fs-test.c Tue Oct 11 19:52:34 2011
@@ -658,6 +658,7 @@ revision_props(const svn_test_opts_t *op
 
   /* Copy a property's value into a new property. */
   SVN_ERR(svn_fs_revision_prop(&value, fs, 0, "color", pool));
+  SVN_TEST_ASSERT(value);
 
   s1.data = value->data;
   s1.len = value->len;
@@ -694,6 +695,7 @@ revision_props(const svn_test_opts_t *op
   /* Obtain a list of all current properties, and make sure it matches
      the expected values. */
   SVN_ERR(svn_fs_revision_proplist(&proplist, fs, 0, pool));
+  SVN_TEST_ASSERT(proplist);
   {
     svn_string_t *prop_value;
 
@@ -4799,6 +4801,102 @@ node_origin_rev(const svn_test_opts_t *o
   return SVN_NO_ERROR;
 }
 
+
+/* Helper: call svn_fs_history_location() and check the results. */
+static svn_error_t *
+check_history_location(const char *expected_path,
+                       svn_revnum_t expected_revision,
+                       svn_fs_history_t *history,
+                       apr_pool_t *pool)
+{
+  const char *actual_path;
+  svn_revnum_t actual_revision;
+
+  SVN_ERR(svn_fs_history_location(&actual_path, &actual_revision,
+                                  history, pool));
+
+  /* Validate the location against our expectations. */
+  if (actual_revision != expected_revision
+      || (actual_path && expected_path && strcmp(actual_path, expected_path))
+      || (actual_path != NULL) != (expected_path != NULL))
+    {
+      return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                               "svn_fs_history_location() failed:\n"
+                               "  expected '%s@%ld'\n"
+                               "     found '%s@%ld",
+                               expected_path ? expected_path : "(null)",
+                               expected_revision,
+                               actual_path ? actual_path : "(null)",
+                               actual_revision);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Test svn_fs_history_*(). */
+static svn_error_t *
+node_history(const svn_test_opts_t *opts,
+             apr_pool_t *pool)
+{
+  svn_fs_t *fs;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *txn_root;
+  svn_revnum_t after_rev;
+
+  /* Prepare a txn to receive the greek tree. */
+  SVN_ERR(svn_test__create_fs(&fs, "test-repo-node-history",
+                              opts, pool));
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+  /* Create and verify the greek tree. */
+  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
+  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
+
+  /* Make some changes, following copy_test() above. */
+
+  /* r2: copy pi to pi2, with textmods. */
+  {
+    svn_fs_root_t *rev_root;
+
+    SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
+    SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
+    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+    SVN_ERR(svn_fs_copy(rev_root, "A/D/G/pi",
+                        txn_root, "A/D/H/pi2",
+                        pool));
+    SVN_ERR(svn_test__set_file_contents
+            (txn_root, "A/D/H/pi2", "This is the file 'pi2'.\n", pool));
+    SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
+  }
+
+  /* Go back in history: pi2@r2 -> pi@r1 */
+  {
+    svn_fs_history_t *history;
+    svn_fs_root_t *rev_root;
+
+    SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
+
+    /* Fetch a history object, and walk it until its start. */
+
+    SVN_ERR(svn_fs_node_history(&history, rev_root, "A/D/H/pi2", pool));
+    SVN_ERR(check_history_location("/A/D/H/pi2", 2, history, pool));
+
+    SVN_ERR(svn_fs_history_prev(&history, history, TRUE, pool));
+    SVN_ERR(check_history_location("/A/D/H/pi2", 2, history, pool));
+
+    SVN_ERR(svn_fs_history_prev(&history, history, TRUE, pool));
+    SVN_ERR(check_history_location("/A/D/G/pi", 1, history, pool));
+
+    SVN_ERR(svn_fs_history_prev(&history, history, TRUE, pool));
+    SVN_TEST_ASSERT(history == NULL);
+  }
+
+  return SVN_NO_ERROR;
+}
+
+
+
 /* ------------------------------------------------------------------------ */
 
 /* The test table.  */
@@ -4878,5 +4976,7 @@ struct svn_test_descriptor_t test_funcs[
                        "test svn_fs_node_origin_rev"),
     SVN_TEST_OPTS_PASS(small_file_integrity,
                        "create and modify small file"),
+    SVN_TEST_OPTS_PASS(node_history,
+                       "test svn_fs_node_history"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_fs_fs/fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_fs_fs/fs-pack-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_fs_fs/fs-pack-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_fs_fs/fs-pack-test.c Tue Oct 11 19:52:34 2011
@@ -95,6 +95,43 @@ get_rev_contents(svn_revnum_t rev, apr_p
   return apr_psprintf(pool, "%" APR_INT64_T_FMT "\n", num);
 }
 
+struct pack_notify_baton
+{
+  apr_int64_t expected_shard;
+  svn_fs_pack_notify_action_t expected_action;
+};
+
+static svn_error_t *
+pack_notify(void *baton,
+            apr_int64_t shard,
+            svn_fs_pack_notify_action_t action,
+            apr_pool_t *pool)
+{
+  struct pack_notify_baton *pnb = baton;
+
+  SVN_TEST_ASSERT(shard == pnb->expected_shard);
+  SVN_TEST_ASSERT(action == pnb->expected_action);
+
+  /* Update expectations. */
+  switch (action)
+    {
+      case svn_fs_pack_notify_start:
+        pnb->expected_action = svn_fs_pack_notify_end;
+        break;
+
+      case svn_fs_pack_notify_end:
+        pnb->expected_action = svn_fs_pack_notify_start;
+        pnb->expected_shard++;
+        break;
+
+      default:
+        return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+                                "Unknown notification action when packing");
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Create a packed filesystem in DIR.  Set the shard size to
    SHARD_SIZE and create NUM_REVS number of revisions (in addition to
    r0).  Use POOL for allocations.  After this function successfully
@@ -113,6 +150,7 @@ create_packed_filesystem(const char *dir
   const char *conflict;
   svn_revnum_t after_rev;
   apr_pool_t *subpool = svn_pool_create(pool);
+  struct pack_notify_baton pnb;
   apr_pool_t *iterpool;
   int version;
 
@@ -156,7 +194,9 @@ create_packed_filesystem(const char *dir
   svn_pool_destroy(subpool);
 
   /* Now pack the FS */
-  return svn_fs_pack(dir, NULL, NULL, NULL, NULL, pool);
+  pnb.expected_shard = 0;
+  pnb.expected_action = svn_fs_pack_notify_start;
+  return svn_fs_pack(dir, pack_notify, &pnb, NULL, NULL, pool);
 }
 
 

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_repos/repos-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_repos/repos-test.c Tue Oct 11 19:52:34 2011
@@ -1314,6 +1314,14 @@ authz(apr_pool_t *pool)
                             "Regression: incomplete ancestry test "
                             "for recursive access lookup.");
 
+  /* The authz rules for the phase 4 tests */
+  contents =
+    "[greek:/dir2//secret]"                                                  NL
+    "* ="                                                                    NL;
+  err = authz_get_handle(&authz_cfg, contents, subpool);
+  SVN_TEST_ASSERT_ERROR(err, SVN_ERR_AUTHZ_INVALID_CONFIG);
+  svn_error_clear(err);
+
   /* That's a wrap! */
   svn_pool_destroy(subpool);
   return SVN_NO_ERROR;

Propchange: subversion/branches/svn_mutex/subversion/tests/libsvn_subr/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Oct 11 19:52:34 2011
@@ -34,3 +34,4 @@ dirent_uri-test
 auth-test
 eol-test
 subst_translate-test
+spillbuf-test

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_subr/auth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_subr/auth-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_subr/auth-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_subr/auth-test.c Tue Oct 11 19:52:34 2011
@@ -54,6 +54,9 @@ test_platform_specific_auth_providers(ap
 #ifdef SVN_HAVE_KWALLET
   number_of_providers += 2;
 #endif
+#ifdef SVN_HAVE_GPG_AGENT
+  number_of_providers += 1;
+#endif
 #ifdef SVN_HAVE_KEYCHAIN_SERVICES
   number_of_providers += 2;
 #endif

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_subr/mergeinfo-test.c Tue Oct 11 19:52:34 2011
@@ -1181,7 +1181,7 @@ test_rangelist_merge(apr_pool_t *pool)
     svn_merge_range_t expected_merge[6];
   };
 
-  #define SIZE_OF_RANGE_MERGE_TEST_ARRAY 59
+  #define SIZE_OF_RANGE_MERGE_TEST_ARRAY 68
   /* The actual test data. */
   struct rangelist_merge_test_data test_data[SIZE_OF_RANGE_MERGE_TEST_ARRAY] =
     {
@@ -1266,6 +1266,29 @@ test_rangelist_merge(apr_pool_t *pool)
       {"/A: 2-17", "/A: 1-5*,7*,12-13*", 2,
        {{0, 1, FALSE}, {1, 17, TRUE}}},
 
+      {"/A: 3-4*,10-15,20", "/A: 5-60*", 5,
+       {{2, 9, FALSE}, {9, 15, TRUE}, {15, 19, FALSE},{19, 20, TRUE},
+        {20, 60, FALSE}}},
+
+      {"/A: 5-60*", "/A: 3-4*,10-15,20", 5,
+       {{2, 9, FALSE}, {9, 15, TRUE}, {15, 19, FALSE},{19, 20, TRUE},
+        {20, 60, FALSE}}},
+
+      {"/A: 3-4*,50-100*", "/A: 5-60*", 1, {{2, 100, FALSE}}},
+
+      {"/A: 5-60*", "/A: 3-4*,50-100*", 1, {{2, 100, FALSE}}},
+
+      {"/A: 3-4*,50-100", "/A: 5-60*", 2, {{2, 49, FALSE}, {49, 100, TRUE}}},
+
+      {"/A: 5-60*", "/A: 3-4*,50-100", 2, {{2, 49, FALSE}, {49, 100, TRUE}}},
+
+      {"/A: 3-4,50-100*", "/A: 5-60", 2, {{2, 60, TRUE}, {60, 100, FALSE}}},
+
+      {"/A: 5-60", "/A: 3-4,50-100*", 2, {{2, 60, TRUE}, {60, 100, FALSE}}},
+
+      {"/A: 5,9,11-15,17,200-300,999", "/A: 7-50", 4,
+       {{4, 5, TRUE}, {6, 50, TRUE}, {199, 300, TRUE}, {998, 999, TRUE}}},
+
       /* A rangelist merged with an empty rangelist should equal the
          non-empty rangelist but in compacted form. */
       {"/A: 1-44,45,46,47-50",       "",  1, {{ 0, 50, TRUE }}},

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_wc/create_wc_for_upgrade.sh
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_wc/create_wc_for_upgrade.sh?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_wc/create_wc_for_upgrade.sh (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_wc/create_wc_for_upgrade.sh Tue Oct 11 19:52:34 2011
@@ -83,10 +83,10 @@ echo epsilon > epsilon
 ### row is created).
 
 # a file with just .working
-### what comes after epsilon??
-echo lambda > lambda
-"${SVN}" add lambda
-"${SVN}" propset l-prop l-value lambda
+# zeta = epsilon+1
+echo zeta > zeta
+"${SVN}" add zeta
+"${SVN}" propset z-prop z-value zeta
 
 # a file with .base and .working
 "${SVN}" propset b-more b-value2 beta

Modified: subversion/branches/svn_mutex/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/libsvn_wc/db-test.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/branches/svn_mutex/subversion/tests/libsvn_wc/db-test.c Tue Oct 11 19:52:34 2011
@@ -140,7 +140,7 @@ static const char * const TESTING_DATA =
   "  null, null, null, null);"
   "insert into nodes values ("
   "  1, 'J/J-e', 0, 'J', 1, 'J/J-e', 1, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
+  "  null, 'other/place', 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
   "  null, null, null, null);"
   "insert into nodes values ("
   "  1, 'J/J-e/J-e-a', 0, 'J/J-e', 1, 'J/J-e/J-e-a', 1, 'normal',"
@@ -172,7 +172,7 @@ static const char * const TESTING_DATA =
   "  15, null, null, null);"
   "insert into nodes values ("
   "  1, 'K/K-b', 0, 'K', 1, 'K/K-b', 1, 'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
+  "  null, 'moved/away', 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
   "  15, null, null, null);"
   ""
    /* Load data into NODES table;
@@ -228,8 +228,12 @@ static const char * const TESTING_DATA =
   "  1, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
   "  10, null, null, null);"
   "insert into nodes values ("
+  "  1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'base-deleted',"
+  "  0, 'J/J-d', 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
+  "  10, null, null, null);"
+  "insert into nodes values ("
   "  1, 'J/J-e', 1, 'J', null, null, null, 'normal',"
-  "  0, 'other/place', 'dir', '()', null, null, null, null, null, null,"
+  "  0, null, 'dir', '()', null, null, null, null, null, null,"
   "  null, null, null, null);"
   "insert into nodes values ("
   "  1, 'J/J-e/J-e-a', 1, 'J/J-e', null, null, null, 'normal',"
@@ -241,7 +245,7 @@ static const char * const TESTING_DATA =
   "  null, null, null, null);"
   "insert into nodes values ("
   "  1, 'J/J-e', 2, 'J', null, null, null, 'base-deleted',"
-  "  0, 'other/place', 'dir', '()', null, null, null, null, null, null,"
+  "  0, null, 'dir', '()', null, null, null, null, null, null,"
   "  null, null, null, null);"
   "insert into nodes values ("
   "  1, 'J/J-e/J-e-a', 2, 'J/J-e', null, null, null, 'base-deleted',"
@@ -273,7 +277,7 @@ static const char * const TESTING_DATA =
   "  null, null, null, null);"
   "insert into nodes values ("
   "  1, 'K/K-b', 1, 'K', null, null, null, 'base-deleted',"
-  "  0, 'moved/away', 'file', '()', null, null, null, null, null, null,"
+  "  0, null, 'file', '()', null, null, null, null, null, null,"
   "  null, null, null, null);"
   "insert into nodes values ("
   "  1, 'L', 1, '', null, null, null, 'normal',"
@@ -295,6 +299,22 @@ static const char * const TESTING_DATA =
   "  1, 'L/L-a/L-a-a', 2, 'L/L-a', null, null, null, 'base-deleted',"
   "  0, null, 'dir', '()', 'immediates', null, null, null, null, null,"
   "  null, null, null, null);"
+  "insert into nodes values ("
+  "  1, 'other/place', 2, 'other', null, null, null, 'normal',"
+  "  1, null, 'dir', '()', 'immediates', null, null, null, null, null,"
+  "  null, null, null, null);"
+  "insert into nodes values ("
+  "  1, 'other/place/J-e-a', 2, 'other/place', null, null, null, 'normal',"
+  "  0, null, 'dir', '()', 'immediates', null, null, null, null, null,"
+  "  null, null, null, null);"
+  "insert into nodes values ("
+  "  1, 'other/place/J-e-b', 2, 'other/place', null, null, null, 'normal',"
+  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
+  "  null, null, null, null);"
+  "insert into nodes values ("
+  "  1, 'other/place/J-e-b/Jeba', 0, 'other/place/J-e-b', null, null, null, 'normal',"
+  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
+  "  15, null, null, null);"
    "insert into actual_node values ("
    "  1, 'I', '', null, null, null, null, null, 'changelist', null, "
    "  null, null, null, null, null);"
@@ -354,7 +374,7 @@ static svn_error_t *
 test_getting_info(apr_pool_t *pool)
 {
   const char *local_abspath;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_wc__db_status_t status;
   svn_revnum_t revision;
   const char *repos_relpath;
@@ -383,7 +403,7 @@ test_getting_info(apr_pool_t *pool)
             &update_root,
             db, local_abspath,
             pool, pool));
-  SVN_TEST_ASSERT(kind == svn_wc__db_kind_dir);
+  SVN_TEST_ASSERT(kind == svn_kind_dir);
   SVN_TEST_ASSERT(status == svn_wc__db_status_normal);
   SVN_TEST_ASSERT(revision == 1);
   SVN_TEST_STRING_ASSERT(repos_relpath, "");
@@ -406,7 +426,7 @@ test_getting_info(apr_pool_t *pool)
             NULL, NULL,
             db, svn_dirent_join(local_abspath, "A", pool),
             pool, pool));
-  SVN_TEST_ASSERT(kind == svn_wc__db_kind_file);
+  SVN_TEST_ASSERT(kind == svn_kind_file);
   SVN_TEST_STRING_ASSERT(SHA1_1, svn_checksum_to_cstring(checksum, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "A");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
@@ -421,7 +441,7 @@ test_getting_info(apr_pool_t *pool)
             NULL, NULL,
             db, svn_dirent_join(local_abspath, "B", pool),
             pool, pool));
-  SVN_TEST_ASSERT(kind == svn_wc__db_kind_symlink);
+  SVN_TEST_ASSERT(kind == svn_kind_symlink);
   SVN_TEST_ASSERT(status == svn_wc__db_status_excluded);
   SVN_TEST_ASSERT(!SVN_IS_VALID_REVNUM(revision));
   SVN_TEST_STRING_ASSERT(repos_relpath, "B");
@@ -444,7 +464,7 @@ test_getting_info(apr_pool_t *pool)
             NULL, NULL, NULL,
             db, svn_dirent_join(local_abspath, "C", pool),
             pool, pool));
-  SVN_TEST_ASSERT(kind == svn_wc__db_kind_unknown);
+  SVN_TEST_ASSERT(kind == svn_kind_unknown);
   SVN_TEST_ASSERT(status == svn_wc__db_status_server_excluded);
 
   /* Test: not-present presence. */
@@ -529,12 +549,12 @@ static svn_error_t *
 validate_node(svn_wc__db_t *db,
               const char *local_abspath,
               const char *relpath,
-              svn_wc__db_kind_t expected_kind,
+              svn_kind_t expected_kind,
               svn_wc__db_status_t expected_status,
               apr_pool_t *scratch_pool)
 {
   const char *path = svn_dirent_join(local_abspath, relpath, scratch_pool);
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_wc__db_status_t status;
   apr_hash_t *props;
   const svn_string_t *value;
@@ -656,18 +676,18 @@ test_inserting_nodes(apr_pool_t *pool)
             pool));
 
   /* Replace an incomplete node with an absent file node. */
-  SVN_ERR(svn_wc__db_base_add_absent_node(
+  SVN_ERR(svn_wc__db_base_add_excluded_node(
             db, svn_dirent_join(local_abspath, "N/N-b", pool),
             "N/N-b", ROOT_ONE, UUID_ONE, 3,
-            svn_wc__db_kind_file, svn_wc__db_status_server_excluded,
+            svn_kind_file, svn_wc__db_status_server_excluded,
             NULL, NULL,
             pool));
 
   /* Create a new excluded directory node. */
-  SVN_ERR(svn_wc__db_base_add_absent_node(
+  SVN_ERR(svn_wc__db_base_add_excluded_node(
             db, svn_dirent_join(local_abspath, "P", pool),
             "P", ROOT_ONE, UUID_ONE, 3,
-            svn_wc__db_kind_dir, svn_wc__db_status_excluded,
+            svn_kind_dir, svn_wc__db_status_excluded,
             NULL, NULL,
             pool));
 
@@ -675,44 +695,44 @@ test_inserting_nodes(apr_pool_t *pool)
   SVN_ERR(svn_wc__db_base_add_not_present_node(
             db, svn_dirent_join(local_abspath, "Q", pool),
             "Q", ROOT_ONE, UUID_ONE, 3,
-            svn_wc__db_kind_symlink,
+            svn_kind_symlink,
             NULL, NULL,
             pool));
 
   /* Create a new absent unknown-kind node. */
-  SVN_ERR(svn_wc__db_base_add_absent_node(
+  SVN_ERR(svn_wc__db_base_add_excluded_node(
             db, svn_dirent_join(local_abspath, "R", pool),
             "R", ROOT_ONE, UUID_ONE, 3,
-            svn_wc__db_kind_unknown, svn_wc__db_status_server_excluded,
+            svn_kind_unknown, svn_wc__db_status_server_excluded,
             NULL, NULL,
             pool));
 
 
   /* Are all the nodes where we expect them to be? */
   SVN_ERR(validate_node(db, local_abspath, "N",
-                        svn_wc__db_kind_dir, svn_wc__db_status_normal,
+                        svn_kind_dir, svn_wc__db_status_normal,
                         pool));
   SVN_ERR(validate_node(db, local_abspath, "N/N-a",
-                        svn_wc__db_kind_file, svn_wc__db_status_normal,
+                        svn_kind_file, svn_wc__db_status_normal,
                         pool));
   SVN_ERR(validate_node(db, local_abspath, "N/N-b",
-                        svn_wc__db_kind_file,
+                        svn_kind_file,
                         svn_wc__db_status_server_excluded,
                         pool));
   SVN_ERR(validate_node(db, local_abspath, "N/N-c",
-                        svn_wc__db_kind_unknown, svn_wc__db_status_incomplete,
+                        svn_kind_unknown, svn_wc__db_status_incomplete,
                         pool));
   SVN_ERR(validate_node(db, local_abspath, "O",
-                        svn_wc__db_kind_symlink, svn_wc__db_status_normal,
+                        svn_kind_symlink, svn_wc__db_status_normal,
                         pool));
   SVN_ERR(validate_node(db, local_abspath, "P",
-                        svn_wc__db_kind_dir, svn_wc__db_status_excluded,
+                        svn_kind_dir, svn_wc__db_status_excluded,
                         pool));
   SVN_ERR(validate_node(db, local_abspath, "Q",
-                        svn_wc__db_kind_symlink, svn_wc__db_status_not_present,
+                        svn_kind_symlink, svn_wc__db_status_not_present,
                         pool));
   SVN_ERR(validate_node(db, local_abspath, "R",
-                        svn_wc__db_kind_unknown,
+                        svn_kind_unknown,
                         svn_wc__db_status_server_excluded,
                         pool));
 
@@ -768,7 +788,7 @@ static svn_error_t *
 test_working_info(apr_pool_t *pool)
 {
   const char *local_abspath;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_wc__db_status_t status;
   svn_revnum_t revision;
   const char *repos_relpath;
@@ -812,7 +832,7 @@ test_working_info(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "I", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_added);
-  SVN_TEST_ASSERT(kind == svn_wc__db_kind_dir);
+  SVN_TEST_ASSERT(kind == svn_kind_dir);
   SVN_TEST_ASSERT(revision == SVN_INVALID_REVNUM);
   SVN_TEST_ASSERT(repos_relpath == NULL);
   SVN_TEST_ASSERT(repos_root_url == NULL);
@@ -856,17 +876,17 @@ test_pdh(apr_pool_t *pool)
      some internal functionality of wc_db.  This is a handy driver for
      debugging wc_db to ensure it manages per-directory handles properly.  */
 
-  SVN_ERR(svn_wc__db_base_add_absent_node(
+  SVN_ERR(svn_wc__db_base_add_excluded_node(
             db, svn_dirent_join(local_abspath, "sub", pool),
             "sub", ROOT_ONE, UUID_ONE, 1,
-            svn_wc__db_kind_file, svn_wc__db_status_server_excluded,
+            svn_kind_file, svn_wc__db_status_server_excluded,
             NULL, NULL,
             pool));
 
-  SVN_ERR(svn_wc__db_base_add_absent_node(
+  SVN_ERR(svn_wc__db_base_add_excluded_node(
             db, svn_dirent_join(local_abspath, "sub/A", pool),
             "sub/A", ROOT_ONE, UUID_ONE, 1,
-            svn_wc__db_kind_file, svn_wc__db_status_server_excluded,
+            svn_kind_file, svn_wc__db_status_server_excluded,
             NULL, NULL,
             pool));
 
@@ -888,6 +908,8 @@ test_scan_addition(apr_pool_t *pool)
   const char *original_root_url;
   const char *original_uuid;
   svn_revnum_t original_revision;
+  const char *moved_from_abspath;
+  const char *delete_op_root_abspath;
 
   SVN_ERR(create_open(&db, &local_abspath, "test_scan_addition", pool));
 
@@ -896,7 +918,7 @@ test_scan_addition(apr_pool_t *pool)
             &status, &op_root_abspath,
             &repos_relpath, &repos_root_url, &repos_uuid,
             &original_repos_relpath, &original_root_url, &original_uuid,
-            &original_revision,
+            &original_revision, NULL, NULL,
             db, svn_dirent_join(local_abspath, "J", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_added);
@@ -914,7 +936,7 @@ test_scan_addition(apr_pool_t *pool)
             &status, &op_root_abspath,
             &repos_relpath, &repos_root_url, &repos_uuid,
             &original_repos_relpath, &original_root_url, &original_uuid,
-            &original_revision,
+            &original_revision, NULL, NULL,
             db, svn_dirent_join(local_abspath, "J/J-a", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_added);
@@ -932,12 +954,16 @@ test_scan_addition(apr_pool_t *pool)
             &status, &op_root_abspath,
             &repos_relpath, &repos_root_url, &repos_uuid,
             &original_repos_relpath, &original_root_url, &original_uuid,
-            &original_revision,
+            &original_revision, &moved_from_abspath, &delete_op_root_abspath,
             db, svn_dirent_join(local_abspath, "J/J-d", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_moved_here);
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-d",
                                    op_root_abspath, pool));
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+                                   moved_from_abspath, pool));
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+                                   delete_op_root_abspath, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-d");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
   SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
@@ -951,7 +977,7 @@ test_scan_addition(apr_pool_t *pool)
             &status, &op_root_abspath,
             &repos_relpath, &repos_root_url, &repos_uuid,
             &original_repos_relpath, &original_root_url, &original_uuid,
-            &original_revision,
+            &original_revision, NULL, NULL,
             db, svn_dirent_join(local_abspath, "J/J-b", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
@@ -970,7 +996,7 @@ test_scan_addition(apr_pool_t *pool)
             &status, &op_root_abspath,
             &repos_relpath, &repos_root_url, &repos_uuid,
             &original_repos_relpath, &original_root_url, &original_uuid,
-            &original_revision,
+            &original_revision, NULL, NULL,
             db, svn_dirent_join(local_abspath, "J/J-b/J-b-a", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
@@ -989,7 +1015,7 @@ test_scan_addition(apr_pool_t *pool)
             &status, &op_root_abspath,
             &repos_relpath, &repos_root_url, &repos_uuid,
             &original_repos_relpath, &original_root_url, &original_uuid,
-            &original_revision,
+            &original_revision, NULL, NULL,
             db, svn_dirent_join(local_abspath, "J/J-b/J-b-b", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
@@ -1015,6 +1041,7 @@ test_scan_deletion(apr_pool_t *pool)
   const char *base_del_abspath;
   const char *work_del_abspath;
   const char *moved_to_abspath;
+  const char *copy_op_root_abspath;
 
   SVN_ERR(create_open(&db, &local_abspath, "test_scan_deletion", pool));
 
@@ -1023,6 +1050,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "J/J-e", pool),
             pool, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
@@ -1031,26 +1059,32 @@ test_scan_deletion(apr_pool_t *pool)
                                    moved_to_abspath, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
                                    work_del_abspath, pool));
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+                                   copy_op_root_abspath, pool));
 
   /* Node was moved elsewhere (child of operation root). */
   SVN_ERR(svn_wc__db_scan_deletion(
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "J/J-e/J-e-a", pool),
             pool, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-a",
                                    moved_to_abspath, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
                                    work_del_abspath, pool));
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+                                   copy_op_root_abspath, pool));
 
   /* Root of delete. Parent is a WORKING node. */
   SVN_ERR(svn_wc__db_scan_deletion(
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "J/J-c", pool),
             pool, pool));
   /* Implicit delete of "J" (via replacement).  */
@@ -1065,6 +1099,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "J/J-c/J-c-a", pool),
             pool, pool));
   /* Implicit delete of "J" (via replacement).  */
@@ -1079,6 +1114,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "J/J-e/J-e-b/Jeba", pool),
             pool, pool));
   /* ### I don't understand this.  "J/J-e/J-e-b/Jeba" is a deleted
@@ -1086,7 +1122,7 @@ test_scan_deletion(apr_pool_t *pool)
      Why does base_del_abspath refer to "J-e"?  */
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-b/Jeba",
                                    moved_to_abspath, pool));
   SVN_TEST_ASSERT(work_del_abspath == NULL);
 
@@ -1095,6 +1131,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "J/J-f/J-f-a", pool),
             pool, pool));
   /* Implicit delete of "J" (via replacement).  */
@@ -1108,6 +1145,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "K", pool),
             pool, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
@@ -1120,6 +1158,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "K/K-a", pool),
             pool, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
@@ -1132,12 +1171,15 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "K/K-b", pool),
             pool, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "K/K-b",
                                    base_del_abspath, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/away",
                                    moved_to_abspath, pool));
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/away",
+                                   copy_op_root_abspath, pool));
   SVN_TEST_ASSERT(work_del_abspath == NULL);
 
   /* Subtree deletion of added tree. Start at child.  */
@@ -1145,6 +1187,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "L/L-a/L-a-a", pool),
             pool, pool));
   SVN_TEST_ASSERT(base_del_abspath == NULL);
@@ -1157,6 +1200,7 @@ test_scan_deletion(apr_pool_t *pool)
             &base_del_abspath,
             &moved_to_abspath,
             &work_del_abspath,
+            NULL,
             db, svn_dirent_join(local_abspath, "L/L-a", pool),
             pool, pool));
   SVN_TEST_ASSERT(base_del_abspath == NULL);
@@ -1384,7 +1428,7 @@ test_externals_store(apr_pool_t *pool)
 
   {
     svn_wc__db_status_t status;
-    svn_wc__db_kind_t kind;
+    svn_kind_t kind;
     const char *repos_root_url;
     const char *repos_uuid;
     const char *defining_abspath;
@@ -1401,7 +1445,7 @@ test_externals_store(apr_pool_t *pool)
                                      pool, pool));
 
     SVN_TEST_ASSERT(status == svn_wc__db_status_normal);
-    SVN_TEST_ASSERT(kind == svn_wc__db_kind_file);
+    SVN_TEST_ASSERT(kind == svn_kind_file);
     SVN_TEST_STRING_ASSERT(repos_root_url, "svn://some-repos/svn");
     SVN_TEST_STRING_ASSERT(repos_uuid, "not-a-uuid");
     SVN_TEST_STRING_ASSERT(defining_abspath, subdir);
@@ -1432,7 +1476,7 @@ test_externals_store(apr_pool_t *pool)
                                      pool, pool));
 
     SVN_TEST_ASSERT(status == svn_wc__db_status_normal);
-    SVN_TEST_ASSERT(kind == svn_wc__db_kind_dir);
+    SVN_TEST_ASSERT(kind == svn_kind_dir);
     SVN_TEST_STRING_ASSERT(repos_root_url, "svn://other-repos/nsv");
     SVN_TEST_STRING_ASSERT(repos_uuid, "no-uuid-either");
     SVN_TEST_STRING_ASSERT(defining_abspath, subdir);