subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1660173 [9/10] - in /subversion/branches/move-tracking-2: ./ build/ build/generator/ contrib/ contrib/client-side/svncopy/ notes/ subversion/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ s...
Date Mon, 16 Feb 2015 17:40:11 GMT
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py Mon Feb 16 17:40:07 2015
@@ -853,13 +853,13 @@ def build_simple_file_move_func(sbox, so
       mv_info_src = [
         {
           'Path'       : re.escape(source_path),
-          'Moved To'   : re.escape(dest),
+          'Moved To'   : re.escape(sbox.ospath(dest)),
         }
       ]
       mv_info_dst = [
         {
           'Path'       : re.escape(dest_path),
-          'Moved From' : re.escape(source),
+          'Moved From' : re.escape(sbox.ospath(source)),
         }
       ]
 
@@ -1373,7 +1373,7 @@ def move_many_update_delete(sbox):
   svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
                                         expected_status)
 
-  # Would be nice if we could run the resolver as a separate step, 
+  # Would be nice if we could run the resolver as a separate step,
   # but 'svn resolve' just fails for any value but working
 
 def move_many_update_add(sbox):
@@ -1483,7 +1483,7 @@ def copy_move_commit(sbox):
     #     create table bbb (Id int not null)
     #   - Commit
     # Repro Issue 2
-    #    - Copy folder aaa under same parent folder (i.e. as a sibling). (using Ctrl drag/drop). 
+    #    - Copy folder aaa under same parent folder (i.e. as a sibling). (using Ctrl drag/drop).
     #      Creates Copy of aaa
     #    - Rename Copy of aaa to eee
     #    - Commit
@@ -1512,7 +1512,7 @@ def move_to_from_external(sbox):
                                      'move',
                                      sbox.ospath('iota'),
                                      sbox.ospath('GG/tau'))
-                                     
+
   svntest.actions.run_and_verify_svn(None, [],
                                      'ci', '-m', 'Commit both',
                                      sbox.ospath(''),
@@ -1566,6 +1566,148 @@ def revert_del_root_of_move(sbox):
     expected_status.tweak('A/B/E', treeconflict='C')
     svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+def move_conflict_details(sbox):
+  "move conflict details"
+
+  sbox.build()
+
+  sbox.simple_append('A/B/E/new', 'new\n')
+  sbox.simple_add('A/B/E/new')
+  sbox.simple_append('A/B/E/alpha', '\nextra\nlines\n')
+  sbox.simple_rm('A/B/E/beta', 'A/B/F')
+  sbox.simple_propset('key', 'VAL', 'A/B/E', 'A/B')
+  sbox.simple_mkdir('A/B/E/new-dir1')
+  sbox.simple_mkdir('A/B/E/new-dir2')
+  sbox.simple_mkdir('A/B/E/new-dir3')
+  sbox.simple_rm('A/B/lambda')
+  sbox.simple_mkdir('A/B/lambda')
+  sbox.simple_commit()
+
+  sbox.simple_update('', 1)
+
+  sbox.simple_move('A/B', 'B')
+
+  sbox.simple_update('', 2)
+
+  expected_info = [
+    {
+      "Moved To": re.escape(sbox.ospath("B")),
+      "Tree conflict": re.escape(
+              'local dir moved away, incoming dir edit upon update' +
+              ' Source  left: (dir) ^/A/B@1' +
+              ' Source right: (dir) ^/A/B@2')
+    }
+  ]
+  svntest.actions.run_and_verify_info(expected_info, sbox.ospath('A/B'))
+
+  sbox.simple_propset('key', 'vAl', 'B')
+  sbox.simple_move('B/E/beta', 'beta')
+  sbox.simple_propset('a', 'b', 'B/F', 'B/lambda')
+  sbox.simple_append('B/E/alpha', 'other\nnew\nlines')
+  sbox.simple_mkdir('B/E/new')
+  sbox.simple_mkdir('B/E/new-dir1')
+  sbox.simple_append('B/E/new-dir2', 'something')
+  sbox.simple_append('B/E/new-dir3', 'something')
+  sbox.simple_add('B/E/new-dir3')
+
+
+  expected_output = [
+    " C   %s\n" % sbox.ospath('B'),         # Property conflicted
+    " U   %s\n" % sbox.ospath('B/E'),       # Just updated
+    "C    %s\n" % sbox.ospath('B/E/alpha'), # Text conflicted
+    "   C %s\n" % sbox.ospath('B/E/beta'),
+    "   C %s\n" % sbox.ospath('B/E/new'),
+    "   C %s\n" % sbox.ospath('B/E/new-dir1'),
+    "   C %s\n" % sbox.ospath('B/E/new-dir2'),
+    "   C %s\n" % sbox.ospath('B/E/new-dir3'),
+    "   C %s\n" % sbox.ospath('B/F'),
+    "   C %s\n" % sbox.ospath('B/lambda'),
+    "Updated to revision 2.\n",
+    "Resolved conflicted state of '%s'\n" % sbox.ospath('A/B')
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'resolve', sbox.ospath('A/B'),
+                                     '--depth', 'empty',
+                                     '--accept', 'mine-conflict')
+
+  expected_info = [
+    {
+      "Path" : re.escape(sbox.ospath('B')),
+
+      "Conflict Properties File" :
+            re.escape(sbox.ospath('B/dir_conflicts.prej')) + '.*',
+      "Conflict Details": re.escape(
+            'incoming dir edit upon update' +
+            ' Source  left: (dir) ^/A/B@1' +
+            ' Source right: (dir) ^/A/B@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/E')),
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/E/alpha')),
+      "Conflict Previous Base File" : '.*alpha.*',
+      "Conflict Previous Working File" : '.*alpha.*',
+      "Conflict Current Base File": '.*alpha.*',
+      "Conflict Details": re.escape(
+          'incoming file edit upon update' +
+          ' Source  left: (file) ^/A/B/E/alpha@1' +
+          ' Source right: (file) ^/A/B/E/alpha@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/E/beta')),
+      "Tree conflict": re.escape(
+          'local file moved away, incoming file delete or move upon update' +
+          ' Source  left: (file) ^/A/B/E/beta@1' +
+          ' Source right: (none) ^/A/B/E/beta@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/E/new')),
+      "Tree conflict": re.escape(
+          'local dir add, incoming file add upon update' +
+          ' Source  left: (none) ^/A/B/E/new@1' +
+          ' Source right: (file) ^/A/B/E/new@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/E/new-dir1')),
+      "Tree conflict": re.escape(
+          'local dir add, incoming dir add upon update' +
+          ' Source  left: (none) ^/A/B/E/new-dir1@1' +
+          ' Source right: (dir) ^/A/B/E/new-dir1@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/E/new-dir2')),
+      "Tree conflict": re.escape(
+          'local file unversioned, incoming dir add upon update' +
+          ' Source  left: (none) ^/A/B/E/new-dir2@1' +
+          ' Source right: (dir) ^/A/B/E/new-dir2@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/E/new-dir3')),
+      "Tree conflict": re.escape(
+          'local file add, incoming dir add upon update' +
+          ' Source  left: (none) ^/A/B/E/new-dir3@1' +
+          ' Source right: (dir) ^/A/B/E/new-dir3@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/F')),
+      "Tree conflict": re.escape(
+          'local dir edit, incoming dir delete or move upon update' +
+          ' Source  left: (dir) ^/A/B/F@1' +
+          ' Source right: (none) ^/A/B/F@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('B/lambda')),
+      "Tree conflict": re.escape(
+          'local file edit, incoming replace with dir upon update' +
+          ' Source  left: (file) ^/A/B/lambda@1' +
+          ' Source right: (dir) ^/A/B/lambda@2')
+    },
+  ]
+
+  svntest.actions.run_and_verify_info(expected_info, sbox.ospath('B'),
+                                      '--depth', 'infinity')
+
 
 #######################################################################
 # Run the tests
@@ -1585,6 +1727,7 @@ test_list = [ None,
               copy_move_commit,
               move_to_from_external,
               revert_del_root_of_move,
+              move_conflict_details,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py Mon Feb 16 17:40:07 2015
@@ -2747,8 +2747,8 @@ def dir_prop_conflict_details(sbox):
   # The conflict properties file line was shown for previous versions, but the
   # conflict source urls are new since 1.8.
   expected_info = {
-    'Conflict Properties File' : re.escape(os.path.abspath(
-                                           sbox.ospath('A/dir_conflicts.prej'))
+    'Conflict Properties File' : re.escape(sbox.ospath('A/dir_conflicts.prej')),
+    'Conflict Details': re.escape('incoming dir edit upon update'
                                            + ' Source  left: (dir) ^/A@1'
                                            + ' Source right: (dir) ^/A@2')
   }

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/redirect_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/redirect_tests.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/redirect_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/redirect_tests.py Mon Feb 16 17:40:07 2015
@@ -154,7 +154,7 @@ def redirected_nonroot_update(sbox):
                                              checkout_url, wc_dir)
   if err:
     raise svntest.Failure
-  
+
   # Relocate (by cheating) the working copy to the redirect URL.  When
   # we then update, we'll expect to find ourselves automagically back
   # to the original URL.  (This is because we can't easily introduce a
@@ -241,6 +241,25 @@ def redirected_copy(sbox):
                                      sbox.redirected_root_url(temporary=True) + '/A',
                                      '^/copy-of-A')
 #----------------------------------------------------------------------
+@SkipUnless(svntest.main.is_ra_type_dav)
+def redirected_commands(sbox):
+  "redirected commands"
+
+  sbox.build(create_wc=False)
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'log',
+                                     sbox.redirected_root_url() + '/A')
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'ls',
+                                     sbox.redirected_root_url() + '/A')
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'info',
+                                     sbox.redirected_root_url() + '/A')
+
+#----------------------------------------------------------------------
 
 ########################################################################
 # Run the tests
@@ -253,6 +272,7 @@ test_list = [ None,
               redirected_nonroot_update,
               redirected_externals,
               redirected_copy,
+              redirected_commands,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py Mon Feb 16 17:40:07 2015
@@ -2093,12 +2093,12 @@ def status_path_handling(sbox):
 
 def status_move_missing_direct(sbox):
   "move information when status is called directly"
-  
+
   sbox.build()
   sbox.simple_copy('A', 'Z')
   sbox.simple_commit('')
   sbox.simple_update('')
-  
+
   sbox.simple_move('Z', 'ZZ')
   sbox.simple_move('A', 'Z')
   sbox.simple_move('Z/B', 'ZB')
@@ -2108,14 +2108,14 @@ def status_move_missing_direct(sbox):
   # Somehow 'svn status' now shows different output for 'ZB/E'
   # when called directly and via an ancestor, as this handles
   # multi-layer in a different way
-  
+
   # Note that the status output may change over different Subversion revisions,
   # but the status on a node should be identical anyway 'svn status' is called
   # on it.
-  
+
   expected_output = [
     'A  +    %s\n' % sbox.ospath('ZB'),
-    '        > moved from %s\n' % os.path.join('..', 'Z', 'B'),    
+    '        > moved from %s\n' % os.path.join('..', 'Z', 'B'),
     'D  +    %s\n' % sbox.ospath('ZB/E'),
     '        > moved to %s\n' % os.path.join('..', 'Z', 'B', 'E'),
   ]
@@ -2133,7 +2133,7 @@ def status_move_missing_direct(sbox):
 
 def status_move_missing_direct_base(sbox):
   "move when status is called directly with base"
-  
+
   sbox.build()
   sbox.simple_copy('A', 'Z')
   sbox.simple_mkdir('Q')
@@ -2141,10 +2141,10 @@ def status_move_missing_direct_base(sbox
   sbox.simple_mkdir('Q/ZB/E')
   sbox.simple_commit('')
   sbox.simple_update('')
-  
+
   sbox.simple_rm('Q')
   sbox.simple_mkdir('Q')
-  
+
   sbox.simple_move('Z', 'ZZ')
   sbox.simple_move('A', 'Z')
   sbox.simple_move('Z/B', 'Q/ZB')
@@ -2154,14 +2154,14 @@ def status_move_missing_direct_base(sbox
   # Somehow 'svn status' now shows different output for 'Q/ZB/E'
   # when called directly and via an ancestor, as this handles
   # multi-layer in a different way
-  
+
   # Note that the status output may change over different Subversion revisions,
   # but the status on a node should be identical anyway 'svn status' is called
   # on it.
-  
+
   # This test had a different result as status_move_missing_direct at the time of
   # writing this test.
-  
+
   expected_output = [
     'A  +    %s\n' % sbox.ospath('Q/ZB'),
     '        > moved from %s\n' % os.path.join('..', '..', 'Z', 'B'),

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py Mon Feb 16 17:40:07 2015
@@ -82,6 +82,10 @@ def check_hotcopy_fsfs_fsx(src, dst):
         if dst_dirent == 'write-lock':
           continue
 
+        # Ignore auto-created rep-cache.db-journal file
+        if dst_dirent == 'rep-cache.db-journal':
+          continue
+
         src_dirent = os.path.join(src_dirpath, dst_dirent)
         if not os.path.exists(src_dirent):
           raise svntest.Failure("%s does not exist in hotcopy "
@@ -96,6 +100,10 @@ def check_hotcopy_fsfs_fsx(src, dst):
         if src_file == 'write-lock':
           continue
 
+        # Ignore auto-created rep-cache.db-journal file
+        if src_file == 'rep-cache.db-journal':
+          continue
+
         src_path = os.path.join(src_dirpath, src_file)
         dst_path = os.path.join(dst_dirpath, src_file)
         if not os.path.isfile(dst_path):
@@ -179,7 +187,7 @@ def check_hotcopy_fsfs(src, dst):
 def check_hotcopy_fsx(src, dst):
     "Verify that the SRC FSX repository has been correctly copied to DST."
     check_hotcopy_fsfs_fsx(src, dst)
-        
+
 #----------------------------------------------------------------------
 
 # How we currently test 'svnadmin' --
@@ -2051,7 +2059,7 @@ def verify_keep_going(sbox):
   svntest.actions.run_and_verify_svn(None, [],
                                      'mkdir', '-m', 'log_msg',
                                      C_url)
-  
+
   r2 = fsfs_file(sbox.repo_dir, 'revs', '2')
   fp = open(r2, 'r+b')
   fp.write("""inserting junk to corrupt the rev""")

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/actions.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/actions.py Mon Feb 16 17:40:07 2015
@@ -1040,19 +1040,20 @@ def run_and_verify_info(expected_infos,
 
     for actual, expected in zip(actual_infos, expected_infos):
       # compare dicts
+      path = actual['Path']
       for key, value in expected.items():
         assert ':' not in key # caller passed impossible expectations?
         if value is None and key in actual:
-          raise main.SVNLineUnequal("Found unexpected key '%s' with value '%s'"
-                                    % (key, actual[key]))
+          raise main.SVNLineUnequal("On '%s': Found unexpected key '%s'\n  Value '%s'"
+                                    % (path, key, actual[key]))
         if value is not None and key not in actual:
-          raise main.SVNLineUnequal("Expected key '%s' (with value '%s') "
-                                    "not found" % (key, value))
+          raise main.SVNLineUnequal("On '%s': Expected key '%s' not found\n Expected value '%s'"
+                                    % (path, key, value))
         if value is not None and not re.match(value, actual[key]):
-          raise verify.SVNUnexpectedStdout("Values of key '%s' don't match:\n"
+          raise verify.SVNUnexpectedStdout("On '%s': Values of key '%s' don't match:\n"
                                            "  Expected: '%s' (regex)\n"
                                            "  Found:    '%s' (string)\n"
-                                           % (key, value, actual[key]))
+                                           % (path, key, value, actual[key]))
 
   except:
     sys.stderr.write("Bad 'svn info' output:\n"

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/switch_tests.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/switch_tests.py Mon Feb 16 17:40:07 2015
@@ -2121,7 +2121,7 @@ def tree_conflicts_on_switch_1_1(sbox):
     'DDF/D1/D2'         : Item(status='  ', treeconflict='U'),
     'DDF/D1/D2/gamma'   : Item(status='  ', treeconflict='U')
   })
-  
+
   expected_disk = svntest.wc.State('', {
   'F'               : Item(),
   'D'               : Item(),

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/update_tests.py?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/update_tests.py Mon Feb 16 17:40:07 2015
@@ -6697,6 +6697,146 @@ def update_child_below_add(sbox):
                                         None, None, None,
                                         sbox.ospath('A/B/E'))
 
+def update_conflict_details(sbox):
+  "update conflict details"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_append('A/B/E/new', 'new\n')
+  sbox.simple_add('A/B/E/new')
+  sbox.simple_append('A/B/E/alpha', '\nextra\nlines\n')
+  sbox.simple_rm('A/B/E/beta', 'A/B/F')
+  sbox.simple_propset('key', 'VAL', 'A/B/E', 'A/B')
+  sbox.simple_mkdir('A/B/E/new-dir1')
+  sbox.simple_mkdir('A/B/E/new-dir2')
+  sbox.simple_mkdir('A/B/E/new-dir3')
+  sbox.simple_rm('A/B/lambda')
+  sbox.simple_mkdir('A/B/lambda')
+  sbox.simple_commit()
+
+  sbox.simple_update('', 1)
+
+  sbox.simple_propset('key', 'vAl', 'A/B')
+  sbox.simple_move('A/B/E/beta', 'beta')
+  sbox.simple_propset('a', 'b', 'A/B/F', 'A/B/lambda')
+  sbox.simple_append('A/B/E/alpha', 'other\nnew\nlines')
+  sbox.simple_mkdir('A/B/E/new')
+  sbox.simple_mkdir('A/B/E/new-dir1')
+  sbox.simple_append('A/B/E/new-dir2', 'something')
+  sbox.simple_append('A/B/E/new-dir3', 'something')
+  sbox.simple_add('A/B/E/new-dir3')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.add({
+    'A/B/E/new'         : Item(status='R ', treeconflict='C', wc_rev='2'),
+    'A/B/E/new-dir2'    : Item(status='D ', treeconflict='C', wc_rev='2'),
+    'A/B/E/new-dir3'    : Item(status='R ', treeconflict='C', wc_rev='2'),
+    'A/B/E/new-dir1'    : Item(status='  ', wc_rev='2'),
+    'A/C'               : Item(status='  ', wc_rev='2'),
+    'iota'              : Item(status='  ', wc_rev='2'),
+    'beta'              : Item(status='A ', copied='+', wc_rev='-')
+  })
+  expected_status.tweak('A/B', status=' C', wc_rev='2')
+  expected_status.tweak('A/B/E/alpha', status='C ', wc_rev='2')
+  expected_status.tweak('A/B/E/beta', status='! ', treeconflict='C', wc_rev=None)
+  expected_status.tweak('A/B/F', status='A ', copied='+', treeconflict='C', wc_rev='-')
+  expected_status.tweak('A/B/lambda', status='RM', copied='+', treeconflict='C', wc_rev='-')
+  expected_status.tweak('A/mu', status='  ', wc_rev='2')
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B'               : Item(status=' C'),
+    'A/B/E'             : Item(status=' U'),
+    'A/B/E/new'         : Item(status='  ', treeconflict='C'),
+    'A/B/E/beta'        : Item(status='  ', treeconflict='C'),
+    'A/B/E/alpha'       : Item(status='C '),
+    'A/B/E/new-dir2'    : Item(status='  ', treeconflict='C'),
+    'A/B/E/new-dir3'    : Item(status='  ', treeconflict='C'),
+    'A/B/E/new-dir1'    : Item(status='E '),
+    'A/B/F'             : Item(status='  ', treeconflict='C'),
+    # ### 2 tree conflict reports; one for delete; one for add...
+    'A/B/lambda'        : Item(status='  ', treeconflict='A',
+                               prev_status='  ', prev_treeconflict='C'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir, expected_output,
+                                        None, expected_status)
+
+  # Update can't pass source as none at a specific URL@revision,
+  # because it doesn't know... the working copy could be mixed
+  # revision or may have excluded parts...
+  expected_info = [
+    {
+      "Path" : re.escape(sbox.ospath('A/B')),
+
+      "Conflict Properties File" :
+            re.escape(sbox.ospath('A/B/dir_conflicts.prej')) + '.*',
+      "Conflict Details": re.escape(
+            'incoming dir edit upon update' +
+            ' Source  left: (dir) ^/A/B@1' +
+            ' Source right: (dir) ^/A/B@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/E')),
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/E/alpha')),
+      "Conflict Previous Base File" : '.*alpha.*',
+      "Conflict Previous Working File" : '.*alpha.*',
+      "Conflict Current Base File": '.*alpha.*',
+      "Conflict Details": re.escape(
+          'incoming file edit upon update' +
+          ' Source  left: (file) ^/A/B/E/alpha@1' +
+          ' Source right: (file) ^/A/B/E/alpha@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/E/beta')),
+      "Tree conflict": re.escape(
+          'local file moved away, incoming file delete or move upon update' +
+          ' Source  left: (file) ^/A/B/E/beta@1' +
+          ' Source right: (none) ^/A/B/E/beta@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/E/new')),
+      "Tree conflict": re.escape(
+          'local dir add, incoming file add upon update' +
+          ' Source  left: (none)' +
+          ' Source right: (file) ^/A/B/E/new@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/E/new-dir1')),
+      # No tree conflict. Existing directory taken over
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/E/new-dir2')),
+      "Tree conflict": re.escape(
+          'local file unversioned, incoming dir add upon update' +
+          ' Source  left: (none)' +
+          ' Source right: (dir) ^/A/B/E/new-dir2@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/E/new-dir3')),
+      "Tree conflict": re.escape(
+          'local file add, incoming dir add upon update' +
+          ' Source  left: (none)' +
+          ' Source right: (dir) ^/A/B/E/new-dir3@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/F')),
+      "Tree conflict": re.escape(
+          'local dir edit, incoming dir delete or move upon update' +
+          ' Source  left: (dir) ^/A/B/F@1' +
+          ' Source right: (none) ^/A/B/F@2')
+    },
+    {
+      "Path" : re.escape(sbox.ospath('A/B/lambda')),
+      "Tree conflict": re.escape(
+          'local file edit, incoming replace with dir upon update' +
+          ' Source  left: (file) ^/A/B/lambda@1' +
+          ' Source right: (dir) ^/A/B/lambda@2')
+    },
+  ]
+
+  svntest.actions.run_and_verify_info(expected_info, sbox.ospath('A/B'),
+                                      '--depth', 'infinity')
 
 #######################################################################
 # Run the tests
@@ -6783,6 +6923,7 @@ test_list = [ None,
               update_moved_away,
               bump_below_tree_conflict,
               update_child_below_add,
+              update_conflict_details,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_client/client-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_client/client-test.c Mon Feb 16 17:40:07 2015
@@ -35,6 +35,8 @@
 #include "svn_repos.h"
 #include "svn_subst.h"
 #include "private/svn_wc_private.h"
+#include "svn_props.h"
+#include "svn_hash.h"
 
 #include "../svn_test.h"
 #include "../svn_test_fs.h"
@@ -1055,6 +1057,236 @@ test_remote_only_status(const svn_test_o
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_copy_pin_externals(const svn_test_opts_t *opts,
+                        apr_pool_t *pool)
+{
+  svn_opt_revision_t rev;
+  svn_opt_revision_t peg_rev;
+  const char *repos_url;
+  const char *A_url;
+  const char *A_copy_url;
+  const char *wc_path;
+  svn_client_ctx_t *ctx;
+  const svn_string_t *propval;
+  apr_hash_t *externals_to_pin;
+  apr_array_header_t *external_items;
+  apr_array_header_t *copy_sources;
+  svn_wc_external_item2_t items[6];
+  svn_client_copy_source_t copy_source;
+  apr_hash_t *props;
+  apr_array_header_t *pinned_externals_descs;
+  apr_array_header_t *pinned_externals;
+  int i;
+  int num_tested_externals;
+  svn_stringbuf_t *externals_test_prop;
+  struct pin_externals_test_data {
+    const char *src_external_desc;
+    const char *expected_dst_external_desc;
+  } pin_externals_test_data[] = {
+    { "^/A/D/gamma B/gamma",    "^/A/D/gamma@2 B/gamma" },
+    { "-r1 ^/A/D/G C/exdir_G",  "-r1 ^/A/D/G C/exdir_G" },
+    { "^/A/D/H@1 C/exdir_H",    "^/A/D/H@1 C/exdir_H"  },
+    { "^/A/D/H C/exdir_H2",     "^/A/D/H@2 C/exdir_H2" },
+    { "-r1 ^/A/B D/z/y/z/blah", "-r1 ^/A/B@2 D/z/y/z/blah" } ,
+    { "-r1 ^/A/D@2 exdir_D", "-r1 ^/A/D@2 exdir_D" },
+    /* Dated revision should retain their date string exactly. */
+    { "-r{1970-01-01T00:00} ^/A/C 70s", "-r{1970-01-01T00:00} ^/A/C@2 70s"},
+    { "-r{2004-02-23} ^/svn 1.0", "-r{2004-02-23} ^/svn 1.0"},
+    { NULL },
+  };
+
+  /* Create a filesytem and repository containing the Greek tree. */
+  SVN_ERR(create_greek_repos(&repos_url, "pin-externals", opts, pool));
+
+  wc_path = svn_test_data_path("pin-externals-working-copy", pool);
+
+  /* Remove old test data from the previous run */
+  SVN_ERR(svn_io_remove_dir2(wc_path, TRUE, NULL, NULL, pool));
+
+  SVN_ERR(svn_io_make_dir_recursively(wc_path, pool));
+  svn_test_add_dir_cleanup(wc_path);
+
+  rev.kind = svn_opt_revision_head;
+  peg_rev.kind = svn_opt_revision_unspecified;
+  SVN_ERR(svn_client_create_context(&ctx, pool));
+
+  /* Configure some externals on ^/A */
+  i = 0;
+  externals_test_prop = svn_stringbuf_create_empty(pool);
+  while (pin_externals_test_data[i].src_external_desc)
+    {
+      svn_stringbuf_appendcstr(externals_test_prop,
+                               pin_externals_test_data[i].src_external_desc);
+      svn_stringbuf_appendbyte(externals_test_prop, '\n');
+      i++;
+    }
+  propval = svn_string_create_from_buf(externals_test_prop, pool);
+  A_url = apr_pstrcat(pool, repos_url, "/A", SVN_VA_NULL);
+  SVN_ERR(svn_client_propset_remote(SVN_PROP_EXTERNALS, propval,
+                                    A_url, TRUE, 1, NULL,
+                                    NULL, NULL, ctx, pool));
+
+  /* Set up parameters for pinning some externals. */
+  externals_to_pin = apr_hash_make(pool);
+
+  items[0].url = "^/A/D/gamma";
+  items[0].target_dir = "B/gamma";
+  items[1].url = "^/A/B";
+  items[1].target_dir = "D/z/y/z/blah";
+  items[2].url = "^/A/D/H";
+  items[2].target_dir = "C/exdir_H2";
+  items[3].url= "^/A/D";
+  items[3].target_dir= "exdir_D";
+  items[4].url = "^/A/C";
+  items[4].target_dir = "70s";
+  /* Also add an entry which doesn't match any actual definition. */
+  items[5].url = "^/this/does/not/exist";
+  items[5].target_dir = "in/test/data";
+
+  external_items = apr_array_make(pool, 2, sizeof(svn_wc_external_item2_t *));
+  for (i = 0; i < sizeof(items) / sizeof(items[0]); i++)
+    APR_ARRAY_PUSH(external_items, svn_wc_external_item2_t *) = &items[i];
+  svn_hash_sets(externals_to_pin, A_url, external_items);
+
+  /* Copy ^/A to ^/A_copy, pinning two non-pinned externals. */
+  copy_source.path = A_url;
+  copy_source.revision = &rev;
+  copy_source.peg_revision = &peg_rev;
+  copy_sources = apr_array_make(pool, 1, sizeof(svn_client_copy_source_t *));
+  APR_ARRAY_PUSH(copy_sources, svn_client_copy_source_t *) = &copy_source;
+  A_copy_url = apr_pstrcat(pool, repos_url, "/A_copy", SVN_VA_NULL);
+  SVN_ERR(svn_client_copy7(copy_sources, A_copy_url, FALSE, FALSE,
+                           FALSE, TRUE, externals_to_pin,
+                           NULL, NULL, NULL, ctx, pool));
+
+  /* Verify that externals were pinned as expected. */
+  SVN_ERR(svn_client_propget5(&props, NULL, SVN_PROP_EXTERNALS,
+                              A_copy_url, &peg_rev, &rev, NULL,
+                              svn_depth_empty, NULL, ctx, pool, pool));
+  propval = svn_hash_gets(props, A_copy_url);
+  SVN_TEST_ASSERT(propval);
+
+  /* Test the unparsed representation of copied externals descriptions. */
+  pinned_externals_descs = svn_cstring_split(propval->data, "\n", FALSE, pool);
+  for (i = 0; i < pinned_externals_descs->nelts; i++)
+    {
+      const char *externals_desc;
+      const char *expected_desc;
+
+      externals_desc = APR_ARRAY_IDX(pinned_externals_descs, i, const char *);
+      expected_desc = pin_externals_test_data[i].expected_dst_external_desc;
+      SVN_TEST_STRING_ASSERT(externals_desc, expected_desc);
+    }
+  /* Ensure all test cases were tested. */
+  SVN_TEST_ASSERT(i == (sizeof(pin_externals_test_data) /
+                        sizeof(pin_externals_test_data[0]) - 1));
+
+  SVN_ERR(svn_wc_parse_externals_description3(&pinned_externals, A_copy_url,
+                                              propval->data, TRUE, pool));
+
+  /* For completeness, test the parsed representation, too */
+  num_tested_externals = 0;
+  for (i = 0; i < pinned_externals->nelts; i++)
+    {
+      svn_wc_external_item2_t *item;
+
+      item = APR_ARRAY_IDX(pinned_externals, i, svn_wc_external_item2_t *);
+      if (strcmp(item->url, "^/A/D/gamma") == 0)
+        {
+          SVN_TEST_STRING_ASSERT(item->target_dir, "B/gamma");
+          /* Pinned to r2. */
+          SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->revision.value.number == 2);
+          SVN_TEST_ASSERT(item->peg_revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->peg_revision.value.number == 2);
+          num_tested_externals++;
+        }
+      else if (strcmp(item->url, "^/A/D/G") == 0)
+        {
+          SVN_TEST_STRING_ASSERT(item->target_dir, "C/exdir_G");
+          /* Not pinned. */
+          SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->revision.value.number == 1);
+          SVN_TEST_ASSERT(item->peg_revision.kind == svn_opt_revision_head);
+          num_tested_externals++;
+        }
+      else if (strcmp(item->url, "^/A/D/H") == 0)
+        {
+          if (strcmp(item->target_dir, "C/exdir_H") == 0)
+            {
+              /* Was already pinned to r1. */
+              SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_number);
+              SVN_TEST_ASSERT(item->revision.value.number == 1);
+              SVN_TEST_ASSERT(item->peg_revision.kind ==
+                              svn_opt_revision_number);
+              SVN_TEST_ASSERT(item->peg_revision.value.number == 1);
+              num_tested_externals++;
+            }
+          else if (strcmp(item->target_dir, "C/exdir_H2") == 0)
+            {
+              /* Pinned to r2. */
+              SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_number);
+              SVN_TEST_ASSERT(item->revision.value.number == 2);
+              SVN_TEST_ASSERT(item->peg_revision.kind ==
+                              svn_opt_revision_number);
+              SVN_TEST_ASSERT(item->peg_revision.value.number == 2);
+              num_tested_externals++;
+            }
+          else
+            SVN_TEST_ASSERT(FALSE); /* unknown external */
+        }
+      else if (strcmp(item->url, "^/A/B") == 0)
+        {
+          SVN_TEST_STRING_ASSERT(item->target_dir, "D/z/y/z/blah");
+          /* Pinned to r2. */
+          SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->revision.value.number == 1);
+          SVN_TEST_ASSERT(item->peg_revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->peg_revision.value.number == 2);
+          num_tested_externals++;
+        }
+      else if (strcmp(item->url, "^/A/D") == 0)
+        {
+          SVN_TEST_STRING_ASSERT(item->target_dir, "exdir_D");
+          /* Pinned to r2. */
+          SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->revision.value.number == 1);
+          SVN_TEST_ASSERT(item->peg_revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->peg_revision.value.number == 2);
+          num_tested_externals++;
+        }
+      else if (strcmp(item->url, "^/A/C") == 0)
+        {
+          SVN_TEST_STRING_ASSERT(item->target_dir, "70s");
+          /* Pinned to r2. */
+          SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_date);
+          /* Don't bother testing the exact date value here. */
+          SVN_TEST_ASSERT(item->peg_revision.kind == svn_opt_revision_number);
+          SVN_TEST_ASSERT(item->peg_revision.value.number == 2);
+          num_tested_externals++;
+        }
+      else if (strcmp(item->url, "^/svn") == 0)
+        {
+          SVN_TEST_STRING_ASSERT(item->target_dir, "1.0");
+          /* Was and not in externals_to_pin, operative revision was a date. */
+          SVN_TEST_ASSERT(item->revision.kind == svn_opt_revision_date);
+          /* Don't bother testing the exact date value here. */
+          SVN_TEST_ASSERT(item->peg_revision.kind == svn_opt_revision_head);
+          num_tested_externals++;
+        }
+      else
+        SVN_TEST_ASSERT(FALSE); /* unknown URL */
+    }
+
+  /* Ensure all test cases were tested. */
+  SVN_TEST_ASSERT(num_tested_externals == (sizeof(pin_externals_test_data) /
+                                           sizeof(pin_externals_test_data[0])
+                                          - 1));
+
+  return SVN_NO_ERROR;
+}
+
 /* ========================================================================== */
 
 
@@ -1079,6 +1311,8 @@ static struct svn_test_descriptor_t test
                        "test svn_client_suggest_merge_sources"),
     SVN_TEST_OPTS_PASS(test_remote_only_status,
                        "test svn_client_status6 with ignore_local_mods"),
+    SVN_TEST_OPTS_PASS(test_copy_pin_externals,
+                       "test svn_client_copy7 with externals_to_pin"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_client/mtcc-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_client/mtcc-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_client/mtcc-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_client/mtcc-test.c Mon Feb 16 17:40:07 2015
@@ -614,7 +614,7 @@ test_file_revs_both_ways(const svn_test_
                                 handle_rev, &hrb,
                                 subpool));
   SVN_TEST_ASSERT(hrb.last == 6);
-  
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c Mon Feb 16 17:40:07 2015
@@ -5136,7 +5136,7 @@ filename_trailing_newline(const svn_test
     SVN_TEST_ASSERT(err == SVN_NO_ERROR);
   else
     SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_PATH_SYNTAX);
-  
+
 
   /* Create another file, with contents. */
   if (!legacy_backend)
@@ -5314,7 +5314,7 @@ test_compat_version(const svn_test_opts_
 {
   svn_version_t *compatible_version;
   apr_hash_t *config = apr_hash_make(pool);
-  
+
   svn_version_t vcurrent = {SVN_VER_MAJOR, SVN_VER_MINOR, 0, ""};
   svn_version_t v1_2_0 = {1, 2, 0, ""};
   svn_version_t v1_3_0 = {1, 3, 0, ""};
@@ -5493,7 +5493,7 @@ reopen_modify(const svn_test_opts_t *opt
 
   /* Create txn with changes. */
   SVN_ERR(svn_fs_begin_txn(&txn, fs, head_rev, pool));
-  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool)); 
+  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
   SVN_ERR(svn_fs_txn_root(&root, txn, pool));
   SVN_ERR(svn_fs_make_dir(root, "X", pool));
 
@@ -5903,7 +5903,7 @@ compare_contents(const svn_test_opts_t *
   svn_checksum_t *checksum1, *checksum2;
 
   /* (path, rev) pairs to compare plus the expected API return values */
-  struct 
+  struct
     {
       svn_revnum_t rev1;
       const char *path1;
@@ -5931,12 +5931,12 @@ compare_contents(const svn_test_opts_t *
       { 3, "bar", 4, "bar", TRUE, svn_tristate_true },
 
       /* variations on the same theme: same content, possibly different rep */
-      { 4, "foo", 4, "bar", FALSE, svn_tristate_unknown }, 
-      { 1, "foo", 4, "bar", FALSE, svn_tristate_unknown }, 
-      { 2, "foo", 4, "bar", FALSE, svn_tristate_unknown }, 
-      { 1, "foo", 4, "foo", FALSE, svn_tristate_unknown }, 
-      { 2, "foo", 4, "foo", FALSE, svn_tristate_unknown }, 
-      { 2, "bar", 4, "bar", FALSE, svn_tristate_unknown }, 
+      { 4, "foo", 4, "bar", FALSE, svn_tristate_unknown },
+      { 1, "foo", 4, "bar", FALSE, svn_tristate_unknown },
+      { 2, "foo", 4, "bar", FALSE, svn_tristate_unknown },
+      { 1, "foo", 4, "foo", FALSE, svn_tristate_unknown },
+      { 2, "foo", 4, "foo", FALSE, svn_tristate_unknown },
+      { 2, "bar", 4, "bar", FALSE, svn_tristate_unknown },
 
       /* EOL */
       { 0 },
@@ -6743,7 +6743,7 @@ test_prop_and_text_rep_sharing_collision
   SVN_ERR(svn_fs_file_length(&length, rev_root, "/foo", pool));
 
   SVN_TEST_ASSERT(length == 23);
-  return SVN_NO_ERROR; 
+  return SVN_NO_ERROR;
 }
 
 /* ------------------------------------------------------------------------ */
@@ -6840,9 +6840,9 @@ static struct svn_test_descriptor_t test
                        "test svn_fs__compatible_version"),
     SVN_TEST_OPTS_PASS(dir_prop_merge,
                        "test merge directory properties"),
-    SVN_TEST_OPTS_WIMP(reopen_modify,
-                       "test reopen and modify txn",
-                       "txn_dir_cache fail in FSFS"),
+    SVN_TEST_OPTS_XFAIL_OTOH(reopen_modify,
+                             "test reopen and modify txn",
+                             SVN_TEST_PASS_IF_FS_TYPE_IS_NOT("fsfs")),
     SVN_TEST_OPTS_PASS(upgrade_while_committing,
                        "upgrade while committing"),
     SVN_TEST_OPTS_PASS(test_paths_changed,

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/locks-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/locks-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/locks-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/locks-test.c Mon Feb 16 17:40:07 2015
@@ -58,7 +58,7 @@ get_locks_callback(void *baton,
     {
       apr_hash_set(b->locks, lock_path->data, lock_path->len,
                    svn_lock_dup(lock, hash_pool));
-      return SVN_NO_ERROR; 
+      return SVN_NO_ERROR;
     }
   else
     {

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c Mon Feb 16 17:40:07 2015
@@ -325,7 +325,7 @@ fuzzing_null_byte_test(const svn_test_op
                              apr_pool_t *pool) \
   { \
     return svn_error_trace(fuzzing_set_byte_test(opts, N, M, pool)); \
-  } 
+  }
 
 /* Add the test function declared above to the test_funcs array. */
 #define TEST_FUZZING_SET_BYTE_TEST_N(N,M)\

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c Mon Feb 16 17:40:07 2015
@@ -144,7 +144,7 @@ create_packed_filesystem(const char *dir
   SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
   SVN_ERR(svn_test__create_greek_tree(txn_root, subpool));
   SVN_ERR(svn_fs_change_txn_prop(txn, SVN_PROP_REVISION_LOG,
-                                 svn_string_create(R1_LOG_MSG, pool), 
+                                 svn_string_create(R1_LOG_MSG, pool),
                                  pool));
   SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, subpool));
   SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));
@@ -1164,7 +1164,7 @@ id_parser_test(const svn_test_opts_t *op
                apr_pool_t *pool)
 {
  #define LONG_MAX_STR #LONG_MAX
-  
+
   /* Verify the revision number parser (e.g. first element of a txn ID) */
   svn_fs_fs__id_part_t id_part;
   SVN_ERR(svn_fs_fs__id_txn_parse(&id_part, "0-0"));

Propchange: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Feb 16 17:40:07 2015
@@ -56,6 +56,7 @@
 /subversion/branches/nfc-nfd-aware-client/subversion/tests/libsvn_fs_x:870276,870376
 /subversion/branches/node_pool/subversion/tests/libsvn_fs_x:1304828-1305388
 /subversion/branches/performance/subversion/tests/libsvn_fs_x:979193,980118,981087,981090,981189,981194,981287,981684,981827,982043,982355,983398,983406,983430,983474,983488,983490,983760,983764,983766,983770,984927,984973,984984,985014,985037,985046,985472,985477,985482,985487-985488,985493,985497,985500,985514,985601,985603,985606,985669,985673,985695,985697,986453,986465,986485,986491-986492,986517,986521,986605,986608,986817,986832,987865,987868-987869,987872,987886-987888,987893,988319,988898,990330,990533,990535-990537,990541,990568,990572,990574-990575,990600,990759,992899,992904,992911,993127,993141,994956,995478,995507,995603,998012,998858,999098,1001413,1001417,1004291,1022668,1022670,1022676,1022715,1022719,1025660,1025672,1027193,1027203,1027206,1027214,1027227,1028077,1028092,1028094,1028104,1028107,1028111,1028354,1029038,1029042-1029043,1029054-1029055,1029062-1029063,1029078,1029080,1029090,1029092-1029093,1029111,1029151,1029158,1029229-1029230,1029232,1029335-10293
 36,1029339-1029340,1029342,1029344,1030763,1030827,1031203,1031235,1032285,1032333,1033040,1033057,1033294,1035869,1035882,1039511,1043705,1053735,1056015,1066452,1067683,1067697-1078365
+/subversion/branches/pin-externals/subversion/tests/libsvn_fs_x:1643757-1659392
 /subversion/branches/py-tests-as-modules/subversion/tests/libsvn_fs_x:956579-1033052
 /subversion/branches/ra_serf-digest-authn/subversion/tests/libsvn_fs_x:875693-876404
 /subversion/branches/reintegrate-improvements/subversion/tests/libsvn_fs_x:873853-874164
@@ -82,4 +83,4 @@
 /subversion/branches/verify-at-commit/subversion/tests/libsvn_fs_x:1462039-1462408
 /subversion/branches/verify-keep-going/subversion/tests/libsvn_fs_x:1439280-1492639,1546002-1546110
 /subversion/branches/wc-collate-path/subversion/tests/libsvn_fs_x:1402685-1480384
-/subversion/trunk/subversion/tests/libsvn_fs_x:1414756-1509914,1606692-1658451
+/subversion/trunk/subversion/tests/libsvn_fs_x:1414756-1509914,1606692-1660163

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/fs-x-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/fs-x-pack-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/fs-x-pack-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/fs-x-pack-test.c Mon Feb 16 17:40:07 2015
@@ -166,7 +166,7 @@ create_packed_filesystem(const char *dir
   SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
   SVN_ERR(svn_test__create_greek_tree(txn_root, subpool));
   SVN_ERR(svn_fs_change_txn_prop(txn, SVN_PROP_REVISION_LOG,
-                                 svn_string_create(R1_LOG_MSG, pool), 
+                                 svn_string_create(R1_LOG_MSG, pool),
                                  pool));
   SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, subpool));
   SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/string-table-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/string-table-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/string-table-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_x/string-table-test.c Mon Feb 16 17:40:07 2015
@@ -124,19 +124,19 @@ short_string_table_body(svn_boolean_t do
                         apr_pool_t *pool)
 {
   apr_size_t indexes[STRING_COUNT] = { 0 };
-    
+
   string_table_builder_t *builder;
   string_table_t *table;
   int i;
-  
+
   builder = svn_fs_x__string_table_builder_create(pool);
   for (i = 0; i < STRING_COUNT; ++i)
     indexes[i] = svn_fs_x__string_table_builder_add(builder, basic_strings[i], 0);
-  
+
   table = svn_fs_x__string_table_create(builder, pool);
   if (do_load_store)
     SVN_ERR(store_and_load_table(&table, pool));
-  
+
   SVN_TEST_ASSERT(indexes[2] == indexes[6]);
   for (i = 0; i < STRING_COUNT; ++i)
     {

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c Mon Feb 16 17:40:07 2015
@@ -32,6 +32,7 @@
 #include "svn_error.h"
 #include "svn_delta.h"
 #include "svn_ra.h"
+#include "svn_time.h"
 #include "svn_pools.h"
 #include "svn_cmdline.h"
 #include "svn_dirent_uri.h"
@@ -41,8 +42,6 @@
 #include "../svn_test_fs.h"
 #include "../../libsvn_ra_local/ra_local.h"
 
-static const char tunnel_repos_name[] = "test-repo-tunnel";
-
 /*-------------------------------------------------------------------*/
 
 /** Helper routines. **/
@@ -136,18 +135,36 @@ commit_tree(svn_ra_session_t *session,
   return SVN_NO_ERROR;
 }
 
-static svn_boolean_t last_tunnel_check;
-static int tunnel_open_count;
-static void *check_tunnel_baton;
-static void *open_tunnel_context;
+/* Baton for opening tunnels */
+typedef struct tunnel_baton_t
+{
+  int magic; /* TUNNEL_MAGIC */
+  int open_count;
+  svn_boolean_t last_check;
+} tunnel_baton_t;
+
+#define TUNNEL_MAGIC 0xF00DF00F
+
+/* Baton for closing a specific tunnel */
+typedef struct close_baton_t
+{
+  int magic;
+  tunnel_baton_t *tb;
+  apr_proc_t *proc;
+} close_baton_t;
+
+#define CLOSE_MAGIC 0x1BADBAD1
 
 static svn_boolean_t
 check_tunnel(void *tunnel_baton, const char *tunnel_name)
 {
-  if (tunnel_baton != check_tunnel_baton)
+  tunnel_baton_t *b = tunnel_baton;
+
+  if (b->magic != TUNNEL_MAGIC)
     abort();
-  last_tunnel_check = (0 == strcmp(tunnel_name, "test"));
-  return last_tunnel_check;
+
+  b->last_check = (0 == strcmp(tunnel_name, "test"));
+  return b->last_check;
 }
 
 static void
@@ -168,8 +185,10 @@ open_tunnel(svn_stream_t **request, svn_
   apr_status_t status;
   const char *args[] = { "svnserve", "-t", "-r", ".", NULL };
   const char *svnserve;
+  tunnel_baton_t *b = tunnel_baton;
+  close_baton_t *cb;
 
-  SVN_TEST_ASSERT(tunnel_baton == check_tunnel_baton);
+  SVN_TEST_ASSERT(b->magic == TUNNEL_MAGIC);
 
   SVN_ERR(svn_dirent_get_absolute(&svnserve, "../../svnserve/svnserve", pool));
 #ifdef WIN32
@@ -193,11 +212,7 @@ open_tunnel(svn_stream_t **request, svn_
                              args, NULL, attr, pool);
   if (status != APR_SUCCESS)
     return svn_error_wrap_apr(status, "Could not run svnserve");
-#ifdef WIN32
   apr_pool_note_subprocess(pool, proc, APR_KILL_NEVER);
-#else
-  apr_pool_note_subprocess(pool, proc, APR_KILL_ONLY_ONCE);
-#endif
 
   /* APR pipe objects inherit by default.  But we don't want the
    * tunnel agent's pipes held open by future child processes
@@ -205,20 +220,42 @@ open_tunnel(svn_stream_t **request, svn_
   apr_file_inherit_unset(proc->in);
   apr_file_inherit_unset(proc->out);
 
+  cb = apr_pcalloc(pool, sizeof(*cb));
+  cb->magic = CLOSE_MAGIC;
+  cb->tb = b;
+  cb->proc = proc;
+
   *request = svn_stream_from_aprfile2(proc->in, FALSE, pool);
   *response = svn_stream_from_aprfile2(proc->out, FALSE, pool);
   *close_func = close_tunnel;
-  open_tunnel_context = *close_baton = &last_tunnel_check;
-  ++tunnel_open_count;
+  *close_baton = cb;
+  ++b->open_count;
   return SVN_NO_ERROR;
 }
 
 static void
 close_tunnel(void *tunnel_context, void *tunnel_baton)
 {
-  assert(tunnel_context == open_tunnel_context);
-  assert(tunnel_baton == check_tunnel_baton);
-  --tunnel_open_count;
+  close_baton_t *b = tunnel_context;
+
+  if (b->magic != CLOSE_MAGIC)
+    abort();
+  if (--b->tb->open_count == 0)
+    {
+      apr_status_t child_exit_status;
+      int child_exit_code;
+      apr_exit_why_e child_exit_why;
+
+      SVN_TEST_ASSERT_NO_RETURN(0 == apr_file_close(b->proc->in));
+      SVN_TEST_ASSERT_NO_RETURN(0 == apr_file_close(b->proc->out));
+
+      child_exit_status =
+        apr_proc_wait(b->proc, &child_exit_code, &child_exit_why, APR_WAIT);
+
+      SVN_TEST_ASSERT_NO_RETURN(child_exit_status == APR_CHILD_DONE);
+      SVN_TEST_ASSERT_NO_RETURN(child_exit_code == 0);
+      SVN_TEST_ASSERT_NO_RETURN(child_exit_why == APR_PROC_EXIT);
+    }
 }
 
 
@@ -293,6 +330,7 @@ static svn_error_t *
 check_tunnel_callback_test(const svn_test_opts_t *opts,
                            apr_pool_t *pool)
 {
+  tunnel_baton_t b = { TUNNEL_MAGIC };
   svn_ra_callbacks2_t *cbtable;
   svn_ra_session_t *session;
   svn_error_t *err;
@@ -300,7 +338,7 @@ check_tunnel_callback_test(const svn_tes
   SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
   cbtable->check_tunnel_func = check_tunnel;
   cbtable->open_tunnel_func = open_tunnel;
-  cbtable->tunnel_baton = check_tunnel_baton = &cbtable;
+  cbtable->tunnel_baton = &b;
   SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton,
                                         TRUE  /* non_interactive */,
                                         "jrandom", "rayjandom",
@@ -309,13 +347,12 @@ check_tunnel_callback_test(const svn_tes
                                         FALSE /* trust_server_cert */,
                                         NULL, NULL, NULL, pool));
 
-  last_tunnel_check = TRUE;
-  open_tunnel_context = NULL;
+  b.last_check = TRUE;
   err = svn_ra_open4(&session, NULL, "svn+foo://localhost/no-repo",
                      NULL, cbtable, NULL, NULL, pool);
   svn_error_clear(err);
   SVN_TEST_ASSERT(err);
-  SVN_TEST_ASSERT(!last_tunnel_check);
+  SVN_TEST_ASSERT(!b.last_check);
   return SVN_NO_ERROR;
 }
 
@@ -323,21 +360,26 @@ static svn_error_t *
 tunnel_callback_test(const svn_test_opts_t *opts,
                      apr_pool_t *pool)
 {
-  apr_pool_t *connection_pool;
-  svn_repos_t *repos;
+  tunnel_baton_t b = { TUNNEL_MAGIC };
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
   const char *url;
   svn_ra_callbacks2_t *cbtable;
   svn_ra_session_t *session;
   svn_error_t *err;
+  const char tunnel_repos_name[] = "test-repo-tunnel";
 
-  SVN_ERR(svn_test__create_repos(&repos, tunnel_repos_name, opts, pool));
+  SVN_ERR(svn_test__create_repos(NULL, tunnel_repos_name, opts, scratch_pool));
+
+  /* Immediately close the repository to avoid race condition with svnserve
+     (and then the cleanup code) with BDB when our pool is cleared. */
+  svn_pool_clear(scratch_pool);
 
   url = apr_pstrcat(pool, "svn+test://localhost/", tunnel_repos_name,
                     SVN_VA_NULL);
   SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
   cbtable->check_tunnel_func = check_tunnel;
   cbtable->open_tunnel_func = open_tunnel;
-  cbtable->tunnel_baton = check_tunnel_baton = &cbtable;
+  cbtable->tunnel_baton = &b;
   SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton,
                                         TRUE  /* non_interactive */,
                                         "jrandom", "rayjandom",
@@ -346,12 +388,9 @@ tunnel_callback_test(const svn_test_opts
                                         FALSE /* trust_server_cert */,
                                         NULL, NULL, NULL, pool));
 
-  last_tunnel_check = FALSE;
-  open_tunnel_context = NULL;
-  tunnel_open_count = 0;
-  connection_pool = svn_pool_create(pool);
+  b.last_check = FALSE;
   err = svn_ra_open4(&session, NULL, url, NULL, cbtable, NULL, NULL,
-                     connection_pool);
+                     scratch_pool);
   if (err && err->apr_err == SVN_ERR_TEST_FAILED)
     {
       svn_handle_error2(err, stderr, FALSE, "svn_tests: ");
@@ -359,10 +398,10 @@ tunnel_callback_test(const svn_test_opts
       return SVN_NO_ERROR;
     }
   SVN_ERR(err);
-  SVN_TEST_ASSERT(last_tunnel_check);
-  SVN_TEST_ASSERT(tunnel_open_count > 0);
-  svn_pool_destroy(connection_pool);
-  SVN_TEST_ASSERT(tunnel_open_count == 0);
+  SVN_TEST_ASSERT(b.last_check);
+  SVN_TEST_ASSERT(b.open_count > 0);
+  svn_pool_destroy(scratch_pool);
+  SVN_TEST_ASSERT(b.open_count == 0);
   return SVN_NO_ERROR;
 }
 
@@ -403,7 +442,7 @@ lock_cb(void *baton,
   result->err = ra_err;
 
   svn_hash_sets(b->results, apr_pstrdup(b->pool, path), result);
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -578,6 +617,52 @@ get_dir_test(const svn_test_opts_t *opts
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_commit_callback2_t for commit_callback_failure() */
+static svn_error_t *
+commit_callback_with_failure(const svn_commit_info_t *info,
+                             void *baton,
+                             apr_pool_t *scratch_pool)
+{
+  apr_time_t timetemp;
+
+  SVN_TEST_ASSERT(info != NULL);
+  SVN_TEST_STRING_ASSERT(info->author, "jrandom");
+  SVN_TEST_STRING_ASSERT(info->post_commit_err, NULL);
+
+  SVN_ERR(svn_time_from_cstring(&timetemp, info->date, scratch_pool));
+  SVN_TEST_ASSERT(timetemp != 0);
+  SVN_TEST_ASSERT(info->repos_root != NULL);
+  SVN_TEST_ASSERT(info->revision == 1);
+
+  return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+}
+
+static svn_error_t *
+commit_callback_failure(const svn_test_opts_t *opts,
+                        apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  const svn_delta_editor_t *editor;
+  void *edit_baton;
+  void *root_baton;
+  SVN_ERR(make_and_open_repos(&ra_session, "commit_cb_failure", opts, pool));
+
+  SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
+                                    apr_hash_make(pool), commit_callback_with_failure,
+                                    NULL, NULL, FALSE, pool));
+
+  SVN_ERR(editor->open_root(edit_baton, 1, pool, &root_baton));
+  SVN_ERR(editor->change_dir_prop(root_baton, "A",
+                                  svn_string_create("B", pool), pool));
+  SVN_ERR(editor->close_directory(root_baton, pool));
+  SVN_TEST_ASSERT_ERROR(editor->close_edit(edit_baton, pool),
+                        SVN_ERR_CANCELLED);
+
+  /* This is what users should do if close_edit fails... Except that in this case
+     the commit actually succeeded*/
+  SVN_ERR(editor->abort_edit(edit_baton, pool));
+  return SVN_NO_ERROR;
+}
 
 
 /* The test table.  */
@@ -597,6 +682,8 @@ static struct svn_test_descriptor_t test
                        "lock multiple paths"),
     SVN_TEST_OPTS_PASS(get_dir_test,
                        "test ra_get_dir2"),
+    SVN_TEST_OPTS_PASS(commit_callback_failure,
+                       "commit callback failure"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/cache-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/cache-test.c Mon Feb 16 17:40:07 2015
@@ -290,7 +290,7 @@ test_membuffer_serializer_error_handling
   /* Test setting data in cache using partial setter that
      always raises an error. */
   SVN_TEST_ASSERT_ERROR(
-    svn_cache__set_partial(cache, "twenty", 
+    svn_cache__set_partial(cache, "twenty",
                            raise_error_partial_setter_func,
                            NULL, pool),
     APR_EGENERAL);

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/checksum-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/checksum-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/checksum-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/checksum-test.c Mon Feb 16 17:40:07 2015
@@ -170,7 +170,7 @@ zero_cross_match(apr_pool_t *pool)
     {
       svn_checksum_t *i_zero;
       svn_checksum_t *i_A;
-    
+
       i_zero = svn_checksum_create(i_kind, pool);
       SVN_ERR(svn_checksum_clear(i_zero));
       SVN_ERR(svn_checksum(&i_A, i_kind, "A", 1, pool));

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/config-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/config-test.c Mon Feb 16 17:40:07 2015
@@ -363,7 +363,7 @@ test_expand(const svn_test_opts_t *opts,
   /* Get expanded "c". */
   svn_config_get(cfg, &val, "section1", "c", NULL);
 
-  /* With pool debugging enabled this ensures that the expanded value 
+  /* With pool debugging enabled this ensures that the expanded value
      of "c" was not created in a temporary pool when expanding "g". */
   SVN_TEST_STRING_ASSERT(val, "bar");
 

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/io-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/io-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/io-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/io-test.c Mon Feb 16 17:40:07 2015
@@ -703,7 +703,7 @@ ignore_enoent(apr_pool_t *pool)
   SVN_ERR(svn_io_set_file_executable(path, FALSE, TRUE, pool));
   SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, TRUE, TRUE, pool, pool));
   SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, FALSE, TRUE, pool, pool));
-  
+
   /* Neither path nor parent exists. */
   path = svn_dirent_join(path, "not-present", pool);
   SVN_ERR(svn_io_remove_dir2(path, TRUE, NULL, NULL, pool));

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/packed-data-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/packed-data-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/packed-data-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/packed-data-test.c Mon Feb 16 17:40:07 2015
@@ -99,7 +99,7 @@ verify_uint_stream(const apr_uint64_t *v
   SVN_TEST_ASSERT(stream);
   SVN_TEST_ASSERT(!svn_packed__next_int_stream(stream));
   SVN_TEST_ASSERT(!svn_packed__first_byte_stream(root));
-  
+
   /* the stream shall contain exactly the items we put into it */
   SVN_TEST_ASSERT(svn_packed__int_count(stream) == count);
   for (i = 0; i < count; ++i)
@@ -356,7 +356,7 @@ pack(const base_record_t *data,
   svn_packed__create_int_substream(base_stream, TRUE, TRUE);   /* large_signed1 */
   svn_packed__create_int_substream(base_stream, FALSE, TRUE);  /* large_signed2 */
   svn_packed__create_int_substream(base_stream, TRUE, FALSE);  /* prime */
-  
+
   for (i = 0; i < count; ++i)
     {
       svn_packed__add_int(base_stream, data[i].counter);
@@ -434,7 +434,7 @@ unpack(apr_size_t *count,
   base_record_t *data;
   *count = svn_packed__int_count(sub_count_stream) / 2;
   data = apr_pcalloc(pool, *count * sizeof(*data));
-  
+
   for (i = 0; i < *count; ++i)
     {
       data[i].counter = (int) svn_packed__get_int(base_stream);

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/priority-queue-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/priority-queue-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/priority-queue-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/priority-queue-test.c Mon Feb 16 17:40:07 2015
@@ -70,7 +70,7 @@ verify_empty_queue(svn_priority_queue__t
   /* these should be no-ops */
   svn_priority_queue__update(queue);
   svn_priority_queue__pop(queue);
-  
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/sqlite-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/sqlite-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/sqlite-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/sqlite-test.c Mon Feb 16 17:40:07 2015
@@ -57,7 +57,7 @@ error_second(svn_sqlite__context_t *sctx
     svn_sqlite__result_error(sctx, "fake error", 0);
   else
     svn_sqlite__result_int64(sctx, 1);
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -102,7 +102,7 @@ test_sqlite_reset(apr_pool_t *pool)
 
   /* The svn_sqlite__step wrapper calls svn_sqlite__reset when step
      fails so the reset call here is a no-op.  The first step can be
-     repeated. */ 
+     repeated. */
   SVN_ERR(svn_sqlite__reset(stmt));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   SVN_TEST_ASSERT(have_row);

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c Mon Feb 16 17:40:07 2015
@@ -849,7 +849,7 @@ test_string_matching(apr_pool_t *pool)
       SVN_TEST_ASSERT(match_len == test->match_len);
       SVN_TEST_ASSERT(rmatch_len == test->rmatch_len);
     }
-  
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/subst_translate-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/subst_translate-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/subst_translate-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/subst_translate-test.c Mon Feb 16 17:40:07 2015
@@ -397,7 +397,7 @@ test_svn_subst_long_keywords(apr_pool_t
       "01234567890123456789012345678901234567890123456789"
       "012345678901234567890123456789012345678901234567";
 
-  /* The longest keyword that can be expanded: the value is empty. */ 
+  /* The longest keyword that can be expanded: the value is empty. */
   const char keyword_z[]
     = "Q"
       "01234567890123456789012345678901234567890123456789"

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/x509-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/x509-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/x509-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/x509-test.c Mon Feb 16 17:40:07 2015
@@ -151,7 +151,7 @@ static struct x509_test cert_tests[] = {
     "b3b9789d8a53868f418619565f6b56af0033bdd3" },
   /* The issuer and subject (except for the country code) is
    * UnversalString encoded.  Created with a hacked version of openssl
-   * using utf8=yes and string_mask=MASK:256.  In order for that to 
+   * using utf8=yes and string_mask=MASK:256.  In order for that to
    * output UniversalString encoded data you need to change the
    * DIRSTRING_TYPE in crypto/asn1/asn1.h to be defined as
    * B_ASN1_DIRECTORYSTRING so that UnviersalString is available to be

Propchange: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/x509-test.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c Mon Feb 16 17:40:07 2015
@@ -294,6 +294,7 @@ test_read_write_tree_conflicts(const svn
   SVN_ERR(sbox_wc_mkdir(&sbox, "A"));
   SVN_ERR(sbox_wc_mkdir(&sbox, "A/bar"));
   SVN_ERR(sbox_file_write(&sbox, "A/foo", ""));
+  SVN_ERR(sbox_wc_add(&sbox, "A/foo"));
 
   conflict1 = tree_conflict_create(child1_abspath, svn_node_file,
                                    svn_wc_operation_merge,

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c Mon Feb 16 17:40:07 2015
@@ -509,7 +509,8 @@ check_db_conflicts(svn_test__sandbox_t *
       local_abspath = svn_dirent_join(b->wc_abspath, info->local_relpath,
                                       iterpool);
 
-      SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db, local_abspath,
+      SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL,
+                                       b->wc_ctx->db, local_abspath,
                                        iterpool, iterpool));
 
       SVN_TEST_ASSERT(conflict != NULL);
@@ -5928,7 +5929,7 @@ check_tree_conflict_repos_path(svn_test_
   const apr_array_header_t *locations;
   svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
 
-  SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db,
+  SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, b->wc_ctx->db,
                                    sbox_wc_path(b, wc_path),
                                    b->pool, b->pool));
 
@@ -9140,15 +9141,15 @@ move_twice_within_delete(const svn_test_
       nodes_row_t nodes[] = {
 
         { 0, "",          "normal",       1, "" },
-                          
+
         { 0, "A",         "normal",       1, "A" },
         { 0, "A/A",       "normal",       1, "A/A" },
         { 0, "A/A/A",     "normal",       1, "A/A/A" },
-                          
+
         { 1, "A",         "base-deleted", NO_COPY_FROM, "B/A" },
         { 1, "A/A",       "base-deleted", NO_COPY_FROM },
         { 1, "A/A/A",     "base-deleted", NO_COPY_FROM },
-                          
+
         { 1, "AA",        "normal",       1, "A/A/A", MOVED_HERE },
 
         { 1, "B",         "normal",       NO_COPY_FROM },
@@ -9686,7 +9687,40 @@ del4_update_delself_AAA(const svn_test_o
   SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
   /* Go back to start position */
   SVN_ERR(sbox_wc_update(&b, "", 1));
-  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  {
+    conflict_info_t conflicts[] = {
+      {"A", FALSE, FALSE,   { svn_wc_conflict_action_edit,
+                              svn_wc_conflict_reason_replaced}},
+      {"B", FALSE, FALSE,   { svn_wc_conflict_action_edit,
+                              svn_wc_conflict_reason_moved_away, "B"}},
+      {"C/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+                              svn_wc_conflict_reason_moved_away, "C/A"}},
+      {0}
+    };
+
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  {
+    conflict_info_t conflicts[] = {
+      {"A/A",  FALSE, FALSE,  { svn_wc_conflict_action_edit,
+                                svn_wc_conflict_reason_deleted}},
+      {"A/A/A", FALSE, FALSE, { svn_wc_conflict_action_add,
+                                svn_wc_conflict_reason_added}},
+      {0}
+    };
+
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
+  SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
+                          svn_wc_conflict_choose_mine_conflict));
   /* Update and resolve via their strategy */
   SVN_ERR(sbox_wc_update(&b, "", 2));
   SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
@@ -9989,14 +10023,46 @@ move4_update_delself_AAA(const svn_test_
 
         { 0 },
       };
-        SVN_ERR(check_db_rows(&b, "", nodes));
+
+      conflict_info_t conflicts[] = {
+        {"A", FALSE, FALSE,   { svn_wc_conflict_action_edit,
+                                svn_wc_conflict_reason_moved_away, "A"}},
+        {"B", FALSE, FALSE,   { svn_wc_conflict_action_edit,
+                                svn_wc_conflict_reason_moved_away, "B"}},
+        {"C/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+                                svn_wc_conflict_reason_moved_away, "C/A"}},
+        {0}
+      };
+
+      SVN_ERR(check_db_rows(&b, "", nodes));
+      SVN_ERR(check_db_conflicts(&b, "", conflicts));
     }
-    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
-    /* Update and resolve via their strategy */
-    SVN_ERR(sbox_wc_update(&b, "", 2));
-    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
 
-    return SVN_NO_ERROR;
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  {
+    conflict_info_t conflicts[] = {
+      {"A/A",  FALSE, FALSE,  { svn_wc_conflict_action_edit,
+                                svn_wc_conflict_reason_moved_away, "A/A"}},
+      {"A/A/A", FALSE, FALSE, { svn_wc_conflict_action_add,
+                                svn_wc_conflict_reason_added}},
+      {0}
+    };
+
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
+  SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Update and resolve via their strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -10191,8 +10257,35 @@ movedhere_extract_retract(const svn_test
   SVN_ERR(sbox_wc_mkdir(&b, "Z/E2"));
 
   SVN_ERR(sbox_wc_update(&b, "", 2));
+  {
+    conflict_info_t conflicts[] = {
+      {"A",    FALSE, FALSE, {svn_wc_conflict_action_edit,
+                              svn_wc_conflict_reason_moved_away, "A"}},
+      {0}
+    };
+
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
   SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
                           svn_wc_conflict_choose_mine_conflict));
+  {
+    conflict_info_t conflicts[] = {
+      {"Z/B1", FALSE, FALSE, {svn_wc_conflict_action_edit,
+                              svn_wc_conflict_reason_deleted}},
+      {"Z/B2", FALSE, FALSE, {svn_wc_conflict_action_edit,
+                              svn_wc_conflict_reason_moved_away, "Z/B2"}},
+      {"Z/C1", FALSE, FALSE, {svn_wc_conflict_action_delete,
+                              svn_wc_conflict_reason_deleted}},
+      {"Z/C2", FALSE, FALSE, {svn_wc_conflict_action_delete,
+                              svn_wc_conflict_reason_moved_away, "Z/C2"}},
+      {"Z/E2", FALSE, FALSE, {svn_wc_conflict_action_add,
+                              svn_wc_conflict_reason_added}},
+
+      {0}
+    };
+
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
   SVN_ERR(sbox_wc_resolve(&b, "Z/B1", svn_depth_empty,
                           svn_wc_conflict_choose_mine_conflict));
   SVN_ERR(sbox_wc_resolve(&b, "Z/B2", svn_depth_empty,
@@ -10203,8 +10296,10 @@ movedhere_extract_retract(const svn_test
   SVN_ERR(sbox_wc_resolve(&b, "Z/C2", svn_depth_empty,
                           svn_wc_conflict_choose_merged));
 
-  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
-                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "Z/E2", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+
+  SVN_ERR(check_db_conflicts(&b, "", NULL));
   {
     nodes_row_t nodes[] = {
 
@@ -10259,6 +10354,8 @@ movedhere_extract_retract(const svn_test
       { 0 },
     };
     SVN_ERR(check_db_rows(&b, "", nodes));
+
+    SVN_ERR(check_db_conflicts(&b, "", NULL));
   }
 
   return SVN_NO_ERROR;
@@ -10815,6 +10912,75 @@ move_edit_obstruction(const svn_test_opt
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+move_deep_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_deep_bump", opts, pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "B"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/B"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/B/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "C"));
+  SVN_ERR(sbox_wc_mkdir(&b, "C/C"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_mkdir(&b, "Z"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A/A/A"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+
+  SVN_ERR(sbox_wc_move(&b, "B/B/A", "B/B/B"));
+  SVN_ERR(sbox_wc_move(&b, "B/B/B/A", "C/C/A"));
+
+  /* This can't bump C/C/A as that is outside the lock range
+     so we expect a tree conflict.
+
+     This used to cause a node not found during bumping
+     because B/B/B/A doesn't have a BASE node */
+  SVN_ERR(sbox_wc_update(&b, "B/B", 2));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",                 "normal",       1, ""},
+      {0, "B",                "normal",       1, "B"},
+      {0, "B/B",              "normal",       2, "B/B"},
+      {0, "B/B/A",            "normal",       2, "B/B/A"},
+      {0, "B/B/A/A",          "normal",       2, "B/B/A/A"},
+      {0, "B/B/A/A/A",        "normal",       2, "B/B/A/A/A"},
+      {0, "C",                "normal",       1, "C"},
+      {0, "C/C",              "normal",       1, "C/C"},
+      {3, "B/B/A",            "base-deleted", NO_COPY_FROM, "B/B/B"},
+      {3, "B/B/A/A",          "base-deleted", NO_COPY_FROM},
+      {3, "B/B/A/A/A",        "base-deleted", NO_COPY_FROM},
+      {3, "B/B/B",            "normal",       2, "B/B/A", MOVED_HERE},
+      {3, "B/B/B/A",          "normal",       2, "B/B/A/A", MOVED_HERE},
+      {3, "B/B/B/A/A",        "normal",       2, "B/B/A/A/A", MOVED_HERE},
+      {3, "C/C/A",            "normal",       1, "B/B/A/A", MOVED_HERE},
+      {3, "C/C/A/A",          "normal",       1, "B/B/A/A/A", MOVED_HERE},
+      {4, "B/B/B/A",          "base-deleted", NO_COPY_FROM, "C/C/A"},
+      {4, "B/B/B/A/A",        "base-deleted", NO_COPY_FROM},
+      {0}
+    };
+    conflict_info_t conflicts[] = {
+      {"B/B/B/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+                                 svn_wc_conflict_reason_moved_away, "B/B/B/A"}},
+      {0}
+    };
+
+    SVN_ERR(check_db_rows(&b, "", nodes));
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
+
+  SVN_ERR(sbox_wc_resolve(&b, "B/B/B/A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(check_db_conflicts(&b, "", NULL));
+
+  return SVN_NO_ERROR;
+}
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
@@ -11022,6 +11188,8 @@ static struct svn_test_descriptor_t test
                         "move within mixed move"),
     SVN_TEST_OPTS_PASS(move_edit_obstruction,
                        "move edit obstruction"),
+    SVN_TEST_OPTS_PASS(move_deep_bump,
+                       "move deep bump"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/move-tracking-2/subversion/tests/svn_test.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/svn_test.h?rev=1660173&r1=1660172&r2=1660173&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/svn_test.h (original)
+++ subversion/branches/move-tracking-2/subversion/tests/svn_test.h Mon Feb 16 17:40:07 2015
@@ -27,6 +27,8 @@
 #define SVN_DEPRECATED
 #endif /* ! SVN_ENABLE_DEPRECATION_WARNINGS_IN_TESTS */
 
+#include <stdio.h>
+
 #include <apr_pools.h>
 
 #include "svn_delta.h"
@@ -54,6 +56,23 @@ extern "C" {
                                #expr, __FILE__, __LINE__);        \
   } while (0)
 
+/**
+ * Macro for testing assumptions when the context does not allow
+ * returning an svn_error_t*.
+ *
+ * Will write to stderr and cause a segfault if EXPR is false.
+ */
+#define SVN_TEST_ASSERT_NO_RETURN(expr)                           \
+  do {                                                            \
+    if (!(expr))                                                  \
+      {                                                           \
+        unsigned int z_e_r_o_p_a_g_e__;                           \
+        fprintf(stderr, "TEST ASSERTION FAILED: %s\n", #expr);    \
+        z_e_r_o_p_a_g_e__ = *(volatile unsigned int*)0;           \
+        *(volatile unsigned int*)0 = z_e_r_o_p_a_g_e__;           \
+      }                                                           \
+  } while (0)
+
 /** Handy macro for testing an expected svn_error_t return value.
  * EXPECTED must be a real error (neither SVN_NO_ERROR nor APR_SUCCESS).
  * The error returned by EXPR will be cleared.
@@ -146,6 +165,11 @@ typedef svn_error_t* (*svn_test_driver2_
 typedef svn_error_t* (*svn_test_driver_opts_t)(const svn_test_opts_t *opts,
                                                apr_pool_t *pool);
 
+/* Prototype for test predicate functions. */
+typedef svn_boolean_t (*svn_test_predicate_func_t)(const svn_test_opts_t *opts,
+                                                   const char *predicate_value,
+                                                   apr_pool_t *pool);
+
 /* Test modes. */
 enum svn_test_mode_t
   {
@@ -155,6 +179,23 @@ enum svn_test_mode_t
     svn_test_all
   };
 
+/* Structure for runtime test predicates. */
+struct svn_test_predicate_t
+{
+  /* The predicate function. */
+  svn_test_predicate_func_t func;
+
+  /* The value that the predicate function tests. */
+  const char *value;
+
+  /* The test mode that's used if the predicate matches. */
+  enum svn_test_mode_t alternate_mode;
+
+  /* Description for the test log */
+  const char *description;
+};
+
+
 /* Each test gets a test descriptor, holding the function and other
  * associated data.
  */
@@ -174,6 +215,9 @@ struct svn_test_descriptor_t
 
   /* An optional description of a work-in-progress test. */
   const char *wip;
+
+  /* An optional runtiume predicate. */
+  struct svn_test_predicate_t predicate;
 };
 
 /* All Subversion test programs include an array of svn_test_descriptor_t's
@@ -217,6 +261,8 @@ int svn_test_main(int argc, const char *
 #define SVN_TEST_OPTS_XFAIL(func, msg) {svn_test_xfail, NULL, func, msg}
 #define SVN_TEST_OPTS_XFAIL_COND(func, p, msg) \
   {(p) ? svn_test_xfail : svn_test_pass, NULL, func, msg}
+#define SVN_TEST_OPTS_XFAIL_OTOH(func, msg, predicate) \
+  {svn_test_xfail, NULL, func, msg, NULL, predicate}
 #define SVN_TEST_OPTS_SKIP(func, p, msg) \
   {(p) ? svn_test_skip : svn_test_pass, NULL, func, msg}
 
@@ -283,6 +329,33 @@ svn_error_t *
 svn_test__init_auth_baton(svn_auth_baton_t **baton,
                           apr_pool_t *result_pool);
 
+
+/*
+ * Test predicates
+ */
+
+#define SVN_TEST_PASS_IF_FS_TYPE_IS(fs_type) \
+  { svn_test__fs_type_is, fs_type, svn_test_pass, \
+    "PASS if fs-type = " fs_type }
+
+#define SVN_TEST_PASS_IF_FS_TYPE_IS_NOT(fs_type) \
+  { svn_test__fs_type_not, fs_type, svn_test_pass, \
+    "PASS if fs-type != " fs_type }
+
+/* Return TRUE if the fs-type in OPTS matches PREDICATE_VALUE. */
+svn_boolean_t
+svn_test__fs_type_is(const svn_test_opts_t *opts,
+                     const char *predicate_value,
+                     apr_pool_t *pool);
+
+
+/* Return TRUE if the fs-type in OPTS does not matches PREDICATE_VALUE. */
+svn_boolean_t
+svn_test__fs_type_not(const svn_test_opts_t *opts,
+                      const char *predicate_value,
+                      apr_pool_t *pool);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */



Mime
View raw message