3
# special_tests.py: testing special file handling
5
# Subversion is a tool for revision control.
6
# See http://subversion.tigris.org for more information.
8
# ====================================================================
9
# Copyright (c) 2000-2004 CollabNet. All rights reserved.
11
# This software is licensed as described in the file COPYING, which
12
# you should have received as part of this distribution. The terms
13
# are also available at http://subversion.tigris.org/license-1.html.
14
# If newer versions of this license are posted there, you may use a
15
# newer version instead, at your option.
17
######################################################################
27
Skip = svntest.testcase.Skip
28
XFail = svntest.testcase.XFail
29
Item = svntest.wc.StateItem
32
######################################################################
35
# Each test must return on success or raise on failure.
38
#----------------------------------------------------------------------
40
def general_symlink(sbox):
41
"general symlink handling"
46
# First try to just commit a symlink
47
newfile_path = os.path.join(wc_dir, 'newfile')
48
linktarget_path = os.path.join(wc_dir, 'linktarget')
49
svntest.main.file_append(linktarget_path, 'this is just a link target')
50
os.symlink('linktarget', newfile_path)
51
svntest.main.run_svn(None, 'add', newfile_path, linktarget_path)
53
expected_output = svntest.wc.State(wc_dir, {
54
'newfile' : Item(verb='Adding'),
55
'linktarget' : Item(verb='Adding'),
58
# Run a diff and verify that we get the correct output
59
stdout_lines, stderr_lines = svntest.main.run_svn(1, 'diff', wc_dir)
61
regex = '^\+link linktarget'
62
for line in stdout_lines:
63
if re.match(regex, line):
68
# Commit and make sure everything is good
69
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
70
expected_status.tweak(wc_rev=1)
72
'newfile' : Item(status=' ', wc_rev=2),
73
'linktarget' : Item(status=' ', wc_rev=2),
76
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
77
expected_status, None,
78
None, None, None, None, wc_dir)
80
## Now we should update to the previous version, verify that no
81
## symlink is present, then update back to HEAD and see if the symlink
82
## is regenerated properly.
83
svntest.actions.run_and_verify_svn(None, None, [],
84
'up', '-r', '1', wc_dir)
86
# Is the symlink gone?
87
if os.path.isfile(newfile_path) or os.path.islink(newfile_path):
90
svntest.actions.run_and_verify_svn(None, None, [],
91
'up', '-r', '2', wc_dir)
93
# Is the symlink back?
94
new_target = os.readlink(newfile_path)
95
if new_target != 'linktarget':
98
## Now change the target of the symlink, verify that it is shown as
99
## modified and that a commit succeeds.
100
os.remove(newfile_path)
101
os.symlink('A', newfile_path)
103
was_cwd = os.getcwd()
105
svntest.actions.run_and_verify_svn(None, [ "M newfile\n" ], [], 'st')
109
expected_output = svntest.wc.State(wc_dir, {
110
'newfile' : Item(verb='Sending'),
113
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
114
expected_status.tweak(wc_rev=2)
115
expected_status.add({
116
'newfile' : Item(status=' ', wc_rev=3),
117
'linktarget' : Item(status=' ', wc_rev=2),
120
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
121
expected_status, None,
122
None, None, None, None, wc_dir)
125
def replace_file_with_symlink(sbox):
126
"replace a normal file with a special file"
131
# First replace a normal file with a symlink and make sure we get an
133
iota_path = os.path.join(wc_dir, 'iota')
135
os.symlink('A', iota_path)
137
# Does status show the obstruction?
138
was_cwd = os.getcwd()
140
svntest.actions.run_and_verify_svn(None, [ "~ iota\n" ], [], 'st')
142
# And does a commit fail?
144
stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
147
regex = 'svn: Commit failed'
148
for line in stderr_lines:
149
if re.match(regex, line):
152
raise svntest.Failure
155
def import_export_symlink(sbox):
156
"import and export a symlink"
161
# create a new symlink to import
162
new_path = os.path.join(wc_dir, 'new_file')
164
os.symlink('linktarget', new_path)
166
# import this symlink into the repository
167
url = svntest.main.current_repo_url + "/dirA/dirB/new_link"
168
output, errput = svntest.actions.run_and_verify_svn(
169
'Import a symlink', None, [], 'import',
170
'-m', 'log msg', new_path, url)
172
regex = "(Committed|Imported) revision [0-9]+."
174
if re.match(regex, line):
177
raise svntest.Failure
179
# remove the unversioned link
182
# run update and verify that the symlink is put back into place
183
svntest.actions.run_and_verify_svn(None, None, [],
186
# Is the symlink back?
187
link_path = wc_dir + "/dirA/dirB/new_link"
188
new_target = os.readlink(link_path)
189
if new_target != 'linktarget':
190
raise svntest.Failure
192
## Now we will try exporting from both the working copy and the
193
## repository directly, verifying that the symlink is created in
196
for export_src, dest_dir in [(sbox.wc_dir, 'export-wc'),
197
(sbox.repo_url, 'export-url')]:
198
export_target = sbox.add_wc_path(dest_dir)
199
svntest.actions.run_and_verify_svn(None, None, [],
200
'export', export_src, export_target)
202
# is the link at the correct place?
203
link_path = os.path.join(export_target, "dirA/dirB/new_link")
204
new_target = os.readlink(link_path)
205
if new_target != 'linktarget':
206
raise svntest.Failure
209
#----------------------------------------------------------------------
210
# Regression test for issue 1986
212
def copy_tree_with_symlink(sbox):
213
"'svn cp dir1 dir2' which contains a symlink"
218
# Create a versioned symlink within directory 'A/D/H'.
219
newfile_path = os.path.join(wc_dir, 'A', 'D', 'H', 'newfile')
220
linktarget_path = os.path.join(wc_dir, 'A', 'D', 'H', 'linktarget')
221
svntest.main.file_append(linktarget_path, 'this is just a link target')
222
os.symlink('linktarget', newfile_path)
223
svntest.main.run_svn(None, 'add', newfile_path, linktarget_path)
225
expected_output = svntest.wc.State(wc_dir, {
226
'A/D/H/newfile' : Item(verb='Adding'),
227
'A/D/H/linktarget' : Item(verb='Adding'),
230
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
231
expected_status.tweak(wc_rev=1)
232
expected_status.add({
233
'A/D/H/newfile' : Item(status=' ', wc_rev=2),
234
'A/D/H/linktarget' : Item(status=' ', wc_rev=2),
237
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
238
expected_status, None,
239
None, None, None, None, wc_dir)
241
H_path = os.path.join(wc_dir, 'A', 'D', 'H')
242
H2_path = os.path.join(wc_dir, 'A', 'D', 'H2')
243
svntest.actions.run_and_verify_svn(None, None, [], 'cp', H_path, H2_path)
245
# 'svn status' should show just "A/D/H2 A +". Nothing broken.
246
expected_status.add({
247
'A/D/H2' : Item(status='A ', copied='+', wc_rev='-'),
248
'A/D/H2/chi' : Item(status=' ', copied='+', wc_rev='-'),
249
'A/D/H2/omega' : Item(status=' ', copied='+', wc_rev='-'),
250
'A/D/H2/psi' : Item(status=' ', copied='+', wc_rev='-'),
251
'A/D/H2/linktarget' : Item(status=' ', copied='+', wc_rev='-'),
252
'A/D/H2/newfile' : Item(status=' ', copied='+', wc_rev='-'),
254
svntest.actions.run_and_verify_status (wc_dir, expected_status)
257
def replace_symlink_with_file(sbox):
258
"replace a special file with a non-special file"
263
# Create a new special file and commit it.
264
newfile_path = os.path.join(wc_dir, 'newfile')
265
linktarget_path = os.path.join(wc_dir, 'linktarget')
266
svntest.main.file_append(linktarget_path, 'this is just a link target')
267
os.symlink('linktarget', newfile_path)
268
svntest.main.run_svn(None, 'add', newfile_path, linktarget_path)
270
expected_output = svntest.wc.State(wc_dir, {
271
'newfile' : Item(verb='Adding'),
272
'linktarget' : Item(verb='Adding'),
275
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
276
expected_status.tweak(wc_rev=1)
277
expected_status.add({
278
'newfile' : Item(status=' ', wc_rev=2),
279
'linktarget' : Item(status=' ', wc_rev=2),
282
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
283
expected_status, None,
284
None, None, None, None, wc_dir)
287
# Now replace the symlink with a normal file and try to commit, we
288
# should get an error
289
os.remove(newfile_path);
290
svntest.main.file_append(newfile_path, "text of actual file");
292
# Does status show the obstruction?
293
was_cwd = os.getcwd()
295
svntest.actions.run_and_verify_svn(None, [ "~ newfile\n" ], [], 'st')
297
# And does a commit fail?
299
stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
302
regex = 'svn: Commit failed'
303
for line in stderr_lines:
304
if re.match(regex, line):
307
raise svntest.Failure
310
def remove_symlink(sbox):
317
newfile_path = os.path.join(wc_dir, 'newfile')
318
linktarget_path = os.path.join(wc_dir, 'linktarget')
319
svntest.main.file_append(linktarget_path, 'this is just a link target')
320
os.symlink('linktarget', newfile_path)
321
svntest.main.run_svn(None, 'add', newfile_path, linktarget_path)
323
expected_output = svntest.wc.State(wc_dir, {
324
'newfile' : Item(verb='Adding'),
325
'linktarget' : Item(verb='Adding'),
328
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
329
expected_status.tweak(wc_rev=1)
330
expected_status.add({
331
'newfile' : Item(status=' ', wc_rev=2),
332
'linktarget' : Item(status=' ', wc_rev=2),
335
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
336
expected_status, None,
337
None, None, None, None, wc_dir)
340
svntest.actions.run_and_verify_svn("", None, [], 'rm', newfile_path)
342
# Commit and verify that it worked
343
expected_output = svntest.wc.State(wc_dir, {
344
'newfile' : Item(verb='Deleting'),
347
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
348
expected_status.tweak(wc_rev=1)
349
expected_status.add({
350
'linktarget' : Item(status=' ', wc_rev=2),
353
svntest.actions.run_and_verify_commit(wc_dir, expected_output,
354
expected_status, None,
355
None, None, None, None, wc_dir)
358
########################################################################
362
# list all tests here, starting with None:
364
Skip(general_symlink, (os.name != 'posix')),
365
Skip(replace_file_with_symlink, (os.name != 'posix')),
366
Skip(import_export_symlink, (os.name != 'posix')),
367
Skip(copy_tree_with_symlink, (os.name != 'posix')),
368
Skip(replace_symlink_with_file, (os.name != 'posix')),
369
Skip(remove_symlink, (os.name != 'posix')),
372
if __name__ == '__main__':
373
svntest.main.run_tests(test_list)