Fix compiler warning due to missing function prototype.
[svn.git] / subversion / tests / cmdline / lock_tests.py
blob5c5bca2ad7f99ec3bc4060ae60a4de9b83ded476
1 #!/usr/bin/env python
3 # lock_tests.py: testing versioned properties
5 # Subversion is a tool for revision control.
6 # See http://subversion.tigris.org for more information.
8 # ====================================================================
9 # Copyright (c) 2005-2006 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 ######################################################################
19 # General modules
20 import re, os, stat
22 # Our testing module
23 import svntest
25 # (abbreviation)
26 Skip = svntest.testcase.Skip
27 SkipUnless = svntest.testcase.SkipUnless
28 XFail = svntest.testcase.XFail
29 Item = svntest.wc.StateItem
31 ######################################################################
32 # Tests
34 #----------------------------------------------------------------------
35 # Each test refers to a section in
36 # notes/locking/locking-functional-spec.txt
38 # II.A.2, II.C.2.a: Lock a file in wc A as user FOO and make sure we
39 # have a representation of it. Checkout wc B as user BAR. Verify
40 # that user BAR cannot commit changes to the file nor its properties.
41 def lock_file(sbox):
42 "lock a file and verify that it's locked"
44 sbox.build()
45 wc_dir = sbox.wc_dir
47 # Make a second copy of the working copy
48 wc_b = sbox.add_wc_path('_b')
49 svntest.actions.duplicate_dir(wc_dir, wc_b)
51 # lock a file as wc_author
52 fname = 'iota'
53 file_path = os.path.join(sbox.wc_dir, fname)
54 file_path_b = os.path.join(wc_b, fname)
56 svntest.main.file_append(file_path, "This represents a binary file\n")
57 svntest.main.run_svn(None, 'commit',
58 '-m', '', file_path)
59 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
60 '-m', '', file_path)
62 # --- Meanwhile, in our other working copy... ---
63 err_re = "((.*User jconstant does not own lock on path.*)|(.*423 Locked.*))"
65 svntest.main.run_svn(None, 'update', wc_b)
66 # -- Try to change a file --
67 # change the locked file
68 svntest.main.file_append(file_path_b, "Covert tweak\n")
70 # attempt (and fail) to commit as user Sally
71 svntest.actions.run_and_verify_commit(wc_b, None, None, err_re,
72 '--username',
73 svntest.main.wc_author2,
74 '-m', '', file_path_b)
76 # Revert our change that we failed to commit
77 svntest.main.run_svn(None, 'revert', file_path_b)
79 # -- Try to change a property --
80 # change the locked file's properties
81 svntest.main.run_svn(None, 'propset', 'sneakyuser', 'Sally', file_path_b)
83 err_re = "((.*User jconstant does not own lock on path.*)" + \
84 "|(.*At least one property change failed.*))"
86 # attempt (and fail) to commit as user Sally
87 svntest.actions.run_and_verify_commit(wc_b, None, None, err_re,
88 '--username',
89 svntest.main.wc_author2,
90 '-m', '', file_path_b)
95 #----------------------------------------------------------------------
96 # II.C.2.b.[12]: Lock a file and commit using the lock. Make sure the
97 # lock is released. Repeat, but request that the lock not be
98 # released. Make sure the lock is retained.
99 def commit_file_keep_lock(sbox):
100 "commit a file and keep lock"
102 sbox.build()
103 wc_dir = sbox.wc_dir
105 fname = 'A/mu'
106 file_path = os.path.join(sbox.wc_dir, fname)
108 # lock fname as wc_author
109 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
110 '-m', 'some lock comment', file_path)
112 # make a change and commit it, holding lock
113 svntest.main.file_append(file_path, "Tweak!\n")
114 svntest.main.run_svn(None, 'commit', '-m', '', '--no-unlock',
115 file_path)
117 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
118 expected_status.tweak(fname, wc_rev=2)
119 expected_status.tweak(fname, writelocked='K')
121 # Make sure the file is still locked
122 svntest.actions.run_and_verify_status(wc_dir, expected_status)
124 def commit_file_unlock(sbox):
125 "commit a file and release lock"
127 sbox.build()
128 wc_dir = sbox.wc_dir
130 fname = 'A/mu'
131 file_path = os.path.join(sbox.wc_dir, fname)
133 # lock fname as wc_author
134 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
135 '-m', 'some lock comment', file_path)
137 # make a change and commit it, allowing lock to be released
138 svntest.main.file_append(file_path, "Tweak!\n")
139 svntest.main.run_svn(None, 'commit', '-m', '',
140 file_path)
142 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
143 expected_status.tweak(fname, wc_rev=2)
145 # Make sure the file is unlocked
146 svntest.actions.run_and_verify_status(wc_dir, expected_status)
148 #----------------------------------------------------------------------
149 def commit_propchange(sbox):
150 "commit a locked file with a prop change"
152 sbox.build()
153 wc_dir = sbox.wc_dir
155 fname = 'A/mu'
156 file_path = os.path.join(sbox.wc_dir, fname)
158 # lock fname as wc_author
159 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
160 '-m', 'some lock comment', file_path)
162 # make a property change and commit it, allowing lock to be released
163 svntest.main.run_svn(None, 'propset', 'blue', 'azul', file_path)
164 svntest.main.run_svn(None, 'commit',
165 '-m', '', file_path)
167 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
168 expected_status.tweak(fname, wc_rev=2)
170 # Make sure the file is unlocked
171 svntest.actions.run_and_verify_status(wc_dir, expected_status)
173 #----------------------------------------------------------------------
174 # II.C.2.c: Lock a file in wc A as user FOO. Attempt to unlock same
175 # file in same wc as user BAR. Should fail.
177 # Attempt again with --force. Should succeed.
179 # II.C.2.c: Lock a file in wc A as user FOO. Attempt to unlock same
180 # file in wc B as user FOO. Should fail.
182 # Attempt again with --force. Should succeed.
183 def break_lock(sbox):
184 "lock a file and verify lock breaking behavior"
186 sbox.build()
187 wc_dir = sbox.wc_dir
189 # Make a second copy of the working copy
190 wc_b = sbox.add_wc_path('_b')
191 svntest.actions.duplicate_dir(wc_dir, wc_b)
193 # lock a file as wc_author
194 fname = 'iota'
195 file_path = os.path.join(sbox.wc_dir, fname)
196 file_path_b = os.path.join(wc_b, fname)
198 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
199 '-m', '', file_path)
201 # --- Meanwhile, in our other working copy... ---
203 svntest.main.run_svn(None, 'update', wc_b)
205 # attempt (and fail) to unlock file
207 # This should give a "iota' is not locked in this working copy" error
208 svntest.actions.run_and_verify_svn(None, None, ".*not locked",
209 'unlock',
210 file_path_b)
212 svntest.actions.run_and_verify_svn(None, ".*unlocked", [],
213 'unlock', '--force',
214 file_path_b)
216 #----------------------------------------------------------------------
217 # II.C.2.d: Lock a file in wc A as user FOO. Attempt to lock same
218 # file in wc B as user BAR. Should fail.
220 # Attempt again with --force. Should succeed.
222 # II.C.2.d: Lock a file in wc A as user FOO. Attempt to lock same
223 # file in wc B as user FOO. Should fail.
225 # Attempt again with --force. Should succeed.
226 def steal_lock(sbox):
227 "lock a file and verify lock stealing behavior"
229 sbox.build()
230 wc_dir = sbox.wc_dir
232 # Make a second copy of the working copy
233 wc_b = sbox.add_wc_path('_b')
234 svntest.actions.duplicate_dir(wc_dir, wc_b)
236 # lock a file as wc_author
237 fname = 'iota'
238 file_path = os.path.join(sbox.wc_dir, fname)
239 file_path_b = os.path.join(wc_b, fname)
241 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
242 '-m', '', file_path)
244 # --- Meanwhile, in our other working copy... ---
246 svntest.main.run_svn(None, 'update', wc_b)
248 # attempt (and fail) to lock file
250 # This should give a "iota' is already locked... error, but exits 0.
251 svntest.actions.run_and_verify_svn2(None, None,
252 ".*already locked", 0,
253 'lock',
254 '-m', 'trying to break', file_path_b)
256 svntest.actions.run_and_verify_svn(None, ".*locked by user", [],
257 'lock', '--force',
258 '-m', 'trying to break', file_path_b)
260 #----------------------------------------------------------------------
261 # II.B.2, II.C.2.e: Lock a file in wc A. Query wc for the
262 # lock and verify that all lock fields are present and correct.
263 def examine_lock(sbox):
264 "examine the fields of a lockfile for correctness"
266 sbox.build()
267 wc_dir = sbox.wc_dir
269 fname = 'iota'
270 comment = 'This is a lock test.'
271 file_path = os.path.join(sbox.wc_dir, fname)
273 # lock a file as wc_author
274 svntest.actions.run_and_validate_lock(file_path,
275 svntest.main.wc_author)
277 #----------------------------------------------------------------------
278 # II.C.1: Lock a file in wc A. Check out wc B. Break the lock in wc
279 # B. Verify that wc A gracefully cleans up the lock via update as
280 # well as via commit.
281 def handle_defunct_lock(sbox):
282 "verify behavior when a lock in a wc is defunct"
284 sbox.build()
285 wc_dir = sbox.wc_dir
288 fname = 'iota'
289 file_path = os.path.join(sbox.wc_dir, fname)
291 # set up our expected status
292 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
294 # lock the file
295 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
296 '-m', '', file_path)
298 # Make a second copy of the working copy
299 wc_b = sbox.add_wc_path('_b')
300 svntest.actions.duplicate_dir(wc_dir, wc_b)
301 file_path_b = os.path.join(wc_b, fname)
303 # --- Meanwhile, in our other working copy... ---
305 # Try unlocking the file in the second wc.
306 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
307 file_path_b)
310 # update the 1st wc, which should clear the lock there
311 svntest.main.run_svn(None, 'update', wc_dir)
313 # Make sure the file is unlocked
314 svntest.actions.run_and_verify_status(wc_dir, expected_status)
318 #----------------------------------------------------------------------
319 # II.B.1: Set "svn:needs-lock" property on file in wc A. Checkout wc
320 # B and verify that that file is set as read-only.
322 # Tests propset, propdel, lock, and unlock
323 def enforce_lock(sbox):
324 "verify svn:needs-lock read-only behavior"
326 sbox.build()
327 wc_dir = sbox.wc_dir
329 iota_path = os.path.join(wc_dir, 'iota')
330 lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
331 mu_path = os.path.join(wc_dir, 'A', 'mu')
333 # Set some binary properties.
334 propval_path = os.path.join(wc_dir, 'propval.tmp')
336 # svn:needs-lock value should be forced to a '*'
337 svntest.actions.set_prop(None, 'svn:needs-lock', 'foo', iota_path,
338 propval_path)
339 svntest.actions.set_prop(None, 'svn:needs-lock', '*', lambda_path,
340 propval_path)
341 expected_err = ".*svn: warning: To turn off the svn:needs-lock property,.*"
342 svntest.actions.set_prop(expected_err, 'svn:needs-lock', ' ',
343 mu_path, propval_path)
345 # Check svn:needs-lock
346 svntest.actions.check_prop('svn:needs-lock', iota_path, ['*'])
347 svntest.actions.check_prop('svn:needs-lock', lambda_path, ['*'])
348 svntest.actions.check_prop('svn:needs-lock', mu_path, ['*'])
350 svntest.main.run_svn(None, 'commit',
351 '-m', '', iota_path, lambda_path, mu_path)
353 # Now make sure that the perms were flipped on all files
354 if os.name == 'posix':
355 mode = stat.S_IWGRP | stat.S_IWOTH | stat.S_IWRITE
356 if ((os.stat(iota_path)[0] & mode)
357 or (os.stat(lambda_path)[0] & mode)
358 or (os.stat(mu_path)[0] & mode)):
359 print "Setting 'svn:needs-lock' property on a file failed to set"
360 print "file mode to read-only."
361 raise svntest.Failure
363 # obtain a lock on one of these files...
364 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
365 '-m', '', iota_path)
367 # ...and verify that the write bit gets set...
368 if not (os.stat(iota_path)[0] & mode):
369 print "Locking a file with 'svn:needs-lock' failed to set write bit."
370 raise svntest.Failure
372 # ...and unlock it...
373 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
374 iota_path)
376 # ...and verify that the write bit gets unset
377 if (os.stat(iota_path)[0] & mode):
378 print "Unlocking a file with 'svn:needs-lock' failed to unset write bit."
379 raise svntest.Failure
381 # Verify that removing the property restores the file to read-write
382 svntest.main.run_svn(None, 'propdel', 'svn:needs-lock', iota_path)
383 if not (os.stat(iota_path)[0] & mode):
384 print "Deleting 'svn:needs-lock' failed to set write bit."
385 raise svntest.Failure
387 #----------------------------------------------------------------------
388 # Test that updating a file with the "svn:needs-lock" property works,
389 # especially on Windows, where renaming A to B fails if B already
390 # exists and has its read-only bit set. See also issue #2278.
391 def update_while_needing_lock(sbox):
392 "update handles svn:needs-lock correctly"
394 sbox.build()
395 wc_dir = sbox.wc_dir
397 iota_path = os.path.join(wc_dir, 'iota')
398 svntest.main.run_svn(None,
399 'propset', 'svn:needs-lock', 'foo', iota_path)
400 svntest.main.run_svn(None,
401 'commit', '-m', 'log msg', iota_path)
402 svntest.main.run_svn(None,
403 'up', wc_dir)
405 # Lock, modify, commit, unlock, to create r3.
406 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
407 '-m', '', iota_path)
408 svntest.main.file_append(iota_path, "This line added in r2.\n")
409 svntest.main.run_svn(None, 'commit',
410 '-m', '', iota_path) # auto-unlocks
412 # Backdate to r2.
413 svntest.main.run_svn(None,
414 'update', '-r2', iota_path)
416 # Try updating forward to r3 again. This is where the bug happened.
417 svntest.main.run_svn(None,
418 'update', '-r3', iota_path)
421 #----------------------------------------------------------------------
422 # Tests update / checkout with changing props
423 def defunct_lock(sbox):
424 "verify svn:needs-lock behavior with defunct lock"
426 sbox.build()
427 wc_dir = sbox.wc_dir
429 # Make a second copy of the working copy
430 wc_b = sbox.add_wc_path('_b')
431 svntest.actions.duplicate_dir(wc_dir, wc_b)
433 iota_path = os.path.join(wc_dir, 'iota')
434 iota_path_b = os.path.join(wc_b, 'iota')
436 mode = stat.S_IWGRP | stat.S_IWOTH | stat.S_IWRITE
438 # Set the prop in wc a
439 svntest.main.run_svn(None, 'propset', 'svn:needs-lock', 'foo', iota_path)
441 # commit r2
442 svntest.main.run_svn(None, 'commit',
443 '-m', '', iota_path)
445 # update wc_b
446 svntest.main.run_svn(None, 'update', wc_b)
448 # lock iota in wc_b
449 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
450 '-m', '', iota_path_b)
453 # break the lock iota in wc a
454 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock', '--force',
455 '-m', '', iota_path)
456 # update wc_b
457 svntest.main.run_svn(None, 'update', wc_b)
459 # make sure that iota got set to read-only
460 if (os.stat(iota_path_b)[0] & mode):
461 print "Upon removal of a defunct lock, a file with 'svn:needs-lock'"
462 print "was not set back to read-only"
463 raise svntest.Failure
467 #----------------------------------------------------------------------
468 # Tests dealing with a lock on a deleted path
469 def deleted_path_lock(sbox):
470 "verify lock removal on a deleted path"
472 sbox.build()
473 wc_dir = sbox.wc_dir
475 iota_path = os.path.join(wc_dir, 'iota')
476 iota_url = sbox.repo_url + '/iota'
478 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
479 '-m', '', iota_path)
481 svntest.actions.run_and_verify_svn(None, None, [], 'delete', iota_path)
483 svntest.actions.run_and_verify_svn(None, None, [], 'commit',
484 '--no-unlock',
485 '-m', '', iota_path)
487 # Now make sure that we can delete the lock from iota via a URL
488 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
489 iota_url)
493 #----------------------------------------------------------------------
494 # Tests dealing with locking and unlocking
495 def lock_unlock(sbox):
496 "lock and unlock some files"
498 sbox.build()
499 wc_dir = sbox.wc_dir
501 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
502 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
503 tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
505 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
506 expected_status.tweak('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', writelocked='K')
508 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
509 '-m', '', pi_path, rho_path, tau_path)
511 svntest.actions.run_and_verify_status(wc_dir, expected_status)
513 expected_status.tweak('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', writelocked=None)
515 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
516 pi_path, rho_path, tau_path)
518 svntest.actions.run_and_verify_status(wc_dir, expected_status)
520 #----------------------------------------------------------------------
521 # Tests dealing with directory deletion and locks
522 def deleted_dir_lock(sbox):
523 "verify removal of a directory with locks inside"
525 sbox.build()
526 wc_dir = sbox.wc_dir
528 parent_dir = os.path.join(wc_dir, 'A', 'D', 'G')
529 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
530 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
531 tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
533 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
534 '-m', '', pi_path, rho_path, tau_path)
536 svntest.actions.run_and_verify_svn(None, None, [], 'delete', parent_dir)
538 svntest.actions.run_and_verify_svn(None, None, [], 'commit',
539 '--no-unlock',
540 '-m', '', parent_dir)
542 #----------------------------------------------------------------------
543 # III.c : Lock a file and check the output of 'svn stat' from the same
544 # working copy and another.
545 def lock_status(sbox):
546 "verify status of lock in working copy"
547 sbox.build()
548 wc_dir = sbox.wc_dir
550 # Make a second copy of the working copy
551 wc_b = sbox.add_wc_path('_b')
552 svntest.actions.duplicate_dir(wc_dir, wc_b)
554 # lock a file as wc_author
555 fname = 'iota'
556 file_path = os.path.join(sbox.wc_dir, fname)
558 svntest.main.file_append(file_path, "This is a spreadsheet\n")
559 svntest.main.run_svn(None, 'commit',
560 '-m', '', file_path)
562 svntest.main.run_svn(None, 'lock',
563 '-m', '', file_path)
565 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
566 expected_status.tweak(fname, wc_rev=2)
567 expected_status.tweak(fname, writelocked='K')
569 svntest.actions.run_and_verify_status(wc_dir, expected_status)
571 # Verify status again after modifying the file
572 svntest.main.file_append(file_path, "check stat output after mod")
574 expected_status.tweak(fname, status='M ')
576 svntest.actions.run_and_verify_status(wc_dir, expected_status)
578 # Verify status of lock from another working copy
579 svntest.main.run_svn(None, 'update', wc_b)
580 expected_status = svntest.actions.get_virginal_state(wc_b, 2)
581 expected_status.tweak(fname, writelocked='O')
583 svntest.actions.run_and_verify_status(wc_b, expected_status)
585 #----------------------------------------------------------------------
586 # III.c : Steal lock on a file from another working copy with 'svn lock
587 # --force', and check the status of lock in the repository from the
588 # working copy in which the file was initially locked.
589 def stolen_lock_status(sbox):
590 "verify status of stolen lock"
591 sbox.build()
592 wc_dir = sbox.wc_dir
594 # Make a second copy of the working copy
595 wc_b = sbox.add_wc_path('_b')
596 svntest.actions.duplicate_dir(wc_dir, wc_b)
598 # lock a file as wc_author
599 fname = 'iota'
600 file_path = os.path.join(sbox.wc_dir, fname)
601 file_path_b = os.path.join(wc_b, fname)
603 svntest.main.file_append(file_path, "This is a spreadsheet\n")
604 svntest.main.run_svn(None, 'commit',
605 '-m', '', file_path)
607 svntest.main.run_svn(None, 'lock',
608 '-m', '', file_path)
610 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
611 expected_status.tweak(fname, wc_rev=2)
612 expected_status.tweak(fname, writelocked='K')
614 svntest.actions.run_and_verify_status(wc_dir, expected_status)
616 # Forcibly lock same file (steal lock) from another working copy
617 svntest.main.run_svn(None, 'update', wc_b)
618 svntest.main.run_svn(None, 'lock',
619 '-m', '', '--force', file_path_b)
621 # Verify status from working copy where file was initially locked
622 expected_status.tweak(fname, writelocked='T')
623 svntest.actions.run_and_verify_status(wc_dir, expected_status)
625 #----------------------------------------------------------------------
626 # III.c : Break lock from another working copy with 'svn unlock --force'
627 # and verify the status of the lock in the repository with 'svn stat -u'
628 # from the working copy in the file was initially locked
629 def broken_lock_status(sbox):
630 "verify status of broken lock"
631 sbox.build()
632 wc_dir = sbox.wc_dir
634 # Make a second copy of the working copy
635 wc_b = sbox.add_wc_path('_b')
636 svntest.actions.duplicate_dir(wc_dir, wc_b)
638 # lock a file as wc_author
639 fname = 'iota'
640 file_path = os.path.join(sbox.wc_dir, fname)
641 file_path_b = os.path.join(wc_b, fname)
643 svntest.main.file_append(file_path, "This is a spreadsheet\n")
644 svntest.main.run_svn(None, 'commit',
645 '-m', '', file_path)
646 svntest.main.run_svn(None, 'lock',
647 '-m', '', file_path)
649 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
650 expected_status.tweak(fname, wc_rev=2)
651 expected_status.tweak(fname, writelocked='K')
653 svntest.actions.run_and_verify_status(wc_dir, expected_status)
655 # Forcibly unlock the same file (break lock) from another working copy
656 svntest.main.run_svn(None, 'update', wc_b)
657 svntest.main.run_svn(None, 'unlock',
658 '--force', file_path_b)
660 # Verify status from working copy where file was initially locked
661 expected_status.tweak(fname, writelocked='B')
663 svntest.actions.run_and_verify_status(wc_dir, expected_status)
665 #----------------------------------------------------------------------
666 # Invalid input test - lock non-existent file
667 def lock_non_existent_file(sbox):
668 "verify error on locking non-existent file"
670 sbox.build()
671 fname = 'A/foo'
672 file_path = os.path.join(sbox.wc_dir, fname)
674 exit_code, output, error = svntest.main.run_svn(1, 'lock',
675 '-m', '', file_path)
677 error_msg = "foo' is not under version control"
678 for line in error:
679 if line.find(error_msg) != -1:
680 break
681 else:
682 print "Error:", error_msg, ": not found in:", error
683 raise svntest.Failure
685 #----------------------------------------------------------------------
686 # Check that locking an out-of-date file fails.
687 def out_of_date(sbox):
688 "lock an out-of-date file and ensure failure"
690 sbox.build()
691 wc_dir = sbox.wc_dir
693 # Make a second copy of the working copy
694 wc_b = sbox.add_wc_path('_b')
695 svntest.actions.duplicate_dir(wc_dir, wc_b)
697 fname = 'iota'
698 file_path = os.path.join(sbox.wc_dir, fname)
699 file_path_b = os.path.join(wc_b, fname)
701 # Make a new revision of the file in the first WC.
702 svntest.main.file_append(file_path, "This represents a binary file\n")
703 svntest.main.run_svn(None, 'commit',
704 '-m', '', file_path)
706 # --- Meanwhile, in our other working copy... ---
707 svntest.actions.run_and_verify_svn2(None, None,
708 ".*newer version of '/iota' exists", 0,
709 'lock',
710 '--username', svntest.main.wc_author2,
711 '-m', '', file_path_b)
713 #----------------------------------------------------------------------
714 # Tests reverting a svn:needs-lock file
715 def revert_lock(sbox):
716 "verify svn:needs-lock behavior with revert"
718 sbox.build()
719 wc_dir = sbox.wc_dir
721 iota_path = os.path.join(wc_dir, 'iota')
723 mode = stat.S_IWGRP | stat.S_IWOTH | stat.S_IWRITE
725 # set the prop in wc
726 svntest.actions.run_and_verify_svn(None, None, [], 'propset',
727 'svn:needs-lock', 'foo', iota_path)
729 # commit r2
730 svntest.actions.run_and_verify_svn(None, None, [], 'commit',
731 '-m', '', iota_path)
733 # make sure that iota got set to read-only
734 if (os.stat(iota_path)[0] & mode):
735 print "Committing a file with 'svn:needs-lock'"
736 print "did not set the file to read-only"
737 raise svntest.Failure
739 # verify status is as we expect
740 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
741 expected_status.tweak('iota', wc_rev=2)
742 svntest.actions.run_and_verify_status(wc_dir, expected_status)
744 # remove read-only-ness
745 svntest.actions.run_and_verify_svn(None, None, [], 'propdel',
746 'svn:needs-lock', iota_path)
748 # make sure that iota got read-only-ness removed
749 if (os.stat(iota_path)[0] & mode == 0):
750 print "Deleting the 'svn:needs-lock' property "
751 print "did not remove read-only-ness"
752 raise svntest.Failure
754 # revert the change
755 svntest.actions.run_and_verify_svn(None, None, [], 'revert', iota_path)
757 # make sure that iota got set back to read-only
758 if (os.stat(iota_path)[0] & mode):
759 print "Reverting a file with 'svn:needs-lock'"
760 print "did not set the file back to read-only"
761 raise svntest.Failure
763 # try propdel and revert from a different directory so
764 # full filenames are used
765 extra_name = 'xx'
767 # now lock the file
768 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
769 '-m', '', iota_path)
771 # modify it
772 svntest.main.file_append(iota_path, "This line added\n")
774 expected_status.tweak(wc_rev=1)
775 expected_status.tweak('iota', wc_rev=2)
776 expected_status.tweak('iota', status='M ', writelocked='K')
777 svntest.actions.run_and_verify_status(wc_dir, expected_status)
779 # revert it
780 svntest.actions.run_and_verify_svn(None, None, [], 'revert', iota_path)
782 # make sure it is still writable since we have the lock
783 if (os.stat(iota_path)[0] & mode == 0):
784 print "Reverting a 'svn:needs-lock' file (with lock in wc) "
785 print "did not leave the file writable"
786 raise svntest.Failure
789 #----------------------------------------------------------------------
790 def examine_lock_via_url(sbox):
791 "examine the fields of a lock from a URL"
793 sbox.build()
794 wc_dir = sbox.wc_dir
796 fname = 'iota'
797 comment = 'This is a lock test.'
798 file_path = os.path.join(sbox.wc_dir, fname)
799 file_url = sbox.repo_url + '/' + fname
801 # lock the file url and check the contents of lock
802 svntest.actions.run_and_validate_lock(file_url,
803 svntest.main.wc_author2)
805 #----------------------------------------------------------------------
806 def lock_several_files(sbox):
807 "lock/unlock several files in one go"
809 sbox.build()
810 wc_dir = sbox.wc_dir
812 # Deliberately have no direct child of A as a target
813 iota_path = os.path.join(sbox.wc_dir, 'iota')
814 lambda_path = os.path.join(sbox.wc_dir, 'A', 'B', 'lambda')
815 alpha_path = os.path.join(sbox.wc_dir, 'A', 'B', 'E', 'alpha')
817 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
818 '--username', svntest.main.wc_author2,
819 '-m', 'lock several',
820 iota_path, lambda_path, alpha_path)
822 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
823 expected_status.tweak('iota', 'A/B/lambda', 'A/B/E/alpha', writelocked='K')
824 svntest.actions.run_and_verify_status(wc_dir, expected_status)
826 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
827 '--username', svntest.main.wc_author2,
828 iota_path, lambda_path, alpha_path)
830 expected_status.tweak('iota', 'A/B/lambda', 'A/B/E/alpha', writelocked=None)
831 svntest.actions.run_and_verify_status(wc_dir, expected_status)
833 #----------------------------------------------------------------------
834 def lock_switched_files(sbox):
835 "lock/unlock switched files"
837 sbox.build()
838 wc_dir = sbox.wc_dir
840 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
841 lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
842 iota_URL = sbox.repo_url + '/iota'
843 alpha_URL = sbox.repo_url + '/A/B/E/alpha'
845 svntest.actions.run_and_verify_svn(None, None, [], 'switch',
846 iota_URL, gamma_path)
847 svntest.actions.run_and_verify_svn(None, None, [], 'switch',
848 alpha_URL, lambda_path)
850 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
851 expected_status.tweak('A/D/gamma', 'A/B/lambda', switched='S')
852 svntest.actions.run_and_verify_status(wc_dir, expected_status)
854 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
855 '-m', 'lock several',
856 gamma_path, lambda_path)
858 expected_status.tweak('A/D/gamma', 'A/B/lambda', writelocked='K')
859 expected_status.tweak('A/B/E/alpha', 'iota', writelocked='O')
860 svntest.actions.run_and_verify_status(wc_dir, expected_status)
862 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
863 gamma_path, lambda_path)
865 expected_status.tweak('A/D/gamma', 'A/B/lambda', writelocked=None)
866 expected_status.tweak('A/B/E/alpha', 'iota', writelocked=None)
867 svntest.actions.run_and_verify_status(wc_dir, expected_status)
869 def lock_uri_encoded(sbox):
870 "lock and unlock a file with an URI-unsafe name"
872 sbox.build()
873 wc_dir = sbox.wc_dir
875 # lock a file as wc_author
876 fname = 'amazing space'
877 file_path = os.path.join(wc_dir, fname)
879 svntest.main.file_append(file_path, "This represents a binary file\n")
880 svntest.actions.run_and_verify_svn(None, None, [], "add", file_path)
882 expected_output = svntest.wc.State(wc_dir, {
883 fname : Item(verb='Adding'),
886 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
887 expected_status.add({ fname: Item(wc_rev=2, status=' ') })
889 # Commit the file.
890 svntest.actions.run_and_verify_commit(wc_dir,
891 expected_output,
892 expected_status,
893 None,
894 file_path)
896 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
897 '-m', '', file_path)
899 # Make sure that the file was locked.
900 expected_status.tweak(fname, writelocked='K')
901 svntest.actions.run_and_verify_status(wc_dir, expected_status)
903 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
904 file_path)
906 # Make sure it was successfully unlocked again.
907 expected_status.tweak(fname, writelocked=None)
908 svntest.actions.run_and_verify_status(wc_dir, expected_status)
910 # And now the URL case.
911 file_url = sbox.repo_url + '/' + fname
912 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
913 '-m', '', file_url)
915 # Make sure that the file was locked.
916 expected_status.tweak(fname, writelocked='O')
917 svntest.actions.run_and_verify_status(wc_dir, expected_status)
919 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
920 file_url)
922 # Make sure it was successfully unlocked again.
923 expected_status.tweak(fname, writelocked=None)
924 svntest.actions.run_and_verify_status(wc_dir, expected_status)
927 #----------------------------------------------------------------------
928 # A regression test for a bug when svn:needs-lock and svn:executable
929 # interact badly. The bug was fixed in trunk @ r14859.
930 def lock_and_exebit1(sbox):
931 "svn:needs-lock and svn:executable, part I"
933 mode_w = stat.S_IWUSR
934 mode_x = stat.S_IXUSR
935 mode_r = stat.S_IRUSR
937 sbox.build()
938 wc_dir = sbox.wc_dir
940 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
942 expected_err = ".*svn: warning: To turn off the svn:needs-lock property,.*"
943 svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
944 'ps', 'svn:needs-lock', ' ', gamma_path)
946 expected_err = ".*svn: warning: To turn off the svn:executable property,.*"
947 svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
948 'ps', 'svn:executable', ' ', gamma_path)
950 # commit
951 svntest.actions.run_and_verify_svn(None, None, [], 'commit',
952 '-m', '', gamma_path)
953 # mode should be +r, -w, +x
954 gamma_stat = os.stat(gamma_path)[0]
955 if (not gamma_stat & mode_r
956 or gamma_stat & mode_w
957 or not gamma_stat & mode_x):
958 print "Committing a file with 'svn:needs-lock, svn:executable'"
959 print "did not set the file to read-only, executable"
960 raise svntest.Failure
962 # lock
963 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
964 '-m', '', gamma_path)
965 # mode should be +r, +w, +x
966 gamma_stat = os.stat(gamma_path)[0]
967 if (not gamma_stat & mode_r
968 or not gamma_stat & mode_w
969 or not gamma_stat & mode_x):
970 print "Locking a file with 'svn:needs-lock, svn:executable'"
971 print "did not set the file to read-write, executable"
972 raise svntest.Failure
974 # modify
975 svntest.main.file_append(gamma_path, "check stat output after mod & unlock")
977 # unlock
978 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
979 gamma_path)
981 # Mode should be +r, -w, +x
982 gamma_stat = os.stat(gamma_path)[0]
983 if (not gamma_stat & mode_r
984 or gamma_stat & mode_w
985 or not gamma_stat & mode_x):
986 print "Unlocking a file with 'svn:needs-lock, svn:executable'"
987 print "did not set the file to read-only, executable"
988 raise svntest.Failure
990 # ci
991 svntest.actions.run_and_verify_svn(None, None, [], 'commit',
992 '-m', '', gamma_path)
994 # Mode should be still +r, -w, +x
995 gamma_stat = os.stat(gamma_path)[0]
996 if (not gamma_stat & mode_r
997 or gamma_stat & mode_w
998 or not gamma_stat & mode_x):
999 print "Commiting a file with 'svn:needs-lock, svn:executable'"
1000 print "after unlocking modified file's permissions"
1001 raise svntest.Failure
1004 #----------------------------------------------------------------------
1005 # A variant of lock_and_exebit1: same test without unlock
1006 def lock_and_exebit2(sbox):
1007 "svn:needs-lock and svn:executable, part II"
1009 mode_w = stat.S_IWUSR
1010 mode_x = stat.S_IXUSR
1011 mode_r = stat.S_IRUSR
1013 sbox.build()
1014 wc_dir = sbox.wc_dir
1016 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
1018 expected_err = ".*svn: warning: To turn off the svn:needs-lock property,.*"
1019 svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
1020 'ps', 'svn:needs-lock', ' ', gamma_path)
1022 expected_err = ".*svn: warning: To turn off the svn:executable property,.*"
1023 svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
1024 'ps', 'svn:executable', ' ', gamma_path)
1026 # commit
1027 svntest.actions.run_and_verify_svn(None, None, [], 'commit',
1028 '-m', '', gamma_path)
1029 # mode should be +r, -w, +x
1030 gamma_stat = os.stat(gamma_path)[0]
1031 if (not gamma_stat & mode_r
1032 or gamma_stat & mode_w
1033 or not gamma_stat & mode_x):
1034 print "Committing a file with 'svn:needs-lock, svn:executable'"
1035 print "did not set the file to read-only, executable"
1036 raise svntest.Failure
1038 # lock
1039 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1040 '-m', '', gamma_path)
1041 # mode should be +r, +w, +x
1042 gamma_stat = os.stat(gamma_path)[0]
1043 if (not gamma_stat & mode_r
1044 or not gamma_stat & mode_w
1045 or not gamma_stat & mode_x):
1046 print "Locking a file with 'svn:needs-lock, svn:executable'"
1047 print "did not set the file to read-write, executable"
1048 raise svntest.Failure
1050 # modify
1051 svntest.main.file_append(gamma_path, "check stat output after mod & unlock")
1053 # commit
1054 svntest.actions.run_and_verify_svn(None, None, [], 'commit',
1055 '-m', '', gamma_path)
1057 # Mode should be +r, -w, +x
1058 gamma_stat = os.stat(gamma_path)[0]
1059 if (not gamma_stat & mode_r
1060 or gamma_stat & mode_w
1061 or not gamma_stat & mode_x):
1062 print "Commiting a file with 'svn:needs-lock, svn:executable'"
1063 print "did not set the file to read-only, executable"
1064 raise svntest.Failure
1066 def commit_xml_unsafe_file_unlock(sbox):
1067 "commit file with xml-unsafe name and release lock"
1069 sbox.build()
1070 wc_dir = sbox.wc_dir
1072 fname = 'foo & bar'
1073 file_path = os.path.join(sbox.wc_dir, fname)
1074 svntest.main.file_append(file_path, "Initial data.\n")
1075 svntest.main.run_svn(None, 'add', file_path)
1076 svntest.main.run_svn(None,
1077 'commit', '-m', '', file_path)
1079 # lock fname as wc_author
1080 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1081 '-m', 'some lock comment', file_path)
1083 # make a change and commit it, allowing lock to be released
1084 svntest.main.file_append(file_path, "Followup data.\n")
1085 svntest.main.run_svn(None,
1086 'commit', '-m', '', file_path)
1088 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1089 expected_status.add({ fname : Item(status=' ', wc_rev=3), })
1091 # Make sure the file is unlocked
1092 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1094 #----------------------------------------------------------------------
1095 def repos_lock_with_info(sbox):
1096 "verify info path@X or path -rY return repos lock"
1098 sbox.build()
1099 wc_dir = sbox.wc_dir
1101 fname = 'iota'
1102 comment = 'This is a lock test.'
1103 file_path = os.path.join(sbox.wc_dir, fname)
1104 file_url = sbox.repo_url + '/' + fname
1106 # lock wc file
1107 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1108 '--username', svntest.main.wc_author2,
1109 '-m', comment, file_path)
1110 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1111 expected_status.tweak(fname, writelocked='K')
1112 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1114 # Steal lock on wc file
1115 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1116 '--username', svntest.main.wc_author2,
1117 '--force',
1118 '-m', comment, file_url)
1119 expected_status.tweak(fname, writelocked='T')
1120 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1122 # Get repository lock token
1123 exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
1124 'info', file_url)
1125 for line in output:
1126 if line.find("Lock Token:") != -1:
1127 repos_lock_token = line[12:]
1128 break
1129 else:
1130 print "Error: Lock token not found"
1131 raise svntest.Failure
1133 # info with revision option
1134 exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
1135 'info',
1136 file_path, '-r1')
1138 for line in output:
1139 if line.find("Lock Token:") != -1:
1140 lock_token = line[12:]
1141 break
1142 else:
1143 print "Error: Lock token not found"
1144 raise svntest.Failure
1146 if (repos_lock_token != lock_token):
1147 print "Error: expected repository lock information not found."
1148 raise svntest.Failure
1150 # info with peg revision
1151 exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
1152 'info',
1153 file_path + '@1')
1154 for line in output:
1155 if line.find("Lock Token:") != -1:
1156 lock_token = line[12:]
1157 break
1158 else:
1159 print "Error: Lock token not found"
1160 raise svntest.Failure
1162 if (repos_lock_token != lock_token):
1163 print "Error: expected repository lock information not found."
1164 raise svntest.Failure
1166 #----------------------------------------------------------------------
1167 def unlock_already_unlocked_files(sbox):
1168 "(un)lock set of files, one already (un)locked"
1170 sbox.build()
1171 wc_dir = sbox.wc_dir
1173 # Deliberately have no direct child of A as a target
1174 iota_path = os.path.join(wc_dir, 'iota')
1175 lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
1176 alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
1177 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
1179 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1180 '--username', svntest.main.wc_author2,
1181 '-m', 'lock several',
1182 iota_path, lambda_path, alpha_path)
1184 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1185 expected_status.tweak('iota', 'A/B/lambda', 'A/B/E/alpha', writelocked='K')
1186 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1188 error_msg = ".*Path '/A/B/E/alpha' is already locked by user '" + \
1189 svntest.main.wc_author2 + "'.*"
1190 svntest.actions.run_and_verify_svn2(None, None, error_msg, 0,
1191 'lock',
1192 '--username', svntest.main.wc_author2,
1193 alpha_path, gamma_path)
1194 expected_status.tweak('A/D/gamma', writelocked='K')
1195 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1197 svntest.actions.run_and_verify_svn(None, ".*unlocked", [], 'unlock',
1198 '--username', svntest.main.wc_author2,
1199 lambda_path)
1201 expected_status.tweak('A/B/lambda', writelocked=None)
1202 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1204 error_msg = "(.*No lock on path '/A/B/lambda'.*)" + \
1205 "|(.*'A/B/lambda' is not locked.*)"
1206 svntest.actions.run_and_verify_svn2(None, None, error_msg, 0,
1207 'unlock',
1208 '--username', svntest.main.wc_author2,
1209 '--force',
1210 iota_path, lambda_path, alpha_path)
1213 expected_status.tweak('iota', 'A/B/E/alpha', writelocked=None)
1214 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1216 #----------------------------------------------------------------------
1217 def info_moved_path(sbox):
1218 "show correct lock info on moved path"
1220 sbox.build()
1221 wc_dir = sbox.wc_dir
1222 fname = os.path.join(wc_dir, "iota")
1223 fname2 = os.path.join(wc_dir, "iota2")
1225 # Move iota, creating r2.
1226 svntest.actions.run_and_verify_svn(None, None, [],
1227 "mv", fname, fname2)
1228 expected_output = svntest.wc.State(wc_dir, {
1229 'iota2' : Item(verb='Adding'),
1230 'iota' : Item(verb='Deleting'),
1232 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1233 expected_status.add({
1234 "iota2" : Item(status=' ', wc_rev=2)
1236 expected_status.remove("iota")
1237 svntest.actions.run_and_verify_commit(wc_dir,
1238 expected_output,
1239 expected_status,
1240 None,
1241 wc_dir)
1243 # Create a new, unrelated iota, creating r3.
1244 svntest.main.file_append(fname, "Another iota")
1245 svntest.actions.run_and_verify_svn(None, None, [],
1246 "add", fname)
1247 expected_output = svntest.wc.State(wc_dir, {
1248 'iota' : Item(verb='Adding'),
1250 expected_status.add({
1251 "iota" : Item(status=' ', wc_rev=3)
1253 svntest.actions.run_and_verify_commit(wc_dir,
1254 expected_output,
1255 expected_status,
1256 None,
1257 wc_dir)
1259 # Lock the new iota.
1260 svntest.actions.run_and_verify_svn(None, ".*locked by user", [],
1261 "lock", fname)
1262 expected_status.tweak("iota", writelocked="K")
1263 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1265 # Get info for old iota at r1. This shouldn't give us any lock info.
1266 exit_code, output, errput = svntest.actions.run_and_verify_svn(
1267 None, None, [], 'info', fname2, '-r1')
1269 # Since we want to make sure that there is *no* lock info, to make this
1270 # more robust, we also check that the info command actually output some info.
1271 got_url = 0
1272 for line in output:
1273 if line.find("URL:") >= 0:
1274 got_url = 1
1275 if line.find("Lock Token:") >= 0:
1276 print fname2 + " was reported as locked."
1277 raise svntest.Failure
1278 if not got_url:
1279 print "Info didn't output an URL."
1280 raise svntest.Failure
1282 #----------------------------------------------------------------------
1283 def ls_url_encoded(sbox):
1284 "ls locked path needing URL encoding"
1286 sbox.build()
1287 wc_dir = sbox.wc_dir
1288 dirname = os.path.join(wc_dir, "space dir")
1289 fname = os.path.join(dirname, "f")
1291 # Create a dir with a space in its name and a file therein.
1292 svntest.actions.run_and_verify_svn(None, None, [],
1293 "mkdir", dirname)
1294 svntest.main.file_append(fname, "someone was here")
1295 svntest.actions.run_and_verify_svn(None, None, [],
1296 "add", fname)
1297 expected_output = svntest.wc.State(wc_dir, {
1298 'space dir' : Item(verb='Adding'),
1299 'space dir/f' : Item(verb='Adding'),
1301 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1302 expected_status.add({
1303 "space dir" : Item(status=' ', wc_rev=2),
1304 "space dir/f" : Item(status=' ', wc_rev=2),
1306 svntest.actions.run_and_verify_commit(wc_dir,
1307 expected_output,
1308 expected_status,
1309 None,
1310 wc_dir)
1312 # Lock the file.
1313 svntest.actions.run_and_verify_svn("Lock space dir/f", ".*locked by user",
1314 [], "lock", fname)
1316 # Make sure ls shows it being locked.
1317 expected_output = " +2 " + re.escape(svntest.main.wc_author) + " +O .+f|" \
1318 " +2 " + re.escape(svntest.main.wc_author) + " .+\./"
1319 svntest.actions.run_and_verify_svn("List space dir",
1320 expected_output, [],
1321 "list", "-v", dirname)
1323 #----------------------------------------------------------------------
1324 # Make sure unlocking a path with the wrong lock token fails.
1325 def unlock_wrong_token(sbox):
1326 "verify unlocking with wrong lock token"
1328 sbox.build()
1329 wc_dir = sbox.wc_dir
1331 # lock a file as wc_author
1332 fname = 'iota'
1333 file_path = os.path.join(sbox.wc_dir, fname)
1334 file_url = sbox.repo_url + "/iota"
1336 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1337 file_path)
1339 # Steal the lock as the same author, but using an URL to keep the old token
1340 # in the WC.
1341 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1342 "--force", file_url)
1344 # Then, unlocking the WC path should fail.
1345 # ### The error message returned is actually this, but let's worry about that
1346 # ### another day...
1347 svntest.actions.run_and_verify_svn2(
1348 None, None, ".*((No lock on path)|(400 Bad Request))", 0,
1349 'unlock', file_path)
1351 #----------------------------------------------------------------------
1352 # Verify that info shows lock info for locked files with URI-unsafe names
1353 # when run in recursive mode.
1354 def examine_lock_encoded_recurse(sbox):
1355 "verify recursive info shows lock info"
1357 sbox.build()
1358 wc_dir = sbox.wc_dir
1360 fname = 'A/B/F/one iota'
1361 file_path = os.path.join(sbox.wc_dir, fname)
1363 svntest.main.file_append(file_path, "This represents a binary file\n")
1364 svntest.actions.run_and_verify_svn(None, None, [], "add", file_path)
1366 expected_output = svntest.wc.State(wc_dir, {
1367 fname : Item(verb='Adding'),
1370 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1371 expected_status.add({ fname: Item(wc_rev=2, status=' ') })
1373 # Commit the file.
1374 svntest.actions.run_and_verify_commit(wc_dir,
1375 expected_output,
1376 expected_status,
1377 None,
1378 file_path)
1380 # lock the file and validate the contents
1381 svntest.actions.run_and_validate_lock(file_path,
1382 svntest.main.wc_author)
1384 # Trying to unlock someone else's lock with --force should fail.
1385 def unlocked_lock_of_other_user(sbox):
1386 "unlock file locked by other user"
1388 sbox.build()
1389 wc_dir = sbox.wc_dir
1391 # lock a file with user jrandom
1392 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
1393 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1394 expected_status.tweak('A/D/G/pi', writelocked='K')
1396 svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
1397 '-m', '', pi_path)
1399 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1401 # now try to unlock with user jconstant, should fail but exit 0.
1402 if sbox.repo_url.startswith("http"):
1403 expected_err = ".*403 Forbidden.*"
1404 else:
1405 expected_err = "svn: warning: User '%s' is trying to use a lock owned by "\
1406 "'%s'.*" % (svntest.main.wc_author2, svntest.main.wc_author)
1407 svntest.actions.run_and_verify_svn2(None, [], expected_err, 0,
1408 'unlock',
1409 '--username', svntest.main.wc_author2,
1410 pi_path)
1411 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1414 ########################################################################
1415 # Run the tests
1417 # list all tests here, starting with None:
1418 test_list = [ None,
1419 lock_file,
1420 commit_file_keep_lock,
1421 commit_file_unlock,
1422 commit_propchange,
1423 break_lock,
1424 steal_lock,
1425 examine_lock,
1426 handle_defunct_lock,
1427 enforce_lock,
1428 defunct_lock,
1429 deleted_path_lock,
1430 lock_unlock,
1431 deleted_dir_lock,
1432 lock_status,
1433 stolen_lock_status,
1434 broken_lock_status,
1435 lock_non_existent_file,
1436 out_of_date,
1437 update_while_needing_lock,
1438 revert_lock,
1439 examine_lock_via_url,
1440 lock_several_files,
1441 lock_switched_files,
1442 lock_uri_encoded,
1443 SkipUnless(lock_and_exebit1, svntest.main.is_posix_os),
1444 SkipUnless(lock_and_exebit2, svntest.main.is_posix_os),
1445 commit_xml_unsafe_file_unlock,
1446 repos_lock_with_info,
1447 unlock_already_unlocked_files,
1448 info_moved_path,
1449 ls_url_encoded,
1450 XFail(unlock_wrong_token, svntest.main.is_ra_type_dav),
1451 examine_lock_encoded_recurse,
1452 XFail(unlocked_lock_of_other_user,
1453 svntest.main.is_ra_type_dav)
1456 if __name__ == '__main__':
1457 svntest.main.run_tests(test_list)
1458 # NOTREACHED
1461 ### End of file.