/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5590.1.1 by John Arbash Meinel
Stop using tuned_gzip, it seems to give incorrect results on python 2.7
1
# Copyright (C) 2006-2011 Canonical Ltd
1563.2.4 by Robert Collins
First cut at including the knit implementation of versioned_file.
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
1563.2.4 by Robert Collins
First cut at including the knit implementation of versioned_file.
16
17
"""Tests for Knit data structure"""
18
5590.1.1 by John Arbash Meinel
Stop using tuned_gzip, it seems to give incorrect results on python 2.7
19
import gzip
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
20
from io import BytesIO
7290.14.1 by Jelmer Vernooij
Use external patiencediff.
21
from patiencediff import PatienceSequenceMatcher
2484.1.17 by John Arbash Meinel
Workaround for Pyrex <0.9.5 and python >=2.5 incompatibilities.
22
import sys
1563.2.4 by Robert Collins
First cut at including the knit implementation of versioned_file.
23
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
24
from .. import (
2196.2.5 by John Arbash Meinel
Add an exception class when the knit index storage method is unknown, and properly test for it
25
    errors,
3350.8.12 by Robert Collins
Stacked make_mpdiffs.
26
    multiparent,
3734.2.4 by Vincent Ladeuil
Fix python2.6 deprecation warnings related to hashlib.
27
    osutils,
4913.2.24 by John Arbash Meinel
Track down a few more import typos.
28
    tests,
5273.1.7 by Vincent Ladeuil
No more use of the get_transport imported *symbol*, all uses are through
29
    transport,
2196.2.5 by John Arbash Meinel
Add an exception class when the knit index storage method is unknown, and properly test for it
30
    )
6670.4.1 by Jelmer Vernooij
Update imports.
31
from ..bzr import (
32
    knit,
33
    pack,
34
    )
35
from ..bzr.index import *
36
from ..bzr.knit import (
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
37
    AnnotatedKnitContent,
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
38
    KnitContent,
6729.7.2 by Jelmer Vernooij
Finish move.
39
    KnitCorrupt,
40
    KnitDataStreamIncompatible,
41
    KnitDataStreamUnknown,
6729.7.1 by Jelmer Vernooij
Move some knit errors.
42
    KnitHeaderError,
6729.7.2 by Jelmer Vernooij
Finish move.
43
    KnitIndexUnknownMethod,
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
44
    KnitVersionedFiles,
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
45
    PlainKnitContent,
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
46
    _VFContentMapGenerator,
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
47
    _KndxIndex,
48
    _KnitGraphIndex,
49
    _KnitKeyAccess,
50
    make_file_factory,
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
51
    )
6670.4.5 by Jelmer Vernooij
Move breezy.repofmt contents to breezy.bzr.
52
from ..bzr import (
5757.8.11 by Jelmer Vernooij
Merge knitpackrepo-6.
53
    knitpack_repo,
54
    pack_repo,
55
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
56
from . import (
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
57
    TestCase,
58
    TestCaseWithMemoryTransport,
59
    TestCaseWithTransport,
3787.1.1 by Robert Collins
Embed the failed text in sha1 knit errors.
60
    TestNotApplicable,
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
61
    )
6670.4.1 by Jelmer Vernooij
Update imports.
62
from ..bzr.versionedfile import (
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
63
    AbsentContentFactory,
3350.8.2 by Robert Collins
stacked get_parent_map.
64
    ConstantMapper,
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
65
    network_bytes_to_kind_and_offset,
3350.8.2 by Robert Collins
stacked get_parent_map.
66
    RecordingVersionedFilesDecorator,
67
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
68
from . import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
69
    features,
70
    )
71
72
73
compiled_knit_feature = features.ModuleAvailableFeature(
6670.4.1 by Jelmer Vernooij
Update imports.
74
    'breezy.bzr._knit_load_data_pyx')
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
75
76
6729.7.2 by Jelmer Vernooij
Finish move.
77
class ErrorTests(TestCase):
78
79
    def test_knit_data_stream_incompatible(self):
80
        error = KnitDataStreamIncompatible(
81
            'stream format', 'target format')
82
        self.assertEqual('Cannot insert knit data stream of format '
83
                         '"stream format" into knit of format '
84
                         '"target format".', str(error))
85
86
    def test_knit_data_stream_unknown(self):
87
        error = KnitDataStreamUnknown(
88
            'stream format')
89
        self.assertEqual('Cannot parse knit data stream of format '
90
                         '"stream format".', str(error))
91
92
    def test_knit_header_error(self):
93
        error = KnitHeaderError('line foo\n', 'path/to/file')
94
        self.assertEqual("Knit header error: 'line foo\\n' unexpected"
95
                         " for file \"path/to/file\".", str(error))
96
97
    def test_knit_index_unknown_method(self):
98
        error = KnitIndexUnknownMethod('http://host/foo.kndx',
99
                                       ['bad', 'no-eol'])
100
        self.assertEqual("Knit index http://host/foo.kndx does not have a"
101
                         " known method in options: ['bad', 'no-eol']",
102
                         str(error))
103
104
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
105
class KnitContentTestsMixin(object):
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
106
107
    def test_constructor(self):
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
108
        content = self._make_content([])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
109
110
    def test_text(self):
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
111
        content = self._make_content([])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
112
        self.assertEqual(content.text(), [])
113
7143.15.2 by Jelmer Vernooij
Run autopep8.
114
        content = self._make_content(
115
            [(b"origin1", b"text1"), (b"origin2", b"text2")])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
116
        self.assertEqual(content.text(), [b"text1", b"text2"])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
117
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
118
    def test_copy(self):
7143.15.2 by Jelmer Vernooij
Run autopep8.
119
        content = self._make_content(
120
            [(b"origin1", b"text1"), (b"origin2", b"text2")])
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
121
        copy = content.copy()
122
        self.assertIsInstance(copy, content.__class__)
123
        self.assertEqual(copy.annotate(), content.annotate())
124
125
    def assertDerivedBlocksEqual(self, source, target, noeol=False):
126
        """Assert that the derived matching blocks match real output"""
127
        source_lines = source.splitlines(True)
128
        target_lines = target.splitlines(True)
7143.15.2 by Jelmer Vernooij
Run autopep8.
129
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
130
        def nl(line):
131
            if noeol and not line.endswith('\n'):
132
                return line + '\n'
133
            else:
134
                return line
7143.15.2 by Jelmer Vernooij
Run autopep8.
135
        source_content = self._make_content(
136
            [(None, nl(l)) for l in source_lines])
137
        target_content = self._make_content(
138
            [(None, nl(l)) for l in target_lines])
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
139
        line_delta = source_content.line_delta(target_content)
140
        delta_blocks = list(KnitContent.get_line_delta_blocks(line_delta,
7143.15.2 by Jelmer Vernooij
Run autopep8.
141
                                                              source_lines, target_lines))
5279.1.1 by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py.
142
        matcher = PatienceSequenceMatcher(None, source_lines, target_lines)
143
        matcher_blocks = list(matcher.get_matching_blocks())
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
144
        self.assertEqual(matcher_blocks, delta_blocks)
145
146
    def test_get_line_delta_blocks(self):
147
        self.assertDerivedBlocksEqual('a\nb\nc\n', 'q\nc\n')
148
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1)
149
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1A)
150
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1B)
151
        self.assertDerivedBlocksEqual(TEXT_1B, TEXT_1A)
152
        self.assertDerivedBlocksEqual(TEXT_1A, TEXT_1B)
153
        self.assertDerivedBlocksEqual(TEXT_1A, '')
154
        self.assertDerivedBlocksEqual('', TEXT_1A)
155
        self.assertDerivedBlocksEqual('', '')
156
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd')
157
158
    def test_get_line_delta_blocks_noeol(self):
159
        """Handle historical knit deltas safely
160
161
        Some existing knit deltas don't consider the last line to differ
162
        when the only difference whether it has a final newline.
163
164
        New knit deltas appear to always consider the last line to differ
165
        in this case.
166
        """
167
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd\n', noeol=True)
168
        self.assertDerivedBlocksEqual('a\nb\nc\nd\n', 'a\nb\nc', noeol=True)
169
        self.assertDerivedBlocksEqual('a\nb\nc\n', 'a\nb\nc', noeol=True)
170
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\n', noeol=True)
171
172
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
173
TEXT_1 = """\
174
Banana cup cakes:
175
176
- bananas
177
- eggs
178
- broken tea cups
179
"""
180
181
TEXT_1A = """\
182
Banana cup cake recipe
183
(serves 6)
184
185
- bananas
186
- eggs
187
- broken tea cups
188
- self-raising flour
189
"""
190
191
TEXT_1B = """\
192
Banana cup cake recipe
193
194
- bananas (do not use plantains!!!)
195
- broken tea cups
196
- flour
197
"""
198
199
delta_1_1a = """\
200
0,1,2
201
Banana cup cake recipe
202
(serves 6)
203
5,5,1
204
- self-raising flour
205
"""
206
207
TEXT_2 = """\
208
Boeuf bourguignon
209
210
- beef
211
- red wine
212
- small onions
213
- carrot
214
- mushrooms
215
"""
216
217
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
218
class TestPlainKnitContent(TestCase, KnitContentTestsMixin):
219
220
    def _make_content(self, lines):
221
        annotated_content = AnnotatedKnitContent(lines)
222
        return PlainKnitContent(annotated_content.text(), 'bogus')
223
224
    def test_annotate(self):
225
        content = self._make_content([])
226
        self.assertEqual(content.annotate(), [])
227
7143.15.2 by Jelmer Vernooij
Run autopep8.
228
        content = self._make_content(
229
            [("origin1", "text1"), ("origin2", "text2")])
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
230
        self.assertEqual(content.annotate(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
231
                         [("bogus", "text1"), ("bogus", "text2")])
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
232
233
    def test_line_delta(self):
234
        content1 = self._make_content([("", "a"), ("", "b")])
235
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
236
        self.assertEqual(content1.line_delta(content2),
7143.15.2 by Jelmer Vernooij
Run autopep8.
237
                         [(1, 2, 2, ["a", "c"])])
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
238
239
    def test_line_delta_iter(self):
240
        content1 = self._make_content([("", "a"), ("", "b")])
241
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
242
        it = content1.line_delta_iter(content2)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
243
        self.assertEqual(next(it), (1, 2, 2, ["a", "c"]))
244
        self.assertRaises(StopIteration, next, it)
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
245
246
247
class TestAnnotatedKnitContent(TestCase, KnitContentTestsMixin):
248
249
    def _make_content(self, lines):
250
        return AnnotatedKnitContent(lines)
251
252
    def test_annotate(self):
253
        content = self._make_content([])
254
        self.assertEqual(content.annotate(), [])
255
7143.15.2 by Jelmer Vernooij
Run autopep8.
256
        content = self._make_content(
257
            [(b"origin1", b"text1"), (b"origin2", b"text2")])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
258
        self.assertEqual(content.annotate(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
259
                         [(b"origin1", b"text1"), (b"origin2", b"text2")])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
260
261
    def test_line_delta(self):
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
262
        content1 = self._make_content([("", "a"), ("", "b")])
263
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
264
        self.assertEqual(content1.line_delta(content2),
7143.15.2 by Jelmer Vernooij
Run autopep8.
265
                         [(1, 2, 2, [("", "a"), ("", "c")])])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
266
267
    def test_line_delta_iter(self):
2794.1.2 by Robert Collins
Nuke versioned file add/get delta support, allowing easy simplification of unannotated Content, reducing memory copies and friction during commit on unannotated texts.
268
        content1 = self._make_content([("", "a"), ("", "b")])
269
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
270
        it = content1.line_delta_iter(content2)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
271
        self.assertEqual(next(it), (1, 2, 2, [("", "a"), ("", "c")]))
272
        self.assertRaises(StopIteration, next, it)
2151.1.1 by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests
273
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
274
275
class MockTransport(object):
276
277
    def __init__(self, file_lines=None):
278
        self.file_lines = file_lines
279
        self.calls = []
2196.2.3 by John Arbash Meinel
Update tests and code to pass after merging bzr.dev
280
        # We have no base directory for the MockTransport
281
        self.base = ''
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
282
283
    def get(self, filename):
284
        if self.file_lines is None:
6729.7.2 by Jelmer Vernooij
Finish move.
285
            raise errors.NoSuchFile(filename)
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
286
        else:
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
287
            return BytesIO(b"\n".join(self.file_lines))
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
288
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
289
    def readv(self, relpath, offsets):
290
        fp = self.get(relpath)
291
        for offset, size in offsets:
292
            fp.seek(offset)
293
            yield offset, fp.read(size)
294
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
295
    def __getattr__(self, name):
296
        def queue_call(*args, **kwargs):
297
            self.calls.append((name, args, kwargs))
298
        return queue_call
299
300
3789.2.2 by John Arbash Meinel
Test that a readv() failing after yielding data will still raise Retry
301
class MockReadvFailingTransport(MockTransport):
302
    """Fail in the middle of a readv() result.
303
3789.2.3 by John Arbash Meinel
Change the mocking a bit, so we can be sure it is failing at the right time.
304
    This Transport will successfully yield the first two requested hunks, but
305
    raise NoSuchFile for the rest.
3789.2.2 by John Arbash Meinel
Test that a readv() failing after yielding data will still raise Retry
306
    """
307
308
    def readv(self, relpath, offsets):
3789.2.3 by John Arbash Meinel
Change the mocking a bit, so we can be sure it is failing at the right time.
309
        count = 0
3789.2.2 by John Arbash Meinel
Test that a readv() failing after yielding data will still raise Retry
310
        for result in MockTransport.readv(self, relpath, offsets):
3789.2.3 by John Arbash Meinel
Change the mocking a bit, so we can be sure it is failing at the right time.
311
            count += 1
312
            # we use 2 because the first offset is the pack header, the second
313
            # is the first actual content requset
314
            if count > 2:
3789.2.2 by John Arbash Meinel
Test that a readv() failing after yielding data will still raise Retry
315
                raise errors.NoSuchFile(relpath)
316
            yield result
317
318
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
319
class KnitRecordAccessTestsMixin(object):
320
    """Tests for getting and putting knit records."""
321
322
    def test_add_raw_records(self):
7464.1.1 by Jelmer Vernooij
Add DirectAccess.add_raw_record.
323
        """add_raw_records adds records retrievable later."""
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
324
        access = self.get_access()
7459.1.1 by Jelmer Vernooij
Make add_raw_records a chunked API.
325
        memos = access.add_raw_records([(b'key', 10)], [b'1234567890'])
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
326
        self.assertEqual([b'1234567890'], list(access.get_raw_records(memos)))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
327
7464.1.1 by Jelmer Vernooij
Add DirectAccess.add_raw_record.
328
    def test_add_raw_record(self):
329
        """add_raw_record adds records retrievable later."""
330
        access = self.get_access()
331
        memos = access.add_raw_record(b'key', 10, [b'1234567890'])
7464.1.2 by Jelmer Vernooij
Fix test.
332
        self.assertEqual([b'1234567890'], list(access.get_raw_records([memos])))
7464.1.1 by Jelmer Vernooij
Add DirectAccess.add_raw_record.
333
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
334
    def test_add_several_raw_records(self):
335
        """add_raw_records with many records and read some back."""
336
        access = self.get_access()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
337
        memos = access.add_raw_records([(b'key', 10), (b'key2', 2), (b'key3', 5)],
7459.1.1 by Jelmer Vernooij
Make add_raw_records a chunked API.
338
                                       [b'12345678901234567'])
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
339
        self.assertEqual([b'1234567890', b'12', b'34567'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
340
                         list(access.get_raw_records(memos)))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
341
        self.assertEqual([b'1234567890'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
342
                         list(access.get_raw_records(memos[0:1])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
343
        self.assertEqual([b'12'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
344
                         list(access.get_raw_records(memos[1:2])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
345
        self.assertEqual([b'34567'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
346
                         list(access.get_raw_records(memos[2:3])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
347
        self.assertEqual([b'1234567890', b'34567'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
348
                         list(access.get_raw_records(memos[0:1] + memos[2:3])))
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
349
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
350
351
class TestKnitKnitAccess(TestCaseWithMemoryTransport, KnitRecordAccessTestsMixin):
352
    """Tests for the .kndx implementation."""
353
354
    def get_access(self):
355
        """Get a .knit style access instance."""
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
356
        mapper = ConstantMapper("foo")
357
        access = _KnitKeyAccess(self.get_transport(), mapper)
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
358
        return access
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
359
360
361
class _TestException(Exception):
362
    """Just an exception for local tests to use."""
363
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
364
365
class TestPackKnitAccess(TestCaseWithMemoryTransport, KnitRecordAccessTestsMixin):
366
    """Tests for the pack based access."""
367
368
    def get_access(self):
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
369
        return self._get_access()[0]
370
371
    def _get_access(self, packname='packfile', index='FOO'):
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
372
        transport = self.get_transport()
7143.15.2 by Jelmer Vernooij
Run autopep8.
373
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
374
        def write_data(bytes):
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
375
            transport.append_bytes(packname, bytes)
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
376
        writer = pack.ContainerWriter(write_data)
377
        writer.begin()
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
378
        access = pack_repo._DirectPackAccess({})
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
379
        access.set_writer(writer, index, (transport, packname))
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
380
        return access, writer
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
381
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
382
    def make_pack_file(self):
383
        """Create a pack file with 2 records."""
384
        access, writer = self._get_access(packname='packname', index='foo')
385
        memos = []
7459.1.1 by Jelmer Vernooij
Make add_raw_records a chunked API.
386
        memos.extend(access.add_raw_records([(b'key1', 10)], [b'1234567890']))
387
        memos.extend(access.add_raw_records([(b'key2', 5)], [b'12345']))
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
388
        writer.end()
389
        return memos
390
5050.64.1 by Andrew Bennetts
Add reload-and-retry logic to RepositoryPackCollection.pack when a concurrent pack happens.
391
    def test_pack_collection_pack_retries(self):
392
        """An explicit pack of a pack collection succeeds even when a
393
        concurrent pack happens.
394
        """
395
        builder = self.make_branch_builder('.')
396
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
397
        builder.build_snapshot(None, [
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
398
            ('add', ('', b'root-id', 'directory', None)),
399
            ('add', ('file', b'file-id', 'file', b'content\nrev 1\n')),
6973.5.2 by Jelmer Vernooij
Add more bees.
400
            ], revision_id=b'rev-1')
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
401
        builder.build_snapshot([b'rev-1'], [
402
            ('modify', ('file', b'content\nrev 2\n')),
6973.5.2 by Jelmer Vernooij
Add more bees.
403
            ], revision_id=b'rev-2')
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
404
        builder.build_snapshot([b'rev-2'], [
405
            ('modify', ('file', b'content\nrev 3\n')),
6973.5.2 by Jelmer Vernooij
Add more bees.
406
            ], revision_id=b'rev-3')
5050.64.1 by Andrew Bennetts
Add reload-and-retry logic to RepositoryPackCollection.pack when a concurrent pack happens.
407
        self.addCleanup(builder.finish_series)
408
        b = builder.get_branch()
409
        self.addCleanup(b.lock_write().unlock)
410
        repo = b.repository
411
        collection = repo._pack_collection
412
        # Concurrently repack the repo.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
413
        reopened_repo = repo.controldir.open_repository()
5050.64.1 by Andrew Bennetts
Add reload-and-retry logic to RepositoryPackCollection.pack when a concurrent pack happens.
414
        reopened_repo.pack()
415
        # Pack the new pack.
416
        collection.pack()
417
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
418
    def make_vf_for_retrying(self):
3789.2.10 by John Arbash Meinel
The first function for KnitVersionedFiles can now retry on request.
419
        """Create 3 packs and a reload function.
420
421
        Originally, 2 pack files will have the data, but one will be missing.
422
        And then the third will be used in place of the first two if reload()
423
        is called.
424
425
        :return: (versioned_file, reload_counter)
426
            versioned_file  a KnitVersionedFiles using the packs for access
427
        """
4617.7.1 by Robert Collins
Lock the format knit retry tests depend on - knits aren't used for 2a formats.
428
        builder = self.make_branch_builder('.', format="1.9")
4454.3.59 by John Arbash Meinel
Track down why the annotate retry code was failing.
429
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
430
        builder.build_snapshot(None, [
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
431
            ('add', ('', b'root-id', 'directory', None)),
432
            ('add', ('file', b'file-id', 'file', b'content\nrev 1\n')),
6973.5.2 by Jelmer Vernooij
Add more bees.
433
            ], revision_id=b'rev-1')
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
434
        builder.build_snapshot([b'rev-1'], [
435
            ('modify', ('file', b'content\nrev 2\n')),
6973.5.2 by Jelmer Vernooij
Add more bees.
436
            ], revision_id=b'rev-2')
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
437
        builder.build_snapshot([b'rev-2'], [
438
            ('modify', ('file', b'content\nrev 3\n')),
6973.5.2 by Jelmer Vernooij
Add more bees.
439
            ], revision_id=b'rev-3')
4454.3.59 by John Arbash Meinel
Track down why the annotate retry code was failing.
440
        builder.finish_series()
441
        b = builder.get_branch()
442
        b.lock_write()
443
        self.addCleanup(b.unlock)
4145.1.6 by Robert Collins
More test fallout, but all caught now.
444
        # Pack these three revisions into another pack file, but don't remove
445
        # the originals
4454.3.59 by John Arbash Meinel
Track down why the annotate retry code was failing.
446
        repo = b.repository
4145.1.6 by Robert Collins
More test fallout, but all caught now.
447
        collection = repo._pack_collection
448
        collection.ensure_loaded()
449
        orig_packs = collection.packs
5757.7.3 by Jelmer Vernooij
Move more knitpack-specific functionality out of Packer.
450
        packer = knitpack_repo.KnitPacker(collection, orig_packs, '.testpack')
4145.1.6 by Robert Collins
More test fallout, but all caught now.
451
        new_pack = packer.pack()
452
        # forget about the new pack
453
        collection.reset()
454
        repo.refresh_data()
4454.3.59 by John Arbash Meinel
Track down why the annotate retry code was failing.
455
        vf = repo.revisions
3789.2.10 by John Arbash Meinel
The first function for KnitVersionedFiles can now retry on request.
456
        # Set up a reload() function that switches to using the new pack file
457
        new_index = new_pack.revision_index
458
        access_tuple = new_pack.access_tuple()
459
        reload_counter = [0, 0, 0]
7143.15.2 by Jelmer Vernooij
Run autopep8.
460
3789.2.10 by John Arbash Meinel
The first function for KnitVersionedFiles can now retry on request.
461
        def reload():
462
            reload_counter[0] += 1
463
            if reload_counter[1] > 0:
464
                # We already reloaded, nothing more to do
465
                reload_counter[2] += 1
466
                return False
467
            reload_counter[1] += 1
468
            vf._index._graph_index._indices[:] = [new_index]
469
            vf._access._indices.clear()
470
            vf._access._indices[new_index] = access_tuple
471
            return True
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
472
        # Delete one of the pack files so the data will need to be reloaded. We
3789.2.12 by John Arbash Meinel
iter_lines_added_or_present now retries.
473
        # will delete the file with 'rev-2' in it
3789.2.10 by John Arbash Meinel
The first function for KnitVersionedFiles can now retry on request.
474
        trans, name = orig_packs[1].access_tuple()
475
        trans.delete(name)
476
        # We don't have the index trigger reloading because we want to test
477
        # that we reload when the .pack disappears
478
        vf._access._reload_func = reload
479
        return vf, reload_counter
480
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
481
    def make_reload_func(self, return_val=True):
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
482
        reload_called = [0]
7143.15.2 by Jelmer Vernooij
Run autopep8.
483
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
484
        def reload():
485
            reload_called[0] += 1
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
486
            return return_val
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
487
        return reload_called, reload
488
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
489
    def make_retry_exception(self):
490
        # We raise a real exception so that sys.exc_info() is properly
491
        # populated
492
        try:
493
            raise _TestException('foobar')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
494
        except _TestException as e:
3789.2.29 by John Arbash Meinel
RetryWithNewPacks requires another argument.
495
            retry_exc = errors.RetryWithNewPacks(None, reload_occurred=False,
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
496
                                                 exc_info=sys.exc_info())
5340.15.2 by John Arbash Meinel
supercede 2.4-613247-cleanup-tests
497
        # GZ 2010-08-10: Cycle with exc_info affects 3 tests
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
498
        return retry_exc
499
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
500
    def test_read_from_several_packs(self):
501
        access, writer = self._get_access()
502
        memos = []
7459.1.1 by Jelmer Vernooij
Make add_raw_records a chunked API.
503
        memos.extend(access.add_raw_records([(b'key', 10)], [b'1234567890']))
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
504
        writer.end()
505
        access, writer = self._get_access('pack2', 'FOOBAR')
7459.1.1 by Jelmer Vernooij
Make add_raw_records a chunked API.
506
        memos.extend(access.add_raw_records([(b'key', 5)], [b'12345']))
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
507
        writer.end()
508
        access, writer = self._get_access('pack3', 'BAZ')
7459.1.1 by Jelmer Vernooij
Make add_raw_records a chunked API.
509
        memos.extend(access.add_raw_records([(b'key', 5)], [b'alpha']))
2592.3.67 by Robert Collins
More tests for bzrlib.knit._PackAccess.
510
        writer.end()
511
        transport = self.get_transport()
7143.15.2 by Jelmer Vernooij
Run autopep8.
512
        access = pack_repo._DirectPackAccess({"FOO": (transport, 'packfile'),
513
                                              "FOOBAR": (transport, 'pack2'),
514
                                              "BAZ": (transport, 'pack3')})
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
515
        self.assertEqual([b'1234567890', b'12345', b'alpha'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
516
                         list(access.get_raw_records(memos)))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
517
        self.assertEqual([b'1234567890'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
518
                         list(access.get_raw_records(memos[0:1])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
519
        self.assertEqual([b'12345'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
520
                         list(access.get_raw_records(memos[1:2])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
521
        self.assertEqual([b'alpha'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
522
                         list(access.get_raw_records(memos[2:3])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
523
        self.assertEqual([b'1234567890', b'alpha'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
524
                         list(access.get_raw_records(memos[0:1] + memos[2:3])))
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
525
2592.3.70 by Robert Collins
Allow setting a writer after creating a knit._PackAccess object.
526
    def test_set_writer(self):
527
        """The writer should be settable post construction."""
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
528
        access = pack_repo._DirectPackAccess({})
2592.3.70 by Robert Collins
Allow setting a writer after creating a knit._PackAccess object.
529
        transport = self.get_transport()
530
        packname = 'packfile'
531
        index = 'foo'
7143.15.2 by Jelmer Vernooij
Run autopep8.
532
2592.3.70 by Robert Collins
Allow setting a writer after creating a knit._PackAccess object.
533
        def write_data(bytes):
534
            transport.append_bytes(packname, bytes)
535
        writer = pack.ContainerWriter(write_data)
536
        writer.begin()
537
        access.set_writer(writer, index, (transport, packname))
7459.1.1 by Jelmer Vernooij
Make add_raw_records a chunked API.
538
        memos = access.add_raw_records([(b'key', 10)], [b'1234567890'])
2592.3.70 by Robert Collins
Allow setting a writer after creating a knit._PackAccess object.
539
        writer.end()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
540
        self.assertEqual([b'1234567890'], list(access.get_raw_records(memos)))
2592.3.70 by Robert Collins
Allow setting a writer after creating a knit._PackAccess object.
541
3789.2.1 by John Arbash Meinel
_DirectPackAccess can now raise RetryWithNewPacks when we think something has happened.
542
    def test_missing_index_raises_retry(self):
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
543
        memos = self.make_pack_file()
3789.2.1 by John Arbash Meinel
_DirectPackAccess can now raise RetryWithNewPacks when we think something has happened.
544
        transport = self.get_transport()
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
545
        reload_called, reload_func = self.make_reload_func()
546
        # Note that the index key has changed from 'foo' to 'bar'
7143.15.2 by Jelmer Vernooij
Run autopep8.
547
        access = pack_repo._DirectPackAccess({'bar': (transport, 'packname')},
548
                                             reload_func=reload_func)
3789.2.1 by John Arbash Meinel
_DirectPackAccess can now raise RetryWithNewPacks when we think something has happened.
549
        e = self.assertListRaises(errors.RetryWithNewPacks,
550
                                  access.get_raw_records, memos)
551
        # Because a key was passed in which does not match our index list, we
552
        # assume that the listing was already reloaded
553
        self.assertTrue(e.reload_occurred)
554
        self.assertIsInstance(e.exc_info, tuple)
555
        self.assertIs(e.exc_info[0], KeyError)
556
        self.assertIsInstance(e.exc_info[1], KeyError)
557
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
558
    def test_missing_index_raises_key_error_with_no_reload(self):
559
        memos = self.make_pack_file()
560
        transport = self.get_transport()
561
        # Note that the index key has changed from 'foo' to 'bar'
7143.15.2 by Jelmer Vernooij
Run autopep8.
562
        access = pack_repo._DirectPackAccess({'bar': (transport, 'packname')})
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
563
        e = self.assertListRaises(KeyError, access.get_raw_records, memos)
564
3789.2.1 by John Arbash Meinel
_DirectPackAccess can now raise RetryWithNewPacks when we think something has happened.
565
    def test_missing_file_raises_retry(self):
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
566
        memos = self.make_pack_file()
567
        transport = self.get_transport()
568
        reload_called, reload_func = self.make_reload_func()
569
        # Note that the 'filename' has been changed to 'different-packname'
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
570
        access = pack_repo._DirectPackAccess(
7143.15.2 by Jelmer Vernooij
Run autopep8.
571
            {'foo': (transport, 'different-packname')},
5757.8.1 by Jelmer Vernooij
Avoid bzrlib.knit imports when using groupcompress repositories.
572
            reload_func=reload_func)
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
573
        e = self.assertListRaises(errors.RetryWithNewPacks,
574
                                  access.get_raw_records, memos)
575
        # The file has gone missing, so we assume we need to reload
576
        self.assertFalse(e.reload_occurred)
577
        self.assertIsInstance(e.exc_info, tuple)
578
        self.assertIs(e.exc_info[0], errors.NoSuchFile)
579
        self.assertIsInstance(e.exc_info[1], errors.NoSuchFile)
580
        self.assertEqual('different-packname', e.exc_info[1].path)
581
582
    def test_missing_file_raises_no_such_file_with_no_reload(self):
583
        memos = self.make_pack_file()
584
        transport = self.get_transport()
585
        # Note that the 'filename' has been changed to 'different-packname'
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
586
        access = pack_repo._DirectPackAccess(
5757.5.2 by Jelmer Vernooij
merge bzr.dev.
587
            {'foo': (transport, 'different-packname')})
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
588
        e = self.assertListRaises(errors.NoSuchFile,
3789.2.1 by John Arbash Meinel
_DirectPackAccess can now raise RetryWithNewPacks when we think something has happened.
589
                                  access.get_raw_records, memos)
590
3789.2.2 by John Arbash Meinel
Test that a readv() failing after yielding data will still raise Retry
591
    def test_failing_readv_raises_retry(self):
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
592
        memos = self.make_pack_file()
593
        transport = self.get_transport()
594
        failing_transport = MockReadvFailingTransport(
7143.15.2 by Jelmer Vernooij
Run autopep8.
595
            [transport.get_bytes('packname')])
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
596
        reload_called, reload_func = self.make_reload_func()
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
597
        access = pack_repo._DirectPackAccess(
5757.5.2 by Jelmer Vernooij
merge bzr.dev.
598
            {'foo': (failing_transport, 'packname')},
5757.8.1 by Jelmer Vernooij
Avoid bzrlib.knit imports when using groupcompress repositories.
599
            reload_func=reload_func)
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
600
        # Asking for a single record will not trigger the Mock failure
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
601
        self.assertEqual([b'1234567890'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
602
                         list(access.get_raw_records(memos[:1])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
603
        self.assertEqual([b'12345'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
604
                         list(access.get_raw_records(memos[1:2])))
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
605
        # A multiple offset readv() will fail mid-way through
606
        e = self.assertListRaises(errors.RetryWithNewPacks,
607
                                  access.get_raw_records, memos)
608
        # The file has gone missing, so we assume we need to reload
609
        self.assertFalse(e.reload_occurred)
610
        self.assertIsInstance(e.exc_info, tuple)
611
        self.assertIs(e.exc_info[0], errors.NoSuchFile)
612
        self.assertIsInstance(e.exc_info[1], errors.NoSuchFile)
613
        self.assertEqual('packname', e.exc_info[1].path)
614
615
    def test_failing_readv_raises_no_such_file_with_no_reload(self):
616
        memos = self.make_pack_file()
617
        transport = self.get_transport()
618
        failing_transport = MockReadvFailingTransport(
7143.15.2 by Jelmer Vernooij
Run autopep8.
619
            [transport.get_bytes('packname')])
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
620
        reload_called, reload_func = self.make_reload_func()
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
621
        access = pack_repo._DirectPackAccess(
7143.15.2 by Jelmer Vernooij
Run autopep8.
622
            {'foo': (failing_transport, 'packname')})
3789.2.3 by John Arbash Meinel
Change the mocking a bit, so we can be sure it is failing at the right time.
623
        # Asking for a single record will not trigger the Mock failure
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
624
        self.assertEqual([b'1234567890'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
625
                         list(access.get_raw_records(memos[:1])))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
626
        self.assertEqual([b'12345'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
627
                         list(access.get_raw_records(memos[1:2])))
3789.2.3 by John Arbash Meinel
Change the mocking a bit, so we can be sure it is failing at the right time.
628
        # A multiple offset readv() will fail mid-way through
3789.2.5 by John Arbash Meinel
Change _DirectPackAccess to only raise Retry when _reload_func is defined.
629
        e = self.assertListRaises(errors.NoSuchFile,
3789.2.2 by John Arbash Meinel
Test that a readv() failing after yielding data will still raise Retry
630
                                  access.get_raw_records, memos)
631
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
632
    def test_reload_or_raise_no_reload(self):
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
633
        access = pack_repo._DirectPackAccess({}, reload_func=None)
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
634
        retry_exc = self.make_retry_exception()
635
        # Without a reload_func, we will just re-raise the original exception
636
        self.assertRaises(_TestException, access.reload_or_raise, retry_exc)
637
638
    def test_reload_or_raise_reload_changed(self):
639
        reload_called, reload_func = self.make_reload_func(return_val=True)
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
640
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
641
        retry_exc = self.make_retry_exception()
642
        access.reload_or_raise(retry_exc)
643
        self.assertEqual([1], reload_called)
7143.15.2 by Jelmer Vernooij
Run autopep8.
644
        retry_exc.reload_occurred = True
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
645
        access.reload_or_raise(retry_exc)
646
        self.assertEqual([2], reload_called)
647
648
    def test_reload_or_raise_reload_no_change(self):
649
        reload_called, reload_func = self.make_reload_func(return_val=False)
5757.5.1 by Jelmer Vernooij
Move _DirectPackAccess to bzrlib.repofmt.pack_repo.
650
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
651
        retry_exc = self.make_retry_exception()
652
        # If reload_occurred is False, then we consider it an error to have
653
        # reload_func() return False (no changes).
654
        self.assertRaises(_TestException, access.reload_or_raise, retry_exc)
655
        self.assertEqual([1], reload_called)
7143.15.2 by Jelmer Vernooij
Run autopep8.
656
        retry_exc.reload_occurred = True
3789.2.6 by John Arbash Meinel
Make _DirectPackAccess.reload_or_raise maintain the logic.
657
        # If reload_occurred is True, then we assume nothing changed because
658
        # it had changed earlier, but didn't change again
659
        access.reload_or_raise(retry_exc)
660
        self.assertEqual([2], reload_called)
661
3789.2.13 by John Arbash Meinel
KnitVersionedFile.annotate() now retries when appropriate.
662
    def test_annotate_retries(self):
663
        vf, reload_counter = self.make_vf_for_retrying()
664
        # It is a little bit bogus to annotate the Revision VF, but it works,
665
        # as we have ancestry stored there
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
666
        key = (b'rev-3',)
3789.2.13 by John Arbash Meinel
KnitVersionedFile.annotate() now retries when appropriate.
667
        reload_lines = vf.annotate(key)
668
        self.assertEqual([1, 1, 0], reload_counter)
669
        plain_lines = vf.annotate(key)
7143.15.2 by Jelmer Vernooij
Run autopep8.
670
        self.assertEqual([1, 1, 0], reload_counter)  # No extra reloading
3789.2.13 by John Arbash Meinel
KnitVersionedFile.annotate() now retries when appropriate.
671
        if reload_lines != plain_lines:
672
            self.fail('Annotation was not identical with reloading.')
673
        # Now delete the packs-in-use, which should trigger another reload, but
674
        # this time we just raise an exception because we can't recover
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
675
        for trans, name in vf._access._indices.values():
3789.2.13 by John Arbash Meinel
KnitVersionedFile.annotate() now retries when appropriate.
676
            trans.delete(name)
677
        self.assertRaises(errors.NoSuchFile, vf.annotate, key)
678
        self.assertEqual([2, 1, 1], reload_counter)
679
3789.2.10 by John Arbash Meinel
The first function for KnitVersionedFiles can now retry on request.
680
    def test__get_record_map_retries(self):
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
681
        vf, reload_counter = self.make_vf_for_retrying()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
682
        keys = [(b'rev-1',), (b'rev-2',), (b'rev-3',)]
3789.2.10 by John Arbash Meinel
The first function for KnitVersionedFiles can now retry on request.
683
        records = vf._get_record_map(keys)
684
        self.assertEqual(keys, sorted(records.keys()))
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
685
        self.assertEqual([1, 1, 0], reload_counter)
686
        # Now delete the packs-in-use, which should trigger another reload, but
687
        # this time we just raise an exception because we can't recover
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
688
        for trans, name in vf._access._indices.values():
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
689
            trans.delete(name)
690
        self.assertRaises(errors.NoSuchFile, vf._get_record_map, keys)
691
        self.assertEqual([2, 1, 1], reload_counter)
692
693
    def test_get_record_stream_retries(self):
694
        vf, reload_counter = self.make_vf_for_retrying()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
695
        keys = [(b'rev-1',), (b'rev-2',), (b'rev-3',)]
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
696
        record_stream = vf.get_record_stream(keys, 'topological', False)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
697
        record = next(record_stream)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
698
        self.assertEqual((b'rev-1',), record.key)
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
699
        self.assertEqual([0, 0, 0], reload_counter)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
700
        record = next(record_stream)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
701
        self.assertEqual((b'rev-2',), record.key)
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
702
        self.assertEqual([1, 1, 0], reload_counter)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
703
        record = next(record_stream)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
704
        self.assertEqual((b'rev-3',), record.key)
3789.2.12 by John Arbash Meinel
iter_lines_added_or_present now retries.
705
        self.assertEqual([1, 1, 0], reload_counter)
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
706
        # Now delete all pack files, and see that we raise the right error
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
707
        for trans, name in vf._access._indices.values():
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
708
            trans.delete(name)
709
        self.assertListRaises(errors.NoSuchFile,
7143.15.2 by Jelmer Vernooij
Run autopep8.
710
                              vf.get_record_stream, keys, 'topological', False)
3789.2.11 by John Arbash Meinel
KnitVersionedFile.get_record_stream now retries *and* fails correctly.
711
3789.2.12 by John Arbash Meinel
iter_lines_added_or_present now retries.
712
    def test_iter_lines_added_or_present_in_keys_retries(self):
713
        vf, reload_counter = self.make_vf_for_retrying()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
714
        keys = [(b'rev-1',), (b'rev-2',), (b'rev-3',)]
3789.2.12 by John Arbash Meinel
iter_lines_added_or_present now retries.
715
        # Unfortunately, iter_lines_added_or_present_in_keys iterates the
716
        # result in random order (determined by the iteration order from a
717
        # set()), so we don't have any solid way to trigger whether data is
718
        # read before or after. However we tried to delete the middle node to
719
        # exercise the code well.
720
        # What we care about is that all lines are always yielded, but not
721
        # duplicated
722
        count = 0
723
        reload_lines = sorted(vf.iter_lines_added_or_present_in_keys(keys))
724
        self.assertEqual([1, 1, 0], reload_counter)
725
        # Now do it again, to make sure the result is equivalent
726
        plain_lines = sorted(vf.iter_lines_added_or_present_in_keys(keys))
7143.15.2 by Jelmer Vernooij
Run autopep8.
727
        self.assertEqual([1, 1, 0], reload_counter)  # No extra reloading
3789.2.12 by John Arbash Meinel
iter_lines_added_or_present now retries.
728
        self.assertEqual(plain_lines, reload_lines)
729
        self.assertEqual(21, len(plain_lines))
730
        # Now delete all pack files, and see that we raise the right error
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
731
        for trans, name in vf._access._indices.values():
3789.2.12 by John Arbash Meinel
iter_lines_added_or_present now retries.
732
            trans.delete(name)
733
        self.assertListRaises(errors.NoSuchFile,
7143.15.2 by Jelmer Vernooij
Run autopep8.
734
                              vf.iter_lines_added_or_present_in_keys, keys)
3789.2.12 by John Arbash Meinel
iter_lines_added_or_present now retries.
735
        self.assertEqual([2, 1, 1], reload_counter)
736
3878.1.1 by John Arbash Meinel
KVF.get_record_stream('unordered') now returns the records based on I/O ordering.
737
    def test_get_record_stream_yields_disk_sorted_order(self):
738
        # if we get 'unordered' pick a semi-optimal order for reading. The
739
        # order should be grouped by pack file, and then by position in file
740
        repo = self.make_repository('test', format='pack-0.92')
741
        repo.lock_write()
742
        self.addCleanup(repo.unlock)
743
        repo.start_write_group()
744
        vf = repo.texts
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
745
        vf.add_lines((b'f-id', b'rev-5'), [(b'f-id', b'rev-4')], [b'lines\n'])
746
        vf.add_lines((b'f-id', b'rev-1'), [], [b'lines\n'])
747
        vf.add_lines((b'f-id', b'rev-2'), [(b'f-id', b'rev-1')], [b'lines\n'])
3878.1.1 by John Arbash Meinel
KVF.get_record_stream('unordered') now returns the records based on I/O ordering.
748
        repo.commit_write_group()
749
        # We inserted them as rev-5, rev-1, rev-2, we should get them back in
750
        # the same order
6973.13.2 by Jelmer Vernooij
Fix some more tests.
751
        stream = vf.get_record_stream([(b'f-id', b'rev-1'), (b'f-id', b'rev-5'),
752
                                       (b'f-id', b'rev-2')], 'unordered', False)
3878.1.1 by John Arbash Meinel
KVF.get_record_stream('unordered') now returns the records based on I/O ordering.
753
        keys = [r.key for r in stream]
6973.13.2 by Jelmer Vernooij
Fix some more tests.
754
        self.assertEqual([(b'f-id', b'rev-5'), (b'f-id', b'rev-1'),
755
                          (b'f-id', b'rev-2')], keys)
3878.1.1 by John Arbash Meinel
KVF.get_record_stream('unordered') now returns the records based on I/O ordering.
756
        repo.start_write_group()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
757
        vf.add_lines((b'f-id', b'rev-4'), [(b'f-id', b'rev-3')], [b'lines\n'])
758
        vf.add_lines((b'f-id', b'rev-3'), [(b'f-id', b'rev-2')], [b'lines\n'])
759
        vf.add_lines((b'f-id', b'rev-6'), [(b'f-id', b'rev-5')], [b'lines\n'])
3878.1.1 by John Arbash Meinel
KVF.get_record_stream('unordered') now returns the records based on I/O ordering.
760
        repo.commit_write_group()
761
        # Request in random order, to make sure the output order isn't based on
762
        # the request
6973.13.2 by Jelmer Vernooij
Fix some more tests.
763
        request_keys = set((b'f-id', b'rev-%d' % i) for i in range(1, 7))
3878.1.1 by John Arbash Meinel
KVF.get_record_stream('unordered') now returns the records based on I/O ordering.
764
        stream = vf.get_record_stream(request_keys, 'unordered', False)
765
        keys = [r.key for r in stream]
766
        # We want to get the keys back in disk order, but it doesn't matter
767
        # which pack we read from first. So this can come back in 2 orders
6973.13.2 by Jelmer Vernooij
Fix some more tests.
768
        alt1 = [(b'f-id', b'rev-%d' % i) for i in [4, 3, 6, 5, 1, 2]]
769
        alt2 = [(b'f-id', b'rev-%d' % i) for i in [5, 1, 2, 4, 3, 6]]
3878.1.1 by John Arbash Meinel
KVF.get_record_stream('unordered') now returns the records based on I/O ordering.
770
        if keys != alt1 and keys != alt2:
771
            self.fail('Returned key order did not match either expected order.'
772
                      ' expected %s or %s, not %s'
773
                      % (alt1, alt2, keys))
774
2592.3.66 by Robert Collins
Allow adaption of KnitData to pack files.
775
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
776
class LowLevelKnitDataTests(TestCase):
777
778
    def create_gz_content(self, text):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
779
        sio = BytesIO()
6973.14.6 by Jelmer Vernooij
Fix some more tests.
780
        with gzip.GzipFile(mode='wb', fileobj=sio) as gz_file:
781
            gz_file.write(text)
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
782
        return sio.getvalue()
783
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
784
    def make_multiple_records(self):
785
        """Create the content for multiple records."""
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
786
        sha1sum = osutils.sha_string(b'foo\nbar\n')
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
787
        total_txt = []
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
788
        gz_txt = self.create_gz_content(b'version rev-id-1 2 %s\n'
789
                                        b'foo\n'
790
                                        b'bar\n'
791
                                        b'end rev-id-1\n'
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
792
                                        % (sha1sum,))
793
        record_1 = (0, len(gz_txt), sha1sum)
794
        total_txt.append(gz_txt)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
795
        sha1sum = osutils.sha_string(b'baz\n')
796
        gz_txt = self.create_gz_content(b'version rev-id-2 1 %s\n'
797
                                        b'baz\n'
798
                                        b'end rev-id-2\n'
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
799
                                        % (sha1sum,))
800
        record_2 = (record_1[1], len(gz_txt), sha1sum)
801
        total_txt.append(gz_txt)
802
        return total_txt, record_1, record_2
803
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
804
    def test_valid_knit_data(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
805
        sha1sum = osutils.sha_string(b'foo\nbar\n')
806
        gz_txt = self.create_gz_content(b'version rev-id-1 2 %s\n'
807
                                        b'foo\n'
808
                                        b'bar\n'
809
                                        b'end rev-id-1\n'
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
810
                                        % (sha1sum,))
811
        transport = MockTransport([gz_txt])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
812
        access = _KnitKeyAccess(transport, ConstantMapper('filename'))
813
        knit = KnitVersionedFiles(None, access)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
814
        records = [((b'rev-id-1',), ((b'rev-id-1',), 0, len(gz_txt)))]
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
815
816
        contents = list(knit._read_records_iter(records))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
817
        self.assertEqual([((b'rev-id-1',), [b'foo\n', b'bar\n'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
818
                           b'4e48e2c9a3d2ca8a708cb0cc545700544efb5021')], contents)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
819
820
        raw_contents = list(knit._read_records_iter_raw(records))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
821
        self.assertEqual([((b'rev-id-1',), gz_txt, sha1sum)], raw_contents)
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
822
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
823
    def test_multiple_records_valid(self):
824
        total_txt, record_1, record_2 = self.make_multiple_records()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
825
        transport = MockTransport([b''.join(total_txt)])
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
826
        access = _KnitKeyAccess(transport, ConstantMapper('filename'))
827
        knit = KnitVersionedFiles(None, access)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
828
        records = [((b'rev-id-1',), ((b'rev-id-1',), record_1[0], record_1[1])),
829
                   ((b'rev-id-2',), ((b'rev-id-2',), record_2[0], record_2[1]))]
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
830
831
        contents = list(knit._read_records_iter(records))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
832
        self.assertEqual([((b'rev-id-1',), [b'foo\n', b'bar\n'], record_1[2]),
833
                          ((b'rev-id-2',), [b'baz\n'], record_2[2])],
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
834
                         contents)
835
836
        raw_contents = list(knit._read_records_iter_raw(records))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
837
        self.assertEqual([((b'rev-id-1',), total_txt[0], record_1[2]),
838
                          ((b'rev-id-2',), total_txt[1], record_2[2])],
3789.2.4 by John Arbash Meinel
Add a multiple-record test, though it isn't quite what we want for the readv tests.
839
                         raw_contents)
840
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
841
    def test_not_enough_lines(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
842
        sha1sum = osutils.sha_string(b'foo\n')
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
843
        # record says 2 lines data says 1
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
844
        gz_txt = self.create_gz_content(b'version rev-id-1 2 %s\n'
845
                                        b'foo\n'
846
                                        b'end rev-id-1\n'
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
847
                                        % (sha1sum,))
848
        transport = MockTransport([gz_txt])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
849
        access = _KnitKeyAccess(transport, ConstantMapper('filename'))
850
        knit = KnitVersionedFiles(None, access)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
851
        records = [((b'rev-id-1',), ((b'rev-id-1',), 0, len(gz_txt)))]
6729.7.2 by Jelmer Vernooij
Finish move.
852
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
853
                          knit._read_records_iter(records))
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
854
855
        # read_records_iter_raw won't detect that sort of mismatch/corruption
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
856
        raw_contents = list(knit._read_records_iter_raw(records))
7143.15.2 by Jelmer Vernooij
Run autopep8.
857
        self.assertEqual([((b'rev-id-1',), gz_txt, sha1sum)], raw_contents)
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
858
859
    def test_too_many_lines(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
860
        sha1sum = osutils.sha_string(b'foo\nbar\n')
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
861
        # record says 1 lines data says 2
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
862
        gz_txt = self.create_gz_content(b'version rev-id-1 1 %s\n'
863
                                        b'foo\n'
864
                                        b'bar\n'
865
                                        b'end rev-id-1\n'
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
866
                                        % (sha1sum,))
867
        transport = MockTransport([gz_txt])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
868
        access = _KnitKeyAccess(transport, ConstantMapper('filename'))
869
        knit = KnitVersionedFiles(None, access)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
870
        records = [((b'rev-id-1',), ((b'rev-id-1',), 0, len(gz_txt)))]
6729.7.2 by Jelmer Vernooij
Finish move.
871
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
872
                          knit._read_records_iter(records))
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
873
874
        # read_records_iter_raw won't detect that sort of mismatch/corruption
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
875
        raw_contents = list(knit._read_records_iter_raw(records))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
876
        self.assertEqual([((b'rev-id-1',), gz_txt, sha1sum)], raw_contents)
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
877
878
    def test_mismatched_version_id(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
879
        sha1sum = osutils.sha_string(b'foo\nbar\n')
880
        gz_txt = self.create_gz_content(b'version rev-id-1 2 %s\n'
881
                                        b'foo\n'
882
                                        b'bar\n'
883
                                        b'end rev-id-1\n'
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
884
                                        % (sha1sum,))
885
        transport = MockTransport([gz_txt])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
886
        access = _KnitKeyAccess(transport, ConstantMapper('filename'))
887
        knit = KnitVersionedFiles(None, access)
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
888
        # We are asking for rev-id-2, but the data is rev-id-1
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
889
        records = [((b'rev-id-2',), ((b'rev-id-2',), 0, len(gz_txt)))]
6729.7.2 by Jelmer Vernooij
Finish move.
890
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
891
                          knit._read_records_iter(records))
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
892
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
893
        # read_records_iter_raw detects mismatches in the header
6729.7.2 by Jelmer Vernooij
Finish move.
894
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
895
                          knit._read_records_iter_raw(records))
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
896
897
    def test_uncompressed_data(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
898
        sha1sum = osutils.sha_string(b'foo\nbar\n')
899
        txt = (b'version rev-id-1 2 %s\n'
900
               b'foo\n'
901
               b'bar\n'
902
               b'end rev-id-1\n'
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
903
               % (sha1sum,))
904
        transport = MockTransport([txt])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
905
        access = _KnitKeyAccess(transport, ConstantMapper('filename'))
906
        knit = KnitVersionedFiles(None, access)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
907
        records = [((b'rev-id-1',), ((b'rev-id-1',), 0, len(txt)))]
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
908
909
        # We don't have valid gzip data ==> corrupt
6729.7.2 by Jelmer Vernooij
Finish move.
910
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
911
                          knit._read_records_iter(records))
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
912
913
        # read_records_iter_raw will notice the bad data
6729.7.2 by Jelmer Vernooij
Finish move.
914
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
915
                          knit._read_records_iter_raw(records))
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
916
917
    def test_corrupted_data(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
918
        sha1sum = osutils.sha_string(b'foo\nbar\n')
919
        gz_txt = self.create_gz_content(b'version rev-id-1 2 %s\n'
920
                                        b'foo\n'
921
                                        b'bar\n'
922
                                        b'end rev-id-1\n'
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
923
                                        % (sha1sum,))
924
        # Change 2 bytes in the middle to \xff
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
925
        gz_txt = gz_txt[:10] + b'\xff\xff' + gz_txt[12:]
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
926
        transport = MockTransport([gz_txt])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
927
        access = _KnitKeyAccess(transport, ConstantMapper('filename'))
928
        knit = KnitVersionedFiles(None, access)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
929
        records = [((b'rev-id-1',), ((b'rev-id-1',), 0, len(gz_txt)))]
6729.7.2 by Jelmer Vernooij
Finish move.
930
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
931
                          knit._read_records_iter(records))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
932
        # read_records_iter_raw will barf on bad gz data
6729.7.2 by Jelmer Vernooij
Finish move.
933
        self.assertRaises(KnitCorrupt, list,
7143.15.2 by Jelmer Vernooij
Run autopep8.
934
                          knit._read_records_iter_raw(records))
2329.1.1 by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption.
935
936
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
937
class LowLevelKnitIndexTests(TestCase):
938
7027.1.2 by Martin
Fixup low level knit tests for Python 3
939
    @property
940
    def _load_data(self):
6670.4.3 by Jelmer Vernooij
Fix more imports.
941
        from ..bzr._knit_load_data_py import _load_data_py
7027.1.2 by Martin
Fixup low level knit tests for Python 3
942
        return _load_data_py
943
944
    def get_knit_index(self, transport, name, mode):
945
        mapper = ConstantMapper(name)
946
        self.overrideAttr(knit, '_load_data', self._load_data)
7143.15.2 by Jelmer Vernooij
Run autopep8.
947
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
948
        def allow_writes():
949
            return 'w' in mode
7027.1.2 by Martin
Fixup low level knit tests for Python 3
950
        return _KndxIndex(transport, mapper, lambda: None, allow_writes, lambda: True)
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
951
952
    def test_create_file(self):
953
        transport = MockTransport()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
954
        index = self.get_knit_index(transport, "filename", "w")
955
        index.keys()
956
        call = transport.calls.pop(0)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
957
        # call[1][1] is a BytesIO - we can't test it by simple equality.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
958
        self.assertEqual('put_file_non_atomic', call[0])
959
        self.assertEqual('filename.kndx', call[1][0])
960
        # With no history, _KndxIndex writes a new index:
961
        self.assertEqual(_KndxIndex.HEADER,
7143.15.2 by Jelmer Vernooij
Run autopep8.
962
                         call[1][1].getvalue())
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
963
        self.assertEqual({'create_parent_dir': True}, call[2])
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
964
965
    def test_read_utf8_version_id(self):
2249.5.12 by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8
966
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
967
        utf8_revision_id = unicode_revision_id.encode('utf-8')
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
968
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
969
            _KndxIndex.HEADER,
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
970
            b'%s option 0 1 :' % (utf8_revision_id,)
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
971
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
972
        index = self.get_knit_index(transport, "filename", "r")
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
973
        # _KndxIndex is a private class, and deals in utf8 revision_ids, not
2249.5.12 by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8
974
        # Unicode revision_ids.
7143.15.2 by Jelmer Vernooij
Run autopep8.
975
        self.assertEqual({(utf8_revision_id,): ()},
976
                         index.get_parent_map(index.keys()))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
977
        self.assertFalse((unicode_revision_id,) in index.keys())
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
978
979
    def test_read_utf8_parents(self):
2249.5.12 by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8
980
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
981
        utf8_revision_id = unicode_revision_id.encode('utf-8')
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
982
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
983
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
984
            b"version option 0 1 .%s :" % (utf8_revision_id,)
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
985
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
986
        index = self.get_knit_index(transport, "filename", "r")
7027.1.2 by Martin
Fixup low level knit tests for Python 3
987
        self.assertEqual({(b"version",): ((utf8_revision_id,),)},
7143.15.2 by Jelmer Vernooij
Run autopep8.
988
                         index.get_parent_map(index.keys()))
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
989
990
    def test_read_ignore_corrupted_lines(self):
991
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
992
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
993
            b"corrupted",
994
            b"corrupted options 0 1 .b .c ",
995
            b"version options 0 1 :"
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
996
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
997
        index = self.get_knit_index(transport, "filename", "r")
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
998
        self.assertEqual(1, len(index.keys()))
7027.1.2 by Martin
Fixup low level knit tests for Python 3
999
        self.assertEqual({(b"version",)}, index.keys())
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1000
1001
    def test_read_corrupted_header(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1002
        transport = MockTransport([b'not a bzr knit index header\n'])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1003
        index = self.get_knit_index(transport, "filename", "r")
1004
        self.assertRaises(KnitHeaderError, index.keys)
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1005
1006
    def test_read_duplicate_entries(self):
1007
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1008
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1009
            b"parent options 0 1 :",
1010
            b"version options1 0 1 0 :",
1011
            b"version options2 1 2 .other :",
1012
            b"version options3 3 4 0 .other :"
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1013
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1014
        index = self.get_knit_index(transport, "filename", "r")
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1015
        self.assertEqual(2, len(index.keys()))
2592.3.8 by Robert Collins
Remove unneeded pulib method lookup on private class _KnitIndex.
1016
        # check that the index used is the first one written. (Specific
1017
        # to KnitIndex style indices.
7027.1.2 by Martin
Fixup low level knit tests for Python 3
1018
        self.assertEqual(b"1", index._dictionary_compress([(b"version",)]))
7143.15.2 by Jelmer Vernooij
Run autopep8.
1019
        self.assertEqual(((b"version",), 3, 4),
1020
                         index.get_position((b"version",)))
7027.1.2 by Martin
Fixup low level knit tests for Python 3
1021
        self.assertEqual([b"options3"], index.get_options((b"version",)))
1022
        self.assertEqual({(b"version",): ((b"parent",), (b"other",))},
7143.15.2 by Jelmer Vernooij
Run autopep8.
1023
                         index.get_parent_map([(b"version",)]))
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1024
1025
    def test_read_compressed_parents(self):
1026
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1027
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1028
            b"a option 0 1 :",
1029
            b"b option 0 1 0 :",
1030
            b"c option 0 1 1 0 :",
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1031
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1032
        index = self.get_knit_index(transport, "filename", "r")
7143.15.2 by Jelmer Vernooij
Run autopep8.
1033
        self.assertEqual({(b"b",): ((b"a",),), (b"c",): ((b"b",), (b"a",))},
1034
                         index.get_parent_map([(b"b",), (b"c",)]))
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1035
1036
    def test_write_utf8_version_id(self):
2249.5.12 by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8
1037
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
1038
        utf8_revision_id = unicode_revision_id.encode('utf-8')
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1039
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1040
            _KndxIndex.HEADER
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1041
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1042
        index = self.get_knit_index(transport, "filename", "r")
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1043
        index.add_records([
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1044
            ((utf8_revision_id,), [b"option"], ((utf8_revision_id,), 0, 1), [])])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1045
        call = transport.calls.pop(0)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
1046
        # call[1][1] is a BytesIO - we can't test it by simple equality.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1047
        self.assertEqual('put_file_non_atomic', call[0])
1048
        self.assertEqual('filename.kndx', call[1][0])
1049
        # With no history, _KndxIndex writes a new index:
1050
        self.assertEqual(_KndxIndex.HEADER +
7143.15.2 by Jelmer Vernooij
Run autopep8.
1051
                         b"\n%s option 0 1  :" % (utf8_revision_id,),
1052
                         call[1][1].getvalue())
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1053
        self.assertEqual({'create_parent_dir': True}, call[2])
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1054
1055
    def test_write_utf8_parents(self):
2249.5.12 by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8
1056
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
1057
        utf8_revision_id = unicode_revision_id.encode('utf-8')
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1058
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1059
            _KndxIndex.HEADER
1060
            ])
1061
        index = self.get_knit_index(transport, "filename", "r")
1062
        index.add_records([
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1063
            ((b"version",), [b"option"], ((b"version",), 0, 1), [(utf8_revision_id,)])])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1064
        call = transport.calls.pop(0)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
1065
        # call[1][1] is a BytesIO - we can't test it by simple equality.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1066
        self.assertEqual('put_file_non_atomic', call[0])
1067
        self.assertEqual('filename.kndx', call[1][0])
1068
        # With no history, _KndxIndex writes a new index:
1069
        self.assertEqual(_KndxIndex.HEADER +
7143.15.2 by Jelmer Vernooij
Run autopep8.
1070
                         b"\nversion option 0 1 .%s :" % (utf8_revision_id,),
1071
                         call[1][1].getvalue())
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1072
        self.assertEqual({'create_parent_dir': True}, call[2])
1073
1074
    def test_keys(self):
1075
        transport = MockTransport([
1076
            _KndxIndex.HEADER
1077
            ])
1078
        index = self.get_knit_index(transport, "filename", "r")
1079
1080
        self.assertEqual(set(), index.keys())
1081
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1082
        index.add_records([((b"a",), [b"option"], ((b"a",), 0, 1), [])])
1083
        self.assertEqual({(b"a",)}, index.keys())
1084
1085
        index.add_records([((b"a",), [b"option"], ((b"a",), 0, 1), [])])
1086
        self.assertEqual({(b"a",)}, index.keys())
1087
1088
        index.add_records([((b"b",), [b"option"], ((b"b",), 0, 1), [])])
1089
        self.assertEqual({(b"a",), (b"b",)}, index.keys())
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1090
1091
    def add_a_b(self, index, random_id=None):
1092
        kwargs = {}
1093
        if random_id is not None:
1094
            kwargs["random_id"] = random_id
1095
        index.add_records([
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1096
            ((b"a",), [b"option"], ((b"a",), 0, 1), [(b"b",)]),
1097
            ((b"a",), [b"opt"], ((b"a",), 1, 2), [(b"c",)]),
1098
            ((b"b",), [b"option"], ((b"b",), 2, 3), [(b"a",)])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1099
            ], **kwargs)
1100
1101
    def assertIndexIsAB(self, index):
1102
        self.assertEqual({
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1103
            (b'a',): ((b'c',),),
1104
            (b'b',): ((b'a',),),
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1105
            },
1106
            index.get_parent_map(index.keys()))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1107
        self.assertEqual(((b"a",), 1, 2), index.get_position((b"a",)))
1108
        self.assertEqual(((b"b",), 2, 3), index.get_position((b"b",)))
1109
        self.assertEqual([b"opt"], index.get_options((b"a",)))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1110
1111
    def test_add_versions(self):
1112
        transport = MockTransport([
1113
            _KndxIndex.HEADER
1114
            ])
1115
        index = self.get_knit_index(transport, "filename", "r")
1116
1117
        self.add_a_b(index)
1118
        call = transport.calls.pop(0)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
1119
        # call[1][1] is a BytesIO - we can't test it by simple equality.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1120
        self.assertEqual('put_file_non_atomic', call[0])
1121
        self.assertEqual('filename.kndx', call[1][0])
1122
        # With no history, _KndxIndex writes a new index:
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1123
        self.assertEqual(
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1124
            _KndxIndex.HEADER +
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1125
            b"\na option 0 1 .b :"
1126
            b"\na opt 1 2 .c :"
1127
            b"\nb option 2 3 0 :",
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1128
            call[1][1].getvalue())
1129
        self.assertEqual({'create_parent_dir': True}, call[2])
1130
        self.assertIndexIsAB(index)
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1131
2841.2.1 by Robert Collins
* Commit no longer checks for new text keys during insertion when the
1132
    def test_add_versions_random_id_is_accepted(self):
1133
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1134
            _KndxIndex.HEADER
2841.2.1 by Robert Collins
* Commit no longer checks for new text keys during insertion when the
1135
            ])
1136
        index = self.get_knit_index(transport, "filename", "r")
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1137
        self.add_a_b(index, random_id=True)
2841.2.1 by Robert Collins
* Commit no longer checks for new text keys during insertion when the
1138
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1139
    def test_delay_create_and_add_versions(self):
1140
        transport = MockTransport()
1141
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1142
        index = self.get_knit_index(transport, "filename", "w")
1143
        # dir_mode=0777)
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1144
        self.assertEqual([], transport.calls)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1145
        self.add_a_b(index)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1146
        # self.assertEqual(
1147
        # [    {"dir_mode": 0777, "create_parent_dir": True, "mode": "wb"},
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1148
        #    kwargs)
1149
        # Two calls: one during which we load the existing index (and when its
1150
        # missing create it), then a second where we write the contents out.
1151
        self.assertEqual(2, len(transport.calls))
1152
        call = transport.calls.pop(0)
1153
        self.assertEqual('put_file_non_atomic', call[0])
1154
        self.assertEqual('filename.kndx', call[1][0])
1155
        # With no history, _KndxIndex writes a new index:
1156
        self.assertEqual(_KndxIndex.HEADER, call[1][1].getvalue())
1157
        self.assertEqual({'create_parent_dir': True}, call[2])
1158
        call = transport.calls.pop(0)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
1159
        # call[1][1] is a BytesIO - we can't test it by simple equality.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1160
        self.assertEqual('put_file_non_atomic', call[0])
1161
        self.assertEqual('filename.kndx', call[1][0])
1162
        # With no history, _KndxIndex writes a new index:
1163
        self.assertEqual(
1164
            _KndxIndex.HEADER +
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1165
            b"\na option 0 1 .b :"
1166
            b"\na opt 1 2 .c :"
1167
            b"\nb option 2 3 0 :",
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1168
            call[1][1].getvalue())
1169
        self.assertEqual({'create_parent_dir': True}, call[2])
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1170
4039.3.5 by John Arbash Meinel
Add direct tests for _get_total_build_size.
1171
    def assertTotalBuildSize(self, size, keys, positions):
1172
        self.assertEqual(size,
1173
                         knit._get_total_build_size(None, keys, positions))
1174
1175
    def test__get_total_build_size(self):
1176
        positions = {
7078.6.1 by Jelmer Vernooij
Fix corrupt knit handling on Python 3.
1177
            (b'a',): (('fulltext', False), ((b'a',), 0, 100), None),
1178
            (b'b',): (('line-delta', False), ((b'b',), 100, 21), (b'a',)),
1179
            (b'c',): (('line-delta', False), ((b'c',), 121, 35), (b'b',)),
1180
            (b'd',): (('line-delta', False), ((b'd',), 156, 12), (b'b',)),
4039.3.5 by John Arbash Meinel
Add direct tests for _get_total_build_size.
1181
            }
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1182
        self.assertTotalBuildSize(100, [(b'a',)], positions)
1183
        self.assertTotalBuildSize(121, [(b'b',)], positions)
4039.3.5 by John Arbash Meinel
Add direct tests for _get_total_build_size.
1184
        # c needs both a & b
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1185
        self.assertTotalBuildSize(156, [(b'c',)], positions)
4039.3.5 by John Arbash Meinel
Add direct tests for _get_total_build_size.
1186
        # we shouldn't count 'b' twice
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1187
        self.assertTotalBuildSize(156, [(b'b',), (b'c',)], positions)
1188
        self.assertTotalBuildSize(133, [(b'd',)], positions)
1189
        self.assertTotalBuildSize(168, [(b'c',), (b'd',)], positions)
4039.3.5 by John Arbash Meinel
Add direct tests for _get_total_build_size.
1190
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1191
    def test_get_position(self):
1192
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1193
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1194
            b"a option 0 1 :",
1195
            b"b option 1 2 :"
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1196
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1197
        index = self.get_knit_index(transport, "filename", "r")
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1198
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1199
        self.assertEqual(((b"a",), 0, 1), index.get_position((b"a",)))
1200
        self.assertEqual(((b"b",), 1, 2), index.get_position((b"b",)))
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1201
1202
    def test_get_method(self):
1203
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1204
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1205
            b"a fulltext,unknown 0 1 :",
1206
            b"b unknown,line-delta 1 2 :",
1207
            b"c bad 3 4 :"
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1208
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1209
        index = self.get_knit_index(transport, "filename", "r")
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1210
7027.1.2 by Martin
Fixup low level knit tests for Python 3
1211
        self.assertEqual("fulltext", index.get_method(b"a"))
1212
        self.assertEqual("line-delta", index.get_method(b"b"))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1213
        self.assertRaises(knit.KnitIndexUnknownMethod, index.get_method, b"c")
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1214
1215
    def test_get_options(self):
1216
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1217
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1218
            b"a opt1 0 1 :",
1219
            b"b opt2,opt3 1 2 :"
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1220
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1221
        index = self.get_knit_index(transport, "filename", "r")
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1222
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1223
        self.assertEqual([b"opt1"], index.get_options(b"a"))
1224
        self.assertEqual([b"opt2", b"opt3"], index.get_options(b"b"))
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1225
3287.5.6 by Robert Collins
Remove _KnitIndex.get_parents.
1226
    def test_get_parent_map(self):
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1227
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1228
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1229
            b"a option 0 1 :",
1230
            b"b option 1 2 0 .c :",
1231
            b"c option 1 2 1 0 .e :"
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1232
            ])
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1233
        index = self.get_knit_index(transport, "filename", "r")
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1234
3287.5.6 by Robert Collins
Remove _KnitIndex.get_parents.
1235
        self.assertEqual({
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1236
            (b"a",): (),
1237
            (b"b",): ((b"a",), (b"c",)),
1238
            (b"c",): ((b"b",), (b"a",), (b"e",)),
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1239
            }, index.get_parent_map(index.keys()))
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1240
2484.1.13 by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid.
1241
    def test_impossible_parent(self):
1242
        """Test we get KnitCorrupt if the parent couldn't possibly exist."""
1243
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1244
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1245
            b"a option 0 1 :",
1246
            b"b option 0 1 4 :"  # We don't have a 4th record
2484.1.13 by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid.
1247
            ])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1248
        index = self.get_knit_index(transport, 'filename', 'r')
6729.7.2 by Jelmer Vernooij
Finish move.
1249
        self.assertRaises(KnitCorrupt, index.keys)
2484.1.13 by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid.
1250
1251
    def test_corrupted_parent(self):
1252
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1253
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1254
            b"a option 0 1 :",
1255
            b"b option 0 1 :",
7143.15.2 by Jelmer Vernooij
Run autopep8.
1256
            b"c option 0 1 1v :",  # Can't have a parent of '1v'
2484.1.13 by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid.
1257
            ])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1258
        index = self.get_knit_index(transport, 'filename', 'r')
6729.7.2 by Jelmer Vernooij
Finish move.
1259
        self.assertRaises(KnitCorrupt, index.keys)
2484.1.13 by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid.
1260
1261
    def test_corrupted_parent_in_list(self):
1262
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1263
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1264
            b"a option 0 1 :",
1265
            b"b option 0 1 :",
7143.15.2 by Jelmer Vernooij
Run autopep8.
1266
            b"c option 0 1 1 v :",  # Can't have a parent of 'v'
2484.1.13 by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid.
1267
            ])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1268
        index = self.get_knit_index(transport, 'filename', 'r')
6729.7.2 by Jelmer Vernooij
Finish move.
1269
        self.assertRaises(KnitCorrupt, index.keys)
2484.1.13 by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid.
1270
2484.1.18 by John Arbash Meinel
Test that we properly verify the size and position strings.
1271
    def test_invalid_position(self):
1272
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1273
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1274
            b"a option 1v 1 :",
2484.1.18 by John Arbash Meinel
Test that we properly verify the size and position strings.
1275
            ])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1276
        index = self.get_knit_index(transport, 'filename', 'r')
6729.7.2 by Jelmer Vernooij
Finish move.
1277
        self.assertRaises(KnitCorrupt, index.keys)
2484.1.18 by John Arbash Meinel
Test that we properly verify the size and position strings.
1278
1279
    def test_invalid_size(self):
1280
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1281
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1282
            b"a option 1 1v :",
2484.1.18 by John Arbash Meinel
Test that we properly verify the size and position strings.
1283
            ])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1284
        index = self.get_knit_index(transport, 'filename', 'r')
6729.7.2 by Jelmer Vernooij
Finish move.
1285
        self.assertRaises(KnitCorrupt, index.keys)
2484.1.18 by John Arbash Meinel
Test that we properly verify the size and position strings.
1286
4011.5.7 by Andrew Bennetts
Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
1287
    def test_scan_unvalidated_index_not_implemented(self):
1288
        transport = MockTransport()
1289
        index = self.get_knit_index(transport, 'filename', 'r')
1290
        self.assertRaises(
1291
            NotImplementedError, index.scan_unvalidated_index,
1292
            'dummy graph_index')
4011.5.11 by Robert Collins
Polish the KnitVersionedFiles.scan_unvalidated_index api.
1293
        self.assertRaises(
1294
            NotImplementedError, index.get_missing_compression_parents)
4011.5.7 by Andrew Bennetts
Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
1295
2484.1.24 by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines
1296
    def test_short_line(self):
1297
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1298
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1299
            b"a option 0 10  :",
7143.15.2 by Jelmer Vernooij
Run autopep8.
1300
            b"b option 10 10 0",  # This line isn't terminated, ignored
2484.1.24 by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines
1301
            ])
1302
        index = self.get_knit_index(transport, "filename", "r")
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1303
        self.assertEqual({(b'a',)}, index.keys())
2484.1.24 by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines
1304
1305
    def test_skip_incomplete_record(self):
1306
        # A line with bogus data should just be skipped
1307
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1308
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1309
            b"a option 0 10  :",
7143.15.2 by Jelmer Vernooij
Run autopep8.
1310
            b"b option 10 10 0",  # This line isn't terminated, ignored
1311
            b"c option 20 10 0 :",  # Properly terminated, and starts with '\n'
2484.1.24 by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines
1312
            ])
1313
        index = self.get_knit_index(transport, "filename", "r")
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1314
        self.assertEqual({(b'a',), (b'c',)}, index.keys())
2484.1.24 by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines
1315
1316
    def test_trailing_characters(self):
1317
        # A line with bogus data should just be skipped
1318
        transport = MockTransport([
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1319
            _KndxIndex.HEADER,
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1320
            b"a option 0 10  :",
7143.15.2 by Jelmer Vernooij
Run autopep8.
1321
            b"b option 10 10 0 :a",  # This line has extra trailing characters
1322
            b"c option 20 10 0 :",  # Properly terminated, and starts with '\n'
2484.1.24 by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines
1323
            ])
1324
        index = self.get_knit_index(transport, "filename", "r")
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1325
        self.assertEqual({(b'a',), (b'c',)}, index.keys())
2484.1.24 by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines
1326
2158.3.1 by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations
1327
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1328
class LowLevelKnitIndexTests_c(LowLevelKnitIndexTests):
1329
4913.2.20 by John Arbash Meinel
Change all of the compiled_foo to compiled_foo_feature
1330
    _test_needs_features = [compiled_knit_feature]
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1331
7027.1.2 by Martin
Fixup low level knit tests for Python 3
1332
    @property
1333
    def _load_data(self):
6670.4.3 by Jelmer Vernooij
Fix more imports.
1334
        from ..bzr._knit_load_data_pyx import _load_data_c
7027.1.2 by Martin
Fixup low level knit tests for Python 3
1335
        return _load_data_c
2484.1.1 by John Arbash Meinel
Add an initial function to read knit indexes in pyrex.
1336
1337
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1338
class Test_KnitAnnotator(TestCaseWithMemoryTransport):
1339
1340
    def make_annotator(self):
1341
        factory = knit.make_pack_factory(True, True, 1)
1342
        vf = factory(self.get_transport())
1343
        return knit._KnitAnnotator(vf)
1344
1345
    def test__expand_fulltext(self):
1346
        ann = self.make_annotator()
6963.2.4 by Jelmer Vernooij
Add bees.
1347
        rev_key = (b'rev-id',)
4454.3.36 by John Arbash Meinel
Only cache the content objects that we will reuse.
1348
        ann._num_compression_children[rev_key] = 1
6963.2.4 by Jelmer Vernooij
Add bees.
1349
        res = ann._expand_record(rev_key, ((b'parent-id',),), None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1350
                                 [b'line1\n', b'line2\n'], ('fulltext', True))
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1351
        # The content object and text lines should be cached appropriately
6963.2.4 by Jelmer Vernooij
Add bees.
1352
        self.assertEqual([b'line1\n', b'line2'], res)
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1353
        content_obj = ann._content_objects[rev_key]
6963.2.4 by Jelmer Vernooij
Add bees.
1354
        self.assertEqual([b'line1\n', b'line2\n'], content_obj._lines)
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1355
        self.assertEqual(res, content_obj.text())
1356
        self.assertEqual(res, ann._text_cache[rev_key])
1357
4454.3.30 by John Arbash Meinel
add a bit more work to be able to process 'pending_annotations'.
1358
    def test__expand_delta_comp_parent_not_available(self):
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1359
        # Parent isn't available yet, so we return nothing, but queue up this
1360
        # node for later processing
1361
        ann = self.make_annotator()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1362
        rev_key = (b'rev-id',)
1363
        parent_key = (b'parent-id',)
1364
        record = [b'0,1,1\n', b'new-line\n']
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1365
        details = ('line-delta', False)
1366
        res = ann._expand_record(rev_key, (parent_key,), parent_key,
1367
                                 record, details)
1368
        self.assertEqual(None, res)
1369
        self.assertTrue(parent_key in ann._pending_deltas)
1370
        pending = ann._pending_deltas[parent_key]
1371
        self.assertEqual(1, len(pending))
1372
        self.assertEqual((rev_key, (parent_key,), record, details), pending[0])
1373
4454.3.33 by John Arbash Meinel
Change the _expand_record code to pop out old content objects.
1374
    def test__expand_record_tracks_num_children(self):
1375
        ann = self.make_annotator()
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1376
        rev_key = (b'rev-id',)
1377
        rev2_key = (b'rev2-id',)
1378
        parent_key = (b'parent-id',)
1379
        record = [b'0,1,1\n', b'new-line\n']
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1380
        details = ('line-delta', False)
4454.3.33 by John Arbash Meinel
Change the _expand_record code to pop out old content objects.
1381
        ann._num_compression_children[parent_key] = 2
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1382
        ann._expand_record(parent_key, (), None, [b'line1\n', b'line2\n'],
7078.6.1 by Jelmer Vernooij
Fix corrupt knit handling on Python 3.
1383
                           ('fulltext', False))
4454.3.33 by John Arbash Meinel
Change the _expand_record code to pop out old content objects.
1384
        res = ann._expand_record(rev_key, (parent_key,), parent_key,
1385
                                 record, details)
1386
        self.assertEqual({parent_key: 1}, ann._num_compression_children)
1387
        # Expanding the second child should remove the content object, and the
1388
        # num_compression_children entry
1389
        res = ann._expand_record(rev2_key, (parent_key,), parent_key,
1390
                                 record, details)
1391
        self.assertFalse(parent_key in ann._content_objects)
1392
        self.assertEqual({}, ann._num_compression_children)
4454.3.36 by John Arbash Meinel
Only cache the content objects that we will reuse.
1393
        # We should not cache the content_objects for rev2 and rev, because
1394
        # they do not have compression children of their own.
1395
        self.assertEqual({}, ann._content_objects)
4454.3.33 by John Arbash Meinel
Change the _expand_record code to pop out old content objects.
1396
4454.3.37 by John Arbash Meinel
Add tests tha left-matching-blocks gets populated.
1397
    def test__expand_delta_records_blocks(self):
1398
        ann = self.make_annotator()
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1399
        rev_key = (b'rev-id',)
1400
        parent_key = (b'parent-id',)
1401
        record = [b'0,1,1\n', b'new-line\n']
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1402
        details = ('line-delta', True)
4454.3.37 by John Arbash Meinel
Add tests tha left-matching-blocks gets populated.
1403
        ann._num_compression_children[parent_key] = 2
1404
        ann._expand_record(parent_key, (), None,
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1405
                           [b'line1\n', b'line2\n', b'line3\n'],
7078.6.1 by Jelmer Vernooij
Fix corrupt knit handling on Python 3.
1406
                           ('fulltext', False))
4454.3.37 by John Arbash Meinel
Add tests tha left-matching-blocks gets populated.
1407
        ann._expand_record(rev_key, (parent_key,), parent_key, record, details)
4454.3.38 by John Arbash Meinel
Start using left-matching-blocks during the actual annotation.
1408
        self.assertEqual({(rev_key, parent_key): [(1, 1, 1), (3, 3, 0)]},
1409
                         ann._matching_blocks)
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1410
        rev2_key = (b'rev2-id',)
6963.2.4 by Jelmer Vernooij
Add bees.
1411
        record = [b'0,1,1\n', b'new-line\n']
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1412
        details = ('line-delta', False)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1413
        ann._expand_record(rev2_key, (parent_key,),
1414
                           parent_key, record, details)
4454.3.37 by John Arbash Meinel
Add tests tha left-matching-blocks gets populated.
1415
        self.assertEqual([(1, 1, 2), (3, 3, 0)],
4454.3.38 by John Arbash Meinel
Start using left-matching-blocks during the actual annotation.
1416
                         ann._matching_blocks[(rev2_key, parent_key)])
1417
1418
    def test__get_parent_ann_uses_matching_blocks(self):
1419
        ann = self.make_annotator()
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1420
        rev_key = (b'rev-id',)
1421
        parent_key = (b'parent-id',)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1422
        parent_ann = [(parent_key,)] * 3
4454.3.38 by John Arbash Meinel
Start using left-matching-blocks during the actual annotation.
1423
        block_key = (rev_key, parent_key)
1424
        ann._annotations_cache[parent_key] = parent_ann
1425
        ann._matching_blocks[block_key] = [(0, 1, 1), (3, 3, 0)]
1426
        # We should not try to access any parent_lines content, because we know
1427
        # we already have the matching blocks
1428
        par_ann, blocks = ann._get_parent_annotations_and_matches(rev_key,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1429
                                                                  [b'1\n', b'2\n', b'3\n'], parent_key)
4454.3.38 by John Arbash Meinel
Start using left-matching-blocks during the actual annotation.
1430
        self.assertEqual(parent_ann, par_ann)
1431
        self.assertEqual([(0, 1, 1), (3, 3, 0)], blocks)
1432
        self.assertEqual({}, ann._matching_blocks)
4454.3.37 by John Arbash Meinel
Add tests tha left-matching-blocks gets populated.
1433
4454.3.31 by John Arbash Meinel
Change the processing lines to now handle fallbacks properly.
1434
    def test__process_pending(self):
4454.3.30 by John Arbash Meinel
add a bit more work to be able to process 'pending_annotations'.
1435
        ann = self.make_annotator()
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1436
        rev_key = (b'rev-id',)
1437
        p1_key = (b'p1-id',)
1438
        p2_key = (b'p2-id',)
1439
        record = [b'0,1,1\n', b'new-line\n']
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1440
        details = ('line-delta', False)
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1441
        p1_record = [b'line1\n', b'line2\n']
4454.3.33 by John Arbash Meinel
Change the _expand_record code to pop out old content objects.
1442
        ann._num_compression_children[p1_key] = 1
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1443
        res = ann._expand_record(rev_key, (p1_key, p2_key), p1_key,
4454.3.30 by John Arbash Meinel
add a bit more work to be able to process 'pending_annotations'.
1444
                                 record, details)
1445
        self.assertEqual(None, res)
1446
        # self.assertTrue(p1_key in ann._pending_deltas)
1447
        self.assertEqual({}, ann._pending_annotation)
1448
        # Now insert p1, and we should be able to expand the delta
1449
        res = ann._expand_record(p1_key, (), None, p1_record,
7078.6.1 by Jelmer Vernooij
Fix corrupt knit handling on Python 3.
1450
                                 ('fulltext', False))
4454.3.30 by John Arbash Meinel
add a bit more work to be able to process 'pending_annotations'.
1451
        self.assertEqual(p1_record, res)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1452
        ann._annotations_cache[p1_key] = [(p1_key,)] * 2
4454.3.30 by John Arbash Meinel
add a bit more work to be able to process 'pending_annotations'.
1453
        res = ann._process_pending(p1_key)
4454.3.31 by John Arbash Meinel
Change the processing lines to now handle fallbacks properly.
1454
        self.assertEqual([], res)
4454.3.30 by John Arbash Meinel
add a bit more work to be able to process 'pending_annotations'.
1455
        self.assertFalse(p1_key in ann._pending_deltas)
1456
        self.assertTrue(p2_key in ann._pending_annotation)
1457
        self.assertEqual({p2_key: [(rev_key, (p1_key, p2_key))]},
1458
                         ann._pending_annotation)
1459
        # Now fill in parent 2, and pending annotation should be satisfied
7078.6.1 by Jelmer Vernooij
Fix corrupt knit handling on Python 3.
1460
        res = ann._expand_record(p2_key, (), None, [], ('fulltext', False))
4454.3.31 by John Arbash Meinel
Change the processing lines to now handle fallbacks properly.
1461
        ann._annotations_cache[p2_key] = []
1462
        res = ann._process_pending(p2_key)
1463
        self.assertEqual([rev_key], res)
1464
        self.assertEqual({}, ann._pending_annotation)
1465
        self.assertEqual({}, ann._pending_deltas)
4454.3.30 by John Arbash Meinel
add a bit more work to be able to process 'pending_annotations'.
1466
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1467
    def test_record_delta_removes_basis(self):
1468
        ann = self.make_annotator()
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1469
        ann._expand_record((b'parent-id',), (), None,
7078.6.1 by Jelmer Vernooij
Fix corrupt knit handling on Python 3.
1470
                           [b'line1\n', b'line2\n'], ('fulltext', False))
6963.2.3 by Jelmer Vernooij
Fix some more tests.
1471
        ann._num_compression_children[b'parent-id'] = 2
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1472
4454.3.64 by John Arbash Meinel
Ensure that _KnitAnnotator also supports add_special_text.
1473
    def test_annotate_special_text(self):
1474
        ann = self.make_annotator()
1475
        vf = ann._vf
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1476
        rev1_key = (b'rev-1',)
1477
        rev2_key = (b'rev-2',)
1478
        rev3_key = (b'rev-3',)
1479
        spec_key = (b'special:',)
1480
        vf.add_lines(rev1_key, [], [b'initial content\n'])
1481
        vf.add_lines(rev2_key, [rev1_key], [b'initial content\n',
1482
                                            b'common content\n',
1483
                                            b'content in 2\n'])
1484
        vf.add_lines(rev3_key, [rev1_key], [b'initial content\n',
1485
                                            b'common content\n',
1486
                                            b'content in 3\n'])
1487
        spec_text = (b'initial content\n'
1488
                     b'common content\n'
1489
                     b'content in 2\n'
1490
                     b'content in 3\n')
4454.3.64 by John Arbash Meinel
Ensure that _KnitAnnotator also supports add_special_text.
1491
        ann.add_special_text(spec_key, [rev2_key, rev3_key], spec_text)
1492
        anns, lines = ann.annotate(spec_key)
1493
        self.assertEqual([(rev1_key,),
1494
                          (rev2_key, rev3_key),
1495
                          (rev2_key,),
1496
                          (rev3_key,),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1497
                          ], anns)
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1498
        self.assertEqualDiff(spec_text, b''.join(lines))
4454.3.64 by John Arbash Meinel
Ensure that _KnitAnnotator also supports add_special_text.
1499
4454.3.28 by John Arbash Meinel
Continue breaking things to build it up cleanly.
1500
1684.3.3 by Robert Collins
Add a special cased weaves to knit converter.
1501
class KnitTests(TestCaseWithTransport):
1502
    """Class containing knit test helper routines."""
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
1503
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1504
    def make_test_knit(self, annotate=False, name='test'):
1505
        mapper = ConstantMapper(name)
1506
        return make_file_factory(annotate, mapper)(self.get_transport())
1863.1.1 by John Arbash Meinel
Allow Versioned files to do caching if explicitly asked, and implement for Knit
1507
1508
3787.1.1 by Robert Collins
Embed the failed text in sha1 knit errors.
1509
class TestBadShaError(KnitTests):
1510
    """Tests for handling of sha errors."""
1511
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
1512
    def test_sha_exception_has_text(self):
3787.1.1 by Robert Collins
Embed the failed text in sha1 knit errors.
1513
        # having the failed text included in the error allows for recovery.
1514
        source = self.make_test_knit()
1515
        target = self.make_test_knit(name="target")
1516
        if not source._max_delta_chain:
1517
            raise TestNotApplicable(
1518
                "cannot get delta-caused sha failures without deltas.")
1519
        # create a basis
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1520
        basis = (b'basis',)
1521
        broken = (b'broken',)
1522
        source.add_lines(basis, (), [b'foo\n'])
1523
        source.add_lines(broken, (basis,), [b'foo\n', b'bar\n'])
3787.1.1 by Robert Collins
Embed the failed text in sha1 knit errors.
1524
        # Seed target with a bad basis text
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1525
        target.add_lines(basis, (), [b'gam\n'])
3787.1.1 by Robert Collins
Embed the failed text in sha1 knit errors.
1526
        target.insert_record_stream(
1527
            source.get_record_stream([broken], 'unordered', False))
6729.7.2 by Jelmer Vernooij
Finish move.
1528
        err = self.assertRaises(KnitCorrupt,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1529
                                next(target.get_record_stream([broken], 'unordered', True
1530
                                                              )).get_bytes_as, 'chunked')
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1531
        self.assertEqual([b'gam\n', b'bar\n'], err.content)
3787.1.2 by Robert Collins
Ensure SHA1KnitCorrupt formats ok.
1532
        # Test for formatting with live data
1533
        self.assertStartsWith(str(err), "Knit ")
3787.1.1 by Robert Collins
Embed the failed text in sha1 knit errors.
1534
1535
2102.2.1 by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions
1536
class TestKnitIndex(KnitTests):
1537
1538
    def test_add_versions_dictionary_compresses(self):
1539
        """Adding versions to the index should update the lookup dict"""
1540
        knit = self.make_test_knit()
1541
        idx = knit._index
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1542
        idx.add_records([((b'a-1',), [b'fulltext'], ((b'a-1',), 0, 0), [])])
2102.2.1 by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions
1543
        self.check_file_contents('test.kndx',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1544
                                 b'# bzr knit index 8\n'
1545
                                 b'\n'
1546
                                 b'a-1 fulltext 0 0  :'
1547
                                 )
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1548
        idx.add_records([
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1549
            ((b'a-2',), [b'fulltext'], ((b'a-2',), 0, 0), [(b'a-1',)]),
1550
            ((b'a-3',), [b'fulltext'], ((b'a-3',), 0, 0), [(b'a-2',)]),
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1551
            ])
2102.2.1 by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions
1552
        self.check_file_contents('test.kndx',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1553
                                 b'# bzr knit index 8\n'
1554
                                 b'\n'
1555
                                 b'a-1 fulltext 0 0  :\n'
1556
                                 b'a-2 fulltext 0 0 0 :\n'
1557
                                 b'a-3 fulltext 0 0 1 :'
1558
                                 )
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1559
        self.assertEqual({(b'a-3',), (b'a-1',), (b'a-2',)}, idx.keys())
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1560
        self.assertEqual({
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1561
            (b'a-1',): (((b'a-1',), 0, 0), None, (), ('fulltext', False)),
1562
            (b'a-2',): (((b'a-2',), 0, 0), None, ((b'a-1',),), ('fulltext', False)),
1563
            (b'a-3',): (((b'a-3',), 0, 0), None, ((b'a-2',),), ('fulltext', False)),
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1564
            }, idx.get_build_details(idx.keys()))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1565
        self.assertEqual({(b'a-1',): (),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1566
                          (b'a-2',): ((b'a-1',),),
1567
                          (b'a-3',): ((b'a-2',),), },
1568
                         idx.get_parent_map(idx.keys()))
2102.2.1 by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions
1569
1570
    def test_add_versions_fails_clean(self):
1571
        """If add_versions fails in the middle, it restores a pristine state.
1572
1573
        Any modifications that are made to the index are reset if all versions
1574
        cannot be added.
1575
        """
1576
        # This cheats a little bit by passing in a generator which will
1577
        # raise an exception before the processing finishes
1578
        # Other possibilities would be to have an version with the wrong number
1579
        # of entries, or to make the backing transport unable to write any
1580
        # files.
1581
1582
        knit = self.make_test_knit()
1583
        idx = knit._index
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1584
        idx.add_records([((b'a-1',), [b'fulltext'], ((b'a-1',), 0, 0), [])])
2102.2.1 by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions
1585
1586
        class StopEarly(Exception):
1587
            pass
1588
1589
        def generate_failure():
1590
            """Add some entries and then raise an exception"""
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1591
            yield ((b'a-2',), [b'fulltext'], (None, 0, 0), (b'a-1',))
1592
            yield ((b'a-3',), [b'fulltext'], (None, 0, 0), (b'a-2',))
2102.2.1 by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions
1593
            raise StopEarly()
1594
1595
        # Assert the pre-condition
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1596
        def assertA1Only():
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1597
            self.assertEqual({(b'a-1',)}, set(idx.keys()))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1598
            self.assertEqual(
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1599
                {(b'a-1',): (((b'a-1',), 0, 0), None, (), ('fulltext', False))},
1600
                idx.get_build_details([(b'a-1',)]))
7143.15.2 by Jelmer Vernooij
Run autopep8.
1601
            self.assertEqual({(b'a-1',): ()}, idx.get_parent_map(idx.keys()))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1602
1603
        assertA1Only()
1604
        self.assertRaises(StopEarly, idx.add_records, generate_failure())
2102.2.1 by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions
1605
        # And it shouldn't be modified
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1606
        assertA1Only()
2171.1.1 by John Arbash Meinel
Knit index files should ignore empty indexes rather than consider them corrupt.
1607
1608
    def test_knit_index_ignores_empty_files(self):
1609
        # There was a race condition in older bzr, where a ^C at the right time
1610
        # could leave an empty .kndx file, which bzr would later claim was a
1611
        # corrupted file since the header was not present. In reality, the file
1612
        # just wasn't created, so it should be ignored.
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
1613
        t = transport.get_transport_from_path('.')
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1614
        t.put_bytes('test.kndx', b'')
2171.1.1 by John Arbash Meinel
Knit index files should ignore empty indexes rather than consider them corrupt.
1615
1616
        knit = self.make_test_knit()
1617
1618
    def test_knit_index_checks_header(self):
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
1619
        t = transport.get_transport_from_path('.')
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1620
        t.put_bytes('test.kndx', b'# not really a knit header\n\n')
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1621
        k = self.make_test_knit()
1622
        self.assertRaises(KnitHeaderError, k.keys)
2592.3.2 by Robert Collins
Implement a get_graph for a new KnitGraphIndex that will implement a KnitIndex on top of the GraphIndex API.
1623
1624
1625
class TestGraphIndexKnit(KnitTests):
1626
    """Tests for knits using a GraphIndex rather than a KnitIndex."""
1627
1628
    def make_g_index(self, name, ref_lists=0, nodes=[]):
1629
        builder = GraphIndexBuilder(ref_lists)
1630
        for node, references, value in nodes:
1631
            builder.add_node(node, references, value)
1632
        stream = builder.finish()
1633
        trans = self.get_transport()
2890.2.1 by Robert Collins
* ``bzrlib.index.GraphIndex`` now requires a size parameter to the
1634
        size = trans.put_file(name, stream)
1635
        return GraphIndex(trans, name, size)
2592.3.2 by Robert Collins
Implement a get_graph for a new KnitGraphIndex that will implement a KnitIndex on top of the GraphIndex API.
1636
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1637
    def two_graph_index(self, deltas=False, catch_adds=False):
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1638
        """Build a two-graph index.
1639
1640
        :param deltas: If true, use underlying indices with two node-ref
1641
            lists and 'parent' set to a delta-compressed against tail.
1642
        """
2592.3.2 by Robert Collins
Implement a get_graph for a new KnitGraphIndex that will implement a KnitIndex on top of the GraphIndex API.
1643
        # build a complex graph across several indices.
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1644
        if deltas:
2624.2.5 by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings.
1645
            # delta compression inn the index
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1646
            index1 = self.make_g_index('1', 2, [
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1647
                ((b'tip', ), b'N0 100', ([(b'parent', )], [], )),
1648
                ((b'tail', ), b'', ([], []))])
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1649
            index2 = self.make_g_index('2', 2, [
7143.15.2 by Jelmer Vernooij
Run autopep8.
1650
                ((b'parent', ), b' 100 78',
1651
                 ([(b'tail', ), (b'ghost', )], [(b'tail', )])),
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1652
                ((b'separate', ), b'', ([], []))])
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1653
        else:
2624.2.5 by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings.
1654
            # just blob location and graph in the index.
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1655
            index1 = self.make_g_index('1', 1, [
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1656
                ((b'tip', ), b'N0 100', ([(b'parent', )], )),
1657
                ((b'tail', ), b'', ([], ))])
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1658
            index2 = self.make_g_index('2', 1, [
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1659
                ((b'parent', ), b' 100 78', ([(b'tail', ), (b'ghost', )], )),
1660
                ((b'separate', ), b'', ([], ))])
2592.3.2 by Robert Collins
Implement a get_graph for a new KnitGraphIndex that will implement a KnitIndex on top of the GraphIndex API.
1661
        combined_index = CombinedGraphIndex([index1, index2])
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1662
        if catch_adds:
1663
            self.combined_index = combined_index
1664
            self.caught_entries = []
1665
            add_callback = self.catch_add
1666
        else:
1667
            add_callback = None
7143.15.2 by Jelmer Vernooij
Run autopep8.
1668
        return _KnitGraphIndex(combined_index, lambda: True, deltas=deltas,
1669
                               add_callback=add_callback)
2592.3.4 by Robert Collins
Implement get_ancestry/get_ancestry_with_ghosts for KnitGraphIndex.
1670
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1671
    def test_keys(self):
1672
        index = self.two_graph_index()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1673
        self.assertEqual({(b'tail',), (b'tip',), (b'parent',), (b'separate',)},
7143.15.2 by Jelmer Vernooij
Run autopep8.
1674
                         set(index.keys()))
2592.3.9 by Robert Collins
Implement KnitGraphIndex.has_version.
1675
2592.3.10 by Robert Collins
Implement KnitGraphIndex.get_position.
1676
    def test_get_position(self):
1677
        index = self.two_graph_index()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1678
        self.assertEqual(
1679
            (index._graph_index._indices[0], 0, 100), index.get_position((b'tip',)))
1680
        self.assertEqual(
1681
            (index._graph_index._indices[1], 100, 78), index.get_position((b'parent',)))
2592.3.10 by Robert Collins
Implement KnitGraphIndex.get_position.
1682
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1683
    def test_get_method_deltas(self):
1684
        index = self.two_graph_index(deltas=True)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1685
        self.assertEqual('fulltext', index.get_method((b'tip',)))
1686
        self.assertEqual('line-delta', index.get_method((b'parent',)))
2592.3.11 by Robert Collins
Implement KnitGraphIndex.get_method.
1687
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1688
    def test_get_method_no_deltas(self):
1689
        # check that the parent-history lookup is ignored with deltas=False.
1690
        index = self.two_graph_index(deltas=False)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1691
        self.assertEqual('fulltext', index.get_method((b'tip',)))
1692
        self.assertEqual('fulltext', index.get_method((b'parent',)))
2592.3.13 by Robert Collins
Implement KnitGraphIndex.get_method.
1693
2592.3.14 by Robert Collins
Implement KnitGraphIndex.get_options.
1694
    def test_get_options_deltas(self):
1695
        index = self.two_graph_index(deltas=True)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1696
        self.assertEqual([b'fulltext', b'no-eol'],
1697
                         index.get_options((b'tip',)))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1698
        self.assertEqual([b'line-delta'], index.get_options((b'parent',)))
2592.3.14 by Robert Collins
Implement KnitGraphIndex.get_options.
1699
1700
    def test_get_options_no_deltas(self):
1701
        # check that the parent-history lookup is ignored with deltas=False.
1702
        index = self.two_graph_index(deltas=False)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1703
        self.assertEqual([b'fulltext', b'no-eol'],
1704
                         index.get_options((b'tip',)))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1705
        self.assertEqual([b'fulltext'], index.get_options((b'parent',)))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1706
1707
    def test_get_parent_map(self):
1708
        index = self.two_graph_index()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1709
        self.assertEqual({(b'parent',): ((b'tail',), (b'ghost',))},
1710
                         index.get_parent_map([(b'parent',), (b'ghost',)]))
2592.3.14 by Robert Collins
Implement KnitGraphIndex.get_options.
1711
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1712
    def catch_add(self, entries):
1713
        self.caught_entries.append(entries)
1714
1715
    def test_add_no_callback_errors(self):
1716
        index = self.two_graph_index()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1717
        self.assertRaises(errors.ReadOnlyError, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1718
                          [((b'new',), b'fulltext,no-eol', (None, 50, 60), [b'separate'])])
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1719
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1720
    def test_add_version_smoke(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1721
        index = self.two_graph_index(catch_adds=True)
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1722
        index.add_records([((b'new',), b'fulltext,no-eol', (None, 50, 60),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1723
                            [(b'separate',)])])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1724
        self.assertEqual([[((b'new', ), b'N50 60', (((b'separate',),),))]],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1725
                         self.caught_entries)
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1726
1727
    def test_add_version_delta_not_delta_index(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1728
        index = self.two_graph_index(catch_adds=True)
6729.7.2 by Jelmer Vernooij
Finish move.
1729
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1730
                          [((b'new',), b'no-eol,line-delta', (None, 0, 100), [(b'parent',)])])
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1731
        self.assertEqual([], self.caught_entries)
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1732
1733
    def test_add_version_same_dup(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1734
        index = self.two_graph_index(catch_adds=True)
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1735
        # options can be spelt two different ways
7143.15.2 by Jelmer Vernooij
Run autopep8.
1736
        index.add_records(
1737
            [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [(b'parent',)])])
1738
        index.add_records(
1739
            [((b'tip',), b'no-eol,fulltext', (None, 0, 100), [(b'parent',)])])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1740
        # position/length are ignored (because each pack could have fulltext or
1741
        # delta, and be at a different position.
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1742
        index.add_records([((b'tip',), b'fulltext,no-eol', (None, 50, 100),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1743
                            [(b'parent',)])])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1744
        index.add_records([((b'tip',), b'fulltext,no-eol', (None, 0, 1000),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1745
                            [(b'parent',)])])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1746
        # but neither should have added data:
1747
        self.assertEqual([[], [], [], []], self.caught_entries)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1748
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1749
    def test_add_version_different_dup(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1750
        index = self.two_graph_index(deltas=True, catch_adds=True)
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1751
        # change options
6729.7.2 by Jelmer Vernooij
Finish move.
1752
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1753
                          [((b'tip',), b'line-delta', (None, 0, 100), [(b'parent',)])])
6729.7.2 by Jelmer Vernooij
Finish move.
1754
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1755
                          [((b'tip',), b'fulltext', (None, 0, 100), [(b'parent',)])])
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1756
        # parents
6729.7.2 by Jelmer Vernooij
Finish move.
1757
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1758
                          [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [])])
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1759
        self.assertEqual([], self.caught_entries)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1760
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1761
    def test_add_versions_nodeltas(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1762
        index = self.two_graph_index(catch_adds=True)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1763
        index.add_records([
7143.15.2 by Jelmer Vernooij
Run autopep8.
1764
            ((b'new',), b'fulltext,no-eol', (None, 50, 60), [(b'separate',)]),
1765
            ((b'new2',), b'fulltext', (None, 0, 6), [(b'new',)]),
1766
            ])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1767
        self.assertEqual([((b'new', ), b'N50 60', (((b'separate',),),)),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1768
                          ((b'new2', ), b' 0 6', (((b'new',),),))],
1769
                         sorted(self.caught_entries[0]))
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1770
        self.assertEqual(1, len(self.caught_entries))
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1771
1772
    def test_add_versions_deltas(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1773
        index = self.two_graph_index(deltas=True, catch_adds=True)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1774
        index.add_records([
7143.15.2 by Jelmer Vernooij
Run autopep8.
1775
            ((b'new',), b'fulltext,no-eol', (None, 50, 60), [(b'separate',)]),
1776
            ((b'new2',), b'line-delta', (None, 0, 6), [(b'new',)]),
1777
            ])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1778
        self.assertEqual([((b'new', ), b'N50 60', (((b'separate',),), ())),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1779
                          ((b'new2', ), b' 0 6', (((b'new',),), ((b'new',),), ))],
1780
                         sorted(self.caught_entries[0]))
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1781
        self.assertEqual(1, len(self.caught_entries))
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1782
1783
    def test_add_versions_delta_not_delta_index(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1784
        index = self.two_graph_index(catch_adds=True)
6729.7.2 by Jelmer Vernooij
Finish move.
1785
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1786
                          [((b'new',), b'no-eol,line-delta', (None, 0, 100), [(b'parent',)])])
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1787
        self.assertEqual([], self.caught_entries)
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1788
2841.2.1 by Robert Collins
* Commit no longer checks for new text keys during insertion when the
1789
    def test_add_versions_random_id_accepted(self):
1790
        index = self.two_graph_index(catch_adds=True)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1791
        index.add_records([], random_id=True)
2841.2.1 by Robert Collins
* Commit no longer checks for new text keys during insertion when the
1792
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1793
    def test_add_versions_same_dup(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1794
        index = self.two_graph_index(catch_adds=True)
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1795
        # options can be spelt two different ways
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1796
        index.add_records([((b'tip',), b'fulltext,no-eol', (None, 0, 100),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1797
                            [(b'parent',)])])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1798
        index.add_records([((b'tip',), b'no-eol,fulltext', (None, 0, 100),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1799
                            [(b'parent',)])])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1800
        # position/length are ignored (because each pack could have fulltext or
1801
        # delta, and be at a different position.
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1802
        index.add_records([((b'tip',), b'fulltext,no-eol', (None, 50, 100),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1803
                            [(b'parent',)])])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1804
        index.add_records([((b'tip',), b'fulltext,no-eol', (None, 0, 1000),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1805
                            [(b'parent',)])])
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1806
        # but neither should have added data.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1807
        self.assertEqual([[], [], [], []], self.caught_entries)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1808
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1809
    def test_add_versions_different_dup(self):
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1810
        index = self.two_graph_index(deltas=True, catch_adds=True)
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1811
        # change options
6729.7.2 by Jelmer Vernooij
Finish move.
1812
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1813
                          [((b'tip',), b'line-delta', (None, 0, 100), [(b'parent',)])])
6729.7.2 by Jelmer Vernooij
Finish move.
1814
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1815
                          [((b'tip',), b'fulltext', (None, 0, 100), [(b'parent',)])])
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1816
        # parents
6729.7.2 by Jelmer Vernooij
Finish move.
1817
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1818
                          [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [])])
2592.3.17 by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
1819
        # change options in the second record
6729.7.2 by Jelmer Vernooij
Finish move.
1820
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1821
                          [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [(b'parent',)]),
1822
                           ((b'tip',), b'line-delta', (None, 0, 100), [(b'parent',)])])
2592.3.19 by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions.
1823
        self.assertEqual([], self.caught_entries)
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1824
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1825
    def make_g_index_missing_compression_parent(self):
1826
        graph_index = self.make_g_index('missing_comp', 2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1827
                                        [((b'tip', ), b' 100 78',
1828
                                          ([(b'missing-parent', ), (b'ghost', )], [(b'missing-parent', )]))])
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1829
        return graph_index
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
1830
4257.4.14 by Andrew Bennetts
Add a unit test for _KnitGraphIndex.get_missing_parents, fix bug that it reveals.
1831
    def make_g_index_missing_parent(self):
1832
        graph_index = self.make_g_index('missing_parent', 2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1833
                                        [((b'parent', ), b' 100 78', ([], [])),
1834
                                         ((b'tip', ), b' 100 78',
1835
                                            ([(b'parent', ), (b'missing-parent', )], [(b'parent', )])),
1836
                                         ])
4257.4.14 by Andrew Bennetts
Add a unit test for _KnitGraphIndex.get_missing_parents, fix bug that it reveals.
1837
        return graph_index
1838
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1839
    def make_g_index_no_external_refs(self):
1840
        graph_index = self.make_g_index('no_external_refs', 2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1841
                                        [((b'rev', ), b' 100 78',
1842
                                          ([(b'parent', ), (b'ghost', )], []))])
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1843
        return graph_index
1844
4011.5.1 by Andrew Bennetts
Start to add _add_unvalidated_index/get_missing_compression_parents methods to _KnitGraphIndex.
1845
    def test_add_good_unvalidated_index(self):
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1846
        unvalidated = self.make_g_index_no_external_refs()
1847
        combined = CombinedGraphIndex([unvalidated])
4011.5.11 by Robert Collins
Polish the KnitVersionedFiles.scan_unvalidated_index api.
1848
        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
4011.5.7 by Andrew Bennetts
Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
1849
        index.scan_unvalidated_index(unvalidated)
4011.5.1 by Andrew Bennetts
Start to add _add_unvalidated_index/get_missing_compression_parents methods to _KnitGraphIndex.
1850
        self.assertEqual(frozenset(), index.get_missing_compression_parents())
1851
4257.4.14 by Andrew Bennetts
Add a unit test for _KnitGraphIndex.get_missing_parents, fix bug that it reveals.
1852
    def test_add_missing_compression_parent_unvalidated_index(self):
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1853
        unvalidated = self.make_g_index_missing_compression_parent()
1854
        combined = CombinedGraphIndex([unvalidated])
4011.5.11 by Robert Collins
Polish the KnitVersionedFiles.scan_unvalidated_index api.
1855
        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
4011.5.7 by Andrew Bennetts
Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
1856
        index.scan_unvalidated_index(unvalidated)
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.
1857
        # This also checks that its only the compression parent that is
1858
        # examined, otherwise 'ghost' would also be reported as a missing
1859
        # parent.
4011.5.1 by Andrew Bennetts
Start to add _add_unvalidated_index/get_missing_compression_parents methods to _KnitGraphIndex.
1860
        self.assertEqual(
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1861
            frozenset([(b'missing-parent',)]),
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1862
            index.get_missing_compression_parents())
4011.5.1 by Andrew Bennetts
Start to add _add_unvalidated_index/get_missing_compression_parents methods to _KnitGraphIndex.
1863
4257.4.14 by Andrew Bennetts
Add a unit test for _KnitGraphIndex.get_missing_parents, fix bug that it reveals.
1864
    def test_add_missing_noncompression_parent_unvalidated_index(self):
1865
        unvalidated = self.make_g_index_missing_parent()
1866
        combined = CombinedGraphIndex([unvalidated])
1867
        index = _KnitGraphIndex(combined, lambda: True, deltas=True,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1868
                                track_external_parent_refs=True)
4257.4.14 by Andrew Bennetts
Add a unit test for _KnitGraphIndex.get_missing_parents, fix bug that it reveals.
1869
        index.scan_unvalidated_index(unvalidated)
1870
        self.assertEqual(
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1871
            frozenset([(b'missing-parent',)]), index.get_missing_parents())
4257.4.14 by Andrew Bennetts
Add a unit test for _KnitGraphIndex.get_missing_parents, fix bug that it reveals.
1872
4257.4.15 by Andrew Bennetts
Add another test for _KnitGraphIndex.get_missing_parents().
1873
    def test_track_external_parent_refs(self):
1874
        g_index = self.make_g_index('empty', 2, [])
1875
        combined = CombinedGraphIndex([g_index])
1876
        index = _KnitGraphIndex(combined, lambda: True, deltas=True,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1877
                                add_callback=self.catch_add, track_external_parent_refs=True)
4257.4.15 by Andrew Bennetts
Add another test for _KnitGraphIndex.get_missing_parents().
1878
        self.caught_entries = []
1879
        index.add_records([
6973.11.7 by Jelmer Vernooij
Fix more tests.
1880
            ((b'new-key',), b'fulltext,no-eol', (None, 50, 60),
1881
             [(b'parent-1',), (b'parent-2',)])])
4257.4.15 by Andrew Bennetts
Add another test for _KnitGraphIndex.get_missing_parents().
1882
        self.assertEqual(
6973.11.7 by Jelmer Vernooij
Fix more tests.
1883
            frozenset([(b'parent-1',), (b'parent-2',)]),
4257.4.15 by Andrew Bennetts
Add another test for _KnitGraphIndex.get_missing_parents().
1884
            index.get_missing_parents())
1885
4011.5.1 by Andrew Bennetts
Start to add _add_unvalidated_index/get_missing_compression_parents methods to _KnitGraphIndex.
1886
    def test_add_unvalidated_index_with_present_external_references(self):
1887
        index = self.two_graph_index(deltas=True)
4011.5.10 by Andrew Bennetts
Replace XXX with better comment.
1888
        # Ugly hack to get at one of the underlying GraphIndex objects that
1889
        # two_graph_index built.
1890
        unvalidated = index._graph_index._indices[1]
1891
        # 'parent' is an external ref of _indices[1] (unvalidated), but is
1892
        # present in _indices[0].
4011.5.7 by Andrew Bennetts
Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
1893
        index.scan_unvalidated_index(unvalidated)
4011.5.1 by Andrew Bennetts
Start to add _add_unvalidated_index/get_missing_compression_parents methods to _KnitGraphIndex.
1894
        self.assertEqual(frozenset(), index.get_missing_compression_parents())
1895
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1896
    def make_new_missing_parent_g_index(self, name):
6973.11.7 by Jelmer Vernooij
Fix more tests.
1897
        missing_parent = name.encode('ascii') + b'-missing-parent'
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1898
        graph_index = self.make_g_index(name, 2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1899
                                        [((name.encode('ascii') + b'tip', ), b' 100 78',
1900
                                          ([(missing_parent, ), (b'ghost', )], [(missing_parent, )]))])
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1901
        return graph_index
1902
1903
    def test_add_mulitiple_unvalidated_indices_with_missing_parents(self):
1904
        g_index_1 = self.make_new_missing_parent_g_index('one')
1905
        g_index_2 = self.make_new_missing_parent_g_index('two')
1906
        combined = CombinedGraphIndex([g_index_1, g_index_2])
4011.5.11 by Robert Collins
Polish the KnitVersionedFiles.scan_unvalidated_index api.
1907
        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
4011.5.7 by Andrew Bennetts
Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
1908
        index.scan_unvalidated_index(g_index_1)
1909
        index.scan_unvalidated_index(g_index_2)
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1910
        self.assertEqual(
6973.11.7 by Jelmer Vernooij
Fix more tests.
1911
            frozenset([(b'one-missing-parent',), (b'two-missing-parent',)]),
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1912
            index.get_missing_compression_parents())
1913
1914
    def test_add_mulitiple_unvalidated_indices_with_mutual_dependencies(self):
1915
        graph_index_a = self.make_g_index('one', 2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1916
                                          [((b'parent-one', ), b' 100 78', ([(b'non-compression-parent',)], [])),
1917
                                           ((b'child-of-two', ), b' 100 78',
1918
                                              ([(b'parent-two',)], [(b'parent-two',)]))])
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1919
        graph_index_b = self.make_g_index('two', 2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1920
                                          [((b'parent-two', ), b' 100 78', ([(b'non-compression-parent',)], [])),
1921
                                           ((b'child-of-one', ), b' 100 78',
1922
                                              ([(b'parent-one',)], [(b'parent-one',)]))])
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1923
        combined = CombinedGraphIndex([graph_index_a, graph_index_b])
4011.5.11 by Robert Collins
Polish the KnitVersionedFiles.scan_unvalidated_index api.
1924
        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
4011.5.7 by Andrew Bennetts
Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
1925
        index.scan_unvalidated_index(graph_index_a)
1926
        index.scan_unvalidated_index(graph_index_b)
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1927
        self.assertEqual(
1928
            frozenset([]), index.get_missing_compression_parents())
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
1929
4011.5.2 by Andrew Bennetts
Add more tests, improve existing tests, add GraphIndex._external_references()
1930
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1931
class TestNoParentsGraphIndexKnit(KnitTests):
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1932
    """Tests for knits using _KnitGraphIndex with no parents."""
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1933
1934
    def make_g_index(self, name, ref_lists=0, nodes=[]):
1935
        builder = GraphIndexBuilder(ref_lists)
1936
        for node, references in nodes:
1937
            builder.add_node(node, references)
1938
        stream = builder.finish()
1939
        trans = self.get_transport()
2890.2.1 by Robert Collins
* ``bzrlib.index.GraphIndex`` now requires a size parameter to the
1940
        size = trans.put_file(name, stream)
1941
        return GraphIndex(trans, name, size)
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1942
4011.5.11 by Robert Collins
Polish the KnitVersionedFiles.scan_unvalidated_index api.
1943
    def test_add_good_unvalidated_index(self):
1944
        unvalidated = self.make_g_index('unvalidated')
1945
        combined = CombinedGraphIndex([unvalidated])
1946
        index = _KnitGraphIndex(combined, lambda: True, parents=False)
1947
        index.scan_unvalidated_index(unvalidated)
1948
        self.assertEqual(frozenset(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1949
                         index.get_missing_compression_parents())
4011.5.11 by Robert Collins
Polish the KnitVersionedFiles.scan_unvalidated_index api.
1950
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1951
    def test_parents_deltas_incompatible(self):
1952
        index = CombinedGraphIndex([])
7143.15.2 by Jelmer Vernooij
Run autopep8.
1953
        self.assertRaises(knit.KnitError, _KnitGraphIndex, lambda: True,
1954
                          index, deltas=True, parents=False)
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1955
1956
    def two_graph_index(self, catch_adds=False):
1957
        """Build a two-graph index.
1958
1959
        :param deltas: If true, use underlying indices with two node-ref
1960
            lists and 'parent' set to a delta-compressed against tail.
1961
        """
1962
        # put several versions in the index.
1963
        index1 = self.make_g_index('1', 0, [
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1964
            ((b'tip', ), b'N0 100'),
1965
            ((b'tail', ), b'')])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1966
        index2 = self.make_g_index('2', 0, [
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1967
            ((b'parent', ), b' 100 78'),
1968
            ((b'separate', ), b'')])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1969
        combined_index = CombinedGraphIndex([index1, index2])
1970
        if catch_adds:
1971
            self.combined_index = combined_index
1972
            self.caught_entries = []
1973
            add_callback = self.catch_add
1974
        else:
1975
            add_callback = None
7143.15.2 by Jelmer Vernooij
Run autopep8.
1976
        return _KnitGraphIndex(combined_index, lambda: True, parents=False,
1977
                               add_callback=add_callback)
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1978
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1979
    def test_keys(self):
1980
        index = self.two_graph_index()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
1981
        self.assertEqual({(b'tail',), (b'tip',), (b'parent',), (b'separate',)},
7143.15.2 by Jelmer Vernooij
Run autopep8.
1982
                         set(index.keys()))
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1983
1984
    def test_get_position(self):
1985
        index = self.two_graph_index()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1986
        self.assertEqual((index._graph_index._indices[0], 0, 100),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1987
                         index.get_position((b'tip',)))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1988
        self.assertEqual((index._graph_index._indices[1], 100, 78),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1989
                         index.get_position((b'parent',)))
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1990
1991
    def test_get_method(self):
1992
        index = self.two_graph_index()
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
1993
        self.assertEqual('fulltext', index.get_method((b'tip',)))
1994
        self.assertEqual([b'fulltext'], index.get_options((b'parent',)))
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
1995
1996
    def test_get_options(self):
1997
        index = self.two_graph_index()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1998
        self.assertEqual([b'fulltext', b'no-eol'],
1999
                         index.get_options((b'tip',)))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2000
        self.assertEqual([b'fulltext'], index.get_options((b'parent',)))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2001
2002
    def test_get_parent_map(self):
2003
        index = self.two_graph_index()
7143.15.2 by Jelmer Vernooij
Run autopep8.
2004
        self.assertEqual({(b'parent',): None},
2005
                         index.get_parent_map([(b'parent',), (b'ghost',)]))
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2006
2007
    def catch_add(self, entries):
2008
        self.caught_entries.append(entries)
2009
2010
    def test_add_no_callback_errors(self):
2011
        index = self.two_graph_index()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2012
        self.assertRaises(errors.ReadOnlyError, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2013
                          [((b'new',), b'fulltext,no-eol', (None, 50, 60), [(b'separate',)])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2014
2015
    def test_add_version_smoke(self):
2016
        index = self.two_graph_index(catch_adds=True)
7143.15.2 by Jelmer Vernooij
Run autopep8.
2017
        index.add_records(
2018
            [((b'new',), b'fulltext,no-eol', (None, 50, 60), [])])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2019
        self.assertEqual([[((b'new', ), b'N50 60')]],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2020
                         self.caught_entries)
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2021
2022
    def test_add_version_delta_not_delta_index(self):
2023
        index = self.two_graph_index(catch_adds=True)
6729.7.2 by Jelmer Vernooij
Finish move.
2024
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2025
                          [((b'new',), b'no-eol,line-delta', (None, 0, 100), [])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2026
        self.assertEqual([], self.caught_entries)
2027
2028
    def test_add_version_same_dup(self):
2029
        index = self.two_graph_index(catch_adds=True)
2030
        # options can be spelt two different ways
7143.15.2 by Jelmer Vernooij
Run autopep8.
2031
        index.add_records(
2032
            [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [])])
2033
        index.add_records(
2034
            [((b'tip',), b'no-eol,fulltext', (None, 0, 100), [])])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2035
        # position/length are ignored (because each pack could have fulltext or
2036
        # delta, and be at a different position.
7143.15.2 by Jelmer Vernooij
Run autopep8.
2037
        index.add_records(
2038
            [((b'tip',), b'fulltext,no-eol', (None, 50, 100), [])])
2039
        index.add_records(
2040
            [((b'tip',), b'fulltext,no-eol', (None, 0, 1000), [])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2041
        # but neither should have added data.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2042
        self.assertEqual([[], [], [], []], self.caught_entries)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2043
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2044
    def test_add_version_different_dup(self):
2045
        index = self.two_graph_index(catch_adds=True)
2046
        # change options
6729.7.2 by Jelmer Vernooij
Finish move.
2047
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2048
                          [((b'tip',), b'no-eol,line-delta', (None, 0, 100), [])])
2049
        self.assertRaises(KnitCorrupt, index.add_records,
2050
                          [((b'tip',), b'line-delta,no-eol', (None, 0, 100), [])])
2051
        self.assertRaises(KnitCorrupt, index.add_records,
2052
                          [((b'tip',), b'fulltext', (None, 0, 100), [])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2053
        # parents
6729.7.2 by Jelmer Vernooij
Finish move.
2054
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2055
                          [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [(b'parent',)])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2056
        self.assertEqual([], self.caught_entries)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2057
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2058
    def test_add_versions(self):
2059
        index = self.two_graph_index(catch_adds=True)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2060
        index.add_records([
7143.15.2 by Jelmer Vernooij
Run autopep8.
2061
            ((b'new',), b'fulltext,no-eol', (None, 50, 60), []),
2062
            ((b'new2',), b'fulltext', (None, 0, 6), []),
2063
            ])
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2064
        self.assertEqual([((b'new', ), b'N50 60'), ((b'new2', ), b' 0 6')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2065
                         sorted(self.caught_entries[0]))
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2066
        self.assertEqual(1, len(self.caught_entries))
2067
2068
    def test_add_versions_delta_not_delta_index(self):
2069
        index = self.two_graph_index(catch_adds=True)
6729.7.2 by Jelmer Vernooij
Finish move.
2070
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2071
                          [((b'new',), b'no-eol,line-delta', (None, 0, 100), [(b'parent',)])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2072
        self.assertEqual([], self.caught_entries)
2073
2074
    def test_add_versions_parents_not_parents_index(self):
2075
        index = self.two_graph_index(catch_adds=True)
6729.7.2 by Jelmer Vernooij
Finish move.
2076
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2077
                          [((b'new',), b'no-eol,fulltext', (None, 0, 100), [(b'parent',)])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2078
        self.assertEqual([], self.caught_entries)
2079
2841.2.1 by Robert Collins
* Commit no longer checks for new text keys during insertion when the
2080
    def test_add_versions_random_id_accepted(self):
2081
        index = self.two_graph_index(catch_adds=True)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2082
        index.add_records([], random_id=True)
2841.2.1 by Robert Collins
* Commit no longer checks for new text keys during insertion when the
2083
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2084
    def test_add_versions_same_dup(self):
2085
        index = self.two_graph_index(catch_adds=True)
2086
        # options can be spelt two different ways
7143.15.2 by Jelmer Vernooij
Run autopep8.
2087
        index.add_records(
2088
            [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [])])
2089
        index.add_records(
2090
            [((b'tip',), b'no-eol,fulltext', (None, 0, 100), [])])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2091
        # position/length are ignored (because each pack could have fulltext or
2092
        # delta, and be at a different position.
7143.15.2 by Jelmer Vernooij
Run autopep8.
2093
        index.add_records(
2094
            [((b'tip',), b'fulltext,no-eol', (None, 50, 100), [])])
2095
        index.add_records(
2096
            [((b'tip',), b'fulltext,no-eol', (None, 0, 1000), [])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2097
        # but neither should have added data.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2098
        self.assertEqual([[], [], [], []], self.caught_entries)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2099
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2100
    def test_add_versions_different_dup(self):
2101
        index = self.two_graph_index(catch_adds=True)
2102
        # change options
6729.7.2 by Jelmer Vernooij
Finish move.
2103
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2104
                          [((b'tip',), b'no-eol,line-delta', (None, 0, 100), [])])
2105
        self.assertRaises(KnitCorrupt, index.add_records,
2106
                          [((b'tip',), b'line-delta,no-eol', (None, 0, 100), [])])
2107
        self.assertRaises(KnitCorrupt, index.add_records,
2108
                          [((b'tip',), b'fulltext', (None, 0, 100), [])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2109
        # parents
6729.7.2 by Jelmer Vernooij
Finish move.
2110
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2111
                          [((b'tip',), b'fulltext,no-eol', (None, 0, 100), [(b'parent',)])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2112
        # change options in the second record
6729.7.2 by Jelmer Vernooij
Finish move.
2113
        self.assertRaises(KnitCorrupt, index.add_records,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2114
                          [((b'tip',), b'fulltext,no-eol', (None, 0, 100), []),
2115
                           ((b'tip',), b'no-eol,line-delta', (None, 0, 100), [])])
2592.3.34 by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs.
2116
        self.assertEqual([], self.caught_entries)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2117
2118
4039.3.6 by John Arbash Meinel
Turn _split_by_prefix into a classmethod, and add direct tests.
2119
class TestKnitVersionedFiles(KnitTests):
2120
4039.3.7 by John Arbash Meinel
Some direct tests for _group_keys_for_io
2121
    def assertGroupKeysForIo(self, exp_groups, keys, non_local_keys,
2122
                             positions, _min_buffer_size=None):
2123
        kvf = self.make_test_knit()
2124
        if _min_buffer_size is None:
2125
            _min_buffer_size = knit._STREAM_MIN_BUFFER_SIZE
2126
        self.assertEqual(exp_groups, kvf._group_keys_for_io(keys,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2127
                                                            non_local_keys, positions,
2128
                                                            _min_buffer_size=_min_buffer_size))
4039.3.7 by John Arbash Meinel
Some direct tests for _group_keys_for_io
2129
4039.3.6 by John Arbash Meinel
Turn _split_by_prefix into a classmethod, and add direct tests.
2130
    def assertSplitByPrefix(self, expected_map, expected_prefix_order,
2131
                            keys):
2132
        split, prefix_order = KnitVersionedFiles._split_by_prefix(keys)
2133
        self.assertEqual(expected_map, split)
2134
        self.assertEqual(expected_prefix_order, prefix_order)
2135
4039.3.7 by John Arbash Meinel
Some direct tests for _group_keys_for_io
2136
    def test__group_keys_for_io(self):
7078.6.1 by Jelmer Vernooij
Fix corrupt knit handling on Python 3.
2137
        ft_detail = ('fulltext', False)
2138
        ld_detail = ('line-delta', False)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2139
        f_a = (b'f', b'a')
2140
        f_b = (b'f', b'b')
2141
        f_c = (b'f', b'c')
2142
        g_a = (b'g', b'a')
2143
        g_b = (b'g', b'b')
2144
        g_c = (b'g', b'c')
4039.3.7 by John Arbash Meinel
Some direct tests for _group_keys_for_io
2145
        positions = {
2146
            f_a: (ft_detail, (f_a, 0, 100), None),
2147
            f_b: (ld_detail, (f_b, 100, 21), f_a),
2148
            f_c: (ld_detail, (f_c, 180, 15), f_b),
2149
            g_a: (ft_detail, (g_a, 121, 35), None),
2150
            g_b: (ld_detail, (g_b, 156, 12), g_a),
2151
            g_c: (ld_detail, (g_c, 195, 13), g_a),
2152
            }
2153
        self.assertGroupKeysForIo([([f_a], set())],
2154
                                  [f_a], [], positions)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2155
        self.assertGroupKeysForIo([([f_a], {f_a})],
4039.3.7 by John Arbash Meinel
Some direct tests for _group_keys_for_io
2156
                                  [f_a], [f_a], positions)
2157
        self.assertGroupKeysForIo([([f_a, f_b], set([]))],
2158
                                  [f_a, f_b], [], positions)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2159
        self.assertGroupKeysForIo([([f_a, f_b], {f_b})],
4039.3.7 by John Arbash Meinel
Some direct tests for _group_keys_for_io
2160
                                  [f_a, f_b], [f_b], positions)
2161
        self.assertGroupKeysForIo([([f_a, f_b, g_a, g_b], set())],
2162
                                  [f_a, g_a, f_b, g_b], [], positions)
2163
        self.assertGroupKeysForIo([([f_a, f_b, g_a, g_b], set())],
2164
                                  [f_a, g_a, f_b, g_b], [], positions,
2165
                                  _min_buffer_size=150)
2166
        self.assertGroupKeysForIo([([f_a, f_b], set()), ([g_a, g_b], set())],
2167
                                  [f_a, g_a, f_b, g_b], [], positions,
2168
                                  _min_buffer_size=100)
2169
        self.assertGroupKeysForIo([([f_c], set()), ([g_b], set())],
2170
                                  [f_c, g_b], [], positions,
2171
                                  _min_buffer_size=125)
2172
        self.assertGroupKeysForIo([([g_b, f_c], set())],
2173
                                  [g_b, f_c], [], positions,
2174
                                  _min_buffer_size=125)
2175
4039.3.6 by John Arbash Meinel
Turn _split_by_prefix into a classmethod, and add direct tests.
2176
    def test__split_by_prefix(self):
6963.2.3 by Jelmer Vernooij
Fix some more tests.
2177
        self.assertSplitByPrefix({b'f': [(b'f', b'a'), (b'f', b'b')],
2178
                                  b'g': [(b'g', b'b'), (b'g', b'a')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2179
                                  }, [b'f', b'g'],
6963.2.3 by Jelmer Vernooij
Fix some more tests.
2180
                                 [(b'f', b'a'), (b'g', b'b'),
2181
                                  (b'g', b'a'), (b'f', b'b')])
2182
2183
        self.assertSplitByPrefix({b'f': [(b'f', b'a'), (b'f', b'b')],
2184
                                  b'g': [(b'g', b'b'), (b'g', b'a')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2185
                                  }, [b'f', b'g'],
6963.2.3 by Jelmer Vernooij
Fix some more tests.
2186
                                 [(b'f', b'a'), (b'f', b'b'),
2187
                                  (b'g', b'b'), (b'g', b'a')])
2188
2189
        self.assertSplitByPrefix({b'f': [(b'f', b'a'), (b'f', b'b')],
2190
                                  b'g': [(b'g', b'b'), (b'g', b'a')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2191
                                  }, [b'f', b'g'],
6963.2.3 by Jelmer Vernooij
Fix some more tests.
2192
                                 [(b'f', b'a'), (b'f', b'b'),
2193
                                  (b'g', b'b'), (b'g', b'a')])
2194
2195
        self.assertSplitByPrefix({b'f': [(b'f', b'a'), (b'f', b'b')],
2196
                                  b'g': [(b'g', b'b'), (b'g', b'a')],
2197
                                  b'': [(b'a',), (b'b',)]
7143.15.2 by Jelmer Vernooij
Run autopep8.
2198
                                  }, [b'f', b'g', b''],
6963.2.3 by Jelmer Vernooij
Fix some more tests.
2199
                                 [(b'f', b'a'), (b'g', b'b'),
2200
                                  (b'a',), (b'b',),
2201
                                  (b'g', b'a'), (b'f', b'b')])
4039.3.6 by John Arbash Meinel
Turn _split_by_prefix into a classmethod, and add direct tests.
2202
2203
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2204
class TestStacking(KnitTests):
2205
2206
    def get_basis_and_test_knit(self):
2207
        basis = self.make_test_knit(name='basis')
3350.8.2 by Robert Collins
stacked get_parent_map.
2208
        basis = RecordingVersionedFilesDecorator(basis)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2209
        test = self.make_test_knit(name='test')
2210
        test.add_fallback_versioned_files(basis)
2211
        return basis, test
2212
2213
    def test_add_fallback_versioned_files(self):
2214
        basis = self.make_test_knit(name='basis')
2215
        test = self.make_test_knit(name='test')
2216
        # It must not error; other tests test that the fallback is referred to
2217
        # when accessing data.
2218
        test.add_fallback_versioned_files(basis)
2219
2220
    def test_add_lines(self):
3350.8.9 by Robert Collins
define behaviour for add_lines with stacked storage.
2221
        # lines added to the test are not added to the basis
2222
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2223
        key = (b'foo',)
2224
        key_basis = (b'bar',)
2225
        key_cross_border = (b'quux',)
2226
        key_delta = (b'zaphod',)
2227
        test.add_lines(key, (), [b'foo\n'])
3350.8.9 by Robert Collins
define behaviour for add_lines with stacked storage.
2228
        self.assertEqual({}, basis.get_parent_map([key]))
2229
        # lines added to the test that reference across the stack do a
2230
        # fulltext.
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2231
        basis.add_lines(key_basis, (), [b'foo\n'])
3350.8.9 by Robert Collins
define behaviour for add_lines with stacked storage.
2232
        basis.calls = []
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2233
        test.add_lines(key_cross_border, (key_basis,), [b'foo\n'])
3350.8.9 by Robert Collins
define behaviour for add_lines with stacked storage.
2234
        self.assertEqual('fulltext', test._index.get_method(key_cross_border))
3830.3.10 by Martin Pool
Update more stacking effort tests
2235
        # we don't even need to look at the basis to see that this should be
2236
        # stored as a fulltext
2237
        self.assertEqual([], basis.calls)
3350.8.9 by Robert Collins
define behaviour for add_lines with stacked storage.
2238
        # Subsequent adds do delta.
3350.8.14 by Robert Collins
Review feedback.
2239
        basis.calls = []
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2240
        test.add_lines(key_delta, (key_cross_border,), [b'foo\n'])
3350.8.9 by Robert Collins
define behaviour for add_lines with stacked storage.
2241
        self.assertEqual('line-delta', test._index.get_method(key_delta))
2242
        self.assertEqual([], basis.calls)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2243
2244
    def test_annotate(self):
3350.8.8 by Robert Collins
Stacking and knits don't play nice for annotation yet.
2245
        # annotations from the test knit are answered without asking the basis
2246
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2247
        key = (b'foo',)
2248
        key_basis = (b'bar',)
2249
        test.add_lines(key, (), [b'foo\n'])
3350.8.8 by Robert Collins
Stacking and knits don't play nice for annotation yet.
2250
        details = test.annotate(key)
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2251
        self.assertEqual([(key, b'foo\n')], details)
3350.8.8 by Robert Collins
Stacking and knits don't play nice for annotation yet.
2252
        self.assertEqual([], basis.calls)
2253
        # But texts that are not in the test knit are looked for in the basis
2254
        # directly.
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2255
        basis.add_lines(key_basis, (), [b'foo\n', b'bar\n'])
3350.8.8 by Robert Collins
Stacking and knits don't play nice for annotation yet.
2256
        basis.calls = []
2257
        details = test.annotate(key_basis)
7143.15.2 by Jelmer Vernooij
Run autopep8.
2258
        self.assertEqual(
2259
            [(key_basis, b'foo\n'), (key_basis, b'bar\n')], details)
3350.9.1 by Robert Collins
Redo annotate more simply, using just the public interfaces for VersionedFiles.
2260
        # Not optimised to date:
2261
        # self.assertEqual([("annotate", key_basis)], basis.calls)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2262
        self.assertEqual([('get_parent_map', {key_basis}),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2263
                          ('get_parent_map', {key_basis}),
2264
                          ('get_record_stream', [key_basis], 'topological', True)],
2265
                         basis.calls)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2266
2267
    def test_check(self):
3517.4.19 by Martin Pool
Update test for knit.check() to expect it to recurse into fallback vfs
2268
        # At the moment checking a stacked knit does implicitly check the
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2269
        # fallback files.
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2270
        basis, test = self.get_basis_and_test_knit()
2271
        test.check()
2272
2273
    def test_get_parent_map(self):
3350.8.2 by Robert Collins
stacked get_parent_map.
2274
        # parents in the test knit are answered without asking the basis
2275
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2276
        key = (b'foo',)
2277
        key_basis = (b'bar',)
2278
        key_missing = (b'missing',)
3350.8.2 by Robert Collins
stacked get_parent_map.
2279
        test.add_lines(key, (), [])
2280
        parent_map = test.get_parent_map([key])
2281
        self.assertEqual({key: ()}, parent_map)
2282
        self.assertEqual([], basis.calls)
2283
        # But parents that are not in the test knit are looked for in the basis
2284
        basis.add_lines(key_basis, (), [])
2285
        basis.calls = []
2286
        parent_map = test.get_parent_map([key, key_basis, key_missing])
2287
        self.assertEqual({key: (),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2288
                          key_basis: ()}, parent_map)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2289
        self.assertEqual([("get_parent_map", {key_basis, key_missing})],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2290
                         basis.calls)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2291
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2292
    def test_get_record_stream_unordered_fulltexts(self):
2293
        # records from the test knit are answered without asking the basis:
2294
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2295
        key = (b'foo',)
2296
        key_basis = (b'bar',)
2297
        key_missing = (b'missing',)
2298
        test.add_lines(key, (), [b'foo\n'])
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2299
        records = list(test.get_record_stream([key], 'unordered', True))
2300
        self.assertEqual(1, len(records))
2301
        self.assertEqual([], basis.calls)
2302
        # Missing (from test knit) objects are retrieved from the basis:
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2303
        basis.add_lines(key_basis, (), [b'foo\n', b'bar\n'])
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2304
        basis.calls = []
2305
        records = list(test.get_record_stream([key_basis, key_missing],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2306
                                              'unordered', True))
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2307
        self.assertEqual(2, len(records))
2308
        calls = list(basis.calls)
2309
        for record in records:
2310
            self.assertSubset([record.key], (key_basis, key_missing))
2311
            if record.key == key_missing:
2312
                self.assertIsInstance(record, AbsentContentFactory)
2313
            else:
2314
                reference = list(basis.get_record_stream([key_basis],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2315
                                                         'unordered', True))[0]
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2316
                self.assertEqual(reference.key, record.key)
2317
                self.assertEqual(reference.sha1, record.sha1)
2318
                self.assertEqual(reference.storage_kind, record.storage_kind)
2319
                self.assertEqual(reference.get_bytes_as(reference.storage_kind),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2320
                                 record.get_bytes_as(record.storage_kind))
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2321
                self.assertEqual(reference.get_bytes_as('fulltext'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2322
                                 record.get_bytes_as('fulltext'))
3350.8.14 by Robert Collins
Review feedback.
2323
        # It's not strictly minimal, but it seems reasonable for now for it to
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2324
        # ask which fallbacks have which parents.
2325
        self.assertEqual([
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2326
            ("get_parent_map", {key_basis, key_missing}),
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2327
            ("get_record_stream", [key_basis], 'unordered', True)],
2328
            calls)
2329
2330
    def test_get_record_stream_ordered_fulltexts(self):
2331
        # ordering is preserved down into the fallback store.
2332
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2333
        key = (b'foo',)
2334
        key_basis = (b'bar',)
2335
        key_basis_2 = (b'quux',)
2336
        key_missing = (b'missing',)
2337
        test.add_lines(key, (key_basis,), [b'foo\n'])
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2338
        # Missing (from test knit) objects are retrieved from the basis:
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2339
        basis.add_lines(key_basis, (key_basis_2,), [b'foo\n', b'bar\n'])
2340
        basis.add_lines(key_basis_2, (), [b'quux\n'])
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2341
        basis.calls = []
2342
        # ask for in non-topological order
2343
        records = list(test.get_record_stream(
2344
            [key, key_basis, key_missing, key_basis_2], 'topological', True))
2345
        self.assertEqual(4, len(records))
2346
        results = []
2347
        for record in records:
2348
            self.assertSubset([record.key],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2349
                              (key_basis, key_missing, key_basis_2, key))
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2350
            if record.key == key_missing:
2351
                self.assertIsInstance(record, AbsentContentFactory)
2352
            else:
2353
                results.append((record.key, record.sha1, record.storage_kind,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2354
                                record.get_bytes_as('fulltext')))
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2355
        calls = list(basis.calls)
2356
        order = [record[0] for record in results]
2357
        self.assertEqual([key_basis_2, key_basis, key], order)
2358
        for result in results:
2359
            if result[0] == key:
2360
                source = test
2361
            else:
2362
                source = basis
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
2363
            record = next(source.get_record_stream([result[0]], 'unordered',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2364
                                                   True))
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2365
            self.assertEqual(record.key, result[0])
2366
            self.assertEqual(record.sha1, result[1])
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2367
            # We used to check that the storage kind matched, but actually it
2368
            # depends on whether it was sourced from the basis, or in a single
2369
            # group, because asking for full texts returns proxy objects to a
2370
            # _ContentMapGenerator object; so checking the kind is unneeded.
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2371
            self.assertEqual(record.get_bytes_as('fulltext'), result[3])
3350.8.14 by Robert Collins
Review feedback.
2372
        # It's not strictly minimal, but it seems reasonable for now for it to
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2373
        # ask which fallbacks have which parents.
6973.7.8 by Jelmer Vernooij
Fix more tests.
2374
        self.assertEqual(2, len(calls))
2375
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
2376
            ("get_parent_map", {key_basis, key_basis_2, key_missing}),
2377
            calls[0])
6997 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-f
2378
        # topological is requested from the fallback, because that is what
2379
        # was requested at the top level.
2380
        self.assertIn(
7143.15.2 by Jelmer Vernooij
Run autopep8.
2381
            calls[1], [
2382
                ("get_record_stream", [key_basis_2,
2383
                                       key_basis], 'topological', True),
6997 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-f
2384
                ("get_record_stream", [key_basis, key_basis_2], 'topological', True)])
3350.8.7 by Robert Collins
get_record_stream for fulltexts working (but note extreme memory use!).
2385
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2386
    def test_get_record_stream_unordered_deltas(self):
2387
        # records from the test knit are answered without asking the basis:
2388
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2389
        key = (b'foo',)
2390
        key_basis = (b'bar',)
2391
        key_missing = (b'missing',)
2392
        test.add_lines(key, (), [b'foo\n'])
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2393
        records = list(test.get_record_stream([key], 'unordered', False))
2394
        self.assertEqual(1, len(records))
2395
        self.assertEqual([], basis.calls)
2396
        # Missing (from test knit) objects are retrieved from the basis:
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2397
        basis.add_lines(key_basis, (), [b'foo\n', b'bar\n'])
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2398
        basis.calls = []
2399
        records = list(test.get_record_stream([key_basis, key_missing],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2400
                                              'unordered', False))
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2401
        self.assertEqual(2, len(records))
2402
        calls = list(basis.calls)
2403
        for record in records:
2404
            self.assertSubset([record.key], (key_basis, key_missing))
2405
            if record.key == key_missing:
2406
                self.assertIsInstance(record, AbsentContentFactory)
2407
            else:
2408
                reference = list(basis.get_record_stream([key_basis],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2409
                                                         'unordered', False))[0]
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2410
                self.assertEqual(reference.key, record.key)
2411
                self.assertEqual(reference.sha1, record.sha1)
2412
                self.assertEqual(reference.storage_kind, record.storage_kind)
2413
                self.assertEqual(reference.get_bytes_as(reference.storage_kind),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2414
                                 record.get_bytes_as(record.storage_kind))
3350.8.14 by Robert Collins
Review feedback.
2415
        # It's not strictly minimal, but it seems reasonable for now for it to
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2416
        # ask which fallbacks have which parents.
2417
        self.assertEqual([
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2418
            ("get_parent_map", {key_basis, key_missing}),
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2419
            ("get_record_stream", [key_basis], 'unordered', False)],
2420
            calls)
2421
2422
    def test_get_record_stream_ordered_deltas(self):
2423
        # ordering is preserved down into the fallback store.
2424
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2425
        key = (b'foo',)
2426
        key_basis = (b'bar',)
2427
        key_basis_2 = (b'quux',)
2428
        key_missing = (b'missing',)
2429
        test.add_lines(key, (key_basis,), [b'foo\n'])
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2430
        # Missing (from test knit) objects are retrieved from the basis:
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2431
        basis.add_lines(key_basis, (key_basis_2,), [b'foo\n', b'bar\n'])
2432
        basis.add_lines(key_basis_2, (), [b'quux\n'])
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2433
        basis.calls = []
2434
        # ask for in non-topological order
2435
        records = list(test.get_record_stream(
2436
            [key, key_basis, key_missing, key_basis_2], 'topological', False))
2437
        self.assertEqual(4, len(records))
2438
        results = []
2439
        for record in records:
2440
            self.assertSubset([record.key],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2441
                              (key_basis, key_missing, key_basis_2, key))
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2442
            if record.key == key_missing:
2443
                self.assertIsInstance(record, AbsentContentFactory)
2444
            else:
2445
                results.append((record.key, record.sha1, record.storage_kind,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2446
                                record.get_bytes_as(record.storage_kind)))
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2447
        calls = list(basis.calls)
2448
        order = [record[0] for record in results]
2449
        self.assertEqual([key_basis_2, key_basis, key], order)
2450
        for result in results:
2451
            if result[0] == key:
2452
                source = test
2453
            else:
2454
                source = basis
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
2455
            record = next(source.get_record_stream([result[0]], 'unordered',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2456
                                                   False))
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2457
            self.assertEqual(record.key, result[0])
2458
            self.assertEqual(record.sha1, result[1])
2459
            self.assertEqual(record.storage_kind, result[2])
7143.15.2 by Jelmer Vernooij
Run autopep8.
2460
            self.assertEqual(record.get_bytes_as(
2461
                record.storage_kind), result[3])
3350.8.14 by Robert Collins
Review feedback.
2462
        # It's not strictly minimal, but it seems reasonable for now for it to
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2463
        # ask which fallbacks have which parents.
2464
        self.assertEqual([
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2465
            ("get_parent_map", {key_basis, key_basis_2, key_missing}),
3350.8.6 by Robert Collins
get_record_stream stacking for delta access.
2466
            ("get_record_stream", [key_basis_2, key_basis], 'topological', False)],
2467
            calls)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2468
2469
    def test_get_sha1s(self):
3350.8.3 by Robert Collins
VF.get_sha1s needed changing to be stackable.
2470
        # sha1's in the test knit are answered without asking the basis
2471
        basis, test = self.get_basis_and_test_knit()
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2472
        key = (b'foo',)
2473
        key_basis = (b'bar',)
2474
        key_missing = (b'missing',)
2475
        test.add_lines(key, (), [b'foo\n'])
2476
        key_sha1sum = osutils.sha_string(b'foo\n')
3350.8.3 by Robert Collins
VF.get_sha1s needed changing to be stackable.
2477
        sha1s = test.get_sha1s([key])
2478
        self.assertEqual({key: key_sha1sum}, sha1s)
2479
        self.assertEqual([], basis.calls)
2480
        # But texts that are not in the test knit are looked for in the basis
2481
        # directly (rather than via text reconstruction) so that remote servers
2482
        # etc don't have to answer with full content.
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2483
        basis.add_lines(key_basis, (), [b'foo\n', b'bar\n'])
2484
        basis_sha1sum = osutils.sha_string(b'foo\nbar\n')
3350.8.3 by Robert Collins
VF.get_sha1s needed changing to be stackable.
2485
        basis.calls = []
2486
        sha1s = test.get_sha1s([key, key_missing, key_basis])
2487
        self.assertEqual({key: key_sha1sum,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2488
                          key_basis: basis_sha1sum}, sha1s)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2489
        self.assertEqual([("get_sha1s", {key_basis, key_missing})],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2490
                         basis.calls)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2491
2492
    def test_insert_record_stream(self):
3350.8.10 by Robert Collins
Stacked insert_record_stream.
2493
        # records are inserted as normal; insert_record_stream builds on
3350.8.14 by Robert Collins
Review feedback.
2494
        # add_lines, so a smoke test should be all that's needed:
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2495
        key_basis = (b'bar',)
2496
        key_delta = (b'zaphod',)
3350.8.10 by Robert Collins
Stacked insert_record_stream.
2497
        basis, test = self.get_basis_and_test_knit()
2498
        source = self.make_test_knit(name='source')
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2499
        basis.add_lines(key_basis, (), [b'foo\n'])
3350.8.10 by Robert Collins
Stacked insert_record_stream.
2500
        basis.calls = []
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2501
        source.add_lines(key_basis, (), [b'foo\n'])
2502
        source.add_lines(key_delta, (key_basis,), [b'bar\n'])
3350.8.10 by Robert Collins
Stacked insert_record_stream.
2503
        stream = source.get_record_stream([key_delta], 'unordered', False)
2504
        test.insert_record_stream(stream)
3830.3.9 by Martin Pool
Simplify kvf insert_record_stream; add has_key shorthand methods; update stacking effort tests
2505
        # XXX: this does somewhat too many calls in making sure of whether it
2506
        # has to recreate the full text.
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2507
        self.assertEqual([("get_parent_map", {key_basis}),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2508
                          ('get_parent_map', {key_basis}),
2509
                          ('get_record_stream', [key_basis], 'unordered', True)],
2510
                         basis.calls)
2511
        self.assertEqual({key_delta: (key_basis,)},
2512
                         test.get_parent_map([key_delta]))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2513
        self.assertEqual(b'bar\n', next(test.get_record_stream([key_delta],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2514
                                                               'unordered', True)).get_bytes_as('fulltext'))
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2515
2516
    def test_iter_lines_added_or_present_in_keys(self):
3350.8.5 by Robert Collins
Iter_lines_added_or_present_in_keys stacks.
2517
        # Lines from the basis are returned, and lines for a given key are only
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2518
        # returned once.
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2519
        key1 = (b'foo1',)
2520
        key2 = (b'foo2',)
3350.8.5 by Robert Collins
Iter_lines_added_or_present_in_keys stacks.
2521
        # all sources are asked for keys:
2522
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2523
        basis.add_lines(key1, (), [b"foo"])
3350.8.5 by Robert Collins
Iter_lines_added_or_present_in_keys stacks.
2524
        basis.calls = []
2525
        lines = list(test.iter_lines_added_or_present_in_keys([key1]))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2526
        self.assertEqual([(b"foo\n", key1)], lines)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2527
        self.assertEqual([("iter_lines_added_or_present_in_keys", {key1})],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2528
                         basis.calls)
3350.8.5 by Robert Collins
Iter_lines_added_or_present_in_keys stacks.
2529
        # keys in both are not duplicated:
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2530
        test.add_lines(key2, (), [b"bar\n"])
2531
        basis.add_lines(key2, (), [b"bar\n"])
3350.8.5 by Robert Collins
Iter_lines_added_or_present_in_keys stacks.
2532
        basis.calls = []
2533
        lines = list(test.iter_lines_added_or_present_in_keys([key2]))
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2534
        self.assertEqual([(b"bar\n", key2)], lines)
3350.8.5 by Robert Collins
Iter_lines_added_or_present_in_keys stacks.
2535
        self.assertEqual([], basis.calls)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2536
2537
    def test_keys(self):
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2538
        key1 = (b'foo1',)
2539
        key2 = (b'foo2',)
3350.8.4 by Robert Collins
Vf.keys() stacking support.
2540
        # all sources are asked for keys:
2541
        basis, test = self.get_basis_and_test_knit()
2542
        keys = test.keys()
2543
        self.assertEqual(set(), set(keys))
2544
        self.assertEqual([("keys",)], basis.calls)
2545
        # keys from a basis are returned:
2546
        basis.add_lines(key1, (), [])
2547
        basis.calls = []
2548
        keys = test.keys()
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2549
        self.assertEqual({key1}, set(keys))
3350.8.4 by Robert Collins
Vf.keys() stacking support.
2550
        self.assertEqual([("keys",)], basis.calls)
2551
        # keys in both are not duplicated:
2552
        test.add_lines(key2, (), [])
2553
        basis.add_lines(key2, (), [])
2554
        basis.calls = []
2555
        keys = test.keys()
2556
        self.assertEqual(2, len(keys))
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2557
        self.assertEqual({key1, key2}, set(keys))
3350.8.4 by Robert Collins
Vf.keys() stacking support.
2558
        self.assertEqual([("keys",)], basis.calls)
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2559
2560
    def test_add_mpdiffs(self):
3350.8.11 by Robert Collins
Stacked add_mpdiffs.
2561
        # records are inserted as normal; add_mpdiff builds on
3350.8.14 by Robert Collins
Review feedback.
2562
        # add_lines, so a smoke test should be all that's needed:
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2563
        key_basis = (b'bar',)
2564
        key_delta = (b'zaphod',)
3350.8.11 by Robert Collins
Stacked add_mpdiffs.
2565
        basis, test = self.get_basis_and_test_knit()
2566
        source = self.make_test_knit(name='source')
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2567
        basis.add_lines(key_basis, (), [b'foo\n'])
3350.8.11 by Robert Collins
Stacked add_mpdiffs.
2568
        basis.calls = []
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2569
        source.add_lines(key_basis, (), [b'foo\n'])
2570
        source.add_lines(key_delta, (key_basis,), [b'bar\n'])
3350.8.11 by Robert Collins
Stacked add_mpdiffs.
2571
        diffs = source.make_mpdiffs([key_delta])
2572
        test.add_mpdiffs([(key_delta, (key_basis,),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2573
                           source.get_sha1s([key_delta])[key_delta], diffs[0])])
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2574
        self.assertEqual([("get_parent_map", {key_basis}),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2575
                          ('get_record_stream', [key_basis], 'unordered', True), ],
2576
                         basis.calls)
2577
        self.assertEqual({key_delta: (key_basis,)},
2578
                         test.get_parent_map([key_delta]))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2579
        self.assertEqual(b'bar\n', next(test.get_record_stream([key_delta],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2580
                                                               'unordered', True)).get_bytes_as('fulltext'))
3350.8.1 by Robert Collins
KnitVersionedFiles.add_fallback_versioned_files exists.
2581
2582
    def test_make_mpdiffs(self):
3350.8.12 by Robert Collins
Stacked make_mpdiffs.
2583
        # Generating an mpdiff across a stacking boundary should detect parent
2584
        # texts regions.
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2585
        key = (b'foo',)
2586
        key_left = (b'bar',)
2587
        key_right = (b'zaphod',)
3350.8.12 by Robert Collins
Stacked make_mpdiffs.
2588
        basis, test = self.get_basis_and_test_knit()
6985 by Jelmer Vernooij
Merge lp:~jelmer/brz/python3-weave-fmt.
2589
        basis.add_lines(key_left, (), [b'bar\n'])
2590
        basis.add_lines(key_right, (), [b'zaphod\n'])
3350.8.12 by Robert Collins
Stacked make_mpdiffs.
2591
        basis.calls = []
2592
        test.add_lines(key, (key_left, key_right),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2593
                       [b'bar\n', b'foo\n', b'zaphod\n'])
3350.8.12 by Robert Collins
Stacked make_mpdiffs.
2594
        diffs = test.make_mpdiffs([key])
2595
        self.assertEqual([
2596
            multiparent.MultiParent([multiparent.ParentText(0, 0, 0, 1),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2597
                                     multiparent.NewText([b'foo\n']),
2598
                                     multiparent.ParentText(1, 0, 2, 1)])],
2599
                         diffs)
3830.3.10 by Martin Pool
Update more stacking effort tests
2600
        self.assertEqual(3, len(basis.calls))
3350.8.12 by Robert Collins
Stacked make_mpdiffs.
2601
        self.assertEqual([
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2602
            ("get_parent_map", {key_left, key_right}),
2603
            ("get_parent_map", {key_left, key_right}),
3350.8.12 by Robert Collins
Stacked make_mpdiffs.
2604
            ],
3830.3.10 by Martin Pool
Update more stacking effort tests
2605
            basis.calls[:-1])
2606
        last_call = basis.calls[-1]
3350.8.14 by Robert Collins
Review feedback.
2607
        self.assertEqual('get_record_stream', last_call[0])
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2608
        self.assertEqual({key_left, key_right}, set(last_call[1]))
4537.3.5 by John Arbash Meinel
Fix 3 tests that assumed it would use 'unordered' in the fallback,
2609
        self.assertEqual('topological', last_call[2])
3350.8.14 by Robert Collins
Review feedback.
2610
        self.assertEqual(True, last_call[3])
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2611
2612
2613
class TestNetworkBehaviour(KnitTests):
2614
    """Tests for getting data out of/into knits over the network."""
2615
2616
    def test_include_delta_closure_generates_a_knit_delta_closure(self):
2617
        vf = self.make_test_knit(name='test')
2618
        # put in three texts, giving ft, delta, delta
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2619
        vf.add_lines((b'base',), (), [b'base\n', b'content\n'])
2620
        vf.add_lines((b'd1',), ((b'base',),), [b'd1\n'])
2621
        vf.add_lines((b'd2',), ((b'd1',),), [b'd2\n'])
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2622
        # But heuristics could interfere, so check what happened:
2623
        self.assertEqual(['knit-ft-gz', 'knit-delta-gz', 'knit-delta-gz'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2624
                         [record.storage_kind for record in
2625
                          vf.get_record_stream([(b'base',), (b'd1',), (b'd2',)],
2626
                                               'topological', False)])
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2627
        # generate a stream of just the deltas include_delta_closure=True,
2628
        # serialise to the network, and check that we get a delta closure on the wire.
7143.15.2 by Jelmer Vernooij
Run autopep8.
2629
        stream = vf.get_record_stream(
2630
            [(b'd1',), (b'd2',)], 'topological', True)
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2631
        netb = [record.get_bytes_as(record.storage_kind) for record in stream]
2632
        # The first bytes should be a memo from _ContentMapGenerator, and the
2633
        # second bytes should be empty (because its a API proxy not something
2634
        # for wire serialisation.
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2635
        self.assertEqual(b'', netb[1])
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2636
        bytes = netb[0]
2637
        kind, line_end = network_bytes_to_kind_and_offset(bytes)
2638
        self.assertEqual('knit-delta-closure', kind)
2639
2640
2641
class TestContentMapGenerator(KnitTests):
2642
    """Tests for ContentMapGenerator"""
2643
2644
    def test_get_record_stream_gives_records(self):
2645
        vf = self.make_test_knit(name='test')
2646
        # put in three texts, giving ft, delta, delta
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2647
        vf.add_lines((b'base',), (), [b'base\n', b'content\n'])
2648
        vf.add_lines((b'd1',), ((b'base',),), [b'd1\n'])
2649
        vf.add_lines((b'd2',), ((b'd1',),), [b'd2\n'])
2650
        keys = [(b'd1',), (b'd2',)]
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2651
        generator = _VFContentMapGenerator(vf, keys,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2652
                                           global_map=vf.get_parent_map(keys))
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2653
        for record in generator.get_record_stream():
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2654
            if record.key == (b'd1',):
2655
                self.assertEqual(b'd1\n', record.get_bytes_as('fulltext'))
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2656
            else:
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2657
                self.assertEqual(b'd2\n', record.get_bytes_as('fulltext'))
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2658
2659
    def test_get_record_stream_kinds_are_raw(self):
2660
        vf = self.make_test_knit(name='test')
2661
        # put in three texts, giving ft, delta, delta
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2662
        vf.add_lines((b'base',), (), [b'base\n', b'content\n'])
2663
        vf.add_lines((b'd1',), ((b'base',),), [b'd1\n'])
2664
        vf.add_lines((b'd2',), ((b'd1',),), [b'd2\n'])
2665
        keys = [(b'base',), (b'd1',), (b'd2',)]
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2666
        generator = _VFContentMapGenerator(vf, keys,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2667
                                           global_map=vf.get_parent_map(keys))
6973.14.2 by Jelmer Vernooij
Fix some knit tests.
2668
        kinds = {(b'base',): 'knit-delta-closure',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2669
                 (b'd1',): 'knit-delta-closure-ref',
2670
                 (b'd2',): 'knit-delta-closure-ref',
2671
                 }
4005.3.6 by Robert Collins
Support delta_closure=True with NetworkRecordStream to transmit deltas over the wire when full text extraction is required on the far end.
2672
        for record in generator.get_record_stream():
2673
            self.assertEqual(kinds[record.key], record.storage_kind)