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
|
|
15 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
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 |
22 |
import sha |
|
|
2484.1.17
by John Arbash Meinel
Workaround for Pyrex <0.9.5 and python >=2.5 incompatibilities. |
23 |
import sys |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
24 |
|
|
2196.2.5
by John Arbash Meinel
Add an exception class when the knit index storage method is unknown, and properly test for it |
25 |
from bzrlib import ( |
26 |
errors, |
|
|
2484.1.5
by John Arbash Meinel
Simplistic implementations of custom parsers for options and parents |
27 |
generate_ids, |
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
28 |
knit, |
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
29 |
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 |
30 |
)
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
31 |
from bzrlib.errors import ( |
32 |
RevisionAlreadyPresent, |
|
33 |
KnitHeaderError, |
|
34 |
RevisionNotPresent, |
|
35 |
NoSuchFile, |
|
36 |
)
|
|
|
2592.3.1
by Robert Collins
Allow giving KnitVersionedFile an index object to use rather than implicitly creating one. |
37 |
from bzrlib.index import * |
|
1684.3.3
by Robert Collins
Add a special cased weaves to knit converter. |
38 |
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. |
39 |
AnnotatedKnitContent, |
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
40 |
DATA_SUFFIX, |
41 |
INDEX_SUFFIX, |
|
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
42 |
KnitContent, |
|
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. |
43 |
KnitGraphIndex, |
|
1684.3.3
by Robert Collins
Add a special cased weaves to knit converter. |
44 |
KnitVersionedFile, |
45 |
KnitPlainFactory, |
|
46 |
KnitAnnotateFactory, |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
47 |
_KnitAccess, |
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
48 |
_KnitData, |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
49 |
_KnitIndex, |
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
50 |
make_file_knit, |
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
51 |
_PackAccess, |
|
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. |
52 |
PlainKnitContent, |
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
53 |
_StreamAccess, |
54 |
_StreamIndex, |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
55 |
WeaveToKnit, |
|
2520.4.41
by Aaron Bentley
Accelerate mpdiff generation |
56 |
KnitSequenceMatcher, |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
57 |
)
|
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
58 |
from bzrlib.osutils import split_lines |
|
3316.2.13
by Robert Collins
* ``VersionedFile.annotate_iter`` is deprecated. While in principal this |
59 |
from bzrlib.symbol_versioning import one_four |
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
60 |
from bzrlib.tests import ( |
61 |
Feature, |
|
62 |
TestCase, |
|
63 |
TestCaseWithMemoryTransport, |
|
64 |
TestCaseWithTransport, |
|
65 |
)
|
|
|
2745.5.3
by Robert Collins
* Move transport logging into a new transport class |
66 |
from bzrlib.transport import get_transport |
|
1563.2.13
by Robert Collins
InterVersionedFile implemented. |
67 |
from bzrlib.transport.memory import MemoryTransport |
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
68 |
from bzrlib.tuned_gzip import GzipFile |
|
2535.3.15
by Andrew Bennetts
Add KnitVersionedFile.get_stream_as_bytes, start smart implementation of RemoteRepository.get_data_stream. |
69 |
from bzrlib.util import bencode |
|
1684.3.3
by Robert Collins
Add a special cased weaves to knit converter. |
70 |
from bzrlib.weave import Weave |
71 |
||
72 |
||
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
73 |
class _CompiledKnitFeature(Feature): |
74 |
||
75 |
def _probe(self): |
|
76 |
try: |
|
|
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 |
77 |
import bzrlib._knit_load_data_c |
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
78 |
except ImportError: |
79 |
return False |
|
80 |
return True |
|
81 |
||
82 |
def feature_name(self): |
|
|
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 |
83 |
return 'bzrlib._knit_load_data_c' |
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
84 |
|
85 |
CompiledKnitFeature = _CompiledKnitFeature() |
|
86 |
||
87 |
||
|
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. |
88 |
class KnitContentTestsMixin(object): |
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
89 |
|
90 |
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. |
91 |
content = self._make_content([]) |
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
92 |
|
93 |
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. |
94 |
content = self._make_content([]) |
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
95 |
self.assertEqual(content.text(), []) |
96 |
||
|
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. |
97 |
content = self._make_content([("origin1", "text1"), ("origin2", "text2")]) |
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
98 |
self.assertEqual(content.text(), ["text1", "text2"]) |
99 |
||
|
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. |
100 |
def test_copy(self): |
101 |
content = self._make_content([("origin1", "text1"), ("origin2", "text2")]) |
|
102 |
copy = content.copy() |
|
103 |
self.assertIsInstance(copy, content.__class__) |
|
104 |
self.assertEqual(copy.annotate(), content.annotate()) |
|
105 |
||
106 |
def assertDerivedBlocksEqual(self, source, target, noeol=False): |
|
107 |
"""Assert that the derived matching blocks match real output""" |
|
108 |
source_lines = source.splitlines(True) |
|
109 |
target_lines = target.splitlines(True) |
|
110 |
def nl(line): |
|
111 |
if noeol and not line.endswith('\n'): |
|
112 |
return line + '\n' |
|
113 |
else: |
|
114 |
return line |
|
115 |
source_content = self._make_content([(None, nl(l)) for l in source_lines]) |
|
116 |
target_content = self._make_content([(None, nl(l)) for l in target_lines]) |
|
117 |
line_delta = source_content.line_delta(target_content) |
|
118 |
delta_blocks = list(KnitContent.get_line_delta_blocks(line_delta, |
|
119 |
source_lines, target_lines)) |
|
120 |
matcher = KnitSequenceMatcher(None, source_lines, target_lines) |
|
121 |
matcher_blocks = list(list(matcher.get_matching_blocks())) |
|
122 |
self.assertEqual(matcher_blocks, delta_blocks) |
|
123 |
||
124 |
def test_get_line_delta_blocks(self): |
|
125 |
self.assertDerivedBlocksEqual('a\nb\nc\n', 'q\nc\n') |
|
126 |
self.assertDerivedBlocksEqual(TEXT_1, TEXT_1) |
|
127 |
self.assertDerivedBlocksEqual(TEXT_1, TEXT_1A) |
|
128 |
self.assertDerivedBlocksEqual(TEXT_1, TEXT_1B) |
|
129 |
self.assertDerivedBlocksEqual(TEXT_1B, TEXT_1A) |
|
130 |
self.assertDerivedBlocksEqual(TEXT_1A, TEXT_1B) |
|
131 |
self.assertDerivedBlocksEqual(TEXT_1A, '') |
|
132 |
self.assertDerivedBlocksEqual('', TEXT_1A) |
|
133 |
self.assertDerivedBlocksEqual('', '') |
|
134 |
self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd') |
|
135 |
||
136 |
def test_get_line_delta_blocks_noeol(self): |
|
137 |
"""Handle historical knit deltas safely |
|
138 |
||
139 |
Some existing knit deltas don't consider the last line to differ
|
|
140 |
when the only difference whether it has a final newline.
|
|
141 |
||
142 |
New knit deltas appear to always consider the last line to differ
|
|
143 |
in this case.
|
|
144 |
"""
|
|
145 |
self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd\n', noeol=True) |
|
146 |
self.assertDerivedBlocksEqual('a\nb\nc\nd\n', 'a\nb\nc', noeol=True) |
|
147 |
self.assertDerivedBlocksEqual('a\nb\nc\n', 'a\nb\nc', noeol=True) |
|
148 |
self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\n', noeol=True) |
|
149 |
||
150 |
||
151 |
class TestPlainKnitContent(TestCase, KnitContentTestsMixin): |
|
152 |
||
153 |
def _make_content(self, lines): |
|
154 |
annotated_content = AnnotatedKnitContent(lines) |
|
155 |
return PlainKnitContent(annotated_content.text(), 'bogus') |
|
156 |
||
157 |
def test_annotate(self): |
|
158 |
content = self._make_content([]) |
|
159 |
self.assertEqual(content.annotate(), []) |
|
160 |
||
161 |
content = self._make_content([("origin1", "text1"), ("origin2", "text2")]) |
|
162 |
self.assertEqual(content.annotate(), |
|
163 |
[("bogus", "text1"), ("bogus", "text2")]) |
|
164 |
||
165 |
def test_line_delta(self): |
|
166 |
content1 = self._make_content([("", "a"), ("", "b")]) |
|
167 |
content2 = self._make_content([("", "a"), ("", "a"), ("", "c")]) |
|
168 |
self.assertEqual(content1.line_delta(content2), |
|
169 |
[(1, 2, 2, ["a", "c"])]) |
|
170 |
||
171 |
def test_line_delta_iter(self): |
|
172 |
content1 = self._make_content([("", "a"), ("", "b")]) |
|
173 |
content2 = self._make_content([("", "a"), ("", "a"), ("", "c")]) |
|
174 |
it = content1.line_delta_iter(content2) |
|
175 |
self.assertEqual(it.next(), (1, 2, 2, ["a", "c"])) |
|
176 |
self.assertRaises(StopIteration, it.next) |
|
177 |
||
178 |
||
179 |
class TestAnnotatedKnitContent(TestCase, KnitContentTestsMixin): |
|
180 |
||
181 |
def _make_content(self, lines): |
|
182 |
return AnnotatedKnitContent(lines) |
|
183 |
||
184 |
def test_annotate(self): |
|
185 |
content = self._make_content([]) |
|
186 |
self.assertEqual(content.annotate(), []) |
|
187 |
||
188 |
content = self._make_content([("origin1", "text1"), ("origin2", "text2")]) |
|
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
189 |
self.assertEqual(content.annotate(), |
190 |
[("origin1", "text1"), ("origin2", "text2")]) |
|
191 |
||
192 |
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. |
193 |
content1 = self._make_content([("", "a"), ("", "b")]) |
194 |
content2 = self._make_content([("", "a"), ("", "a"), ("", "c")]) |
|
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
195 |
self.assertEqual(content1.line_delta(content2), |
196 |
[(1, 2, 2, [("", "a"), ("", "c")])]) |
|
197 |
||
198 |
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. |
199 |
content1 = self._make_content([("", "a"), ("", "b")]) |
200 |
content2 = self._make_content([("", "a"), ("", "a"), ("", "c")]) |
|
|
2151.1.1
by John Arbash Meinel
(Dmitry Vasiliev) Tune KnitContent and add tests |
201 |
it = content1.line_delta_iter(content2) |
202 |
self.assertEqual(it.next(), (1, 2, 2, [("", "a"), ("", "c")])) |
|
203 |
self.assertRaises(StopIteration, it.next) |
|
204 |
||
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
205 |
|
206 |
class MockTransport(object): |
|
207 |
||
208 |
def __init__(self, file_lines=None): |
|
209 |
self.file_lines = file_lines |
|
210 |
self.calls = [] |
|
|
2196.2.3
by John Arbash Meinel
Update tests and code to pass after merging bzr.dev |
211 |
# We have no base directory for the MockTransport
|
212 |
self.base = '' |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
213 |
|
214 |
def get(self, filename): |
|
215 |
if self.file_lines is None: |
|
216 |
raise NoSuchFile(filename) |
|
217 |
else: |
|
218 |
return StringIO("\n".join(self.file_lines)) |
|
219 |
||
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
220 |
def readv(self, relpath, offsets): |
221 |
fp = self.get(relpath) |
|
222 |
for offset, size in offsets: |
|
223 |
fp.seek(offset) |
|
224 |
yield offset, fp.read(size) |
|
225 |
||
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
226 |
def __getattr__(self, name): |
227 |
def queue_call(*args, **kwargs): |
|
228 |
self.calls.append((name, args, kwargs)) |
|
229 |
return queue_call |
|
230 |
||
231 |
||
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
232 |
class KnitRecordAccessTestsMixin(object): |
233 |
"""Tests for getting and putting knit records.""" |
|
234 |
||
235 |
def assertAccessExists(self, access): |
|
236 |
"""Ensure the data area for access has been initialised/exists.""" |
|
237 |
raise NotImplementedError(self.assertAccessExists) |
|
238 |
||
239 |
def test_add_raw_records(self): |
|
240 |
"""Add_raw_records adds records retrievable later.""" |
|
241 |
access = self.get_access() |
|
242 |
memos = access.add_raw_records([10], '1234567890') |
|
243 |
self.assertEqual(['1234567890'], list(access.get_raw_records(memos))) |
|
|
2592.3.67
by Robert Collins
More tests for bzrlib.knit._PackAccess. |
244 |
|
245 |
def test_add_several_raw_records(self): |
|
246 |
"""add_raw_records with many records and read some back.""" |
|
247 |
access = self.get_access() |
|
248 |
memos = access.add_raw_records([10, 2, 5], '12345678901234567') |
|
249 |
self.assertEqual(['1234567890', '12', '34567'], |
|
250 |
list(access.get_raw_records(memos))) |
|
251 |
self.assertEqual(['1234567890'], |
|
252 |
list(access.get_raw_records(memos[0:1]))) |
|
253 |
self.assertEqual(['12'], |
|
254 |
list(access.get_raw_records(memos[1:2]))) |
|
255 |
self.assertEqual(['34567'], |
|
256 |
list(access.get_raw_records(memos[2:3]))) |
|
257 |
self.assertEqual(['1234567890', '34567'], |
|
258 |
list(access.get_raw_records(memos[0:1] + memos[2:3]))) |
|
259 |
||
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
260 |
def test_create(self): |
261 |
"""create() should make a file on disk.""" |
|
262 |
access = self.get_access() |
|
263 |
access.create() |
|
264 |
self.assertAccessExists(access) |
|
265 |
||
266 |
def test_open_file(self): |
|
267 |
"""open_file never errors.""" |
|
268 |
access = self.get_access() |
|
269 |
access.open_file() |
|
270 |
||
271 |
||
272 |
class TestKnitKnitAccess(TestCaseWithMemoryTransport, KnitRecordAccessTestsMixin): |
|
273 |
"""Tests for the .kndx implementation.""" |
|
274 |
||
275 |
def assertAccessExists(self, access): |
|
276 |
self.assertNotEqual(None, access.open_file()) |
|
277 |
||
278 |
def get_access(self): |
|
279 |
"""Get a .knit style access instance.""" |
|
280 |
access = _KnitAccess(self.get_transport(), "foo.knit", None, None, |
|
281 |
False, False) |
|
282 |
return access |
|
283 |
||
284 |
||
285 |
class TestPackKnitAccess(TestCaseWithMemoryTransport, KnitRecordAccessTestsMixin): |
|
286 |
"""Tests for the pack based access.""" |
|
287 |
||
288 |
def assertAccessExists(self, access): |
|
289 |
# as pack based access has no backing unless an index maps data, this
|
|
290 |
# is a no-op.
|
|
291 |
pass
|
|
292 |
||
293 |
def get_access(self): |
|
|
2592.3.67
by Robert Collins
More tests for bzrlib.knit._PackAccess. |
294 |
return self._get_access()[0] |
295 |
||
296 |
def _get_access(self, packname='packfile', index='FOO'): |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
297 |
transport = self.get_transport() |
298 |
def write_data(bytes): |
|
|
2592.3.67
by Robert Collins
More tests for bzrlib.knit._PackAccess. |
299 |
transport.append_bytes(packname, bytes) |
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
300 |
writer = pack.ContainerWriter(write_data) |
301 |
writer.begin() |
|
|
2592.3.67
by Robert Collins
More tests for bzrlib.knit._PackAccess. |
302 |
indices = {index:(transport, packname)} |
303 |
access = _PackAccess(indices, writer=(writer, index)) |
|
304 |
return access, writer |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
305 |
|
|
2592.3.67
by Robert Collins
More tests for bzrlib.knit._PackAccess. |
306 |
def test_read_from_several_packs(self): |
307 |
access, writer = self._get_access() |
|
308 |
memos = [] |
|
309 |
memos.extend(access.add_raw_records([10], '1234567890')) |
|
310 |
writer.end() |
|
311 |
access, writer = self._get_access('pack2', 'FOOBAR') |
|
312 |
memos.extend(access.add_raw_records([5], '12345')) |
|
313 |
writer.end() |
|
314 |
access, writer = self._get_access('pack3', 'BAZ') |
|
315 |
memos.extend(access.add_raw_records([5], 'alpha')) |
|
316 |
writer.end() |
|
317 |
transport = self.get_transport() |
|
318 |
access = _PackAccess({"FOO":(transport, 'packfile'), |
|
319 |
"FOOBAR":(transport, 'pack2'), |
|
320 |
"BAZ":(transport, 'pack3')}) |
|
321 |
self.assertEqual(['1234567890', '12345', 'alpha'], |
|
322 |
list(access.get_raw_records(memos))) |
|
323 |
self.assertEqual(['1234567890'], |
|
324 |
list(access.get_raw_records(memos[0:1]))) |
|
325 |
self.assertEqual(['12345'], |
|
326 |
list(access.get_raw_records(memos[1:2]))) |
|
327 |
self.assertEqual(['alpha'], |
|
328 |
list(access.get_raw_records(memos[2:3]))) |
|
329 |
self.assertEqual(['1234567890', 'alpha'], |
|
330 |
list(access.get_raw_records(memos[0:1] + memos[2:3]))) |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
331 |
|
|
2592.3.70
by Robert Collins
Allow setting a writer after creating a knit._PackAccess object. |
332 |
def test_set_writer(self): |
333 |
"""The writer should be settable post construction.""" |
|
334 |
access = _PackAccess({}) |
|
335 |
transport = self.get_transport() |
|
336 |
packname = 'packfile' |
|
337 |
index = 'foo' |
|
338 |
def write_data(bytes): |
|
339 |
transport.append_bytes(packname, bytes) |
|
340 |
writer = pack.ContainerWriter(write_data) |
|
341 |
writer.begin() |
|
342 |
access.set_writer(writer, index, (transport, packname)) |
|
343 |
memos = access.add_raw_records([10], '1234567890') |
|
344 |
writer.end() |
|
345 |
self.assertEqual(['1234567890'], list(access.get_raw_records(memos))) |
|
346 |
||
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
347 |
|
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
348 |
class LowLevelKnitDataTests(TestCase): |
349 |
||
350 |
def create_gz_content(self, text): |
|
351 |
sio = StringIO() |
|
352 |
gz_file = gzip.GzipFile(mode='wb', fileobj=sio) |
|
353 |
gz_file.write(text) |
|
354 |
gz_file.close() |
|
355 |
return sio.getvalue() |
|
356 |
||
357 |
def test_valid_knit_data(self): |
|
358 |
sha1sum = sha.new('foo\nbar\n').hexdigest() |
|
359 |
gz_txt = self.create_gz_content('version rev-id-1 2 %s\n' |
|
360 |
'foo\n' |
|
361 |
'bar\n' |
|
362 |
'end rev-id-1\n' |
|
363 |
% (sha1sum,)) |
|
364 |
transport = MockTransport([gz_txt]) |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
365 |
access = _KnitAccess(transport, 'filename', None, None, False, False) |
366 |
data = _KnitData(access=access) |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
367 |
records = [('rev-id-1', (None, 0, len(gz_txt)))] |
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
368 |
|
369 |
contents = data.read_records(records) |
|
370 |
self.assertEqual({'rev-id-1':(['foo\n', 'bar\n'], sha1sum)}, contents) |
|
371 |
||
372 |
raw_contents = list(data.read_records_iter_raw(records)) |
|
373 |
self.assertEqual([('rev-id-1', gz_txt)], raw_contents) |
|
374 |
||
375 |
def test_not_enough_lines(self): |
|
376 |
sha1sum = sha.new('foo\n').hexdigest() |
|
377 |
# record says 2 lines data says 1
|
|
378 |
gz_txt = self.create_gz_content('version rev-id-1 2 %s\n' |
|
379 |
'foo\n' |
|
380 |
'end rev-id-1\n' |
|
381 |
% (sha1sum,)) |
|
382 |
transport = MockTransport([gz_txt]) |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
383 |
access = _KnitAccess(transport, 'filename', None, None, False, False) |
384 |
data = _KnitData(access=access) |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
385 |
records = [('rev-id-1', (None, 0, len(gz_txt)))] |
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
386 |
self.assertRaises(errors.KnitCorrupt, data.read_records, records) |
387 |
||
388 |
# read_records_iter_raw won't detect that sort of mismatch/corruption
|
|
389 |
raw_contents = list(data.read_records_iter_raw(records)) |
|
390 |
self.assertEqual([('rev-id-1', gz_txt)], raw_contents) |
|
391 |
||
392 |
def test_too_many_lines(self): |
|
393 |
sha1sum = sha.new('foo\nbar\n').hexdigest() |
|
394 |
# record says 1 lines data says 2
|
|
395 |
gz_txt = self.create_gz_content('version rev-id-1 1 %s\n' |
|
396 |
'foo\n' |
|
397 |
'bar\n' |
|
398 |
'end rev-id-1\n' |
|
399 |
% (sha1sum,)) |
|
400 |
transport = MockTransport([gz_txt]) |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
401 |
access = _KnitAccess(transport, 'filename', None, None, False, False) |
402 |
data = _KnitData(access=access) |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
403 |
records = [('rev-id-1', (None, 0, len(gz_txt)))] |
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
404 |
self.assertRaises(errors.KnitCorrupt, data.read_records, records) |
405 |
||
406 |
# read_records_iter_raw won't detect that sort of mismatch/corruption
|
|
407 |
raw_contents = list(data.read_records_iter_raw(records)) |
|
408 |
self.assertEqual([('rev-id-1', gz_txt)], raw_contents) |
|
409 |
||
410 |
def test_mismatched_version_id(self): |
|
411 |
sha1sum = sha.new('foo\nbar\n').hexdigest() |
|
412 |
gz_txt = self.create_gz_content('version rev-id-1 2 %s\n' |
|
413 |
'foo\n' |
|
414 |
'bar\n' |
|
415 |
'end rev-id-1\n' |
|
416 |
% (sha1sum,)) |
|
417 |
transport = MockTransport([gz_txt]) |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
418 |
access = _KnitAccess(transport, 'filename', None, None, False, False) |
419 |
data = _KnitData(access=access) |
|
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
420 |
# We are asking for rev-id-2, but the data is rev-id-1
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
421 |
records = [('rev-id-2', (None, 0, len(gz_txt)))] |
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
422 |
self.assertRaises(errors.KnitCorrupt, data.read_records, records) |
423 |
||
424 |
# read_records_iter_raw will notice if we request the wrong version.
|
|
425 |
self.assertRaises(errors.KnitCorrupt, list, |
|
426 |
data.read_records_iter_raw(records)) |
|
427 |
||
428 |
def test_uncompressed_data(self): |
|
429 |
sha1sum = sha.new('foo\nbar\n').hexdigest() |
|
430 |
txt = ('version rev-id-1 2 %s\n' |
|
431 |
'foo\n' |
|
432 |
'bar\n' |
|
433 |
'end rev-id-1\n' |
|
434 |
% (sha1sum,)) |
|
435 |
transport = MockTransport([txt]) |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
436 |
access = _KnitAccess(transport, 'filename', None, None, False, False) |
437 |
data = _KnitData(access=access) |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
438 |
records = [('rev-id-1', (None, 0, len(txt)))] |
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
439 |
|
440 |
# We don't have valid gzip data ==> corrupt
|
|
441 |
self.assertRaises(errors.KnitCorrupt, data.read_records, records) |
|
442 |
||
443 |
# read_records_iter_raw will notice the bad data
|
|
444 |
self.assertRaises(errors.KnitCorrupt, list, |
|
445 |
data.read_records_iter_raw(records)) |
|
446 |
||
447 |
def test_corrupted_data(self): |
|
448 |
sha1sum = sha.new('foo\nbar\n').hexdigest() |
|
449 |
gz_txt = self.create_gz_content('version rev-id-1 2 %s\n' |
|
450 |
'foo\n' |
|
451 |
'bar\n' |
|
452 |
'end rev-id-1\n' |
|
453 |
% (sha1sum,)) |
|
454 |
# Change 2 bytes in the middle to \xff
|
|
455 |
gz_txt = gz_txt[:10] + '\xff\xff' + gz_txt[12:] |
|
456 |
transport = MockTransport([gz_txt]) |
|
|
2592.3.66
by Robert Collins
Allow adaption of KnitData to pack files. |
457 |
access = _KnitAccess(transport, 'filename', None, None, False, False) |
458 |
data = _KnitData(access=access) |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
459 |
records = [('rev-id-1', (None, 0, len(gz_txt)))] |
|
2329.1.1
by John Arbash Meinel
Update _KnitData parser to raise more helpful errors when it detects corruption. |
460 |
|
461 |
self.assertRaises(errors.KnitCorrupt, data.read_records, records) |
|
462 |
||
463 |
# read_records_iter_raw will notice if we request the wrong version.
|
|
464 |
self.assertRaises(errors.KnitCorrupt, list, |
|
465 |
data.read_records_iter_raw(records)) |
|
466 |
||
467 |
||
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
468 |
class LowLevelKnitIndexTests(TestCase): |
469 |
||
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
470 |
def get_knit_index(self, *args, **kwargs): |
471 |
orig = knit._load_data |
|
472 |
def reset(): |
|
473 |
knit._load_data = orig |
|
474 |
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 |
475 |
from bzrlib._knit_load_data_py import _load_data_py |
476 |
knit._load_data = _load_data_py |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
477 |
return _KnitIndex(get_scope=lambda:None, *args, **kwargs) |
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
478 |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
479 |
def test_no_such_file(self): |
480 |
transport = MockTransport() |
|
481 |
||
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
482 |
self.assertRaises(NoSuchFile, self.get_knit_index, |
483 |
transport, "filename", "r") |
|
484 |
self.assertRaises(NoSuchFile, self.get_knit_index, |
|
485 |
transport, "filename", "w", create=False) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
486 |
|
487 |
def test_create_file(self): |
|
488 |
transport = MockTransport() |
|
489 |
||
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
490 |
index = self.get_knit_index(transport, "filename", "w", |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
491 |
file_mode="wb", create=True) |
492 |
self.assertEqual( |
|
493 |
("put_bytes_non_atomic", |
|
494 |
("filename", index.HEADER), {"mode": "wb"}), |
|
495 |
transport.calls.pop(0)) |
|
496 |
||
497 |
def test_delay_create_file(self): |
|
498 |
transport = MockTransport() |
|
499 |
||
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
500 |
index = self.get_knit_index(transport, "filename", "w", |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
501 |
create=True, file_mode="wb", create_parent_dir=True, |
502 |
delay_create=True, dir_mode=0777) |
|
503 |
self.assertEqual([], transport.calls) |
|
504 |
||
505 |
index.add_versions([]) |
|
506 |
name, (filename, f), kwargs = transport.calls.pop(0) |
|
507 |
self.assertEqual("put_file_non_atomic", name) |
|
508 |
self.assertEqual( |
|
509 |
{"dir_mode": 0777, "create_parent_dir": True, "mode": "wb"}, |
|
510 |
kwargs) |
|
511 |
self.assertEqual("filename", filename) |
|
512 |
self.assertEqual(index.HEADER, f.read()) |
|
513 |
||
514 |
index.add_versions([]) |
|
515 |
self.assertEqual(("append_bytes", ("filename", ""), {}), |
|
516 |
transport.calls.pop(0)) |
|
517 |
||
518 |
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 |
519 |
unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}" |
520 |
utf8_revision_id = unicode_revision_id.encode('utf-8') |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
521 |
transport = MockTransport([ |
522 |
_KnitIndex.HEADER, |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
523 |
'%s option 0 1 :' % (utf8_revision_id,) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
524 |
])
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
525 |
index = self.get_knit_index(transport, "filename", "r") |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
526 |
# _KnitIndex is a private class, and deals in utf8 revision_ids, not
|
527 |
# Unicode revision_ids.
|
|
528 |
self.assertTrue(index.has_version(utf8_revision_id)) |
|
529 |
self.assertFalse(index.has_version(unicode_revision_id)) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
530 |
|
531 |
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 |
532 |
unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}" |
533 |
utf8_revision_id = unicode_revision_id.encode('utf-8') |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
534 |
transport = MockTransport([ |
535 |
_KnitIndex.HEADER, |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
536 |
"version option 0 1 .%s :" % (utf8_revision_id,) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
537 |
])
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
538 |
index = self.get_knit_index(transport, "filename", "r") |
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
539 |
self.assertEqual((utf8_revision_id,), |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
540 |
index.get_parents_with_ghosts("version")) |
541 |
||
542 |
def test_read_ignore_corrupted_lines(self): |
|
543 |
transport = MockTransport([ |
|
544 |
_KnitIndex.HEADER, |
|
545 |
"corrupted", |
|
546 |
"corrupted options 0 1 .b .c ", |
|
547 |
"version options 0 1 :"
|
|
548 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
549 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
550 |
self.assertEqual(1, index.num_versions()) |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
551 |
self.assertTrue(index.has_version("version")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
552 |
|
553 |
def test_read_corrupted_header(self): |
|
|
2196.2.3
by John Arbash Meinel
Update tests and code to pass after merging bzr.dev |
554 |
transport = MockTransport(['not a bzr knit index header\n']) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
555 |
self.assertRaises(KnitHeaderError, |
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
556 |
self.get_knit_index, transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
557 |
|
558 |
def test_read_duplicate_entries(self): |
|
559 |
transport = MockTransport([ |
|
560 |
_KnitIndex.HEADER, |
|
561 |
"parent options 0 1 :", |
|
562 |
"version options1 0 1 0 :", |
|
563 |
"version options2 1 2 .other :", |
|
564 |
"version options3 3 4 0 .other :"
|
|
565 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
566 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
567 |
self.assertEqual(2, index.num_versions()) |
|
2592.3.8
by Robert Collins
Remove unneeded pulib method lookup on private class _KnitIndex. |
568 |
# check that the index used is the first one written. (Specific
|
569 |
# to KnitIndex style indices.
|
|
570 |
self.assertEqual("1", index._version_list_to_index(["version"])) |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
571 |
self.assertEqual((None, 3, 4), index.get_position("version")) |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
572 |
self.assertEqual(["options3"], index.get_options("version")) |
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
573 |
self.assertEqual(("parent", "other"), |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
574 |
index.get_parents_with_ghosts("version")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
575 |
|
576 |
def test_read_compressed_parents(self): |
|
577 |
transport = MockTransport([ |
|
578 |
_KnitIndex.HEADER, |
|
579 |
"a option 0 1 :", |
|
580 |
"b option 0 1 0 :", |
|
581 |
"c option 0 1 1 0 :", |
|
582 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
583 |
index = self.get_knit_index(transport, "filename", "r") |
|
3287.5.6
by Robert Collins
Remove _KnitIndex.get_parents. |
584 |
self.assertEqual({"b":("a",), "c":("b", "a")}, |
585 |
index.get_parent_map(["b", "c"])) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
586 |
|
587 |
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 |
588 |
unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}" |
589 |
utf8_revision_id = unicode_revision_id.encode('utf-8') |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
590 |
transport = MockTransport([ |
591 |
_KnitIndex.HEADER |
|
592 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
593 |
index = self.get_knit_index(transport, "filename", "r") |
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
594 |
index.add_version(utf8_revision_id, ["option"], (None, 0, 1), []) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
595 |
self.assertEqual(("append_bytes", ("filename", |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
596 |
"\n%s option 0 1 :" % (utf8_revision_id,)), |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
597 |
{}),
|
598 |
transport.calls.pop(0)) |
|
599 |
||
600 |
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 |
601 |
unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}" |
602 |
utf8_revision_id = unicode_revision_id.encode('utf-8') |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
603 |
transport = MockTransport([ |
604 |
_KnitIndex.HEADER |
|
605 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
606 |
index = self.get_knit_index(transport, "filename", "r") |
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
607 |
index.add_version("version", ["option"], (None, 0, 1), [utf8_revision_id]) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
608 |
self.assertEqual(("append_bytes", ("filename", |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
609 |
"\nversion option 0 1 .%s :" % (utf8_revision_id,)), |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
610 |
{}),
|
611 |
transport.calls.pop(0)) |
|
612 |
||
613 |
def test_get_ancestry(self): |
|
614 |
transport = MockTransport([ |
|
615 |
_KnitIndex.HEADER, |
|
616 |
"a option 0 1 :", |
|
617 |
"b option 0 1 0 .e :", |
|
618 |
"c option 0 1 1 0 :", |
|
619 |
"d option 0 1 2 .f :"
|
|
620 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
621 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
622 |
|
623 |
self.assertEqual([], index.get_ancestry([])) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
624 |
self.assertEqual(["a"], index.get_ancestry(["a"])) |
625 |
self.assertEqual(["a", "b"], index.get_ancestry(["b"])) |
|
626 |
self.assertEqual(["a", "b", "c"], index.get_ancestry(["c"])) |
|
627 |
self.assertEqual(["a", "b", "c", "d"], index.get_ancestry(["d"])) |
|
628 |
self.assertEqual(["a", "b"], index.get_ancestry(["a", "b"])) |
|
629 |
self.assertEqual(["a", "b", "c"], index.get_ancestry(["a", "c"])) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
630 |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
631 |
self.assertRaises(RevisionNotPresent, index.get_ancestry, ["e"]) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
632 |
|
633 |
def test_get_ancestry_with_ghosts(self): |
|
634 |
transport = MockTransport([ |
|
635 |
_KnitIndex.HEADER, |
|
636 |
"a option 0 1 :", |
|
637 |
"b option 0 1 0 .e :", |
|
638 |
"c option 0 1 0 .f .g :", |
|
639 |
"d option 0 1 2 .h .j .k :"
|
|
640 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
641 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
642 |
|
643 |
self.assertEqual([], index.get_ancestry_with_ghosts([])) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
644 |
self.assertEqual(["a"], index.get_ancestry_with_ghosts(["a"])) |
645 |
self.assertEqual(["a", "e", "b"], |
|
646 |
index.get_ancestry_with_ghosts(["b"])) |
|
647 |
self.assertEqual(["a", "g", "f", "c"], |
|
648 |
index.get_ancestry_with_ghosts(["c"])) |
|
649 |
self.assertEqual(["a", "g", "f", "c", "k", "j", "h", "d"], |
|
650 |
index.get_ancestry_with_ghosts(["d"])) |
|
651 |
self.assertEqual(["a", "e", "b"], |
|
652 |
index.get_ancestry_with_ghosts(["a", "b"])) |
|
653 |
self.assertEqual(["a", "g", "f", "c"], |
|
654 |
index.get_ancestry_with_ghosts(["a", "c"])) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
655 |
self.assertEqual( |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
656 |
["a", "g", "f", "c", "e", "b", "k", "j", "h", "d"], |
657 |
index.get_ancestry_with_ghosts(["b", "d"])) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
658 |
|
659 |
self.assertRaises(RevisionNotPresent, |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
660 |
index.get_ancestry_with_ghosts, ["e"]) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
661 |
|
662 |
def test_num_versions(self): |
|
663 |
transport = MockTransport([ |
|
664 |
_KnitIndex.HEADER |
|
665 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
666 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
667 |
|
668 |
self.assertEqual(0, index.num_versions()) |
|
669 |
self.assertEqual(0, len(index)) |
|
670 |
||
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
671 |
index.add_version("a", ["option"], (None, 0, 1), []) |
672 |
self.assertEqual(1, index.num_versions()) |
|
673 |
self.assertEqual(1, len(index)) |
|
674 |
||
675 |
index.add_version("a", ["option2"], (None, 1, 2), []) |
|
676 |
self.assertEqual(1, index.num_versions()) |
|
677 |
self.assertEqual(1, len(index)) |
|
678 |
||
679 |
index.add_version("b", ["option"], (None, 0, 1), []) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
680 |
self.assertEqual(2, index.num_versions()) |
681 |
self.assertEqual(2, len(index)) |
|
682 |
||
683 |
def test_get_versions(self): |
|
684 |
transport = MockTransport([ |
|
685 |
_KnitIndex.HEADER |
|
686 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
687 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
688 |
|
689 |
self.assertEqual([], index.get_versions()) |
|
690 |
||
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
691 |
index.add_version("a", ["option"], (None, 0, 1), []) |
692 |
self.assertEqual(["a"], index.get_versions()) |
|
693 |
||
694 |
index.add_version("a", ["option"], (None, 0, 1), []) |
|
695 |
self.assertEqual(["a"], index.get_versions()) |
|
696 |
||
697 |
index.add_version("b", ["option"], (None, 0, 1), []) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
698 |
self.assertEqual(["a", "b"], index.get_versions()) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
699 |
|
700 |
def test_add_version(self): |
|
701 |
transport = MockTransport([ |
|
702 |
_KnitIndex.HEADER |
|
703 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
704 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
705 |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
706 |
index.add_version("a", ["option"], (None, 0, 1), ["b"]) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
707 |
self.assertEqual(("append_bytes", |
708 |
("filename", "\na option 0 1 .b :"), |
|
709 |
{}), transport.calls.pop(0)) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
710 |
self.assertTrue(index.has_version("a")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
711 |
self.assertEqual(1, index.num_versions()) |
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
712 |
self.assertEqual((None, 0, 1), index.get_position("a")) |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
713 |
self.assertEqual(["option"], index.get_options("a")) |
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
714 |
self.assertEqual(("b",), index.get_parents_with_ghosts("a")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
715 |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
716 |
index.add_version("a", ["opt"], (None, 1, 2), ["c"]) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
717 |
self.assertEqual(("append_bytes", |
718 |
("filename", "\na opt 1 2 .c :"), |
|
719 |
{}), transport.calls.pop(0)) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
720 |
self.assertTrue(index.has_version("a")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
721 |
self.assertEqual(1, index.num_versions()) |
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
722 |
self.assertEqual((None, 1, 2), index.get_position("a")) |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
723 |
self.assertEqual(["opt"], index.get_options("a")) |
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
724 |
self.assertEqual(("c",), index.get_parents_with_ghosts("a")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
725 |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
726 |
index.add_version("b", ["option"], (None, 2, 3), ["a"]) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
727 |
self.assertEqual(("append_bytes", |
728 |
("filename", "\nb option 2 3 0 :"), |
|
729 |
{}), transport.calls.pop(0)) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
730 |
self.assertTrue(index.has_version("b")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
731 |
self.assertEqual(2, index.num_versions()) |
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
732 |
self.assertEqual((None, 2, 3), index.get_position("b")) |
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
733 |
self.assertEqual(["option"], index.get_options("b")) |
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
734 |
self.assertEqual(("a",), index.get_parents_with_ghosts("b")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
735 |
|
736 |
def test_add_versions(self): |
|
737 |
transport = MockTransport([ |
|
738 |
_KnitIndex.HEADER |
|
739 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
740 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
741 |
|
742 |
index.add_versions([ |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
743 |
("a", ["option"], (None, 0, 1), ["b"]), |
744 |
("a", ["opt"], (None, 1, 2), ["c"]), |
|
745 |
("b", ["option"], (None, 2, 3), ["a"]) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
746 |
])
|
747 |
self.assertEqual(("append_bytes", ("filename", |
|
748 |
"\na option 0 1 .b :" |
|
749 |
"\na opt 1 2 .c :" |
|
750 |
"\nb option 2 3 0 :" |
|
751 |
), {}), transport.calls.pop(0)) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
752 |
self.assertTrue(index.has_version("a")) |
753 |
self.assertTrue(index.has_version("b")) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
754 |
self.assertEqual(2, index.num_versions()) |
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
755 |
self.assertEqual((None, 1, 2), index.get_position("a")) |
756 |
self.assertEqual((None, 2, 3), index.get_position("b")) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
757 |
self.assertEqual(["opt"], index.get_options("a")) |
758 |
self.assertEqual(["option"], index.get_options("b")) |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
759 |
self.assertEqual(("c",), index.get_parents_with_ghosts("a")) |
760 |
self.assertEqual(("a",), index.get_parents_with_ghosts("b")) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
761 |
|
|
2841.2.1
by Robert Collins
* Commit no longer checks for new text keys during insertion when the |
762 |
def test_add_versions_random_id_is_accepted(self): |
763 |
transport = MockTransport([ |
|
764 |
_KnitIndex.HEADER |
|
765 |
])
|
|
766 |
index = self.get_knit_index(transport, "filename", "r") |
|
767 |
||
768 |
index.add_versions([ |
|
769 |
("a", ["option"], (None, 0, 1), ["b"]), |
|
770 |
("a", ["opt"], (None, 1, 2), ["c"]), |
|
771 |
("b", ["option"], (None, 2, 3), ["a"]) |
|
772 |
], random_id=True) |
|
773 |
||
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
774 |
def test_delay_create_and_add_versions(self): |
775 |
transport = MockTransport() |
|
776 |
||
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
777 |
index = self.get_knit_index(transport, "filename", "w", |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
778 |
create=True, file_mode="wb", create_parent_dir=True, |
779 |
delay_create=True, dir_mode=0777) |
|
780 |
self.assertEqual([], transport.calls) |
|
781 |
||
782 |
index.add_versions([ |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
783 |
("a", ["option"], (None, 0, 1), ["b"]), |
784 |
("a", ["opt"], (None, 1, 2), ["c"]), |
|
785 |
("b", ["option"], (None, 2, 3), ["a"]) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
786 |
])
|
787 |
name, (filename, f), kwargs = transport.calls.pop(0) |
|
788 |
self.assertEqual("put_file_non_atomic", name) |
|
789 |
self.assertEqual( |
|
790 |
{"dir_mode": 0777, "create_parent_dir": True, "mode": "wb"}, |
|
791 |
kwargs) |
|
792 |
self.assertEqual("filename", filename) |
|
793 |
self.assertEqual( |
|
794 |
index.HEADER + |
|
795 |
"\na option 0 1 .b :" |
|
796 |
"\na opt 1 2 .c :" |
|
797 |
"\nb option 2 3 0 :", |
|
798 |
f.read()) |
|
799 |
||
800 |
def test_has_version(self): |
|
801 |
transport = MockTransport([ |
|
802 |
_KnitIndex.HEADER, |
|
803 |
"a option 0 1 :"
|
|
804 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
805 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
806 |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
807 |
self.assertTrue(index.has_version("a")) |
808 |
self.assertFalse(index.has_version("b")) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
809 |
|
810 |
def test_get_position(self): |
|
811 |
transport = MockTransport([ |
|
812 |
_KnitIndex.HEADER, |
|
813 |
"a option 0 1 :", |
|
814 |
"b option 1 2 :"
|
|
815 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
816 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
817 |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
818 |
self.assertEqual((None, 0, 1), index.get_position("a")) |
819 |
self.assertEqual((None, 1, 2), index.get_position("b")) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
820 |
|
821 |
def test_get_method(self): |
|
822 |
transport = MockTransport([ |
|
823 |
_KnitIndex.HEADER, |
|
824 |
"a fulltext,unknown 0 1 :", |
|
825 |
"b unknown,line-delta 1 2 :", |
|
826 |
"c bad 3 4 :"
|
|
827 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
828 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
829 |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
830 |
self.assertEqual("fulltext", index.get_method("a")) |
831 |
self.assertEqual("line-delta", index.get_method("b")) |
|
832 |
self.assertRaises(errors.KnitIndexUnknownMethod, index.get_method, "c") |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
833 |
|
834 |
def test_get_options(self): |
|
835 |
transport = MockTransport([ |
|
836 |
_KnitIndex.HEADER, |
|
837 |
"a opt1 0 1 :", |
|
838 |
"b opt2,opt3 1 2 :"
|
|
839 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
840 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
841 |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
842 |
self.assertEqual(["opt1"], index.get_options("a")) |
843 |
self.assertEqual(["opt2", "opt3"], index.get_options("b")) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
844 |
|
|
3287.5.6
by Robert Collins
Remove _KnitIndex.get_parents. |
845 |
def test_get_parent_map(self): |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
846 |
transport = MockTransport([ |
847 |
_KnitIndex.HEADER, |
|
848 |
"a option 0 1 :", |
|
849 |
"b option 1 2 0 .c :", |
|
850 |
"c option 1 2 1 0 .e :"
|
|
851 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
852 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
853 |
|
|
3287.5.6
by Robert Collins
Remove _KnitIndex.get_parents. |
854 |
self.assertEqual({ |
855 |
"a":(), |
|
856 |
"b":("a", "c"), |
|
857 |
"c":("b", "a", "e"), |
|
858 |
}, index.get_parent_map(["a", "b", "c"])) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
859 |
|
860 |
def test_get_parents_with_ghosts(self): |
|
861 |
transport = MockTransport([ |
|
862 |
_KnitIndex.HEADER, |
|
863 |
"a option 0 1 :", |
|
864 |
"b option 1 2 0 .c :", |
|
865 |
"c option 1 2 1 0 .e :"
|
|
866 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
867 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
868 |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
869 |
self.assertEqual((), index.get_parents_with_ghosts("a")) |
870 |
self.assertEqual(("a", "c"), index.get_parents_with_ghosts("b")) |
|
871 |
self.assertEqual(("b", "a", "e"), |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
872 |
index.get_parents_with_ghosts("c")) |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
873 |
|
874 |
def test_check_versions_present(self): |
|
875 |
transport = MockTransport([ |
|
876 |
_KnitIndex.HEADER, |
|
877 |
"a option 0 1 :", |
|
878 |
"b option 0 1 :"
|
|
879 |
])
|
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
880 |
index = self.get_knit_index(transport, "filename", "r") |
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
881 |
|
882 |
check = index.check_versions_present |
|
883 |
||
884 |
check([]) |
|
|
2249.5.12
by John Arbash Meinel
Change the APIs for VersionedFile, Store, and some of Repository into utf-8 |
885 |
check(["a"]) |
886 |
check(["b"]) |
|
887 |
check(["a", "b"]) |
|
888 |
self.assertRaises(RevisionNotPresent, check, ["c"]) |
|
889 |
self.assertRaises(RevisionNotPresent, check, ["a", "b", "c"]) |
|
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
890 |
|
|
2484.1.13
by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid. |
891 |
def test_impossible_parent(self): |
892 |
"""Test we get KnitCorrupt if the parent couldn't possibly exist.""" |
|
893 |
transport = MockTransport([ |
|
894 |
_KnitIndex.HEADER, |
|
895 |
"a option 0 1 :", |
|
896 |
"b option 0 1 4 :" # We don't have a 4th record |
|
897 |
])
|
|
|
2484.1.17
by John Arbash Meinel
Workaround for Pyrex <0.9.5 and python >=2.5 incompatibilities. |
898 |
try: |
899 |
self.assertRaises(errors.KnitCorrupt, |
|
900 |
self.get_knit_index, transport, 'filename', 'r') |
|
901 |
except TypeError, e: |
|
902 |
if (str(e) == ('exceptions must be strings, classes, or instances,' |
|
903 |
' not exceptions.IndexError') |
|
904 |
and sys.version_info[0:2] >= (2,5)): |
|
905 |
self.knownFailure('Pyrex <0.9.5 fails with TypeError when' |
|
906 |
' raising new style exceptions with python'
|
|
907 |
' >=2.5') |
|
|
2484.1.19
by John Arbash Meinel
Don't suppress the TypeError if it doesn't match our requirements. |
908 |
else: |
909 |
raise
|
|
|
2484.1.13
by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid. |
910 |
|
911 |
def test_corrupted_parent(self): |
|
912 |
transport = MockTransport([ |
|
913 |
_KnitIndex.HEADER, |
|
914 |
"a option 0 1 :", |
|
915 |
"b option 0 1 :", |
|
916 |
"c option 0 1 1v :", # Can't have a parent of '1v' |
|
917 |
])
|
|
|
2484.1.17
by John Arbash Meinel
Workaround for Pyrex <0.9.5 and python >=2.5 incompatibilities. |
918 |
try: |
919 |
self.assertRaises(errors.KnitCorrupt, |
|
920 |
self.get_knit_index, transport, 'filename', 'r') |
|
921 |
except TypeError, e: |
|
922 |
if (str(e) == ('exceptions must be strings, classes, or instances,' |
|
923 |
' not exceptions.ValueError') |
|
924 |
and sys.version_info[0:2] >= (2,5)): |
|
925 |
self.knownFailure('Pyrex <0.9.5 fails with TypeError when' |
|
926 |
' raising new style exceptions with python'
|
|
927 |
' >=2.5') |
|
|
2484.1.19
by John Arbash Meinel
Don't suppress the TypeError if it doesn't match our requirements. |
928 |
else: |
929 |
raise
|
|
|
2484.1.13
by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid. |
930 |
|
931 |
def test_corrupted_parent_in_list(self): |
|
932 |
transport = MockTransport([ |
|
933 |
_KnitIndex.HEADER, |
|
934 |
"a option 0 1 :", |
|
935 |
"b option 0 1 :", |
|
|
2484.1.17
by John Arbash Meinel
Workaround for Pyrex <0.9.5 and python >=2.5 incompatibilities. |
936 |
"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. |
937 |
])
|
|
2484.1.17
by John Arbash Meinel
Workaround for Pyrex <0.9.5 and python >=2.5 incompatibilities. |
938 |
try: |
939 |
self.assertRaises(errors.KnitCorrupt, |
|
940 |
self.get_knit_index, transport, 'filename', 'r') |
|
941 |
except TypeError, e: |
|
942 |
if (str(e) == ('exceptions must be strings, classes, or instances,' |
|
943 |
' not exceptions.ValueError') |
|
944 |
and sys.version_info[0:2] >= (2,5)): |
|
945 |
self.knownFailure('Pyrex <0.9.5 fails with TypeError when' |
|
946 |
' raising new style exceptions with python'
|
|
947 |
' >=2.5') |
|
|
2484.1.19
by John Arbash Meinel
Don't suppress the TypeError if it doesn't match our requirements. |
948 |
else: |
949 |
raise
|
|
|
2484.1.13
by John Arbash Meinel
Add a test that KnitCorrupt is raised when parent strings are invalid. |
950 |
|
|
2484.1.18
by John Arbash Meinel
Test that we properly verify the size and position strings. |
951 |
def test_invalid_position(self): |
952 |
transport = MockTransport([ |
|
953 |
_KnitIndex.HEADER, |
|
954 |
"a option 1v 1 :", |
|
955 |
])
|
|
956 |
try: |
|
957 |
self.assertRaises(errors.KnitCorrupt, |
|
958 |
self.get_knit_index, transport, 'filename', 'r') |
|
959 |
except TypeError, e: |
|
960 |
if (str(e) == ('exceptions must be strings, classes, or instances,' |
|
961 |
' not exceptions.ValueError') |
|
962 |
and sys.version_info[0:2] >= (2,5)): |
|
963 |
self.knownFailure('Pyrex <0.9.5 fails with TypeError when' |
|
964 |
' raising new style exceptions with python'
|
|
965 |
' >=2.5') |
|
|
2484.1.19
by John Arbash Meinel
Don't suppress the TypeError if it doesn't match our requirements. |
966 |
else: |
967 |
raise
|
|
|
2484.1.18
by John Arbash Meinel
Test that we properly verify the size and position strings. |
968 |
|
969 |
def test_invalid_size(self): |
|
970 |
transport = MockTransport([ |
|
971 |
_KnitIndex.HEADER, |
|
972 |
"a option 1 1v :", |
|
973 |
])
|
|
974 |
try: |
|
975 |
self.assertRaises(errors.KnitCorrupt, |
|
976 |
self.get_knit_index, transport, 'filename', 'r') |
|
977 |
except TypeError, e: |
|
978 |
if (str(e) == ('exceptions must be strings, classes, or instances,' |
|
979 |
' not exceptions.ValueError') |
|
980 |
and sys.version_info[0:2] >= (2,5)): |
|
981 |
self.knownFailure('Pyrex <0.9.5 fails with TypeError when' |
|
982 |
' raising new style exceptions with python'
|
|
983 |
' >=2.5') |
|
|
2484.1.19
by John Arbash Meinel
Don't suppress the TypeError if it doesn't match our requirements. |
984 |
else: |
985 |
raise
|
|
|
2484.1.18
by John Arbash Meinel
Test that we properly verify the size and position strings. |
986 |
|
|
2484.1.24
by John Arbash Meinel
Add direct tests of how we handle incomplete/'broken' lines |
987 |
def test_short_line(self): |
988 |
transport = MockTransport([ |
|
989 |
_KnitIndex.HEADER, |
|
990 |
"a option 0 10 :", |
|
991 |
"b option 10 10 0", # This line isn't terminated, ignored |
|
992 |
])
|
|
993 |
index = self.get_knit_index(transport, "filename", "r") |
|
994 |
self.assertEqual(['a'], index.get_versions()) |
|
995 |
||
996 |
def test_skip_incomplete_record(self): |
|
997 |
# A line with bogus data should just be skipped
|
|
998 |
transport = MockTransport([ |
|
999 |
_KnitIndex.HEADER, |
|
1000 |
"a option 0 10 :", |
|
1001 |
"b option 10 10 0", # This line isn't terminated, ignored |
|
1002 |
"c option 20 10 0 :", # Properly terminated, and starts with '\n' |
|
1003 |
])
|
|
1004 |
index = self.get_knit_index(transport, "filename", "r") |
|
1005 |
self.assertEqual(['a', 'c'], index.get_versions()) |
|
1006 |
||
1007 |
def test_trailing_characters(self): |
|
1008 |
# A line with bogus data should just be skipped
|
|
1009 |
transport = MockTransport([ |
|
1010 |
_KnitIndex.HEADER, |
|
1011 |
"a option 0 10 :", |
|
1012 |
"b option 10 10 0 :a", # This line has extra trailing characters |
|
1013 |
"c option 20 10 0 :", # Properly terminated, and starts with '\n' |
|
1014 |
])
|
|
1015 |
index = self.get_knit_index(transport, "filename", "r") |
|
1016 |
self.assertEqual(['a', 'c'], index.get_versions()) |
|
1017 |
||
|
2158.3.1
by Dmitry Vasiliev
KnitIndex tests/fixes/optimizations |
1018 |
|
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
1019 |
class LowLevelKnitIndexTests_c(LowLevelKnitIndexTests): |
1020 |
||
1021 |
_test_needs_features = [CompiledKnitFeature] |
|
1022 |
||
1023 |
def get_knit_index(self, *args, **kwargs): |
|
1024 |
orig = knit._load_data |
|
1025 |
def reset(): |
|
1026 |
knit._load_data = orig |
|
1027 |
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 |
1028 |
from bzrlib._knit_load_data_c import _load_data_c |
1029 |
knit._load_data = _load_data_c |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1030 |
return _KnitIndex(get_scope=lambda:None, *args, **kwargs) |
|
2484.1.1
by John Arbash Meinel
Add an initial function to read knit indexes in pyrex. |
1031 |
|
1032 |
||
|
1684.3.3
by Robert Collins
Add a special cased weaves to knit converter. |
1033 |
class KnitTests(TestCaseWithTransport): |
1034 |
"""Class containing knit test helper routines.""" |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1035 |
|
|
2535.3.27
by Andrew Bennetts
Merge from bzr.dev. |
1036 |
def make_test_knit(self, annotate=False, delay_create=False, index=None, |
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1037 |
name='test', delta=True, access_mode='w'): |
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1038 |
if not annotate: |
1039 |
factory = KnitPlainFactory() |
|
1040 |
else: |
|
1041 |
factory = None |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1042 |
if index is None: |
1043 |
index = _KnitIndex(get_transport('.'), name + INDEX_SUFFIX, |
|
1044 |
access_mode, create=True, file_mode=None, |
|
1045 |
create_parent_dir=False, delay_create=delay_create, |
|
1046 |
dir_mode=None, get_scope=lambda:None) |
|
1047 |
access = _KnitAccess(get_transport('.'), name + DATA_SUFFIX, None, |
|
1048 |
None, delay_create, False) |
|
1049 |
return KnitVersionedFile(name, get_transport('.'), factory=factory, |
|
1050 |
create=True, delay_create=delay_create, index=index, |
|
1051 |
access_method=access, delta=delta) |
|
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1052 |
|
|
2535.3.53
by Andrew Bennetts
Remove get_stream_as_bytes from KnitVersionedFile's API, make it a function in knitrepo.py instead. |
1053 |
def assertRecordContentEqual(self, knit, version_id, candidate_content): |
1054 |
"""Assert that some raw record content matches the raw record content |
|
1055 |
for a particular version_id in the given knit.
|
|
1056 |
"""
|
|
1057 |
index_memo = knit._index.get_position(version_id) |
|
1058 |
record = (version_id, index_memo) |
|
1059 |
[(_, expected_content)] = list(knit._data.read_records_iter_raw([record])) |
|
1060 |
self.assertEqual(expected_content, candidate_content) |
|
1061 |
||
|
1684.3.3
by Robert Collins
Add a special cased weaves to knit converter. |
1062 |
|
1063 |
class BasicKnitTests(KnitTests): |
|
1064 |
||
1065 |
def add_stock_one_and_one_a(self, k): |
|
1066 |
k.add_lines('text-1', [], split_lines(TEXT_1)) |
|
1067 |
k.add_lines('text-1a', ['text-1'], split_lines(TEXT_1A)) |
|
1068 |
||
1069 |
def test_knit_constructor(self): |
|
1070 |
"""Construct empty k""" |
|
1071 |
self.make_test_knit() |
|
1072 |
||
|
2592.3.1
by Robert Collins
Allow giving KnitVersionedFile an index object to use rather than implicitly creating one. |
1073 |
def test_make_explicit_index(self): |
1074 |
"""We can supply an index to use.""" |
|
1075 |
knit = KnitVersionedFile('test', get_transport('.'), |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1076 |
index='strangelove', access_method="a") |
|
2592.3.1
by Robert Collins
Allow giving KnitVersionedFile an index object to use rather than implicitly creating one. |
1077 |
self.assertEqual(knit._index, 'strangelove') |
1078 |
||
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1079 |
def test_knit_add(self): |
1080 |
"""Store one text in knit and retrieve""" |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1081 |
k = self.make_test_knit() |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1082 |
k.add_lines('text-1', [], split_lines(TEXT_1)) |
1083 |
self.assertTrue(k.has_version('text-1')) |
|
1084 |
self.assertEqualDiff(''.join(k.get_lines('text-1')), TEXT_1) |
|
1085 |
||
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1086 |
def test_newline_empty_lines(self): |
1087 |
# ensure that ["\n"] round trips ok.
|
|
1088 |
knit = self.make_test_knit() |
|
1089 |
knit.add_lines('a', [], ["\n"]) |
|
1090 |
knit.add_lines_with_ghosts('b', [], ["\n"]) |
|
1091 |
self.assertEqual(["\n"], knit.get_lines('a')) |
|
1092 |
self.assertEqual(["\n"], knit.get_lines('b')) |
|
1093 |
self.assertEqual(['fulltext'], knit._index.get_options('a')) |
|
1094 |
self.assertEqual(['fulltext'], knit._index.get_options('b')) |
|
1095 |
knit.add_lines('c', ['a'], ["\n"]) |
|
1096 |
knit.add_lines_with_ghosts('d', ['b'], ["\n"]) |
|
1097 |
self.assertEqual(["\n"], knit.get_lines('c')) |
|
1098 |
self.assertEqual(["\n"], knit.get_lines('d')) |
|
1099 |
self.assertEqual(['line-delta'], knit._index.get_options('c')) |
|
1100 |
self.assertEqual(['line-delta'], knit._index.get_options('d')) |
|
1101 |
||
1102 |
def test_empty_lines(self): |
|
1103 |
# bizarrely, [] is not listed as having no-eol.
|
|
1104 |
knit = self.make_test_knit() |
|
1105 |
knit.add_lines('a', [], []) |
|
1106 |
knit.add_lines_with_ghosts('b', [], []) |
|
1107 |
self.assertEqual([], knit.get_lines('a')) |
|
1108 |
self.assertEqual([], knit.get_lines('b')) |
|
1109 |
self.assertEqual(['fulltext'], knit._index.get_options('a')) |
|
1110 |
self.assertEqual(['fulltext'], knit._index.get_options('b')) |
|
1111 |
knit.add_lines('c', ['a'], []) |
|
1112 |
knit.add_lines_with_ghosts('d', ['b'], []) |
|
1113 |
self.assertEqual([], knit.get_lines('c')) |
|
1114 |
self.assertEqual([], knit.get_lines('d')) |
|
1115 |
self.assertEqual(['line-delta'], knit._index.get_options('c')) |
|
1116 |
self.assertEqual(['line-delta'], knit._index.get_options('d')) |
|
1117 |
||
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1118 |
def test_knit_reload(self): |
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1119 |
# test that the content in a reloaded knit is correct
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1120 |
k = self.make_test_knit() |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1121 |
k.add_lines('text-1', [], split_lines(TEXT_1)) |
1122 |
del k |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1123 |
k2 = make_file_knit('test', get_transport('.'), access_mode='r', |
1124 |
factory=KnitPlainFactory(), create=True) |
|
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1125 |
self.assertTrue(k2.has_version('text-1')) |
1126 |
self.assertEqualDiff(''.join(k2.get_lines('text-1')), TEXT_1) |
|
1127 |
||
1128 |
def test_knit_several(self): |
|
1129 |
"""Store several texts in a knit""" |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1130 |
k = self.make_test_knit() |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1131 |
k.add_lines('text-1', [], split_lines(TEXT_1)) |
1132 |
k.add_lines('text-2', [], split_lines(TEXT_2)) |
|
1133 |
self.assertEqualDiff(''.join(k.get_lines('text-1')), TEXT_1) |
|
1134 |
self.assertEqualDiff(''.join(k.get_lines('text-2')), TEXT_2) |
|
1135 |
||
1136 |
def test_repeated_add(self): |
|
1137 |
"""Knit traps attempt to replace existing version""" |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1138 |
k = self.make_test_knit() |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1139 |
k.add_lines('text-1', [], split_lines(TEXT_1)) |
1140 |
self.assertRaises(RevisionAlreadyPresent, |
|
1141 |
k.add_lines, |
|
1142 |
'text-1', [], split_lines(TEXT_1)) |
|
1143 |
||
1144 |
def test_empty(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1145 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1146 |
k.add_lines('text-1', [], []) |
1147 |
self.assertEquals(k.get_lines('text-1'), []) |
|
1148 |
||
1149 |
def test_incomplete(self): |
|
1150 |
"""Test if texts without a ending line-end can be inserted and |
|
1151 |
extracted."""
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1152 |
k = make_file_knit('test', get_transport('.'), delta=False, create=True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1153 |
k.add_lines('text-1', [], ['a\n', 'b' ]) |
1154 |
k.add_lines('text-2', ['text-1'], ['a\rb\n', 'b\n']) |
|
|
1666.1.6
by Robert Collins
Make knit the default format. |
1155 |
# reopening ensures maximum room for confusion
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1156 |
k = make_file_knit('test', get_transport('.'), delta=False, create=True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1157 |
self.assertEquals(k.get_lines('text-1'), ['a\n', 'b' ]) |
1158 |
self.assertEquals(k.get_lines('text-2'), ['a\rb\n', 'b\n']) |
|
1159 |
||
1160 |
def test_delta(self): |
|
1161 |
"""Expression of knit delta as lines""" |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1162 |
k = self.make_test_knit() |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1163 |
td = list(line_delta(TEXT_1.splitlines(True), |
1164 |
TEXT_1A.splitlines(True))) |
|
1165 |
self.assertEqualDiff(''.join(td), delta_1_1a) |
|
1166 |
out = apply_line_delta(TEXT_1.splitlines(True), td) |
|
1167 |
self.assertEqualDiff(''.join(out), TEXT_1A) |
|
1168 |
||
1169 |
def test_add_with_parents(self): |
|
1170 |
"""Store in knit with parents""" |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1171 |
k = self.make_test_knit() |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1172 |
self.add_stock_one_and_one_a(k) |
|
3287.5.2
by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code. |
1173 |
self.assertEqual({'text-1':(), 'text-1a':('text-1',)}, |
1174 |
k.get_parent_map(['text-1', 'text-1a'])) |
|
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1175 |
|
1176 |
def test_ancestry(self): |
|
1177 |
"""Store in knit with parents""" |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1178 |
k = self.make_test_knit() |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1179 |
self.add_stock_one_and_one_a(k) |
1180 |
self.assertEquals(set(k.get_ancestry(['text-1a'])), set(['text-1a', 'text-1'])) |
|
1181 |
||
1182 |
def test_add_delta(self): |
|
1183 |
"""Store in knit with parents""" |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1184 |
k = self.make_test_knit(annotate=False) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1185 |
self.add_stock_one_and_one_a(k) |
1186 |
self.assertEqualDiff(''.join(k.get_lines('text-1a')), TEXT_1A) |
|
1187 |
||
|
2592.3.21
by Robert Collins
Test using a KnitGraphIndex for storage. |
1188 |
def test_add_delta_knit_graph_index(self): |
1189 |
"""Does adding work with a KnitGraphIndex.""" |
|
1190 |
index = InMemoryGraphIndex(2) |
|
1191 |
knit_index = KnitGraphIndex(index, add_callback=index.add_nodes, |
|
1192 |
deltas=True) |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1193 |
k = self.make_test_knit(annotate=True, index=knit_index) |
|
2592.3.21
by Robert Collins
Test using a KnitGraphIndex for storage. |
1194 |
self.add_stock_one_and_one_a(k) |
1195 |
self.assertEqualDiff(''.join(k.get_lines('text-1a')), TEXT_1A) |
|
1196 |
# check the index had the right data added.
|
|
1197 |
self.assertEqual(set([ |
|
|
2624.2.14
by Robert Collins
Add source index to the index iteration API to allow mapping back to the origin of retrieved data. |
1198 |
(index, ('text-1', ), ' 0 127', ((), ())), |
1199 |
(index, ('text-1a', ), ' 127 140', ((('text-1', ),), (('text-1', ),))), |
|
|
2592.3.21
by Robert Collins
Test using a KnitGraphIndex for storage. |
1200 |
]), set(index.iter_all_entries())) |
1201 |
# we should not have a .kndx file
|
|
1202 |
self.assertFalse(get_transport('.').has('test.kndx')) |
|
1203 |
||
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1204 |
def test_annotate(self): |
1205 |
"""Annotations""" |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1206 |
k = self.make_test_knit(annotate=True, name='knit') |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1207 |
self.insert_and_test_small_annotate(k) |
1208 |
||
1209 |
def insert_and_test_small_annotate(self, k): |
|
1210 |
"""test annotation with k works correctly.""" |
|
1211 |
k.add_lines('text-1', [], ['a\n', 'b\n']) |
|
1212 |
k.add_lines('text-2', ['text-1'], ['a\n', 'c\n']) |
|
1213 |
||
1214 |
origins = k.annotate('text-2') |
|
1215 |
self.assertEquals(origins[0], ('text-1', 'a\n')) |
|
1216 |
self.assertEquals(origins[1], ('text-2', 'c\n')) |
|
1217 |
||
1218 |
def test_annotate_fulltext(self): |
|
1219 |
"""Annotations""" |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1220 |
k = self.make_test_knit(annotate=True, name='knit', delta=False) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1221 |
self.insert_and_test_small_annotate(k) |
1222 |
||
1223 |
def test_annotate_merge_1(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1224 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1225 |
k.add_lines('text-a1', [], ['a\n', 'b\n']) |
1226 |
k.add_lines('text-a2', [], ['d\n', 'c\n']) |
|
1227 |
k.add_lines('text-am', ['text-a1', 'text-a2'], ['d\n', 'b\n']) |
|
1228 |
origins = k.annotate('text-am') |
|
1229 |
self.assertEquals(origins[0], ('text-a2', 'd\n')) |
|
1230 |
self.assertEquals(origins[1], ('text-a1', 'b\n')) |
|
1231 |
||
1232 |
def test_annotate_merge_2(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1233 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1234 |
k.add_lines('text-a1', [], ['a\n', 'b\n', 'c\n']) |
1235 |
k.add_lines('text-a2', [], ['x\n', 'y\n', 'z\n']) |
|
1236 |
k.add_lines('text-am', ['text-a1', 'text-a2'], ['a\n', 'y\n', 'c\n']) |
|
1237 |
origins = k.annotate('text-am') |
|
1238 |
self.assertEquals(origins[0], ('text-a1', 'a\n')) |
|
1239 |
self.assertEquals(origins[1], ('text-a2', 'y\n')) |
|
1240 |
self.assertEquals(origins[2], ('text-a1', 'c\n')) |
|
1241 |
||
1242 |
def test_annotate_merge_9(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1243 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1244 |
k.add_lines('text-a1', [], ['a\n', 'b\n', 'c\n']) |
1245 |
k.add_lines('text-a2', [], ['x\n', 'y\n', 'z\n']) |
|
1246 |
k.add_lines('text-am', ['text-a1', 'text-a2'], ['k\n', 'y\n', 'c\n']) |
|
1247 |
origins = k.annotate('text-am') |
|
1248 |
self.assertEquals(origins[0], ('text-am', 'k\n')) |
|
1249 |
self.assertEquals(origins[1], ('text-a2', 'y\n')) |
|
1250 |
self.assertEquals(origins[2], ('text-a1', 'c\n')) |
|
1251 |
||
1252 |
def test_annotate_merge_3(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1253 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1254 |
k.add_lines('text-a1', [], ['a\n', 'b\n', 'c\n']) |
1255 |
k.add_lines('text-a2', [] ,['x\n', 'y\n', 'z\n']) |
|
1256 |
k.add_lines('text-am', ['text-a1', 'text-a2'], ['k\n', 'y\n', 'z\n']) |
|
1257 |
origins = k.annotate('text-am') |
|
1258 |
self.assertEquals(origins[0], ('text-am', 'k\n')) |
|
1259 |
self.assertEquals(origins[1], ('text-a2', 'y\n')) |
|
1260 |
self.assertEquals(origins[2], ('text-a2', 'z\n')) |
|
1261 |
||
1262 |
def test_annotate_merge_4(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1263 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1264 |
k.add_lines('text-a1', [], ['a\n', 'b\n', 'c\n']) |
1265 |
k.add_lines('text-a2', [], ['x\n', 'y\n', 'z\n']) |
|
1266 |
k.add_lines('text-a3', ['text-a1'], ['a\n', 'b\n', 'p\n']) |
|
1267 |
k.add_lines('text-am', ['text-a2', 'text-a3'], ['a\n', 'b\n', 'z\n']) |
|
1268 |
origins = k.annotate('text-am') |
|
1269 |
self.assertEquals(origins[0], ('text-a1', 'a\n')) |
|
1270 |
self.assertEquals(origins[1], ('text-a1', 'b\n')) |
|
1271 |
self.assertEquals(origins[2], ('text-a2', 'z\n')) |
|
1272 |
||
1273 |
def test_annotate_merge_5(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1274 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1275 |
k.add_lines('text-a1', [], ['a\n', 'b\n', 'c\n']) |
1276 |
k.add_lines('text-a2', [], ['d\n', 'e\n', 'f\n']) |
|
1277 |
k.add_lines('text-a3', [], ['x\n', 'y\n', 'z\n']) |
|
1278 |
k.add_lines('text-am', |
|
1279 |
['text-a1', 'text-a2', 'text-a3'], |
|
1280 |
['a\n', 'e\n', 'z\n']) |
|
1281 |
origins = k.annotate('text-am') |
|
1282 |
self.assertEquals(origins[0], ('text-a1', 'a\n')) |
|
1283 |
self.assertEquals(origins[1], ('text-a2', 'e\n')) |
|
1284 |
self.assertEquals(origins[2], ('text-a3', 'z\n')) |
|
1285 |
||
1286 |
def test_annotate_file_cherry_pick(self): |
|
|
1563.2.16
by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable. |
1287 |
k = self.make_test_knit(True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1288 |
k.add_lines('text-1', [], ['a\n', 'b\n', 'c\n']) |
1289 |
k.add_lines('text-2', ['text-1'], ['d\n', 'e\n', 'f\n']) |
|
1290 |
k.add_lines('text-3', ['text-2', 'text-1'], ['a\n', 'b\n', 'c\n']) |
|
1291 |
origins = k.annotate('text-3') |
|
1292 |
self.assertEquals(origins[0], ('text-1', 'a\n')) |
|
1293 |
self.assertEquals(origins[1], ('text-1', 'b\n')) |
|
1294 |
self.assertEquals(origins[2], ('text-1', 'c\n')) |
|
1295 |
||
|
2851.4.6
by Ian Clatworthy
review tweaks |
1296 |
def _test_join_with_factories(self, k1_factory, k2_factory): |
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1297 |
k1 = make_file_knit('test1', get_transport('.'), factory=k1_factory, create=True) |
|
2851.4.1
by Ian Clatworthy
Support joining plain knits to annotated knits and vice versa |
1298 |
k1.add_lines('text-a', [], ['a1\n', 'a2\n', 'a3\n']) |
1299 |
k1.add_lines('text-b', ['text-a'], ['a1\n', 'b2\n', 'a3\n']) |
|
1300 |
k1.add_lines('text-c', [], ['c1\n', 'c2\n', 'c3\n']) |
|
1301 |
k1.add_lines('text-d', ['text-c'], ['c1\n', 'd2\n', 'd3\n']) |
|
1302 |
k1.add_lines('text-m', ['text-b', 'text-d'], ['a1\n', 'b2\n', 'd3\n']) |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1303 |
k2 = make_file_knit('test2', get_transport('.'), factory=k2_factory, create=True) |
|
2851.4.6
by Ian Clatworthy
review tweaks |
1304 |
count = k2.join(k1, version_ids=['text-m']) |
1305 |
self.assertEquals(count, 5) |
|
1306 |
self.assertTrue(k2.has_version('text-a')) |
|
1307 |
self.assertTrue(k2.has_version('text-c')) |
|
1308 |
origins = k2.annotate('text-m') |
|
1309 |
self.assertEquals(origins[0], ('text-a', 'a1\n')) |
|
1310 |
self.assertEquals(origins[1], ('text-b', 'b2\n')) |
|
1311 |
self.assertEquals(origins[2], ('text-d', 'd3\n')) |
|
|
2851.4.1
by Ian Clatworthy
Support joining plain knits to annotated knits and vice versa |
1312 |
|
1313 |
def test_knit_join_plain_to_plain(self): |
|
1314 |
"""Test joining a plain knit with a plain knit.""" |
|
|
2851.4.6
by Ian Clatworthy
review tweaks |
1315 |
self._test_join_with_factories(KnitPlainFactory(), KnitPlainFactory()) |
|
2851.4.1
by Ian Clatworthy
Support joining plain knits to annotated knits and vice versa |
1316 |
|
1317 |
def test_knit_join_anno_to_anno(self): |
|
1318 |
"""Test joining an annotated knit with an annotated knit.""" |
|
|
2851.4.6
by Ian Clatworthy
review tweaks |
1319 |
self._test_join_with_factories(None, None) |
|
2851.4.1
by Ian Clatworthy
Support joining plain knits to annotated knits and vice versa |
1320 |
|
1321 |
def test_knit_join_anno_to_plain(self): |
|
1322 |
"""Test joining an annotated knit with a plain knit.""" |
|
|
2851.4.6
by Ian Clatworthy
review tweaks |
1323 |
self._test_join_with_factories(None, KnitPlainFactory()) |
|
2851.4.1
by Ian Clatworthy
Support joining plain knits to annotated knits and vice versa |
1324 |
|
1325 |
def test_knit_join_plain_to_anno(self): |
|
1326 |
"""Test joining a plain knit with an annotated knit.""" |
|
|
2851.4.6
by Ian Clatworthy
review tweaks |
1327 |
self._test_join_with_factories(KnitPlainFactory(), None) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1328 |
|
1329 |
def test_reannotate(self): |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1330 |
k1 = make_file_knit('knit1', get_transport('.'), |
|
1563.2.25
by Robert Collins
Merge in upstream. |
1331 |
factory=KnitAnnotateFactory(), create=True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1332 |
# 0
|
1333 |
k1.add_lines('text-a', [], ['a\n', 'b\n']) |
|
1334 |
# 1
|
|
1335 |
k1.add_lines('text-b', ['text-a'], ['a\n', 'c\n']) |
|
1336 |
||
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1337 |
k2 = make_file_knit('test2', get_transport('.'), |
|
1563.2.25
by Robert Collins
Merge in upstream. |
1338 |
factory=KnitAnnotateFactory(), create=True) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1339 |
k2.join(k1, version_ids=['text-b']) |
1340 |
||
1341 |
# 2
|
|
1342 |
k1.add_lines('text-X', ['text-b'], ['a\n', 'b\n']) |
|
1343 |
# 2
|
|
1344 |
k2.add_lines('text-c', ['text-b'], ['z\n', 'c\n']) |
|
1345 |
# 3
|
|
1346 |
k2.add_lines('text-Y', ['text-b'], ['b\n', 'c\n']) |
|
1347 |
||
1348 |
# test-c will have index 3
|
|
1349 |
k1.join(k2, version_ids=['text-c']) |
|
1350 |
||
1351 |
lines = k1.get_lines('text-c') |
|
1352 |
self.assertEquals(lines, ['z\n', 'c\n']) |
|
1353 |
||
1354 |
origins = k1.annotate('text-c') |
|
|
1594.2.24
by Robert Collins
Make use of the transaction finalisation warning support to implement in-knit caching. |
1355 |
self.assertEquals(origins[0], ('text-c', 'z\n')) |
1356 |
self.assertEquals(origins[1], ('text-b', 'c\n')) |
|
1357 |
||
|
1756.3.4
by Aaron Bentley
Fix bug getting texts when line deltas were reused |
1358 |
def test_get_line_delta_texts(self): |
1359 |
"""Make sure we can call get_texts on text with reused line deltas""" |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1360 |
k1 = make_file_knit('test1', get_transport('.'), |
1361 |
factory=KnitPlainFactory(), create=True) |
|
|
1756.3.4
by Aaron Bentley
Fix bug getting texts when line deltas were reused |
1362 |
for t in range(3): |
1363 |
if t == 0: |
|
1364 |
parents = [] |
|
1365 |
else: |
|
1366 |
parents = ['%d' % (t-1)] |
|
1367 |
k1.add_lines('%d' % t, parents, ['hello\n'] * t) |
|
1368 |
k1.get_texts(('%d' % t) for t in range(3)) |
|
|
1594.3.1
by Robert Collins
Merge transaction finalisation and ensure iter_lines_added_or_present in knits does a old-to-new read in the knit. |
1369 |
|
1370 |
def test_iter_lines_reads_in_order(self): |
|
|
2745.5.3
by Robert Collins
* Move transport logging into a new transport class |
1371 |
instrumented_t = get_transport('trace+memory:///') |
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1372 |
k1 = make_file_knit('id', instrumented_t, create=True, delta=True) |
|
2745.5.3
by Robert Collins
* Move transport logging into a new transport class |
1373 |
self.assertEqual([('get', 'id.kndx',)], instrumented_t._activity) |
|
1594.3.1
by Robert Collins
Merge transaction finalisation and ensure iter_lines_added_or_present in knits does a old-to-new read in the knit. |
1374 |
# add texts with no required ordering
|
1375 |
k1.add_lines('base', [], ['text\n']) |
|
1376 |
k1.add_lines('base2', [], ['text2\n']) |
|
|
2745.5.4
by Robert Collins
Review feedback. |
1377 |
# clear the logged activity, but preserve the list instance in case of
|
1378 |
# clones pointing at it.
|
|
|
2745.5.3
by Robert Collins
* Move transport logging into a new transport class |
1379 |
del instrumented_t._activity[:] |
|
1594.3.1
by Robert Collins
Merge transaction finalisation and ensure iter_lines_added_or_present in knits does a old-to-new read in the knit. |
1380 |
# request a last-first iteration
|
|
2745.5.3
by Robert Collins
* Move transport logging into a new transport class |
1381 |
results = list(k1.iter_lines_added_or_present_in_versions( |
1382 |
['base2', 'base'])) |
|
|
2745.5.6
by Robert Collins
Fix knit test fallout from final readv api change. |
1383 |
self.assertEqual( |
1384 |
[('readv', 'id.knit', [(0, 87), (87, 89)], False, None)], |
|
|
2745.5.3
by Robert Collins
* Move transport logging into a new transport class |
1385 |
instrumented_t._activity) |
|
2975.3.1
by Robert Collins
Change (without backwards compatibility) the |
1386 |
self.assertEqual([('text\n', 'base'), ('text2\n', 'base2')], results) |
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1387 |
|
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1388 |
def test_knit_format(self): |
1389 |
# this tests that a new knit index file has the expected content
|
|
1390 |
# and that is writes the data we expect as records are added.
|
|
1391 |
knit = self.make_test_knit(True) |
|
|
1946.2.1
by John Arbash Meinel
2 changes to knits. Delay creating the .knit or .kndx file until we have actually tried to write data. Because of this, we must allow the Knit to create the prefix directories |
1392 |
# Now knit files are not created until we first add data to them
|
|
1666.1.6
by Robert Collins
Make knit the default format. |
1393 |
self.assertFileEqual("# bzr knit index 8\n", 'test.kndx') |
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1394 |
knit.add_lines_with_ghosts('revid', ['a_ghost'], ['a\n']) |
1395 |
self.assertFileEqual( |
|
|
1666.1.6
by Robert Collins
Make knit the default format. |
1396 |
"# bzr knit index 8\n" |
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1397 |
"\n" |
1398 |
"revid fulltext 0 84 .a_ghost :", |
|
1399 |
'test.kndx') |
|
1400 |
knit.add_lines_with_ghosts('revid2', ['revid'], ['a\n']) |
|
1401 |
self.assertFileEqual( |
|
|
1666.1.6
by Robert Collins
Make knit the default format. |
1402 |
"# bzr knit index 8\n" |
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1403 |
"\nrevid fulltext 0 84 .a_ghost :" |
1404 |
"\nrevid2 line-delta 84 82 0 :", |
|
1405 |
'test.kndx') |
|
1406 |
# we should be able to load this file again
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1407 |
knit = make_file_knit('test', get_transport('.'), access_mode='r') |
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1408 |
self.assertEqual(['revid', 'revid2'], knit.versions()) |
1409 |
# write a short write to the file and ensure that its ignored
|
|
|
2484.1.23
by John Arbash Meinel
When we append a new line, don't use text mode |
1410 |
indexfile = file('test.kndx', 'ab') |
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1411 |
indexfile.write('\nrevid3 line-delta 166 82 1 2 3 4 5 .phwoar:demo ') |
1412 |
indexfile.close() |
|
1413 |
# we should be able to load this file again
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1414 |
knit = make_file_knit('test', get_transport('.'), access_mode='w') |
|
1654.1.5
by Robert Collins
Merge partial index write support for knits, adding a test case per review comments. |
1415 |
self.assertEqual(['revid', 'revid2'], knit.versions()) |
1416 |
# and add a revision with the same id the failed write had
|
|
1417 |
knit.add_lines('revid3', ['revid2'], ['a\n']) |
|
1418 |
# and when reading it revid3 should now appear.
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1419 |
knit = make_file_knit('test', get_transport('.'), access_mode='r') |
|
1654.1.5
by Robert Collins
Merge partial index write support for knits, adding a test case per review comments. |
1420 |
self.assertEqual(['revid', 'revid2', 'revid3'], knit.versions()) |
|
3287.5.2
by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code. |
1421 |
self.assertEqual({'revid3':('revid2',)}, knit.get_parent_map(['revid3'])) |
|
1654.1.5
by Robert Collins
Merge partial index write support for knits, adding a test case per review comments. |
1422 |
|
|
1946.2.1
by John Arbash Meinel
2 changes to knits. Delay creating the .knit or .kndx file until we have actually tried to write data. Because of this, we must allow the Knit to create the prefix directories |
1423 |
def test_delay_create(self): |
1424 |
"""Test that passing delay_create=True creates files late""" |
|
1425 |
knit = self.make_test_knit(annotate=True, delay_create=True) |
|
1426 |
self.failIfExists('test.knit') |
|
1427 |
self.failIfExists('test.kndx') |
|
1428 |
knit.add_lines_with_ghosts('revid', ['a_ghost'], ['a\n']) |
|
1429 |
self.failUnlessExists('test.knit') |
|
1430 |
self.assertFileEqual( |
|
1431 |
"# bzr knit index 8\n" |
|
1432 |
"\n" |
|
1433 |
"revid fulltext 0 84 .a_ghost :", |
|
1434 |
'test.kndx') |
|
1435 |
||
|
1946.2.2
by John Arbash Meinel
test delay_create does the right thing |
1436 |
def test_create_parent_dir(self): |
1437 |
"""create_parent_dir can create knits in nonexistant dirs""" |
|
1438 |
# Has no effect if we don't set 'delay_create'
|
|
1439 |
trans = get_transport('.') |
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1440 |
self.assertRaises(NoSuchFile, make_file_knit, 'dir/test', |
|
1946.2.2
by John Arbash Meinel
test delay_create does the right thing |
1441 |
trans, access_mode='w', factory=None, |
1442 |
create=True, create_parent_dir=True) |
|
1443 |
# Nothing should have changed yet
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1444 |
knit = make_file_knit('dir/test', trans, access_mode='w', |
|
1946.2.2
by John Arbash Meinel
test delay_create does the right thing |
1445 |
factory=None, create=True, |
1446 |
create_parent_dir=True, |
|
1447 |
delay_create=True) |
|
1448 |
self.failIfExists('dir/test.knit') |
|
1449 |
self.failIfExists('dir/test.kndx') |
|
1450 |
self.failIfExists('dir') |
|
1451 |
knit.add_lines('revid', [], ['a\n']) |
|
1452 |
self.failUnlessExists('dir') |
|
1453 |
self.failUnlessExists('dir/test.knit') |
|
1454 |
self.assertFileEqual( |
|
1455 |
"# bzr knit index 8\n" |
|
1456 |
"\n" |
|
1457 |
"revid fulltext 0 84 :", |
|
1458 |
'dir/test.kndx') |
|
1459 |
||
|
1946.2.13
by John Arbash Meinel
Test that passing modes does the right thing for knits. |
1460 |
def test_create_mode_700(self): |
1461 |
trans = get_transport('.') |
|
1462 |
if not trans._can_roundtrip_unix_modebits(): |
|
1463 |
# Can't roundtrip, so no need to run this test
|
|
1464 |
return
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1465 |
knit = make_file_knit('dir/test', trans, access_mode='w', factory=None, |
1466 |
create=True, create_parent_dir=True, delay_create=True, |
|
1467 |
file_mode=0600, dir_mode=0700) |
|
|
1946.2.13
by John Arbash Meinel
Test that passing modes does the right thing for knits. |
1468 |
knit.add_lines('revid', [], ['a\n']) |
1469 |
self.assertTransportMode(trans, 'dir', 0700) |
|
1470 |
self.assertTransportMode(trans, 'dir/test.knit', 0600) |
|
1471 |
self.assertTransportMode(trans, 'dir/test.kndx', 0600) |
|
1472 |
||
1473 |
def test_create_mode_770(self): |
|
1474 |
trans = get_transport('.') |
|
1475 |
if not trans._can_roundtrip_unix_modebits(): |
|
1476 |
# Can't roundtrip, so no need to run this test
|
|
1477 |
return
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1478 |
knit = make_file_knit('dir/test', trans, access_mode='w', factory=None, |
1479 |
create=True, create_parent_dir=True, delay_create=True, |
|
1480 |
file_mode=0660, dir_mode=0770) |
|
|
1946.2.13
by John Arbash Meinel
Test that passing modes does the right thing for knits. |
1481 |
knit.add_lines('revid', [], ['a\n']) |
1482 |
self.assertTransportMode(trans, 'dir', 0770) |
|
1483 |
self.assertTransportMode(trans, 'dir/test.knit', 0660) |
|
1484 |
self.assertTransportMode(trans, 'dir/test.kndx', 0660) |
|
1485 |
||
1486 |
def test_create_mode_777(self): |
|
1487 |
trans = get_transport('.') |
|
1488 |
if not trans._can_roundtrip_unix_modebits(): |
|
1489 |
# Can't roundtrip, so no need to run this test
|
|
1490 |
return
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
1491 |
knit = make_file_knit('dir/test', trans, access_mode='w', factory=None, |
1492 |
create=True, create_parent_dir=True, delay_create=True, |
|
1493 |
file_mode=0666, dir_mode=0777) |
|
|
1946.2.13
by John Arbash Meinel
Test that passing modes does the right thing for knits. |
1494 |
knit.add_lines('revid', [], ['a\n']) |
1495 |
self.assertTransportMode(trans, 'dir', 0777) |
|
1496 |
self.assertTransportMode(trans, 'dir/test.knit', 0666) |
|
1497 |
self.assertTransportMode(trans, 'dir/test.kndx', 0666) |
|
1498 |
||
|
1664.2.1
by Aaron Bentley
Start work on plan_merge test |
1499 |
def test_plan_merge(self): |
1500 |
my_knit = self.make_test_knit(annotate=True) |
|
1501 |
my_knit.add_lines('text1', [], split_lines(TEXT_1)) |
|
1502 |
my_knit.add_lines('text1a', ['text1'], split_lines(TEXT_1A)) |
|
1503 |
my_knit.add_lines('text1b', ['text1'], split_lines(TEXT_1B)) |
|
|
1664.2.3
by Aaron Bentley
Add failing test case |
1504 |
plan = list(my_knit.plan_merge('text1a', 'text1b')) |
|
1664.2.6
by Aaron Bentley
Got plan-merge passing tests |
1505 |
for plan_line, expected_line in zip(plan, AB_MERGE): |
1506 |
self.assertEqual(plan_line, expected_line) |
|
|
1641.1.2
by Robert Collins
Change knit index files to be robust in the presence of partial writes. |
1507 |
|
|
3370.1.4
by Andrew Bennetts
Organise data stream tests in test_knit slightly better. |
1508 |
|
1509 |
class GetDataStreamTests(KnitTests): |
|
1510 |
"""Tests for get_data_stream.""" |
|
1511 |
||
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1512 |
def test_get_stream_empty(self): |
1513 |
"""Get a data stream for an empty knit file.""" |
|
1514 |
k1 = self.make_test_knit() |
|
1515 |
format, data_list, reader_callable = k1.get_data_stream([]) |
|
|
2535.3.17
by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request. |
1516 |
self.assertEqual('knit-plain', format) |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1517 |
self.assertEqual([], data_list) |
1518 |
content = reader_callable(None) |
|
1519 |
self.assertEqual('', content) |
|
1520 |
self.assertIsInstance(content, str) |
|
1521 |
||
1522 |
def test_get_stream_one_version(self): |
|
1523 |
"""Get a data stream for a single record out of a knit containing just |
|
1524 |
one record.
|
|
1525 |
"""
|
|
1526 |
k1 = self.make_test_knit() |
|
1527 |
test_data = [ |
|
1528 |
('text-a', [], TEXT_1), |
|
1529 |
]
|
|
1530 |
expected_data_list = [ |
|
1531 |
# version, options, length, parents
|
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
1532 |
('text-a', ['fulltext'], 122, ()), |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1533 |
]
|
1534 |
for version_id, parents, lines in test_data: |
|
1535 |
k1.add_lines(version_id, parents, split_lines(lines)) |
|
1536 |
||
1537 |
format, data_list, reader_callable = k1.get_data_stream(['text-a']) |
|
|
2535.3.17
by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request. |
1538 |
self.assertEqual('knit-plain', format) |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1539 |
self.assertEqual(expected_data_list, data_list) |
1540 |
# There's only one record in the knit, so the content should be the
|
|
1541 |
# entire knit data file's contents.
|
|
|
2535.3.36
by Andrew Bennetts
Merge bzr.dev |
1542 |
self.assertEqual(k1.transport.get_bytes(k1._data._access._filename), |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1543 |
reader_callable(None)) |
1544 |
||
1545 |
def test_get_stream_get_one_version_of_many(self): |
|
1546 |
"""Get a data stream for just one version out of a knit containing many |
|
1547 |
versions.
|
|
1548 |
"""
|
|
1549 |
k1 = self.make_test_knit() |
|
1550 |
# Insert the same data as test_knit_join, as they seem to cover a range
|
|
1551 |
# of cases (no parents, one parent, multiple parents).
|
|
1552 |
test_data = [ |
|
1553 |
('text-a', [], TEXT_1), |
|
1554 |
('text-b', ['text-a'], TEXT_1), |
|
1555 |
('text-c', [], TEXT_1), |
|
1556 |
('text-d', ['text-c'], TEXT_1), |
|
1557 |
('text-m', ['text-b', 'text-d'], TEXT_1), |
|
1558 |
]
|
|
1559 |
expected_data_list = [ |
|
1560 |
# version, options, length, parents
|
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
1561 |
('text-m', ['line-delta'], 84, ('text-b', 'text-d')), |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1562 |
]
|
1563 |
for version_id, parents, lines in test_data: |
|
1564 |
k1.add_lines(version_id, parents, split_lines(lines)) |
|
1565 |
||
1566 |
format, data_list, reader_callable = k1.get_data_stream(['text-m']) |
|
|
2535.3.17
by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request. |
1567 |
self.assertEqual('knit-plain', format) |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1568 |
self.assertEqual(expected_data_list, data_list) |
1569 |
self.assertRecordContentEqual(k1, 'text-m', reader_callable(None)) |
|
1570 |
||
|
3023.2.2
by Martin Pool
Fix KnitVersionedFile.get_data_stream to not assume .versions() is sorted. (lp:165106) |
1571 |
def test_get_data_stream_unordered_index(self): |
1572 |
"""Get a data stream when the knit index reports versions out of order. |
|
1573 |
||
1574 |
https://bugs.launchpad.net/bzr/+bug/164637
|
|
1575 |
"""
|
|
1576 |
k1 = self.make_test_knit() |
|
1577 |
test_data = [ |
|
1578 |
('text-a', [], TEXT_1), |
|
1579 |
('text-b', ['text-a'], TEXT_1), |
|
1580 |
('text-c', [], TEXT_1), |
|
1581 |
('text-d', ['text-c'], TEXT_1), |
|
1582 |
('text-m', ['text-b', 'text-d'], TEXT_1), |
|
1583 |
]
|
|
1584 |
for version_id, parents, lines in test_data: |
|
1585 |
k1.add_lines(version_id, parents, split_lines(lines)) |
|
1586 |
# monkey-patch versions method to return out of order, as if coming
|
|
1587 |
# from multiple independently indexed packs
|
|
1588 |
original_versions = k1.versions |
|
1589 |
k1.versions = lambda: reversed(original_versions()) |
|
1590 |
expected_data_list = [ |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
1591 |
('text-a', ['fulltext'], 122, ()), |
1592 |
('text-b', ['line-delta'], 84, ('text-a',))] |
|
|
3023.2.2
by Martin Pool
Fix KnitVersionedFile.get_data_stream to not assume .versions() is sorted. (lp:165106) |
1593 |
# now check the fulltext is first and the delta second
|
1594 |
format, data_list, _ = k1.get_data_stream(['text-a', 'text-b']) |
|
1595 |
self.assertEqual('knit-plain', format) |
|
1596 |
self.assertEqual(expected_data_list, data_list) |
|
1597 |
# and that's true if we ask for them in the opposite order too
|
|
1598 |
format, data_list, _ = k1.get_data_stream(['text-b', 'text-a']) |
|
1599 |
self.assertEqual(expected_data_list, data_list) |
|
1600 |
# also try requesting more versions
|
|
1601 |
format, data_list, _ = k1.get_data_stream([ |
|
1602 |
'text-m', 'text-b', 'text-a']) |
|
1603 |
self.assertEqual([ |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
1604 |
('text-a', ['fulltext'], 122, ()), |
1605 |
('text-b', ['line-delta'], 84, ('text-a',)), |
|
1606 |
('text-m', ['line-delta'], 84, ('text-b', 'text-d')), |
|
|
3023.2.2
by Martin Pool
Fix KnitVersionedFile.get_data_stream to not assume .versions() is sorted. (lp:165106) |
1607 |
], data_list) |
1608 |
||
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1609 |
def test_get_stream_ghost_parent(self): |
1610 |
"""Get a data stream for a version with a ghost parent.""" |
|
1611 |
k1 = self.make_test_knit() |
|
1612 |
# Test data
|
|
1613 |
k1.add_lines('text-a', [], split_lines(TEXT_1)) |
|
1614 |
k1.add_lines_with_ghosts('text-b', ['text-a', 'text-ghost'], |
|
1615 |
split_lines(TEXT_1)) |
|
1616 |
# Expected data
|
|
1617 |
expected_data_list = [ |
|
1618 |
# version, options, length, parents
|
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
1619 |
('text-b', ['line-delta'], 84, ('text-a', 'text-ghost')), |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1620 |
]
|
1621 |
||
1622 |
format, data_list, reader_callable = k1.get_data_stream(['text-b']) |
|
|
2535.3.17
by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request. |
1623 |
self.assertEqual('knit-plain', format) |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1624 |
self.assertEqual(expected_data_list, data_list) |
1625 |
self.assertRecordContentEqual(k1, 'text-b', reader_callable(None)) |
|
1626 |
||
1627 |
def test_get_stream_get_multiple_records(self): |
|
1628 |
"""Get a stream for multiple records of a knit.""" |
|
1629 |
k1 = self.make_test_knit() |
|
1630 |
# Insert the same data as test_knit_join, as they seem to cover a range
|
|
1631 |
# of cases (no parents, one parent, multiple parents).
|
|
1632 |
test_data = [ |
|
1633 |
('text-a', [], TEXT_1), |
|
1634 |
('text-b', ['text-a'], TEXT_1), |
|
1635 |
('text-c', [], TEXT_1), |
|
1636 |
('text-d', ['text-c'], TEXT_1), |
|
1637 |
('text-m', ['text-b', 'text-d'], TEXT_1), |
|
1638 |
]
|
|
|
3023.2.3
by Martin Pool
Update tests for new ordering of results from get_data_stream - the order is not defined by the interface, but is stable |
1639 |
for version_id, parents, lines in test_data: |
1640 |
k1.add_lines(version_id, parents, split_lines(lines)) |
|
1641 |
||
1642 |
# This test is actually a bit strict as the order in which they're
|
|
1643 |
# returned is not defined. This matches the current (deterministic)
|
|
1644 |
# behaviour.
|
|
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1645 |
expected_data_list = [ |
1646 |
# version, options, length, parents
|
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
1647 |
('text-d', ['line-delta'], 84, ('text-c',)), |
1648 |
('text-b', ['line-delta'], 84, ('text-a',)), |
|
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1649 |
]
|
1650 |
# Note that even though we request the revision IDs in a particular
|
|
1651 |
# order, the data stream may return them in any order it likes. In this
|
|
1652 |
# case, they'll be in the order they were inserted into the knit.
|
|
1653 |
format, data_list, reader_callable = k1.get_data_stream( |
|
1654 |
['text-d', 'text-b']) |
|
|
2535.3.17
by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request. |
1655 |
self.assertEqual('knit-plain', format) |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1656 |
self.assertEqual(expected_data_list, data_list) |
|
3023.2.3
by Martin Pool
Update tests for new ordering of results from get_data_stream - the order is not defined by the interface, but is stable |
1657 |
# must match order they're returned
|
1658 |
self.assertRecordContentEqual(k1, 'text-d', reader_callable(84)) |
|
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1659 |
self.assertRecordContentEqual(k1, 'text-b', reader_callable(84)) |
1660 |
self.assertEqual('', reader_callable(None), |
|
1661 |
"There should be no more bytes left to read.") |
|
1662 |
||
1663 |
def test_get_stream_all(self): |
|
1664 |
"""Get a data stream for all the records in a knit. |
|
1665 |
||
1666 |
This exercises fulltext records, line-delta records, records with
|
|
1667 |
various numbers of parents, and reading multiple records out of the
|
|
1668 |
callable. These cases ought to all be exercised individually by the
|
|
1669 |
other test_get_stream_* tests; this test is basically just paranoia.
|
|
1670 |
"""
|
|
1671 |
k1 = self.make_test_knit() |
|
1672 |
# Insert the same data as test_knit_join, as they seem to cover a range
|
|
1673 |
# of cases (no parents, one parent, multiple parents).
|
|
1674 |
test_data = [ |
|
1675 |
('text-a', [], TEXT_1), |
|
1676 |
('text-b', ['text-a'], TEXT_1), |
|
1677 |
('text-c', [], TEXT_1), |
|
1678 |
('text-d', ['text-c'], TEXT_1), |
|
1679 |
('text-m', ['text-b', 'text-d'], TEXT_1), |
|
1680 |
]
|
|
|
3023.2.3
by Martin Pool
Update tests for new ordering of results from get_data_stream - the order is not defined by the interface, but is stable |
1681 |
for version_id, parents, lines in test_data: |
1682 |
k1.add_lines(version_id, parents, split_lines(lines)) |
|
1683 |
||
1684 |
# This test is actually a bit strict as the order in which they're
|
|
1685 |
# returned is not defined. This matches the current (deterministic)
|
|
1686 |
# behaviour.
|
|
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1687 |
expected_data_list = [ |
1688 |
# version, options, length, parents
|
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
1689 |
('text-a', ['fulltext'], 122, ()), |
1690 |
('text-b', ['line-delta'], 84, ('text-a',)), |
|
1691 |
('text-m', ['line-delta'], 84, ('text-b', 'text-d')), |
|
1692 |
('text-c', ['fulltext'], 121, ()), |
|
1693 |
('text-d', ['line-delta'], 84, ('text-c',)), |
|
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1694 |
]
|
1695 |
format, data_list, reader_callable = k1.get_data_stream( |
|
1696 |
['text-a', 'text-b', 'text-c', 'text-d', 'text-m']) |
|
|
2535.3.17
by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request. |
1697 |
self.assertEqual('knit-plain', format) |
|
2535.3.3
by Andrew Bennetts
Add Knit.get_data_stream. |
1698 |
self.assertEqual(expected_data_list, data_list) |
1699 |
for version_id, options, length, parents in expected_data_list: |
|
1700 |
bytes = reader_callable(length) |
|
1701 |
self.assertRecordContentEqual(k1, version_id, bytes) |
|
1702 |
||
|
3370.1.4
by Andrew Bennetts
Organise data stream tests in test_knit slightly better. |
1703 |
|
1704 |
class InsertDataStreamTests(KnitTests): |
|
1705 |
"""Tests for insert_data_stream.""" |
|
1706 |
||
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1707 |
def assertKnitFilesEqual(self, knit1, knit2): |
1708 |
"""Assert that the contents of the index and data files of two knits are |
|
1709 |
equal.
|
|
1710 |
"""
|
|
1711 |
self.assertEqual( |
|
|
2535.3.36
by Andrew Bennetts
Merge bzr.dev |
1712 |
knit1.transport.get_bytes(knit1._data._access._filename), |
1713 |
knit2.transport.get_bytes(knit2._data._access._filename)) |
|
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1714 |
self.assertEqual( |
1715 |
knit1.transport.get_bytes(knit1._index._filename), |
|
1716 |
knit2.transport.get_bytes(knit2._index._filename)) |
|
1717 |
||
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1718 |
def assertKnitValuesEqual(self, left, right): |
|
3052.2.5
by Andrew Bennetts
Address the rest of the review comments from John and myself. |
1719 |
"""Assert that the texts, annotations and graph of left and right are |
1720 |
the same.
|
|
1721 |
"""
|
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1722 |
self.assertEqual(set(left.versions()), set(right.versions())) |
1723 |
for version in left.versions(): |
|
1724 |
self.assertEqual(left.get_parents_with_ghosts(version), |
|
1725 |
right.get_parents_with_ghosts(version)) |
|
1726 |
self.assertEqual(left.get_lines(version), |
|
1727 |
right.get_lines(version)) |
|
1728 |
self.assertEqual(left.annotate(version), |
|
1729 |
right.annotate(version)) |
|
1730 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1731 |
def test_empty_stream(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1732 |
"""Inserting a data stream with no records should not put any data into |
1733 |
the knit.
|
|
1734 |
"""
|
|
1735 |
k1 = self.make_test_knit() |
|
1736 |
k1.insert_data_stream( |
|
1737 |
(k1.get_format_signature(), [], lambda ignored: '')) |
|
|
2535.3.36
by Andrew Bennetts
Merge bzr.dev |
1738 |
self.assertEqual('', k1.transport.get_bytes(k1._data._access._filename), |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1739 |
"The .knit should be completely empty.") |
1740 |
self.assertEqual(k1._index.HEADER, |
|
1741 |
k1.transport.get_bytes(k1._index._filename), |
|
1742 |
"The .kndx should have nothing apart from the header.") |
|
1743 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1744 |
def test_one_record(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1745 |
"""Inserting a data stream with one record from a knit with one record |
1746 |
results in byte-identical files.
|
|
1747 |
"""
|
|
1748 |
source = self.make_test_knit(name='source') |
|
1749 |
source.add_lines('text-a', [], split_lines(TEXT_1)) |
|
1750 |
data_stream = source.get_data_stream(['text-a']) |
|
1751 |
target = self.make_test_knit(name='target') |
|
1752 |
target.insert_data_stream(data_stream) |
|
1753 |
self.assertKnitFilesEqual(source, target) |
|
1754 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1755 |
def test_annotated_stream_into_unannotated_knit(self): |
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1756 |
"""Inserting an annotated datastream to an unannotated knit works.""" |
1757 |
# case one - full texts.
|
|
1758 |
source = self.make_test_knit(name='source', annotate=True) |
|
1759 |
target = self.make_test_knit(name='target', annotate=False) |
|
1760 |
source.add_lines('text-a', [], split_lines(TEXT_1)) |
|
1761 |
target.insert_data_stream(source.get_data_stream(['text-a'])) |
|
1762 |
self.assertKnitValuesEqual(source, target) |
|
1763 |
# case two - deltas.
|
|
1764 |
source.add_lines('text-b', ['text-a'], split_lines(TEXT_2)) |
|
1765 |
target.insert_data_stream(source.get_data_stream(['text-b'])) |
|
1766 |
self.assertKnitValuesEqual(source, target) |
|
1767 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1768 |
def test_unannotated_stream_into_annotated_knit(self): |
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
1769 |
"""Inserting an unannotated datastream to an annotated knit works.""" |
1770 |
# case one - full texts.
|
|
1771 |
source = self.make_test_knit(name='source', annotate=False) |
|
1772 |
target = self.make_test_knit(name='target', annotate=True) |
|
1773 |
source.add_lines('text-a', [], split_lines(TEXT_1)) |
|
1774 |
target.insert_data_stream(source.get_data_stream(['text-a'])) |
|
1775 |
self.assertKnitValuesEqual(source, target) |
|
1776 |
# case two - deltas.
|
|
1777 |
source.add_lines('text-b', ['text-a'], split_lines(TEXT_2)) |
|
1778 |
target.insert_data_stream(source.get_data_stream(['text-b'])) |
|
1779 |
self.assertKnitValuesEqual(source, target) |
|
1780 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1781 |
def test_records_already_present(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1782 |
"""Insert a data stream where some records are alreday present in the |
1783 |
target, and some not. Only the new records are inserted.
|
|
1784 |
"""
|
|
1785 |
source = self.make_test_knit(name='source') |
|
1786 |
target = self.make_test_knit(name='target') |
|
1787 |
# Insert 'text-a' into both source and target
|
|
1788 |
source.add_lines('text-a', [], split_lines(TEXT_1)) |
|
1789 |
target.insert_data_stream(source.get_data_stream(['text-a'])) |
|
1790 |
# Insert 'text-b' into just the source.
|
|
1791 |
source.add_lines('text-b', ['text-a'], split_lines(TEXT_1)) |
|
1792 |
# Get a data stream of both text-a and text-b, and insert it.
|
|
1793 |
data_stream = source.get_data_stream(['text-a', 'text-b']) |
|
1794 |
target.insert_data_stream(data_stream) |
|
1795 |
# The source and target will now be identical. This means the text-a
|
|
1796 |
# record was not added a second time.
|
|
1797 |
self.assertKnitFilesEqual(source, target) |
|
1798 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1799 |
def test_multiple_records(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1800 |
"""Inserting a data stream of all records from a knit with multiple |
1801 |
records results in byte-identical files.
|
|
1802 |
"""
|
|
1803 |
source = self.make_test_knit(name='source') |
|
1804 |
source.add_lines('text-a', [], split_lines(TEXT_1)) |
|
1805 |
source.add_lines('text-b', ['text-a'], split_lines(TEXT_1)) |
|
1806 |
source.add_lines('text-c', [], split_lines(TEXT_1)) |
|
1807 |
data_stream = source.get_data_stream(['text-a', 'text-b', 'text-c']) |
|
1808 |
||
1809 |
target = self.make_test_knit(name='target') |
|
1810 |
target.insert_data_stream(data_stream) |
|
1811 |
||
1812 |
self.assertKnitFilesEqual(source, target) |
|
1813 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1814 |
def test_ghost_parent(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1815 |
"""Insert a data stream with a record that has a ghost parent.""" |
1816 |
# Make a knit with a record, text-a, that has a ghost parent.
|
|
1817 |
source = self.make_test_knit(name='source') |
|
1818 |
source.add_lines_with_ghosts('text-a', ['text-ghost'], |
|
1819 |
split_lines(TEXT_1)) |
|
1820 |
data_stream = source.get_data_stream(['text-a']) |
|
1821 |
||
1822 |
target = self.make_test_knit(name='target') |
|
1823 |
target.insert_data_stream(data_stream) |
|
1824 |
||
1825 |
self.assertKnitFilesEqual(source, target) |
|
1826 |
||
1827 |
# The target knit object is in a consistent state, i.e. the record we
|
|
1828 |
# just added is immediately visible.
|
|
1829 |
self.assertTrue(target.has_version('text-a')) |
|
|
3287.6.5
by Robert Collins
Deprecate VersionedFile.has_ghost. |
1830 |
self.assertFalse(target.has_version('text-ghost')) |
1831 |
self.assertEqual({'text-a':('text-ghost',)}, |
|
1832 |
target.get_parent_map(['text-a', 'text-ghost'])) |
|
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1833 |
self.assertEqual(split_lines(TEXT_1), target.get_lines('text-a')) |
1834 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1835 |
def test_inconsistent_version_lines(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1836 |
"""Inserting a data stream which has different content for a version_id |
1837 |
than already exists in the knit will raise KnitCorrupt.
|
|
1838 |
"""
|
|
1839 |
source = self.make_test_knit(name='source') |
|
1840 |
target = self.make_test_knit(name='target') |
|
1841 |
# Insert a different 'text-a' into both source and target
|
|
1842 |
source.add_lines('text-a', [], split_lines(TEXT_1)) |
|
1843 |
target.add_lines('text-a', [], split_lines(TEXT_2)) |
|
1844 |
# Insert a data stream with conflicting content into the target
|
|
1845 |
data_stream = source.get_data_stream(['text-a']) |
|
1846 |
self.assertRaises( |
|
1847 |
errors.KnitCorrupt, target.insert_data_stream, data_stream) |
|
1848 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1849 |
def test_inconsistent_version_parents(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1850 |
"""Inserting a data stream which has different parents for a version_id |
1851 |
than already exists in the knit will raise KnitCorrupt.
|
|
1852 |
"""
|
|
1853 |
source = self.make_test_knit(name='source') |
|
1854 |
target = self.make_test_knit(name='target') |
|
1855 |
# Insert a different 'text-a' into both source and target. They differ
|
|
1856 |
# only by the parents list, the content is the same.
|
|
1857 |
source.add_lines_with_ghosts('text-a', [], split_lines(TEXT_1)) |
|
1858 |
target.add_lines_with_ghosts('text-a', ['a-ghost'], split_lines(TEXT_1)) |
|
1859 |
# Insert a data stream with conflicting content into the target
|
|
1860 |
data_stream = source.get_data_stream(['text-a']) |
|
1861 |
self.assertRaises( |
|
1862 |
errors.KnitCorrupt, target.insert_data_stream, data_stream) |
|
1863 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1864 |
def test_unknown_stream_format(self): |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1865 |
"""A data stream in a different format to the target knit cannot be |
1866 |
inserted.
|
|
1867 |
||
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1868 |
It will raise KnitDataStreamUnknown because the fallback code will fail
|
1869 |
to make a knit. In future we may need KnitDataStreamIncompatible again,
|
|
1870 |
for more exotic cases.
|
|
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1871 |
"""
|
1872 |
data_stream = ('fake-format-signature', [], lambda _: '') |
|
1873 |
target = self.make_test_knit(name='target') |
|
1874 |
self.assertRaises( |
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1875 |
errors.KnitDataStreamUnknown, |
|
2535.3.4
by Andrew Bennetts
Simple implementation of Knit.insert_data_stream. |
1876 |
target.insert_data_stream, data_stream) |
1877 |
||
|
3370.1.5
by Andrew Bennetts
Rename test methods to be a little clearer after reorganisation. |
1878 |
def test_bug_208418(self): |
|
3287.7.4
by Andrew Bennetts
Failing test for bug 208418. |
1879 |
"""You can insert a stream with an incompatible format, even when: |
1880 |
* the stream has a line-delta record,
|
|
1881 |
* whose parent is in the target, also stored as a line-delta
|
|
1882 |
||
1883 |
See <https://launchpad.net/bugs/208418>.
|
|
1884 |
"""
|
|
1885 |
base_lines = split_lines(TEXT_1) |
|
1886 |
# Make the target
|
|
1887 |
target = self.make_test_knit(name='target', annotate=True) |
|
1888 |
target.add_lines('version-1', [], base_lines) |
|
1889 |
target.add_lines('version-2', ['version-1'], base_lines + ['a\n']) |
|
1890 |
# The second record should be a delta.
|
|
1891 |
self.assertEqual('line-delta', target._index.get_method('version-2')) |
|
1892 |
||
1893 |
# Make a source, with a different format, but the same data
|
|
1894 |
source = self.make_test_knit(name='source', annotate=False) |
|
1895 |
source.add_lines('version-1', [], base_lines) |
|
1896 |
source.add_lines('version-2', ['version-1'], base_lines + ['a\n']) |
|
1897 |
# Now add another record, which should be stored as a delta against
|
|
1898 |
# version-2.
|
|
1899 |
source.add_lines('version-3', ['version-2'], base_lines + ['b\n']) |
|
1900 |
self.assertEqual('line-delta', source._index.get_method('version-3')) |
|
1901 |
||
1902 |
# Make a stream of the new version
|
|
1903 |
data_stream = source.get_data_stream(['version-3']) |
|
1904 |
# And insert into the target
|
|
1905 |
target.insert_data_stream(data_stream) |
|
1906 |
# No errors should have been raised.
|
|
1907 |
||
|
3370.1.6
by Andrew Bennetts
Add test for line-deltas inserted into a non-delta knit. |
1908 |
def test_line_delta_record_into_non_delta_knit(self): |
1909 |
# Make a data stream with a line-delta record
|
|
1910 |
source = self.make_test_knit(name='source', delta=True) |
|
1911 |
base_lines = split_lines(TEXT_1) |
|
1912 |
source.add_lines('version-1', [], base_lines) |
|
1913 |
source.add_lines('version-2', ['version-1'], base_lines + ['a\n']) |
|
1914 |
# The second record should be a delta.
|
|
1915 |
self.assertEqual('line-delta', source._index.get_method('version-2')) |
|
1916 |
data_stream = source.get_data_stream(['version-1', 'version-2']) |
|
1917 |
||
1918 |
# Insert the stream into a non-delta knit.
|
|
1919 |
target = self.make_test_knit(name='target', delta=False) |
|
1920 |
target.insert_data_stream(data_stream) |
|
1921 |
||
1922 |
# Both versions are fulltexts in the target
|
|
1923 |
self.assertEqual('fulltext', target._index.get_method('version-1')) |
|
1924 |
self.assertEqual('fulltext', target._index.get_method('version-2')) |
|
|
3360.2.9
by Martin Pool
merge #205156 |
1925 |
|
1926 |
||
|
3370.1.4
by Andrew Bennetts
Organise data stream tests in test_knit slightly better. |
1927 |
class DataStreamTests(KnitTests): |
1928 |
||
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1929 |
def assertMadeStreamKnit(self, source_knit, versions, target_knit): |
1930 |
"""Assert that a knit made from a stream is as expected.""" |
|
1931 |
a_stream = source_knit.get_data_stream(versions) |
|
1932 |
expected_data = a_stream[2](None) |
|
1933 |
a_stream = source_knit.get_data_stream(versions) |
|
1934 |
a_knit = target_knit._knit_from_datastream(a_stream) |
|
1935 |
self.assertEqual(source_knit.factory.__class__, |
|
1936 |
a_knit.factory.__class__) |
|
1937 |
self.assertIsInstance(a_knit._data._access, _StreamAccess) |
|
1938 |
self.assertIsInstance(a_knit._index, _StreamIndex) |
|
1939 |
self.assertEqual(a_knit._index.data_list, a_stream[1]) |
|
1940 |
self.assertEqual(a_knit._data._access.data, expected_data) |
|
1941 |
self.assertEqual(a_knit.filename, target_knit.filename) |
|
1942 |
self.assertEqual(a_knit.transport, target_knit.transport) |
|
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
1943 |
self.assertEqual(a_knit._index, a_knit._data._access.stream_index) |
1944 |
self.assertEqual(target_knit, a_knit._data._access.backing_knit) |
|
1945 |
self.assertIsInstance(a_knit._data._access.orig_factory, |
|
1946 |
source_knit.factory.__class__) |
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
1947 |
|
1948 |
def test__knit_from_data_stream_empty(self): |
|
1949 |
"""Create a knit object from a datastream.""" |
|
1950 |
annotated = self.make_test_knit(name='source', annotate=True) |
|
1951 |
plain = self.make_test_knit(name='target', annotate=False) |
|
1952 |
# case 1: annotated source
|
|
1953 |
self.assertMadeStreamKnit(annotated, [], annotated) |
|
1954 |
self.assertMadeStreamKnit(annotated, [], plain) |
|
1955 |
# case 2: plain source
|
|
1956 |
self.assertMadeStreamKnit(plain, [], annotated) |
|
1957 |
self.assertMadeStreamKnit(plain, [], plain) |
|
1958 |
||
1959 |
def test__knit_from_data_stream_unknown_format(self): |
|
1960 |
annotated = self.make_test_knit(name='source', annotate=True) |
|
1961 |
self.assertRaises(errors.KnitDataStreamUnknown, |
|
1962 |
annotated._knit_from_datastream, ("unknown", None, None)) |
|
1963 |
||
1964 |
||
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1965 |
TEXT_1 = """\ |
1966 |
Banana cup cakes:
|
|
1967 |
||
1968 |
- bananas
|
|
1969 |
- eggs
|
|
1970 |
- broken tea cups
|
|
1971 |
"""
|
|
1972 |
||
1973 |
TEXT_1A = """\ |
|
1974 |
Banana cup cake recipe
|
|
1975 |
(serves 6)
|
|
1976 |
||
1977 |
- bananas
|
|
1978 |
- eggs
|
|
1979 |
- broken tea cups
|
|
1980 |
- self-raising flour
|
|
1981 |
"""
|
|
1982 |
||
|
1664.2.1
by Aaron Bentley
Start work on plan_merge test |
1983 |
TEXT_1B = """\ |
1984 |
Banana cup cake recipe
|
|
1985 |
||
1986 |
- bananas (do not use plantains!!!)
|
|
1987 |
- broken tea cups
|
|
1988 |
- flour
|
|
1989 |
"""
|
|
1990 |
||
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
1991 |
delta_1_1a = """\ |
1992 |
0,1,2
|
|
1993 |
Banana cup cake recipe
|
|
1994 |
(serves 6)
|
|
1995 |
5,5,1
|
|
1996 |
- self-raising flour
|
|
1997 |
"""
|
|
1998 |
||
1999 |
TEXT_2 = """\ |
|
2000 |
Boeuf bourguignon
|
|
2001 |
||
2002 |
- beef
|
|
2003 |
- red wine
|
|
2004 |
- small onions
|
|
2005 |
- carrot
|
|
2006 |
- mushrooms
|
|
2007 |
"""
|
|
2008 |
||
|
1664.2.3
by Aaron Bentley
Add failing test case |
2009 |
AB_MERGE_TEXT="""unchanged|Banana cup cake recipe |
2010 |
new-a|(serves 6)
|
|
2011 |
unchanged|
|
|
2012 |
killed-b|- bananas
|
|
2013 |
killed-b|- eggs
|
|
2014 |
new-b|- bananas (do not use plantains!!!)
|
|
2015 |
unchanged|- broken tea cups
|
|
2016 |
new-a|- self-raising flour
|
|
|
1664.2.6
by Aaron Bentley
Got plan-merge passing tests |
2017 |
new-b|- flour
|
2018 |
"""
|
|
|
1664.2.3
by Aaron Bentley
Add failing test case |
2019 |
AB_MERGE=[tuple(l.split('|')) for l in AB_MERGE_TEXT.splitlines(True)] |
2020 |
||
2021 |
||
|
1563.2.4
by Robert Collins
First cut at including the knit implementation of versioned_file. |
2022 |
def line_delta(from_lines, to_lines): |
2023 |
"""Generate line-based delta from one text to another""" |
|
2024 |
s = difflib.SequenceMatcher(None, from_lines, to_lines) |
|
2025 |
for op in s.get_opcodes(): |
|
2026 |
if op[0] == 'equal': |
|
2027 |
continue
|
|
2028 |
yield '%d,%d,%d\n' % (op[1], op[2], op[4]-op[3]) |
|
2029 |
for i in range(op[3], op[4]): |
|
2030 |
yield to_lines[i] |
|
2031 |
||
2032 |
||
2033 |
def apply_line_delta(basis_lines, delta_lines): |
|
2034 |
"""Apply a line-based perfect diff |
|
2035 |
|
|
2036 |
basis_lines -- text to apply the patch to
|
|
2037 |
delta_lines -- diff instructions and content
|
|
2038 |
"""
|
|
2039 |
out = basis_lines[:] |
|
2040 |
i = 0 |
|
2041 |
offset = 0 |
|
2042 |
while i < len(delta_lines): |
|
2043 |
l = delta_lines[i] |
|
2044 |
a, b, c = map(long, l.split(',')) |
|
2045 |
i = i + 1 |
|
2046 |
out[offset+a:offset+b] = delta_lines[i:i+c] |
|
2047 |
i = i + c |
|
2048 |
offset = offset + (b - a) + c |
|
2049 |
return out |
|
|
1684.3.3
by Robert Collins
Add a special cased weaves to knit converter. |
2050 |
|
2051 |
||
2052 |
class TestWeaveToKnit(KnitTests): |
|
2053 |
||
2054 |
def test_weave_to_knit_matches(self): |
|
2055 |
# check that the WeaveToKnit is_compatible function
|
|
2056 |
# registers True for a Weave to a Knit.
|
|
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
2057 |
w = Weave(get_scope=lambda:None) |
|
1684.3.3
by Robert Collins
Add a special cased weaves to knit converter. |
2058 |
k = self.make_test_knit() |
2059 |
self.failUnless(WeaveToKnit.is_compatible(w, k)) |
|
2060 |
self.failIf(WeaveToKnit.is_compatible(k, w)) |
|
2061 |
self.failIf(WeaveToKnit.is_compatible(w, w)) |
|
2062 |
self.failIf(WeaveToKnit.is_compatible(k, k)) |
|
|
1863.1.1
by John Arbash Meinel
Allow Versioned files to do caching if explicitly asked, and implement for Knit |
2063 |
|
2064 |
||
|
2102.2.1
by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions |
2065 |
class TestKnitIndex(KnitTests): |
2066 |
||
2067 |
def test_add_versions_dictionary_compresses(self): |
|
2068 |
"""Adding versions to the index should update the lookup dict""" |
|
2069 |
knit = self.make_test_knit() |
|
2070 |
idx = knit._index |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
2071 |
idx.add_version('a-1', ['fulltext'], (None, 0, 0), []) |
|
2102.2.1
by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions |
2072 |
self.check_file_contents('test.kndx', |
2073 |
'# bzr knit index 8\n' |
|
2074 |
'\n' |
|
2075 |
'a-1 fulltext 0 0 :'
|
|
2076 |
)
|
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
2077 |
idx.add_versions([('a-2', ['fulltext'], (None, 0, 0), ['a-1']), |
2078 |
('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 |
2079 |
])
|
2080 |
self.check_file_contents('test.kndx', |
|
2081 |
'# bzr knit index 8\n' |
|
2082 |
'\n' |
|
2083 |
'a-1 fulltext 0 0 :\n' |
|
2084 |
'a-2 fulltext 0 0 0 :\n' |
|
2085 |
'a-3 fulltext 0 0 1 :'
|
|
2086 |
)
|
|
2087 |
self.assertEqual(['a-1', 'a-2', 'a-3'], idx._history) |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
2088 |
self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, (), 0), |
2089 |
'a-2':('a-2', ['fulltext'], 0, 0, ('a-1',), 1), |
|
2090 |
'a-3':('a-3', ['fulltext'], 0, 0, ('a-2',), 2), |
|
|
2102.2.1
by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions |
2091 |
}, idx._cache) |
2092 |
||
2093 |
def test_add_versions_fails_clean(self): |
|
2094 |
"""If add_versions fails in the middle, it restores a pristine state. |
|
2095 |
||
2096 |
Any modifications that are made to the index are reset if all versions
|
|
2097 |
cannot be added.
|
|
2098 |
"""
|
|
2099 |
# This cheats a little bit by passing in a generator which will
|
|
2100 |
# raise an exception before the processing finishes
|
|
2101 |
# Other possibilities would be to have an version with the wrong number
|
|
2102 |
# of entries, or to make the backing transport unable to write any
|
|
2103 |
# files.
|
|
2104 |
||
2105 |
knit = self.make_test_knit() |
|
2106 |
idx = knit._index |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
2107 |
idx.add_version('a-1', ['fulltext'], (None, 0, 0), []) |
|
2102.2.1
by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions |
2108 |
|
2109 |
class StopEarly(Exception): |
|
2110 |
pass
|
|
2111 |
||
2112 |
def generate_failure(): |
|
2113 |
"""Add some entries and then raise an exception""" |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
2114 |
yield ('a-2', ['fulltext'], (None, 0, 0), ('a-1',)) |
2115 |
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 |
2116 |
raise StopEarly() |
2117 |
||
2118 |
# Assert the pre-condition
|
|
2119 |
self.assertEqual(['a-1'], idx._history) |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
2120 |
self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, (), 0)}, idx._cache) |
|
2102.2.1
by John Arbash Meinel
Fix bug #64789 _KnitIndex.add_versions() should dict compress new revisions |
2121 |
|
2122 |
self.assertRaises(StopEarly, idx.add_versions, generate_failure()) |
|
2123 |
||
2124 |
# And it shouldn't be modified
|
|
2125 |
self.assertEqual(['a-1'], idx._history) |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
2126 |
self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, (), 0)}, idx._cache) |
|
2171.1.1
by John Arbash Meinel
Knit index files should ignore empty indexes rather than consider them corrupt. |
2127 |
|
2128 |
def test_knit_index_ignores_empty_files(self): |
|
2129 |
# There was a race condition in older bzr, where a ^C at the right time
|
|
2130 |
# could leave an empty .kndx file, which bzr would later claim was a
|
|
2131 |
# corrupted file since the header was not present. In reality, the file
|
|
2132 |
# just wasn't created, so it should be ignored.
|
|
2133 |
t = get_transport('.') |
|
2134 |
t.put_bytes('test.kndx', '') |
|
2135 |
||
2136 |
knit = self.make_test_knit() |
|
2137 |
||
2138 |
def test_knit_index_checks_header(self): |
|
2139 |
t = get_transport('.') |
|
2140 |
t.put_bytes('test.kndx', '# not really a knit header\n\n') |
|
2141 |
||
|
2196.2.1
by John Arbash Meinel
Merge Dmitry's optimizations and minimize the actual diff. |
2142 |
self.assertRaises(KnitHeaderError, self.make_test_knit) |
|
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. |
2143 |
|
2144 |
||
2145 |
class TestGraphIndexKnit(KnitTests): |
|
2146 |
"""Tests for knits using a GraphIndex rather than a KnitIndex.""" |
|
2147 |
||
2148 |
def make_g_index(self, name, ref_lists=0, nodes=[]): |
|
2149 |
builder = GraphIndexBuilder(ref_lists) |
|
2150 |
for node, references, value in nodes: |
|
2151 |
builder.add_node(node, references, value) |
|
2152 |
stream = builder.finish() |
|
2153 |
trans = self.get_transport() |
|
|
2890.2.1
by Robert Collins
* ``bzrlib.index.GraphIndex`` now requires a size parameter to the |
2154 |
size = trans.put_file(name, stream) |
2155 |
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. |
2156 |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2157 |
def two_graph_index(self, deltas=False, catch_adds=False): |
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2158 |
"""Build a two-graph index. |
2159 |
||
2160 |
:param deltas: If true, use underlying indices with two node-ref
|
|
2161 |
lists and 'parent' set to a delta-compressed against tail.
|
|
2162 |
"""
|
|
|
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. |
2163 |
# build a complex graph across several indices.
|
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2164 |
if deltas: |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2165 |
# delta compression inn the index
|
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2166 |
index1 = self.make_g_index('1', 2, [ |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2167 |
(('tip', ), 'N0 100', ([('parent', )], [], )), |
2168 |
(('tail', ), '', ([], []))]) |
|
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2169 |
index2 = self.make_g_index('2', 2, [ |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2170 |
(('parent', ), ' 100 78', ([('tail', ), ('ghost', )], [('tail', )])), |
2171 |
(('separate', ), '', ([], []))]) |
|
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2172 |
else: |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2173 |
# just blob location and graph in the index.
|
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2174 |
index1 = self.make_g_index('1', 1, [ |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2175 |
(('tip', ), 'N0 100', ([('parent', )], )), |
2176 |
(('tail', ), '', ([], ))]) |
|
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2177 |
index2 = self.make_g_index('2', 1, [ |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2178 |
(('parent', ), ' 100 78', ([('tail', ), ('ghost', )], )), |
2179 |
(('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. |
2180 |
combined_index = CombinedGraphIndex([index1, index2]) |
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2181 |
if catch_adds: |
2182 |
self.combined_index = combined_index |
|
2183 |
self.caught_entries = [] |
|
2184 |
add_callback = self.catch_add |
|
2185 |
else: |
|
2186 |
add_callback = None |
|
2187 |
return KnitGraphIndex(combined_index, deltas=deltas, |
|
2188 |
add_callback=add_callback) |
|
|
2592.3.4
by Robert Collins
Implement get_ancestry/get_ancestry_with_ghosts for KnitGraphIndex. |
2189 |
|
2190 |
def test_get_ancestry(self): |
|
|
2592.3.30
by Robert Collins
Make GraphKnitIndex get_ancestry the same as regular knits. |
2191 |
# get_ancestry is defined as eliding ghosts, not erroring.
|
2192 |
index = self.two_graph_index() |
|
|
2592.3.4
by Robert Collins
Implement get_ancestry/get_ancestry_with_ghosts for KnitGraphIndex. |
2193 |
self.assertEqual([], index.get_ancestry([])) |
2194 |
self.assertEqual(['separate'], index.get_ancestry(['separate'])) |
|
2195 |
self.assertEqual(['tail'], index.get_ancestry(['tail'])) |
|
2196 |
self.assertEqual(['tail', 'parent'], index.get_ancestry(['parent'])) |
|
2197 |
self.assertEqual(['tail', 'parent', 'tip'], index.get_ancestry(['tip'])) |
|
2198 |
self.assertTrue(index.get_ancestry(['tip', 'separate']) in |
|
2199 |
(['tail', 'parent', 'tip', 'separate'], |
|
2200 |
['separate', 'tail', 'parent', 'tip'], |
|
2201 |
))
|
|
2202 |
# and without topo_sort
|
|
2203 |
self.assertEqual(set(['separate']), |
|
2204 |
set(index.get_ancestry(['separate'], topo_sorted=False))) |
|
2205 |
self.assertEqual(set(['tail']), |
|
2206 |
set(index.get_ancestry(['tail'], topo_sorted=False))) |
|
2207 |
self.assertEqual(set(['tail', 'parent']), |
|
2208 |
set(index.get_ancestry(['parent'], topo_sorted=False))) |
|
2209 |
self.assertEqual(set(['tail', 'parent', 'tip']), |
|
2210 |
set(index.get_ancestry(['tip'], topo_sorted=False))) |
|
2211 |
self.assertEqual(set(['separate', 'tail', 'parent', 'tip']), |
|
2212 |
set(index.get_ancestry(['tip', 'separate']))) |
|
|
2592.3.30
by Robert Collins
Make GraphKnitIndex get_ancestry the same as regular knits. |
2213 |
# asking for a ghost makes it go boom.
|
2214 |
self.assertRaises(errors.RevisionNotPresent, index.get_ancestry, ['ghost']) |
|
|
2592.3.4
by Robert Collins
Implement get_ancestry/get_ancestry_with_ghosts for KnitGraphIndex. |
2215 |
|
2216 |
def test_get_ancestry_with_ghosts(self): |
|
2217 |
index = self.two_graph_index() |
|
2218 |
self.assertEqual([], index.get_ancestry_with_ghosts([])) |
|
2219 |
self.assertEqual(['separate'], index.get_ancestry_with_ghosts(['separate'])) |
|
2220 |
self.assertEqual(['tail'], index.get_ancestry_with_ghosts(['tail'])) |
|
2221 |
self.assertTrue(index.get_ancestry_with_ghosts(['parent']) in |
|
2222 |
(['tail', 'ghost', 'parent'], |
|
2223 |
['ghost', 'tail', 'parent'], |
|
2224 |
))
|
|
2225 |
self.assertTrue(index.get_ancestry_with_ghosts(['tip']) in |
|
2226 |
(['tail', 'ghost', 'parent', 'tip'], |
|
2227 |
['ghost', 'tail', 'parent', 'tip'], |
|
2228 |
))
|
|
2229 |
self.assertTrue(index.get_ancestry_with_ghosts(['tip', 'separate']) in |
|
2230 |
(['tail', 'ghost', 'parent', 'tip', 'separate'], |
|
2231 |
['ghost', 'tail', 'parent', 'tip', 'separate'], |
|
2232 |
['separate', 'tail', 'ghost', 'parent', 'tip'], |
|
2233 |
['separate', 'ghost', 'tail', 'parent', 'tip'], |
|
2234 |
))
|
|
|
2592.3.30
by Robert Collins
Make GraphKnitIndex get_ancestry the same as regular knits. |
2235 |
# asking for a ghost makes it go boom.
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2236 |
self.assertRaises(errors.RevisionNotPresent, index.get_ancestry_with_ghosts, ['ghost']) |
|
2592.3.5
by Robert Collins
Implement KnitGraphIndex.num_versions. |
2237 |
|
2238 |
def test_num_versions(self): |
|
2239 |
index = self.two_graph_index() |
|
2240 |
self.assertEqual(4, index.num_versions()) |
|
|
2592.3.6
by Robert Collins
Implement KnitGraphIndex.get_versions. |
2241 |
|
2242 |
def test_get_versions(self): |
|
2243 |
index = self.two_graph_index() |
|
2244 |
self.assertEqual(set(['tail', 'tip', 'parent', 'separate']), |
|
2245 |
set(index.get_versions())) |
|
2246 |
||
|
2592.3.9
by Robert Collins
Implement KnitGraphIndex.has_version. |
2247 |
def test_has_version(self): |
2248 |
index = self.two_graph_index() |
|
2249 |
self.assertTrue(index.has_version('tail')) |
|
2250 |
self.assertFalse(index.has_version('ghost')) |
|
2251 |
||
|
2592.3.10
by Robert Collins
Implement KnitGraphIndex.get_position. |
2252 |
def test_get_position(self): |
2253 |
index = self.two_graph_index() |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
2254 |
self.assertEqual((index._graph_index._indices[0], 0, 100), index.get_position('tip')) |
2255 |
self.assertEqual((index._graph_index._indices[1], 100, 78), index.get_position('parent')) |
|
|
2592.3.10
by Robert Collins
Implement KnitGraphIndex.get_position. |
2256 |
|
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2257 |
def test_get_method_deltas(self): |
2258 |
index = self.two_graph_index(deltas=True) |
|
|
2592.3.11
by Robert Collins
Implement KnitGraphIndex.get_method. |
2259 |
self.assertEqual('fulltext', index.get_method('tip')) |
2260 |
self.assertEqual('line-delta', index.get_method('parent')) |
|
2261 |
||
|
2592.3.13
by Robert Collins
Implement KnitGraphIndex.get_method. |
2262 |
def test_get_method_no_deltas(self): |
2263 |
# check that the parent-history lookup is ignored with deltas=False.
|
|
2264 |
index = self.two_graph_index(deltas=False) |
|
2265 |
self.assertEqual('fulltext', index.get_method('tip')) |
|
2266 |
self.assertEqual('fulltext', index.get_method('parent')) |
|
2267 |
||
|
2592.3.14
by Robert Collins
Implement KnitGraphIndex.get_options. |
2268 |
def test_get_options_deltas(self): |
2269 |
index = self.two_graph_index(deltas=True) |
|
|
2658.2.1
by Robert Collins
Fix mismatch between KnitGraphIndex and KnitIndex in get_options. |
2270 |
self.assertEqual(['fulltext', 'no-eol'], index.get_options('tip')) |
2271 |
self.assertEqual(['line-delta'], index.get_options('parent')) |
|
|
2592.3.14
by Robert Collins
Implement KnitGraphIndex.get_options. |
2272 |
|
2273 |
def test_get_options_no_deltas(self): |
|
2274 |
# check that the parent-history lookup is ignored with deltas=False.
|
|
2275 |
index = self.two_graph_index(deltas=False) |
|
|
2658.2.1
by Robert Collins
Fix mismatch between KnitGraphIndex and KnitIndex in get_options. |
2276 |
self.assertEqual(['fulltext', 'no-eol'], index.get_options('tip')) |
2277 |
self.assertEqual(['fulltext'], index.get_options('parent')) |
|
|
2592.3.14
by Robert Collins
Implement KnitGraphIndex.get_options. |
2278 |
|
|
2592.3.15
by Robert Collins
Implement KnitGraphIndex.get_parents/get_parents_with_ghosts. |
2279 |
def test_get_parents_with_ghosts(self): |
2280 |
index = self.two_graph_index() |
|
2281 |
self.assertEqual(('tail', 'ghost'), index.get_parents_with_ghosts('parent')) |
|
|
2592.3.43
by Robert Collins
A knit iter_parents API. |
2282 |
# and errors on ghosts.
|
2283 |
self.assertRaises(errors.RevisionNotPresent, |
|
2284 |
index.get_parents_with_ghosts, 'ghost') |
|
|
2592.3.15
by Robert Collins
Implement KnitGraphIndex.get_parents/get_parents_with_ghosts. |
2285 |
|
|
2592.3.16
by Robert Collins
Implement KnitGraphIndex.check_versions_present. |
2286 |
def test_check_versions_present(self): |
2287 |
# ghosts should not be considered present
|
|
2288 |
index = self.two_graph_index() |
|
2289 |
self.assertRaises(RevisionNotPresent, index.check_versions_present, |
|
2290 |
['ghost']) |
|
2291 |
self.assertRaises(RevisionNotPresent, index.check_versions_present, |
|
2292 |
['tail', 'ghost']) |
|
2293 |
index.check_versions_present(['tail', 'separate']) |
|
|
2592.3.14
by Robert Collins
Implement KnitGraphIndex.get_options. |
2294 |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2295 |
def catch_add(self, entries): |
2296 |
self.caught_entries.append(entries) |
|
2297 |
||
2298 |
def test_add_no_callback_errors(self): |
|
2299 |
index = self.two_graph_index() |
|
2300 |
self.assertRaises(errors.ReadOnlyError, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2301 |
'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. |
2302 |
|
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2303 |
def test_add_version_smoke(self): |
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2304 |
index = self.two_graph_index(catch_adds=True) |
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2305 |
index.add_version('new', 'fulltext,no-eol', (None, 50, 60), ['separate']) |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2306 |
self.assertEqual([[(('new', ), 'N50 60', ((('separate',),),))]], |
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2307 |
self.caught_entries) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2308 |
|
2309 |
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. |
2310 |
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. |
2311 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2312 |
'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. |
2313 |
self.assertEqual([], self.caught_entries) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2314 |
|
2315 |
def test_add_version_same_dup(self): |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2316 |
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. |
2317 |
# options can be spelt two different ways
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2318 |
index.add_version('tip', 'fulltext,no-eol', (None, 0, 100), ['parent']) |
2319 |
index.add_version('tip', 'no-eol,fulltext', (None, 0, 100), ['parent']) |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2320 |
# but neither should have added data.
|
2321 |
self.assertEqual([[], []], self.caught_entries) |
|
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2322 |
|
2323 |
def test_add_version_different_dup(self): |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2324 |
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. |
2325 |
# change options
|
2326 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2327 |
'tip', 'no-eol,line-delta', (None, 0, 100), ['parent']) |
2328 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
2329 |
'tip', 'line-delta,no-eol', (None, 0, 100), ['parent']) |
|
2330 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
2331 |
'tip', 'fulltext', (None, 0, 100), ['parent']) |
|
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2332 |
# position/length
|
2333 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2334 |
'tip', 'fulltext,no-eol', (None, 50, 100), ['parent']) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2335 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2336 |
'tip', 'fulltext,no-eol', (None, 0, 1000), ['parent']) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2337 |
# parents
|
2338 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2339 |
'tip', 'fulltext,no-eol', (None, 0, 100), []) |
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2340 |
self.assertEqual([], self.caught_entries) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2341 |
|
2342 |
def test_add_versions_nodeltas(self): |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2343 |
index = self.two_graph_index(catch_adds=True) |
2344 |
index.add_versions([ |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2345 |
('new', 'fulltext,no-eol', (None, 50, 60), ['separate']), |
2346 |
('new2', 'fulltext', (None, 0, 6), ['new']), |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2347 |
])
|
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2348 |
self.assertEqual([(('new', ), 'N50 60', ((('separate',),),)), |
2349 |
(('new2', ), ' 0 6', ((('new',),),))], |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2350 |
sorted(self.caught_entries[0])) |
2351 |
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. |
2352 |
|
2353 |
def test_add_versions_deltas(self): |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2354 |
index = self.two_graph_index(deltas=True, catch_adds=True) |
2355 |
index.add_versions([ |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2356 |
('new', 'fulltext,no-eol', (None, 50, 60), ['separate']), |
2357 |
('new2', 'line-delta', (None, 0, 6), ['new']), |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2358 |
])
|
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2359 |
self.assertEqual([(('new', ), 'N50 60', ((('separate',),), ())), |
2360 |
(('new2', ), ' 0 6', ((('new',),), (('new',),), ))], |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2361 |
sorted(self.caught_entries[0])) |
2362 |
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. |
2363 |
|
2364 |
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. |
2365 |
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. |
2366 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2367 |
[('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. |
2368 |
self.assertEqual([], self.caught_entries) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2369 |
|
|
2841.2.1
by Robert Collins
* Commit no longer checks for new text keys during insertion when the |
2370 |
def test_add_versions_random_id_accepted(self): |
2371 |
index = self.two_graph_index(catch_adds=True) |
|
2372 |
index.add_versions([], random_id=True) |
|
2373 |
||
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2374 |
def test_add_versions_same_dup(self): |
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2375 |
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. |
2376 |
# options can be spelt two different ways
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2377 |
index.add_versions([('tip', 'fulltext,no-eol', (None, 0, 100), ['parent'])]) |
2378 |
index.add_versions([('tip', 'no-eol,fulltext', (None, 0, 100), ['parent'])]) |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2379 |
# but neither should have added data.
|
2380 |
self.assertEqual([[], []], self.caught_entries) |
|
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2381 |
|
2382 |
def test_add_versions_different_dup(self): |
|
|
2592.3.19
by Robert Collins
Change KnitGraphIndex from returning data to performing a callback on insertions. |
2383 |
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. |
2384 |
# change options
|
2385 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2386 |
[('tip', 'no-eol,line-delta', (None, 0, 100), ['parent'])]) |
2387 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
2388 |
[('tip', 'line-delta,no-eol', (None, 0, 100), ['parent'])]) |
|
2389 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
2390 |
[('tip', 'fulltext', (None, 0, 100), ['parent'])]) |
|
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2391 |
# position/length
|
2392 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2393 |
[('tip', 'fulltext,no-eol', (None, 50, 100), ['parent'])]) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2394 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2395 |
[('tip', 'fulltext,no-eol', (None, 0, 1000), ['parent'])]) |
|
2592.3.17
by Robert Collins
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. |
2396 |
# parents
|
2397 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2398 |
[('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. |
2399 |
# change options in the second record
|
2400 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2401 |
[('tip', 'fulltext,no-eol', (None, 0, 100), ['parent']), |
2402 |
('tip', '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. |
2403 |
self.assertEqual([], self.caught_entries) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2404 |
|
2405 |
class TestNoParentsGraphIndexKnit(KnitTests): |
|
2406 |
"""Tests for knits using KnitGraphIndex with no parents.""" |
|
2407 |
||
2408 |
def make_g_index(self, name, ref_lists=0, nodes=[]): |
|
2409 |
builder = GraphIndexBuilder(ref_lists) |
|
2410 |
for node, references in nodes: |
|
2411 |
builder.add_node(node, references) |
|
2412 |
stream = builder.finish() |
|
2413 |
trans = self.get_transport() |
|
|
2890.2.1
by Robert Collins
* ``bzrlib.index.GraphIndex`` now requires a size parameter to the |
2414 |
size = trans.put_file(name, stream) |
2415 |
return GraphIndex(trans, name, size) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2416 |
|
2417 |
def test_parents_deltas_incompatible(self): |
|
2418 |
index = CombinedGraphIndex([]) |
|
2419 |
self.assertRaises(errors.KnitError, KnitGraphIndex, index, |
|
2420 |
deltas=True, parents=False) |
|
2421 |
||
2422 |
def two_graph_index(self, catch_adds=False): |
|
2423 |
"""Build a two-graph index. |
|
2424 |
||
2425 |
:param deltas: If true, use underlying indices with two node-ref
|
|
2426 |
lists and 'parent' set to a delta-compressed against tail.
|
|
2427 |
"""
|
|
2428 |
# put several versions in the index.
|
|
2429 |
index1 = self.make_g_index('1', 0, [ |
|
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2430 |
(('tip', ), 'N0 100'), |
2431 |
(('tail', ), '')]) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2432 |
index2 = self.make_g_index('2', 0, [ |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2433 |
(('parent', ), ' 100 78'), |
2434 |
(('separate', ), '')]) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2435 |
combined_index = CombinedGraphIndex([index1, index2]) |
2436 |
if catch_adds: |
|
2437 |
self.combined_index = combined_index |
|
2438 |
self.caught_entries = [] |
|
2439 |
add_callback = self.catch_add |
|
2440 |
else: |
|
2441 |
add_callback = None |
|
2442 |
return KnitGraphIndex(combined_index, parents=False, |
|
2443 |
add_callback=add_callback) |
|
2444 |
||
2445 |
def test_get_ancestry(self): |
|
2446 |
# with no parents, ancestry is always just the key.
|
|
2447 |
index = self.two_graph_index() |
|
2448 |
self.assertEqual([], index.get_ancestry([])) |
|
2449 |
self.assertEqual(['separate'], index.get_ancestry(['separate'])) |
|
2450 |
self.assertEqual(['tail'], index.get_ancestry(['tail'])) |
|
2451 |
self.assertEqual(['parent'], index.get_ancestry(['parent'])) |
|
2452 |
self.assertEqual(['tip'], index.get_ancestry(['tip'])) |
|
2453 |
self.assertTrue(index.get_ancestry(['tip', 'separate']) in |
|
2454 |
(['tip', 'separate'], |
|
2455 |
['separate', 'tip'], |
|
2456 |
))
|
|
2457 |
# asking for a ghost makes it go boom.
|
|
2458 |
self.assertRaises(errors.RevisionNotPresent, index.get_ancestry, ['ghost']) |
|
2459 |
||
2460 |
def test_get_ancestry_with_ghosts(self): |
|
2461 |
index = self.two_graph_index() |
|
2462 |
self.assertEqual([], index.get_ancestry_with_ghosts([])) |
|
2463 |
self.assertEqual(['separate'], index.get_ancestry_with_ghosts(['separate'])) |
|
2464 |
self.assertEqual(['tail'], index.get_ancestry_with_ghosts(['tail'])) |
|
2465 |
self.assertEqual(['parent'], index.get_ancestry_with_ghosts(['parent'])) |
|
2466 |
self.assertEqual(['tip'], index.get_ancestry_with_ghosts(['tip'])) |
|
2467 |
self.assertTrue(index.get_ancestry_with_ghosts(['tip', 'separate']) in |
|
2468 |
(['tip', 'separate'], |
|
2469 |
['separate', 'tip'], |
|
2470 |
))
|
|
2471 |
# asking for a ghost makes it go boom.
|
|
2472 |
self.assertRaises(errors.RevisionNotPresent, index.get_ancestry_with_ghosts, ['ghost']) |
|
2473 |
||
2474 |
def test_num_versions(self): |
|
2475 |
index = self.two_graph_index() |
|
2476 |
self.assertEqual(4, index.num_versions()) |
|
2477 |
||
2478 |
def test_get_versions(self): |
|
2479 |
index = self.two_graph_index() |
|
2480 |
self.assertEqual(set(['tail', 'tip', 'parent', 'separate']), |
|
2481 |
set(index.get_versions())) |
|
2482 |
||
2483 |
def test_has_version(self): |
|
2484 |
index = self.two_graph_index() |
|
2485 |
self.assertTrue(index.has_version('tail')) |
|
2486 |
self.assertFalse(index.has_version('ghost')) |
|
2487 |
||
2488 |
def test_get_position(self): |
|
2489 |
index = self.two_graph_index() |
|
|
2592.3.71
by Robert Collins
Basic version of knit-based repository operating, many tests failing. |
2490 |
self.assertEqual((index._graph_index._indices[0], 0, 100), index.get_position('tip')) |
2491 |
self.assertEqual((index._graph_index._indices[1], 100, 78), index.get_position('parent')) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2492 |
|
2493 |
def test_get_method(self): |
|
2494 |
index = self.two_graph_index() |
|
2495 |
self.assertEqual('fulltext', index.get_method('tip')) |
|
|
2658.2.1
by Robert Collins
Fix mismatch between KnitGraphIndex and KnitIndex in get_options. |
2496 |
self.assertEqual(['fulltext'], index.get_options('parent')) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2497 |
|
2498 |
def test_get_options(self): |
|
2499 |
index = self.two_graph_index() |
|
|
2658.2.1
by Robert Collins
Fix mismatch between KnitGraphIndex and KnitIndex in get_options. |
2500 |
self.assertEqual(['fulltext', 'no-eol'], index.get_options('tip')) |
2501 |
self.assertEqual(['fulltext'], index.get_options('parent')) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2502 |
|
2503 |
def test_get_parents_with_ghosts(self): |
|
2504 |
index = self.two_graph_index() |
|
2505 |
self.assertEqual((), index.get_parents_with_ghosts('parent')) |
|
|
2592.3.43
by Robert Collins
A knit iter_parents API. |
2506 |
# and errors on ghosts.
|
2507 |
self.assertRaises(errors.RevisionNotPresent, |
|
2508 |
index.get_parents_with_ghosts, 'ghost') |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2509 |
|
2510 |
def test_check_versions_present(self): |
|
2511 |
index = self.two_graph_index() |
|
2512 |
self.assertRaises(RevisionNotPresent, index.check_versions_present, |
|
2513 |
['missing']) |
|
2514 |
self.assertRaises(RevisionNotPresent, index.check_versions_present, |
|
2515 |
['tail', 'missing']) |
|
2516 |
index.check_versions_present(['tail', 'separate']) |
|
2517 |
||
2518 |
def catch_add(self, entries): |
|
2519 |
self.caught_entries.append(entries) |
|
2520 |
||
2521 |
def test_add_no_callback_errors(self): |
|
2522 |
index = self.two_graph_index() |
|
2523 |
self.assertRaises(errors.ReadOnlyError, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2524 |
'new', 'fulltext,no-eol', (None, 50, 60), ['separate']) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2525 |
|
2526 |
def test_add_version_smoke(self): |
|
2527 |
index = self.two_graph_index(catch_adds=True) |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2528 |
index.add_version('new', 'fulltext,no-eol', (None, 50, 60), []) |
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2529 |
self.assertEqual([[(('new', ), 'N50 60')]], |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2530 |
self.caught_entries) |
2531 |
||
2532 |
def test_add_version_delta_not_delta_index(self): |
|
2533 |
index = self.two_graph_index(catch_adds=True) |
|
2534 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2535 |
'new', 'no-eol,line-delta', (None, 0, 100), []) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2536 |
self.assertEqual([], self.caught_entries) |
2537 |
||
2538 |
def test_add_version_same_dup(self): |
|
2539 |
index = self.two_graph_index(catch_adds=True) |
|
2540 |
# options can be spelt two different ways
|
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2541 |
index.add_version('tip', 'fulltext,no-eol', (None, 0, 100), []) |
2542 |
index.add_version('tip', 'no-eol,fulltext', (None, 0, 100), []) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2543 |
# but neither should have added data.
|
2544 |
self.assertEqual([[], []], self.caught_entries) |
|
2545 |
||
2546 |
def test_add_version_different_dup(self): |
|
2547 |
index = self.two_graph_index(catch_adds=True) |
|
2548 |
# change options
|
|
2549 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2550 |
'tip', 'no-eol,line-delta', (None, 0, 100), []) |
2551 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
2552 |
'tip', 'line-delta,no-eol', (None, 0, 100), []) |
|
2553 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
2554 |
'tip', 'fulltext', (None, 0, 100), []) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2555 |
# position/length
|
2556 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2557 |
'tip', 'fulltext,no-eol', (None, 50, 100), []) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2558 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2559 |
'tip', 'fulltext,no-eol', (None, 0, 1000), []) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2560 |
# parents
|
2561 |
self.assertRaises(errors.KnitCorrupt, index.add_version, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2562 |
'tip', 'fulltext,no-eol', (None, 0, 100), ['parent']) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2563 |
self.assertEqual([], self.caught_entries) |
2564 |
||
2565 |
def test_add_versions(self): |
|
2566 |
index = self.two_graph_index(catch_adds=True) |
|
2567 |
index.add_versions([ |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2568 |
('new', 'fulltext,no-eol', (None, 50, 60), []), |
2569 |
('new2', 'fulltext', (None, 0, 6), []), |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2570 |
])
|
|
2624.2.5
by Robert Collins
Change bzrlib.index.Index keys to be 1-tuples, not strings. |
2571 |
self.assertEqual([(('new', ), 'N50 60'), (('new2', ), ' 0 6')], |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2572 |
sorted(self.caught_entries[0])) |
2573 |
self.assertEqual(1, len(self.caught_entries)) |
|
2574 |
||
2575 |
def test_add_versions_delta_not_delta_index(self): |
|
2576 |
index = self.two_graph_index(catch_adds=True) |
|
2577 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2578 |
[('new', 'no-eol,line-delta', (None, 0, 100), ['parent'])]) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2579 |
self.assertEqual([], self.caught_entries) |
2580 |
||
2581 |
def test_add_versions_parents_not_parents_index(self): |
|
2582 |
index = self.two_graph_index(catch_adds=True) |
|
2583 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2584 |
[('new', 'no-eol,fulltext', (None, 0, 100), ['parent'])]) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2585 |
self.assertEqual([], self.caught_entries) |
2586 |
||
|
2841.2.1
by Robert Collins
* Commit no longer checks for new text keys during insertion when the |
2587 |
def test_add_versions_random_id_accepted(self): |
2588 |
index = self.two_graph_index(catch_adds=True) |
|
2589 |
index.add_versions([], random_id=True) |
|
2590 |
||
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2591 |
def test_add_versions_same_dup(self): |
2592 |
index = self.two_graph_index(catch_adds=True) |
|
2593 |
# options can be spelt two different ways
|
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2594 |
index.add_versions([('tip', 'fulltext,no-eol', (None, 0, 100), [])]) |
2595 |
index.add_versions([('tip', 'no-eol,fulltext', (None, 0, 100), [])]) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2596 |
# but neither should have added data.
|
2597 |
self.assertEqual([[], []], self.caught_entries) |
|
2598 |
||
2599 |
def test_add_versions_different_dup(self): |
|
2600 |
index = self.two_graph_index(catch_adds=True) |
|
2601 |
# change options
|
|
2602 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2603 |
[('tip', 'no-eol,line-delta', (None, 0, 100), [])]) |
2604 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
2605 |
[('tip', 'line-delta,no-eol', (None, 0, 100), [])]) |
|
2606 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
2607 |
[('tip', 'fulltext', (None, 0, 100), [])]) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2608 |
# position/length
|
2609 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2610 |
[('tip', 'fulltext,no-eol', (None, 50, 100), [])]) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2611 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2612 |
[('tip', 'fulltext,no-eol', (None, 0, 1000), [])]) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2613 |
# parents
|
2614 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2615 |
[('tip', 'fulltext,no-eol', (None, 0, 100), ['parent'])]) |
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2616 |
# change options in the second record
|
2617 |
self.assertRaises(errors.KnitCorrupt, index.add_versions, |
|
|
2670.2.2
by Robert Collins
* In ``bzrlib.knit`` the internal interface has been altered to use |
2618 |
[('tip', 'fulltext,no-eol', (None, 0, 100), []), |
2619 |
('tip', 'no-eol,line-delta', (None, 0, 100), [])]) |
|
|
2592.3.34
by Robert Collins
Rough unfactored support for parentless KnitGraphIndexs. |
2620 |
self.assertEqual([], self.caught_entries) |
2621 |
||
|
3015.2.19
by Robert Collins
Don't include the pack container length in the lengths given by get_data_stream. |
2622 |
class TestPackKnits(KnitTests): |
2623 |
"""Tests that use a _PackAccess and KnitGraphIndex.""" |
|
2624 |
||
2625 |
def test_get_data_stream_packs_ignores_pack_overhead(self): |
|
2626 |
# Packs have an encoding overhead that should not be included in the
|
|
2627 |
# 'size' field of a data stream, because it is not returned by the
|
|
2628 |
# raw_reading functions - it is why index_memo's are opaque, and
|
|
2629 |
# get_data_stream was abusing this.
|
|
2630 |
packname = 'test.pack' |
|
2631 |
transport = self.get_transport() |
|
2632 |
def write_data(bytes): |
|
2633 |
transport.append_bytes(packname, bytes) |
|
2634 |
writer = pack.ContainerWriter(write_data) |
|
2635 |
writer.begin() |
|
2636 |
index = InMemoryGraphIndex(2) |
|
2637 |
knit_index = KnitGraphIndex(index, add_callback=index.add_nodes, |
|
2638 |
deltas=True) |
|
2639 |
indices = {index:(transport, packname)} |
|
2640 |
access = _PackAccess(indices, writer=(writer, index)) |
|
2641 |
k = KnitVersionedFile('test', get_transport('.'), |
|
2642 |
delta=True, create=True, index=knit_index, access_method=access) |
|
2643 |
# insert something into the knit
|
|
2644 |
k.add_lines('text-1', [], ["foo\n"]) |
|
2645 |
# get a data stream for it
|
|
2646 |
stream = k.get_data_stream(['text-1']) |
|
2647 |
# if the stream has been incorrectly assembled, we will get a short read
|
|
2648 |
# reading from the stream (as streams have no trailer)
|
|
2649 |
expected_length = stream[1][0][2] |
|
2650 |
# we use -1 to do the read, so that if a trailer is added this test
|
|
2651 |
# will fail and we'll adjust it to handle that case correctly, rather
|
|
2652 |
# than allowing an over-read that is bogus.
|
|
2653 |
self.assertEqual(expected_length, len(stream[2](-1))) |
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2654 |
|
2655 |
||
2656 |
class Test_StreamIndex(KnitTests): |
|
2657 |
||
2658 |
def get_index(self, knit, stream): |
|
2659 |
"""Get a _StreamIndex from knit and stream.""" |
|
2660 |
return knit._knit_from_datastream(stream)._index |
|
2661 |
||
2662 |
def assertIndexVersions(self, knit, versions): |
|
2663 |
"""Check that the _StreamIndex versions are those of the stream.""" |
|
2664 |
index = self.get_index(knit, knit.get_data_stream(versions)) |
|
2665 |
self.assertEqual(set(index.get_versions()), set(versions)) |
|
2666 |
# check we didn't get duplicates
|
|
2667 |
self.assertEqual(len(index.get_versions()), len(versions)) |
|
2668 |
||
2669 |
def assertIndexAncestry(self, knit, ancestry_versions, versions, result): |
|
2670 |
"""Check the result of a get_ancestry call on knit.""" |
|
2671 |
index = self.get_index(knit, knit.get_data_stream(versions)) |
|
|
3052.2.4
by Andrew Bennetts
Some tweaks suggested by John's review. |
2672 |
self.assertEqual( |
2673 |
set(result), |
|
2674 |
set(index.get_ancestry(ancestry_versions, False))) |
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2675 |
|
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2676 |
def assertGetMethod(self, knit, versions, version, result): |
2677 |
index = self.get_index(knit, knit.get_data_stream(versions)) |
|
2678 |
self.assertEqual(result, index.get_method(version)) |
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2679 |
|
2680 |
def assertGetOptions(self, knit, version, options): |
|
2681 |
index = self.get_index(knit, knit.get_data_stream(version)) |
|
2682 |
self.assertEqual(options, index.get_options(version)) |
|
2683 |
||
2684 |
def assertGetPosition(self, knit, versions, version, result): |
|
2685 |
index = self.get_index(knit, knit.get_data_stream(versions)) |
|
|
3052.2.5
by Andrew Bennetts
Address the rest of the review comments from John and myself. |
2686 |
if result[1] is None: |
2687 |
result = (result[0], index, result[2], result[3]) |
|
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2688 |
self.assertEqual(result, index.get_position(version)) |
2689 |
||
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2690 |
def assertGetParentsWithGhosts(self, knit, versions, version, parents): |
2691 |
index = self.get_index(knit, knit.get_data_stream(versions)) |
|
2692 |
self.assertEqual(parents, index.get_parents_with_ghosts(version)) |
|
2693 |
||
2694 |
def make_knit_with_4_versions_2_dags(self): |
|
2695 |
knit = self.make_test_knit() |
|
2696 |
knit.add_lines('a', [], ["foo"]) |
|
2697 |
knit.add_lines('b', [], []) |
|
2698 |
knit.add_lines('c', ['b', 'a'], []) |
|
2699 |
knit.add_lines_with_ghosts('d', ['e', 'f'], []) |
|
2700 |
return knit |
|
2701 |
||
2702 |
def test_versions(self): |
|
2703 |
"""The versions of a StreamIndex are those of the datastream.""" |
|
2704 |
knit = self.make_knit_with_4_versions_2_dags() |
|
2705 |
# ask for most permutations, which catches bugs like falling back to the
|
|
2706 |
# target knit, or showing ghosts, etc.
|
|
2707 |
self.assertIndexVersions(knit, []) |
|
2708 |
self.assertIndexVersions(knit, ['a']) |
|
2709 |
self.assertIndexVersions(knit, ['b']) |
|
2710 |
self.assertIndexVersions(knit, ['c']) |
|
2711 |
self.assertIndexVersions(knit, ['d']) |
|
2712 |
self.assertIndexVersions(knit, ['a', 'b']) |
|
2713 |
self.assertIndexVersions(knit, ['b', 'c']) |
|
2714 |
self.assertIndexVersions(knit, ['a', 'c']) |
|
2715 |
self.assertIndexVersions(knit, ['a', 'b', 'c']) |
|
2716 |
self.assertIndexVersions(knit, ['a', 'b', 'c', 'd']) |
|
2717 |
||
2718 |
def test_construct(self): |
|
2719 |
"""Constructing a StreamIndex generates index data.""" |
|
2720 |
data_list = [('text-a', ['fulltext'], 127, []), |
|
2721 |
('text-b', ['option'], 128, ['text-c'])] |
|
|
3224.1.8
by John Arbash Meinel
Add noeol to the return signature of get_build_details. |
2722 |
index = _StreamIndex(data_list, None) |
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2723 |
self.assertEqual({'text-a':(['fulltext'], (0, 127), []), |
2724 |
'text-b':(['option'], (127, 127 + 128), ['text-c'])}, |
|
2725 |
index._by_version) |
|
2726 |
||
2727 |
def test_get_ancestry(self): |
|
2728 |
knit = self.make_knit_with_4_versions_2_dags() |
|
2729 |
self.assertIndexAncestry(knit, ['a'], ['a'], ['a']) |
|
2730 |
self.assertIndexAncestry(knit, ['b'], ['b'], ['b']) |
|
2731 |
self.assertIndexAncestry(knit, ['c'], ['c'], ['c']) |
|
2732 |
self.assertIndexAncestry(knit, ['c'], ['a', 'b', 'c'], |
|
|
3052.2.4
by Andrew Bennetts
Some tweaks suggested by John's review. |
2733 |
set(['a', 'b', 'c'])) |
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2734 |
self.assertIndexAncestry(knit, ['c', 'd'], ['a', 'b', 'c', 'd'], |
|
3052.2.4
by Andrew Bennetts
Some tweaks suggested by John's review. |
2735 |
set(['a', 'b', 'c', 'd'])) |
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2736 |
|
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2737 |
def test_get_method(self): |
2738 |
knit = self.make_knit_with_4_versions_2_dags() |
|
2739 |
self.assertGetMethod(knit, ['a'], 'a', 'fulltext') |
|
2740 |
self.assertGetMethod(knit, ['c'], 'c', 'line-delta') |
|
2741 |
# get_method on a basis that is not in the datastream (but in the
|
|
2742 |
# backing knit) returns 'fulltext', because thats what we'll create as
|
|
2743 |
# we thunk across.
|
|
2744 |
self.assertGetMethod(knit, ['c'], 'b', 'fulltext') |
|
2745 |
||
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2746 |
def test_get_options(self): |
2747 |
knit = self.make_knit_with_4_versions_2_dags() |
|
2748 |
self.assertGetOptions(knit, 'a', ['no-eol', 'fulltext']) |
|
2749 |
self.assertGetOptions(knit, 'c', ['line-delta']) |
|
2750 |
||
2751 |
def test_get_parents_with_ghosts(self): |
|
2752 |
knit = self.make_knit_with_4_versions_2_dags() |
|
|
3287.5.5
by Robert Collins
Refactor internals of knit implementations to implement get_parents_with_ghosts in terms of get_parent_map. |
2753 |
self.assertGetParentsWithGhosts(knit, ['a'], 'a', ()) |
2754 |
self.assertGetParentsWithGhosts(knit, ['c'], 'c', ('b', 'a')) |
|
2755 |
self.assertGetParentsWithGhosts(knit, ['d'], 'd', ('e', 'f')) |
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2756 |
|
2757 |
def test_get_position(self): |
|
2758 |
knit = self.make_knit_with_4_versions_2_dags() |
|
|
3052.2.6
by Andrew Bennetts
Fix typo in comment. |
2759 |
# get_position returns (thunk_flag, index(can be None), start, end) for
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2760 |
# _StreamAccess to use.
|
|
3052.2.5
by Andrew Bennetts
Address the rest of the review comments from John and myself. |
2761 |
self.assertGetPosition(knit, ['a'], 'a', (False, None, 0, 78)) |
2762 |
self.assertGetPosition(knit, ['a', 'c'], 'c', (False, None, 78, 156)) |
|
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2763 |
# get_position on a text that is not in the datastream (but in the
|
|
3052.2.5
by Andrew Bennetts
Address the rest of the review comments from John and myself. |
2764 |
# backing knit) returns (True, 'versionid', None, None) - and then the
|
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2765 |
# access object can construct the relevant data as needed.
|
|
3052.2.5
by Andrew Bennetts
Address the rest of the review comments from John and myself. |
2766 |
self.assertGetPosition(knit, ['a', 'c'], 'b', (True, 'b', None, None)) |
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2767 |
|
2768 |
||
2769 |
class Test_StreamAccess(KnitTests): |
|
|
3052.2.2
by Robert Collins
* Operations pulling data from a smart server where the underlying |
2770 |
|
2771 |
def get_index_access(self, knit, stream): |
|
2772 |
"""Get a _StreamAccess from knit and stream.""" |
|
2773 |
knit = knit._knit_from_datastream(stream) |
|
2774 |
return knit._index, knit._data._access |
|
2775 |
||
2776 |
def assertGetRawRecords(self, knit, versions): |
|
2777 |
index, access = self.get_index_access(knit, |
|
2778 |
knit.get_data_stream(versions)) |
|
2779 |
# check that every version asked for can be obtained from the resulting
|
|
2780 |
# access object.
|
|
2781 |
# batch
|
|
2782 |
memos = [] |
|
2783 |
for version in versions: |
|
2784 |
memos.append(knit._index.get_position(version)) |
|
2785 |
original = {} |
|
2786 |
for version, data in zip( |
|
2787 |
versions, knit._data._access.get_raw_records(memos)): |
|
2788 |
original[version] = data |
|
2789 |
memos = [] |
|
2790 |
for version in versions: |
|
2791 |
memos.append(index.get_position(version)) |
|
2792 |
streamed = {} |
|
2793 |
for version, data in zip(versions, access.get_raw_records(memos)): |
|
2794 |
streamed[version] = data |
|
2795 |
self.assertEqual(original, streamed) |
|
2796 |
# individually
|
|
2797 |
for version in versions: |
|
2798 |
data = list(access.get_raw_records( |
|
2799 |
[index.get_position(version)]))[0] |
|
2800 |
self.assertEqual(original[version], data) |
|
2801 |
||
2802 |
def make_knit_with_two_versions(self): |
|
2803 |
knit = self.make_test_knit() |
|
2804 |
knit.add_lines('a', [], ["foo"]) |
|
2805 |
knit.add_lines('b', [], ["bar"]) |
|
2806 |
return knit |
|
2807 |
||
2808 |
def test_get_raw_records(self): |
|
2809 |
knit = self.make_knit_with_two_versions() |
|
2810 |
self.assertGetRawRecords(knit, ['a', 'b']) |
|
2811 |
self.assertGetRawRecords(knit, ['a']) |
|
2812 |
self.assertGetRawRecords(knit, ['b']) |
|
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2813 |
|
2814 |
def test_get_raw_record_from_backing_knit(self): |
|
2815 |
# the thunk layer should create an artificial A on-demand when needed.
|
|
2816 |
source_knit = self.make_test_knit(name='plain', annotate=False) |
|
2817 |
target_knit = self.make_test_knit(name='annotated', annotate=True) |
|
2818 |
source_knit.add_lines("A", [], ["Foo\n"]) |
|
2819 |
# Give the target A, so we can try to thunk across to it.
|
|
2820 |
target_knit.join(source_knit) |
|
2821 |
index, access = self.get_index_access(target_knit, |
|
2822 |
source_knit.get_data_stream([])) |
|
|
3052.2.5
by Andrew Bennetts
Address the rest of the review comments from John and myself. |
2823 |
raw_data = list(access.get_raw_records([(True, "A", None, None)]))[0] |
|
3052.2.3
by Robert Collins
Handle insert_data_stream of an unannotated stream into an annotated knit. |
2824 |
df = GzipFile(mode='rb', fileobj=StringIO(raw_data)) |
2825 |
self.assertEqual( |
|
2826 |
'version A 1 5d36b88bb697a2d778f024048bafabd443d74503\n' |
|
2827 |
'Foo\nend A\n', |
|
2828 |
df.read()) |
|
2829 |
||
2830 |
def test_asking_for_thunk_stream_is_not_plain_errors(self): |
|
2831 |
knit = self.make_test_knit(name='annotated', annotate=True) |
|
2832 |
knit.add_lines("A", [], ["Foo\n"]) |
|
2833 |
index, access = self.get_index_access(knit, |
|
2834 |
knit.get_data_stream([])) |
|
2835 |
self.assertRaises(errors.KnitCorrupt, |
|
|
3052.2.5
by Andrew Bennetts
Address the rest of the review comments from John and myself. |
2836 |
list, access.get_raw_records([(True, "A", None, None)])) |
|
3316.2.3
by Robert Collins
Remove manual notification of transaction finishing on versioned files. |
2837 |
|
2838 |
||
2839 |
class TestFormatSignatures(KnitTests): |
|
2840 |
||
2841 |
def test_knit_format_signatures(self): |
|
2842 |
"""Different formats of knit have different signature strings.""" |
|
2843 |
knit = self.make_test_knit(name='a', annotate=True) |
|
2844 |
self.assertEqual('knit-annotated', knit.get_format_signature()) |
|
2845 |
knit = self.make_test_knit(name='p', annotate=False) |
|
2846 |
self.assertEqual('knit-plain', knit.get_format_signature()) |