diff options
Diffstat (limited to 'bzrlib/tests/blackbox/test_break_lock.py')
-rw-r--r-- | bzrlib/tests/blackbox/test_break_lock.py | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/bzrlib/tests/blackbox/test_break_lock.py b/bzrlib/tests/blackbox/test_break_lock.py new file mode 100644 index 0000000..c4bd48a --- /dev/null +++ b/bzrlib/tests/blackbox/test_break_lock.py @@ -0,0 +1,143 @@ +# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +"""Tests for lock-breaking user interface""" + +from bzrlib import ( + branch, + config, + controldir, + errors, + osutils, + tests, + ) +from bzrlib.tests.matchers import ContainsNoVfsCalls +from bzrlib.tests.script import ( + run_script, + ) + + +class TestBreakLock(tests.TestCaseWithTransport): + + # General principal for break-lock: All the elements that might be locked + # by a bzr operation on PATH, are candidates that break-lock may unlock. + # so pathologically if we have a lightweight checkout A, of branch B, which + # is bound to location C, the following things should be checked for locks + # to break: + # wt = WorkingTree(A) + # wt.branch + # wt.branch.repository + # wt.branch.get_master_branch() + # wt.branch.get_master_branch().repository + # so for smoke tests all we need is a bound branch with a checkout of that + # and we can then use different urls to test individual cases, for as much + # granularity as needed. + + def setUp(self): + super(TestBreakLock, self).setUp() + self.build_tree( + ['master-repo/', + 'master-repo/master-branch/', + 'repo/', + 'repo/branch/', + 'checkout/']) + controldir.ControlDir.create('master-repo').create_repository() + self.master_branch = controldir.ControlDir.create_branch_convenience( + 'master-repo/master-branch') + controldir.ControlDir.create('repo').create_repository() + local_branch = controldir.ControlDir.create_branch_convenience('repo/branch') + local_branch.bind(self.master_branch) + checkoutdir = controldir.ControlDir.create('checkout') + checkoutdir.set_branch_reference(local_branch) + self.wt = checkoutdir.create_workingtree() + + def test_break_lock_help(self): + out, err = self.run_bzr('break-lock --help') + # shouldn't fail and should not produce error output + self.assertEqual('', err) + + def test_break_lock_no_interaction(self): + """With --force, the user isn't asked for confirmation""" + self.master_branch.lock_write() + run_script(self, """ + $ bzr break-lock --force master-repo/master-branch + Broke lock ...master-branch/.bzr/... + """) + # lock should now be dead + self.assertRaises(errors.LockBroken, self.master_branch.unlock) + + def test_break_lock_everything_locked(self): + ### if everything is locked, we should be able to unlock the lot. + # however, we dont test breaking the working tree because we + # cannot accurately do so right now: the dirstate lock is held + # by an os lock, and we need to spawn a separate process to lock it + # then kill -9 it. + # sketch of test: + # lock most of the dir: + self.wt.branch.lock_write() + self.master_branch.lock_write() + # run the break-lock + # we need 5 yes's - wt, branch, repo, bound branch, bound repo. + self.run_bzr('break-lock checkout', stdin="y\ny\ny\ny\n") + # a new tree instance should be lockable + br = branch.Branch.open('checkout') + br.lock_write() + br.unlock() + # and a new instance of the master branch + mb = br.get_master_branch() + mb.lock_write() + mb.unlock() + self.assertRaises(errors.LockBroken, self.wt.unlock) + self.assertRaises(errors.LockBroken, self.master_branch.unlock) + + +class TestConfigBreakLock(tests.TestCaseWithTransport): + + def setUp(self): + super(TestConfigBreakLock, self).setUp() + self.config_file_name = './my.conf' + self.build_tree_contents([(self.config_file_name, + '[DEFAULT]\none=1\n')]) + self.config = config.LockableConfig(file_name=self.config_file_name) + self.config.lock_write() + + def test_create_pending_lock(self): + self.addCleanup(self.config.unlock) + self.assertTrue(self.config._lock.is_held) + + def test_break_lock(self): + self.run_bzr('break-lock --config %s' + % osutils.dirname(self.config_file_name), + stdin="y\n") + self.assertRaises(errors.LockBroken, self.config.unlock) + + +class TestSmartServerBreakLock(tests.TestCaseWithTransport): + + def test_simple_branch_break_lock(self): + self.setup_smart_server_with_call_log() + t = self.make_branch_and_tree('branch') + t.branch.lock_write() + self.reset_smart_call_log() + out, err = self.run_bzr(['break-lock', '--force', self.get_url('branch')]) + # This figure represent the amount of work to perform this use case. It + # is entirely ok to reduce this number if a test fails due to rpc_count + # being too low. If rpc_count increases, more network roundtrips have + # become necessary for this use case. Please do not adjust this number + # upwards without agreement from bzr's network support maintainers. + self.assertThat(self.hpss_calls, ContainsNoVfsCalls) + self.assertLength(1, self.hpss_connections) + self.assertLength(5, self.hpss_calls) |