import shutil, re, os
import svntest
from svntest import verify, actions, main
Skip = svntest.testcase.Skip_deco
SkipUnless = svntest.testcase.SkipUnless_deco
XFail = svntest.testcase.XFail_deco
Issues = svntest.testcase.Issues_deco
Issue = svntest.testcase.Issue_deco
Wimp = svntest.testcase.Wimp_deco
Item = svntest.wc.StateItem
from svntest.main import SVN_PROP_MERGEINFO, server_has_mergeinfo
from externals_tests import change_external
from switch_tests import do_routine_switching
def relocate_deleted_missing_copied(sbox):
"relocate with deleted, missing and copied entries"
sbox.build()
wc_dir = sbox.wc_dir
mu_path = os.path.join(wc_dir, 'A', 'mu')
svntest.actions.run_and_verify_svn(None, None, [], 'rm', mu_path)
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.remove('A/mu')
expected_output = svntest.wc.State(wc_dir, {
'A/mu' : Item(verb='Deleting'),
})
svntest.actions.run_and_verify_commit(wc_dir,
expected_output,
expected_status,
None, wc_dir)
svntest.main.safe_rmtree(os.path.join(wc_dir, 'A', 'B', 'F'))
D_path = os.path.join(wc_dir, 'A', 'D')
D2_path = os.path.join(wc_dir, 'A', 'D2')
svntest.actions.run_and_verify_svn(None, None, [], 'copy',
D_path, D2_path)
D2G_path = os.path.join(wc_dir, 'A', 'D2', 'G')
svntest.actions.run_and_verify_svn(None, None, [], 'rm', D2G_path)
expected_status.add({
'A/D2' : Item(status='A ', wc_rev='-', copied='+'),
'A/D2/gamma' : Item(status=' ', wc_rev='-', copied='+'),
'A/D2/G' : Item(status='D ', wc_rev='-', copied='+'),
'A/D2/G/pi' : Item(status='D ', wc_rev='-', copied='+'),
'A/D2/G/rho' : Item(status='D ', wc_rev='-', copied='+'),
'A/D2/G/tau' : Item(status='D ', wc_rev='-', copied='+'),
'A/D2/H' : Item(status=' ', wc_rev='-', copied='+'),
'A/D2/H/chi' : Item(status=' ', wc_rev='-', copied='+'),
'A/D2/H/omega' : Item(status=' ', wc_rev='-', copied='+'),
'A/D2/H/psi' : Item(status=' ', wc_rev='-', copied='+'),
})
if svntest.main.wc_is_singledb(wc_dir):
expected_status.tweak('A/B/F', status='! ', wc_rev='1')
else:
expected_status.tweak('A/B/F', status='! ', wc_rev='?')
svntest.actions.run_and_verify_status(wc_dir, expected_status)
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
svntest.main.copy_repos(repo_dir, other_repo_dir, 2, 0)
svntest.main.safe_rmtree(repo_dir, 1)
svntest.actions.run_and_verify_svn(None, None, [], 'switch', '--relocate',
repo_url, other_repo_url, wc_dir)
if svntest.main.wc_is_singledb(wc_dir):
expected_output = svntest.wc.State(wc_dir, {
'A/B/F' : Item(verb='Restored'),
})
else:
expected_output = svntest.wc.State(wc_dir, {
'A/B/F' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.remove('A/mu')
expected_disk.add({
'A/D2' : Item(),
'A/D2/gamma' : Item("This is the file 'gamma'.\n"),
'A/D2/H' : Item(),
'A/D2/H/chi' : Item("This is the file 'chi'.\n"),
'A/D2/H/omega' : Item("This is the file 'omega'.\n"),
'A/D2/H/psi' : Item("This is the file 'psi'.\n"),
})
if not svntest.main.wc_is_singledb(wc_dir):
expected_disk.add({
'A/D2/G' : Item(),
})
expected_status.add({
'A/B/F' : Item(status=' ', wc_rev='2'),
})
expected_status.tweak(wc_rev=2)
expected_status.tweak('A/D2', 'A/D2/gamma',
'A/D2/H', 'A/D2/H/chi', 'A/D2/H/omega', 'A/D2/H/psi',
wc_rev='-')
expected_status.tweak('A/D2/G', 'A/D2/G/pi', 'A/D2/G/rho', 'A/D2/G/tau',
copied='+', wc_rev='-')
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status)
expected_output = svntest.wc.State(wc_dir, {
'A/D2' : Item(verb='Adding'),
'A/D2/G' : Item(verb='Deleting'),
})
expected_status.tweak('A/D2', 'A/D2/gamma',
'A/D2/H', 'A/D2/H/chi', 'A/D2/H/omega', 'A/D2/H/psi',
status=' ', wc_rev='3', copied=None)
expected_status.remove('A/D2/G', 'A/D2/G/pi', 'A/D2/G/rho', 'A/D2/G/tau')
svntest.actions.run_and_verify_commit(wc_dir,
expected_output, expected_status,
None, wc_dir)
@Issue(2380)
def relocate_beyond_repos_root(sbox):
"relocate with prefixes longer than repo root"
sbox.build(read_only=True, create_wc=False)
wc_backup = sbox.add_wc_path('backup')
wc_dir = sbox.wc_dir
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
A_url = repo_url + "/A"
A_wc_dir = wc_dir
other_A_url = other_repo_url + "/A"
other_B_url = other_repo_url + "/B"
svntest.main.safe_rmtree(wc_dir, 1)
svntest.actions.run_and_verify_svn(None, None, [], 'checkout',
repo_url + '/A', wc_dir)
svntest.main.copy_repos(repo_dir, other_repo_dir, 1, 0)
svntest.actions.run_and_verify_svn(None, None,
".*Invalid relocation destination.*",
'relocate',
A_url, other_B_url, A_wc_dir)
svntest.actions.run_and_verify_svn(None, None,
".*is not the root.*",
'relocate',
repo_url, other_B_url, A_wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'relocate',
A_url, other_A_url, A_wc_dir)
expected_infos = [
{ 'URL' : re.escape(other_A_url) + '$',
'Path' : '.+',
'Repository UUID' : '.+',
'Revision' : '.+',
'Node Kind' : '.+',
'Last Changed Date' : '.+' },
]
svntest.actions.run_and_verify_info(expected_infos, A_wc_dir, '-rHEAD')
def relocate_and_propset(sbox):
"out of date propset should fail after a relocate"
svntest.main.safe_rmtree(sbox.repo_dir, 1)
svntest.main.create_repos(sbox.repo_dir)
wc_dir = sbox.wc_dir
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
svntest.main.greek_state.write_to_disk(svntest.main.greek_dump_dir)
exit_code, output, errput = svntest.main.run_svn(
None, 'import', '-m', 'Log message for revision 1.',
svntest.main.greek_dump_dir, sbox.repo_url)
svntest.main.safe_rmtree(wc_dir, 1)
svntest.actions.run_and_verify_svn(None,
None, [],
'checkout',
repo_url, wc_dir)
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
svntest.main.copy_repos(repo_dir, other_repo_dir, 1, 0)
svntest.main.safe_rmtree(repo_dir, 1)
svntest.actions.run_and_verify_svn(None, None, [], 'relocate',
repo_url, other_repo_url, wc_dir)
D_path = os.path.join(wc_dir, 'A', 'D')
gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
svntest.main.run_svn(None, 'rm', gamma_path)
expected_output = svntest.wc.State(wc_dir, {
'A/D/gamma' : Item(verb='Deleting'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.remove('A/D/gamma')
svntest.actions.run_and_verify_commit(wc_dir,
expected_output,
expected_status,
None, wc_dir)
svntest.main.run_svn(None, 'ps', 'foo', 'bar', D_path)
svntest.actions.run_and_verify_commit(wc_dir,
None,
None,
"[Oo]ut.of.date",
wc_dir)
def single_file_relocate(sbox):
"relocate a single file"
svntest.main.safe_rmtree(sbox.repo_dir, 1)
svntest.main.create_repos(sbox.repo_dir)
wc_dir = sbox.wc_dir
iota_path = os.path.join(sbox.wc_dir, 'iota')
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
iota_url = repo_url + '/iota'
svntest.main.greek_state.write_to_disk(svntest.main.greek_dump_dir)
exit_code, output, errput = svntest.main.run_svn(
None, 'import', '-m', 'Log message for revision 1.',
svntest.main.greek_dump_dir, sbox.repo_url)
svntest.main.safe_rmtree(wc_dir, 1)
svntest.actions.run_and_verify_svn(None,
None, [],
'checkout',
repo_url, wc_dir)
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
other_iota_url = other_repo_url + '/iota'
svntest.main.copy_repos(repo_dir, other_repo_dir, 1, 0)
svntest.main.safe_rmtree(repo_dir, 1)
svntest.actions.run_and_verify_svn(None, None,
".*Cannot relocate.*",
'relocate',
iota_url, other_iota_url, iota_path)
def relocate_with_switched_children(sbox):
"relocate a directory with switched children"
sbox.build()
wc_dir = sbox.wc_dir
do_routine_switching(sbox.wc_dir, sbox.repo_url, False)
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
svntest.main.copy_repos(repo_dir, other_repo_dir, 1, 0)
svntest.main.safe_rmtree(repo_dir, 1)
svntest.actions.run_and_verify_svn(None, None, [], 'relocate',
repo_url, other_repo_url, wc_dir)
expected_output = svntest.wc.State(wc_dir, { })
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.tweak('A/B', 'iota',
switched='S')
expected_status.remove('A/B/E', 'A/B/F', 'A/B/E/alpha', 'A/B/E/beta',
'A/B/lambda')
expected_status.add({
'A/B/pi' : Item(status=' ', wc_rev='1'),
'A/B/rho' : Item(status=' ', wc_rev='1'),
'A/B/tau' : Item(status=' ', wc_rev='1'),
})
svntest.actions.run_and_verify_commit(wc_dir,
expected_output, expected_status,
None, wc_dir)
info_output = {
wc_dir: '.*.other$',
os.path.join(wc_dir, 'iota'): '.*.other/A/D/gamma$',
os.path.join(wc_dir, 'A', 'B'): '.*.other/A/D/G$',
os.path.join(wc_dir, 'A', 'B', 'pi'): '.*.other/A/D/G/pi$',
}
for path, pattern in info_output.items():
expected_info = { 'URL' : pattern }
svntest.actions.run_and_verify_info([expected_info], path)
@Issue(3597)
def relocate_with_relative_externals(sbox):
"relocate a directory containing relative externals"
sbox.build()
wc_dir = sbox.wc_dir
change_external(os.path.join(wc_dir, 'A', 'B'),
"^/A/D/G G-ext\n../D/H H-ext", commit=True)
svntest.actions.run_and_verify_svn(None, None, [], 'update', wc_dir)
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
svntest.main.copy_repos(repo_dir, other_repo_dir, 2, 0)
svntest.main.safe_rmtree(repo_dir, 1)
svntest.actions.run_and_verify_svn(None, None, [], 'relocate',
repo_url, other_repo_url, wc_dir)
svntest.actions.run_and_verify_info([{ 'URL' : '.*.other/A/D/G$' }],
os.path.join(wc_dir, 'A', 'B', 'G-ext'))
svntest.actions.run_and_verify_info([{ 'URL' : '.*.other/A/D/H$' }],
os.path.join(wc_dir, 'A', 'B', 'H-ext'))
test_list = [ None,
relocate_deleted_missing_copied,
relocate_beyond_repos_root,
relocate_and_propset,
single_file_relocate,
relocate_with_switched_children,
relocate_with_relative_externals,
]
if __name__ == '__main__':
svntest.main.run_tests(test_list)