Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=959735&r1=959734&r2=959735&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Thu Jul 1 17:51:36 2010 @@ -29,6 +29,7 @@ import shutil, re, os # Our testing module import svntest +from svntest import verify, actions, main # (abbreviation) Skip = svntest.testcase.Skip @@ -38,6 +39,7 @@ Item = svntest.wc.StateItem from svntest.main import SVN_PROP_MERGEINFO, server_has_mergeinfo + ### Bummer. It would be really nice to have easy access to the URL ### member of our entries files so that switches could be testing by ### examining the modified ancestry. But status doesn't show this @@ -839,42 +841,84 @@ def bad_intermediate_urls(sbox): def obstructed_switch(sbox): "obstructed switch" + #svntest.factory.make(sbox, """svn cp -m msgcopy url/A/B/E url/A/B/Esave + # svn rm A/B/E/alpha + # svn commit + # echo "hello" >> A/B/E/alpha + # svn switch url/A/B/Esave A/B/E + # svn status + # svn info A/B/E/alpha""") sbox.build() wc_dir = sbox.wc_dir + url = sbox.repo_url - E_url = sbox.repo_url + '/A/B/E' - E_url2 = sbox.repo_url + '/A/B/Esave' - svntest.actions.run_and_verify_svn(None, - ['\n', 'Committed revision 2.\n'], [], - 'cp', '-m', 'msgcopy', E_url, E_url2) + A_B_E = os.path.join(wc_dir, 'A', 'B', 'E') + A_B_E_alpha = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') + url_A_B_E = url + '/A/B/E' + url_A_B_Esave = url + '/A/B/Esave' - E_path = os.path.join(wc_dir, 'A', 'B', 'E') - alpha_path = os.path.join(E_path, 'alpha') - svntest.actions.run_and_verify_svn(None, None, [], 'rm', alpha_path) - expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + # svn cp -m msgcopy url/A/B/E url/A/B/Esave + expected_stdout = verify.UnorderedOutput([ + '\n', + 'Committed revision 2.\n', + ]) + + actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'cp', '-m', + 'msgcopy', url_A_B_E, url_A_B_Esave) + + # svn rm A/B/E/alpha + expected_stdout = ['D ' + A_B_E_alpha + '\n'] + + actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'rm', + A_B_E_alpha) + + # svn commit + expected_output = svntest.wc.State(wc_dir, { + 'A/B/E/alpha' : Item(verb='Deleting'), + }) + + expected_status = actions.get_virginal_state(wc_dir, 1) expected_status.remove('A/B/E/alpha') + + actions.run_and_verify_commit(wc_dir, expected_output, expected_status, + None, wc_dir) + + # echo "hello" >> A/B/E/alpha + main.file_append(A_B_E_alpha, 'hello') + + # svn switch url/A/B/Esave A/B/E expected_output = svntest.wc.State(wc_dir, { - 'A/B/E/alpha' : Item(verb='Deleting'), - }) - svntest.actions.run_and_verify_commit(wc_dir, - expected_output, expected_status, - None, wc_dir) + 'A/B/E/alpha' : Item(status=' ', treeconflict='C'), + }) - svntest.main.file_append(alpha_path, "hello") - exit_code, out, err = svntest.main.run_svn(1, 'sw', E_url2, E_path) + expected_disk = svntest.main.greek_state.copy() + expected_disk.tweak('A/B/E/alpha', contents='hello') - for line in err: - if line.find("file of the same name already exists") != -1: - break - else: - raise svntest.Failure + expected_status.add({ + 'A/B/E/alpha' : Item(status='? ', treeconflict='C'), + }) + expected_status.tweak('A/B/E', wc_rev='3', switched='S') + expected_status.tweak('A/B/E/beta', wc_rev='3') - os.remove(alpha_path) - svntest.actions.run_and_verify_svn(None, None, [], 'sw', E_url2, E_path) - expected_status = svntest.actions.get_virginal_state(wc_dir, 1) - expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', wc_rev=3) - expected_status.tweak('A/B/E', switched='S') - svntest.actions.run_and_verify_status(wc_dir, expected_status) + actions.run_and_verify_switch(wc_dir, A_B_E, url_A_B_Esave, + expected_output, expected_disk, expected_status, None, None, None, None, + None, False) + + # svn status + expected_status.add({ + 'A/B/Esave' : Item(status=' '), + 'A/B/Esave/beta' : Item(status=' '), + 'A/B/Esave/alpha' : Item(status=' '), + }) + + actions.run_and_verify_unquiet_status(wc_dir, expected_status) + + # svn info A/B/E/alpha + expected_stdout = verify.RegexOutput( + ".*local unversioned, incoming add upon switch", + match_all=False) + actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'info', + A_B_E_alpha) #---------------------------------------------------------------------- @@ -1233,191 +1277,230 @@ def forced_switch(sbox): def forced_switch_failures(sbox): "forced switch detects tree conflicts" - sbox.build() + # svntest.factory.make(sbox, + # """ + # # Add a directory to obstruct a file. + # mkdir A/B/F/pi + # + # # Add a file to obstruct a directory. + # echo "The file 'H'" > A/C/H + # + # # Test three cases where forced switch should cause a tree conflict + # + # # 1) A forced switch that tries to add a file when an unversioned + # # directory of the same name already exists. (Currently fails) + # svn switch --force url/A/D A/C + # + # # 2) A forced switch that tries to add a dir when a file of the same + # # name already exists. (Tree conflict) + # svn switch --force url/A/D/G A/B/F + # svn info A/B/F/pi + # + # # 3) A forced update that tries to add a directory when a versioned + # # directory of the same name already exists. + # + # # Make dir A/D/H/I in repos. + # svn mkdir -m "Log message" url/A/D/H/I + # + # # Make A/D/G/I and co A/D/H/I into it. + # mkdir A/D/G/I + # svn co url/A/D/H/I A/D/G/I + # + # # Try the forced switch. A/D/G/I obstructs the dir A/D/G/I coming + # # from the repos, causing an error. + # svn switch --force url/A/D/H A/D/G + # + # # Delete all three obstructions and finish the update. + # rm -rf A/D/G/I + # rm A/B/F/pi + # rm A/C/H + # + # # A/B/F is switched to A/D/G + # # A/C is switched to A/D + # # A/D/G is switched to A/D/H + # svn up + # """) + # exit(0) + sbox.build() + wc_dir = sbox.wc_dir + url = sbox.repo_url + + A_B_F = os.path.join(wc_dir, 'A', 'B', 'F') + A_B_F_pi = os.path.join(wc_dir, 'A', 'B', 'F', 'pi') + A_C = os.path.join(wc_dir, 'A', 'C') + A_C_H = os.path.join(wc_dir, 'A', 'C', 'H') + A_D_G = os.path.join(wc_dir, 'A', 'D', 'G') + A_D_G_I = os.path.join(wc_dir, 'A', 'D', 'G', 'I') + url_A_D = url + '/A/D' + url_A_D_G = url + '/A/D/G' + url_A_D_H = url + '/A/D/H' + url_A_D_H_I = url + '/A/D/H/I' # Add a directory to obstruct a file. - pi_path = os.path.join(sbox.wc_dir, 'A', 'B', 'F', 'pi') - os.mkdir(pi_path) + # mkdir A/B/F/pi + os.makedirs(A_B_F_pi) # Add a file to obstruct a directory. - H_path = os.path.join(sbox.wc_dir, 'A', 'C', 'H') - svntest.main.file_write(H_path, "The file 'H'\n") + # echo "The file 'H'" > A/C/H + main.file_write(A_C_H, "The file 'H'\n") # Test three cases where forced switch should cause a tree conflict - # 1) A forced switch that tries to add a file when an unversioned # directory of the same name already exists. (Currently fails) + # svn switch --force url/A/D A/C + expected_error = ('Failed to add directory.*' + A_C_H + + '.*a non-directory object.*already exists\n') + + actions.run_and_verify_switch(wc_dir, A_C, url_A_D, None, None, None, + expected_error, None, None, None, None, False, '--force') + + # 2) A forced switch that tries to add a dir when a file of the same + # name already exists. + # svn switch --force url/A/D/G A/B/F + expected_output = svntest.wc.State(wc_dir, { + 'A/B/F/rho' : Item(status='A '), + 'A/B/F/pi' : Item(status=' ', treeconflict='C'), + 'A/B/F/tau' : Item(status='A '), + }) + expected_disk = svntest.main.greek_state.copy() expected_disk.add({ - 'A/C' : Item(), - 'A/C/gamma' : Item("This is the file 'gamma'.\n"), - 'A/C/H' : Item("The file 'H'\n"), + 'A/C/gamma' : Item(contents="This is the file 'gamma'.\n"), 'A/C/G' : Item(), - 'A/C/G/rho' : Item("This is the file 'rho'.\n"), - 'A/C/G/pi' : Item("This is the file 'pi'.\n"), - 'A/C/G/tau' : Item("This is the file 'tau'.\n"), - }) - expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1) + 'A/C/G/pi' : Item(contents="This is the file 'pi'.\n"), + 'A/C/G/rho' : Item(contents="This is the file 'rho'.\n"), + 'A/C/G/tau' : Item(contents="This is the file 'tau'.\n"), + 'A/C/H' : Item(contents="The file 'H'\n"), + 'A/B/F/pi' : Item(), + 'A/B/F/rho' : Item(contents="This is the file 'rho'.\n"), + 'A/B/F/tau' : Item(contents="This is the file 'tau'.\n"), + }) + + expected_status = actions.get_virginal_state(wc_dir, 1) expected_status.add({ - 'A/C' : Item(status='! ', wc_rev='1', switched='S'), + 'A/B/F/tau' : Item(status=' ', wc_rev='1'), + 'A/B/F/pi' : Item(status='? ', treeconflict='C'), + 'A/B/F/rho' : Item(status=' ', wc_rev='1'), 'A/C/G' : Item(status=' ', wc_rev='1'), - 'A/C/G/pi' : Item(status=' ', wc_rev='1'), 'A/C/G/rho' : Item(status=' ', wc_rev='1'), + 'A/C/G/pi' : Item(status=' ', wc_rev='1'), 'A/C/G/tau' : Item(status=' ', wc_rev='1'), 'A/C/gamma' : Item(status=' ', wc_rev='1'), - }) - svntest.actions.run_and_verify_switch(sbox.wc_dir, - os.path.join(sbox.wc_dir, 'A', 'C'), - sbox.repo_url + "/A/D", - None, None, None, - ".*Failed to add directory .*" + \ - ": a non-directory object of the" + \ - " same name already exists\n", - None, None, None, None, 0, '--force') + }) + expected_status.tweak('A/B/F', switched='S') + expected_status.tweak('A/C', status='! ', switched='S') + + actions.run_and_verify_switch(wc_dir, A_B_F, url_A_D_G, expected_output, + expected_disk, expected_status, None, None, None, None, None, False, + '--force') + + # svn info A/B/F/pi + expected_stdout = verify.ExpectedOutput( + 'Tree conflict: local unversioned, incoming add upon switch\n', + match_all=False) + + actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'info', + A_B_F_pi) - # 2) A forced switch that tries to add a dir when a file of the same - # name already exists. (Currently fails) - expected_disk.add({ - 'A/B/F/pi' : Item(), - }) - expected_status.add({ - 'A/B/F' : Item(status='! ', wc_rev='1', switched='S'), - }) - svntest.actions.run_and_verify_switch(sbox.wc_dir, - os.path.join(sbox.wc_dir, - 'A', 'B', 'F'), - sbox.repo_url + "/A/D/G", - None, None, None, - ".*Failed to add file .*" + \ - ": a non-file object of the " + \ - "same name already exists\n", - None, None, None, None, 0, '--force') # 3) A forced update that tries to add a directory when a versioned # directory of the same name already exists. - # Make dir A/D/H/I in repos. - I_url = sbox.repo_url + "/A/D/H/I" - exit_code, so, se = svntest.actions.run_and_verify_svn( - "Unexpected error during mkdir", - ['\n', 'Committed revision 2.\n'], [], - "mkdir", I_url, "-m", "Log Message") + # svn mkdir -m "Log message" url/A/D/H/I + expected_stdout = verify.UnorderedOutput([ + '\n', + 'Committed revision 2.\n', + ]) + + actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'mkdir', + '-m', 'Log message', url_A_D_H_I) # Make A/D/G/I and co A/D/H/I into it. - I_path = os.path.join(sbox.wc_dir, 'A', 'D', 'G', 'I') - os.mkdir(I_path) - exit_code, so, se = svntest.actions.run_and_verify_svn( - "Unexpected error during co", - ['Checked out revision 2.\n'], [], - "co", I_url, I_path) + # mkdir A/D/G/I + os.makedirs(A_D_G_I) + + # svn co url/A/D/H/I A/D/G/I + expected_output = svntest.wc.State(wc_dir, {}) + + expected_disk.add({ + 'A/D/G/I' : Item(), + }) + + exit_code, so, se = svntest.actions.run_and_verify_svn( + "Unexpected error during co", + ['Checked out revision 2.\n'], [], + "co", url_A_D_H_I, A_D_G_I) # Try the forced switch. A/D/G/I obstructs the dir A/D/G/I coming # from the repos, causing an error. - G_path = os.path.join(sbox.wc_dir, 'A', 'D', 'G') - svntest.actions.run_and_verify_switch(sbox.wc_dir, - G_path, - sbox.repo_url + "/A/D/H", - None, None, None, - "Failed to add directory '.*I'." - "*already exists", - None, None, None, None, False, - '--force') + # svn switch --force url/A/D/H A/D/G + expected_error = ('Failed to add directory.*' + A_D_G_I + + '.*a separate working copy.*already exists') + + actions.run_and_verify_switch(wc_dir, A_D_G, url_A_D_H, None, None, None, + expected_error, None, None, None, None, False, '--force') # Delete all three obstructions and finish the update. - svntest.main.safe_rmtree(I_path) - svntest.main.safe_rmtree(pi_path) - os.remove(H_path) + # rm -rf A/D/G/I + main.safe_rmtree(A_D_G_I) - # For our expected disk start with the standard greek tree. - expected_disk = svntest.main.greek_state.copy() + # rm A/B/F/pi + main.safe_rmtree(A_B_F_pi) + + # rm A/C/H + os.remove(A_C_H) - ### There has to be a simpler way to do this...but it will do for now. # A/B/F is switched to A/D/G - new_A_B_F = svntest.wc.State('', { - "A/B/F" : Item(), - "A/B/F/rho" : Item("This is the file 'rho'.\n"), - "A/B/F/pi" : Item("This is the file 'pi'.\n"), - "A/B/F/tau" : Item("This is the file 'tau'.\n"), - }) # A/C is switched to A/D - new_A_C = svntest.wc.State('', { - "A/C" : Item(), - "A/C/gamma" : Item("This is the file 'gamma'.\n"), - "A/C/G" : Item(), - "A/C/G/pi" : Item("This is the file 'pi'.\n"), - "A/C/G/rho" : Item("This is the file 'rho'.\n"), - "A/C/G/tau" : Item("This is the file 'tau'.\n"), - "A/C/H" : Item(), - "A/C/H/chi" : Item("This is the file 'chi'.\n"), - "A/C/H/I" : Item(), - "A/C/H/omega" : Item("This is the file 'omega'.\n"), - "A/C/H/psi" : Item("This is the file 'psi'.\n"), - }) # A/D/G is switched to A/D/H - new_A_D_G = svntest.wc.State('', { - "A/D/G" : Item(), - "A/D/G/chi" : Item("This is the file 'chi'.\n"), - "A/D/G/omega" : Item("This is the file 'omega'.\n"), - "A/D/G/I" : Item(), - "A/D/G/psi" : Item("This is the file 'psi'.\n"), - "A/D/H" : Item(), - "A/D/H/chi" : Item("This is the file 'chi'.\n"), - "A/D/H/omega" : Item("This is the file 'omega'.\n"), - "A/D/H/I" : Item(), - "A/D/H/psi" : Item("This is the file 'psi'.\n"), - "iota" : Item("This is the file 'iota'.\n"), - }) - # Remove the three switched subtrees and replace with their new contents. - expected_disk.remove('A/B/F', 'A/C', - 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau') - expected_disk.add_state('', new_A_B_F) - expected_disk.add_state('', new_A_C) - expected_disk.add_state('', new_A_D_G) - - expected_status = svntest.wc.State(sbox.wc_dir, { - "" : Item(), - "A" : Item(), - "A/B" : Item(), - "A/B/lambda" : Item(), - "A/B/E" : Item(), - "A/B/E/alpha" : Item(), - "A/B/E/beta" : Item(), - "A/B/F" : Item(switched='S'), - "A/B/F/rho" : Item(), - "A/B/F/pi" : Item(), - "A/B/F/tau" : Item(), - "A/mu" : Item(), - "A/C" : Item(switched='S'), - "A/C/gamma" : Item(), - "A/C/G" : Item(), - "A/C/G/pi" : Item(), - "A/C/G/rho" : Item(), - "A/C/G/tau" : Item(), - "A/C/H" : Item(), - "A/C/H/chi" : Item(), - "A/C/H/I" : Item(), - "A/C/H/omega" : Item(), - "A/C/H/psi" : Item(), - "A/D" : Item(), - "A/D/gamma" : Item(), - "A/D/G" : Item(switched='S'), - "A/D/G/chi" : Item(), - "A/D/G/omega" : Item(), - "A/D/G/I" : Item(), - "A/D/G/psi" : Item(), - "A/D/H" : Item(), - "A/D/H/chi" : Item(), - "A/D/H/omega" : Item(), - "A/D/H/I" : Item(), - "A/D/H/psi" : Item(), - "iota" : Item(), - }) - expected_status.tweak(status=' ', wc_rev=2) - svntest.actions.run_and_verify_update(sbox.wc_dir, - None, - expected_disk, - expected_status, - None, None, None, None, None, False) + # svn up + expected_output = svntest.wc.State(wc_dir, { + 'A/C/H' : Item(status='A '), + 'A/C/H/omega' : Item(status='A '), + 'A/C/H/chi' : Item(status='A '), + 'A/C/H/I' : Item(status='A '), + 'A/C/H/psi' : Item(status='A '), + 'A/D/G/omega' : Item(status='A '), + 'A/D/G/I' : Item(status='A '), + 'A/D/G/psi' : Item(status='A '), + 'A/D/H/I' : Item(status='A '), + 'A/B/F/pi' : Item(status='A '), + }) + + expected_disk.remove('A/D/G/tau', 'A/D/G/rho', 'A/D/G/pi') + expected_disk.add({ + 'A/D/H/I' : Item(), + 'A/D/G/omega' : Item(contents="This is the file 'omega'.\n"), + 'A/D/G/psi' : Item(contents="This is the file 'psi'.\n"), + 'A/D/G/chi' : Item(contents="This is the file 'chi'.\n"), + 'A/C/H/I' : Item(), + 'A/C/H/omega' : Item(contents="This is the file 'omega'.\n"), + 'A/C/H/psi' : Item(contents="This is the file 'psi'.\n"), + 'A/C/H/chi' : Item(contents="This is the file 'chi'.\n"), + }) + expected_disk.tweak('A/C/H', contents=None) + expected_disk.tweak('A/B/F/pi', contents="This is the file 'pi'.\n") + + expected_status.remove('A/D/G/tau', 'A/D/G/rho', 'A/D/G/pi') + expected_status.add({ + 'A/D/G/omega' : Item(status=' ', wc_rev='2'), + 'A/D/G/I' : Item(status=' ', wc_rev='2'), + 'A/D/G/psi' : Item(status=' ', wc_rev='2'), + 'A/D/G/chi' : Item(status=' ', wc_rev='2'), + 'A/D/H/I' : Item(status=' ', wc_rev='2'), + 'A/C/H' : Item(status=' ', wc_rev='2'), + 'A/C/H/psi' : Item(status=' ', wc_rev='2'), + 'A/C/H/omega' : Item(status=' ', wc_rev='2'), + 'A/C/H/chi' : Item(status=' ', wc_rev='2'), + 'A/C/H/I' : Item(status=' ', wc_rev='2'), + }) + expected_status.tweak(wc_rev='2', status=' ') + expected_status.tweak('A/B/F/pi', treeconflict=None) + expected_status.tweak('A/D/G', switched='S') + + actions.run_and_verify_update(wc_dir, expected_output, expected_disk, + expected_status, None, None, None, None, None, False, wc_dir) + def switch_with_obstructing_local_adds(sbox): "switch tolerates WC adds" @@ -1455,11 +1538,11 @@ def switch_with_obstructing_local_adds(s # Setup expected results of switch. expected_output = svntest.wc.State(sbox.wc_dir, { - "A/B/F/gamma" : Item(status='E '), + "A/B/F/gamma" : Item(status=' ', treeconflict='C'), "A/B/F/G" : Item(status='E '), - "A/B/F/G/pi" : Item(status='C '), + "A/B/F/G/pi" : Item(status=' ', treeconflict='C'), "A/B/F/G/rho" : Item(status='A '), - "A/B/F/G/tau" : Item(status='E '), + "A/B/F/G/tau" : Item(status=' ', treeconflict='C'), "A/B/F/H" : Item(status='A '), "A/B/F/H/chi" : Item(status='A '), "A/B/F/H/omega" : Item(status='A '), @@ -1470,12 +1553,7 @@ def switch_with_obstructing_local_adds(s expected_disk.add({ "A/B/F/gamma" : Item("This is the file 'gamma'.\n"), "A/B/F/G" : Item(), - "A/B/F/G/pi" : Item("\n".join(["<<<<<<< .mine", - "This is the OBSTRUCTING file 'pi'.", - "=======", - "This is the file 'pi'.", - ">>>>>>> .r1", - ""])), + "A/B/F/G/pi" : Item("This is the OBSTRUCTING file 'pi'.\n"), "A/B/F/G/rho" : Item("This is the file 'rho'.\n"), "A/B/F/G/tau" : Item("This is the file 'tau'.\n"), "A/B/F/G/upsilon" : Item("This is the unversioned file 'upsilon'.\n"), @@ -1488,11 +1566,12 @@ def switch_with_obstructing_local_adds(s expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1) expected_status.tweak('A/B/F', switched='S') expected_status.add({ - "A/B/F/gamma" : Item(status=' ', wc_rev=1), + "A/B/F/gamma" : Item(status='R ', treeconflict='C', wc_rev='1'), + "A/B/F/G" : Item(status=' ', wc_rev=1), - "A/B/F/G/pi" : Item(status='C ', wc_rev=1), + "A/B/F/G/pi" : Item(status='R ', treeconflict='C', wc_rev='1'), "A/B/F/G/rho" : Item(status=' ', wc_rev=1), - "A/B/F/G/tau" : Item(status=' ', wc_rev=1), + "A/B/F/G/tau" : Item(status='R ', treeconflict='C', wc_rev='1'), "A/B/F/G/upsilon" : Item(status='A ', wc_rev=0), "A/B/F/H" : Item(status=' ', wc_rev=1), "A/B/F/H/chi" : Item(status=' ', wc_rev=1),
Modified: subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py?rev=959735&r1=959734&r2=959735&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py Thu Jul 1 17:51:36 2010 @@ -107,6 +107,7 @@ def incoming_paths(root_dir, parent_dir) 'F1' : os.path.join(root_dir, "F1"), 'F' : os.path.join(parent_dir, "F"), 'F2' : os.path.join(parent_dir, "F2-in"), + 'F3' : os.path.join(root_dir, "F3"), 'D1' : os.path.join(root_dir, "D1"), 'D' : os.path.join(parent_dir, "D"), 'D2' : os.path.join(parent_dir, "D2-in"), @@ -120,6 +121,7 @@ def localmod_paths(root_dir, parent_dir) 'F1' : os.path.join(root_dir, "F1"), 'F' : os.path.join(parent_dir, "F"), 'F2' : os.path.join(parent_dir, "F2-local"), + 'F3' : os.path.join(root_dir, "F3"), 'D1' : os.path.join(root_dir, "D1"), 'D' : os.path.join(parent_dir, "D"), 'D2' : os.path.join(parent_dir, "D2-local"), @@ -127,8 +129,9 @@ def localmod_paths(root_dir, parent_dir) # Perform the action MODACTION on the WC items given by PATHS. The # available actions can be seen within this function. -def modify(modaction, paths): +def modify(modaction, paths, is_init=True): F1 = paths['F1'] # existing file to copy from + F3 = paths['F3'] # existing file to copy from F = paths['F'] # target file F2 = paths['F2'] # non-existing file to copy/move to D1 = paths['D1'] # existing dir to copy from @@ -161,7 +164,10 @@ def modify(modaction, paths): main.run_svn(None, 'add', D) main.run_svn(None, 'pset', 'dprop2', 'A prop of added dir D.', D) elif modaction == 'fC': # file Copy (from F1) - main.run_svn(None, 'copy', F1, F) + if is_init: + main.run_svn(None, 'copy', F1, F) + else: + main.run_svn(None, 'copy', F3, F) elif modaction == 'dC': # dir Copy (from D1) main.run_svn(None, 'copy', D1, D) elif modaction == 'fM': # file Move (to F2) @@ -199,6 +205,7 @@ def modify(modaction, paths): # File names: # F1 = any existing file +# F3 = any existing file # F = the file-path being acted on # F2 = any non-existent file-path # D1 = any existing dir @@ -316,8 +323,10 @@ def set_up_repos(wc_dir, br_dir, scenari # create the file F1 and dir D1 which the tests regard as pre-existing paths = incoming_paths(wc_dir, wc_dir) # second arg is bogus but unimportant F1 = paths['F1'] # existing file to copy from + F3 = paths['F3'] # existing file to copy from main.file_write(F1, "This is initially file F1.\n") - main.run_svn(None, 'add', F1) + main.file_write(F3, "This is initially file F3.\n") + main.run_svn(None, 'add', F1, F3) D1 = paths['D1'] # existing dir to copy from main.run_svn(None, 'mkdir', D1) @@ -411,7 +420,7 @@ def ensure_tree_conflict(sbox, operation verbose_print("--- Making local mods") for modaction in loc_action: - modify(modaction, localmod_paths(".", target_path)) + modify(modaction, localmod_paths(".", target_path), is_init=False) if commit_local_mods: run_and_verify_svn(None, AnyOutput, [], 'commit', target_path, Modified: subversion/trunk/subversion/tests/cmdline/update_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/update_tests.py?rev=959735&r1=959734&r2=959735&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/update_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/update_tests.py Thu Jul 1 17:51:36 2010 @@ -29,7 +29,7 @@ import sys, re, os, subprocess # Our testing module import svntest -from svntest import wc +from svntest import wc, actions, verify from merge_tests import expected_merge_output from merge_tests import set_up_branch @@ -2147,13 +2147,32 @@ def forced_update_failures(sbox): # A forced update that tries to add a file when an unversioned directory # of the same name already exists should fail. - F_Path = os.path.join(wc_backup, 'A', 'B', 'F') - svntest.actions.run_and_verify_update(F_Path, None, None, None, - ".*Failed to add file.*" + \ - "a non-file object of the " + \ - "same name already exists", - None, None, None, None, 0, F_Path, - '--force') + #svntest.factory.make(sbox, """svn up --force $WC_DIR.backup/A/B/F""") + #exit(0) + backup_A_B_F = os.path.join(wc_backup, 'A', 'B', 'F') + + # svn up --force $WC_DIR.backup/A/B/F + expected_output = svntest.wc.State(wc_backup, { + 'A/B/F/nu' : Item(status=' ', treeconflict='C'), + }) + + expected_disk = svntest.main.greek_state.copy() + expected_disk.add({ + 'A/B/F/nu' : Item(), + 'A/C/I' : + Item(contents="This is the file 'I'...shouldn't I be a dir?\n"), + }) + + expected_status = actions.get_virginal_state(wc_backup, 1) + expected_status.add({ + 'A/B/F/nu' : Item(status='? ', treeconflict='C'), + }) + expected_status.tweak('A/B/F', wc_rev='2') + + actions.run_and_verify_update(wc_backup, expected_output, + expected_disk, expected_status, None, None, None, None, None, False, + '--force', backup_A_B_F) + # A forced update that tries to add a directory when an unversioned file # of the same name already exists should fail. @@ -2803,44 +2822,17 @@ def update_with_obstructing_additions(sb }) expected_status.tweak('', 'iota', status=' ', wc_rev=4) - expected_status.tweak('omicron', status='A ', copied='+', wc_rev='-', + expected_status.tweak('omicron', status='R ', copied='+', wc_rev='-', treeconflict='C') - ### ugh. this update will leave the working copy in a BROKEN state. - ### the incoming add is flagged as a tree conflict against our local-copy. - ### the file will be "skipped" during the update, and the file will be - ### dropped on the floor. 'omicron' is then left in the same "local-copy" - ### scheduling state (schedule-add). however, this is incorrect because - ### the directory says it is r4 which *includes* an 'omicron', yet we - ### have discarded all knowledge of it. the update *should* place the - ### incoming 'omicron' into the "revert base" and mark our local copy as - ### a schedule-replace. - ### - ### see: http://svn.haxx.se/dev/archive-2009-04/0760.shtml svntest.actions.run_and_verify_update(wc_dir, expected_output, expected_disk, expected_status, None, None, None, None, None, False, wc_dir, '-N') # Resolve the tree conflict. - svntest.main.run_svn(None, 'resolve', '--accept', 'working', omicron_path) + svntest.main.run_svn(None, 'resolved', omicron_path) - ### in wc-1, I believe we see the local-copy as a different revision - ### than the parent directory (entry->revision is overloaded; normally, - ### it is supposed to represent the BASE revision; we drop a copyfrom - ### rev in there, making it appear different from the parent), so we - ### send the mixed-rev in the update report (UNVERIFIED; this is - ### speculation on cause; the effect is known, as follows). given the - ### mixed-rev report, the server will send down another add, reporting - ### another conflict. - ### - ### in wc-ng, a local-copy does not have a revision (it hasn't been - ### committed yet!). further, all BASE information has been lost, so - ### there is no knowledge of a BASE 'omicron', which is not-present or - ### at an old revision, or whatever. thus, wc-ng sees "r4" for the - ### directory and thinks there are no sub-items to report as different. - ### the server returns with "you're up to date" rather than sending - ### another add. thus, no conflict occurs on 'omicron'. expected_output = wc.State(wc_dir, { }) expected_status.tweak('omicron', treeconflict=None) @@ -4235,20 +4227,34 @@ def restarted_update_should_delete_dir_p expected_status, None, other_wc) # Back in the first working copy, create an obstructing path and - # update. The update will be interrupted, resulting in an incomplete - # dir which still has the property. + # update. The update will flag a tree conflict. svntest.main.file_write(zeta_path, 'Obstructing file\n') - error_re = 'Failed to add file.*file of the same name already exists' - svntest.actions.run_and_verify_update(wc_dir, None, None, None, - error_re) + #svntest.factory.make(sbox, 'svn up') + #exit(0) + # svn up + expected_output = svntest.wc.State(wc_dir, { + 'A' : Item(status=' U'), + 'A/zeta' : Item(status=' ', treeconflict='C'), + }) + + expected_disk = svntest.main.greek_state.copy() + expected_disk.add({ + 'A/zeta' : Item(contents="Obstructing file\n"), + }) + + expected_status = actions.get_virginal_state(wc_dir, 3) + expected_status.add({ + 'A/zeta' : Item(status='? ', treeconflict='C'), + }) + + actions.run_and_verify_update(wc_dir, expected_output, expected_disk, + expected_status, None, None, None, None, None, False, wc_dir) # Now, delete the obstructing path and rerun the update. - # A's property should disappear. os.unlink(zeta_path) expected_output = svntest.wc.State(wc_dir, { - 'A' : Item(status=' U'), 'A/zeta' : Item(status='A '), })
