mergeinfo_tests.py [plain text]
import shutil, sys, re, os
import svntest
from svntest import wc
Item = wc.StateItem
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
exp_noop_up_out = svntest.actions.expected_noop_update_output
from svntest.main import SVN_PROP_MERGEINFO
from svntest.main import server_has_mergeinfo
import merge_tests
from merge_tests import set_up_branch
from merge_tests import expected_merge_output
def adjust_error_for_server_version(expected_err):
"Return the expected error regexp appropriate for the server version."
if server_has_mergeinfo():
return expected_err
else:
return ".*Retrieval of mergeinfo unsupported by '.+'"
def no_mergeinfo(sbox):
"'mergeinfo' on a URL that lacks mergeinfo"
sbox.build(create_wc=False)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
[], sbox.repo_url, sbox.repo_url)
def mergeinfo(sbox):
"'mergeinfo' on a path with mergeinfo"
sbox.build()
wc_dir = sbox.wc_dir
svntest.actions.run_and_verify_svn(None, None, [], 'ps', SVN_PROP_MERGEINFO,
'/:1', wc_dir)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['1'], sbox.repo_url, wc_dir)
@SkipUnless(server_has_mergeinfo)
def explicit_mergeinfo_source(sbox):
"'mergeinfo' with source selection"
sbox.build()
wc_dir = sbox.wc_dir
H_path = os.path.join(wc_dir, 'A', 'D', 'H')
H2_path = os.path.join(wc_dir, 'A', 'D', 'H2')
B_url = sbox.repo_url + '/A/B'
B_path = os.path.join(wc_dir, 'A', 'B')
G_url = sbox.repo_url + '/A/D/G'
G_path = os.path.join(wc_dir, 'A', 'D', 'G')
H2_url = sbox.repo_url + '/A/D/H2'
mergeinfo = '/A/B:1\n/A/D/G:1\n'
svntest.actions.set_prop(SVN_PROP_MERGEINFO, mergeinfo, H_path)
svntest.main.run_svn(None, "cp", H_path, H2_path)
svntest.main.run_svn(None, "ci", "-m", "r2", wc_dir)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['1'], B_url, H_path)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['1'], B_path, H_path)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['1'], G_url, H_path)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['1'], G_path, H_path)
@SkipUnless(server_has_mergeinfo)
def mergeinfo_non_source(sbox):
"'mergeinfo' with uninteresting source selection"
sbox.build()
wc_dir = sbox.wc_dir
H_path = os.path.join(wc_dir, 'A', 'D', 'H')
H2_path = os.path.join(wc_dir, 'A', 'D', 'H2')
B_url = sbox.repo_url + '/A/B'
B_path = os.path.join(wc_dir, 'A', 'B')
G_url = sbox.repo_url + '/A/D/G'
G_path = os.path.join(wc_dir, 'A', 'D', 'G')
H2_url = sbox.repo_url + '/A/D/H2'
mergeinfo = '/A/B:1\n/A/D/G:1\n'
svntest.actions.set_prop(SVN_PROP_MERGEINFO, mergeinfo, H_path)
svntest.main.run_svn(None, "cp", H_path, H2_path)
svntest.main.run_svn(None, "ci", "-m", "r2", wc_dir)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
[], H2_url, H_path)
@Issue(3138)
def mergeinfo_on_unknown_url(sbox):
"mergeinfo of an unknown url should return error"
sbox.build()
wc_dir = sbox.wc_dir
iota_path = os.path.join(wc_dir, 'iota')
svntest.actions.run_and_verify_svn(None, None, [], 'rm', iota_path)
svntest.actions.run_and_verify_svn("", None, [],
"ci", wc_dir, "-m", "log message")
url = sbox.repo_url + "/iota"
expected_err = adjust_error_for_server_version(".*File not found.*iota.*|"
".*iota.*path not found.*")
svntest.actions.run_and_verify_svn("", None, expected_err,
"mergeinfo", "--show-revs", "eligible",
url, wc_dir)
@Issue(3126)
def non_inheritable_mergeinfo(sbox):
"non-inheritable mergeinfo shows as merged"
sbox.build()
wc_dir = sbox.wc_dir
expected_disk, expected_status = set_up_branch(sbox)
A_COPY_path = os.path.join(wc_dir, "A_COPY")
D_COPY_path = os.path.join(wc_dir, "A_COPY", "D")
rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho")
svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], 'up',
wc_dir)
expected_status.tweak(wc_rev=6)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[4]],
['U ' + rho_COPY_path + '\n',
' U ' + A_COPY_path + '\n',]),
[], 'merge', '-c4',
sbox.repo_url + '/A',
A_COPY_path)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[6]], ' G ' + A_COPY_path + '\n'),
[], 'merge', '-c6',
sbox.repo_url + '/A',
A_COPY_path, '--depth', 'empty')
expected_output = wc.State(wc_dir, {
'A_COPY' : Item(verb='Sending'),
'A_COPY/D/G/rho' : Item(verb='Sending'),
})
expected_status.tweak('A_COPY', 'A_COPY/D/G/rho', wc_rev=7)
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
expected_status, None, wc_dir)
svntest.actions.run_and_verify_svn(None, exp_noop_up_out(7), [], 'up',
wc_dir)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['4','6*'],
sbox.repo_url + '/A',
A_COPY_path)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['3','5','6*'],
sbox.repo_url + '/A',
A_COPY_path,
'--show-revs', 'eligible')
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['4'],
sbox.repo_url + '/A/D',
D_COPY_path)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['3','6'],
sbox.repo_url + '/A/D',
D_COPY_path,
'--show-revs', 'eligible')
@Issue(3242)
@SkipUnless(server_has_mergeinfo)
def recursive_mergeinfo(sbox):
"test svn mergeinfo -R"
sbox.build()
wc_dir = sbox.wc_dir
expected_disk, expected_status = set_up_branch(sbox)
A_path = os.path.join(wc_dir, "A")
A_COPY_path = os.path.join(wc_dir, "A_COPY")
B_COPY_path = os.path.join(wc_dir, "A_COPY", "B")
C_COPY_path = os.path.join(wc_dir, "A_COPY", "C")
rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho")
H_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H")
F_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F")
omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega")
beta_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "beta")
A2_path = os.path.join(wc_dir, "A2")
nu_path = os.path.join(wc_dir, "A2", "B", "F", "nu")
nu_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F", "nu")
nu2_path = os.path.join(wc_dir, "A2", "C", "nu2")
svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], 'up', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'ren', A_path, A2_path)
svntest.actions.run_and_verify_svn(None, None, [],
'ci', wc_dir, '-m', 'rename A to A2')
svntest.main.file_write(nu_path, "A new file.\n")
svntest.main.file_write(nu2_path, "Another new file.\n")
svntest.main.run_svn(None, "add", nu_path, nu2_path)
svntest.actions.run_and_verify_svn(None, None, [],
'ci', wc_dir, '-m', 'Add 2 new files')
svntest.actions.run_and_verify_svn(None, exp_noop_up_out(8), [], 'up',
wc_dir)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[4]], ' U ' + A_COPY_path + '\n'),
[], 'merge', '-c4', '--depth', 'empty',
sbox.repo_url + '/A2',
A_COPY_path)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[6]],
['U ' + omega_COPY_path + '\n',
' G ' + H_COPY_path + '\n']),
[], 'merge', '-c6',
sbox.repo_url + '/A2/D/H',
H_COPY_path)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[5]],
['U ' + beta_COPY_path + '\n',
' G ' + A_COPY_path + '\n',
' G ' + B_COPY_path + '\n',
' U ' + B_COPY_path + '\n',], elides=True),
[], 'merge', '-c5',
sbox.repo_url + '/A2',
A_COPY_path)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[-5]],
' G ' + C_COPY_path + '\n'),
[], 'merge', '-c-5',
sbox.repo_url + '/A2/C', C_COPY_path)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[8]],
['A ' + nu_COPY_path + '\n',
' G ' + F_COPY_path + '\n']),
[], 'merge', '-c8',
sbox.repo_url + '/A2/B/F',
F_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'ci', wc_dir, '-m', 'Many merges')
svntest.actions.run_and_verify_svn(None, exp_noop_up_out(9), [], 'up',
wc_dir)
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['3', '4*', '8*'],
sbox.repo_url + '/A2',
sbox.repo_url + '/A_COPY',
'--show-revs', 'eligible', '-R')
svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
['4*', '5', '6', '8*'],
A2_path,
A_COPY_path,
'--show-revs', 'merged',
'--depth', 'infinity')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''), ['6'],
sbox.repo_url + '/A2/D/H',
sbox.repo_url + '/A_COPY/D/H',
'--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''), ['6'],
sbox.repo_url + '/A2/D/H/omega',
sbox.repo_url + '/A_COPY/D/H/omega',
'--show-revs', 'merged')
@SkipUnless(server_has_mergeinfo)
def mergeinfo_on_pegged_wc_path(sbox):
"svn mergeinfo on pegged working copy target"
sbox.build()
wc_dir = sbox.wc_dir
expected_disk, expected_status = set_up_branch(sbox)
A_path = os.path.join(wc_dir, "A")
A_COPY_path = os.path.join(wc_dir, "A_COPY")
psi_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "psi")
omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega")
beta_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "beta")
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[3],[6]],
['U ' + psi_COPY_path + '\n',
'U ' + omega_COPY_path + '\n',
' U ' + A_COPY_path + '\n',
' G ' + A_COPY_path + '\n',]),
[], 'merge', '-c3,6', sbox.repo_url + '/A', A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'ci', wc_dir,
'-m', 'Merge r3 and r6')
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[5]],
['U ' + beta_COPY_path + '\n',
' U ' + A_COPY_path + '\n']),
[], 'merge', '-c5', '--allow-mixed-revisions',
sbox.repo_url + '/A', A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'ci', wc_dir,
'-m', 'Merge r5')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version('.*No such revision 99'),
[], A_path, A_COPY_path + '@99', '--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['3','5','6'], A_path, A_COPY_path + '@BASE', '--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['3','5','6'], A_path, A_COPY_path + '@HEAD', '--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
[], A_path, A_COPY_path + '@4', '--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['3','5','6'], A_path, A_COPY_path + '@COMMITTED', '--show-revs',
'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['3', '6'], A_path, A_COPY_path + '@PREV', '--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4'], A_path, A_COPY_path + '@BASE', '--show-revs', 'eligible')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4'], A_path, A_COPY_path + '@HEAD', '--show-revs', 'eligible')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['3', '4', '5', '6'], A_path, A_COPY_path + '@4', '--show-revs', 'eligible')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4'], A_path, A_COPY_path + '@COMMITTED', '--show-revs',
'eligible')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4', '5'], A_path, A_COPY_path + '@PREV', '--show-revs', 'eligible')
@Issue(3986)
@SkipUnless(server_has_mergeinfo)
def wc_target_inherits_mergeinfo_from_repos(sbox):
"wc target inherits mergeinfo from repos"
sbox.build()
wc_dir = sbox.wc_dir
wc_disk, wc_status = set_up_branch(sbox, nbr_of_branches=2)
A_COPY_path = os.path.join(wc_dir, 'A_COPY')
rho_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'G', 'rho')
gamma_2_path = os.path.join(wc_dir, 'A_COPY_2', 'D', 'gamma')
tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
D_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D')
svntest.actions.run_and_verify_svn(None, None, [], 'merge',
sbox.repo_url + '/A/D/G/rho',
rho_COPY_path, '-c5')
svntest.actions.run_and_verify_svn(None, None, [], 'merge',
sbox.repo_url + '/A',
A_COPY_path, '-c7')
svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
'Cherrypicks to branch subtree and root',
wc_dir)
subtree_wc = sbox.add_wc_path('D_COPY')
svntest.actions.run_and_verify_svn(None, None, [], 'co',
sbox.repo_url + '/A_COPY/D',
subtree_wc)
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4','5'], sbox.repo_url + '/A/D', subtree_wc,
'--show-revs', 'eligible')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4'], sbox.repo_url + '/A/D', subtree_wc,
'--show-revs', 'eligible', '-R')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['7'], sbox.repo_url + '/A/D', subtree_wc,
'--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['5','7'], sbox.repo_url + '/A/D', subtree_wc,
'--show-revs', 'merged', '-R')
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
svntest.main.file_write(gamma_2_path, "New content.\n")
svntest.main.file_write(tau_path, "New content.\n")
svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
'Make changes under both A and A_COPY_2',
wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'merge',
sbox.repo_url + '/A_COPY_2',
A_COPY_path, '-c9')
svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
'Merge r8 from A_COPY_2 to A_COPY',
wc_dir)
def test_svn_mergeinfo_4_way(wc_target):
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4','5','9'], sbox.repo_url + '/A/D', wc_target,
'--show-revs', 'eligible')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['4','9'], sbox.repo_url + '/A/D', wc_target,
'--show-revs', 'eligible', '-R')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['7'], sbox.repo_url + '/A/D', wc_target,
'--show-revs', 'merged')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['5','7'], sbox.repo_url + '/A/D', wc_target,
'--show-revs', 'merged', '-R')
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'up', subtree_wc)
test_svn_mergeinfo_4_way(D_COPY_path)
test_svn_mergeinfo_4_way(subtree_wc)
@Issue(3791)
@SkipUnless(server_has_mergeinfo)
def natural_history_is_not_eligible_nor_merged(sbox):
"natural history is not eligible nor merged"
sbox.build()
wc_dir = sbox.wc_dir
wc_disk, wc_status = set_up_branch(sbox)
nu_path = os.path.join(wc_dir, 'A', 'C', 'nu')
A_COPY_path = os.path.join(wc_dir, 'A_COPY')
nu_COPY_path = os.path.join(wc_dir, 'A_COPY', 'C', 'nu')
svntest.main.file_write(nu_path, "This is the file 'nu'.\n")
svntest.actions.run_and_verify_svn(None, None, [], 'add', nu_path)
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'Add a file', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'merge',
sbox.repo_url + '/A', A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'Add a file', wc_dir)
svntest.main.file_write(nu_path, "Modification to file 'nu'.\n")
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'Modify added file', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'merge',
sbox.repo_url + '/A/C/nu', nu_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'Add a file', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
[], sbox.repo_url + '/A',
A_COPY_path, '--show-revs', 'eligible', '-R')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['3','4','5','6','7','9'], sbox.repo_url + '/A',
A_COPY_path, '--show-revs', 'merged', '-R')
@Issue(4050)
@SkipUnless(server_has_mergeinfo)
def noninheritabled_mergeinfo_not_always_eligible(sbox):
"noninheritabled mergeinfo not always eligible"
sbox.build()
wc_dir = sbox.wc_dir
A_path = os.path.join(wc_dir, 'A')
branch_path = os.path.join(wc_dir, 'branch')
svntest.main.run_svn(None, 'copy', sbox.repo_url + '/A',
sbox.repo_url + '/branch', '-m', 'make a branch')
svntest.main.run_svn(None, 'ps', 'prop', 'val', A_path)
svntest.main.run_svn(None, 'commit', '-m', 'file edit', wc_dir)
svntest.main.run_svn(None, 'up', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'merge',
sbox.repo_url + '/A', branch_path,
'-c3', '--depth=empty')
svntest.main.run_svn(None, 'commit', '-m', 'shallow merge', wc_dir)
svntest.actions.run_and_verify_svn(None, ["/A:3*\n"], [],
'propget', SVN_PROP_MERGEINFO,
branch_path)
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
['3'], sbox.repo_url + '/A', sbox.repo_url + '/branch',
'--show-revs', 'merged', '-R')
svntest.actions.run_and_verify_mergeinfo(
adjust_error_for_server_version(''),
[], sbox.repo_url + '/A', sbox.repo_url + '/branch',
'--show-revs', 'eligible', '-R')
test_list = [ None,
no_mergeinfo,
mergeinfo,
explicit_mergeinfo_source,
mergeinfo_non_source,
mergeinfo_on_unknown_url,
non_inheritable_mergeinfo,
recursive_mergeinfo,
mergeinfo_on_pegged_wc_path,
wc_target_inherits_mergeinfo_from_repos,
natural_history_is_not_eligible_nor_merged,
noninheritabled_mergeinfo_not_always_eligible,
]
if __name__ == '__main__':
svntest.main.run_tests(test_list)