/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2008-2011 Canonical Ltd
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
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
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
16
17
"""Tests for pack repositories.
18
19
These tests are repeated for all pack-based repository formats.
20
"""
21
22
from stat import S_ISDIR
23
6670.4.1 by Jelmer Vernooij
Update imports.
24
from ..bzr.btree_index import BTreeGraphIndex
25
from ..bzr.index import GraphIndex
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
26
from .. import (
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
27
    controldir,
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
28
    errors,
7239.1.1 by Jelmer Vernooij
Fix signature handling when repacking.
29
    gpg,
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
30
    osutils,
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
31
    repository,
32
    revision as _mod_revision,
33
    tests,
5609.9.1 by Martin
Blindly change all users of get_transport to address the function via the transport module
34
    transport,
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
35
    ui,
4360.4.6 by John Arbash Meinel
Change how 'missing.*parent_prevents_commit' determines what to skip.
36
    )
6670.4.1 by Jelmer Vernooij
Update imports.
37
from ..bzr import (
38
    inventory,
39
    )
6670.4.5 by Jelmer Vernooij
Move breezy.repofmt contents to breezy.bzr.
40
from ..bzr.groupcompress_repo import RepositoryFormat2a
6670.4.16 by Jelmer Vernooij
Move smart to breezy.bzr.
41
from ..bzr.smart import (
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
42
    client,
43
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
44
from . import (
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
45
    TestCaseWithTransport,
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
46
    TestNotApplicable,
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
47
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
48
from ..transport import (
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
49
    memory,
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
50
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
51
from . import test_server
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
52
53
54
class TestPackRepository(TestCaseWithTransport):
55
    """Tests to be repeated across all pack-based formats.
56
57
    The following are populated from the test scenario:
58
59
    :ivar format_name: Registered name fo the format to test.
60
    :ivar format_string: On-disk format marker.
61
    :ivar format_supports_external_lookups: Boolean.
62
    """
63
64
    def get_format(self):
6653.6.5 by Jelmer Vernooij
Rename make_bzrdir to make_controldir.
65
        return controldir.format_registry.make_controldir(self.format_name)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
66
67
    def test_attribute__fetch_order(self):
3606.7.3 by John Arbash Meinel
We don't have to fetch in topological order, as long as we fix all of the delta logic pieces.
68
        """Packs do not need ordered data retrieval."""
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
69
        format = self.get_format()
70
        repo = self.make_repository('.', format=format)
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
71
        self.assertEqual('unordered', repo._format._fetch_order)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
72
73
    def test_attribute__fetch_uses_deltas(self):
74
        """Packs reuse deltas."""
75
        format = self.get_format()
76
        repo = self.make_repository('.', format=format)
4597.1.10 by John Arbash Meinel
Fix some tests that were failing because we checked against RepositoryFormatCHK1
77
        if isinstance(format.repository_format, RepositoryFormat2a):
4265.1.4 by John Arbash Meinel
Special case the CHK1 format to allow it to not fetch using deltas.
78
            # TODO: This is currently a workaround. CHK format repositories
79
            #       ignore the 'deltas' flag, but during conversions, we can't
80
            #       do unordered delta fetches. Remove this clause once we
81
            #       improve the inter-format fetching.
82
            self.assertEqual(False, repo._format._fetch_uses_deltas)
83
        else:
84
            self.assertEqual(True, repo._format._fetch_uses_deltas)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
85
86
    def test_disk_layout(self):
87
        format = self.get_format()
88
        repo = self.make_repository('.', format=format)
89
        # in case of side effects of locking.
90
        repo.lock_write()
91
        repo.unlock()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
92
        t = repo.controldir.get_repository_transport(None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
93
        self.check_format(t)
94
        # XXX: no locks left when unlocked at the moment
95
        # self.assertEqualDiff('', t.get('lock').read())
96
        self.check_databases(t)
97
98
    def check_format(self, t):
99
        self.assertEqualDiff(
7143.15.2 by Jelmer Vernooij
Run autopep8.
100
            self.format_string.encode('ascii'),  # from scenario
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
101
            t.get('format').read())
102
103
    def assertHasNoKndx(self, t, knit_name):
104
        """Assert that knit_name has no index on t."""
105
        self.assertFalse(t.has(knit_name + '.kndx'))
106
107
    def assertHasNoKnit(self, t, knit_name):
108
        """Assert that knit_name exists on t."""
109
        # no default content
110
        self.assertFalse(t.has(knit_name + '.knit'))
111
112
    def check_databases(self, t):
113
        """check knit content for a repository."""
114
        # check conversion worked
115
        self.assertHasNoKndx(t, 'inventory')
116
        self.assertHasNoKnit(t, 'inventory')
117
        self.assertHasNoKndx(t, 'revisions')
118
        self.assertHasNoKnit(t, 'revisions')
119
        self.assertHasNoKndx(t, 'signatures')
120
        self.assertHasNoKnit(t, 'signatures')
121
        self.assertFalse(t.has('knits'))
122
        # revision-indexes file-container directory
123
        self.assertEqual([],
7143.15.2 by Jelmer Vernooij
Run autopep8.
124
                         list(self.index_class(t, 'pack-names', None).iter_all_entries()))
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
125
        self.assertTrue(S_ISDIR(t.stat('packs').st_mode))
126
        self.assertTrue(S_ISDIR(t.stat('upload').st_mode))
127
        self.assertTrue(S_ISDIR(t.stat('indices').st_mode))
128
        self.assertTrue(S_ISDIR(t.stat('obsolete_packs').st_mode))
129
130
    def test_shared_disk_layout(self):
131
        format = self.get_format()
132
        repo = self.make_repository('.', shared=True, format=format)
133
        # we want:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
134
        t = repo.controldir.get_repository_transport(None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
135
        self.check_format(t)
136
        # XXX: no locks left when unlocked at the moment
137
        # self.assertEqualDiff('', t.get('lock').read())
138
        # We should have a 'shared-storage' marker file.
7045.1.14 by Jelmer Vernooij
More fixes.
139
        with t.get('shared-storage') as f:
140
            self.assertEqualDiff(b'', f.read())
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
141
        self.check_databases(t)
142
143
    def test_shared_no_tree_disk_layout(self):
144
        format = self.get_format()
145
        repo = self.make_repository('.', shared=True, format=format)
146
        repo.set_make_working_trees(False)
147
        # we want:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
148
        t = repo.controldir.get_repository_transport(None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
149
        self.check_format(t)
150
        # XXX: no locks left when unlocked at the moment
151
        # self.assertEqualDiff('', t.get('lock').read())
152
        # We should have a 'shared-storage' marker file.
7045.1.14 by Jelmer Vernooij
More fixes.
153
        with t.get('shared-storage') as f:
154
            self.assertEqualDiff(b'', f.read())
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
155
        # We should have a marker for the no-working-trees flag.
7045.1.14 by Jelmer Vernooij
More fixes.
156
        with t.get('no-working-trees') as f:
157
            self.assertEqualDiff(b'', f.read())
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
158
        # The marker should go when we toggle the setting.
159
        repo.set_make_working_trees(True)
160
        self.assertFalse(t.has('no-working-trees'))
161
        self.check_databases(t)
162
163
    def test_adding_revision_creates_pack_indices(self):
164
        format = self.get_format()
165
        tree = self.make_branch_and_tree('.', format=format)
7143.15.2 by Jelmer Vernooij
Run autopep8.
166
        trans = tree.branch.repository.controldir.get_repository_transport(
167
            None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
168
        self.assertEqual([],
7143.15.2 by Jelmer Vernooij
Run autopep8.
169
                         list(self.index_class(trans, 'pack-names', None).iter_all_entries()))
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
170
        tree.commit('foobarbaz')
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
171
        index = self.index_class(trans, 'pack-names', None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
172
        index_nodes = list(index.iter_all_entries())
173
        self.assertEqual(1, len(index_nodes))
174
        node = index_nodes[0]
175
        name = node[1][0]
176
        # the pack sizes should be listed in the index
177
        pack_value = node[2]
7045.1.20 by Jelmer Vernooij
Fix per_pack_repository tests.
178
        sizes = [int(digits) for digits in pack_value.split(b' ')]
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
179
        for size, suffix in zip(sizes, ['.rix', '.iix', '.tix', '.six']):
7045.1.20 by Jelmer Vernooij
Fix per_pack_repository tests.
180
            stat = trans.stat('indices/%s%s' % (name.decode('ascii'), suffix))
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
181
            self.assertEqual(size, stat.st_size)
182
183
    def test_pulling_nothing_leads_to_no_new_names(self):
184
        format = self.get_format()
185
        tree1 = self.make_branch_and_tree('1', format=format)
186
        tree2 = self.make_branch_and_tree('2', format=format)
187
        tree1.branch.repository.fetch(tree2.branch.repository)
7143.15.2 by Jelmer Vernooij
Run autopep8.
188
        trans = tree1.branch.repository.controldir.get_repository_transport(
189
            None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
190
        self.assertEqual([],
7143.15.2 by Jelmer Vernooij
Run autopep8.
191
                         list(self.index_class(trans, 'pack-names', None).iter_all_entries()))
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
192
193
    def test_commit_across_pack_shape_boundary_autopacks(self):
194
        format = self.get_format()
195
        tree = self.make_branch_and_tree('.', format=format)
7143.15.2 by Jelmer Vernooij
Run autopep8.
196
        trans = tree.branch.repository.controldir.get_repository_transport(
197
            None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
198
        # This test could be a little cheaper by replacing the packs
199
        # attribute on the repository to allow a different pack distribution
200
        # and max packs policy - so we are checking the policy is honoured
201
        # in the test. But for now 11 commits is not a big deal in a single
202
        # test.
203
        for x in range(9):
204
            tree.commit('commit %s' % x)
205
        # there should be 9 packs:
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
206
        index = self.index_class(trans, 'pack-names', None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
207
        self.assertEqual(9, len(list(index.iter_all_entries())))
208
        # insert some files in obsolete_packs which should be removed by pack.
6973.6.2 by Jelmer Vernooij
Fix more tests.
209
        trans.put_bytes('obsolete_packs/foo', b'123')
210
        trans.put_bytes('obsolete_packs/bar', b'321')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
211
        # committing one more should coalesce to 1 of 10.
212
        tree.commit('commit triggering pack')
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
213
        index = self.index_class(trans, 'pack-names', None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
214
        self.assertEqual(1, len(list(index.iter_all_entries())))
215
        # packing should not damage data
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
216
        tree = tree.controldir.open_workingtree()
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
217
        check_result = tree.branch.repository.check(
218
            [tree.branch.last_revision()])
7143.15.2 by Jelmer Vernooij
Run autopep8.
219
        nb_files = 5  # .pack, .rix, .iix, .tix, .six
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
220
        if tree.branch.repository._format.supports_chks:
7143.15.2 by Jelmer Vernooij
Run autopep8.
221
            nb_files += 1  # .cix
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
222
        # We should have 10 x nb_files files in the obsolete_packs directory.
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
223
        obsolete_files = list(trans.list_dir('obsolete_packs'))
224
        self.assertFalse('foo' in obsolete_files)
225
        self.assertFalse('bar' in obsolete_files)
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
226
        self.assertEqual(10 * nb_files, len(obsolete_files))
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
227
        # XXX: Todo check packs obsoleted correctly - old packs and indices
228
        # in the obsolete_packs directory.
229
        large_pack_name = list(index.iter_all_entries())[0][1][0]
230
        # finally, committing again should not touch the large pack.
231
        tree.commit('commit not triggering pack')
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
232
        index = self.index_class(trans, 'pack-names', None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
233
        self.assertEqual(2, len(list(index.iter_all_entries())))
234
        pack_names = [node[1][0] for node in index.iter_all_entries()]
235
        self.assertTrue(large_pack_name in pack_names)
236
4431.3.7 by Jonathan Lange
Cherrypick bzr.dev 4470, resolving conflicts.
237
    def test_commit_write_group_returns_new_pack_names(self):
4634.30.1 by Robert Collins
Properly pack 2a repositories during conversion operations. (Robert Collins. #423818)
238
        # This test doesn't need real disk.
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
239
        self.vfs_transport_factory = memory.MemoryServer
4431.3.7 by Jonathan Lange
Cherrypick bzr.dev 4470, resolving conflicts.
240
        format = self.get_format()
4634.30.1 by Robert Collins
Properly pack 2a repositories during conversion operations. (Robert Collins. #423818)
241
        repo = self.make_repository('foo', format=format)
7045.1.20 by Jelmer Vernooij
Fix per_pack_repository tests.
242
        with repo.lock_write():
4634.30.1 by Robert Collins
Properly pack 2a repositories during conversion operations. (Robert Collins. #423818)
243
            # All current pack repository styles autopack at 10 revisions; and
244
            # autopack as well as regular commit write group needs to return
245
            # the new pack name. Looping is a little ugly, but we don't have a
246
            # clean way to test both the autopack logic and the normal code
247
            # path without doing this loop.
248
            for pos in range(10):
6973.10.4 by Jelmer Vernooij
Update python3.passing.
249
                revid = b'%d' % pos
4634.30.1 by Robert Collins
Properly pack 2a repositories during conversion operations. (Robert Collins. #423818)
250
                repo.start_write_group()
251
                try:
252
                    inv = inventory.Inventory(revision_id=revid)
253
                    inv.root.revision = revid
254
                    repo.texts.add_lines((inv.root.file_id, revid), [], [])
255
                    rev = _mod_revision.Revision(timestamp=0, timezone=None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
256
                                                 committer="Foo Bar <foo@example.com>", message="Message",
257
                                                 revision_id=revid)
4634.30.1 by Robert Collins
Properly pack 2a repositories during conversion operations. (Robert Collins. #423818)
258
                    rev.parent_ids = ()
259
                    repo.add_revision(revid, rev, inv=inv)
260
                except:
261
                    repo.abort_write_group()
262
                    raise
263
                else:
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
264
                    old_names = set(repo._pack_collection._names)
4634.30.1 by Robert Collins
Properly pack 2a repositories during conversion operations. (Robert Collins. #423818)
265
                    result = repo.commit_write_group()
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
266
                    cur_names = set(repo._pack_collection._names)
267
                    # In this test, len(result) is always 1, so unordered is ok
268
                    new_names = list(cur_names - old_names)
7078.7.1 by Jelmer Vernooij
Fix some stream tests.
269
                    self.assertEqual(new_names, result)
4431.3.7 by Jonathan Lange
Cherrypick bzr.dev 4470, resolving conflicts.
270
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
271
    def test_fail_obsolete_deletion(self):
272
        # failing to delete obsolete packs is not fatal
273
        format = self.get_format()
5017.3.44 by Vincent Ladeuil
-s bt.per_pack_repos passing
274
        server = test_server.FakeNFSServer()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
275
        self.start_server(server)
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
276
        t = transport.get_transport_from_url(server.get_url())
5609.9.1 by Martin
Blindly change all users of get_transport to address the function via the transport module
277
        bzrdir = self.get_format().initialize_on_transport(t)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
278
        repo = bzrdir.create_repository()
279
        repo_transport = bzrdir.get_repository_transport(None)
280
        self.assertTrue(repo_transport.has('obsolete_packs'))
281
        # these files are in use by another client and typically can't be deleted
6973.6.2 by Jelmer Vernooij
Fix more tests.
282
        repo_transport.put_bytes('obsolete_packs/.nfsblahblah', b'contents')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
283
        repo._pack_collection._clear_obsolete_packs()
284
        self.assertTrue(repo_transport.has('obsolete_packs/.nfsblahblah'))
285
5086.7.8 by Andrew Bennetts
Test that pack collection uses set_sibling_indices.
286
    def test_pack_collection_sets_sibling_indices(self):
287
        """The CombinedGraphIndex objects in the pack collection are all
288
        siblings of each other, so that search-order reorderings will be copied
289
        to each other.
290
        """
291
        repo = self.make_repository('repo')
292
        pack_coll = repo._pack_collection
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
293
        indices = {pack_coll.revision_index, pack_coll.inventory_index,
7143.15.2 by Jelmer Vernooij
Run autopep8.
294
                   pack_coll.text_index, pack_coll.signature_index}
5086.7.8 by Andrew Bennetts
Test that pack collection uses set_sibling_indices.
295
        if pack_coll.chk_index is not None:
296
            indices.add(pack_coll.chk_index)
297
        combined_indices = set(idx.combined_index for idx in indices)
298
        for combined_index in combined_indices:
299
            self.assertEqual(
300
                combined_indices.difference([combined_index]),
301
                combined_index._sibling_indices)
302
7239.1.1 by Jelmer Vernooij
Fix signature handling when repacking.
303
    def test_pack_with_signatures(self):
304
        format = self.get_format()
305
        tree = self.make_branch_and_tree('.', format=format)
306
        trans = tree.branch.repository.controldir.get_repository_transport(
307
            None)
308
        revid1 = tree.commit('start')
309
        revid2 = tree.commit('more work')
310
        strategy = gpg.LoopbackGPGStrategy(None)
311
        repo = tree.branch.repository
312
        self.addCleanup(repo.lock_write().unlock)
313
        repo.start_write_group()
314
        repo.sign_revision(revid1, strategy)
315
        repo.commit_write_group()
316
        repo.start_write_group()
317
        repo.sign_revision(revid2, strategy)
318
        repo.commit_write_group()
319
        tree.branch.repository.pack()
320
        # there should be 1 pack:
321
        index = self.index_class(trans, 'pack-names', None)
322
        self.assertEqual(1, len(list(index.iter_all_entries())))
323
        self.assertEqual(2, len(tree.branch.repository.all_revision_ids()))
324
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
325
    def test_pack_after_two_commits_packs_everything(self):
326
        format = self.get_format()
327
        tree = self.make_branch_and_tree('.', format=format)
7143.15.2 by Jelmer Vernooij
Run autopep8.
328
        trans = tree.branch.repository.controldir.get_repository_transport(
329
            None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
330
        tree.commit('start')
331
        tree.commit('more work')
332
        tree.branch.repository.pack()
333
        # there should be 1 pack:
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
334
        index = self.index_class(trans, 'pack-names', None)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
335
        self.assertEqual(1, len(list(index.iter_all_entries())))
336
        self.assertEqual(2, len(tree.branch.repository.all_revision_ids()))
337
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
338
    def test_pack_preserves_all_inventories(self):
339
        # This is related to bug:
340
        #   https://bugs.launchpad.net/bzr/+bug/412198
341
        # Stacked repositories need to keep the inventory for parents, even
342
        # after a pack operation. However, it is harder to test that, then just
343
        # test that all inventory texts are preserved.
344
        format = self.get_format()
345
        builder = self.make_branch_builder('source', format=format)
346
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
347
        builder.build_snapshot(None, [
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
348
            ('add', ('', b'root-id', 'directory', None))],
6855.4.1 by Jelmer Vernooij
Yet more bees.
349
            revision_id=b'A-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
350
        builder.build_snapshot(None, [
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
351
            ('add', ('file', b'file-id', 'file', b'B content\n'))],
6855.4.1 by Jelmer Vernooij
Yet more bees.
352
            revision_id=b'B-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
353
        builder.build_snapshot(None, [
6883.22.11 by Jelmer Vernooij
merge trunk
354
            ('modify', ('file', b'C content\n'))],
6855.4.1 by Jelmer Vernooij
Yet more bees.
355
            revision_id=b'C-id')
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
356
        builder.finish_series()
357
        b = builder.get_branch()
358
        b.lock_read()
359
        self.addCleanup(b.unlock)
360
        repo = self.make_repository('repo', shared=True, format=format)
361
        repo.lock_write()
362
        self.addCleanup(repo.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
363
        repo.fetch(b.repository, revision_id=b'B-id')
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
364
        inv = next(b.repository.iter_inventories([b'C-id']))
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
365
        repo.start_write_group()
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
366
        repo.add_inventory(b'C-id', inv, [b'B-id'])
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
367
        repo.commit_write_group()
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
368
        self.assertEqual([(b'A-id',), (b'B-id',), (b'C-id',)],
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
369
                         sorted(repo.inventories.keys()))
370
        repo.pack()
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
371
        self.assertEqual([(b'A-id',), (b'B-id',), (b'C-id',)],
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
372
                         sorted(repo.inventories.keys()))
373
        # Content should be preserved as well
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
374
        self.assertEqual(inv, next(repo.iter_inventories([b'C-id'])))
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
375
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
376
    def test_pack_layout(self):
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
377
        # Test that the ordering of revisions in pack repositories is
378
        # tip->ancestor
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
379
        format = self.get_format()
380
        tree = self.make_branch_and_tree('.', format=format)
7143.15.2 by Jelmer Vernooij
Run autopep8.
381
        trans = tree.branch.repository.controldir.get_repository_transport(
382
            None)
6855.4.1 by Jelmer Vernooij
Yet more bees.
383
        tree.commit('start', rev_id=b'1')
384
        tree.commit('more work', rev_id=b'2')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
385
        tree.branch.repository.pack()
386
        tree.lock_read()
387
        self.addCleanup(tree.unlock)
388
        pack = tree.branch.repository._pack_collection.get_pack_by_name(
389
            tree.branch.repository._pack_collection.names()[0])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
390
        # revision access tends to be tip->ancestor, so ordering that way on
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
391
        # disk is a good idea.
7045.1.20 by Jelmer Vernooij
Fix per_pack_repository tests.
392
        pos_1 = pos_2 = None
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
393
        for _1, key, val, refs in pack.revision_index.iter_all_entries():
6619.3.18 by Jelmer Vernooij
Run 2to3 idioms fixer.
394
            if isinstance(format.repository_format, RepositoryFormat2a):
4350.2.1 by John Arbash Meinel
Update a test to support CHK formats.
395
                # group_start, group_len, internal_start, internal_len
6631.3.1 by Martin
Run 2to3 map fixer and refactor after
396
                pos = list(map(int, val.split()))
4350.2.1 by John Arbash Meinel
Update a test to support CHK formats.
397
            else:
398
                # eol_flag, start, len
399
                pos = int(val[1:].split()[0])
7045.1.20 by Jelmer Vernooij
Fix per_pack_repository tests.
400
            if key == (b'1',):
4350.2.1 by John Arbash Meinel
Update a test to support CHK formats.
401
                pos_1 = pos
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
402
            else:
4350.2.1 by John Arbash Meinel
Update a test to support CHK formats.
403
                pos_2 = pos
404
        self.assertTrue(pos_2 < pos_1, 'rev 1 came before rev 2 %s > %s'
405
                                       % (pos_1, pos_2))
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
406
407
    def test_pack_repositories_support_multiple_write_locks(self):
408
        format = self.get_format()
409
        self.make_repository('.', shared=True, format=format)
410
        r1 = repository.Repository.open('.')
411
        r2 = repository.Repository.open('.')
412
        r1.lock_write()
413
        self.addCleanup(r1.unlock)
414
        r2.lock_write()
415
        r2.unlock()
416
417
    def _add_text(self, repo, fileid):
418
        """Add a text to the repository within a write group."""
7143.15.2 by Jelmer Vernooij
Run autopep8.
419
        repo.texts.add_lines((fileid, b'samplerev+' + fileid), [],
420
                             [b'smaplerev+' + fileid])
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
421
422
    def test_concurrent_writers_merge_new_packs(self):
423
        format = self.get_format()
424
        self.make_repository('.', shared=True, format=format)
425
        r1 = repository.Repository.open('.')
426
        r2 = repository.Repository.open('.')
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
427
        with r1.lock_write():
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
428
            # access enough data to load the names list
429
            list(r1.all_revision_ids())
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
430
            with r2.lock_write():
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
431
                # access enough data to load the names list
432
                list(r2.all_revision_ids())
433
                r1.start_write_group()
434
                try:
435
                    r2.start_write_group()
436
                    try:
6973.10.4 by Jelmer Vernooij
Update python3.passing.
437
                        self._add_text(r1, b'fileidr1')
438
                        self._add_text(r2, b'fileidr2')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
439
                    except:
440
                        r2.abort_write_group()
441
                        raise
442
                except:
443
                    r1.abort_write_group()
444
                    raise
445
                # both r1 and r2 have open write groups with data in them
446
                # created while the other's write group was open.
447
                # Commit both which requires a merge to the pack-names.
448
                try:
449
                    r1.commit_write_group()
450
                except:
451
                    r1.abort_write_group()
452
                    r2.abort_write_group()
453
                    raise
454
                r2.commit_write_group()
455
                # tell r1 to reload from disk
456
                r1._pack_collection.reset()
457
                # Now both repositories should know about both names
458
                r1._pack_collection.ensure_loaded()
459
                r2._pack_collection.ensure_loaded()
7143.15.2 by Jelmer Vernooij
Run autopep8.
460
                self.assertEqual(r1._pack_collection.names(),
461
                                 r2._pack_collection.names())
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
462
                self.assertEqual(2, len(r1._pack_collection.names()))
463
464
    def test_concurrent_writer_second_preserves_dropping_a_pack(self):
465
        format = self.get_format()
466
        self.make_repository('.', shared=True, format=format)
467
        r1 = repository.Repository.open('.')
468
        r2 = repository.Repository.open('.')
469
        # add a pack to drop
7143.21.1 by Jelmer Vernooij
Add WriteGroup contextmanager.
470
        with r1.lock_write():
471
            with repository.WriteGroup(r1):
6973.10.4 by Jelmer Vernooij
Update python3.passing.
472
                self._add_text(r1, b'fileidr1')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
473
            r1._pack_collection.ensure_loaded()
474
            name_to_drop = r1._pack_collection.all_packs()[0].name
7143.21.1 by Jelmer Vernooij
Add WriteGroup contextmanager.
475
        with r1.lock_write():
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
476
            # access enough data to load the names list
477
            list(r1.all_revision_ids())
7143.21.1 by Jelmer Vernooij
Add WriteGroup contextmanager.
478
            with r2.lock_write():
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
479
                # access enough data to load the names list
480
                list(r2.all_revision_ids())
481
                r1._pack_collection.ensure_loaded()
482
                try:
483
                    r2.start_write_group()
484
                    try:
485
                        # in r1, drop the pack
486
                        r1._pack_collection._remove_pack_from_memory(
487
                            r1._pack_collection.get_pack_by_name(name_to_drop))
488
                        # in r2, add a pack
6973.10.4 by Jelmer Vernooij
Update python3.passing.
489
                        self._add_text(r2, b'fileidr2')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
490
                    except:
491
                        r2.abort_write_group()
492
                        raise
493
                except:
494
                    r1._pack_collection.reset()
495
                    raise
496
                # r1 has a changed names list, and r2 an open write groups with
497
                # changes.
498
                # save r1, and then commit the r2 write group, which requires a
499
                # merge to the pack-names, which should not reinstate
500
                # name_to_drop
501
                try:
502
                    r1._pack_collection._save_pack_names()
503
                    r1._pack_collection.reset()
504
                except:
505
                    r2.abort_write_group()
506
                    raise
507
                try:
508
                    r2.commit_write_group()
509
                except:
510
                    r2.abort_write_group()
511
                    raise
512
                # Now both repositories should now about just one name.
513
                r1._pack_collection.ensure_loaded()
514
                r2._pack_collection.ensure_loaded()
7143.15.2 by Jelmer Vernooij
Run autopep8.
515
                self.assertEqual(r1._pack_collection.names(),
516
                                 r2._pack_collection.names())
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
517
                self.assertEqual(1, len(r1._pack_collection.names()))
518
                self.assertFalse(name_to_drop in r1._pack_collection.names())
519
3789.1.1 by John Arbash Meinel
add the failing acceptance test for the first portion.
520
    def test_concurrent_pack_triggers_reload(self):
521
        # create 2 packs, which we will then collapse
522
        tree = self.make_branch_and_tree('tree')
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
523
        with tree.lock_write():
3789.1.2 by John Arbash Meinel
Add RepositoryPackCollection.reload_pack_names()
524
            rev1 = tree.commit('one')
525
            rev2 = tree.commit('two')
526
            r2 = repository.Repository.open('tree')
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
527
            with r2.lock_read():
3789.1.1 by John Arbash Meinel
add the failing acceptance test for the first portion.
528
                # Now r2 has read the pack-names file, but will need to reload
529
                # it after r1 has repacked
3789.1.2 by John Arbash Meinel
Add RepositoryPackCollection.reload_pack_names()
530
                tree.branch.repository.pack()
7143.15.2 by Jelmer Vernooij
Run autopep8.
531
                self.assertEqual({rev2: (rev1,)}, r2.get_parent_map([rev2]))
3789.1.1 by John Arbash Meinel
add the failing acceptance test for the first portion.
532
3789.2.8 by John Arbash Meinel
Add a test that KnitPackRepository.get_record_stream retries when appropriate.
533
    def test_concurrent_pack_during_get_record_reloads(self):
534
        tree = self.make_branch_and_tree('tree')
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
535
        with tree.lock_write():
3789.2.8 by John Arbash Meinel
Add a test that KnitPackRepository.get_record_stream retries when appropriate.
536
            rev1 = tree.commit('one')
537
            rev2 = tree.commit('two')
3789.2.14 by John Arbash Meinel
Update AggregateIndex to pass the reload_func into _DirectPackAccess
538
            keys = [(rev1,), (rev2,)]
3789.2.8 by John Arbash Meinel
Add a test that KnitPackRepository.get_record_stream retries when appropriate.
539
            r2 = repository.Repository.open('tree')
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
540
            with r2.lock_read():
3789.2.8 by John Arbash Meinel
Add a test that KnitPackRepository.get_record_stream retries when appropriate.
541
                # At this point, we will start grabbing a record stream, and
542
                # trigger a repack mid-way
543
                packed = False
544
                result = {}
545
                record_stream = r2.revisions.get_record_stream(keys,
7143.15.2 by Jelmer Vernooij
Run autopep8.
546
                                                               'unordered', False)
3789.2.8 by John Arbash Meinel
Add a test that KnitPackRepository.get_record_stream retries when appropriate.
547
                for record in record_stream:
548
                    result[record.key] = record
549
                    if not packed:
550
                        tree.branch.repository.pack()
551
                        packed = True
552
                # The first record will be found in the original location, but
553
                # after the pack, we have to reload to find the next record
3789.2.14 by John Arbash Meinel
Update AggregateIndex to pass the reload_func into _DirectPackAccess
554
                self.assertEqual(sorted(keys), sorted(result.keys()))
3789.2.8 by John Arbash Meinel
Add a test that KnitPackRepository.get_record_stream retries when appropriate.
555
4634.113.2 by John Arbash Meinel
Add a test which triggers the behavior.
556
    def test_concurrent_pack_during_autopack(self):
557
        tree = self.make_branch_and_tree('tree')
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
558
        with tree.lock_write():
6651.2.2 by Martin
Apply 2to3 xrange fix and fix up with sixish range
559
            for i in range(9):
4634.113.2 by John Arbash Meinel
Add a test which triggers the behavior.
560
                tree.commit('rev %d' % (i,))
561
            r2 = repository.Repository.open('tree')
7356.1.5 by Jelmer Vernooij
Use more ExitStacks.
562
            with r2.lock_write():
4634.113.2 by John Arbash Meinel
Add a test which triggers the behavior.
563
                # Monkey patch so that pack occurs while the other repo is
564
                # autopacking. This is slightly bad, but all current pack
565
                # repository implementations have a _pack_collection, and we
566
                # test that it gets triggered. So if a future format changes
567
                # things, the test will fail rather than succeed accidentally.
568
                autopack_count = [0]
569
                r1 = tree.branch.repository
570
                orig = r1._pack_collection.pack_distribution
7143.15.2 by Jelmer Vernooij
Run autopep8.
571
4634.113.2 by John Arbash Meinel
Add a test which triggers the behavior.
572
                def trigger_during_auto(*args, **kwargs):
573
                    ret = orig(*args, **kwargs)
574
                    if not autopack_count[0]:
575
                        r2.pack()
576
                    autopack_count[0] += 1
577
                    return ret
578
                r1._pack_collection.pack_distribution = trigger_during_auto
579
                tree.commit('autopack-rev')
580
                # This triggers 2 autopacks. The first one causes r2.pack() to
581
                # fire, but r2 doesn't see the new pack file yet. The
582
                # autopack restarts and sees there are 2 files and there
583
                # should be only 1 for 10 commits. So it goes ahead and
584
                # finishes autopacking.
585
                self.assertEqual([2], autopack_count)
586
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
587
    def test_lock_write_does_not_physically_lock(self):
588
        repo = self.make_repository('.', format=self.get_format())
589
        repo.lock_write()
590
        self.addCleanup(repo.unlock)
591
        self.assertFalse(repo.get_physical_lock_status())
592
593
    def prepare_for_break_lock(self):
594
        # Setup the global ui factory state so that a break-lock method call
595
        # will find usable input in the input stream.
4449.3.27 by Martin Pool
More test updates to use CannedInputUIFactory
596
        ui.ui_factory = ui.CannedInputUIFactory([True])
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
597
598
    def test_break_lock_breaks_physical_lock(self):
599
        repo = self.make_repository('.', format=self.get_format())
600
        repo._pack_collection.lock_names()
3650.4.1 by Aaron Bentley
Fix test kipple in test_break_lock_breaks_physical_lock
601
        repo.control_files.leave_in_place()
602
        repo.unlock()
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
603
        repo2 = repository.Repository.open('.')
604
        self.assertTrue(repo.get_physical_lock_status())
605
        self.prepare_for_break_lock()
606
        repo2.break_lock()
607
        self.assertFalse(repo.get_physical_lock_status())
608
609
    def test_broken_physical_locks_error_on__unlock_names_lock(self):
610
        repo = self.make_repository('.', format=self.get_format())
611
        repo._pack_collection.lock_names()
612
        self.assertTrue(repo.get_physical_lock_status())
613
        repo2 = repository.Repository.open('.')
614
        self.prepare_for_break_lock()
615
        repo2.break_lock()
7143.15.2 by Jelmer Vernooij
Run autopep8.
616
        self.assertRaises(errors.LockBroken,
617
                          repo._pack_collection._unlock_names)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
618
619
    def test_fetch_without_find_ghosts_ignores_ghosts(self):
620
        # we want two repositories at this point:
621
        # one with a revision that is a ghost in the other
622
        # repository.
623
        # 'ghost' is present in has_ghost, 'ghost' is absent in 'missing_ghost'.
624
        # 'references' is present in both repositories, and 'tip' is present
625
        # just in has_ghost.
626
        # has_ghost       missing_ghost
7143.15.2 by Jelmer Vernooij
Run autopep8.
627
        # ------------------------------
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
628
        # 'ghost'             -
629
        # 'references'    'references'
630
        # 'tip'               -
631
        # In this test we fetch 'tip' which should not fetch 'ghost'
632
        has_ghost = self.make_repository('has_ghost', format=self.get_format())
633
        missing_ghost = self.make_repository('missing_ghost',
7143.15.2 by Jelmer Vernooij
Run autopep8.
634
                                             format=self.get_format())
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
635
636
        def add_commit(repo, revision_id, parent_ids):
637
            repo.lock_write()
638
            repo.start_write_group()
639
            inv = inventory.Inventory(revision_id=revision_id)
640
            inv.root.revision = revision_id
641
            root_id = inv.root.file_id
642
            sha1 = repo.add_inventory(revision_id, inv, [])
643
            repo.texts.add_lines((root_id, revision_id), [], [])
644
            rev = _mod_revision.Revision(timestamp=0,
645
                                         timezone=None,
646
                                         committer="Foo Bar <foo@example.com>",
647
                                         message="Message",
648
                                         inventory_sha1=sha1,
649
                                         revision_id=revision_id)
650
            rev.parent_ids = parent_ids
651
            repo.add_revision(revision_id, rev)
652
            repo.commit_write_group()
653
            repo.unlock()
6973.5.2 by Jelmer Vernooij
Add more bees.
654
        add_commit(has_ghost, b'ghost', [])
655
        add_commit(has_ghost, b'references', [b'ghost'])
656
        add_commit(missing_ghost, b'references', [b'ghost'])
657
        add_commit(has_ghost, b'tip', [b'references'])
658
        missing_ghost.fetch(has_ghost, b'tip')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
659
        # missing ghost now has tip and not ghost.
6973.5.2 by Jelmer Vernooij
Add more bees.
660
        rev = missing_ghost.get_revision(b'tip')
661
        inv = missing_ghost.get_inventory(b'tip')
662
        self.assertRaises(errors.NoSuchRevision,
7143.15.2 by Jelmer Vernooij
Run autopep8.
663
                          missing_ghost.get_revision, b'ghost')
6973.5.2 by Jelmer Vernooij
Add more bees.
664
        self.assertRaises(errors.NoSuchRevision,
7143.15.2 by Jelmer Vernooij
Run autopep8.
665
                          missing_ghost.get_inventory, b'ghost')
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
666
4011.5.6 by Andrew Bennetts
Make sure it's not possible to commit a pack write group when any versioned file has missing compression parents.
667
    def make_write_ready_repo(self):
4360.4.6 by John Arbash Meinel
Change how 'missing.*parent_prevents_commit' determines what to skip.
668
        format = self.get_format()
4597.1.10 by John Arbash Meinel
Fix some tests that were failing because we checked against RepositoryFormatCHK1
669
        if isinstance(format.repository_format, RepositoryFormat2a):
4360.4.6 by John Arbash Meinel
Change how 'missing.*parent_prevents_commit' determines what to skip.
670
            raise TestNotApplicable("No missing compression parents")
671
        repo = self.make_repository('.', format=format)
4011.5.6 by Andrew Bennetts
Make sure it's not possible to commit a pack write group when any versioned file has missing compression parents.
672
        repo.lock_write()
4360.4.6 by John Arbash Meinel
Change how 'missing.*parent_prevents_commit' determines what to skip.
673
        self.addCleanup(repo.unlock)
4011.5.6 by Andrew Bennetts
Make sure it's not possible to commit a pack write group when any versioned file has missing compression parents.
674
        repo.start_write_group()
4360.4.6 by John Arbash Meinel
Change how 'missing.*parent_prevents_commit' determines what to skip.
675
        self.addCleanup(repo.abort_write_group)
4011.5.6 by Andrew Bennetts
Make sure it's not possible to commit a pack write group when any versioned file has missing compression parents.
676
        return repo
677
678
    def test_missing_inventories_compression_parent_prevents_commit(self):
679
        repo = self.make_write_ready_repo()
680
        key = ('junk',)
681
        repo.inventories._index._missing_compression_parents.add(key)
682
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
683
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
684
685
    def test_missing_revisions_compression_parent_prevents_commit(self):
686
        repo = self.make_write_ready_repo()
687
        key = ('junk',)
688
        repo.revisions._index._missing_compression_parents.add(key)
689
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
690
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
691
692
    def test_missing_signatures_compression_parent_prevents_commit(self):
693
        repo = self.make_write_ready_repo()
694
        key = ('junk',)
695
        repo.signatures._index._missing_compression_parents.add(key)
696
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
697
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
698
699
    def test_missing_text_compression_parent_prevents_commit(self):
700
        repo = self.make_write_ready_repo()
701
        key = ('some', 'junk')
702
        repo.texts._index._missing_compression_parents.add(key)
703
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
704
        e = self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
705
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
706
    def test_supports_external_lookups(self):
707
        repo = self.make_repository('.', format=self.get_format())
708
        self.assertEqual(self.format_supports_external_lookups,
7143.15.2 by Jelmer Vernooij
Run autopep8.
709
                         repo._format.supports_external_lookups)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
710
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
711
    def _lock_write(self, write_lockable):
712
        """Lock write_lockable, add a cleanup and return the result.
7143.15.2 by Jelmer Vernooij
Run autopep8.
713
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
714
        :param write_lockable: An object with a lock_write method.
715
        :return: The result of write_lockable.lock_write().
716
        """
717
        result = write_lockable.lock_write()
718
        self.addCleanup(result.unlock)
719
        return result
720
3825.4.1 by Andrew Bennetts
Add suppress_errors to abort_write_group.
721
    def test_abort_write_group_does_not_raise_when_suppressed(self):
722
        """Similar to per_repository.test_write_group's test of the same name.
723
724
        Also requires that the exception is logged.
725
        """
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
726
        self.vfs_transport_factory = memory.MemoryServer
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
727
        repo = self.make_repository('repo', format=self.get_format())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
728
        token = self._lock_write(repo).repository_token
3825.4.1 by Andrew Bennetts
Add suppress_errors to abort_write_group.
729
        repo.start_write_group()
730
        # Damage the repository on the filesystem
731
        self.get_transport('').rename('repo', 'foo')
732
        # abort_write_group will not raise an error
733
        self.assertEqual(None, repo.abort_write_group(suppress_errors=True))
734
        # But it does log an error
4794.1.15 by Robert Collins
Review feedback.
735
        log = self.get_log()
4794.1.8 by Robert Collins
Move the passing of test logs to the result to be via the getDetails API and remove all public use of TestCase._get_log.
736
        self.assertContainsRe(log, 'abort_write_group failed')
6681.2.10 by Jelmer Vernooij
Fix failures.
737
        self.assertContainsRe(log, r'INFO  brz: ERROR \(ignored\):')
3825.4.1 by Andrew Bennetts
Add suppress_errors to abort_write_group.
738
        if token is not None:
739
            repo.leave_lock_in_place()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
740
3825.4.1 by Andrew Bennetts
Add suppress_errors to abort_write_group.
741
    def test_abort_write_group_does_raise_when_not_suppressed(self):
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
742
        self.vfs_transport_factory = memory.MemoryServer
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
743
        repo = self.make_repository('repo', format=self.get_format())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
744
        token = self._lock_write(repo).repository_token
3825.4.1 by Andrew Bennetts
Add suppress_errors to abort_write_group.
745
        repo.start_write_group()
746
        # Damage the repository on the filesystem
747
        self.get_transport('').rename('repo', 'foo')
748
        # abort_write_group will not raise an error
749
        self.assertRaises(Exception, repo.abort_write_group)
750
        if token is not None:
751
            repo.leave_lock_in_place()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
752
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
753
    def test_suspend_write_group(self):
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
754
        self.vfs_transport_factory = memory.MemoryServer
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
755
        repo = self.make_repository('repo', format=self.get_format())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
756
        token = self._lock_write(repo).repository_token
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
757
        repo.start_write_group()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
758
        repo.texts.add_lines((b'file-id', b'revid'), (), [b'lines'])
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
759
        wg_tokens = repo.suspend_write_group()
760
        expected_pack_name = wg_tokens[0] + '.pack'
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
761
        expected_names = [wg_tokens[0] + ext for ext in
7143.15.2 by Jelmer Vernooij
Run autopep8.
762
                          ('.rix', '.iix', '.tix', '.six')]
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
763
        if repo.chk_bytes is not None:
764
            expected_names.append(wg_tokens[0] + '.cix')
765
        expected_names.append(expected_pack_name)
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
766
        upload_transport = repo._pack_collection._upload_transport
767
        limbo_files = upload_transport.list_dir('')
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
768
        self.assertEqual(sorted(expected_names), sorted(limbo_files))
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
769
        md5 = osutils.md5(upload_transport.get_bytes(expected_pack_name))
770
        self.assertEqual(wg_tokens[0], md5.hexdigest())
771
4343.3.8 by John Arbash Meinel
Some cleanup passes.
772
    def test_resume_chk_bytes(self):
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
773
        self.vfs_transport_factory = memory.MemoryServer
4343.3.8 by John Arbash Meinel
Some cleanup passes.
774
        repo = self.make_repository('repo', format=self.get_format())
775
        if repo.chk_bytes is None:
776
            raise TestNotApplicable('no chk_bytes for this repository')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
777
        token = self._lock_write(repo).repository_token
4343.3.8 by John Arbash Meinel
Some cleanup passes.
778
        repo.start_write_group()
6973.10.4 by Jelmer Vernooij
Update python3.passing.
779
        text = b'a bit of text\n'
6973.13.2 by Jelmer Vernooij
Fix some more tests.
780
        key = (b'sha1:' + osutils.sha_string(text),)
4343.3.8 by John Arbash Meinel
Some cleanup passes.
781
        repo.chk_bytes.add_lines(key, (), [text])
782
        wg_tokens = repo.suspend_write_group()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
783
        same_repo = repo.controldir.open_repository()
4343.3.8 by John Arbash Meinel
Some cleanup passes.
784
        same_repo.lock_write()
785
        self.addCleanup(same_repo.unlock)
786
        same_repo.resume_write_group(wg_tokens)
787
        self.assertEqual([key], list(same_repo.chk_bytes.keys()))
788
        self.assertEqual(
7018.3.10 by Jelmer Vernooij
Consistent return values in PreviewTree.list_files.
789
            text, next(same_repo.chk_bytes.get_record_stream([key],
7143.15.2 by Jelmer Vernooij
Run autopep8.
790
                                                             'unordered', True)).get_bytes_as('fulltext'))
4343.3.8 by John Arbash Meinel
Some cleanup passes.
791
        same_repo.abort_write_group()
792
        self.assertEqual([], list(same_repo.chk_bytes.keys()))
793
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
794
    def test_resume_write_group_then_abort(self):
795
        # Create a repo, start a write group, insert some data, suspend.
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
796
        self.vfs_transport_factory = memory.MemoryServer
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
797
        repo = self.make_repository('repo', format=self.get_format())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
798
        token = self._lock_write(repo).repository_token
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
799
        repo.start_write_group()
6973.10.4 by Jelmer Vernooij
Update python3.passing.
800
        text_key = (b'file-id', b'revid')
801
        repo.texts.add_lines(text_key, (), [b'lines'])
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
802
        wg_tokens = repo.suspend_write_group()
803
        # Get a fresh repository object for the repo on the filesystem.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
804
        same_repo = repo.controldir.open_repository()
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
805
        # Resume
806
        same_repo.lock_write()
807
        self.addCleanup(same_repo.unlock)
808
        same_repo.resume_write_group(wg_tokens)
809
        same_repo.abort_write_group()
810
        self.assertEqual(
811
            [], same_repo._pack_collection._upload_transport.list_dir(''))
812
        self.assertEqual(
813
            [], same_repo._pack_collection._pack_transport.list_dir(''))
814
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
815
    def test_commit_resumed_write_group(self):
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
816
        self.vfs_transport_factory = memory.MemoryServer
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
817
        repo = self.make_repository('repo', format=self.get_format())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
818
        token = self._lock_write(repo).repository_token
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
819
        repo.start_write_group()
6973.10.4 by Jelmer Vernooij
Update python3.passing.
820
        text_key = (b'file-id', b'revid')
821
        repo.texts.add_lines(text_key, (), [b'lines'])
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
822
        wg_tokens = repo.suspend_write_group()
823
        # Get a fresh repository object for the repo on the filesystem.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
824
        same_repo = repo.controldir.open_repository()
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
825
        # Resume
826
        same_repo.lock_write()
827
        self.addCleanup(same_repo.unlock)
828
        same_repo.resume_write_group(wg_tokens)
829
        same_repo.commit_write_group()
830
        expected_pack_name = wg_tokens[0] + '.pack'
831
        expected_names = [wg_tokens[0] + ext for ext in
7143.15.2 by Jelmer Vernooij
Run autopep8.
832
                          ('.rix', '.iix', '.tix', '.six')]
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
833
        if repo.chk_bytes is not None:
834
            expected_names.append(wg_tokens[0] + '.cix')
835
        self.assertEqual(
836
            [], same_repo._pack_collection._upload_transport.list_dir(''))
837
        index_names = repo._pack_collection._index_transport.list_dir('')
838
        self.assertEqual(sorted(expected_names), sorted(index_names))
839
        pack_names = repo._pack_collection._pack_transport.list_dir('')
840
        self.assertEqual([expected_pack_name], pack_names)
841
4002.1.5 by Andrew Bennetts
Fix possible security issue with resuming write groups: make sure the token is well-formed so that it's not possible to steal a write group from another repo.
842
    def test_resume_malformed_token(self):
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
843
        self.vfs_transport_factory = memory.MemoryServer
4002.1.5 by Andrew Bennetts
Fix possible security issue with resuming write groups: make sure the token is well-formed so that it's not possible to steal a write group from another repo.
844
        # Make a repository with a suspended write group
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
845
        repo = self.make_repository('repo', format=self.get_format())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
846
        token = self._lock_write(repo).repository_token
4002.1.5 by Andrew Bennetts
Fix possible security issue with resuming write groups: make sure the token is well-formed so that it's not possible to steal a write group from another repo.
847
        repo.start_write_group()
6973.10.4 by Jelmer Vernooij
Update python3.passing.
848
        text_key = (b'file-id', b'revid')
849
        repo.texts.add_lines(text_key, (), [b'lines'])
4002.1.5 by Andrew Bennetts
Fix possible security issue with resuming write groups: make sure the token is well-formed so that it's not possible to steal a write group from another repo.
850
        wg_tokens = repo.suspend_write_group()
851
        # Make a new repository
4343.3.7 by John Arbash Meinel
Update the suspend/resume/commit/abort_write_group tests for CHK1.
852
        new_repo = self.make_repository('new_repo', format=self.get_format())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
853
        token = self._lock_write(new_repo).repository_token
4002.1.5 by Andrew Bennetts
Fix possible security issue with resuming write groups: make sure the token is well-formed so that it's not possible to steal a write group from another repo.
854
        hacked_wg_token = (
855
            '../../../../repo/.bzr/repository/upload/' + wg_tokens[0])
856
        self.assertRaises(
4002.1.7 by Andrew Bennetts
Rename UnresumableWriteGroups to UnresumableWriteGroup.
857
            errors.UnresumableWriteGroup,
4002.1.5 by Andrew Bennetts
Fix possible security issue with resuming write groups: make sure the token is well-formed so that it's not possible to steal a write group from another repo.
858
            new_repo.resume_write_group, [hacked_wg_token])
859
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
860
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
861
class TestPackRepositoryStacking(TestCaseWithTransport):
862
863
    """Tests for stacking pack repositories"""
864
865
    def setUp(self):
866
        if not self.format_supports_external_lookups:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
867
            raise TestNotApplicable("%r doesn't support stacking"
7143.15.2 by Jelmer Vernooij
Run autopep8.
868
                                    % (self.format_name,))
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
869
        super(TestPackRepositoryStacking, self).setUp()
870
871
    def get_format(self):
6653.6.5 by Jelmer Vernooij
Rename make_bzrdir to make_controldir.
872
        return controldir.format_registry.make_controldir(self.format_name)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
873
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
874
    def test_stack_checks_rich_root_compatibility(self):
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
875
        # early versions of the packing code relied on pack internals to
876
        # stack, but the current version should be able to stack on any
877
        # format.
878
        #
879
        # TODO: Possibly this should be run per-repository-format and raise
880
        # TestNotApplicable on formats that don't support stacking. -- mbp
881
        # 20080729
882
        repo = self.make_repository('repo', format=self.get_format())
883
        if repo.supports_rich_root():
884
            # can only stack on repositories that have compatible internal
885
            # metadata
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
886
            if getattr(repo._format, 'supports_tree_reference', False):
4343.3.27 by John Arbash Meinel
Now that dev6 supports external references, the tests for
887
                matching_format_name = 'pack-0.92-subtree'
888
            else:
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
889
                if repo._format.supports_chks:
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
890
                    matching_format_name = '2a'
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
891
                else:
4343.3.27 by John Arbash Meinel
Now that dev6 supports external references, the tests for
892
                    matching_format_name = 'rich-root-pack'
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
893
            mismatching_format_name = 'pack-0.92'
894
        else:
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
895
            # We don't have a non-rich-root CHK format.
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
896
            if repo._format.supports_chks:
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
897
                raise AssertionError("no non-rich-root CHK formats known")
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
898
            else:
899
                matching_format_name = 'pack-0.92'
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
900
            mismatching_format_name = 'pack-0.92-subtree'
901
        base = self.make_repository('base', format=matching_format_name)
902
        repo.add_fallback_repository(base)
903
        # you can't stack on something with incompatible data
904
        bad_repo = self.make_repository('mismatch',
7143.15.2 by Jelmer Vernooij
Run autopep8.
905
                                        format=mismatching_format_name)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
906
        e = self.assertRaises(errors.IncompatibleRepositories,
7143.15.2 by Jelmer Vernooij
Run autopep8.
907
                              repo.add_fallback_repository, bad_repo)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
908
        self.assertContainsRe(str(e),
7143.15.2 by Jelmer Vernooij
Run autopep8.
909
                              r'(?m)KnitPackRepository.*/mismatch/.*\nis not compatible with\n'
910
                              r'.*Repository.*/repo/.*\n'
911
                              r'different rich-root support')
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
912
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
913
    def test_stack_checks_serializers_compatibility(self):
914
        repo = self.make_repository('repo', format=self.get_format())
915
        if getattr(repo._format, 'supports_tree_reference', False):
916
            # can only stack on repositories that have compatible internal
917
            # metadata
4343.3.27 by John Arbash Meinel
Now that dev6 supports external references, the tests for
918
            matching_format_name = 'pack-0.92-subtree'
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
919
            mismatching_format_name = 'rich-root-pack'
920
        else:
921
            if repo.supports_rich_root():
4343.3.27 by John Arbash Meinel
Now that dev6 supports external references, the tests for
922
                if repo._format.supports_chks:
4597.1.6 by John Arbash Meinel
Add a test that inventory texts are preserved during pack.
923
                    matching_format_name = '2a'
4343.3.27 by John Arbash Meinel
Now that dev6 supports external references, the tests for
924
                else:
925
                    matching_format_name = 'rich-root-pack'
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
926
                mismatching_format_name = 'pack-0.92-subtree'
927
            else:
928
                raise TestNotApplicable('No formats use non-v5 serializer'
7143.15.2 by Jelmer Vernooij
Run autopep8.
929
                                        ' without having rich-root also set')
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
930
        base = self.make_repository('base', format=matching_format_name)
931
        repo.add_fallback_repository(base)
932
        # you can't stack on something with incompatible data
933
        bad_repo = self.make_repository('mismatch',
7143.15.2 by Jelmer Vernooij
Run autopep8.
934
                                        format=mismatching_format_name)
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
935
        e = self.assertRaises(errors.IncompatibleRepositories,
7143.15.2 by Jelmer Vernooij
Run autopep8.
936
                              repo.add_fallback_repository, bad_repo)
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
937
        self.assertContainsRe(str(e),
7143.15.2 by Jelmer Vernooij
Run autopep8.
938
                              r'(?m)KnitPackRepository.*/mismatch/.*\nis not compatible with\n'
939
                              r'.*Repository.*/repo/.*\n'
940
                              r'different serializers')
3606.10.5 by John Arbash Meinel
Switch out --1.6-rich-root for --1.6.1-rich-root.
941
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
942
    def test_adding_pack_does_not_record_pack_names_from_other_repositories(self):
943
        base = self.make_branch_and_tree('base', format=self.get_format())
944
        base.commit('foo')
7143.15.2 by Jelmer Vernooij
Run autopep8.
945
        referencing = self.make_branch_and_tree(
946
            'repo', format=self.get_format())
947
        referencing.branch.repository.add_fallback_repository(
948
            base.branch.repository)
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
949
        local_tree = referencing.branch.create_checkout('local')
950
        local_tree.commit('bar')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
951
        new_instance = referencing.controldir.open_repository()
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
952
        new_instance.lock_read()
953
        self.addCleanup(new_instance.unlock)
954
        new_instance._pack_collection.ensure_loaded()
955
        self.assertEqual(1, len(new_instance._pack_collection.all_packs()))
956
957
    def test_autopack_only_considers_main_repo_packs(self):
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
958
        format = self.get_format()
959
        base = self.make_branch_and_tree('base', format=format)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
960
        base.commit('foo')
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
961
        tree = self.make_branch_and_tree('repo', format=format)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
962
        tree.branch.repository.add_fallback_repository(base.branch.repository)
7143.15.2 by Jelmer Vernooij
Run autopep8.
963
        trans = tree.branch.repository.controldir.get_repository_transport(
964
            None)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
965
        # This test could be a little cheaper by replacing the packs
966
        # attribute on the repository to allow a different pack distribution
967
        # and max packs policy - so we are checking the policy is honoured
968
        # in the test. But for now 11 commits is not a big deal in a single
969
        # test.
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
970
        local_tree = tree.branch.create_checkout('local')
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
971
        for x in range(9):
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
972
            local_tree.commit('commit %s' % x)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
973
        # there should be 9 packs:
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
974
        index = self.index_class(trans, 'pack-names', None)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
975
        self.assertEqual(9, len(list(index.iter_all_entries())))
976
        # committing one more should coalesce to 1 of 10.
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
977
        local_tree.commit('commit triggering pack')
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
978
        index = self.index_class(trans, 'pack-names', None)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
979
        self.assertEqual(1, len(list(index.iter_all_entries())))
980
        # packing should not damage data
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
981
        tree = tree.controldir.open_workingtree()
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
982
        check_result = tree.branch.repository.check(
983
            [tree.branch.last_revision()])
7143.15.2 by Jelmer Vernooij
Run autopep8.
984
        nb_files = 5  # .pack, .rix, .iix, .tix, .six
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
985
        if tree.branch.repository._format.supports_chks:
7143.15.2 by Jelmer Vernooij
Run autopep8.
986
            nb_files += 1  # .cix
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
987
        # We should have 10 x nb_files files in the obsolete_packs directory.
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
988
        obsolete_files = list(trans.list_dir('obsolete_packs'))
989
        self.assertFalse('foo' in obsolete_files)
990
        self.assertFalse('bar' in obsolete_files)
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
991
        self.assertEqual(10 * nb_files, len(obsolete_files))
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
992
        # XXX: Todo check packs obsoleted correctly - old packs and indices
993
        # in the obsolete_packs directory.
994
        large_pack_name = list(index.iter_all_entries())[0][1][0]
995
        # finally, committing again should not touch the large pack.
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
996
        local_tree.commit('commit not triggering pack')
3735.1.1 by Robert Collins
Add development2 formats using BTree indices.
997
        index = self.index_class(trans, 'pack-names', None)
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
998
        self.assertEqual(2, len(list(index.iter_all_entries())))
999
        pack_names = [node[1][0] for node in index.iter_all_entries()]
1000
        self.assertTrue(large_pack_name in pack_names)
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
1001
1002
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1003
class TestKeyDependencies(TestCaseWithTransport):
1004
1005
    def get_format(self):
6653.6.5 by Jelmer Vernooij
Rename make_bzrdir to make_controldir.
1006
        return controldir.format_registry.make_controldir(self.format_name)
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1007
1008
    def create_source_and_target(self):
1009
        builder = self.make_branch_builder('source', format=self.get_format())
1010
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1011
        builder.build_snapshot(None, [
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1012
            ('add', ('', b'root-id', 'directory', None))],
6855.4.1 by Jelmer Vernooij
Yet more bees.
1013
            revision_id=b'A-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1014
        builder.build_snapshot(
7143.15.2 by Jelmer Vernooij
Run autopep8.
1015
            [b'A-id', b'ghost-id'], [],
1016
            revision_id=b'B-id', )
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1017
        builder.finish_series()
4634.29.16 by Andrew Bennetts
Fix buggy TestKeyDependencies test, tweak error string and comment.
1018
        repo = self.make_repository('target', format=self.get_format())
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1019
        b = builder.get_branch()
1020
        b.lock_read()
1021
        self.addCleanup(b.unlock)
1022
        repo.lock_write()
1023
        self.addCleanup(repo.unlock)
1024
        return b.repository, repo
1025
1026
    def test_key_dependencies_cleared_on_abort(self):
1027
        source_repo, target_repo = self.create_source_and_target()
1028
        target_repo.start_write_group()
1029
        try:
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1030
            stream = source_repo.revisions.get_record_stream([(b'B-id',)],
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1031
                                                             'unordered', True)
1032
            target_repo.revisions.insert_record_stream(stream)
1033
            key_refs = target_repo.revisions._index._key_dependencies
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1034
            self.assertEqual([(b'B-id',)], sorted(key_refs.get_referrers()))
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1035
        finally:
1036
            target_repo.abort_write_group()
1037
        self.assertEqual([], sorted(key_refs.get_referrers()))
1038
1039
    def test_key_dependencies_cleared_on_suspend(self):
1040
        source_repo, target_repo = self.create_source_and_target()
1041
        target_repo.start_write_group()
1042
        try:
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1043
            stream = source_repo.revisions.get_record_stream([(b'B-id',)],
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1044
                                                             'unordered', True)
1045
            target_repo.revisions.insert_record_stream(stream)
1046
            key_refs = target_repo.revisions._index._key_dependencies
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1047
            self.assertEqual([(b'B-id',)], sorted(key_refs.get_referrers()))
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1048
        finally:
1049
            target_repo.suspend_write_group()
1050
        self.assertEqual([], sorted(key_refs.get_referrers()))
1051
1052
    def test_key_dependencies_cleared_on_commit(self):
1053
        source_repo, target_repo = self.create_source_and_target()
1054
        target_repo.start_write_group()
1055
        try:
4634.29.16 by Andrew Bennetts
Fix buggy TestKeyDependencies test, tweak error string and comment.
1056
            # Copy all texts, inventories, and chks so that nothing is missing
1057
            # for revision B-id.
1058
            for vf_name in ['texts', 'chk_bytes', 'inventories']:
1059
                source_vf = getattr(source_repo, vf_name, None)
1060
                if source_vf is None:
1061
                    continue
1062
                target_vf = getattr(target_repo, vf_name)
1063
                stream = source_vf.get_record_stream(
1064
                    source_vf.keys(), 'unordered', True)
1065
                target_vf.insert_record_stream(stream)
1066
            # Copy just revision B-id
1067
            stream = source_repo.revisions.get_record_stream(
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1068
                [(b'B-id',)], 'unordered', True)
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1069
            target_repo.revisions.insert_record_stream(stream)
1070
            key_refs = target_repo.revisions._index._key_dependencies
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1071
            self.assertEqual([(b'B-id',)], sorted(key_refs.get_referrers()))
4343.3.33 by John Arbash Meinel
Clear KeyDependencies on abort/suspend/commit_write_group.
1072
        finally:
1073
            target_repo.commit_write_group()
1074
        self.assertEqual([], sorted(key_refs.get_referrers()))
1075
1076
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
1077
class TestSmartServerAutopack(TestCaseWithTransport):
1078
1079
    def setUp(self):
1080
        super(TestSmartServerAutopack, self).setUp()
1081
        # Create a smart server that publishes whatever the backing VFS server
1082
        # does.
5017.3.44 by Vincent Ladeuil
-s bt.per_pack_repos passing
1083
        self.smart_server = test_server.SmartTCPServer_for_testing()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
1084
        self.start_server(self.smart_server, self.get_server())
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
1085
        # Log all HPSS calls into self.hpss_calls.
1086
        client._SmartClient.hooks.install_named_hook(
1087
            'call', self.capture_hpss_call, None)
1088
        self.hpss_calls = []
1089
1090
    def capture_hpss_call(self, params):
1091
        self.hpss_calls.append(params.method)
1092
1093
    def get_format(self):
6653.6.5 by Jelmer Vernooij
Rename make_bzrdir to make_controldir.
1094
        return controldir.format_registry.make_controldir(self.format_name)
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
1095
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
1096
    def test_autopack_or_streaming_rpc_is_used_when_using_hpss(self):
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
1097
        # Make local and remote repos
3735.2.98 by John Arbash Meinel
Merge bzr.dev 4032. Resolve the new streaming fetch.
1098
        format = self.get_format()
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
1099
        tree = self.make_branch_and_tree('local', format=format)
1100
        self.make_branch_and_tree('remote', format=format)
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
1101
        remote_branch_url = self.smart_server.get_url() + 'remote'
7143.15.2 by Jelmer Vernooij
Run autopep8.
1102
        remote_branch = controldir.ControlDir.open(
1103
            remote_branch_url).open_branch()
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
1104
        # Make 9 local revisions, and push them one at a time to the remote
1105
        # repo to produce 9 pack files.
1106
        for x in range(9):
1107
            tree.commit('commit %s' % x)
1108
            tree.branch.push(remote_branch)
1109
        # Make one more push to trigger an autopack
1110
        self.hpss_calls = []
1111
        tree.commit('commit triggering pack')
1112
        tree.branch.push(remote_branch)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1113
        autopack_calls = len([call for call in self.hpss_calls if call
1114
                              == b'PackRepository.autopack'])
4476.3.66 by Andrew Bennetts
Fix trivial test failure by making the test recognise the new insert_stream_1.18 verb.
1115
        streaming_calls = len([call for call in self.hpss_calls if call in
7143.15.2 by Jelmer Vernooij
Run autopep8.
1116
                               (b'Repository.insert_stream', b'Repository.insert_stream_1.19')])
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
1117
        if autopack_calls:
1118
            # Non streaming server
1119
            self.assertEqual(1, autopack_calls)
1120
            self.assertEqual(0, streaming_calls)
1121
        else:
1122
            # Streaming was used, which autopacks on the remote end.
1123
            self.assertEqual(0, autopack_calls)
1124
            # NB: The 2 calls are because of the sanity check that the server
1125
            # supports the verb (see remote.py:RemoteSink.insert_stream for
1126
            # details).
1127
            self.assertEqual(2, streaming_calls)
3801.1.18 by Andrew Bennetts
Add a test that ensures that the autopack RPC is actually used for all pack formats.
1128
1129
6625.1.5 by Martin
Drop custom load_tests implementation and use unittest signature
1130
def load_tests(loader, basic_tests, pattern):
3582.3.3 by Martin Pool
Reenable tests for stacking pack repositories
1131
    # these give the bzrdir canned format name, and the repository on-disk
1132
    # format string
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
1133
    scenarios_params = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
1134
        dict(format_name='pack-0.92',
1135
             format_string="Bazaar pack repository format 1 (needs bzr 0.92)\n",
1136
             format_supports_external_lookups=False,
1137
             index_class=GraphIndex),
1138
        dict(format_name='pack-0.92-subtree',
1139
             format_string="Bazaar pack repository format 1 "
1140
             "with subtree support (needs bzr 0.92)\n",
1141
             format_supports_external_lookups=False,
1142
             index_class=GraphIndex),
1143
        dict(format_name='1.6',
1144
             format_string="Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n",
1145
             format_supports_external_lookups=True,
1146
             index_class=GraphIndex),
1147
        dict(format_name='1.6.1-rich-root',
1148
             format_string="Bazaar RepositoryFormatKnitPack5RichRoot "
1149
             "(bzr 1.6.1)\n",
1150
             format_supports_external_lookups=True,
1151
             index_class=GraphIndex),
1152
        dict(format_name='1.9',
1153
             format_string="Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n",
1154
             format_supports_external_lookups=True,
1155
             index_class=BTreeGraphIndex),
1156
        dict(format_name='1.9-rich-root',
1157
             format_string="Bazaar RepositoryFormatKnitPack6RichRoot "
1158
             "(bzr 1.9)\n",
1159
             format_supports_external_lookups=True,
1160
             index_class=BTreeGraphIndex),
1161
        dict(format_name='2a',
1162
             format_string="Bazaar repository format 2a "
1163
             "(needs bzr 1.16 or later)\n",
1164
             format_supports_external_lookups=True,
1165
             index_class=BTreeGraphIndex),
1166
        ]
3582.3.1 by Martin Pool
Split pack repository tests into their own file and use scenarios
1167
    # name of the scenario is the format name
4084.5.1 by Robert Collins
Bulk update all test adaptation into a single approach, using multiply_tests rather than test adapters.
1168
    scenarios = [(s['format_name'], s) for s in scenarios_params]
1169
    return tests.multiply_tests(basic_tests, scenarios, loader.suiteClass())