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