#!/usr/bin/env python
#
# basic_tests.py: testing working-copy interactions with ra_local
#
# Subversion is a tool for revision control.
# See http://subversion.tigris.org for more information.
#
# ====================================================================
# Copyright (c) 2000-2006 CollabNet. All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://subversion.tigris.org/license-1.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
######################################################################
# General modules
import shutil, stat, string, sys, re, os.path
# Our testing module
import svntest
from svntest import wc, SVNAnyOutput
# (abbreviation)
Skip = svntest.testcase.Skip
XFail = svntest.testcase.XFail
Item = wc.StateItem
######################################################################
# Tests
#
# Each test must return on success or raise on failure.
#----------------------------------------------------------------------
def basic_checkout(sbox):
"basic checkout of a wc"
sbox.build()
wc_dir = sbox.wc_dir
# Checkout of a different URL into a working copy fails
A_url = svntest.main.current_repo_url + '/A'
svntest.actions.run_and_verify_svn("No error where some expected",
None, SVNAnyOutput,
# "Obstructed update",
'co', A_url,
'--username',
svntest.main.wc_author,
'--password',
svntest.main.wc_passwd,
wc_dir)
# Make some changes to the working copy
mu_path = os.path.join(wc_dir, 'A', 'mu')
svntest.main.file_append (mu_path, 'appended mu text')
lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
os.remove(lambda_path)
G_path = os.path.join(wc_dir, 'A', 'D', 'G')
svntest.actions.run_and_verify_svn(None, None, [], 'rm', G_path)
expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
expected_output.tweak('A/mu', status='M ')
expected_output.tweak('A/B/lambda', status='! ')
expected_output.tweak('A/D/G',
'A/D/G/pi',
'A/D/G/rho',
'A/D/G/tau', status='D ')
svntest.actions.run_and_verify_status(wc_dir, expected_output)
# Repeat checkout of original URL into working copy with modifications
url = svntest.main.current_repo_url
svntest.actions.run_and_verify_svn("Repeat checkout failed", None, [],
'co', url,
'--username',
svntest.main.wc_author,
'--password',
svntest.main.wc_passwd,
wc_dir)
# lambda is restored, modifications remain, deletes remain scheduled
# for deletion although files are restored to the filesystem
expected_output.tweak('A/B/lambda', status=' ')
svntest.actions.run_and_verify_status (wc_dir, expected_output)
#----------------------------------------------------------------------
def basic_status(sbox):
"basic status command"
sbox.build()
wc_dir = sbox.wc_dir
# Created expected output tree for 'svn status'
output = svntest.actions.get_virginal_state(wc_dir, 1)
svntest.actions.run_and_verify_status(wc_dir, output)
current_dir = os.getcwd()
try:
os.chdir(os.path.join(wc_dir, 'A'))
output = svntest.actions.get_virginal_state("..", 1)
svntest.actions.run_and_verify_status("..", output)
finally:
os.chdir(current_dir)
#----------------------------------------------------------------------
def basic_commit(sbox):
"basic commit command"
sbox.build()
wc_dir = sbox.wc_dir
# Make a couple of local mods to files
mu_path = os.path.join(wc_dir, 'A', 'mu')
rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
svntest.main.file_append (mu_path, 'appended mu text')
svntest.main.file_append (rho_path, 'new appended text for rho')
# Created expected output tree for 'svn ci'
expected_output = wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
'A/D/G/rho' : Item(verb='Sending'),
})
# Create expected status tree; all local revisions should be at 1,
# but mu and rho should be at revision 2.
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev=1)
expected_status.tweak('A/mu', 'A/D/G/rho', wc_rev=2)
svntest.actions.run_and_verify_commit (wc_dir,
expected_output,
expected_status,
None,
None, None,
None, None,
wc_dir)
#----------------------------------------------------------------------
def basic_update(sbox):
"basic update command"
sbox.build()
wc_dir = sbox.wc_dir
# Make a backup copy of the working copy
wc_backup = sbox.add_wc_path('backup')
svntest.actions.duplicate_dir(wc_dir, wc_backup)
# Make a couple of local mods to files
mu_path = os.path.join(wc_dir, 'A', 'mu')
rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
svntest.main.file_append (mu_path, 'appended mu text')
svntest.main.file_append (rho_path, 'new appended text for rho')
# Created expected output tree for 'svn ci'
expected_output = wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
'A/D/G/rho' : Item(verb='Sending'),
})
# Create expected status tree; all local revisions should be at 1,
# but mu and rho should be at revision 2.
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev=1)
expected_status.tweak('A/mu', 'A/D/G/rho', wc_rev=2)
# Commit.
svntest.actions.run_and_verify_commit (wc_dir, expected_output,
expected_status, None,
None, None, None, None, wc_dir)
# Create expected output tree for an update of the wc_backup.
expected_output = wc.State(wc_backup, {
'A/mu' : Item(status='U '),
'A/D/G/rho' : Item(status='U '),
})
# Create expected disk tree for the update.
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('A/mu',
contents=expected_disk.desc['A/mu'].contents
+ 'appended mu text')
expected_disk.tweak('A/D/G/rho',
contents=expected_disk.desc['A/D/G/rho'].contents
+ 'new appended text for rho')
# Create expected status tree for the update.
expected_status = svntest.actions.get_virginal_state(wc_backup, 2)
# Do the update and check the results in three ways.
svntest.actions.run_and_verify_update(wc_backup,
expected_output,
expected_disk,
expected_status)
# Unversioned paths, those that are not immediate children of a versioned
# path, are skipped and do not raise an error
xx_path = os.path.join(wc_dir, 'xx', 'xx')
out, err = svntest.actions.run_and_verify_svn("update xx/xx",
["Skipped '"+xx_path+"'\n"], [],
'update', xx_path)
out, err = svntest.actions.run_and_verify_svn("update xx/xx",
[], [],
'update', '--quiet', xx_path)
#----------------------------------------------------------------------
def basic_mkdir_url(sbox):
"basic mkdir URL"
sbox.build()
Y_url = svntest.main.current_repo_url + '/Y'
Y_Z_url = svntest.main.current_repo_url + '/Y/Z'
svntest.actions.run_and_verify_svn("mkdir URL URL/subdir",
["\n", "Committed revision 2.\n"], [],
'mkdir', '-m', 'log_msg', Y_url, Y_Z_url)
expected_output = wc.State(sbox.wc_dir, {
'Y' : Item(status='A '),
'Y/Z' : Item(status='A '),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'Y' : Item(),
'Y/Z' : Item()
})
expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 2)
expected_status.add({
'Y' : Item(status=' ', wc_rev=2),
'Y/Z' : Item(status=' ', wc_rev=2)
})
svntest.actions.run_and_verify_update(sbox.wc_dir,
expected_output,
expected_disk,
expected_status)
#----------------------------------------------------------------------
def basic_corruption(sbox):
"basic corruption detection"
## I always wanted a test named "basic_corruption". :-)
## Here's how it works:
##
## 1. Make a working copy at rev 1, duplicate it. Now we have
## two working copies at rev 1. Call them first and second.
## 2. Make a local mod to `first/A/mu'.
## 3. Intentionally corrupt `first/A/.svn/text-base/mu.svn-base'.
## 4. Try to commit, expect a failure.
## 5. Repair the text-base, commit again, expect success.
## 6. Intentionally corrupt `second/A/.svn/text-base/mu.svn-base'.
## 7. Try to update `second', expect failure.
## 8. Repair the text-base, update again, expect success.
##
## Here we go...
sbox.build()
wc_dir = sbox.wc_dir
# Make the "other" working copy
other_wc = sbox.add_wc_path('other')
svntest.actions.duplicate_dir (wc_dir, other_wc)
# Make a local mod to mu
mu_path = os.path.join (wc_dir, 'A', 'mu')
svntest.main.file_append (mu_path, 'appended mu text')
# Created expected output tree for 'svn ci'
expected_output = wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
})
# Create expected status tree; all local revisions should be at 1,
# but mu should be at revision 2.
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev=1)
expected_status.tweak('A/mu', wc_rev=2)
# Modify mu's text-base, so we get a checksum failure the first time
# we try to commit.
tb_dir_path = os.path.join (wc_dir, 'A',
svntest.main.get_admin_name(), 'text-base')
mu_tb_path = os.path.join (tb_dir_path, 'mu.svn-base')
mu_saved_tb_path = mu_tb_path + "-saved"
tb_dir_saved_mode = os.stat(tb_dir_path)[stat.ST_MODE]
mu_tb_saved_mode = os.stat(mu_tb_path)[stat.ST_MODE]
os.chmod (tb_dir_path, 0777) # ### What's a more portable way to do this?
os.chmod (mu_tb_path, 0666) # ### Would rather not use hardcoded numbers.
shutil.copyfile (mu_tb_path, mu_saved_tb_path)
svntest.main.file_append (mu_tb_path, 'Aaagggkkk, corruption!')
os.chmod (tb_dir_path, tb_dir_saved_mode)
os.chmod (mu_tb_path, mu_tb_saved_mode)
# This commit should fail due to text base corruption.
svntest.actions.run_and_verify_commit (wc_dir, expected_output,
expected_status, "svn: Checksum",
None, None, None, None, wc_dir)
# Restore the uncorrupted text base.
os.chmod (tb_dir_path, 0777)
os.chmod (mu_tb_path, 0666)
os.remove (mu_tb_path)
os.rename (mu_saved_tb_path, mu_tb_path)
os.chmod (tb_dir_path, tb_dir_saved_mode)
os.chmod (mu_tb_path, mu_tb_saved_mode)
# This commit should succeed.
svntest.actions.run_and_verify_commit (wc_dir, expected_output,
expected_status, None,
None, None, None, None, wc_dir)
# Create expected output tree for an update of the other_wc.
expected_output = wc.State(other_wc, {
'A/mu' : Item(status='U '),
})
# Create expected disk tree for the update.
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('A/mu',
contents=expected_disk.desc['A/mu'].contents
+ 'appended mu text')
# Create expected status tree for the update.
expected_status = svntest.actions.get_virginal_state(other_wc, 2)
# Modify mu's text-base, so we get a checksum failure the first time
# we try to update.
tb_dir_path = os.path.join (other_wc, 'A',
svntest.main.get_admin_name(), 'text-base')
mu_tb_path = os.path.join (tb_dir_path, 'mu.svn-base')
mu_saved_tb_path = mu_tb_path + "-saved"
tb_dir_saved_mode = os.stat(tb_dir_path)[stat.ST_MODE]
mu_tb_saved_mode = os.stat(mu_tb_path)[stat.ST_MODE]
os.chmod (tb_dir_path, 0777)
os.chmod (mu_tb_path, 0666)
shutil.copyfile (mu_tb_path, mu_saved_tb_path)
svntest.main.file_append (mu_tb_path, 'Aiyeeeee, corruption!\nHelp!\n')
os.chmod (tb_dir_path, tb_dir_saved_mode)
os.chmod (mu_tb_path, mu_tb_saved_mode)
# Do the update and check the results in three ways.
svntest.actions.run_and_verify_update(other_wc,
expected_output,
expected_disk,
expected_status,
"svn: Checksum", other_wc)
# Restore the uncorrupted text base.
os.chmod (tb_dir_path, 0777)
os.chmod (mu_tb_path, 0666)
os.remove (mu_tb_path)
os.rename (mu_saved_tb_path, mu_tb_path)
os.chmod (tb_dir_path, tb_dir_saved_mode)
os.chmod (mu_tb_path, mu_tb_saved_mode)
# This update should succeed. (Actually, I'm kind of astonished
# that this works without even an intervening "svn cleanup".)
svntest.actions.run_and_verify_update (other_wc,
expected_output,
expected_disk,
expected_status)
#----------------------------------------------------------------------
def basic_merging_update(sbox):
"receiving text merges as part of an update"
sbox.build()
wc_dir = sbox.wc_dir
# First change the greek tree to make two files 10 lines long
mu_path = os.path.join(wc_dir, 'A', 'mu')
rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
mu_text = ""
rho_text = ""
for x in range(2,11):
mu_text = mu_text + '\nThis is line ' + `x` + ' in mu'
rho_text = rho_text + '\nThis is line ' + `x` + ' in rho'
svntest.main.file_append (mu_path, mu_text)
svntest.main.file_append (rho_path, rho_text)
# Create expected output tree for initial commit
expected_output = wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
'A/D/G/rho' : Item(verb='Sending'),
})
# Create expected status tree; all local revisions should be at 1,
# but mu and rho should be at revision 2.
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev=1)
expected_status.tweak('A/mu', 'A/D/G/rho', wc_rev=2)
# Initial commit.
svntest.actions.run_and_verify_commit (wc_dir,
expected_output,
expected_status,
None,
None, None, None, None,
wc_dir)
# Make a backup copy of the working copy
wc_backup = sbox.add_wc_path('backup')
svntest.actions.duplicate_dir(wc_dir, wc_backup)
# Make a couple of local mods to files
svntest.main.file_append (mu_path, ' Appended to line 10 of mu')
svntest.main.file_append (rho_path, ' Appended to line 10 of rho')
# Created expected output tree for 'svn ci'
expected_output = wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
'A/D/G/rho' : Item(verb='Sending'),
})
# Create expected status tree; all local revisions should be at 1,
# but mu and rho should be at revision 3.
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
expected_status.tweak(wc_rev=1)
expected_status.tweak('A/mu', 'A/D/G/rho', wc_rev=3)
# Commit.
svntest.actions.run_and_verify_commit (wc_dir,
expected_output,
expected_status,
None,
None, None, None, None,
wc_dir)
# Make local mods to wc_backup by recreating mu and rho
mu_path_backup = os.path.join(wc_backup, 'A', 'mu')
rho_path_backup = os.path.join(wc_backup, 'A', 'D', 'G', 'rho')
fp_mu = open(mu_path_backup, 'w+')
# open in 'truncate to zero then write" mode
backup_mu_text='This is the new line 1 in the backup copy of mu'
for x in range(2,11):
backup_mu_text = backup_mu_text + '\nThis is line ' + `x` + ' in mu'
fp_mu.write(backup_mu_text)
fp_mu.close()
fp_rho = open(rho_path_backup, 'w+') # now open rho in write mode
backup_rho_text='This is the new line 1 in the backup copy of rho'
for x in range(2,11):
backup_rho_text = backup_rho_text + '\nThis is line ' + `x` + ' in rho'
fp_rho.write(backup_rho_text)
fp_rho.close()
# Create expected output tree for an update of the wc_backup.
expected_output = wc.State(wc_backup, {
'A/mu' : Item(status='G '),
'A/D/G/rho' : Item(status='G '),
})
# Create expected disk tree for the update.
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('A/mu',
contents=backup_mu_text + ' Appended to line 10 of mu')
expected_disk.tweak('A/D/G/rho',
contents=backup_rho_text + ' Appended to line 10 of rho')
# Create expected status tree for the update.
expected_status = svntest.actions.get_virginal_state(wc_backup, 3)
expected_status.tweak('A/mu', 'A/D/G/rho', status='M ')
# Do the update and check the results in three ways.
svntest.actions.run_and_verify_update(wc_backup,
expected_output,
expected_disk,
expected_status)
#----------------------------------------------------------------------
def basic_conflict(sbox):
"basic conflict creation and resolution"
sbox.build()
wc_dir = sbox.wc_dir
# Make a backup copy of the working copy
wc_backup = sbox.add_wc_path('backup')
svntest.actions.duplicate_dir(wc_dir, wc_backup)
# Make a couple of local mods to files which will be committed
mu_path = os.path.join(wc_dir, 'A', 'mu')
rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
svntest.main.file_append (mu_path, 'Original appended text for mu\n')
svntest.main.file_append (rho_path, 'Original appended text for rho\n')
# Make a couple of local mods to files which will be conflicted
mu_path_backup = os.path.join(wc_backup, 'A', 'mu')
rho_path_backup = os.path.join(wc_backup, 'A', 'D', 'G', 'rho')
svntest.main.file_append (mu_path_backup,
'Conflicting appended text for mu\n')
svntest.main.file_append (rho_path_backup,
'Conflicting appended text for rho\n')
# Created expected output tree for 'svn ci'
expected_output = wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
'A/D/G/rho' : Item(verb='Sending'),
})
# Create expected status tree; all local revisions should be at 1,
# but mu and rho should be at revision 2.
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev=1)
expected_status.tweak('A/mu', 'A/D/G/rho', wc_rev=2)
# Commit.
svntest.actions.run_and_verify_commit (wc_dir, expected_output,
expected_status, None,
None, None, None, None, wc_dir)
# Create expected output tree for an update of the wc_backup.
expected_output = wc.State(wc_backup, {
'A/mu' : Item(status='C '),
'A/D/G/rho' : Item(status='C '),
})
# Create expected disk tree for the update.
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('A/mu', contents="""This is the file 'mu'.
<<<<<<< .mine
Conflicting appended text for mu
=======
Original appended text for mu
>>>>>>> .r2
""")
expected_disk.tweak('A/D/G/rho', contents="""This is the file 'rho'.
<<<<<<< .mine
Conflicting appended text for rho
=======
Original appended text for rho
>>>>>>> .r2
""")
# Create expected status tree for the update.
expected_status = svntest.actions.get_virginal_state(wc_backup, '2')
expected_status.tweak('A/mu', 'A/D/G/rho', status='C ')
# "Extra" files that we expect to result from the conflicts.
# These are expressed as list of regexps. What a cool system! :-)
extra_files = ['mu.*\.r1', 'mu.*\.r2', 'mu.*\.mine',
'rho.*\.r1', 'rho.*\.r2', 'rho.*\.mine',]
# Do the update and check the results in three ways.
# All "extra" files are passed to detect_conflict_files().
svntest.actions.run_and_verify_update(wc_backup,
expected_output,
expected_disk,
expected_status,
None,
svntest.tree.detect_conflict_files,
extra_files)
# verify that the extra_files list is now empty.
if len(extra_files) != 0:
# Because we want to be a well-behaved test, we silently raise if
# the test fails. However, these two print statements would
# probably reveal the cause for the failure, if they were
# uncommented:
#
# print "Not all extra reject files have been accounted for:"
# print extra_files
### we should raise a less generic error here. which?
raise svntest.Failure
# So now mu and rho are both in a "conflicted" state. Run 'svn
# resolved' on them.
svntest.actions.run_and_verify_svn("Resolved command", None, [],
'resolved',
mu_path_backup,
rho_path_backup)
# See if they've changed back to plain old 'M' state.
expected_status.tweak('A/mu', 'A/D/G/rho', status='M ')
# There should be *no* extra backup files lying around the working
# copy after resolving the conflict; thus we're not passing a custom
# singleton handler.
svntest.actions.run_and_verify_status(wc_backup, expected_status)
#----------------------------------------------------------------------
def basic_cleanup(sbox):
"basic cleanup command"
sbox.build()
wc_dir = sbox.wc_dir
# Lock some directories.
B_path = os.path.join(wc_dir, 'A', 'B')
G_path = os.path.join(wc_dir, 'A', 'D', 'G')
C_path = os.path.join(wc_dir, 'A', 'C')
svntest.actions.lock_admin_dir(B_path)
svntest.actions.lock_admin_dir(G_path)
svntest.actions.lock_admin_dir(C_path)
# Verify locked status.
expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
expected_output.tweak('A/B', 'A/D/G', 'A/C', locked='L')
svntest.actions.run_and_verify_status (wc_dir, expected_output)
# Run cleanup (### todo: cleanup doesn't currently print anything)
svntest.actions.run_and_verify_svn("Cleanup command", None, [],
'cleanup', wc_dir)
# Verify unlocked status.
expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
svntest.actions.run_and_verify_status(wc_dir, expected_output)
#----------------------------------------------------------------------
def basic_revert(sbox):
"basic revert command"
sbox.build()
wc_dir = sbox.wc_dir
# Modify some files and props.
beta_path = os.path.join(wc_dir, 'A', 'B', 'E', 'beta')
gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
iota_path = os.path.join(wc_dir, 'iota')
rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
zeta_path = os.path.join(wc_dir, 'A', 'D', 'H', 'zeta')
svntest.main.file_append(beta_path, "Added some text to 'beta'.\n")
svntest.main.file_append(iota_path, "Added some text to 'iota'.\n")
svntest.main.file_append(rho_path, "Added some text to 'rho'.\n")
svntest.main.file_append(zeta_path, "Added some text to 'zeta'.\n")
svntest.actions.run_and_verify_svn("Add command", None, [],
'add', zeta_path)
svntest.actions.run_and_verify_svn("Add prop command", None, [],
'ps', 'random-prop', 'propvalue',
gamma_path)
svntest.actions.run_and_verify_svn("Add prop command", None, [],
'ps', 'random-prop', 'propvalue',
iota_path)
# Verify modified status.
expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
expected_output.tweak('A/B/E/beta', 'A/D/G/rho', status='M ')
expected_output.tweak('iota', status='MM')
expected_output.tweak('A/D/gamma', status=' M')
expected_output.add({
'A/D/H/zeta' : Item(status='A ', wc_rev=0),
})
svntest.actions.run_and_verify_status (wc_dir, expected_output)
# Run revert (### todo: revert doesn't currently print anything)
svntest.actions.run_and_verify_svn("Revert command", None, [],
'revert', beta_path)
svntest.actions.run_and_verify_svn("Revert command", None, [],
'revert', gamma_path)
svntest.actions.run_and_verify_svn("Revert command", None, [],
'revert', iota_path)
svntest.actions.run_and_verify_svn("Revert command", None, [],
'revert', rho_path)
svntest.actions.run_and_verify_svn("Revert command", None, [],
'revert', zeta_path)
# Verify unmodified status.
expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
svntest.actions.run_and_verify_status (wc_dir, expected_output)
# Now, really make sure the contents are back to their original state.
fp = open(beta_path, 'r')
lines = fp.readlines()
if not ((len (lines) == 1) and (lines[0] == "This is the file 'beta'.\n")):
print "Revert failed to restore original text."
raise svntest.Failure
fp = open(iota_path, 'r')
lines = fp.readlines()
if not ((len (lines) == 1) and (lines[0] == "This is the file 'iota'.\n")):
print "Revert failed to restore original text."
raise svntest.Failure
fp = open(rho_path, 'r')
lines = fp.readlines()
if not ((len (lines) == 1) and (lines[0] == "This is the file 'rho'.\n")):
print "Revert failed to restore original text."
raise svntest.Failure
fp = open(zeta_path, 'r')
lines = fp.readlines()
if not ((len (lines) == 1) and (lines[0] == "Added some text to 'zeta'.\n")):
### we should raise a less generic error here. which?
raise svntest.Failure
# Finally, check that reverted file is not readonly
os.remove(beta_path)
svntest.actions.run_and_verify_svn(None, None, [], 'revert', beta_path)
if not (open(beta_path, 'rw+')):
raise svntest.Failure
# Check that a directory scheduled to be added, but physically
# removed, can be reverted.
X_path = os.path.join(wc_dir, 'X')
svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', X_path)
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.add({
'X' : Item(status='A ', wc_rev=0),
})
svntest.actions.run_and_verify_status (wc_dir, expected_status)
svntest.main.safe_rmtree(X_path)
svntest.actions.run_and_verify_svn(None, None, [], 'revert', X_path)
expected_status.remove('X')
svntest.actions.run_and_verify_status (wc_dir, expected_status)
# Check that a directory scheduled for deletion, but physically
# removed, can be reverted.
E_path = os.path.join(wc_dir, 'A', 'B', 'E')
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
### Most of the rest of this test is ineffective, due to the
### problems described in issue #1611.
svntest.actions.run_and_verify_svn("", None, [], 'rm', E_path)
svntest.main.safe_rmtree(E_path)
expected_status.tweak('A/B/E', status='D ')
expected_status.tweak('A/B/E', wc_rev='?')
### FIXME: A weakness in the test framework, described in detail
### in issue #1611, prevents us from checking via status. Grr.
#
# svntest.actions.run_and_verify_status (wc_dir, expected_status,
# None, None, None, None)
#
#
### If you were to uncomment the above, you'd get an error like so:
#
# =============================================================
# Expected E and actual E are different!
# =============================================================
# EXPECTED NODE TO BE:
# =============================================================
# * Node name: E
# Path: working_copies/basic_tests-10/A/B/E
# Contents: None
# Properties: {}
# Attributes: {'status': 'D ', 'wc_rev': '?'}
# Children: 2
# =============================================================
# ACTUAL NODE FOUND:
# =============================================================
# * Node name: E
# Path: working_copies/basic_tests-10/A/B/E
# Contents: None
# Properties: {}
# Attributes: {'status': 'D ', 'wc_rev': '?'}
# Children: is a file.
# Unequal Types: one Node is a file, the other is a directory
# This will actually print
#
# "Failed to revert 'working_copies/basic_tests-10/A/B/E' -- \
# try updating instead."
#
# ...but due to test suite lossage, it'll still look like success.
svntest.actions.run_and_verify_svn(None, None, [], 'revert', E_path)
### FIXME: Again, the problem described in issue #1611 bites us here.
#
# expected_status.tweak('A/B/E', status=' ')
# svntest.actions.run_and_verify_status (wc_dir, expected_status,
# None, None, None, None)
#----------------------------------------------------------------------
def basic_switch(sbox):
"basic switch command"
sbox.build()
wc_dir = sbox.wc_dir
### Switch the file `iota' to `A/D/gamma'.
# Construct some paths for convenience
iota_path = os.path.join(wc_dir, 'iota')
gamma_url = svntest.main.current_repo_url + '/A/D/gamma'
# Create expected output tree
expected_output = wc.State(wc_dir, {
'iota' : Item(status='U '),
})
# Create expected disk tree (iota will have gamma's contents)
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('iota',
contents=expected_disk.desc['A/D/gamma'].contents)
# Create expected status tree
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.tweak('iota', switched='S')
# Do the switch and check the results in three ways.
svntest.actions.run_and_verify_switch(wc_dir, iota_path, gamma_url,
expected_output,
expected_disk,
expected_status)
### Switch the directory `A/D/H' to `A/D/G'.
# Construct some paths for convenience
ADH_path = os.path.join(wc_dir, 'A', 'D', 'H')
chi_path = os.path.join(ADH_path, 'chi')
omega_path = os.path.join(ADH_path, 'omega')
psi_path = os.path.join(ADH_path, 'psi')
pi_path = os.path.join(ADH_path, 'pi')
tau_path = os.path.join(ADH_path, 'tau')
rho_path = os.path.join(ADH_path, 'rho')
ADG_url = svntest.main.current_repo_url + '/A/D/G'
# Create expected output tree
expected_output = wc.State(wc_dir, {
'A/D/H/chi' : Item(status='D '),
'A/D/H/omega' : Item(status='D '),
'A/D/H/psi' : Item(status='D '),
'A/D/H/pi' : Item(status='A '),
'A/D/H/rho' : Item(status='A '),
'A/D/H/tau' : Item(status='A '),
})
# Create expected disk tree (iota will have gamma's contents,
# A/D/H/* will look like A/D/G/*)
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('iota',
contents=expected_disk.desc['A/D/gamma'].contents)
expected_disk.remove('A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
expected_disk.add({
'A/D/H/pi' : Item("This is the file 'pi'.\n"),
'A/D/H/rho' : Item("This is the file 'rho'.\n"),
'A/D/H/tau' : Item("This is the file 'tau'.\n"),
})
# Create expected status
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.remove('A/D/H/chi',
'A/D/H/omega',
'A/D/H/psi')
expected_status.add({
'A/D/H/pi' : Item(status=' ', wc_rev=1),
'A/D/H/rho' : Item(status=' ', wc_rev=1),
'A/D/H/tau' : Item(status=' ', wc_rev=1),
})
expected_status.tweak('iota', 'A/D/H', switched='S')
# Do the switch and check the results in three ways.
svntest.actions.run_and_verify_switch(wc_dir, ADH_path, ADG_url,
expected_output,
expected_disk,
expected_status)
#----------------------------------------------------------------------
def verify_file_deleted(message, path):
try:
open(path, 'r')
except IOError:
return
if message is not None:
print message
###TODO We should raise a less generic error here. which?
raise Failure
def can_cd_to_dir(path):
current_dir = os.getcwd()
try:
os.chdir(path)
except OSError:
return 0
os.chdir(current_dir)
return 1
def basic_delete(sbox):
"basic delete command"
sbox.build()
wc_dir = sbox.wc_dir
# modify text of chi
chi_parent_path = os.path.join(wc_dir, 'A', 'D', 'H')
chi_path = os.path.join(chi_parent_path, 'chi')
svntest.main.file_append(chi_path, 'added to chi')
# modify props of rho (file)
rho_parent_path = os.path.join(wc_dir, 'A', 'D', 'G')
rho_path = os.path.join(rho_parent_path, 'rho')
svntest.main.run_svn(None, 'ps', 'abc', 'def', rho_path)
# modify props of F (dir)
F_parent_path = os.path.join(wc_dir, 'A', 'B')
F_path = os.path.join(F_parent_path, 'F')
svntest.main.run_svn(None, 'ps', 'abc', 'def', F_path)
# unversioned file
sigma_parent_path = os.path.join(wc_dir, 'A', 'C')
sigma_path = os.path.join(sigma_parent_path, 'sigma')
svntest.main.file_append(sigma_path, 'unversioned sigma')
# unversioned directory
Q_parent_path = sigma_parent_path
Q_path = os.path.join(Q_parent_path, 'Q')
os.mkdir(Q_path)
# added directory hierarchies
X_parent_path = os.path.join(wc_dir, 'A', 'B')
X_path = os.path.join(X_parent_path, 'X')
svntest.main.run_svn(None, 'mkdir', X_path)
X_child_path = os.path.join(X_path, 'xi')
svntest.main.file_append(X_child_path, 'added xi')
svntest.main.run_svn(None, 'add', X_child_path)
Y_parent_path = os.path.join(wc_dir, 'A', 'D')
Y_path = os.path.join(Y_parent_path, 'Y')
svntest.main.run_svn(None, 'mkdir', Y_path)
# check status
expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
expected_output.tweak('A/D/H/chi', status='M ')
expected_output.tweak('A/D/G/rho', 'A/B/F', status=' M')
# expected_output.tweak('A/C/sigma', status='? ')
expected_output.add({
'A/B/X' : Item(status='A ', wc_rev=0),
'A/B/X/xi' : Item(status='A ', wc_rev=0),
'A/D/Y' : Item(status='A ', wc_rev=0),
})
svntest.actions.run_and_verify_status(wc_dir, expected_output)
# 'svn rm' that should fail
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', chi_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', chi_parent_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', rho_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', rho_parent_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', F_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', F_parent_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', sigma_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', sigma_parent_path)
svntest.actions.run_and_verify_svn(None, None, SVNAnyOutput,
'rm', X_path)
# check status has not changed
svntest.actions.run_and_verify_status (wc_dir, expected_output)
# 'svn rm' that should work
E_path = os.path.join(wc_dir, 'A', 'B', 'E')
svntest.actions.run_and_verify_svn(None, None, [], 'rm', E_path)
# 'svn rm --force' that should work
svntest.actions.run_and_verify_svn(None, None, [], 'rm', '--force',
chi_parent_path)
svntest.actions.run_and_verify_svn(None, None, [],
'rm', '--force', rho_parent_path)
svntest.actions.run_and_verify_svn(None, None, [],
'rm', '--force', F_path)
svntest.actions.run_and_verify_svn(None, None, [],
'rm', '--force', sigma_parent_path)
svntest.actions.run_and_verify_svn(None, None, [],
'rm', '--force', X_path)
# Deleting already removed from wc versioned item with --force
iota_path = os.path.join(wc_dir, 'iota')
os.remove(iota_path)
svntest.actions.run_and_verify_svn(None, None, [],
'rm', '--force', iota_path)
# and without --force
gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
os.remove(gamma_path)
svntest.actions.run_and_verify_svn(None, None, [], 'rm', gamma_path)
# Deleting already scheduled for deletion doesn't require --force
svntest.actions.run_and_verify_svn(None, None, [], 'rm', gamma_path)
svntest.actions.run_and_verify_svn(None, None, [], 'rm', E_path)
# check status
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.tweak('A/D/H',
'A/D/H/chi',
'A/D/H/omega',
'A/D/H/psi',
'A/D/G',
'A/D/G/rho',
'A/D/G/pi',
'A/D/G/tau',
'A/B/E',
'A/B/E/alpha',
'A/B/E/beta',
'A/B/F',
'A/C',
'iota',
'A/D/gamma', status='D ')
expected_status.add({
'A/D/Y' : Item(status='A ', wc_rev=0),
})
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# issue 687 delete directory with uncommitted directory child
svntest.actions.run_and_verify_svn(None, None, [],
'rm', '--force', Y_parent_path)
expected_status.tweak('A/D', status='D ')
expected_status.remove('A/D/Y')
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# check files have been removed
verify_file_deleted("Failed to remove text modified file", rho_path)
verify_file_deleted("Failed to remove prop modified file", chi_path)
verify_file_deleted("Failed to remove unversioned file", sigma_path)
verify_file_deleted("Failed to remove unmodified file",
os.path.join(E_path, 'alpha'))
# check versioned dir is not removed
if not can_cd_to_dir(F_path):
print "Removed versioned dir"
### we should raise a less generic error here. which?
raise svntest.Failure
# check unversioned and added dirs has been removed
if can_cd_to_dir(Q_path):
print "Failed to remove unversioned dir"
### we should raise a less generic error here. which?
raise svntest.Failure
if can_cd_to_dir(X_path):
print "Failed to remove added dir"
### we should raise a less generic error here. which?
raise svntest.Failure
# Deleting unversioned file explicitly
foo_path = os.path.join(wc_dir, 'foo')
svntest.main.file_append(foo_path, 'unversioned foo')
svntest.actions.run_and_verify_svn(None, None, [],
'rm', '--force', foo_path)
verify_file_deleted("Failed to remove unversioned file foo", foo_path)
# At one stage deleting an URL dumped core
iota_URL = svntest.main.current_repo_url + '/iota'
svntest.actions.run_and_verify_svn(None,
["\n", "Committed revision 2.\n"], [],
'rm', '-m', 'delete iota URL',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
iota_URL)
#----------------------------------------------------------------------
def basic_checkout_deleted(sbox):
"checkout a path no longer in HEAD"
sbox.build()
wc_dir = sbox.wc_dir
# Delete A/D and commit.
D_path = os.path.join(wc_dir, 'A', 'D')
svntest.actions.run_and_verify_svn("error scheduling A/D for deletion",
None, [], 'rm', '--force', D_path)
expected_output = wc.State(wc_dir, {
'A/D' : Item(verb='Deleting'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev=1)
expected_status.remove('A/D', 'A/D/G', 'A/D/G/rho', 'A/D/G/pi', 'A/D/G/tau',
'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega',
'A/D/gamma')
svntest.actions.run_and_verify_commit(wc_dir,
expected_output, expected_status,
None, None, None, None, None,
wc_dir)
# Now try to checkout revision 1 of A/D.
url = svntest.main.current_repo_url + '/A/D'
wc2 = os.path.join (sbox.wc_dir, 'new_D')
svntest.actions.run_and_verify_svn("error checking out r1 of A/D",
None, [], 'co', '-r', '1',
'--username',
svntest.main.wc_author,
'--password',
svntest.main.wc_passwd,
url + "@1", wc2)
#----------------------------------------------------------------------
# Issue 846, changing a deleted file to an added directory is not
# supported.
def basic_node_kind_change(sbox):
"attempt to change node kind"
sbox.build()
wc_dir = sbox.wc_dir
# Schedule a file for deletion
gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
svntest.main.run_svn(None, 'rm', gamma_path)
# Status shows deleted file
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.tweak('A/D/gamma', status='D ')
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# Try and fail to create a directory (file scheduled for deletion)
svntest.actions.run_and_verify_svn('Cannot change node kind',
None, SVNAnyOutput,
'mkdir', gamma_path)
# Status is unchanged
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# Commit file deletion
expected_output = wc.State(wc_dir, {
'A/D/gamma' : Item(verb='Deleting'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev=1)
expected_status.remove('A/D/gamma')
svntest.actions.run_and_verify_commit(wc_dir,
expected_output, expected_status,
None, None, None, None, None,
wc_dir)
# Try and fail to create a directory (file deleted)
svntest.actions.run_and_verify_svn('Cannot change node kind',
None, SVNAnyOutput,
'mkdir', gamma_path)
# Status is unchanged
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# Update to finally get rid of file
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
# mkdir should succeed
svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', gamma_path)
expected_status.tweak(wc_rev=2)
expected_status.add({
'A/D/gamma' : Item(status='A ', wc_rev=0),
})
svntest.actions.run_and_verify_status(wc_dir, expected_status)
#----------------------------------------------------------------------
def basic_import(sbox):
"basic import of single new file"
sbox.build()
wc_dir = sbox.wc_dir
# create a new directory with files of various permissions
new_path = os.path.join(wc_dir, 'new_file')
svntest.main.file_append(new_path, "some text")
# import new files into repository
url = svntest.main.current_repo_url + "/dirA/dirB/new_file"
output, errput = svntest.actions.run_and_verify_svn(
'Cannot change node kind', None, [], 'import',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
'-m', 'Log message for new import', new_path, url)
lastline = string.strip(output.pop())
cm = re.compile ("(Committed|Imported) revision [0-9]+.")
match = cm.search (lastline)
if not match:
### we should raise a less generic error here. which?
raise svntest.Failure
# remove (uncontrolled) local file
os.remove(new_path)
# Create expected disk tree for the update (disregarding props)
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'dirA/dirB/new_file' : Item('some text'),
})
# Create expected status tree for the update (disregarding props).
# Newly imported file should be at revision 2.
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.add({
'dirA' : Item(status=' ', wc_rev=2),
'dirA/dirB' : Item(status=' ', wc_rev=2),
'dirA/dirB/new_file' : Item(status=' ', wc_rev=2),
})
# Create expected output tree for the update.
expected_output = svntest.wc.State(wc_dir, {
'dirA' : Item(status='A '),
'dirA/dirB' : Item(status='A '),
'dirA/dirB/new_file' : Item(status='A '),
})
# do update and check three ways
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
expected_status,
None, None, None,
None, None, 1)
#----------------------------------------------------------------------
def basic_cat(sbox):
"basic cat of files"
sbox.build()
wc_dir = sbox.wc_dir
mu_path = os.path.join(wc_dir, 'A', 'mu')
# Get repository text even if wc is modified
svntest.main.file_append(mu_path, "some text")
svntest.actions.run_and_verify_svn(None, ["This is the file 'mu'.\n"],
[], 'cat',
###TODO is user/pass really necessary?
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
mu_path)
#----------------------------------------------------------------------
def basic_ls(sbox):
'basic ls'
sbox.build()
wc_dir = sbox.wc_dir
# Even on Windows, the output will use forward slashes, so that's
# what we expect below.
cwd = os.getcwd()
try:
os.chdir(wc_dir)
svntest.actions.run_and_verify_svn("ls implicit current directory",
["A/\n", "iota\n"],
[], 'ls',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd)
finally:
os.chdir(cwd)
svntest.actions.run_and_verify_svn('ls the root of working copy',
['A/\n', 'iota\n'],
[], 'ls',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
wc_dir)
svntest.actions.run_and_verify_svn('ls a working copy directory',
['B/\n', 'C/\n', 'D/\n', 'mu\n'],
[], 'ls',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
os.path.join(wc_dir, 'A'))
svntest.actions.run_and_verify_svn('ls working copy directory with -r BASE',
['B/\n', 'C/\n', 'D/\n', 'mu\n'],
[], 'ls', '-r', 'BASE',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
os.path.join(wc_dir, 'A'))
svntest.actions.run_and_verify_svn('ls a single file',
['mu\n'],
[], 'ls',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
os.path.join(wc_dir, 'A', 'mu'))
svntest.actions.run_and_verify_svn('recursive ls',
['E/\n', 'E/alpha\n', 'E/beta\n', 'F/\n',
'lambda\n' ], [], 'ls', '-R',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
os.path.join(wc_dir, 'A', 'B'))
#----------------------------------------------------------------------
def nonexistent_repository(sbox):
"'svn log file:///nonexistent_path' should fail"
# The bug was that
#
# $ svn log file:///nonexistent_path
#
# would go into an infinite loop, instead of failing immediately as
# it should. The loop was because svn_ra_local__split_URL() used
# svn_path_split() to lop off components and look for a repository
# in each shorter path in turn, depending on svn_path_is_empty()
# to test if it had reached the end. Somewhere along the line we
# changed the path functions (perhaps revision 3113?), and
# svn_path_split() stopped cooperating with svn_path_is_empty() in
# this particular context -- svn_path_split() would reach "/",
# svn_path_is_empty() would correctly claim that "/" is not empty,
# the next svn_path_split() would return "/" again, and so on,
# forever.
#
# This bug was fixed in revision 3150, by checking for "/"
# explicitly in svn_ra_local__split_URL(). By the time you read
# this, that may or may not be the settled fix, however, so check
# the logs to see if anything happened later.
#
# Anyway: this test _always_ operates on a file:/// path. Note that
# if someone runs this test on a system with "/nonexistent_path" in
# the root directory, the test could fail, and that's just too bad :-).
output, errput = svntest.actions.run_and_verify_svn(
None, None, SVNAnyOutput,
'log', 'file:///nonexistent_path')
for line in errput:
if re.match(".*Unable to open an ra_local session to URL.*", line):
return
# Else never matched the expected error output, so the test failed.
raise svntest.main.SVNUnmatchedError
#----------------------------------------------------------------------
# Issue 1064. This test is only useful if running over ra_dav
# with authentication enabled, otherwise it will pass trivially.
def basic_auth_cache(sbox):
"basic auth caching"
sbox.build()
wc_dir = sbox.wc_dir
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
# Create a working copy without auth tokens
svntest.main.safe_rmtree(wc_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
'--no-auth-cache',
repo_url, wc_dir)
# Failed with "not locked" error on missing directory
svntest.main.safe_rmtree(os.path.join(wc_dir, 'A', 'B', 'E'))
svntest.actions.run_and_verify_svn(None, None, [],
'status', '-u',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
os.path.join(wc_dir, 'A', 'B'))
# Failed with "already locked" error on new dir
svntest.actions.run_and_verify_svn(None, None, [],
'copy',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
repo_url + '/A/B/E',
os.path.join(wc_dir, 'A', 'D', 'G'))
#----------------------------------------------------------------------
def basic_add_ignores(sbox):
'ignored files in added dirs should not be added'
# The bug was that
#
# $ svn add dir
#
# where dir contains some items that match the ignore list and some
# do not would add all items, ignored or not.
sbox.build()
wc_dir = sbox.wc_dir
dir_path = os.path.join(wc_dir, 'dir')
foo_c_path = os.path.join(dir_path, 'foo.c')
foo_o_path = os.path.join(dir_path, 'foo.o')
os.mkdir(dir_path, 0755)
open(foo_c_path, 'w')
open(foo_o_path, 'w')
output, err = svntest.actions.run_and_verify_svn(
"No output where some expected", SVNAnyOutput, [],
'add', dir_path)
for line in output:
# If we see foo.o in the add output, fail the test.
if re.match(r'^A\s+.*foo.o$', line):
raise svntest.actions.SVNUnexpectedOutput
# Else never matched the unwanted output, so the test passed.
#----------------------------------------------------------------------
def basic_add_local_ignores(sbox):
'ignore files matching local ignores in added dirs'
#Issue #2243
#svn add command not keying off svn:ignore value
sbox.build()
wc_dir = sbox.wc_dir
dir_path = os.path.join(wc_dir, 'dir')
file_path = os.path.join(dir_path, 'app.lock')
svntest.actions.run_and_verify_svn(None, SVNAnyOutput, [],
'mkdir', dir_path)
svntest.main.run_svn(None, 'propset', 'svn:ignore', '*.lock', dir_path)
open(file_path, 'w')
svntest.actions.run_and_verify_svn(None, [], [],
'add', '--force', dir_path)
#----------------------------------------------------------------------
def basic_add_no_ignores(sbox):
'add ignored files in added dirs'
# add ignored files using the '--no-ignore' option
sbox.build()
wc_dir = sbox.wc_dir
dir_path = os.path.join(wc_dir, 'dir')
foo_c_path = os.path.join(dir_path, 'foo.c')
# add a few files that match the default ignore patterns
foo_o_path = os.path.join(dir_path, 'foo.o')
foo_lo_path = os.path.join(dir_path, 'foo.lo')
foo_rej_path = os.path.join(dir_path, 'foo.rej')
os.mkdir(dir_path, 0755)
open(foo_c_path, 'w')
open(foo_o_path, 'w')
open(foo_lo_path, 'w')
open(foo_rej_path, 'w')
output, err = svntest.actions.run_and_verify_svn(
"No output where some expected", SVNAnyOutput, [],
'add', '--no-ignore', dir_path)
for line in output:
# If we don't see ignores in the add output, fail the test.
if not re.match(r'^A\s+.*(foo.(o|rej|lo|c)|dir)$', line):
raise svntest.actions.SVNUnexpectedOutput
#----------------------------------------------------------------------
def uri_syntax(sbox):
'make sure URI syntaxes are parsed correctly'
sbox.build(create_wc = False)
local_dir = sbox.wc_dir
# Revision 6638 made 'svn co http://host' seg fault, this tests the fix.
url = svntest.main.current_repo_url
scheme = url[:string.find(url, ":")]
url = scheme + "://some_nonexistent_host_with_no_trailing_slash"
svntest.actions.run_and_verify_svn("No error where one expected",
None, SVNAnyOutput,
'co', url, local_dir)
# Different RA layers give different errors for failed checkouts;
# for us, it's only important to know that it _did_ error (as
# opposed to segfaulting), so we don't examine the error text.
#----------------------------------------------------------------------
def basic_checkout_file(sbox):
"trying to check out a file should fail"
sbox.build()
iota_url = svntest.main.current_repo_url + '/iota'
output, errput = svntest.main.run_svn(1, 'co', iota_url)
for line in errput:
if string.find(line, "refers to a file") != -1:
break
else:
raise svntest.Failure
#----------------------------------------------------------------------
def basic_info(sbox):
"basic info command"
def check_paths(lines, expected_paths):
"check that paths found on input lines beginning 'Path: ' are as expected"
paths = []
for line in lines:
if line.startswith('Path: '):
paths.append(line[6:].rstrip())
if paths != expected_paths:
print "Reported paths:", paths
print "Expected paths:", expected_paths
raise svntest.Failure
sbox.build()
cwd = os.getcwd()
try:
os.chdir(sbox.wc_dir)
# Check that "info" works with 0, 1 and more than 1 explicit targets.
output, errput = svntest.main.run_svn(None, 'info')
check_paths(output, ['.'])
output, errput = svntest.main.run_svn(None, 'info', 'iota')
check_paths(output, ['iota'])
output, errput = svntest.main.run_svn(None, 'info', 'iota', '.')
check_paths(output, ['iota', '.'])
finally:
os.chdir(cwd)
def repos_root(sbox):
"check that repos root gets set on checkout"
def check_repos_root(lines):
for line in lines:
if line == "Repository Root: " + svntest.main.current_repo_url + "\n":
break
else:
print "Bad or missing repository root"
raise svntest.Failure
sbox.build()
output, errput = svntest.main.run_svn (None, "info",
sbox.wc_dir)
check_repos_root(output)
output, errput = svntest.main.run_svn (None, "info",
os.path.join(sbox.wc_dir, "A"))
check_repos_root(output)
output, errput = svntest.main.run_svn (None, "info",
os.path.join(sbox.wc_dir, "A", "B",
"lambda"))
check_repos_root(output)
def basic_peg_revision(sbox):
"checks peg revision on filename with @ sign"
sbox.build()
wc_dir = sbox.wc_dir
repos_dir = sbox.repo_url
filename = 'abc@abc'
wc_file = wc_dir + '/' + filename
url = repos_dir + '/' + filename
svntest.main.file_append(wc_file, 'xyz\n')
svntest.main.run_svn(None, 'add', wc_file)
svntest.main.run_svn(None, 'ci', '-m', 'secret log msg', wc_file)
# Without the trailing "@", expect failure.
output, errlines = svntest.actions.run_and_verify_svn(\
None, None, ".*Syntax error parsing revision 'abc'", 'cat', wc_file)
output, errlines = svntest.actions.run_and_verify_svn(\
None, None, ".*Syntax error parsing revision 'abc'", 'cat', url)
# With the trailing "@", expect success.
output, errlines = svntest.actions.run_and_verify_svn(None, ["xyz\n"], [],
'cat', wc_file+'@')
output, errlines = svntest.actions.run_and_verify_svn(None, ["xyz\n"], [],
'cat', url+'@')
def info_nonhead(sbox):
"info on file not existing in HEAD"
sbox.build()
wc_dir = sbox.wc_dir
repo_url = sbox.repo_url
fname = os.path.join(wc_dir, 'iota')
furl = repo_url + "/iota"
# Remove iota and commit.
svntest.actions.run_and_verify_svn(None, None, [],
"delete", fname)
expected_output = svntest.wc.State(wc_dir, {
'iota' : Item(verb='Deleting'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.remove("iota")
svntest.actions.run_and_verify_commit (wc_dir,
expected_output,
expected_status,
None,
None, None,
None, None,
wc_dir)
# Get info for old iota at r1.
output, errput = svntest.actions.run_and_verify_svn(None, None, [],
'info',
furl + '@1', '-r1')
got_url = 0
for line in output:
if line.find("URL:") >= 0:
got_url = 1
if not got_url:
print "Info didn't output an URL."
raise svntest.Failure
#----------------------------------------------------------------------
# Issue #2442.
def ls_nonhead(sbox):
"ls a path no longer in HEAD"
sbox.build()
wc_dir = sbox.wc_dir
# Delete A/D/rho and commit.
G_path = os.path.join(wc_dir, 'A', 'D', 'G')
svntest.actions.run_and_verify_svn("error scheduling A/D/G for deletion",
None, [], 'rm', G_path)
expected_output = wc.State(wc_dir, {
'A/D/G' : Item(verb='Deleting'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.remove('A/D/G', 'A/D/G/rho', 'A/D/G/pi', 'A/D/G/tau',)
svntest.actions.run_and_verify_commit(wc_dir,
expected_output, expected_status,
None, None, None, None, None,
wc_dir)
# Check that we can list a file in A/D/G at revision 1.
rho_url = sbox.repo_url + "/A/D/G/rho"
svntest.actions.run_and_verify_svn(None, '.* rho\n', [],
'ls', '--verbose', rho_url + '@1')
#----------------------------------------------------------------------
# Issue #2315.
def cat_added_PREV(sbox):
"cat added file using -rPREV"
sbox.build()
wc_dir = sbox.wc_dir
f_path = os.path.join(wc_dir, 'f')
# Create and add a file.
svntest.main.file_append (f_path, 'new text')
svntest.actions.run_and_verify_svn("adding file",
None, [], 'add', f_path)
# Cat'ing the previous version should fail.
svntest.actions.run_and_verify_svn("cat PREV version of file",
None, ".*has no committed revision.*",
'cat', '-rPREV', f_path)
def checkout_creates_intermediate_folders(sbox):
"checkout and create some intermediate folders"
sbox.build(create_wc = False)
checkout_target = os.path.join(sbox.wc_dir, 'a', 'b', 'c')
# checkout a working copy in a/b/c, should create these intermediate
# folders
expected_output = svntest.main.greek_state.copy()
expected_output.wc_dir = checkout_target
expected_output.tweak(status='A ', contents=None)
expected_wc = svntest.main.greek_state
svntest.actions.run_and_verify_checkout(sbox.repo_url,
checkout_target,
expected_output,
expected_wc)
# Test that, if a peg revision is provided without an explicit revision,
# svn will checkout the directory as it was at rPEG, rather than at HEAD.
def checkout_peg_rev(sbox):
"checkout with peg revision"
sbox.build()
wc_dir = sbox.wc_dir
# create a new revision
mu_path = os.path.join(wc_dir, 'A', 'mu')
svntest.main.file_append (mu_path, 'appended mu text')
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'changed file mu', wc_dir)
# now checkout the repo@1 in another folder, this should create our initial
# wc without the change in mu.
checkout_target = sbox.add_wc_path('checkout')
os.mkdir(checkout_target)
expected_output = svntest.main.greek_state.copy()
expected_output.wc_dir = checkout_target
expected_output.tweak(status='A ', contents=None)
expected_wc = svntest.main.greek_state.copy()
svntest.actions.run_and_verify_checkout(sbox.repo_url + '@1',
checkout_target,
expected_output,
expected_wc)
# Issue #2612.
def ls_space_in_repo_name(sbox):
'basic ls of repos with space in name'
sbox.build(name = "repo with spaces")
wc_dir = sbox.wc_dir
svntest.actions.run_and_verify_svn('ls the root of the repository',
['A/\n', 'iota\n'],
[], 'ls',
'--username', svntest.main.wc_author,
'--password', svntest.main.wc_passwd,
sbox.repo_url)
########################################################################
# Run the tests
# list all tests here, starting with None:
test_list = [ None,
basic_checkout,
basic_status,
basic_commit,
basic_update,
basic_mkdir_url,
basic_corruption,
basic_merging_update,
basic_conflict,
basic_cleanup,
basic_revert,
basic_switch,
basic_delete,
basic_checkout_deleted,
basic_node_kind_change,
basic_import,
basic_cat,
basic_ls,
nonexistent_repository,
basic_auth_cache,
basic_add_ignores,
uri_syntax,
basic_checkout_file,
basic_info,
basic_add_local_ignores,
basic_add_no_ignores,
repos_root,
basic_peg_revision,
info_nonhead,
ls_nonhead,
cat_added_PREV,
checkout_creates_intermediate_folders,
checkout_peg_rev,
ls_space_in_repo_name,
### todo: more tests needed:
### test "svn rm http://some_url"
### not sure this file is the right place, though.
]
if __name__ == '__main__':
svntest.main.run_tests(test_list)
# NOTREACHED
### End of file.
syntax highlighted by Code2HTML, v. 0.9.1