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 *) = ©_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 */
