/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4988.10.5 by John Arbash Meinel
Merge bzr.dev 5021 to resolve NEWS
1
# Copyright (C) 2006-2010 Canonical Ltd
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
16
17
"""Test locks across all branch implemenations"""
18
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
19
from breezy import (
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
20
    errors,
21
    tests,
22
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
23
from breezy.tests import (
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
24
    lock_helpers,
25
    per_branch,
26
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
27
from breezy.tests.matchers import *
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
28
29
30
class TestBranchLocking(per_branch.TestCaseWithBranch):
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
31
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
32
    def setUp(self):
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
33
        super(TestBranchLocking, self).setUp()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
34
        self.reduceLockdirTimeout()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
35
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
36
    def get_instrumented_branch(self):
37
        """Get a Branch object which has been instrumented"""
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
38
        # TODO: jam 20060630 It may be that not all formats have a
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
39
        # 'control_files' member. So we should fail gracefully if
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
40
        # not there. But assuming it has them lets us test the exact
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
41
        # lock/unlock order.
42
        self.locks = []
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
43
        b = lock_helpers.LockWrapper(self.locks, self.get_branch(), 'b')
44
        b.repository = lock_helpers.LockWrapper(self.locks, b.repository, 'r')
6150.2.4 by Jelmer Vernooij
Support branches without control_files.
45
        bcf = getattr(b, "control_files", None)
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
46
        rcf = getattr(b.repository, 'control_files', None)
47
        if rcf is None:
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
48
            self.combined_branch = False
49
        else:
50
            # Look out for branch types that reuse their control files
6150.2.4 by Jelmer Vernooij
Support branches without control_files.
51
            self.combined_control = bcf is rcf and bcf is not None
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
52
        try:
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
53
            b.control_files = lock_helpers.LockWrapper(
54
                self.locks, b.control_files, 'bc')
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
55
        except AttributeError:
56
            # RemoteBranch seems to trigger this.
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
57
            raise tests.TestSkipped(
58
                'Could not instrument branch control files.')
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
59
        if self.combined_control:
60
            # instrument the repository control files too to ensure its worked
61
            # with correctly. When they are not shared, we trust the repository
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
62
            # API and only instrument the repository itself.
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
63
            b.repository.control_files = lock_helpers.LockWrapper(
64
                self.locks, b.repository.control_files, 'rc')
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
65
        return b
66
67
    def test_01_lock_read(self):
68
        # Test that locking occurs in the correct order
69
        b = self.get_instrumented_branch()
70
71
        self.assertFalse(b.is_locked())
72
        self.assertFalse(b.repository.is_locked())
73
        b.lock_read()
74
        try:
75
            self.assertTrue(b.is_locked())
76
            self.assertTrue(b.repository.is_locked())
77
        finally:
78
            b.unlock()
79
        self.assertFalse(b.is_locked())
80
        self.assertFalse(b.repository.is_locked())
81
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
82
        if self.combined_control:
83
            self.assertEqual([('b', 'lr', True),
84
                              ('r', 'lr', True),
85
                              ('rc', 'lr', True),
86
                              ('bc', 'lr', True),
87
                              ('b', 'ul', True),
88
                              ('bc', 'ul', True),
89
                              ('r', 'ul', True),
90
                              ('rc', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
91
                              ], self.locks)
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
92
        else:
93
            self.assertEqual([('b', 'lr', True),
94
                              ('r', 'lr', True),
95
                              ('bc', 'lr', True),
96
                              ('b', 'ul', True),
97
                              ('bc', 'ul', True),
98
                              ('r', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
99
                              ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
100
101
    def test_02_lock_write(self):
102
        # Test that locking occurs in the correct order
103
        b = self.get_instrumented_branch()
104
105
        self.assertFalse(b.is_locked())
106
        self.assertFalse(b.repository.is_locked())
107
        b.lock_write()
108
        try:
109
            self.assertTrue(b.is_locked())
110
            self.assertTrue(b.repository.is_locked())
111
        finally:
112
            b.unlock()
113
        self.assertFalse(b.is_locked())
114
        self.assertFalse(b.repository.is_locked())
115
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
116
        if self.combined_control:
117
            self.assertEqual([('b', 'lw', True),
118
                              ('r', 'lw', True),
119
                              ('rc', 'lw', True),
120
                              ('bc', 'lw', True),
121
                              ('b', 'ul', True),
122
                              ('bc', 'ul', True),
123
                              ('r', 'ul', True),
124
                              ('rc', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
125
                              ], self.locks)
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
126
        else:
127
            self.assertEqual([('b', 'lw', True),
128
                              ('r', 'lw', True),
129
                              ('bc', 'lw', True),
130
                              ('b', 'ul', True),
131
                              ('bc', 'ul', True),
132
                              ('r', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
133
                              ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
134
135
    def test_03_lock_fail_unlock_repo(self):
136
        # Make sure branch.unlock() is called, even if there is a
137
        # failure while unlocking the repository.
138
        b = self.get_instrumented_branch()
139
        b.repository.disable_unlock()
140
141
        self.assertFalse(b.is_locked())
142
        self.assertFalse(b.repository.is_locked())
143
        b.lock_write()
144
        try:
145
            self.assertTrue(b.is_locked())
146
            self.assertTrue(b.repository.is_locked())
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
147
            self.assertLogsError(lock_helpers.TestPreventLocking, b.unlock)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
148
            if self.combined_control:
149
                self.assertTrue(b.is_locked())
150
            else:
151
                self.assertFalse(b.is_locked())
152
            self.assertTrue(b.repository.is_locked())
153
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
154
            # We unlock the branch control files, even if
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
155
            # we fail to unlock the repository
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
156
            if self.combined_control:
157
                self.assertEqual([('b', 'lw', True),
158
                                  ('r', 'lw', True),
159
                                  ('rc', 'lw', True),
160
                                  ('bc', 'lw', True),
161
                                  ('b', 'ul', True),
162
                                  ('bc', 'ul', True),
163
                                  ('r', 'ul', False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
164
                                  ], self.locks)
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
165
            else:
166
                self.assertEqual([('b', 'lw', True),
167
                                  ('r', 'lw', True),
168
                                  ('bc', 'lw', True),
169
                                  ('b', 'ul', True),
170
                                  ('bc', 'ul', True),
171
                                  ('r', 'ul', False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
172
                                  ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
173
174
        finally:
175
            # For cleanup purposes, make sure we are unlocked
176
            b.repository._other.unlock()
177
178
    def test_04_lock_fail_unlock_control(self):
4288.1.11 by Robert Collins
Hopefully fix locking tests to match the new code (and still be good statements of intent).
179
        # Make sure repository.unlock() is not called, if we fail to unlock
180
        # self leaving ourselves still locked, so that attempts to recover
181
        # don't encounter an unlocked repository.
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
182
        b = self.get_instrumented_branch()
183
        b.control_files.disable_unlock()
184
185
        self.assertFalse(b.is_locked())
186
        self.assertFalse(b.repository.is_locked())
187
        b.lock_write()
188
        try:
189
            self.assertTrue(b.is_locked())
190
            self.assertTrue(b.repository.is_locked())
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
191
            self.assertLogsError(lock_helpers.TestPreventLocking, b.unlock)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
192
            self.assertTrue(b.is_locked())
4288.1.11 by Robert Collins
Hopefully fix locking tests to match the new code (and still be good statements of intent).
193
            self.assertTrue(b.repository.is_locked())
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
194
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
195
            # We unlock the repository even if
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
196
            # we fail to unlock the control files
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
197
            if self.combined_control:
198
                self.assertEqual([('b', 'lw', True),
199
                                  ('r', 'lw', True),
200
                                  ('rc', 'lw', True),
201
                                  ('bc', 'lw', True),
202
                                  ('b', 'ul', True),
203
                                  ('bc', 'ul', False),
204
                                  ('r', 'ul', True),
205
                                  ('rc', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
206
                                  ], self.locks)
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
207
            else:
208
                self.assertEqual([('b', 'lw', True),
209
                                  ('r', 'lw', True),
210
                                  ('bc', 'lw', True),
211
                                  ('b', 'ul', True),
212
                                  ('bc', 'ul', False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
213
                                  ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
214
215
        finally:
216
            # For cleanup purposes, make sure we are unlocked
217
            b.control_files._other.unlock()
218
219
    def test_05_lock_read_fail_repo(self):
220
        # Test that the branch is not locked if it cannot lock the repository
221
        b = self.get_instrumented_branch()
222
        b.repository.disable_lock_read()
223
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
224
        self.assertRaises(lock_helpers.TestPreventLocking, b.lock_read)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
225
        self.assertFalse(b.is_locked())
226
        self.assertFalse(b.repository.is_locked())
227
228
        self.assertEqual([('b', 'lr', True),
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
229
                          ('r', 'lr', False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
230
                          ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
231
232
    def test_06_lock_write_fail_repo(self):
233
        # Test that the branch is not locked if it cannot lock the repository
234
        b = self.get_instrumented_branch()
235
        b.repository.disable_lock_write()
236
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
237
        self.assertRaises(lock_helpers.TestPreventLocking, b.lock_write)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
238
        self.assertFalse(b.is_locked())
239
        self.assertFalse(b.repository.is_locked())
240
241
        self.assertEqual([('b', 'lw', True),
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
242
                          ('r', 'lw', False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
243
                          ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
244
245
    def test_07_lock_read_fail_control(self):
246
        # Test the repository is unlocked if we can't lock self
247
        b = self.get_instrumented_branch()
248
        b.control_files.disable_lock_read()
249
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
250
        self.assertRaises(lock_helpers.TestPreventLocking, b.lock_read)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
251
        self.assertFalse(b.is_locked())
252
        self.assertFalse(b.repository.is_locked())
253
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
254
        if self.combined_control:
255
            self.assertEqual([('b', 'lr', True),
256
                              ('r', 'lr', True),
257
                              ('rc', 'lr', True),
258
                              ('bc', 'lr', False),
259
                              ('r', 'ul', True),
260
                              ('rc', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
261
                              ], self.locks)
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
262
        else:
263
            self.assertEqual([('b', 'lr', True),
264
                              ('r', 'lr', True),
265
                              ('bc', 'lr', False),
266
                              ('r', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
267
                              ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
268
269
    def test_08_lock_write_fail_control(self):
270
        # Test the repository is unlocked if we can't lock self
271
        b = self.get_instrumented_branch()
272
        b.control_files.disable_lock_write()
273
5010.2.16 by Vincent Ladeuil
Fix imports in per_branch/test_locking.py.
274
        self.assertRaises(lock_helpers.TestPreventLocking, b.lock_write)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
275
        self.assertFalse(b.is_locked())
276
        self.assertFalse(b.repository.is_locked())
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
277
        if self.combined_control:
278
            self.assertEqual([('b', 'lw', True),
279
                              ('r', 'lw', True),
280
                              ('rc', 'lw', True),
281
                              ('bc', 'lw', False),
282
                              ('r', 'ul', True),
283
                              ('rc', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
284
                              ], self.locks)
3015.2.14 by Robert Collins
Make branch_implementations.test_locking honour the repository API more.
285
        else:
286
            self.assertEqual([('b', 'lw', True),
287
                              ('r', 'lw', True),
288
                              ('bc', 'lw', False),
289
                              ('r', 'ul', True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
290
                              ], self.locks)
1711.8.5 by John Arbash Meinel
Move the new locking tests into their own files, and move the helper functions into a test helper.
291
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
292
    def test_lock_write_returns_None_refuses_token(self):
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
293
        branch = self.make_branch('b')
6754.8.4 by Jelmer Vernooij
Use new context stuff.
294
        with branch.lock_write() as lock:
295
            if lock.token is not None:
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
296
                # This test does not apply, because this lockable supports
297
                # tokens.
298
                return
299
            self.assertRaises(errors.TokenLockingNotSupported,
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
300
                              branch.lock_write, token='token')
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
301
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
302
    def test_reentering_lock_write_raises_on_token_mismatch(self):
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
303
        branch = self.make_branch('b')
6754.8.4 by Jelmer Vernooij
Use new context stuff.
304
        with branch.lock_write() as lock:
305
            if lock.token is None:
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
306
                # This test does not apply, because this lockable refuses
307
                # tokens.
308
                return
6973.10.6 by Jelmer Vernooij
Fix tests.
309
            different_branch_token = lock.token + b'xxx'
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
310
            # Re-using the same lockable instance with a different branch token
311
            # will raise TokenMismatch.
312
            self.assertRaises(errors.TokenMismatch,
313
                              branch.lock_write,
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
314
                              token=different_branch_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
315
316
    def test_lock_write_with_nonmatching_token(self):
317
        branch = self.make_branch('b')
6754.8.4 by Jelmer Vernooij
Use new context stuff.
318
        with branch.lock_write() as lock:
319
            if lock.token is None:
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
320
                # This test does not apply, because this branch refuses
321
                # tokens.
322
                return
6973.10.6 by Jelmer Vernooij
Fix tests.
323
            different_branch_token = lock.token + b'xxx'
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
324
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
325
            new_branch = branch.controldir.open_branch()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
326
            # We only want to test the relocking abilities of branch, so use the
327
            # existing repository object which is already locked.
328
            new_branch.repository = branch.repository
329
            self.assertRaises(errors.TokenMismatch,
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
330
                              new_branch.lock_write,
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
331
                              token=different_branch_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
332
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
333
    def test_lock_write_with_matching_token(self):
334
        """Test that a branch can be locked with a token, if it is already
335
        locked by that token."""
336
        branch = self.make_branch('b')
6754.8.4 by Jelmer Vernooij
Use new context stuff.
337
        with branch.lock_write() as lock:
338
            if lock.token is None:
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
339
                # This test does not apply, because this branch refuses tokens.
340
                return
341
            # The same instance will accept a second lock_write if the specified
342
            # token matches.
6754.8.4 by Jelmer Vernooij
Use new context stuff.
343
            branch.lock_write(token=lock.token)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
344
            branch.unlock()
345
            # Calling lock_write on a new instance for the same lockable will
346
            # also succeed.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
347
            new_branch = branch.controldir.open_branch()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
348
            # We only want to test the relocking abilities of branch, so use the
349
            # existing repository object which is already locked.
350
            new_branch.repository = branch.repository
6754.8.4 by Jelmer Vernooij
Use new context stuff.
351
            new_branch.lock_write(token=lock.token)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
352
            new_branch.unlock()
353
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
354
    def test_unlock_after_lock_write_with_token(self):
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
355
        # If lock_write did not physically acquire the lock (because it was
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
356
        # passed some tokens), then unlock should not physically release it.
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
357
        branch = self.make_branch('b')
6754.8.4 by Jelmer Vernooij
Use new context stuff.
358
        with branch.lock_write() as lock:
359
            if lock.token is None:
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
360
                # This test does not apply, because this lockable refuses
361
                # tokens.
362
                return
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
363
            new_branch = branch.controldir.open_branch()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
364
            # We only want to test the relocking abilities of branch, so use the
365
            # existing repository object which is already locked.
366
            new_branch.repository = branch.repository
6754.8.4 by Jelmer Vernooij
Use new context stuff.
367
            new_branch.lock_write(token=lock.token)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
368
            new_branch.unlock()
7143.15.2 by Jelmer Vernooij
Run autopep8.
369
            self.assertTrue(branch.get_physical_lock_status())  # XXX
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
370
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
371
    def test_lock_write_with_token_fails_when_unlocked(self):
372
        # First, lock and then unlock to get superficially valid tokens.  This
373
        # mimics a likely programming error, where a caller accidentally tries
374
        # to lock with a token that is no longer valid (because the original
375
        # lock was released).
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
376
        branch = self.make_branch('b')
6754.8.4 by Jelmer Vernooij
Use new context stuff.
377
        token = branch.lock_write().token
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
378
        branch.unlock()
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
379
        if token is None:
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
380
            # This test does not apply, because this lockable refuses
381
            # tokens.
382
            return
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
383
        self.assertRaises(errors.TokenMismatch, branch.lock_write, token=token)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
384
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
385
    def test_lock_write_reenter_with_token(self):
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
386
        branch = self.make_branch('b')
6754.8.4 by Jelmer Vernooij
Use new context stuff.
387
        with branch.lock_write() as lock:
388
            if lock.token is None:
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
389
                # This test does not apply, because this lockable refuses
390
                # tokens.
391
                return
392
            # Relock with a token.
6754.8.4 by Jelmer Vernooij
Use new context stuff.
393
            branch.lock_write(token=lock.token)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
394
            branch.unlock()
395
        # The lock should be unlocked on disk.  Verify that with a new lock
396
        # instance.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
397
        new_branch = branch.controldir.open_branch()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
398
        # Calling lock_write now should work, rather than raise LockContention.
399
        new_branch.lock_write()
400
        new_branch.unlock()
401
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
402
    def test_leave_lock_in_place(self):
403
        branch = self.make_branch('b')
404
        # Lock the branch, then use leave_lock_in_place so that when we
405
        # unlock the branch the lock is still held on disk.
6754.8.4 by Jelmer Vernooij
Use new context stuff.
406
        token = None
407
        with branch.lock_write() as lock:
408
            token = lock.token
409
            if lock.token is None:
410
                # This test does not apply, because this repository refuses
411
                # lock tokens.
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
412
                self.assertRaises(NotImplementedError,
413
                                  branch.leave_lock_in_place)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
414
                return
415
            branch.leave_lock_in_place()
416
        # We should be unable to relock the repo.
417
        self.assertRaises(errors.LockContention, branch.lock_write)
4327.1.11 by Vincent Ladeuil
Fix the last 6 lock-related failures.
418
        # Cleanup
419
        branch.lock_write(token)
420
        branch.dont_leave_lock_in_place()
421
        branch.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
422
423
    def test_dont_leave_lock_in_place(self):
424
        branch = self.make_branch('b')
425
        # Create a lock on disk.
6754.8.4 by Jelmer Vernooij
Use new context stuff.
426
        token = branch.lock_write().token
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
427
        try:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
428
            if token is None:
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
429
                # This test does not apply, because this branch refuses lock
430
                # tokens.
431
                self.assertRaises(NotImplementedError,
432
                                  branch.dont_leave_lock_in_place)
433
                return
434
            try:
435
                branch.leave_lock_in_place()
436
            except NotImplementedError:
437
                # This branch doesn't support this API.
438
                return
3015.2.5 by Robert Collins
Handle repositories that cannot be remotely locked in branch_implementations.test_locking.
439
            try:
440
                branch.repository.leave_lock_in_place()
441
            except NotImplementedError:
442
                # This repo doesn't support leaving locks around,
443
                # assume it is essentially lock-free.
444
                repo_token = None
445
            else:
446
                repo_token = branch.repository.lock_write()
447
                branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
448
        finally:
449
            branch.unlock()
450
        # Reacquire the lock (with a different branch object) by using the
451
        # tokens.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
452
        new_branch = branch.controldir.open_branch()
3015.2.5 by Robert Collins
Handle repositories that cannot be remotely locked in branch_implementations.test_locking.
453
        if repo_token is not None:
454
            # We have to explicitly lock the repository first.
455
            new_branch.repository.lock_write(token=repo_token)
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
456
        new_branch.lock_write(token=token)
3015.2.5 by Robert Collins
Handle repositories that cannot be remotely locked in branch_implementations.test_locking.
457
        if repo_token is not None:
458
            # Now we don't need our own repository lock anymore (the branch is
459
            # holding it for us).
460
            new_branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
461
        # Call dont_leave_lock_in_place, so that the lock will be released by
462
        # this instance, even though the lock wasn't originally acquired by it.
463
        new_branch.dont_leave_lock_in_place()
3015.2.5 by Robert Collins
Handle repositories that cannot be remotely locked in branch_implementations.test_locking.
464
        if repo_token is not None:
465
            new_branch.repository.dont_leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
466
        new_branch.unlock()
2018.15.1 by Andrew Bennetts
All branch_implementations/test_locking tests passing.
467
        # Now the branch (and repository) is unlocked.  Test this by locking it
468
        # without tokens.
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
469
        branch.lock_write()
470
        branch.unlock()
471
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
472
    def test_lock_read_then_unlock(self):
473
        # Calling lock_read then unlocking should work without errors.
474
        branch = self.make_branch('b')
475
        branch.lock_read()
476
        branch.unlock()
477
6754.8.2 by Jelmer Vernooij
Add tests for context manager.
478
    def test_lock_read_context_manager(self):
479
        # Calling lock_read then unlocking should work without errors.
480
        branch = self.make_branch('b')
481
        self.assertFalse(branch.is_locked())
482
        with branch.lock_read():
483
            self.assertTrue(branch.is_locked())
484
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
485
    def test_lock_read_returns_unlockable(self):
486
        branch = self.make_branch('b')
487
        self.assertThat(branch.lock_read, ReturnsUnlockable(branch))
488
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
489
    def test_lock_write_locks_repo_too(self):
490
        branch = self.make_branch('b')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
491
        branch = branch.controldir.open_branch()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
492
        branch.lock_write()
493
        try:
3015.2.15 by Robert Collins
Review feedback.
494
            # The branch should have asked the repository to lock.
3015.2.5 by Robert Collins
Handle repositories that cannot be remotely locked in branch_implementations.test_locking.
495
            self.assertTrue(branch.repository.is_write_locked())
496
            # Does the repository type actually lock?
497
            if not branch.repository.get_physical_lock_status():
498
                # The test was successfully applied, so it was applicable.
499
                return
500
            # Now the branch.repository is physically locked, so we can't lock
501
            # it with a new repository instance.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
502
            new_repo = branch.controldir.open_repository()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
503
            self.assertRaises(errors.LockContention, new_repo.lock_write)
504
            # We can call lock_write on the original repository object though,
505
            # because it is already locked.
506
            branch.repository.lock_write()
507
            branch.repository.unlock()
508
        finally:
509
            branch.unlock()
3692.1.2 by Andrew Bennetts
Fix regression introduced by fix, and add a test for that regression.
510
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
511
    def test_lock_write_returns_unlockable(self):
512
        branch = self.make_branch('b')
513
        self.assertThat(branch.lock_write, ReturnsUnlockable(branch))
514
5241.1.1 by Andrew Bennetts
Fix AttributeError in RemoteBranch.lock_write after lock_read.
515
    def test_lock_write_raises_in_lock_read(self):
516
        branch = self.make_branch('b')
517
        branch.lock_read()
5285.2.1 by Andrew Bennetts
Fix trivial "was gc'd while locked" warning in test_lock_write_raises_in_lock_read.
518
        self.addCleanup(branch.unlock)
5241.1.1 by Andrew Bennetts
Fix AttributeError in RemoteBranch.lock_write after lock_read.
519
        err = self.assertRaises(errors.ReadOnlyError, branch.lock_write)
520
3692.1.2 by Andrew Bennetts
Fix regression introduced by fix, and add a test for that regression.
521
    def test_lock_and_unlock_leaves_repo_unlocked(self):
522
        branch = self.make_branch('b')
523
        branch.lock_write()
524
        branch.unlock()
525
        self.assertRaises(errors.LockNotHeld, branch.repository.unlock)