externals_tests.py [plain text]
import sys
import os
import re
import tempfile
import svntest
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
def externals_test_setup(sbox):
"""Set up a repository in which some directories have the externals property,
and set up another repository, referred to by some of those externals.
Both repositories contain greek trees with five revisions worth of
random changes, then in the sixth revision the first repository --
and only the first -- has some externals properties set. ### Later,
test putting externals on the second repository. ###
The arrangement of the externals in the first repository is:
/A/B/ ==> ^/A/D/gamma gamma
/A/C/ ==> exdir_G <scheme>:///<other_repos>/A/D/G
../../../<other_repos_basename>/A/D/H@1 exdir_H
/A/D/ ==> ^/../<other_repos_basename>/A exdir_A
//<other_repos>/A/D/G/ exdir_A/G/
exdir_A/H -r 1 <scheme>:///<other_repos>/A/D/H
/<some_paths>/A/B x/y/z/blah
A dictionary is returned keyed by the directory created by the
external whose value is the URL of the external.
"""
sbox.build(create_wc = False)
svntest.main.safe_rmtree(sbox.wc_dir)
wc_init_dir = sbox.add_wc_path('init') repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
other_repo_basename = os.path.basename(other_repo_dir)
scheme_relative_other_repo_url = other_repo_url[other_repo_url.find(':')+1:]
server_relative_other_repo_url = other_repo_url
for i in range(3):
j = server_relative_other_repo_url.find('/') + 1
server_relative_other_repo_url = server_relative_other_repo_url[j:]
server_relative_other_repo_url = '/' + server_relative_other_repo_url
mu_path = os.path.join(wc_init_dir, "A/mu")
pi_path = os.path.join(wc_init_dir, "A/D/G/pi")
lambda_path = os.path.join(wc_init_dir, "A/B/lambda")
omega_path = os.path.join(wc_init_dir, "A/D/H/omega")
B_path = os.path.join(wc_init_dir, "A/B")
C_path = os.path.join(wc_init_dir, "A/C")
D_path = os.path.join(wc_init_dir, "A/D")
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_init_dir)
svntest.main.file_append(mu_path, "Added to mu in revision 2.\n")
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'log msg',
'--quiet', wc_init_dir)
svntest.main.file_append(pi_path, "Added to pi in revision 3.\n")
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'log msg',
'--quiet', wc_init_dir)
svntest.main.file_append(lambda_path, "Added to lambda in revision 4.\n")
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'log msg',
'--quiet', wc_init_dir)
svntest.main.file_append(omega_path, "Added to omega in revision 5.\n")
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'log msg',
'--quiet', wc_init_dir)
expected_output = svntest.wc.State(wc_init_dir, {
})
svntest.actions.run_and_verify_update(wc_init_dir,
expected_output, None, None)
svntest.main.copy_repos(repo_dir, other_repo_dir, 5)
external_url_for = { }
external_url_for["A/B/gamma"] = "^/A/D/gamma"
external_url_for["A/C/exdir_G"] = other_repo_url + "/A/D/G"
external_url_for["A/C/exdir_H"] = "../../../" + \
other_repo_basename + \
"/A/D/H@1"
externals_desc = \
external_url_for["A/B/gamma"] + " gamma\n"
change_external(B_path, externals_desc, commit=False)
externals_desc = \
"exdir_G " + external_url_for["A/C/exdir_G"] + "\n" + \
external_url_for["A/C/exdir_H"] + " exdir_H\n"
change_external(C_path, externals_desc, commit=False)
external_url_for["A/D/exdir_A"] = "^/../" + other_repo_basename + "/A"
external_url_for["A/D/exdir_A/G/"] = scheme_relative_other_repo_url + \
"/A/D/G/"
external_url_for["A/D/exdir_A/H"] = other_repo_url + "/A/D/H"
external_url_for["A/D/x/y/z/blah"] = server_relative_other_repo_url + "/A/B"
externals_desc = \
external_url_for["A/D/exdir_A"] + " exdir_A" + \
"\n" + \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G/" + \
"\n" + \
"exdir_A/H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
external_url_for["A/D/x/y/z/blah"] + " x/y/z/blah" + \
"\n"
change_external(D_path, externals_desc, commit=False)
expected_output = svntest.wc.State(wc_init_dir, {
'A/B' : Item(verb='Sending'),
'A/C' : Item(verb='Sending'),
'A/D' : Item(verb='Sending'),
})
expected_status = svntest.actions.get_virginal_state(wc_init_dir, 5)
expected_status.tweak('A/B', 'A/C', 'A/D', wc_rev=6, status=' ')
svntest.actions.run_and_verify_commit(wc_init_dir,
expected_output,
expected_status,
None, wc_init_dir)
return external_url_for
def change_external(path, new_val, commit=True):
"""Change the value of the externals property on PATH to NEW_VAL,
and commit the change unless COMMIT is False."""
(fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
svntest.main.file_append(tmp_f, new_val)
svntest.actions.run_and_verify_svn(None, None, [], 'pset',
'-F', tmp_f, 'svn:externals', path)
if commit:
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'log msg', '--quiet', path)
os.close(fd)
os.remove(tmp_f)
def change_external_expect_error(path, new_val, expected_err):
"""Try to change the value of the externals property on PATH to NEW_VAL,
but expect to get an error message that matches EXPECTED_ERR."""
(fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
svntest.main.file_append(tmp_f, new_val)
svntest.actions.run_and_verify_svn(None, None, expected_err, 'pset',
'-F', tmp_f, 'svn:externals', path)
os.close(fd)
os.remove(tmp_f)
def probe_paths_exist(paths):
""" Probe each one of PATHS to see if it exists, otherwise throw a
Failure exception. """
for path in paths:
if not os.path.exists(path):
raise svntest.Failure("Probing for " + path + " failed.")
def probe_paths_missing(paths):
""" Probe each one of PATHS to see if does not exist, otherwise throw a
Failure exception. """
for path in paths:
if os.path.exists(path):
raise svntest.Failure(path + " unexpectedly still exists.")
def checkout_with_externals(sbox):
"test checkouts with externals"
externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
expected_existing_paths = [
os.path.join(wc_dir, "A", "B", "gamma"),
os.path.join(wc_dir, "A", "C", "exdir_G"),
os.path.join(wc_dir, "A", "C", "exdir_G", "pi"),
os.path.join(wc_dir, "A", "C", "exdir_H"),
os.path.join(wc_dir, "A", "C", "exdir_H", "omega"),
os.path.join(wc_dir, "A", "D", "x"),
os.path.join(wc_dir, "A", "D", "x", "y"),
os.path.join(wc_dir, "A", "D", "x", "y", "z"),
os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah"),
os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "alpha"),
os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "beta"),
]
probe_paths_exist(expected_existing_paths)
for path, contents in ((os.path.join(wc_dir, "A", "C", "exdir_H", "omega"),
"This is the file 'omega'.\n"),
(os.path.join(wc_dir, "A", "B", "gamma"),
"This is the file 'gamma'.\n")):
if open(path).read() != contents:
raise svntest.Failure("Unexpected contents for rev 1 of " + path)
def update_receive_new_external(sbox):
"update to receive a new external module"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
other_wc_dir = sbox.add_wc_path('other')
repo_url = sbox.repo_url
other_repo_url = repo_url + ".other"
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, other_wc_dir)
new_externals_desc = \
external_url_for["A/D/exdir_A"] + " exdir_A" + \
"\n" + \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G/" + \
"\n" + \
"exdir_E " + other_repo_url + "/A/B/E" + \
"\n" + \
"exdir_A/H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
external_url_for["A/D/x/y/z/blah"] + " x/y/z/blah" + \
"\n"
change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
expected_output = svntest.wc.State(other_wc_dir, {
'A/D' : Item(status=' U'),
'A/D/exdir_E/beta' : Item(status='A '),
'A/D/exdir_E/alpha' : Item(status='A '),
})
svntest.actions.run_and_verify_update(other_wc_dir,
expected_output, None, None)
probe_paths_exist([os.path.join(other_wc_dir, "A", "D", "exdir_E")])
def update_lose_external(sbox):
"update to lose an external module"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
other_wc_dir = sbox.add_wc_path('other')
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, other_wc_dir)
new_externals_desc = \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G" + \
"\n" + \
"exdir_A/H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
external_url_for["A/D/x/y/z/blah"] + " x/y/z/blah" + \
"\n"
change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
svntest.main.safe_rmtree(os.path.join(other_wc_dir, "A", "D", "exdir_A", \
"D"))
expected_output = svntest.wc.State(other_wc_dir, {
'A/D' : Item(status=' U'),
'A/D/exdir_A' : Item(verb='Removed external'),
})
svntest.actions.run_and_verify_update(other_wc_dir,
expected_output, None, None)
expected_existing_paths = [
os.path.join(other_wc_dir, "A", "D", "exdir_A"),
os.path.join(other_wc_dir, "A", "D", "exdir_A", "G"),
os.path.join(other_wc_dir, "A", "D", "exdir_A", "H"),
]
probe_paths_exist(expected_existing_paths)
expected_missing_paths = [
os.path.join(other_wc_dir, "A", "D", "exdir_A", "mu"),
os.path.join(other_wc_dir, "A", "D", "exdir_A", "B"),
os.path.join(other_wc_dir, "A", "D", "exdir_A", "C"),
os.path.join(other_wc_dir, "A", "D", "exdir_A", "D"),
]
probe_paths_missing(expected_missing_paths)
def update_change_pristine_external(sbox):
"update change to an unmodified external module"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
other_wc_dir = sbox.add_wc_path('other')
repo_url = sbox.repo_url
other_repo_url = repo_url + ".other"
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, other_wc_dir)
new_externals_desc = \
external_url_for["A/D/exdir_A"] + " exdir_A" + \
"\n" + \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G" + \
"\n" + \
"exdir_A/H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
"x/y/z/blah " + other_repo_url + "/A/B/F" + \
"\n"
change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
expected_output = svntest.wc.State(other_wc_dir, {
'A/D' : Item(status=' U'),
'A/D/x/y/z/blah/F' : Item(status='D '),
'A/D/x/y/z/blah/E' : Item(status='D '),
'A/D/x/y/z/blah/lambda': Item(status='D '),
})
svntest.actions.run_and_verify_update(other_wc_dir,
expected_output, None, None)
xyzb_path = os.path.join(other_wc_dir, "x", "y", "z", "blah")
expected_missing_paths = [
os.path.join(xyzb_path, "alpha"),
os.path.join(xyzb_path, "beta"),
]
probe_paths_missing(expected_missing_paths)
def update_change_modified_external(sbox):
"update changes to a modified external module"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
other_wc_dir = sbox.add_wc_path('other')
repo_url = sbox.repo_url
other_repo_url = repo_url + ".other"
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, other_wc_dir)
alpha_path = os.path.join(other_wc_dir, "A", "D",
"x", "y", "z", "blah", "alpha")
svntest.main.file_append(alpha_path, "Some new text in alpha.\n")
new_file = os.path.join(other_wc_dir, "A", "D",
"x", "y", "z", "blah", "fish.txt")
svntest.main.file_append(new_file, "This is an unversioned file.\n")
new_externals_desc = \
external_url_for["A/D/exdir_A"] + " exdir_A" + \
"\n" + \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G/" + \
"\n" + \
"exdir_A/H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
"x/y/z/blah " + other_repo_url + "/A/B/F" + \
"\n"
change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
expected_output = svntest.wc.State(other_wc_dir, {
'A/D' : Item(status=' U'),
'A/D/x/y/z/blah/F' : Item(status='D '),
'A/D/x/y/z/blah/lambda': Item(status='D '),
'A/D/x/y/z/blah/E' : Item(status='D '),
})
svntest.actions.run_and_verify_update(other_wc_dir,
expected_output, None, None)
xyzb_path = os.path.join(other_wc_dir, "x", "y", "z", "blah")
expected_missing_paths = [
os.path.join(xyzb_path, "alpha"),
os.path.join(xyzb_path, "beta"),
]
probe_paths_missing(expected_missing_paths)
def update_receive_change_under_external(sbox):
"update changes under an external module"
externals_test_setup(sbox)
wc_dir = sbox.wc_dir
other_wc_dir = sbox.add_wc_path('other')
repo_url = sbox.repo_url
other_repo_url = repo_url + ".other"
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
other_repo_url, other_wc_dir)
other_gamma_path = os.path.join(other_wc_dir, 'A', 'D', 'gamma')
svntest.main.file_append(other_gamma_path, "New text in other gamma.\n")
expected_output = svntest.wc.State(other_wc_dir, {
'A/D/gamma' : Item(verb='Sending'),
})
expected_status = svntest.actions.get_virginal_state(other_wc_dir, 5)
expected_status.tweak('A/D/gamma', wc_rev=6)
svntest.actions.run_and_verify_commit(other_wc_dir,
expected_output,
expected_status,
None, other_wc_dir)
expected_output = svntest.wc.State(wc_dir, {
'A/D/exdir_A/D/gamma': Item(status='U '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
external_gamma_path = os.path.join(wc_dir, 'A', 'D', 'exdir_A', 'D', 'gamma')
contents = open(external_gamma_path).read()
if contents != ("This is the file 'gamma'.\n"
"New text in other gamma.\n"):
raise svntest.Failure("Unexpected contents for externally modified " +
external_gamma_path)
other_rho_path = os.path.join(other_wc_dir, 'A', 'D', 'G', 'rho')
svntest.main.file_append(other_rho_path, "New text in other rho.\n")
expected_output = svntest.wc.State(other_wc_dir, {
'A/D/G/rho' : Item(verb='Sending'),
})
expected_status = svntest.actions.get_virginal_state(other_wc_dir, 5)
expected_status.tweak('A/D/gamma', wc_rev=6)
expected_status.tweak('A/D/G/rho', wc_rev=7)
svntest.actions.run_and_verify_commit(other_wc_dir,
expected_output,
expected_status,
None, other_wc_dir)
expected_output = svntest.wc.State(sbox.ospath('A/C'), {
'exdir_G/rho' : Item(status='U '),
})
svntest.actions.run_and_verify_update(sbox.ospath('A/C'),
expected_output, None, None)
external_rho_path = os.path.join(wc_dir, 'A', 'C', 'exdir_G', 'rho')
contents = open(external_rho_path).read()
if contents != ("This is the file 'rho'.\n"
"New text in other rho.\n"):
raise svntest.Failure("Unexpected contents for externally modified " +
external_rho_path)
def modify_and_update_receive_new_external(sbox):
"commit and update additional externals"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
B_path = os.path.join(wc_dir, "A/B")
externals_desc = \
external_url_for["A/D/exdir_A/G/"] + " exdir_G" + \
"\n" + \
"exdir_H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
"exdir_Z " + external_url_for["A/D/exdir_A/H"] + \
"\n"
change_external(B_path, externals_desc)
was_cwd = os.getcwd()
os.chdir(B_path)
svntest.actions.run_and_verify_svn("update failed",
svntest.verify.AnyOutput, [], 'up' )
os.chdir(was_cwd)
probe_paths_exist([os.path.join(B_path, "exdir_Z")])
def disallow_dot_or_dotdot_directory_reference(sbox):
"error if external target dir involves '.' or '..'"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
def set_externals_for_path_expect_error(path, val):
expected_err = ".*Invalid svn:externals property on '.*': target " + \
"'.*' is an absolute path or involves '..'.*"
change_external_expect_error(path, val, expected_err)
B_path = os.path.join(wc_dir, 'A', 'B')
G_path = os.path.join(wc_dir, 'A', 'D', 'G')
H_path = os.path.join(wc_dir, 'A', 'D', 'H')
C_path = os.path.join(wc_dir, 'A', 'C')
F_path = os.path.join(wc_dir, 'A', 'B', 'F')
external_urls = list(external_url_for.values())
externals_value_1 = external_urls.pop() + " ../foo\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_2 = external_urls.pop() + " foo/bar/../baz\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_3 = external_urls.pop() + " foo/..\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_4 = external_urls.pop() + " .\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_5 = external_urls.pop() + " ./\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_6 = external_urls.pop() + " ..\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_7 = external_urls.pop() + " ././/.///. \n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_8 = external_urls.pop() + " /foo \n"
if not external_urls: external_urls = list(external_url_for.values())
if svntest.main.is_os_windows():
externals_value_9 = external_urls.pop() + " D:/foo\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_10 = external_urls.pop() + " D:\\foo\n"
if not external_urls: external_urls = list(external_url_for.values())
externals_value_11 = external_urls.pop() + " D:foo\n"
if not external_urls: external_urls = list(external_url_for.values())
set_externals_for_path_expect_error(B_path, externals_value_1)
set_externals_for_path_expect_error(G_path, externals_value_2)
set_externals_for_path_expect_error(H_path, externals_value_3)
set_externals_for_path_expect_error(C_path, externals_value_4)
set_externals_for_path_expect_error(F_path, externals_value_5)
set_externals_for_path_expect_error(B_path, externals_value_6)
set_externals_for_path_expect_error(G_path, externals_value_7)
set_externals_for_path_expect_error(H_path, externals_value_8)
if svntest.main.is_os_windows():
set_externals_for_path_expect_error(B_path, externals_value_9)
set_externals_for_path_expect_error(B_path, externals_value_10)
set_externals_for_path_expect_error(B_path, externals_value_11)
def export_with_externals(sbox):
"test exports with externals"
externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'export',
repo_url, wc_dir)
expected_existing_paths = [
os.path.join(wc_dir, "A", "C", "exdir_G"),
os.path.join(wc_dir, "A", "C", "exdir_G", "pi"),
os.path.join(wc_dir, "A", "C", "exdir_H"),
os.path.join(wc_dir, "A", "C", "exdir_H", "omega"),
os.path.join(wc_dir, "A", "D", "x"),
os.path.join(wc_dir, "A", "D", "x", "y"),
os.path.join(wc_dir, "A", "D", "x", "y", "z"),
os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah"),
os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "alpha"),
os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "beta"),
]
probe_paths_exist(expected_existing_paths)
exdir_G_pi_path = os.path.join(wc_dir, "A", "C", "exdir_G", "pi")
contents = open(exdir_G_pi_path).read()
if contents != ("This is the file 'pi'.\n"
"Added to pi in revision 3.\n"):
raise svntest.Failure("Unexpected contents for rev 1 of " +
exdir_G_pi_path)
exdir_H_omega_path = os.path.join(wc_dir, "A", "C", "exdir_H", "omega")
contents = open(exdir_H_omega_path).read()
if contents != "This is the file 'omega'.\n":
raise svntest.Failure("Unexpected contents for rev 1 of " +
exdir_H_omega_path)
@Issue(2429)
def export_wc_with_externals(sbox):
"test exports from working copies with externals"
paths_dict = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
export_target = sbox.add_wc_path('export')
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'export', wc_dir, export_target)
paths = [
os.path.join(export_target, "A", "C", "exdir_G"),
os.path.join(export_target, "A", "C", "exdir_G", "pi"),
os.path.join(export_target, "A", "C", "exdir_H"),
os.path.join(export_target, "A", "C", "exdir_H", "omega"),
os.path.join(export_target, "A", "D", "x"),
os.path.join(export_target, "A", "D", "x", "y"),
os.path.join(export_target, "A", "D", "x", "y", "z"),
os.path.join(export_target, "A", "D", "x", "y", "z", "blah"),
os.path.join(export_target, "A", "D", "x", "y", "z", "blah", "E", "alpha"),
os.path.join(export_target, "A", "D", "x", "y", "z", "blah", "E", "beta"),
]
probe_paths_exist(paths)
svntest.main.safe_rmtree(export_target)
svntest.actions.run_and_verify_svn(None, None, [],
'export', '--ignore-externals',
wc_dir, export_target)
probe_paths_missing(paths)
def external_with_peg_and_op_revision(sbox):
"use a peg revision to specify an external module"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'rm',
external_url_for["A/D/exdir_A/H"],
'-m', 'remove original A/D/H')
new_externals_desc = \
external_url_for["A/D/exdir_A/H"] + "@4 exdir_A/H" + \
"\n" + \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G" + \
"\n"
change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
expected_output = svntest.wc.State(wc_dir, {
'A/D/x/y/z/blah' : Item(verb='Removed external'),
'A/D/exdir_A' : Item(verb='Removed external'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
external_chi_path = os.path.join(wc_dir, 'A', 'D', 'exdir_A', 'H', 'chi')
contents = open(external_chi_path).read()
if contents != "This is the file 'chi'.\n":
raise svntest.Failure("Unexpected contents for externally modified " +
external_chi_path)
def new_style_externals(sbox):
"check the new '-rN URL PATH' syntax"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
new_externals_desc = \
external_url_for["A/C/exdir_G"] + " exdir_G" + \
"\n" + \
"-r 1 " + external_url_for["A/C/exdir_H"] + " exdir_H" + \
"\n" + \
"-r1 " + external_url_for["A/C/exdir_H"] + " exdir_I" + \
"\n"
change_external(os.path.join(wc_dir, "A/C"), new_externals_desc)
expected_output = svntest.wc.State(wc_dir, {
'A/C/exdir_I/chi' : Item(status='A '),
'A/C/exdir_I/omega' : Item(status='A '),
'A/C/exdir_I/psi' : Item(status='A '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
for dir_name in ["exdir_H", "exdir_I"]:
exdir_X_omega_path = os.path.join(wc_dir, "A", "C", dir_name, "omega")
contents = open(exdir_X_omega_path).read()
if contents != "This is the file 'omega'.\n":
raise svntest.Failure("Unexpected contents for rev 1 of " +
exdir_X_omega_path)
def disallow_propset_invalid_formatted_externals(sbox):
"error if propset'ing external with invalid format"
sbox.build()
wc_dir = sbox.wc_dir
A_path = os.path.join(wc_dir, 'A')
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
svntest.actions.run_and_verify_status(wc_dir, expected_status)
for ext in [ 'arg1',
'arg1 arg2 arg3',
'arg1 arg2 arg3 arg4',
'arg1 arg2 arg3 arg4 arg5',
'-r',
'-r1',
'-r 1',
'-r1 arg1',
'-r 1 arg1',
'arg1 -r',
'arg1 -r1',
'arg1 -r 1',
]:
change_external_expect_error(A_path, ext,
'.*Error parsing svn:externals.*')
for ext in [ '-r abc arg1 arg2',
'-rabc arg1 arg2',
'arg1 -r abc arg2',
'arg1 -rabc arg2',
]:
change_external_expect_error(A_path, ext,
'.*Error parsing svn:externals.*')
for ext in [ 'http://example.com/ http://example.com/',
'-r1 http://example.com/ http://example.com/',
'-r 1 http://example.com/ http://example.com/',
'http://example.com/ -r1 http://example.com/',
'http://example.com/ -r 1 http://example.com/',
]:
change_external_expect_error(A_path, ext,
'.*cannot use two absolute URLs.*')
for ext in [ 'http://example.com/ -r1 foo',
'http://example.com/ -r 1 foo',
'-r1 foo http://example.com/',
'-r 1 foo http://example.com/'
]:
change_external_expect_error(A_path, ext,
'.*cannot use a URL \'.*\' as the ' \
'target directory for an external ' \
'definition.*')
def old_style_externals_ignore_peg_reg(sbox):
"old 'PATH URL' format should ignore peg revisions"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
expected_output = svntest.wc.State(wc_dir, {
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
ext = "exdir_G " + external_url_for["A/C/exdir_G"] + "@HEAD\n"
change_external(os.path.join(wc_dir, "A"), ext)
expected_error = "|".join([".*Error handling externals definition.*",
".*URL .*/A/D/G@HEAD' .* doesn't exist.*",
])
svntest.actions.run_and_verify_svn2("External '%s' used pegs" % ext.strip(),
None,
expected_error,
1,
'up',
wc_dir)
def cannot_move_or_remove_file_externals(sbox):
"should not be able to mv or rm a file external"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn("Able to delete file external",
None,
".*Cannot remove the external at "
".*gamma.*; please .* "
"the svn:externals .*",
'rm',
os.path.join(wc_dir, 'A', 'B', 'gamma'))
svntest.actions.run_and_verify_svn("Able to move file external",
None,
".*Cannot move the external at "
".*gamma.*; please .*edit.*"
"svn:externals.*",
'mv',
os.path.join(wc_dir, 'A', 'B', 'gamma'),
os.path.join(wc_dir, 'A', 'B', 'gamma1'))
expected_status = svntest.actions.get_virginal_state(wc_dir, 6)
svntest.actions.run_and_verify_svn(None, None, [],
'rm',
os.path.join(wc_dir, "A", "B"))
expected_status.tweak('A/B', status='D ')
expected_output = svntest.wc.State(wc_dir, {
'A/B' : Item(verb='Deleting'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 6)
expected_status.remove('A/B', 'A/B/E', 'A/B/E/alpha', 'A/B/E/beta',
'A/B/F', 'A/B/lambda')
expected_status.add({
'A/D/exdir_A' : Item(status='X '),
'A/D/x' : Item(status='X '),
'A/C/exdir_H' : Item(status='X '),
'A/C/exdir_G' : Item(status='X '),
})
svntest.actions.run_and_verify_commit(wc_dir,
expected_output, expected_status,
None, wc_dir)
expected_output = svntest.wc.State(wc_dir, {
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
open(os.path.join(wc_dir, 'A', 'D', 'gamma')).close()
def cant_place_file_external_into_dir_external(sbox):
"place a file external into a directory external"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
other_repo_url = repo_url + ".other"
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
ext = "^/A/D A/D-copy\n" + \
"^/A/B/E/beta A/D-copy/G/beta\n"
change_external(wc_dir, ext)
svntest.actions.run_and_verify_svn(None, None, 'svn: E205011: ' +
'Failure occurred.*definitions',
'up', wc_dir)
@Issue(2461)
def external_into_path_with_spaces(sbox):
"allow spaces in external local paths"
sbox.build()
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
ext = '^/A/D "A/copy of D"\n' +\
'^/A/D A/another\ copy\ of\ D'
change_external(wc_dir, ext)
expected_output = svntest.wc.State(wc_dir, {
'A/another copy of D/G': Item(status='A '),
'A/another copy of D/G/pi': Item(status='A '),
'A/another copy of D/G/tau': Item(status='A '),
'A/another copy of D/G/rho': Item(status='A '),
'A/another copy of D/H': Item(status='A '),
'A/another copy of D/H/chi': Item(status='A '),
'A/another copy of D/H/omega': Item(status='A '),
'A/another copy of D/H/psi': Item(status='A '),
'A/another copy of D/gamma': Item(status='A '),
'A/copy of D/H' : Item(status='A '),
'A/copy of D/H/chi' : Item(status='A '),
'A/copy of D/H/omega': Item(status='A '),
'A/copy of D/H/psi' : Item(status='A '),
'A/copy of D/gamma' : Item(status='A '),
'A/copy of D/G' : Item(status='A '),
'A/copy of D/G/rho' : Item(status='A '),
'A/copy of D/G/tau' : Item(status='A '),
'A/copy of D/G/pi' : Item(status='A '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
probe_paths_exist([
os.path.join(wc_dir, 'A', 'copy of D'),
os.path.join(wc_dir, 'A', 'another copy of D'),
])
@Issue(3368)
def binary_file_externals(sbox):
"binary file externals"
sbox.build()
wc_dir = sbox.wc_dir
theta_contents = open(os.path.join(sys.path[0], "theta.bin"), 'rb').read()
theta_path = os.path.join(wc_dir, 'A', 'theta')
svntest.main.file_write(theta_path, theta_contents, 'wb')
svntest.main.run_svn(None, 'add', theta_path)
expected_output = svntest.wc.State(wc_dir, {
'A/theta' : Item(verb='Adding (bin)'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.add({
'A/theta' : Item(status=' ', wc_rev=2),
})
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
expected_status, None, wc_dir)
C = os.path.join(wc_dir, 'A', 'C')
external = os.path.join(C, 'external')
externals_prop = "^/A/theta external\n"
change_external(C, externals_prop)
expected_output = svntest.wc.State(wc_dir, {
'A/C/external' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'A/theta' : Item(
theta_contents,
props={'svn:mime-type' : 'application/octet-stream'}),
'A/C' : Item(props={'svn:externals':externals_prop}),
'A/C/external' : Item(
theta_contents,
props={'svn:mime-type' : 'application/octet-stream'}),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
expected_status.add({
'A/theta' : Item(status=' ', wc_rev=3),
'A/C/external' : Item(status=' ', wc_rev=3, switched='X'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
@Issue(3351)
def update_lose_file_external(sbox):
"delete a file external"
sbox.build()
wc_dir = sbox.wc_dir
C = os.path.join(wc_dir, 'A', 'C')
external = os.path.join(C, 'external')
externals_prop = "^/A/mu external\n"
change_external(C, externals_prop)
expected_output = svntest.wc.State(wc_dir, {
'A/C/external' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'A/C' : Item(props={'svn:externals':externals_prop}),
'A/C/external' : Item("This is the file 'mu'.\n"),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.add({
'A/C/external' : Item(status=' ', wc_rev='2', switched='X'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
svntest.actions.run_and_verify_svn(None, None, [],
'propdel', 'svn:externals', C)
expected_output = svntest.wc.State(wc_dir, {
'A/C' : Item(verb='Sending'),
})
expected_status.tweak('A/C', wc_rev = 3)
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
expected_status, None, wc_dir)
expected_output = svntest.wc.State(wc_dir, {
'A/C/external' : Item(verb='Removed external')
})
expected_disk.tweak('A/C', props = {})
expected_disk.remove('A/C/external')
expected_status.tweak(wc_rev = 3)
expected_status.remove('A/C/external')
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
probe_paths_missing([os.path.join(wc_dir, 'A', 'C', 'external')])
@Issue(3351)
def switch_relative_external(sbox):
"switch a relative external"
sbox.build()
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
A_path = os.path.join(wc_dir, 'A')
A_copy_path = os.path.join(wc_dir, 'A_copy')
A_copy_url = repo_url + '/A_copy'
D_path = os.path.join(A_path, 'D')
ext_path = os.path.join(D_path, 'ext')
externals_prop = "../B ext\n"
change_external(D_path, externals_prop)
expected_output = svntest.wc.State(wc_dir, {
'A/D/ext/E' : Item(status='A '),
'A/D/ext/E/beta' : Item(status='A '),
'A/D/ext/E/alpha' : Item(status='A '),
'A/D/ext/F' : Item(status='A '),
'A/D/ext/lambda' : Item(status='A '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
svntest.actions.run_and_verify_svn(None, None, [], 'cp',
'--quiet', A_path, A_copy_path)
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'log msg',
'--quiet', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'sw',
A_copy_url, A_path)
expected_infos = [
{ 'Path' : re.escape(D_path),
'URL' : sbox.repo_url + '/A_copy/D',
},
{ 'Path' : re.escape(ext_path),
'URL' : sbox.repo_url + '/A_copy/B',
},
]
svntest.actions.run_and_verify_info(expected_infos, D_path, ext_path)
def export_sparse_wc_with_externals(sbox):
"export from a sparse working copy with externals"
externals_test_setup(sbox)
repo_url = sbox.repo_url + '/A/B'
wc_dir = sbox.wc_dir
children = [ 'E', 'F', 'lambda' ]
ext_children = [ 'gamma' ]
def wc_paths_of(relative_paths):
return [ os.path.join(wc_dir, path) for path in relative_paths ]
child_paths = wc_paths_of(children)
ext_child_paths = wc_paths_of(ext_children)
export_target = sbox.add_wc_path('export')
svntest.actions.run_and_verify_svn(None, None, [],
'checkout', '--depth=empty',
repo_url, wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'update', *child_paths)
svntest.actions.run_and_verify_svn(None, None, [],
'export', wc_dir, export_target)
svntest.main.safe_rmtree(export_target)
def relegate_external(sbox):
"relegate external from one repo to another"
sbox.build()
wc_dir = sbox.wc_dir
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
A_path = os.path.join(wc_dir, 'A')
externals_desc = '^/A/B/E external'
change_external(A_path, externals_desc)
expected_output = svntest.wc.State(wc_dir, {
'A/external/alpha' : Item(status='A '),
'A/external/beta' : Item(status='A '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
other_repo_dir, other_repo_url = sbox.add_repo_path('other')
svntest.main.copy_repos(repo_dir, other_repo_dir, 2)
externals_desc = other_repo_url + '/A/B/E external\n'
change_external(A_path, externals_desc)
expected_output = svntest.wc.State(wc_dir, {
'A/external' : Item(), 'A/external/alpha' : Item(status='A '),
'A/external/beta' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('A', props={'svn:externals' : externals_desc})
expected_disk.add({
'A/external' : Item(),
'A/external/alpha' : Item('This is the file \'alpha\'.\n'),
'A/external/beta' : Item('This is the file \'beta\'.\n'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
expected_status.add({
'A/external' : Item(status='X '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
@Issue(3552)
def wc_repos_file_externals(sbox):
"tag directory with file externals from wc to url"
sbox.build()
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
theta_path = os.path.join(wc_dir, 'A', 'theta')
svntest.main.file_write(theta_path, 'theta', 'w')
svntest.main.run_svn(None, 'add', theta_path)
expected_output = svntest.wc.State(wc_dir, {
'A/theta' : Item(verb='Adding'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.add({
'A/theta' : Item(status=' ', wc_rev=2),
})
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
expected_status, None, wc_dir)
C = os.path.join(wc_dir, 'A', 'C')
external = os.path.join(C, 'theta')
externals_prop = "^/A/theta theta\n"
change_external(C, externals_prop)
expected_output = svntest.wc.State(wc_dir, {
'A/C/theta' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'A/theta' : Item('theta'),
'A/C' : Item(props={'svn:externals':externals_prop}),
'A/C/theta' : Item('theta'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
expected_status.add({
'A/theta' : Item(status=' ', wc_rev=3),
'A/C/theta' : Item(status=' ', wc_rev=3, switched='X'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
tag_url = repo_url + '/A/I'
svntest.main.run_svn(None, 'cp', C, tag_url, '-m', 'create tag')
expected_output = svntest.wc.State(wc_dir, {
'A/I' : Item(status='A '),
'A/I/theta' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'A/theta' : Item('theta'),
'A/C' : Item(props={'svn:externals':externals_prop}),
'A/C/theta' : Item('theta'),
'A/I' : Item(props={'svn:externals':externals_prop}),
'A/I/theta' : Item('theta'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 4)
expected_status.add({
'A/theta' : Item(status=' ', wc_rev=4),
'A/C/theta' : Item(status=' ', wc_rev=4, switched='X'),
'A/I' : Item(status=' ', wc_rev=4),
'A/I/theta' : Item(status=' ', wc_rev=4, switched='X'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
@Issue(3843)
def merge_target_with_externals(sbox):
"merge target with externals"
externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
A_path = os.path.join(wc_dir, "A")
A_branch_path = os.path.join(wc_dir, "A-branch")
A_gamma_branch_path = os.path.join(wc_dir, "A-branch", "D", "gamma")
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
externals_prop = "^/A/mu external\n^/A/mu@6 external-pinned\n"
change_external(sbox.ospath('A'), externals_prop)
svntest.actions.run_and_verify_svn(None, None, [], 'copy', A_path + '@1',
A_branch_path)
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'make a copy', wc_dir)
svntest.main.file_write(A_gamma_branch_path, "The new gamma!\n")
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'branch edit', wc_dir)
expected_output = svntest.wc.State(wc_dir, {
'A/external' : Item(status='A '),
'A/external-pinned' : Item(status='A '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
svntest.actions.run_and_verify_svn(None, None, [], 'merge', '-c8',
repo_url + '/A-branch', A_path)
svntest.actions.run_and_verify_svn(
"Unexpected subtree mergeinfo created",
["Properties on '" + A_path + "':\n",
" svn:mergeinfo\n",
" /A-branch:8\n"],
[], 'pg', svntest.main.SVN_PROP_MERGEINFO, '-vR', wc_dir)
def update_modify_file_external(sbox):
"update that modifies a file external"
sbox.build()
wc_dir = sbox.wc_dir
externals_prop = "^/A/mu external\n"
change_external(sbox.ospath('A'), externals_prop)
expected_output = svntest.wc.State(wc_dir, {
'A/external' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'A' : Item(props={'svn:externals':externals_prop}),
'A/external' : Item("This is the file 'mu'.\n"),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.add({
'A/external' : Item(status=' ', wc_rev='2', switched='X'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
svntest.main.file_append(sbox.ospath('A/mu'), 'appended mu text')
expected_output = svntest.wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
})
expected_status.tweak('A/mu', wc_rev=3)
svntest.actions.run_and_verify_commit(wc_dir,
expected_output,
expected_status,
None,
wc_dir)
expected_output = svntest.wc.State(wc_dir, {
'A/external' : Item(status='U '),
})
expected_disk.tweak('A/mu', 'A/external',
contents=expected_disk.desc['A/mu'].contents
+ 'appended mu text')
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
expected_status.add({
'A/external' : Item(status=' ', wc_rev='3', switched='X'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None, None, None,
True)
@Issue(2267)
def update_external_on_locally_added_dir(sbox):
"update an external on a locally added dir"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
other_repo_url = repo_url + ".other"
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
new_externals_desc = \
external_url_for["A/D/exdir_A"] + " exdir_A" + \
"\n" + \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G/" + \
"\n" + \
"exdir_E " + other_repo_url + "/A/B/E" + \
"\n" + \
"exdir_A/H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
external_url_for["A/D/x/y/z/blah"] + " x/y/z/blah" + \
"\n"
new_dir = sbox.ospath("A/foo")
sbox.simple_mkdir("A/foo")
change_external(new_dir, new_externals_desc, commit=False)
expected_output = svntest.wc.State(wc_dir, {
'A/foo/exdir_A/B' : Item(status='A '),
'A/foo/exdir_A/B/E' : Item(status='A '),
'A/foo/exdir_A/B/E/beta': Item(status='A '),
'A/foo/exdir_A/B/E/alpha': Item(status='A '),
'A/foo/exdir_A/B/F' : Item(status='A '),
'A/foo/exdir_A/B/lambda': Item(status='A '),
'A/foo/exdir_A/D' : Item(status='A '),
'A/foo/exdir_A/D/G' : Item(status='A '),
'A/foo/exdir_A/D/G/rho': Item(status='A '),
'A/foo/exdir_A/D/G/pi': Item(status='A '),
'A/foo/exdir_A/D/G/tau': Item(status='A '),
'A/foo/exdir_A/D/gamma': Item(status='A '),
'A/foo/exdir_A/D/H' : Item(status='A '),
'A/foo/exdir_A/D/H/chi': Item(status='A '),
'A/foo/exdir_A/D/H/omega': Item(status='A '),
'A/foo/exdir_A/D/H/psi': Item(status='A '),
'A/foo/exdir_A/C' : Item(status='A '),
'A/foo/exdir_A/mu' : Item(status='A '),
'A/foo/exdir_A/H/omega': Item(status='A '),
'A/foo/exdir_A/H/psi': Item(status='A '),
'A/foo/exdir_A/H/chi': Item(status='A '),
'A/foo/exdir_A/G/tau': Item(status='A '),
'A/foo/exdir_A/G/rho': Item(status='A '),
'A/foo/exdir_A/G/pi': Item(status='A '),
'A/foo/x/y/z/blah/F': Item(status='A '),
'A/foo/x/y/z/blah/E': Item(status='A '),
'A/foo/x/y/z/blah/E/beta': Item(status='A '),
'A/foo/x/y/z/blah/E/alpha': Item(status='A '),
'A/foo/x/y/z/blah/lambda': Item(status='A '),
'A/foo/exdir_E/beta': Item(status='A '),
'A/foo/exdir_E/alpha': Item(status='A '),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
probe_paths_exist([os.path.join(wc_dir, "A", "foo", "exdir_E")])
@Issue(2267)
def switch_external_on_locally_added_dir(sbox):
"switch an external on a locally added dir"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
other_repo_url = repo_url + ".other"
A_path = repo_url + "/A"
A_copy_path = repo_url + "/A_copy"
svntest.actions.run_and_verify_svn(None, None, [],
'copy',
A_path, A_copy_path,
'-m', 'Create branch of A')
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
A_path, wc_dir)
new_externals_desc = \
external_url_for["A/D/exdir_A"] + " exdir_A" + \
"\n" + \
external_url_for["A/D/exdir_A/G/"] + " exdir_A/G/" + \
"\n" + \
"exdir_E " + other_repo_url + "/A/B/E" + \
"\n" + \
"exdir_A/H -r 1 " + external_url_for["A/D/exdir_A/H"] + \
"\n" + \
external_url_for["A/D/x/y/z/blah"] + " x/y/z/blah" + \
"\n"
new_dir = sbox.ospath("foo")
sbox.simple_mkdir("foo")
change_external(new_dir, new_externals_desc, commit=False)
svntest.actions.run_and_verify_svn(None, None, [], 'sw', A_copy_path, wc_dir)
probe_paths_exist([os.path.join(wc_dir, "foo", "exdir_E")])
@Issue(3819)
def file_external_in_sibling(sbox):
"update a file external in sibling dir"
sbox.build()
wc_dir = sbox.wc_dir
externals_prop = "^/iota iota\n"
sbox.simple_mkdir("A2")
change_external(sbox.ospath('A2'), externals_prop)
sbox.simple_update()
os.chdir(sbox.ospath("A"))
svntest.actions.run_and_verify_svn(None,
svntest.actions.expected_noop_update_output(2),
[], 'update')
@Issue(3823)
def file_external_update_without_commit(sbox):
"update a file external without committing target"
sbox.build(read_only=True)
externals_prop = "^/iota iota\n"
sbox.simple_mkdir("A2")
change_external(sbox.ospath('A2'), externals_prop, commit=False)
sbox.simple_update()
def incoming_file_on_file_external(sbox):
"bring in a new file over a file external"
sbox.build()
repo_url = sbox.repo_url
wc_dir = sbox.wc_dir
change_external(sbox.wc_dir, "^/A/B/lambda ext\n")
sbox.simple_update()
svntest.main.run_svn(None, 'cp', repo_url + '/iota',
repo_url + '/ext', '-m', 'copied')
expected_output = svntest.wc.State(wc_dir, {
'ext' : Item(verb='Skipped'),
})
svntest.actions.run_and_verify_update(wc_dir, expected_output, None, None)
def incoming_file_external_on_file(sbox):
"bring in a new file external over a file"
sbox.build()
wc_dir = sbox.wc_dir
change_external(sbox.wc_dir, "^/A/B/lambda iota\n")
svntest.actions.run_and_verify_update(wc_dir, None, None, None,
'.*The file external.*overwrite.*')
def exclude_externals(sbox):
"try to exclude externals"
external_url_for = externals_test_setup(sbox)
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
repo_url, wc_dir)
svntest.actions.run_and_verify_update(sbox.ospath('A/B/gamma'),
None, None, None,
'.*Cannot exclude.*',
None, None, None, None, False,
'--set-depth', 'exclude',
sbox.ospath('A/B/gamma'))
svntest.actions.run_and_verify_update(sbox.ospath('A/C/exdir_G'),
None, None, None,
'.*Cannot exclude.*',
None, None, None, None, False,
'--set-depth', 'exclude',
sbox.ospath('A/C/exdir_G'))
expected_status = svntest.actions.get_virginal_state(wc_dir, 6)
expected_status.add({
'A/B/gamma' : Item(status=' ', wc_rev='6', switched='X'),
'A/C/exdir_H' : Item(status='X '),
'A/C/exdir_G' : Item(status='X '),
'A/D/exdir_A' : Item(status='X '),
'A/D/x' : Item(status='X '),
})
svntest.actions.run_and_verify_update(wc_dir,
None, None, expected_status, None,
None, None, None, None, False,
'--set-depth', 'infinity', wc_dir)
def file_externals_different_url(sbox):
"update file externals via different url"
sbox.build()
wc_dir = sbox.wc_dir
r1_url = sbox.repo_url
r2_dir, r2_url = sbox.add_repo_path('2')
svntest.main.copy_repos(sbox.repo_dir, r2_dir, 1, 0)
sbox.simple_propset('svn:externals',
'r1-e-1 ' + r1_url + '/iota\n' +
r1_url + '/iota r1-e-2\n' +
'r2-e-1 ' + r2_url + '/iota\n' +
r2_url + '/iota r2-e-2\n' +
'^/iota rr-e-1\n', '')
expected_output = svntest.wc.State(wc_dir, {
'r1-e-1' : Item(status='A '),
'r1-e-2' : Item(status='A '),
'r2-e-1' : Item(status='A '),
'r2-e-2' : Item(status='A '),
'rr-e-1' : Item(status='A '),
})
expected_status = actions.get_virginal_state(wc_dir, 1)
expected_status.tweak('', status=' M')
expected_status.add({
'r2-e-1' : Item(status=' ', wc_rev='1', switched='X'),
'r1-e-1' : Item(status=' ', wc_rev='1', switched='X'),
'r1-e-2' : Item(status=' ', wc_rev='1', switched='X'),
'rr-e-1' : Item(status=' ', wc_rev='1', switched='X'),
'r2-e-2' : Item(status=' ', wc_rev='1', switched='X'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None,
expected_status, None)
for e in ['r1-e-1', 'r1-e-2', 'r2-e-1', 'r2-e-2', 'rr-e-1']:
actions.run_and_verify_info([{'Repository Root' : r1_url}],
os.path.join(sbox.wc_dir, e))
svntest.actions.run_and_verify_svn(None, None, [],
'relocate', r1_url, r2_url, wc_dir)
expected_output = svntest.wc.State(wc_dir, {
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None,
expected_status, None)
for e in ['r1-e-1', 'r1-e-2', 'r2-e-1', 'r2-e-2', 'rr-e-1']:
actions.run_and_verify_info([{'Repository Root' : r2_url}],
os.path.join(sbox.wc_dir, e))
def file_external_in_unversioned(sbox):
"file external in unversioned dir"
sbox.build()
wc_dir = sbox.wc_dir
sbox.simple_propset('svn:externals', '^/A/mu X/mu', 'A')
expected_output = svntest.wc.State(wc_dir, {
'A/X/mu' : Item(status='A '),
})
svntest.actions.run_and_verify_update(wc_dir, expected_output, None, None)
svntest.actions.run_and_verify_svn(None, None, [], 'cleanup', wc_dir)
from svntest import verify, actions, main
@Issue(3589, 4000)
def copy_file_externals(sbox):
"a WC->WC copy should exclude file externals"
sbox.build()
wc_dir = sbox.wc_dir
X = os.path.join(wc_dir, 'X')
expected_stdout = ['A ' + X + '\n']
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'mkdir', X)
expected_stdout = ["property 'svn:externals' set on '" + X + "'\n"]
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
'svn:externals', '''
^/iota xiota
^/A/mu xmu
''', X)
X = os.path.join(wc_dir, 'X')
X_copy = os.path.join(wc_dir, 'X_copy')
X_xmu = os.path.join(wc_dir, 'X', 'xmu')
expected_output = svntest.wc.State(wc_dir, {
'X' : Item(verb='Adding'),
})
expected_status = actions.get_virginal_state(wc_dir, 1)
expected_status.add({
'X' : Item(status=' ', wc_rev='2'),
})
actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
None, wc_dir)
expected_output = svntest.wc.State(wc_dir, {
'X/xmu' : Item(status='A '),
'X/xiota' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'X' : Item(),
'X/xiota' : Item(contents="This is the file 'iota'.\n"),
'X/xmu' : Item(contents="This is the file 'mu'.\n"),
})
expected_status.add({
'X/xiota' : Item(status=' ', wc_rev='2', switched='X'),
'X/xmu' : Item(status=' ', wc_rev='2', switched='X'),
})
expected_status.tweak(wc_rev='2')
actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
expected_status, None, None, None, None, None, False, wc_dir)
main.file_append(X_xmu, 'mod\n')
expected_output = svntest.wc.State(wc_dir, {
'X/xmu' : Item(verb='Sending'),
})
expected_status.tweak('X/xmu', wc_rev='3')
actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
None, X_xmu)
expected_output = svntest.wc.State(wc_dir, {
'A/mu' : Item(status='U '),
})
expected_disk.tweak('A/mu', 'X/xmu',
contents="This is the file 'mu'.\nmod\n")
expected_status.tweak(wc_rev='3')
actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
expected_status, None, None, None, None, None, False, wc_dir)
expected_stdout = ['A ' + X_copy + '\n']
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'cp', X,
X_copy)
expected_output = svntest.wc.State(wc_dir, {
'X_copy' : Item(verb='Adding'),
})
expected_status.add({
'X_copy' : Item(status=' ', wc_rev='4'),
})
actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
None, wc_dir)
expected_disk.add({
'X_copy' : Item(),
})
expected_disk.tweak('X', 'X_copy',
props={'svn:externals' : '\n ^/iota xiota\n ^/A/mu xmu\n \n'})
actions.verify_disk(wc_dir, expected_disk, True)
expected_output = svntest.wc.State(wc_dir, {
'X_copy/xmu' : Item(status='A '),
'X_copy/xiota' : Item(status='A '),
})
expected_disk.add({
'X_copy/xmu' : Item(contents="This is the file 'mu'.\nmod\n"),
'X_copy/xiota' : Item(contents="This is the file 'iota'.\n"),
})
expected_status.add({
'X_copy/xmu' : Item(status=' ', wc_rev='4', switched='X'),
'X_copy/xiota' : Item(status=' ', wc_rev='4', switched='X'),
})
expected_status.tweak(wc_rev='4')
actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
expected_status, None, None, None, None, None, True, wc_dir)
@Issue(4093)
def remap_file_external_with_prop_del(sbox):
"file external remap segfaults due to deleted props"
sbox.build()
wc_dir = sbox.wc_dir
A_path = os.path.join(wc_dir, "A")
mu_path = os.path.join(wc_dir, "A", "mu")
svntest.actions.run_and_verify_svn(None, None, [],
'ps', 'propname', 'propval', mu_path)
svntest.actions.run_and_verify_svn(None, None, [],
'commit', '-m', 'New property on a file',
wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
externals_prop = "^/A/mu external\n"
change_external(A_path, externals_prop)
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
externals_prop = "^/iota external\n"
change_external(A_path, externals_prop)
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
@Issue(4053)
def dir_external_with_dash_r_only(sbox):
"whether '-r1 ^/A B' updates properly"
sbox.build()
wc_dir = sbox.wc_dir
url = sbox.repo_url
A_B_E_alpha = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
E_ext = os.path.join(wc_dir, 'E_ext')
main.file_write(A_B_E_alpha, 'newer alpha\n')
expected_output = svntest.wc.State(wc_dir, {
'A/B/E/alpha' : Item(verb='Sending'),
})
expected_status = actions.get_virginal_state(wc_dir, 1)
expected_status.tweak('A/B/E/alpha', wc_rev='2')
actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
None, wc_dir)
expected_stdout = ["property 'svn:externals' set on '" + wc_dir + "'\n"]
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
'svn:externals', ' -r1 ^/A/B/E E_ext', wc_dir)
expected_output = svntest.wc.State(wc_dir, {
'E_ext/beta' : Item(status='A '),
'E_ext/alpha' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'E_ext' : Item(),
'E_ext/alpha' : Item(contents="This is the file 'alpha'.\n"),
'E_ext/beta' : Item(contents="This is the file 'beta'.\n"),
})
expected_disk.tweak('A/B/E/alpha', contents='newer alpha\n')
expected_status.tweak(wc_rev='2')
expected_status.tweak('', status=' M')
expected_status.add({
'E_ext' : Item(status='X '),
})
actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
expected_status, None, None, None, None, None, False, wc_dir)
expected_info = { 'Revision': '1' }
actions.run_and_verify_info([expected_info], E_ext)
@Issue(4123)
def url_to_wc_copy_of_externals(sbox):
"url-to-wc copy of externals"
sbox.build()
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
svntest.actions.run_and_verify_svn(None, None, [], 'ps',
'svn:externals', '^/A/D/G external',
os.path.join(wc_dir, 'A', 'C'))
svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
'create an external', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
external_root_path = os.path.join(wc_dir, "External-WC-to-URL-Copy")
external_ex_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
"external")
external_pi_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
"external", "pi")
external_rho_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
"external", "rho")
external_tau_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
"external", "tau")
expected_stdout = verify.UnorderedOutput([
"\n",
" U " + external_root_path + "\n",
"Fetching external item into '" + external_ex_path + "':\n",
"A " + external_pi_path + "\n",
"A " + external_rho_path + "\n",
"A " + external_tau_path + "\n",
"Checked out external at revision 2.\n",
"Checked out revision 2.\n",
"A " + external_root_path + "\n"
])
exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
"OUTPUT", expected_stdout, [], 0, 'copy', repo_url + '/A/C',
os.path.join(wc_dir, 'External-WC-to-URL-Copy'))
@Issue(3741)
def update_dir_external_shallow(sbox):
"shallow update should remove externals"
sbox.build()
sbox.simple_propset('svn:externals', '^/A/D/H X', 'A/B/E')
sbox.simple_commit()
sbox.simple_update()
expected_output = svntest.wc.State(sbox.wc_dir, {
'A/B/E/alpha' : Item(status='D '),
'A/B/E/X' : Item(verb='Removed external'),
'A/B/E/beta' : Item(status='D '),
})
svntest.actions.run_and_verify_update(sbox.wc_dir,
expected_output, None, None,
None, None, None, None, None, False,
'--set-depth=empty',
sbox.ospath('A/B/E'))
expected_output = svntest.wc.State(sbox.wc_dir, {
'A/B/E/X/psi' : Item(status='A '),
'A/B/E/X/chi' : Item(status='A '),
'A/B/E/X/omega' : Item(status='A '),
'A/B/E/alpha' : Item(status='A '),
'A/B/E/beta' : Item(status='A '),
})
svntest.actions.run_and_verify_update(sbox.wc_dir,
expected_output, None, None,
None, None, None, None, None, False,
'--set-depth=infinity',
sbox.ospath('A/B/E'))
test_list = [ None,
checkout_with_externals,
update_receive_new_external,
update_lose_external,
update_change_pristine_external,
update_change_modified_external,
update_receive_change_under_external,
modify_and_update_receive_new_external,
disallow_dot_or_dotdot_directory_reference,
export_with_externals,
export_wc_with_externals,
external_with_peg_and_op_revision,
new_style_externals,
disallow_propset_invalid_formatted_externals,
old_style_externals_ignore_peg_reg,
cannot_move_or_remove_file_externals,
cant_place_file_external_into_dir_external,
external_into_path_with_spaces,
binary_file_externals,
update_lose_file_external,
switch_relative_external,
export_sparse_wc_with_externals,
relegate_external,
wc_repos_file_externals,
merge_target_with_externals,
update_modify_file_external,
update_external_on_locally_added_dir,
switch_external_on_locally_added_dir,
file_external_in_sibling,
file_external_update_without_commit,
incoming_file_on_file_external,
incoming_file_external_on_file,
exclude_externals,
file_externals_different_url,
file_external_in_unversioned,
copy_file_externals,
remap_file_external_with_prop_del,
dir_external_with_dash_r_only,
url_to_wc_copy_of_externals,
update_dir_external_shallow,
]
if __name__ == '__main__':
svntest.main.run_tests(test_list)