##// END OF EJS Templates
rawdata: update callers in testing/storage.py...
marmoute -
r43046:22e74b5a default
parent child Browse files
Show More
@@ -1,1346 +1,1346 b''
1 # storage.py - Testing of storage primitives.
1 # storage.py - Testing of storage primitives.
2 #
2 #
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import unittest
10 import unittest
11
11
12 from ..node import (
12 from ..node import (
13 hex,
13 hex,
14 nullid,
14 nullid,
15 nullrev,
15 nullrev,
16 )
16 )
17 from .. import (
17 from .. import (
18 error,
18 error,
19 mdiff,
19 mdiff,
20 repository,
20 repository,
21 )
21 )
22 from ..utils import (
22 from ..utils import (
23 storageutil,
23 storageutil,
24 )
24 )
25
25
26 class basetestcase(unittest.TestCase):
26 class basetestcase(unittest.TestCase):
27 if not getattr(unittest.TestCase, r'assertRaisesRegex', False):
27 if not getattr(unittest.TestCase, r'assertRaisesRegex', False):
28 assertRaisesRegex = (# camelcase-required
28 assertRaisesRegex = (# camelcase-required
29 unittest.TestCase.assertRaisesRegexp)
29 unittest.TestCase.assertRaisesRegexp)
30
30
31 class ifileindextests(basetestcase):
31 class ifileindextests(basetestcase):
32 """Generic tests for the ifileindex interface.
32 """Generic tests for the ifileindex interface.
33
33
34 All file storage backends for index data should conform to the tests in this
34 All file storage backends for index data should conform to the tests in this
35 class.
35 class.
36
36
37 Use ``makeifileindextests()`` to create an instance of this type.
37 Use ``makeifileindextests()`` to create an instance of this type.
38 """
38 """
39 def testempty(self):
39 def testempty(self):
40 f = self._makefilefn()
40 f = self._makefilefn()
41 self.assertEqual(len(f), 0, 'new file store has 0 length by default')
41 self.assertEqual(len(f), 0, 'new file store has 0 length by default')
42 self.assertEqual(list(f), [], 'iter yields nothing by default')
42 self.assertEqual(list(f), [], 'iter yields nothing by default')
43
43
44 gen = iter(f)
44 gen = iter(f)
45 with self.assertRaises(StopIteration):
45 with self.assertRaises(StopIteration):
46 next(gen)
46 next(gen)
47
47
48 self.assertFalse(f.hasnode(None))
48 self.assertFalse(f.hasnode(None))
49 self.assertFalse(f.hasnode(0))
49 self.assertFalse(f.hasnode(0))
50 self.assertFalse(f.hasnode(nullrev))
50 self.assertFalse(f.hasnode(nullrev))
51 self.assertFalse(f.hasnode(nullid))
51 self.assertFalse(f.hasnode(nullid))
52 self.assertFalse(f.hasnode(b'0'))
52 self.assertFalse(f.hasnode(b'0'))
53 self.assertFalse(f.hasnode(b'a' * 20))
53 self.assertFalse(f.hasnode(b'a' * 20))
54
54
55 # revs() should evaluate to an empty list.
55 # revs() should evaluate to an empty list.
56 self.assertEqual(list(f.revs()), [])
56 self.assertEqual(list(f.revs()), [])
57
57
58 revs = iter(f.revs())
58 revs = iter(f.revs())
59 with self.assertRaises(StopIteration):
59 with self.assertRaises(StopIteration):
60 next(revs)
60 next(revs)
61
61
62 self.assertEqual(list(f.revs(start=20)), [])
62 self.assertEqual(list(f.revs(start=20)), [])
63
63
64 # parents() and parentrevs() work with nullid/nullrev.
64 # parents() and parentrevs() work with nullid/nullrev.
65 self.assertEqual(f.parents(nullid), (nullid, nullid))
65 self.assertEqual(f.parents(nullid), (nullid, nullid))
66 self.assertEqual(f.parentrevs(nullrev), (nullrev, nullrev))
66 self.assertEqual(f.parentrevs(nullrev), (nullrev, nullrev))
67
67
68 with self.assertRaises(error.LookupError):
68 with self.assertRaises(error.LookupError):
69 f.parents(b'\x01' * 20)
69 f.parents(b'\x01' * 20)
70
70
71 for i in range(-5, 5):
71 for i in range(-5, 5):
72 if i == nullrev:
72 if i == nullrev:
73 continue
73 continue
74
74
75 with self.assertRaises(IndexError):
75 with self.assertRaises(IndexError):
76 f.parentrevs(i)
76 f.parentrevs(i)
77
77
78 # nullid/nullrev lookup always works.
78 # nullid/nullrev lookup always works.
79 self.assertEqual(f.rev(nullid), nullrev)
79 self.assertEqual(f.rev(nullid), nullrev)
80 self.assertEqual(f.node(nullrev), nullid)
80 self.assertEqual(f.node(nullrev), nullid)
81
81
82 with self.assertRaises(error.LookupError):
82 with self.assertRaises(error.LookupError):
83 f.rev(b'\x01' * 20)
83 f.rev(b'\x01' * 20)
84
84
85 for i in range(-5, 5):
85 for i in range(-5, 5):
86 if i == nullrev:
86 if i == nullrev:
87 continue
87 continue
88
88
89 with self.assertRaises(IndexError):
89 with self.assertRaises(IndexError):
90 f.node(i)
90 f.node(i)
91
91
92 self.assertEqual(f.lookup(nullid), nullid)
92 self.assertEqual(f.lookup(nullid), nullid)
93 self.assertEqual(f.lookup(nullrev), nullid)
93 self.assertEqual(f.lookup(nullrev), nullid)
94 self.assertEqual(f.lookup(hex(nullid)), nullid)
94 self.assertEqual(f.lookup(hex(nullid)), nullid)
95 self.assertEqual(f.lookup(b'%d' % nullrev), nullid)
95 self.assertEqual(f.lookup(b'%d' % nullrev), nullid)
96
96
97 with self.assertRaises(error.LookupError):
97 with self.assertRaises(error.LookupError):
98 f.lookup(b'badvalue')
98 f.lookup(b'badvalue')
99
99
100 with self.assertRaises(error.LookupError):
100 with self.assertRaises(error.LookupError):
101 f.lookup(hex(nullid)[0:12])
101 f.lookup(hex(nullid)[0:12])
102
102
103 with self.assertRaises(error.LookupError):
103 with self.assertRaises(error.LookupError):
104 f.lookup(b'-2')
104 f.lookup(b'-2')
105
105
106 with self.assertRaises(error.LookupError):
106 with self.assertRaises(error.LookupError):
107 f.lookup(b'0')
107 f.lookup(b'0')
108
108
109 with self.assertRaises(error.LookupError):
109 with self.assertRaises(error.LookupError):
110 f.lookup(b'1')
110 f.lookup(b'1')
111
111
112 with self.assertRaises(error.LookupError):
112 with self.assertRaises(error.LookupError):
113 f.lookup(b'11111111111111111111111111111111111111')
113 f.lookup(b'11111111111111111111111111111111111111')
114
114
115 for i in range(-5, 5):
115 for i in range(-5, 5):
116 if i == nullrev:
116 if i == nullrev:
117 continue
117 continue
118
118
119 with self.assertRaises(LookupError):
119 with self.assertRaises(LookupError):
120 f.lookup(i)
120 f.lookup(i)
121
121
122 self.assertEqual(f.linkrev(nullrev), nullrev)
122 self.assertEqual(f.linkrev(nullrev), nullrev)
123
123
124 for i in range(-5, 5):
124 for i in range(-5, 5):
125 if i == nullrev:
125 if i == nullrev:
126 continue
126 continue
127
127
128 with self.assertRaises(IndexError):
128 with self.assertRaises(IndexError):
129 f.linkrev(i)
129 f.linkrev(i)
130
130
131 self.assertFalse(f.iscensored(nullrev))
131 self.assertFalse(f.iscensored(nullrev))
132
132
133 for i in range(-5, 5):
133 for i in range(-5, 5):
134 if i == nullrev:
134 if i == nullrev:
135 continue
135 continue
136
136
137 with self.assertRaises(IndexError):
137 with self.assertRaises(IndexError):
138 f.iscensored(i)
138 f.iscensored(i)
139
139
140 self.assertEqual(list(f.commonancestorsheads(nullid, nullid)), [])
140 self.assertEqual(list(f.commonancestorsheads(nullid, nullid)), [])
141
141
142 with self.assertRaises(ValueError):
142 with self.assertRaises(ValueError):
143 self.assertEqual(list(f.descendants([])), [])
143 self.assertEqual(list(f.descendants([])), [])
144
144
145 self.assertEqual(list(f.descendants([nullrev])), [])
145 self.assertEqual(list(f.descendants([nullrev])), [])
146
146
147 self.assertEqual(f.heads(), [nullid])
147 self.assertEqual(f.heads(), [nullid])
148 self.assertEqual(f.heads(nullid), [nullid])
148 self.assertEqual(f.heads(nullid), [nullid])
149 self.assertEqual(f.heads(None, [nullid]), [nullid])
149 self.assertEqual(f.heads(None, [nullid]), [nullid])
150 self.assertEqual(f.heads(nullid, [nullid]), [nullid])
150 self.assertEqual(f.heads(nullid, [nullid]), [nullid])
151
151
152 self.assertEqual(f.children(nullid), [])
152 self.assertEqual(f.children(nullid), [])
153
153
154 with self.assertRaises(error.LookupError):
154 with self.assertRaises(error.LookupError):
155 f.children(b'\x01' * 20)
155 f.children(b'\x01' * 20)
156
156
157 def testsinglerevision(self):
157 def testsinglerevision(self):
158 f = self._makefilefn()
158 f = self._makefilefn()
159 with self._maketransactionfn() as tr:
159 with self._maketransactionfn() as tr:
160 node = f.add(b'initial', None, tr, 0, nullid, nullid)
160 node = f.add(b'initial', None, tr, 0, nullid, nullid)
161
161
162 self.assertEqual(len(f), 1)
162 self.assertEqual(len(f), 1)
163 self.assertEqual(list(f), [0])
163 self.assertEqual(list(f), [0])
164
164
165 gen = iter(f)
165 gen = iter(f)
166 self.assertEqual(next(gen), 0)
166 self.assertEqual(next(gen), 0)
167
167
168 with self.assertRaises(StopIteration):
168 with self.assertRaises(StopIteration):
169 next(gen)
169 next(gen)
170
170
171 self.assertTrue(f.hasnode(node))
171 self.assertTrue(f.hasnode(node))
172 self.assertFalse(f.hasnode(hex(node)))
172 self.assertFalse(f.hasnode(hex(node)))
173 self.assertFalse(f.hasnode(nullrev))
173 self.assertFalse(f.hasnode(nullrev))
174 self.assertFalse(f.hasnode(nullid))
174 self.assertFalse(f.hasnode(nullid))
175 self.assertFalse(f.hasnode(node[0:12]))
175 self.assertFalse(f.hasnode(node[0:12]))
176 self.assertFalse(f.hasnode(hex(node)[0:20]))
176 self.assertFalse(f.hasnode(hex(node)[0:20]))
177
177
178 self.assertEqual(list(f.revs()), [0])
178 self.assertEqual(list(f.revs()), [0])
179 self.assertEqual(list(f.revs(start=1)), [])
179 self.assertEqual(list(f.revs(start=1)), [])
180 self.assertEqual(list(f.revs(start=0)), [0])
180 self.assertEqual(list(f.revs(start=0)), [0])
181 self.assertEqual(list(f.revs(stop=0)), [0])
181 self.assertEqual(list(f.revs(stop=0)), [0])
182 self.assertEqual(list(f.revs(stop=1)), [0])
182 self.assertEqual(list(f.revs(stop=1)), [0])
183 self.assertEqual(list(f.revs(1, 1)), [])
183 self.assertEqual(list(f.revs(1, 1)), [])
184 # TODO buggy
184 # TODO buggy
185 self.assertEqual(list(f.revs(1, 0)), [1, 0])
185 self.assertEqual(list(f.revs(1, 0)), [1, 0])
186 self.assertEqual(list(f.revs(2, 0)), [2, 1, 0])
186 self.assertEqual(list(f.revs(2, 0)), [2, 1, 0])
187
187
188 self.assertEqual(f.parents(node), (nullid, nullid))
188 self.assertEqual(f.parents(node), (nullid, nullid))
189 self.assertEqual(f.parentrevs(0), (nullrev, nullrev))
189 self.assertEqual(f.parentrevs(0), (nullrev, nullrev))
190
190
191 with self.assertRaises(error.LookupError):
191 with self.assertRaises(error.LookupError):
192 f.parents(b'\x01' * 20)
192 f.parents(b'\x01' * 20)
193
193
194 with self.assertRaises(IndexError):
194 with self.assertRaises(IndexError):
195 f.parentrevs(1)
195 f.parentrevs(1)
196
196
197 self.assertEqual(f.rev(node), 0)
197 self.assertEqual(f.rev(node), 0)
198
198
199 with self.assertRaises(error.LookupError):
199 with self.assertRaises(error.LookupError):
200 f.rev(b'\x01' * 20)
200 f.rev(b'\x01' * 20)
201
201
202 self.assertEqual(f.node(0), node)
202 self.assertEqual(f.node(0), node)
203
203
204 with self.assertRaises(IndexError):
204 with self.assertRaises(IndexError):
205 f.node(1)
205 f.node(1)
206
206
207 self.assertEqual(f.lookup(node), node)
207 self.assertEqual(f.lookup(node), node)
208 self.assertEqual(f.lookup(0), node)
208 self.assertEqual(f.lookup(0), node)
209 self.assertEqual(f.lookup(-1), nullid)
209 self.assertEqual(f.lookup(-1), nullid)
210 self.assertEqual(f.lookup(b'0'), node)
210 self.assertEqual(f.lookup(b'0'), node)
211 self.assertEqual(f.lookup(hex(node)), node)
211 self.assertEqual(f.lookup(hex(node)), node)
212
212
213 with self.assertRaises(error.LookupError):
213 with self.assertRaises(error.LookupError):
214 f.lookup(hex(node)[0:12])
214 f.lookup(hex(node)[0:12])
215
215
216 with self.assertRaises(error.LookupError):
216 with self.assertRaises(error.LookupError):
217 f.lookup(-2)
217 f.lookup(-2)
218
218
219 with self.assertRaises(error.LookupError):
219 with self.assertRaises(error.LookupError):
220 f.lookup(b'-2')
220 f.lookup(b'-2')
221
221
222 with self.assertRaises(error.LookupError):
222 with self.assertRaises(error.LookupError):
223 f.lookup(1)
223 f.lookup(1)
224
224
225 with self.assertRaises(error.LookupError):
225 with self.assertRaises(error.LookupError):
226 f.lookup(b'1')
226 f.lookup(b'1')
227
227
228 self.assertEqual(f.linkrev(0), 0)
228 self.assertEqual(f.linkrev(0), 0)
229
229
230 with self.assertRaises(IndexError):
230 with self.assertRaises(IndexError):
231 f.linkrev(1)
231 f.linkrev(1)
232
232
233 self.assertFalse(f.iscensored(0))
233 self.assertFalse(f.iscensored(0))
234
234
235 with self.assertRaises(IndexError):
235 with self.assertRaises(IndexError):
236 f.iscensored(1)
236 f.iscensored(1)
237
237
238 self.assertEqual(list(f.descendants([0])), [])
238 self.assertEqual(list(f.descendants([0])), [])
239
239
240 self.assertEqual(f.heads(), [node])
240 self.assertEqual(f.heads(), [node])
241 self.assertEqual(f.heads(node), [node])
241 self.assertEqual(f.heads(node), [node])
242 self.assertEqual(f.heads(stop=[node]), [node])
242 self.assertEqual(f.heads(stop=[node]), [node])
243
243
244 with self.assertRaises(error.LookupError):
244 with self.assertRaises(error.LookupError):
245 f.heads(stop=[b'\x01' * 20])
245 f.heads(stop=[b'\x01' * 20])
246
246
247 self.assertEqual(f.children(node), [])
247 self.assertEqual(f.children(node), [])
248
248
249 def testmultiplerevisions(self):
249 def testmultiplerevisions(self):
250 fulltext0 = b'x' * 1024
250 fulltext0 = b'x' * 1024
251 fulltext1 = fulltext0 + b'y'
251 fulltext1 = fulltext0 + b'y'
252 fulltext2 = b'y' + fulltext0 + b'z'
252 fulltext2 = b'y' + fulltext0 + b'z'
253
253
254 f = self._makefilefn()
254 f = self._makefilefn()
255 with self._maketransactionfn() as tr:
255 with self._maketransactionfn() as tr:
256 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
256 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
257 node1 = f.add(fulltext1, None, tr, 1, node0, nullid)
257 node1 = f.add(fulltext1, None, tr, 1, node0, nullid)
258 node2 = f.add(fulltext2, None, tr, 3, node1, nullid)
258 node2 = f.add(fulltext2, None, tr, 3, node1, nullid)
259
259
260 self.assertEqual(len(f), 3)
260 self.assertEqual(len(f), 3)
261 self.assertEqual(list(f), [0, 1, 2])
261 self.assertEqual(list(f), [0, 1, 2])
262
262
263 gen = iter(f)
263 gen = iter(f)
264 self.assertEqual(next(gen), 0)
264 self.assertEqual(next(gen), 0)
265 self.assertEqual(next(gen), 1)
265 self.assertEqual(next(gen), 1)
266 self.assertEqual(next(gen), 2)
266 self.assertEqual(next(gen), 2)
267
267
268 with self.assertRaises(StopIteration):
268 with self.assertRaises(StopIteration):
269 next(gen)
269 next(gen)
270
270
271 self.assertEqual(list(f.revs()), [0, 1, 2])
271 self.assertEqual(list(f.revs()), [0, 1, 2])
272 self.assertEqual(list(f.revs(0)), [0, 1, 2])
272 self.assertEqual(list(f.revs(0)), [0, 1, 2])
273 self.assertEqual(list(f.revs(1)), [1, 2])
273 self.assertEqual(list(f.revs(1)), [1, 2])
274 self.assertEqual(list(f.revs(2)), [2])
274 self.assertEqual(list(f.revs(2)), [2])
275 self.assertEqual(list(f.revs(3)), [])
275 self.assertEqual(list(f.revs(3)), [])
276 self.assertEqual(list(f.revs(stop=1)), [0, 1])
276 self.assertEqual(list(f.revs(stop=1)), [0, 1])
277 self.assertEqual(list(f.revs(stop=2)), [0, 1, 2])
277 self.assertEqual(list(f.revs(stop=2)), [0, 1, 2])
278 self.assertEqual(list(f.revs(stop=3)), [0, 1, 2])
278 self.assertEqual(list(f.revs(stop=3)), [0, 1, 2])
279 self.assertEqual(list(f.revs(2, 0)), [2, 1, 0])
279 self.assertEqual(list(f.revs(2, 0)), [2, 1, 0])
280 self.assertEqual(list(f.revs(2, 1)), [2, 1])
280 self.assertEqual(list(f.revs(2, 1)), [2, 1])
281 # TODO this is wrong
281 # TODO this is wrong
282 self.assertEqual(list(f.revs(3, 2)), [3, 2])
282 self.assertEqual(list(f.revs(3, 2)), [3, 2])
283
283
284 self.assertEqual(f.parents(node0), (nullid, nullid))
284 self.assertEqual(f.parents(node0), (nullid, nullid))
285 self.assertEqual(f.parents(node1), (node0, nullid))
285 self.assertEqual(f.parents(node1), (node0, nullid))
286 self.assertEqual(f.parents(node2), (node1, nullid))
286 self.assertEqual(f.parents(node2), (node1, nullid))
287
287
288 self.assertEqual(f.parentrevs(0), (nullrev, nullrev))
288 self.assertEqual(f.parentrevs(0), (nullrev, nullrev))
289 self.assertEqual(f.parentrevs(1), (0, nullrev))
289 self.assertEqual(f.parentrevs(1), (0, nullrev))
290 self.assertEqual(f.parentrevs(2), (1, nullrev))
290 self.assertEqual(f.parentrevs(2), (1, nullrev))
291
291
292 self.assertEqual(f.rev(node0), 0)
292 self.assertEqual(f.rev(node0), 0)
293 self.assertEqual(f.rev(node1), 1)
293 self.assertEqual(f.rev(node1), 1)
294 self.assertEqual(f.rev(node2), 2)
294 self.assertEqual(f.rev(node2), 2)
295
295
296 with self.assertRaises(error.LookupError):
296 with self.assertRaises(error.LookupError):
297 f.rev(b'\x01' * 20)
297 f.rev(b'\x01' * 20)
298
298
299 self.assertEqual(f.node(0), node0)
299 self.assertEqual(f.node(0), node0)
300 self.assertEqual(f.node(1), node1)
300 self.assertEqual(f.node(1), node1)
301 self.assertEqual(f.node(2), node2)
301 self.assertEqual(f.node(2), node2)
302
302
303 with self.assertRaises(IndexError):
303 with self.assertRaises(IndexError):
304 f.node(3)
304 f.node(3)
305
305
306 self.assertEqual(f.lookup(node0), node0)
306 self.assertEqual(f.lookup(node0), node0)
307 self.assertEqual(f.lookup(0), node0)
307 self.assertEqual(f.lookup(0), node0)
308 self.assertEqual(f.lookup(b'0'), node0)
308 self.assertEqual(f.lookup(b'0'), node0)
309 self.assertEqual(f.lookup(hex(node0)), node0)
309 self.assertEqual(f.lookup(hex(node0)), node0)
310
310
311 self.assertEqual(f.lookup(node1), node1)
311 self.assertEqual(f.lookup(node1), node1)
312 self.assertEqual(f.lookup(1), node1)
312 self.assertEqual(f.lookup(1), node1)
313 self.assertEqual(f.lookup(b'1'), node1)
313 self.assertEqual(f.lookup(b'1'), node1)
314 self.assertEqual(f.lookup(hex(node1)), node1)
314 self.assertEqual(f.lookup(hex(node1)), node1)
315
315
316 self.assertEqual(f.linkrev(0), 0)
316 self.assertEqual(f.linkrev(0), 0)
317 self.assertEqual(f.linkrev(1), 1)
317 self.assertEqual(f.linkrev(1), 1)
318 self.assertEqual(f.linkrev(2), 3)
318 self.assertEqual(f.linkrev(2), 3)
319
319
320 with self.assertRaises(IndexError):
320 with self.assertRaises(IndexError):
321 f.linkrev(3)
321 f.linkrev(3)
322
322
323 self.assertFalse(f.iscensored(0))
323 self.assertFalse(f.iscensored(0))
324 self.assertFalse(f.iscensored(1))
324 self.assertFalse(f.iscensored(1))
325 self.assertFalse(f.iscensored(2))
325 self.assertFalse(f.iscensored(2))
326
326
327 with self.assertRaises(IndexError):
327 with self.assertRaises(IndexError):
328 f.iscensored(3)
328 f.iscensored(3)
329
329
330 self.assertEqual(f.commonancestorsheads(node1, nullid), [])
330 self.assertEqual(f.commonancestorsheads(node1, nullid), [])
331 self.assertEqual(f.commonancestorsheads(node1, node0), [node0])
331 self.assertEqual(f.commonancestorsheads(node1, node0), [node0])
332 self.assertEqual(f.commonancestorsheads(node1, node1), [node1])
332 self.assertEqual(f.commonancestorsheads(node1, node1), [node1])
333 self.assertEqual(f.commonancestorsheads(node0, node1), [node0])
333 self.assertEqual(f.commonancestorsheads(node0, node1), [node0])
334 self.assertEqual(f.commonancestorsheads(node1, node2), [node1])
334 self.assertEqual(f.commonancestorsheads(node1, node2), [node1])
335 self.assertEqual(f.commonancestorsheads(node2, node1), [node1])
335 self.assertEqual(f.commonancestorsheads(node2, node1), [node1])
336
336
337 self.assertEqual(list(f.descendants([0])), [1, 2])
337 self.assertEqual(list(f.descendants([0])), [1, 2])
338 self.assertEqual(list(f.descendants([1])), [2])
338 self.assertEqual(list(f.descendants([1])), [2])
339 self.assertEqual(list(f.descendants([0, 1])), [1, 2])
339 self.assertEqual(list(f.descendants([0, 1])), [1, 2])
340
340
341 self.assertEqual(f.heads(), [node2])
341 self.assertEqual(f.heads(), [node2])
342 self.assertEqual(f.heads(node0), [node2])
342 self.assertEqual(f.heads(node0), [node2])
343 self.assertEqual(f.heads(node1), [node2])
343 self.assertEqual(f.heads(node1), [node2])
344 self.assertEqual(f.heads(node2), [node2])
344 self.assertEqual(f.heads(node2), [node2])
345
345
346 # TODO this behavior seems wonky. Is it correct? If so, the
346 # TODO this behavior seems wonky. Is it correct? If so, the
347 # docstring for heads() should be updated to reflect desired
347 # docstring for heads() should be updated to reflect desired
348 # behavior.
348 # behavior.
349 self.assertEqual(f.heads(stop=[node1]), [node1, node2])
349 self.assertEqual(f.heads(stop=[node1]), [node1, node2])
350 self.assertEqual(f.heads(stop=[node0]), [node0, node2])
350 self.assertEqual(f.heads(stop=[node0]), [node0, node2])
351 self.assertEqual(f.heads(stop=[node1, node2]), [node1, node2])
351 self.assertEqual(f.heads(stop=[node1, node2]), [node1, node2])
352
352
353 with self.assertRaises(error.LookupError):
353 with self.assertRaises(error.LookupError):
354 f.heads(stop=[b'\x01' * 20])
354 f.heads(stop=[b'\x01' * 20])
355
355
356 self.assertEqual(f.children(node0), [node1])
356 self.assertEqual(f.children(node0), [node1])
357 self.assertEqual(f.children(node1), [node2])
357 self.assertEqual(f.children(node1), [node2])
358 self.assertEqual(f.children(node2), [])
358 self.assertEqual(f.children(node2), [])
359
359
360 def testmultipleheads(self):
360 def testmultipleheads(self):
361 f = self._makefilefn()
361 f = self._makefilefn()
362
362
363 with self._maketransactionfn() as tr:
363 with self._maketransactionfn() as tr:
364 node0 = f.add(b'0', None, tr, 0, nullid, nullid)
364 node0 = f.add(b'0', None, tr, 0, nullid, nullid)
365 node1 = f.add(b'1', None, tr, 1, node0, nullid)
365 node1 = f.add(b'1', None, tr, 1, node0, nullid)
366 node2 = f.add(b'2', None, tr, 2, node1, nullid)
366 node2 = f.add(b'2', None, tr, 2, node1, nullid)
367 node3 = f.add(b'3', None, tr, 3, node0, nullid)
367 node3 = f.add(b'3', None, tr, 3, node0, nullid)
368 node4 = f.add(b'4', None, tr, 4, node3, nullid)
368 node4 = f.add(b'4', None, tr, 4, node3, nullid)
369 node5 = f.add(b'5', None, tr, 5, node0, nullid)
369 node5 = f.add(b'5', None, tr, 5, node0, nullid)
370
370
371 self.assertEqual(len(f), 6)
371 self.assertEqual(len(f), 6)
372
372
373 self.assertEqual(list(f.descendants([0])), [1, 2, 3, 4, 5])
373 self.assertEqual(list(f.descendants([0])), [1, 2, 3, 4, 5])
374 self.assertEqual(list(f.descendants([1])), [2])
374 self.assertEqual(list(f.descendants([1])), [2])
375 self.assertEqual(list(f.descendants([2])), [])
375 self.assertEqual(list(f.descendants([2])), [])
376 self.assertEqual(list(f.descendants([3])), [4])
376 self.assertEqual(list(f.descendants([3])), [4])
377 self.assertEqual(list(f.descendants([0, 1])), [1, 2, 3, 4, 5])
377 self.assertEqual(list(f.descendants([0, 1])), [1, 2, 3, 4, 5])
378 self.assertEqual(list(f.descendants([1, 3])), [2, 4])
378 self.assertEqual(list(f.descendants([1, 3])), [2, 4])
379
379
380 self.assertEqual(f.heads(), [node2, node4, node5])
380 self.assertEqual(f.heads(), [node2, node4, node5])
381 self.assertEqual(f.heads(node0), [node2, node4, node5])
381 self.assertEqual(f.heads(node0), [node2, node4, node5])
382 self.assertEqual(f.heads(node1), [node2])
382 self.assertEqual(f.heads(node1), [node2])
383 self.assertEqual(f.heads(node2), [node2])
383 self.assertEqual(f.heads(node2), [node2])
384 self.assertEqual(f.heads(node3), [node4])
384 self.assertEqual(f.heads(node3), [node4])
385 self.assertEqual(f.heads(node4), [node4])
385 self.assertEqual(f.heads(node4), [node4])
386 self.assertEqual(f.heads(node5), [node5])
386 self.assertEqual(f.heads(node5), [node5])
387
387
388 # TODO this seems wrong.
388 # TODO this seems wrong.
389 self.assertEqual(f.heads(stop=[node0]), [node0, node2, node4, node5])
389 self.assertEqual(f.heads(stop=[node0]), [node0, node2, node4, node5])
390 self.assertEqual(f.heads(stop=[node1]), [node1, node2, node4, node5])
390 self.assertEqual(f.heads(stop=[node1]), [node1, node2, node4, node5])
391
391
392 self.assertEqual(f.children(node0), [node1, node3, node5])
392 self.assertEqual(f.children(node0), [node1, node3, node5])
393 self.assertEqual(f.children(node1), [node2])
393 self.assertEqual(f.children(node1), [node2])
394 self.assertEqual(f.children(node2), [])
394 self.assertEqual(f.children(node2), [])
395 self.assertEqual(f.children(node3), [node4])
395 self.assertEqual(f.children(node3), [node4])
396 self.assertEqual(f.children(node4), [])
396 self.assertEqual(f.children(node4), [])
397 self.assertEqual(f.children(node5), [])
397 self.assertEqual(f.children(node5), [])
398
398
399 class ifiledatatests(basetestcase):
399 class ifiledatatests(basetestcase):
400 """Generic tests for the ifiledata interface.
400 """Generic tests for the ifiledata interface.
401
401
402 All file storage backends for data should conform to the tests in this
402 All file storage backends for data should conform to the tests in this
403 class.
403 class.
404
404
405 Use ``makeifiledatatests()`` to create an instance of this type.
405 Use ``makeifiledatatests()`` to create an instance of this type.
406 """
406 """
407 def testempty(self):
407 def testempty(self):
408 f = self._makefilefn()
408 f = self._makefilefn()
409
409
410 self.assertEqual(f.storageinfo(), {})
410 self.assertEqual(f.storageinfo(), {})
411 self.assertEqual(f.storageinfo(revisionscount=True, trackedsize=True),
411 self.assertEqual(f.storageinfo(revisionscount=True, trackedsize=True),
412 {'revisionscount': 0, 'trackedsize': 0})
412 {'revisionscount': 0, 'trackedsize': 0})
413
413
414 self.assertEqual(f.size(nullrev), 0)
414 self.assertEqual(f.size(nullrev), 0)
415
415
416 for i in range(-5, 5):
416 for i in range(-5, 5):
417 if i == nullrev:
417 if i == nullrev:
418 continue
418 continue
419
419
420 with self.assertRaises(IndexError):
420 with self.assertRaises(IndexError):
421 f.size(i)
421 f.size(i)
422
422
423 self.assertEqual(f.revision(nullid), b'')
423 self.assertEqual(f.revision(nullid), b'')
424 self.assertEqual(f.revision(nullid, raw=True), b'')
424 self.assertEqual(f.rawdata(nullid), b'')
425
425
426 with self.assertRaises(error.LookupError):
426 with self.assertRaises(error.LookupError):
427 f.revision(b'\x01' * 20)
427 f.revision(b'\x01' * 20)
428
428
429 self.assertEqual(f.read(nullid), b'')
429 self.assertEqual(f.read(nullid), b'')
430
430
431 with self.assertRaises(error.LookupError):
431 with self.assertRaises(error.LookupError):
432 f.read(b'\x01' * 20)
432 f.read(b'\x01' * 20)
433
433
434 self.assertFalse(f.renamed(nullid))
434 self.assertFalse(f.renamed(nullid))
435
435
436 with self.assertRaises(error.LookupError):
436 with self.assertRaises(error.LookupError):
437 f.read(b'\x01' * 20)
437 f.read(b'\x01' * 20)
438
438
439 self.assertTrue(f.cmp(nullid, b''))
439 self.assertTrue(f.cmp(nullid, b''))
440 self.assertTrue(f.cmp(nullid, b'foo'))
440 self.assertTrue(f.cmp(nullid, b'foo'))
441
441
442 with self.assertRaises(error.LookupError):
442 with self.assertRaises(error.LookupError):
443 f.cmp(b'\x01' * 20, b'irrelevant')
443 f.cmp(b'\x01' * 20, b'irrelevant')
444
444
445 # Emitting empty list is an empty generator.
445 # Emitting empty list is an empty generator.
446 gen = f.emitrevisions([])
446 gen = f.emitrevisions([])
447 with self.assertRaises(StopIteration):
447 with self.assertRaises(StopIteration):
448 next(gen)
448 next(gen)
449
449
450 # Emitting null node yields nothing.
450 # Emitting null node yields nothing.
451 gen = f.emitrevisions([nullid])
451 gen = f.emitrevisions([nullid])
452 with self.assertRaises(StopIteration):
452 with self.assertRaises(StopIteration):
453 next(gen)
453 next(gen)
454
454
455 # Requesting unknown node fails.
455 # Requesting unknown node fails.
456 with self.assertRaises(error.LookupError):
456 with self.assertRaises(error.LookupError):
457 list(f.emitrevisions([b'\x01' * 20]))
457 list(f.emitrevisions([b'\x01' * 20]))
458
458
459 def testsinglerevision(self):
459 def testsinglerevision(self):
460 fulltext = b'initial'
460 fulltext = b'initial'
461
461
462 f = self._makefilefn()
462 f = self._makefilefn()
463 with self._maketransactionfn() as tr:
463 with self._maketransactionfn() as tr:
464 node = f.add(fulltext, None, tr, 0, nullid, nullid)
464 node = f.add(fulltext, None, tr, 0, nullid, nullid)
465
465
466 self.assertEqual(f.storageinfo(), {})
466 self.assertEqual(f.storageinfo(), {})
467 self.assertEqual(f.storageinfo(revisionscount=True, trackedsize=True),
467 self.assertEqual(f.storageinfo(revisionscount=True, trackedsize=True),
468 {'revisionscount': 1, 'trackedsize': len(fulltext)})
468 {'revisionscount': 1, 'trackedsize': len(fulltext)})
469
469
470 self.assertEqual(f.size(0), len(fulltext))
470 self.assertEqual(f.size(0), len(fulltext))
471
471
472 with self.assertRaises(IndexError):
472 with self.assertRaises(IndexError):
473 f.size(1)
473 f.size(1)
474
474
475 self.assertEqual(f.revision(node), fulltext)
475 self.assertEqual(f.revision(node), fulltext)
476 self.assertEqual(f.revision(node, raw=True), fulltext)
476 self.assertEqual(f.rawdata(node), fulltext)
477
477
478 self.assertEqual(f.read(node), fulltext)
478 self.assertEqual(f.read(node), fulltext)
479
479
480 self.assertFalse(f.renamed(node))
480 self.assertFalse(f.renamed(node))
481
481
482 self.assertFalse(f.cmp(node, fulltext))
482 self.assertFalse(f.cmp(node, fulltext))
483 self.assertTrue(f.cmp(node, fulltext + b'extra'))
483 self.assertTrue(f.cmp(node, fulltext + b'extra'))
484
484
485 # Emitting a single revision works.
485 # Emitting a single revision works.
486 gen = f.emitrevisions([node])
486 gen = f.emitrevisions([node])
487 rev = next(gen)
487 rev = next(gen)
488
488
489 self.assertEqual(rev.node, node)
489 self.assertEqual(rev.node, node)
490 self.assertEqual(rev.p1node, nullid)
490 self.assertEqual(rev.p1node, nullid)
491 self.assertEqual(rev.p2node, nullid)
491 self.assertEqual(rev.p2node, nullid)
492 self.assertIsNone(rev.linknode)
492 self.assertIsNone(rev.linknode)
493 self.assertEqual(rev.basenode, nullid)
493 self.assertEqual(rev.basenode, nullid)
494 self.assertIsNone(rev.baserevisionsize)
494 self.assertIsNone(rev.baserevisionsize)
495 self.assertIsNone(rev.revision)
495 self.assertIsNone(rev.revision)
496 self.assertIsNone(rev.delta)
496 self.assertIsNone(rev.delta)
497
497
498 with self.assertRaises(StopIteration):
498 with self.assertRaises(StopIteration):
499 next(gen)
499 next(gen)
500
500
501 # Requesting revision data works.
501 # Requesting revision data works.
502 gen = f.emitrevisions([node], revisiondata=True)
502 gen = f.emitrevisions([node], revisiondata=True)
503 rev = next(gen)
503 rev = next(gen)
504
504
505 self.assertEqual(rev.node, node)
505 self.assertEqual(rev.node, node)
506 self.assertEqual(rev.p1node, nullid)
506 self.assertEqual(rev.p1node, nullid)
507 self.assertEqual(rev.p2node, nullid)
507 self.assertEqual(rev.p2node, nullid)
508 self.assertIsNone(rev.linknode)
508 self.assertIsNone(rev.linknode)
509 self.assertEqual(rev.basenode, nullid)
509 self.assertEqual(rev.basenode, nullid)
510 self.assertIsNone(rev.baserevisionsize)
510 self.assertIsNone(rev.baserevisionsize)
511 self.assertEqual(rev.revision, fulltext)
511 self.assertEqual(rev.revision, fulltext)
512 self.assertIsNone(rev.delta)
512 self.assertIsNone(rev.delta)
513
513
514 with self.assertRaises(StopIteration):
514 with self.assertRaises(StopIteration):
515 next(gen)
515 next(gen)
516
516
517 # Emitting an unknown node after a known revision results in error.
517 # Emitting an unknown node after a known revision results in error.
518 with self.assertRaises(error.LookupError):
518 with self.assertRaises(error.LookupError):
519 list(f.emitrevisions([node, b'\x01' * 20]))
519 list(f.emitrevisions([node, b'\x01' * 20]))
520
520
521 def testmultiplerevisions(self):
521 def testmultiplerevisions(self):
522 fulltext0 = b'x' * 1024
522 fulltext0 = b'x' * 1024
523 fulltext1 = fulltext0 + b'y'
523 fulltext1 = fulltext0 + b'y'
524 fulltext2 = b'y' + fulltext0 + b'z'
524 fulltext2 = b'y' + fulltext0 + b'z'
525
525
526 f = self._makefilefn()
526 f = self._makefilefn()
527 with self._maketransactionfn() as tr:
527 with self._maketransactionfn() as tr:
528 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
528 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
529 node1 = f.add(fulltext1, None, tr, 1, node0, nullid)
529 node1 = f.add(fulltext1, None, tr, 1, node0, nullid)
530 node2 = f.add(fulltext2, None, tr, 3, node1, nullid)
530 node2 = f.add(fulltext2, None, tr, 3, node1, nullid)
531
531
532 self.assertEqual(f.storageinfo(), {})
532 self.assertEqual(f.storageinfo(), {})
533 self.assertEqual(
533 self.assertEqual(
534 f.storageinfo(revisionscount=True, trackedsize=True),
534 f.storageinfo(revisionscount=True, trackedsize=True),
535 {
535 {
536 'revisionscount': 3,
536 'revisionscount': 3,
537 'trackedsize': len(fulltext0) + len(fulltext1) + len(fulltext2),
537 'trackedsize': len(fulltext0) + len(fulltext1) + len(fulltext2),
538 })
538 })
539
539
540 self.assertEqual(f.size(0), len(fulltext0))
540 self.assertEqual(f.size(0), len(fulltext0))
541 self.assertEqual(f.size(1), len(fulltext1))
541 self.assertEqual(f.size(1), len(fulltext1))
542 self.assertEqual(f.size(2), len(fulltext2))
542 self.assertEqual(f.size(2), len(fulltext2))
543
543
544 with self.assertRaises(IndexError):
544 with self.assertRaises(IndexError):
545 f.size(3)
545 f.size(3)
546
546
547 self.assertEqual(f.revision(node0), fulltext0)
547 self.assertEqual(f.revision(node0), fulltext0)
548 self.assertEqual(f.revision(node0, raw=True), fulltext0)
548 self.assertEqual(f.rawdata(node0), fulltext0)
549 self.assertEqual(f.revision(node1), fulltext1)
549 self.assertEqual(f.revision(node1), fulltext1)
550 self.assertEqual(f.revision(node1, raw=True), fulltext1)
550 self.assertEqual(f.rawdata(node1), fulltext1)
551 self.assertEqual(f.revision(node2), fulltext2)
551 self.assertEqual(f.revision(node2), fulltext2)
552 self.assertEqual(f.revision(node2, raw=True), fulltext2)
552 self.assertEqual(f.rawdata(node2), fulltext2)
553
553
554 with self.assertRaises(error.LookupError):
554 with self.assertRaises(error.LookupError):
555 f.revision(b'\x01' * 20)
555 f.revision(b'\x01' * 20)
556
556
557 self.assertEqual(f.read(node0), fulltext0)
557 self.assertEqual(f.read(node0), fulltext0)
558 self.assertEqual(f.read(node1), fulltext1)
558 self.assertEqual(f.read(node1), fulltext1)
559 self.assertEqual(f.read(node2), fulltext2)
559 self.assertEqual(f.read(node2), fulltext2)
560
560
561 with self.assertRaises(error.LookupError):
561 with self.assertRaises(error.LookupError):
562 f.read(b'\x01' * 20)
562 f.read(b'\x01' * 20)
563
563
564 self.assertFalse(f.renamed(node0))
564 self.assertFalse(f.renamed(node0))
565 self.assertFalse(f.renamed(node1))
565 self.assertFalse(f.renamed(node1))
566 self.assertFalse(f.renamed(node2))
566 self.assertFalse(f.renamed(node2))
567
567
568 with self.assertRaises(error.LookupError):
568 with self.assertRaises(error.LookupError):
569 f.renamed(b'\x01' * 20)
569 f.renamed(b'\x01' * 20)
570
570
571 self.assertFalse(f.cmp(node0, fulltext0))
571 self.assertFalse(f.cmp(node0, fulltext0))
572 self.assertFalse(f.cmp(node1, fulltext1))
572 self.assertFalse(f.cmp(node1, fulltext1))
573 self.assertFalse(f.cmp(node2, fulltext2))
573 self.assertFalse(f.cmp(node2, fulltext2))
574
574
575 self.assertTrue(f.cmp(node1, fulltext0))
575 self.assertTrue(f.cmp(node1, fulltext0))
576 self.assertTrue(f.cmp(node2, fulltext1))
576 self.assertTrue(f.cmp(node2, fulltext1))
577
577
578 with self.assertRaises(error.LookupError):
578 with self.assertRaises(error.LookupError):
579 f.cmp(b'\x01' * 20, b'irrelevant')
579 f.cmp(b'\x01' * 20, b'irrelevant')
580
580
581 # Nodes should be emitted in order.
581 # Nodes should be emitted in order.
582 gen = f.emitrevisions([node0, node1, node2], revisiondata=True)
582 gen = f.emitrevisions([node0, node1, node2], revisiondata=True)
583
583
584 rev = next(gen)
584 rev = next(gen)
585
585
586 self.assertEqual(rev.node, node0)
586 self.assertEqual(rev.node, node0)
587 self.assertEqual(rev.p1node, nullid)
587 self.assertEqual(rev.p1node, nullid)
588 self.assertEqual(rev.p2node, nullid)
588 self.assertEqual(rev.p2node, nullid)
589 self.assertIsNone(rev.linknode)
589 self.assertIsNone(rev.linknode)
590 self.assertEqual(rev.basenode, nullid)
590 self.assertEqual(rev.basenode, nullid)
591 self.assertIsNone(rev.baserevisionsize)
591 self.assertIsNone(rev.baserevisionsize)
592 self.assertEqual(rev.revision, fulltext0)
592 self.assertEqual(rev.revision, fulltext0)
593 self.assertIsNone(rev.delta)
593 self.assertIsNone(rev.delta)
594
594
595 rev = next(gen)
595 rev = next(gen)
596
596
597 self.assertEqual(rev.node, node1)
597 self.assertEqual(rev.node, node1)
598 self.assertEqual(rev.p1node, node0)
598 self.assertEqual(rev.p1node, node0)
599 self.assertEqual(rev.p2node, nullid)
599 self.assertEqual(rev.p2node, nullid)
600 self.assertIsNone(rev.linknode)
600 self.assertIsNone(rev.linknode)
601 self.assertEqual(rev.basenode, node0)
601 self.assertEqual(rev.basenode, node0)
602 self.assertIsNone(rev.baserevisionsize)
602 self.assertIsNone(rev.baserevisionsize)
603 self.assertIsNone(rev.revision)
603 self.assertIsNone(rev.revision)
604 self.assertEqual(rev.delta,
604 self.assertEqual(rev.delta,
605 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' +
605 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' +
606 fulltext1)
606 fulltext1)
607
607
608 rev = next(gen)
608 rev = next(gen)
609
609
610 self.assertEqual(rev.node, node2)
610 self.assertEqual(rev.node, node2)
611 self.assertEqual(rev.p1node, node1)
611 self.assertEqual(rev.p1node, node1)
612 self.assertEqual(rev.p2node, nullid)
612 self.assertEqual(rev.p2node, nullid)
613 self.assertIsNone(rev.linknode)
613 self.assertIsNone(rev.linknode)
614 self.assertEqual(rev.basenode, node1)
614 self.assertEqual(rev.basenode, node1)
615 self.assertIsNone(rev.baserevisionsize)
615 self.assertIsNone(rev.baserevisionsize)
616 self.assertIsNone(rev.revision)
616 self.assertIsNone(rev.revision)
617 self.assertEqual(rev.delta,
617 self.assertEqual(rev.delta,
618 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' +
618 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' +
619 fulltext2)
619 fulltext2)
620
620
621 with self.assertRaises(StopIteration):
621 with self.assertRaises(StopIteration):
622 next(gen)
622 next(gen)
623
623
624 # Request not in DAG order is reordered to be in DAG order.
624 # Request not in DAG order is reordered to be in DAG order.
625 gen = f.emitrevisions([node2, node1, node0], revisiondata=True)
625 gen = f.emitrevisions([node2, node1, node0], revisiondata=True)
626
626
627 rev = next(gen)
627 rev = next(gen)
628
628
629 self.assertEqual(rev.node, node0)
629 self.assertEqual(rev.node, node0)
630 self.assertEqual(rev.p1node, nullid)
630 self.assertEqual(rev.p1node, nullid)
631 self.assertEqual(rev.p2node, nullid)
631 self.assertEqual(rev.p2node, nullid)
632 self.assertIsNone(rev.linknode)
632 self.assertIsNone(rev.linknode)
633 self.assertEqual(rev.basenode, nullid)
633 self.assertEqual(rev.basenode, nullid)
634 self.assertIsNone(rev.baserevisionsize)
634 self.assertIsNone(rev.baserevisionsize)
635 self.assertEqual(rev.revision, fulltext0)
635 self.assertEqual(rev.revision, fulltext0)
636 self.assertIsNone(rev.delta)
636 self.assertIsNone(rev.delta)
637
637
638 rev = next(gen)
638 rev = next(gen)
639
639
640 self.assertEqual(rev.node, node1)
640 self.assertEqual(rev.node, node1)
641 self.assertEqual(rev.p1node, node0)
641 self.assertEqual(rev.p1node, node0)
642 self.assertEqual(rev.p2node, nullid)
642 self.assertEqual(rev.p2node, nullid)
643 self.assertIsNone(rev.linknode)
643 self.assertIsNone(rev.linknode)
644 self.assertEqual(rev.basenode, node0)
644 self.assertEqual(rev.basenode, node0)
645 self.assertIsNone(rev.baserevisionsize)
645 self.assertIsNone(rev.baserevisionsize)
646 self.assertIsNone(rev.revision)
646 self.assertIsNone(rev.revision)
647 self.assertEqual(rev.delta,
647 self.assertEqual(rev.delta,
648 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' +
648 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' +
649 fulltext1)
649 fulltext1)
650
650
651 rev = next(gen)
651 rev = next(gen)
652
652
653 self.assertEqual(rev.node, node2)
653 self.assertEqual(rev.node, node2)
654 self.assertEqual(rev.p1node, node1)
654 self.assertEqual(rev.p1node, node1)
655 self.assertEqual(rev.p2node, nullid)
655 self.assertEqual(rev.p2node, nullid)
656 self.assertIsNone(rev.linknode)
656 self.assertIsNone(rev.linknode)
657 self.assertEqual(rev.basenode, node1)
657 self.assertEqual(rev.basenode, node1)
658 self.assertIsNone(rev.baserevisionsize)
658 self.assertIsNone(rev.baserevisionsize)
659 self.assertIsNone(rev.revision)
659 self.assertIsNone(rev.revision)
660 self.assertEqual(rev.delta,
660 self.assertEqual(rev.delta,
661 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' +
661 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' +
662 fulltext2)
662 fulltext2)
663
663
664 with self.assertRaises(StopIteration):
664 with self.assertRaises(StopIteration):
665 next(gen)
665 next(gen)
666
666
667 # Unrecognized nodesorder value raises ProgrammingError.
667 # Unrecognized nodesorder value raises ProgrammingError.
668 with self.assertRaises(error.ProgrammingError):
668 with self.assertRaises(error.ProgrammingError):
669 list(f.emitrevisions([], nodesorder='bad'))
669 list(f.emitrevisions([], nodesorder='bad'))
670
670
671 # nodesorder=storage is recognized. But we can't test it thoroughly
671 # nodesorder=storage is recognized. But we can't test it thoroughly
672 # because behavior is storage-dependent.
672 # because behavior is storage-dependent.
673 res = list(f.emitrevisions([node2, node1, node0],
673 res = list(f.emitrevisions([node2, node1, node0],
674 nodesorder='storage'))
674 nodesorder='storage'))
675 self.assertEqual(len(res), 3)
675 self.assertEqual(len(res), 3)
676 self.assertEqual({o.node for o in res}, {node0, node1, node2})
676 self.assertEqual({o.node for o in res}, {node0, node1, node2})
677
677
678 # nodesorder=nodes forces the order.
678 # nodesorder=nodes forces the order.
679 gen = f.emitrevisions([node2, node0], nodesorder='nodes',
679 gen = f.emitrevisions([node2, node0], nodesorder='nodes',
680 revisiondata=True)
680 revisiondata=True)
681
681
682 rev = next(gen)
682 rev = next(gen)
683 self.assertEqual(rev.node, node2)
683 self.assertEqual(rev.node, node2)
684 self.assertEqual(rev.p1node, node1)
684 self.assertEqual(rev.p1node, node1)
685 self.assertEqual(rev.p2node, nullid)
685 self.assertEqual(rev.p2node, nullid)
686 self.assertEqual(rev.basenode, nullid)
686 self.assertEqual(rev.basenode, nullid)
687 self.assertIsNone(rev.baserevisionsize)
687 self.assertIsNone(rev.baserevisionsize)
688 self.assertEqual(rev.revision, fulltext2)
688 self.assertEqual(rev.revision, fulltext2)
689 self.assertIsNone(rev.delta)
689 self.assertIsNone(rev.delta)
690
690
691 rev = next(gen)
691 rev = next(gen)
692 self.assertEqual(rev.node, node0)
692 self.assertEqual(rev.node, node0)
693 self.assertEqual(rev.p1node, nullid)
693 self.assertEqual(rev.p1node, nullid)
694 self.assertEqual(rev.p2node, nullid)
694 self.assertEqual(rev.p2node, nullid)
695 # Delta behavior is storage dependent, so we can't easily test it.
695 # Delta behavior is storage dependent, so we can't easily test it.
696
696
697 with self.assertRaises(StopIteration):
697 with self.assertRaises(StopIteration):
698 next(gen)
698 next(gen)
699
699
700 # assumehaveparentrevisions=False (the default) won't send a delta for
700 # assumehaveparentrevisions=False (the default) won't send a delta for
701 # the first revision.
701 # the first revision.
702 gen = f.emitrevisions({node2, node1}, revisiondata=True)
702 gen = f.emitrevisions({node2, node1}, revisiondata=True)
703
703
704 rev = next(gen)
704 rev = next(gen)
705 self.assertEqual(rev.node, node1)
705 self.assertEqual(rev.node, node1)
706 self.assertEqual(rev.p1node, node0)
706 self.assertEqual(rev.p1node, node0)
707 self.assertEqual(rev.p2node, nullid)
707 self.assertEqual(rev.p2node, nullid)
708 self.assertEqual(rev.basenode, nullid)
708 self.assertEqual(rev.basenode, nullid)
709 self.assertIsNone(rev.baserevisionsize)
709 self.assertIsNone(rev.baserevisionsize)
710 self.assertEqual(rev.revision, fulltext1)
710 self.assertEqual(rev.revision, fulltext1)
711 self.assertIsNone(rev.delta)
711 self.assertIsNone(rev.delta)
712
712
713 rev = next(gen)
713 rev = next(gen)
714 self.assertEqual(rev.node, node2)
714 self.assertEqual(rev.node, node2)
715 self.assertEqual(rev.p1node, node1)
715 self.assertEqual(rev.p1node, node1)
716 self.assertEqual(rev.p2node, nullid)
716 self.assertEqual(rev.p2node, nullid)
717 self.assertEqual(rev.basenode, node1)
717 self.assertEqual(rev.basenode, node1)
718 self.assertIsNone(rev.baserevisionsize)
718 self.assertIsNone(rev.baserevisionsize)
719 self.assertIsNone(rev.revision)
719 self.assertIsNone(rev.revision)
720 self.assertEqual(rev.delta,
720 self.assertEqual(rev.delta,
721 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' +
721 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' +
722 fulltext2)
722 fulltext2)
723
723
724 with self.assertRaises(StopIteration):
724 with self.assertRaises(StopIteration):
725 next(gen)
725 next(gen)
726
726
727 # assumehaveparentrevisions=True allows delta against initial revision.
727 # assumehaveparentrevisions=True allows delta against initial revision.
728 gen = f.emitrevisions([node2, node1],
728 gen = f.emitrevisions([node2, node1],
729 revisiondata=True, assumehaveparentrevisions=True)
729 revisiondata=True, assumehaveparentrevisions=True)
730
730
731 rev = next(gen)
731 rev = next(gen)
732 self.assertEqual(rev.node, node1)
732 self.assertEqual(rev.node, node1)
733 self.assertEqual(rev.p1node, node0)
733 self.assertEqual(rev.p1node, node0)
734 self.assertEqual(rev.p2node, nullid)
734 self.assertEqual(rev.p2node, nullid)
735 self.assertEqual(rev.basenode, node0)
735 self.assertEqual(rev.basenode, node0)
736 self.assertIsNone(rev.baserevisionsize)
736 self.assertIsNone(rev.baserevisionsize)
737 self.assertIsNone(rev.revision)
737 self.assertIsNone(rev.revision)
738 self.assertEqual(rev.delta,
738 self.assertEqual(rev.delta,
739 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' +
739 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' +
740 fulltext1)
740 fulltext1)
741
741
742 # forceprevious=True forces a delta against the previous revision.
742 # forceprevious=True forces a delta against the previous revision.
743 # Special case for initial revision.
743 # Special case for initial revision.
744 gen = f.emitrevisions([node0], revisiondata=True,
744 gen = f.emitrevisions([node0], revisiondata=True,
745 deltamode=repository.CG_DELTAMODE_PREV)
745 deltamode=repository.CG_DELTAMODE_PREV)
746
746
747 rev = next(gen)
747 rev = next(gen)
748 self.assertEqual(rev.node, node0)
748 self.assertEqual(rev.node, node0)
749 self.assertEqual(rev.p1node, nullid)
749 self.assertEqual(rev.p1node, nullid)
750 self.assertEqual(rev.p2node, nullid)
750 self.assertEqual(rev.p2node, nullid)
751 self.assertEqual(rev.basenode, nullid)
751 self.assertEqual(rev.basenode, nullid)
752 self.assertIsNone(rev.baserevisionsize)
752 self.assertIsNone(rev.baserevisionsize)
753 self.assertIsNone(rev.revision)
753 self.assertIsNone(rev.revision)
754 self.assertEqual(rev.delta,
754 self.assertEqual(rev.delta,
755 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' +
755 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' +
756 fulltext0)
756 fulltext0)
757
757
758 with self.assertRaises(StopIteration):
758 with self.assertRaises(StopIteration):
759 next(gen)
759 next(gen)
760
760
761 gen = f.emitrevisions([node0, node2], revisiondata=True,
761 gen = f.emitrevisions([node0, node2], revisiondata=True,
762 deltamode=repository.CG_DELTAMODE_PREV)
762 deltamode=repository.CG_DELTAMODE_PREV)
763
763
764 rev = next(gen)
764 rev = next(gen)
765 self.assertEqual(rev.node, node0)
765 self.assertEqual(rev.node, node0)
766 self.assertEqual(rev.p1node, nullid)
766 self.assertEqual(rev.p1node, nullid)
767 self.assertEqual(rev.p2node, nullid)
767 self.assertEqual(rev.p2node, nullid)
768 self.assertEqual(rev.basenode, nullid)
768 self.assertEqual(rev.basenode, nullid)
769 self.assertIsNone(rev.baserevisionsize)
769 self.assertIsNone(rev.baserevisionsize)
770 self.assertIsNone(rev.revision)
770 self.assertIsNone(rev.revision)
771 self.assertEqual(rev.delta,
771 self.assertEqual(rev.delta,
772 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' +
772 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' +
773 fulltext0)
773 fulltext0)
774
774
775 rev = next(gen)
775 rev = next(gen)
776 self.assertEqual(rev.node, node2)
776 self.assertEqual(rev.node, node2)
777 self.assertEqual(rev.p1node, node1)
777 self.assertEqual(rev.p1node, node1)
778 self.assertEqual(rev.p2node, nullid)
778 self.assertEqual(rev.p2node, nullid)
779 self.assertEqual(rev.basenode, node0)
779 self.assertEqual(rev.basenode, node0)
780
780
781 with self.assertRaises(StopIteration):
781 with self.assertRaises(StopIteration):
782 next(gen)
782 next(gen)
783
783
784 def testrenamed(self):
784 def testrenamed(self):
785 fulltext0 = b'foo'
785 fulltext0 = b'foo'
786 fulltext1 = b'bar'
786 fulltext1 = b'bar'
787 fulltext2 = b'baz'
787 fulltext2 = b'baz'
788
788
789 meta1 = {
789 meta1 = {
790 b'copy': b'source0',
790 b'copy': b'source0',
791 b'copyrev': b'a' * 40,
791 b'copyrev': b'a' * 40,
792 }
792 }
793
793
794 meta2 = {
794 meta2 = {
795 b'copy': b'source1',
795 b'copy': b'source1',
796 b'copyrev': b'b' * 40,
796 b'copyrev': b'b' * 40,
797 }
797 }
798
798
799 stored1 = b''.join([
799 stored1 = b''.join([
800 b'\x01\ncopy: source0\n',
800 b'\x01\ncopy: source0\n',
801 b'copyrev: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\x01\n',
801 b'copyrev: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\x01\n',
802 fulltext1,
802 fulltext1,
803 ])
803 ])
804
804
805 stored2 = b''.join([
805 stored2 = b''.join([
806 b'\x01\ncopy: source1\n',
806 b'\x01\ncopy: source1\n',
807 b'copyrev: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n\x01\n',
807 b'copyrev: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n\x01\n',
808 fulltext2,
808 fulltext2,
809 ])
809 ])
810
810
811 f = self._makefilefn()
811 f = self._makefilefn()
812 with self._maketransactionfn() as tr:
812 with self._maketransactionfn() as tr:
813 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
813 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
814 node1 = f.add(fulltext1, meta1, tr, 1, node0, nullid)
814 node1 = f.add(fulltext1, meta1, tr, 1, node0, nullid)
815 node2 = f.add(fulltext2, meta2, tr, 2, nullid, nullid)
815 node2 = f.add(fulltext2, meta2, tr, 2, nullid, nullid)
816
816
817 # Metadata header isn't recognized when parent isn't nullid.
817 # Metadata header isn't recognized when parent isn't nullid.
818 self.assertEqual(f.size(1), len(stored1))
818 self.assertEqual(f.size(1), len(stored1))
819 self.assertEqual(f.size(2), len(fulltext2))
819 self.assertEqual(f.size(2), len(fulltext2))
820
820
821 self.assertEqual(f.revision(node1), stored1)
821 self.assertEqual(f.revision(node1), stored1)
822 self.assertEqual(f.revision(node1, raw=True), stored1)
822 self.assertEqual(f.rawdata(node1), stored1)
823 self.assertEqual(f.revision(node2), stored2)
823 self.assertEqual(f.revision(node2), stored2)
824 self.assertEqual(f.revision(node2, raw=True), stored2)
824 self.assertEqual(f.rawdata(node2), stored2)
825
825
826 self.assertEqual(f.read(node1), fulltext1)
826 self.assertEqual(f.read(node1), fulltext1)
827 self.assertEqual(f.read(node2), fulltext2)
827 self.assertEqual(f.read(node2), fulltext2)
828
828
829 # Returns False when first parent is set.
829 # Returns False when first parent is set.
830 self.assertFalse(f.renamed(node1))
830 self.assertFalse(f.renamed(node1))
831 self.assertEqual(f.renamed(node2), (b'source1', b'\xbb' * 20))
831 self.assertEqual(f.renamed(node2), (b'source1', b'\xbb' * 20))
832
832
833 self.assertTrue(f.cmp(node1, fulltext1))
833 self.assertTrue(f.cmp(node1, fulltext1))
834 self.assertTrue(f.cmp(node1, stored1))
834 self.assertTrue(f.cmp(node1, stored1))
835 self.assertFalse(f.cmp(node2, fulltext2))
835 self.assertFalse(f.cmp(node2, fulltext2))
836 self.assertTrue(f.cmp(node2, stored2))
836 self.assertTrue(f.cmp(node2, stored2))
837
837
838 def testmetadataprefix(self):
838 def testmetadataprefix(self):
839 # Content with metadata prefix has extra prefix inserted in storage.
839 # Content with metadata prefix has extra prefix inserted in storage.
840 fulltext0 = b'\x01\nfoo'
840 fulltext0 = b'\x01\nfoo'
841 stored0 = b'\x01\n\x01\n\x01\nfoo'
841 stored0 = b'\x01\n\x01\n\x01\nfoo'
842
842
843 fulltext1 = b'\x01\nbar'
843 fulltext1 = b'\x01\nbar'
844 meta1 = {
844 meta1 = {
845 b'copy': b'source0',
845 b'copy': b'source0',
846 b'copyrev': b'b' * 40,
846 b'copyrev': b'b' * 40,
847 }
847 }
848 stored1 = b''.join([
848 stored1 = b''.join([
849 b'\x01\ncopy: source0\n',
849 b'\x01\ncopy: source0\n',
850 b'copyrev: %s\n' % (b'b' * 40),
850 b'copyrev: %s\n' % (b'b' * 40),
851 b'\x01\n\x01\nbar',
851 b'\x01\n\x01\nbar',
852 ])
852 ])
853
853
854 f = self._makefilefn()
854 f = self._makefilefn()
855 with self._maketransactionfn() as tr:
855 with self._maketransactionfn() as tr:
856 node0 = f.add(fulltext0, {}, tr, 0, nullid, nullid)
856 node0 = f.add(fulltext0, {}, tr, 0, nullid, nullid)
857 node1 = f.add(fulltext1, meta1, tr, 1, nullid, nullid)
857 node1 = f.add(fulltext1, meta1, tr, 1, nullid, nullid)
858
858
859 # TODO this is buggy.
859 # TODO this is buggy.
860 self.assertEqual(f.size(0), len(fulltext0) + 4)
860 self.assertEqual(f.size(0), len(fulltext0) + 4)
861
861
862 self.assertEqual(f.size(1), len(fulltext1))
862 self.assertEqual(f.size(1), len(fulltext1))
863
863
864 self.assertEqual(f.revision(node0), stored0)
864 self.assertEqual(f.revision(node0), stored0)
865 self.assertEqual(f.revision(node0, raw=True), stored0)
865 self.assertEqual(f.rawdata(node0), stored0)
866
866
867 self.assertEqual(f.revision(node1), stored1)
867 self.assertEqual(f.revision(node1), stored1)
868 self.assertEqual(f.revision(node1, raw=True), stored1)
868 self.assertEqual(f.rawdata(node1), stored1)
869
869
870 self.assertEqual(f.read(node0), fulltext0)
870 self.assertEqual(f.read(node0), fulltext0)
871 self.assertEqual(f.read(node1), fulltext1)
871 self.assertEqual(f.read(node1), fulltext1)
872
872
873 self.assertFalse(f.cmp(node0, fulltext0))
873 self.assertFalse(f.cmp(node0, fulltext0))
874 self.assertTrue(f.cmp(node0, stored0))
874 self.assertTrue(f.cmp(node0, stored0))
875
875
876 self.assertFalse(f.cmp(node1, fulltext1))
876 self.assertFalse(f.cmp(node1, fulltext1))
877 self.assertTrue(f.cmp(node1, stored0))
877 self.assertTrue(f.cmp(node1, stored0))
878
878
879 def testbadnoderead(self):
879 def testbadnoderead(self):
880 f = self._makefilefn()
880 f = self._makefilefn()
881
881
882 fulltext0 = b'foo\n' * 30
882 fulltext0 = b'foo\n' * 30
883 fulltext1 = fulltext0 + b'bar\n'
883 fulltext1 = fulltext0 + b'bar\n'
884
884
885 with self._maketransactionfn() as tr:
885 with self._maketransactionfn() as tr:
886 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
886 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
887 node1 = b'\xaa' * 20
887 node1 = b'\xaa' * 20
888
888
889 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
889 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
890 rawtext=fulltext1)
890 rawtext=fulltext1)
891
891
892 self.assertEqual(len(f), 2)
892 self.assertEqual(len(f), 2)
893 self.assertEqual(f.parents(node1), (node0, nullid))
893 self.assertEqual(f.parents(node1), (node0, nullid))
894
894
895 # revision() raises since it performs hash verification.
895 # revision() raises since it performs hash verification.
896 with self.assertRaises(error.StorageError):
896 with self.assertRaises(error.StorageError):
897 f.revision(node1)
897 f.revision(node1)
898
898
899 # raw=True still verifies because there are no special storage
899 # rawdata() still verifies because there are no special storage
900 # settings.
900 # settings.
901 with self.assertRaises(error.StorageError):
901 with self.assertRaises(error.StorageError):
902 f.revision(node1, raw=True)
902 f.rawdata(node1)
903
903
904 # read() behaves like revision().
904 # read() behaves like revision().
905 with self.assertRaises(error.StorageError):
905 with self.assertRaises(error.StorageError):
906 f.read(node1)
906 f.read(node1)
907
907
908 # We can't test renamed() here because some backends may not require
908 # We can't test renamed() here because some backends may not require
909 # reading/validating the fulltext to return rename metadata.
909 # reading/validating the fulltext to return rename metadata.
910
910
911 def testbadnoderevisionraw(self):
911 def testbadnoderevisionraw(self):
912 # Like above except we test revision(raw=True) first to isolate
912 # Like above except we test rawdata() first to isolate
913 # revision caching behavior.
913 # revision caching behavior.
914 f = self._makefilefn()
914 f = self._makefilefn()
915
915
916 fulltext0 = b'foo\n' * 30
916 fulltext0 = b'foo\n' * 30
917 fulltext1 = fulltext0 + b'bar\n'
917 fulltext1 = fulltext0 + b'bar\n'
918
918
919 with self._maketransactionfn() as tr:
919 with self._maketransactionfn() as tr:
920 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
920 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
921 node1 = b'\xaa' * 20
921 node1 = b'\xaa' * 20
922
922
923 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
923 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
924 rawtext=fulltext1)
924 rawtext=fulltext1)
925
925
926 with self.assertRaises(error.StorageError):
926 with self.assertRaises(error.StorageError):
927 f.revision(node1, raw=True)
927 f.rawdata(node1)
928
928
929 with self.assertRaises(error.StorageError):
929 with self.assertRaises(error.StorageError):
930 f.revision(node1, raw=True)
930 f.rawdata(node1)
931
931
932 def testbadnoderevisionraw(self):
932 def testbadnoderevisionraw(self):
933 # Like above except we test read() first to isolate revision caching
933 # Like above except we test read() first to isolate revision caching
934 # behavior.
934 # behavior.
935 f = self._makefilefn()
935 f = self._makefilefn()
936
936
937 fulltext0 = b'foo\n' * 30
937 fulltext0 = b'foo\n' * 30
938 fulltext1 = fulltext0 + b'bar\n'
938 fulltext1 = fulltext0 + b'bar\n'
939
939
940 with self._maketransactionfn() as tr:
940 with self._maketransactionfn() as tr:
941 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
941 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
942 node1 = b'\xaa' * 20
942 node1 = b'\xaa' * 20
943
943
944 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
944 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
945 rawtext=fulltext1)
945 rawtext=fulltext1)
946
946
947 with self.assertRaises(error.StorageError):
947 with self.assertRaises(error.StorageError):
948 f.read(node1)
948 f.read(node1)
949
949
950 with self.assertRaises(error.StorageError):
950 with self.assertRaises(error.StorageError):
951 f.read(node1)
951 f.read(node1)
952
952
953 def testbadnodedelta(self):
953 def testbadnodedelta(self):
954 f = self._makefilefn()
954 f = self._makefilefn()
955
955
956 fulltext0 = b'foo\n' * 31
956 fulltext0 = b'foo\n' * 31
957 fulltext1 = fulltext0 + b'bar\n'
957 fulltext1 = fulltext0 + b'bar\n'
958 fulltext2 = fulltext1 + b'baz\n'
958 fulltext2 = fulltext1 + b'baz\n'
959
959
960 with self._maketransactionfn() as tr:
960 with self._maketransactionfn() as tr:
961 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
961 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
962 node1 = b'\xaa' * 20
962 node1 = b'\xaa' * 20
963
963
964 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
964 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1,
965 rawtext=fulltext1)
965 rawtext=fulltext1)
966
966
967 with self.assertRaises(error.StorageError):
967 with self.assertRaises(error.StorageError):
968 f.read(node1)
968 f.read(node1)
969
969
970 node2 = storageutil.hashrevisionsha1(fulltext2, node1, nullid)
970 node2 = storageutil.hashrevisionsha1(fulltext2, node1, nullid)
971
971
972 with self._maketransactionfn() as tr:
972 with self._maketransactionfn() as tr:
973 delta = mdiff.textdiff(fulltext1, fulltext2)
973 delta = mdiff.textdiff(fulltext1, fulltext2)
974 self._addrawrevisionfn(f, tr, node2, node1, nullid,
974 self._addrawrevisionfn(f, tr, node2, node1, nullid,
975 2, delta=(1, delta))
975 2, delta=(1, delta))
976
976
977 self.assertEqual(len(f), 3)
977 self.assertEqual(len(f), 3)
978
978
979 # Assuming a delta is stored, we shouldn't need to validate node1 in
979 # Assuming a delta is stored, we shouldn't need to validate node1 in
980 # order to retrieve node2.
980 # order to retrieve node2.
981 self.assertEqual(f.read(node2), fulltext2)
981 self.assertEqual(f.read(node2), fulltext2)
982
982
983 def testcensored(self):
983 def testcensored(self):
984 f = self._makefilefn()
984 f = self._makefilefn()
985
985
986 stored1 = storageutil.packmeta({
986 stored1 = storageutil.packmeta({
987 b'censored': b'tombstone',
987 b'censored': b'tombstone',
988 }, b'')
988 }, b'')
989
989
990 with self._maketransactionfn() as tr:
990 with self._maketransactionfn() as tr:
991 node0 = f.add(b'foo', None, tr, 0, nullid, nullid)
991 node0 = f.add(b'foo', None, tr, 0, nullid, nullid)
992
992
993 # The node value doesn't matter since we can't verify it.
993 # The node value doesn't matter since we can't verify it.
994 node1 = b'\xbb' * 20
994 node1 = b'\xbb' * 20
995
995
996 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1,
996 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1,
997 censored=True)
997 censored=True)
998
998
999 self.assertTrue(f.iscensored(1))
999 self.assertTrue(f.iscensored(1))
1000
1000
1001 with self.assertRaises(error.CensoredNodeError):
1001 with self.assertRaises(error.CensoredNodeError):
1002 f.revision(1)
1002 f.revision(1)
1003
1003
1004 with self.assertRaises(error.CensoredNodeError):
1004 with self.assertRaises(error.CensoredNodeError):
1005 f.revision(1, raw=True)
1005 f.rawdata(1)
1006
1006
1007 with self.assertRaises(error.CensoredNodeError):
1007 with self.assertRaises(error.CensoredNodeError):
1008 f.read(1)
1008 f.read(1)
1009
1009
1010 def testcensoredrawrevision(self):
1010 def testcensoredrawrevision(self):
1011 # Like above, except we do the revision(raw=True) request first to
1011 # Like above, except we do the rawdata() request first to
1012 # isolate revision caching behavior.
1012 # isolate revision caching behavior.
1013
1013
1014 f = self._makefilefn()
1014 f = self._makefilefn()
1015
1015
1016 stored1 = storageutil.packmeta({
1016 stored1 = storageutil.packmeta({
1017 b'censored': b'tombstone',
1017 b'censored': b'tombstone',
1018 }, b'')
1018 }, b'')
1019
1019
1020 with self._maketransactionfn() as tr:
1020 with self._maketransactionfn() as tr:
1021 node0 = f.add(b'foo', None, tr, 0, nullid, nullid)
1021 node0 = f.add(b'foo', None, tr, 0, nullid, nullid)
1022
1022
1023 # The node value doesn't matter since we can't verify it.
1023 # The node value doesn't matter since we can't verify it.
1024 node1 = b'\xbb' * 20
1024 node1 = b'\xbb' * 20
1025
1025
1026 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1,
1026 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1,
1027 censored=True)
1027 censored=True)
1028
1028
1029 with self.assertRaises(error.CensoredNodeError):
1029 with self.assertRaises(error.CensoredNodeError):
1030 f.revision(1, raw=True)
1030 f.rawdata(1)
1031
1031
1032 class ifilemutationtests(basetestcase):
1032 class ifilemutationtests(basetestcase):
1033 """Generic tests for the ifilemutation interface.
1033 """Generic tests for the ifilemutation interface.
1034
1034
1035 All file storage backends that support writing should conform to this
1035 All file storage backends that support writing should conform to this
1036 interface.
1036 interface.
1037
1037
1038 Use ``makeifilemutationtests()`` to create an instance of this type.
1038 Use ``makeifilemutationtests()`` to create an instance of this type.
1039 """
1039 """
1040 def testaddnoop(self):
1040 def testaddnoop(self):
1041 f = self._makefilefn()
1041 f = self._makefilefn()
1042 with self._maketransactionfn() as tr:
1042 with self._maketransactionfn() as tr:
1043 node0 = f.add(b'foo', None, tr, 0, nullid, nullid)
1043 node0 = f.add(b'foo', None, tr, 0, nullid, nullid)
1044 node1 = f.add(b'foo', None, tr, 0, nullid, nullid)
1044 node1 = f.add(b'foo', None, tr, 0, nullid, nullid)
1045 # Varying by linkrev shouldn't impact hash.
1045 # Varying by linkrev shouldn't impact hash.
1046 node2 = f.add(b'foo', None, tr, 1, nullid, nullid)
1046 node2 = f.add(b'foo', None, tr, 1, nullid, nullid)
1047
1047
1048 self.assertEqual(node1, node0)
1048 self.assertEqual(node1, node0)
1049 self.assertEqual(node2, node0)
1049 self.assertEqual(node2, node0)
1050 self.assertEqual(len(f), 1)
1050 self.assertEqual(len(f), 1)
1051
1051
1052 def testaddrevisionbadnode(self):
1052 def testaddrevisionbadnode(self):
1053 f = self._makefilefn()
1053 f = self._makefilefn()
1054 with self._maketransactionfn() as tr:
1054 with self._maketransactionfn() as tr:
1055 # Adding a revision with bad node value fails.
1055 # Adding a revision with bad node value fails.
1056 with self.assertRaises(error.StorageError):
1056 with self.assertRaises(error.StorageError):
1057 f.addrevision(b'foo', tr, 0, nullid, nullid, node=b'\x01' * 20)
1057 f.addrevision(b'foo', tr, 0, nullid, nullid, node=b'\x01' * 20)
1058
1058
1059 def testaddrevisionunknownflag(self):
1059 def testaddrevisionunknownflag(self):
1060 f = self._makefilefn()
1060 f = self._makefilefn()
1061 with self._maketransactionfn() as tr:
1061 with self._maketransactionfn() as tr:
1062 for i in range(15, 0, -1):
1062 for i in range(15, 0, -1):
1063 if (1 << i) & ~repository.REVISION_FLAGS_KNOWN:
1063 if (1 << i) & ~repository.REVISION_FLAGS_KNOWN:
1064 flags = 1 << i
1064 flags = 1 << i
1065 break
1065 break
1066
1066
1067 with self.assertRaises(error.StorageError):
1067 with self.assertRaises(error.StorageError):
1068 f.addrevision(b'foo', tr, 0, nullid, nullid, flags=flags)
1068 f.addrevision(b'foo', tr, 0, nullid, nullid, flags=flags)
1069
1069
1070 def testaddgroupsimple(self):
1070 def testaddgroupsimple(self):
1071 f = self._makefilefn()
1071 f = self._makefilefn()
1072
1072
1073 callbackargs = []
1073 callbackargs = []
1074 def cb(*args, **kwargs):
1074 def cb(*args, **kwargs):
1075 callbackargs.append((args, kwargs))
1075 callbackargs.append((args, kwargs))
1076
1076
1077 def linkmapper(node):
1077 def linkmapper(node):
1078 return 0
1078 return 0
1079
1079
1080 with self._maketransactionfn() as tr:
1080 with self._maketransactionfn() as tr:
1081 nodes = f.addgroup([], None, tr, addrevisioncb=cb)
1081 nodes = f.addgroup([], None, tr, addrevisioncb=cb)
1082
1082
1083 self.assertEqual(nodes, [])
1083 self.assertEqual(nodes, [])
1084 self.assertEqual(callbackargs, [])
1084 self.assertEqual(callbackargs, [])
1085 self.assertEqual(len(f), 0)
1085 self.assertEqual(len(f), 0)
1086
1086
1087 fulltext0 = b'foo'
1087 fulltext0 = b'foo'
1088 delta0 = mdiff.trivialdiffheader(len(fulltext0)) + fulltext0
1088 delta0 = mdiff.trivialdiffheader(len(fulltext0)) + fulltext0
1089
1089
1090 with self._maketransactionfn() as tr:
1090 with self._maketransactionfn() as tr:
1091 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
1091 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid)
1092
1092
1093 f = self._makefilefn()
1093 f = self._makefilefn()
1094
1094
1095 deltas = [
1095 deltas = [
1096 (node0, nullid, nullid, nullid, nullid, delta0, 0),
1096 (node0, nullid, nullid, nullid, nullid, delta0, 0),
1097 ]
1097 ]
1098
1098
1099 with self._maketransactionfn() as tr:
1099 with self._maketransactionfn() as tr:
1100 nodes = f.addgroup(deltas, linkmapper, tr, addrevisioncb=cb)
1100 nodes = f.addgroup(deltas, linkmapper, tr, addrevisioncb=cb)
1101
1101
1102 self.assertEqual(nodes, [
1102 self.assertEqual(nodes, [
1103 b'\x49\xd8\xcb\xb1\x5c\xe2\x57\x92\x04\x47'
1103 b'\x49\xd8\xcb\xb1\x5c\xe2\x57\x92\x04\x47'
1104 b'\x00\x6b\x46\x97\x8b\x7a\xf9\x80\xa9\x79'])
1104 b'\x00\x6b\x46\x97\x8b\x7a\xf9\x80\xa9\x79'])
1105
1105
1106 self.assertEqual(len(callbackargs), 1)
1106 self.assertEqual(len(callbackargs), 1)
1107 self.assertEqual(callbackargs[0][0][1], nodes[0])
1107 self.assertEqual(callbackargs[0][0][1], nodes[0])
1108
1108
1109 self.assertEqual(list(f.revs()), [0])
1109 self.assertEqual(list(f.revs()), [0])
1110 self.assertEqual(f.rev(nodes[0]), 0)
1110 self.assertEqual(f.rev(nodes[0]), 0)
1111 self.assertEqual(f.node(0), nodes[0])
1111 self.assertEqual(f.node(0), nodes[0])
1112
1112
1113 def testaddgroupmultiple(self):
1113 def testaddgroupmultiple(self):
1114 f = self._makefilefn()
1114 f = self._makefilefn()
1115
1115
1116 fulltexts = [
1116 fulltexts = [
1117 b'foo',
1117 b'foo',
1118 b'bar',
1118 b'bar',
1119 b'x' * 1024,
1119 b'x' * 1024,
1120 ]
1120 ]
1121
1121
1122 nodes = []
1122 nodes = []
1123 with self._maketransactionfn() as tr:
1123 with self._maketransactionfn() as tr:
1124 for fulltext in fulltexts:
1124 for fulltext in fulltexts:
1125 nodes.append(f.add(fulltext, None, tr, 0, nullid, nullid))
1125 nodes.append(f.add(fulltext, None, tr, 0, nullid, nullid))
1126
1126
1127 f = self._makefilefn()
1127 f = self._makefilefn()
1128 deltas = []
1128 deltas = []
1129 for i, fulltext in enumerate(fulltexts):
1129 for i, fulltext in enumerate(fulltexts):
1130 delta = mdiff.trivialdiffheader(len(fulltext)) + fulltext
1130 delta = mdiff.trivialdiffheader(len(fulltext)) + fulltext
1131
1131
1132 deltas.append((nodes[i], nullid, nullid, nullid, nullid, delta, 0))
1132 deltas.append((nodes[i], nullid, nullid, nullid, nullid, delta, 0))
1133
1133
1134 with self._maketransactionfn() as tr:
1134 with self._maketransactionfn() as tr:
1135 self.assertEqual(f.addgroup(deltas, lambda x: 0, tr), nodes)
1135 self.assertEqual(f.addgroup(deltas, lambda x: 0, tr), nodes)
1136
1136
1137 self.assertEqual(len(f), len(deltas))
1137 self.assertEqual(len(f), len(deltas))
1138 self.assertEqual(list(f.revs()), [0, 1, 2])
1138 self.assertEqual(list(f.revs()), [0, 1, 2])
1139 self.assertEqual(f.rev(nodes[0]), 0)
1139 self.assertEqual(f.rev(nodes[0]), 0)
1140 self.assertEqual(f.rev(nodes[1]), 1)
1140 self.assertEqual(f.rev(nodes[1]), 1)
1141 self.assertEqual(f.rev(nodes[2]), 2)
1141 self.assertEqual(f.rev(nodes[2]), 2)
1142 self.assertEqual(f.node(0), nodes[0])
1142 self.assertEqual(f.node(0), nodes[0])
1143 self.assertEqual(f.node(1), nodes[1])
1143 self.assertEqual(f.node(1), nodes[1])
1144 self.assertEqual(f.node(2), nodes[2])
1144 self.assertEqual(f.node(2), nodes[2])
1145
1145
1146 def testdeltaagainstcensored(self):
1146 def testdeltaagainstcensored(self):
1147 # Attempt to apply a delta made against a censored revision.
1147 # Attempt to apply a delta made against a censored revision.
1148 f = self._makefilefn()
1148 f = self._makefilefn()
1149
1149
1150 stored1 = storageutil.packmeta({
1150 stored1 = storageutil.packmeta({
1151 b'censored': b'tombstone',
1151 b'censored': b'tombstone',
1152 }, b'')
1152 }, b'')
1153
1153
1154 with self._maketransactionfn() as tr:
1154 with self._maketransactionfn() as tr:
1155 node0 = f.add(b'foo\n' * 30, None, tr, 0, nullid, nullid)
1155 node0 = f.add(b'foo\n' * 30, None, tr, 0, nullid, nullid)
1156
1156
1157 # The node value doesn't matter since we can't verify it.
1157 # The node value doesn't matter since we can't verify it.
1158 node1 = b'\xbb' * 20
1158 node1 = b'\xbb' * 20
1159
1159
1160 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1,
1160 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1,
1161 censored=True)
1161 censored=True)
1162
1162
1163 delta = mdiff.textdiff(b'bar\n' * 30, (b'bar\n' * 30) + b'baz\n')
1163 delta = mdiff.textdiff(b'bar\n' * 30, (b'bar\n' * 30) + b'baz\n')
1164 deltas = [(b'\xcc' * 20, node1, nullid, b'\x01' * 20, node1, delta, 0)]
1164 deltas = [(b'\xcc' * 20, node1, nullid, b'\x01' * 20, node1, delta, 0)]
1165
1165
1166 with self._maketransactionfn() as tr:
1166 with self._maketransactionfn() as tr:
1167 with self.assertRaises(error.CensoredBaseError):
1167 with self.assertRaises(error.CensoredBaseError):
1168 f.addgroup(deltas, lambda x: 0, tr)
1168 f.addgroup(deltas, lambda x: 0, tr)
1169
1169
1170 def testcensorrevisionbasic(self):
1170 def testcensorrevisionbasic(self):
1171 f = self._makefilefn()
1171 f = self._makefilefn()
1172
1172
1173 with self._maketransactionfn() as tr:
1173 with self._maketransactionfn() as tr:
1174 node0 = f.add(b'foo\n' * 30, None, tr, 0, nullid, nullid)
1174 node0 = f.add(b'foo\n' * 30, None, tr, 0, nullid, nullid)
1175 node1 = f.add(b'foo\n' * 31, None, tr, 1, node0, nullid)
1175 node1 = f.add(b'foo\n' * 31, None, tr, 1, node0, nullid)
1176 node2 = f.add(b'foo\n' * 32, None, tr, 2, node1, nullid)
1176 node2 = f.add(b'foo\n' * 32, None, tr, 2, node1, nullid)
1177
1177
1178 with self._maketransactionfn() as tr:
1178 with self._maketransactionfn() as tr:
1179 f.censorrevision(tr, node1)
1179 f.censorrevision(tr, node1)
1180
1180
1181 self.assertEqual(len(f), 3)
1181 self.assertEqual(len(f), 3)
1182 self.assertEqual(list(f.revs()), [0, 1, 2])
1182 self.assertEqual(list(f.revs()), [0, 1, 2])
1183
1183
1184 self.assertEqual(f.read(node0), b'foo\n' * 30)
1184 self.assertEqual(f.read(node0), b'foo\n' * 30)
1185 self.assertEqual(f.read(node2), b'foo\n' * 32)
1185 self.assertEqual(f.read(node2), b'foo\n' * 32)
1186
1186
1187 with self.assertRaises(error.CensoredNodeError):
1187 with self.assertRaises(error.CensoredNodeError):
1188 f.read(node1)
1188 f.read(node1)
1189
1189
1190 def testgetstrippointnoparents(self):
1190 def testgetstrippointnoparents(self):
1191 # N revisions where none have parents.
1191 # N revisions where none have parents.
1192 f = self._makefilefn()
1192 f = self._makefilefn()
1193
1193
1194 with self._maketransactionfn() as tr:
1194 with self._maketransactionfn() as tr:
1195 for rev in range(10):
1195 for rev in range(10):
1196 f.add(b'%d' % rev, None, tr, rev, nullid, nullid)
1196 f.add(b'%d' % rev, None, tr, rev, nullid, nullid)
1197
1197
1198 for rev in range(10):
1198 for rev in range(10):
1199 self.assertEqual(f.getstrippoint(rev), (rev, set()))
1199 self.assertEqual(f.getstrippoint(rev), (rev, set()))
1200
1200
1201 def testgetstrippointlinear(self):
1201 def testgetstrippointlinear(self):
1202 # N revisions in a linear chain.
1202 # N revisions in a linear chain.
1203 f = self._makefilefn()
1203 f = self._makefilefn()
1204
1204
1205 with self._maketransactionfn() as tr:
1205 with self._maketransactionfn() as tr:
1206 p1 = nullid
1206 p1 = nullid
1207
1207
1208 for rev in range(10):
1208 for rev in range(10):
1209 f.add(b'%d' % rev, None, tr, rev, p1, nullid)
1209 f.add(b'%d' % rev, None, tr, rev, p1, nullid)
1210
1210
1211 for rev in range(10):
1211 for rev in range(10):
1212 self.assertEqual(f.getstrippoint(rev), (rev, set()))
1212 self.assertEqual(f.getstrippoint(rev), (rev, set()))
1213
1213
1214 def testgetstrippointmultipleheads(self):
1214 def testgetstrippointmultipleheads(self):
1215 f = self._makefilefn()
1215 f = self._makefilefn()
1216
1216
1217 with self._maketransactionfn() as tr:
1217 with self._maketransactionfn() as tr:
1218 node0 = f.add(b'0', None, tr, 0, nullid, nullid)
1218 node0 = f.add(b'0', None, tr, 0, nullid, nullid)
1219 node1 = f.add(b'1', None, tr, 1, node0, nullid)
1219 node1 = f.add(b'1', None, tr, 1, node0, nullid)
1220 f.add(b'2', None, tr, 2, node1, nullid)
1220 f.add(b'2', None, tr, 2, node1, nullid)
1221 f.add(b'3', None, tr, 3, node0, nullid)
1221 f.add(b'3', None, tr, 3, node0, nullid)
1222 f.add(b'4', None, tr, 4, node0, nullid)
1222 f.add(b'4', None, tr, 4, node0, nullid)
1223
1223
1224 for rev in range(5):
1224 for rev in range(5):
1225 self.assertEqual(f.getstrippoint(rev), (rev, set()))
1225 self.assertEqual(f.getstrippoint(rev), (rev, set()))
1226
1226
1227 def testgetstrippointearlierlinkrevs(self):
1227 def testgetstrippointearlierlinkrevs(self):
1228 f = self._makefilefn()
1228 f = self._makefilefn()
1229
1229
1230 with self._maketransactionfn() as tr:
1230 with self._maketransactionfn() as tr:
1231 node0 = f.add(b'0', None, tr, 0, nullid, nullid)
1231 node0 = f.add(b'0', None, tr, 0, nullid, nullid)
1232 f.add(b'1', None, tr, 10, node0, nullid)
1232 f.add(b'1', None, tr, 10, node0, nullid)
1233 f.add(b'2', None, tr, 5, node0, nullid)
1233 f.add(b'2', None, tr, 5, node0, nullid)
1234
1234
1235 self.assertEqual(f.getstrippoint(0), (0, set()))
1235 self.assertEqual(f.getstrippoint(0), (0, set()))
1236 self.assertEqual(f.getstrippoint(1), (1, set()))
1236 self.assertEqual(f.getstrippoint(1), (1, set()))
1237 self.assertEqual(f.getstrippoint(2), (1, set()))
1237 self.assertEqual(f.getstrippoint(2), (1, set()))
1238 self.assertEqual(f.getstrippoint(3), (1, set()))
1238 self.assertEqual(f.getstrippoint(3), (1, set()))
1239 self.assertEqual(f.getstrippoint(4), (1, set()))
1239 self.assertEqual(f.getstrippoint(4), (1, set()))
1240 self.assertEqual(f.getstrippoint(5), (1, set()))
1240 self.assertEqual(f.getstrippoint(5), (1, set()))
1241 self.assertEqual(f.getstrippoint(6), (1, {2}))
1241 self.assertEqual(f.getstrippoint(6), (1, {2}))
1242 self.assertEqual(f.getstrippoint(7), (1, {2}))
1242 self.assertEqual(f.getstrippoint(7), (1, {2}))
1243 self.assertEqual(f.getstrippoint(8), (1, {2}))
1243 self.assertEqual(f.getstrippoint(8), (1, {2}))
1244 self.assertEqual(f.getstrippoint(9), (1, {2}))
1244 self.assertEqual(f.getstrippoint(9), (1, {2}))
1245 self.assertEqual(f.getstrippoint(10), (1, {2}))
1245 self.assertEqual(f.getstrippoint(10), (1, {2}))
1246 self.assertEqual(f.getstrippoint(11), (3, set()))
1246 self.assertEqual(f.getstrippoint(11), (3, set()))
1247
1247
1248 def teststripempty(self):
1248 def teststripempty(self):
1249 f = self._makefilefn()
1249 f = self._makefilefn()
1250
1250
1251 with self._maketransactionfn() as tr:
1251 with self._maketransactionfn() as tr:
1252 f.strip(0, tr)
1252 f.strip(0, tr)
1253
1253
1254 self.assertEqual(len(f), 0)
1254 self.assertEqual(len(f), 0)
1255
1255
1256 def teststripall(self):
1256 def teststripall(self):
1257 f = self._makefilefn()
1257 f = self._makefilefn()
1258
1258
1259 with self._maketransactionfn() as tr:
1259 with self._maketransactionfn() as tr:
1260 p1 = nullid
1260 p1 = nullid
1261 for rev in range(10):
1261 for rev in range(10):
1262 p1 = f.add(b'%d' % rev, None, tr, rev, p1, nullid)
1262 p1 = f.add(b'%d' % rev, None, tr, rev, p1, nullid)
1263
1263
1264 self.assertEqual(len(f), 10)
1264 self.assertEqual(len(f), 10)
1265
1265
1266 with self._maketransactionfn() as tr:
1266 with self._maketransactionfn() as tr:
1267 f.strip(0, tr)
1267 f.strip(0, tr)
1268
1268
1269 self.assertEqual(len(f), 0)
1269 self.assertEqual(len(f), 0)
1270
1270
1271 def teststrippartial(self):
1271 def teststrippartial(self):
1272 f = self._makefilefn()
1272 f = self._makefilefn()
1273
1273
1274 with self._maketransactionfn() as tr:
1274 with self._maketransactionfn() as tr:
1275 f.add(b'0', None, tr, 0, nullid, nullid)
1275 f.add(b'0', None, tr, 0, nullid, nullid)
1276 node1 = f.add(b'1', None, tr, 5, nullid, nullid)
1276 node1 = f.add(b'1', None, tr, 5, nullid, nullid)
1277 node2 = f.add(b'2', None, tr, 10, nullid, nullid)
1277 node2 = f.add(b'2', None, tr, 10, nullid, nullid)
1278
1278
1279 self.assertEqual(len(f), 3)
1279 self.assertEqual(len(f), 3)
1280
1280
1281 with self._maketransactionfn() as tr:
1281 with self._maketransactionfn() as tr:
1282 f.strip(11, tr)
1282 f.strip(11, tr)
1283
1283
1284 self.assertEqual(len(f), 3)
1284 self.assertEqual(len(f), 3)
1285
1285
1286 with self._maketransactionfn() as tr:
1286 with self._maketransactionfn() as tr:
1287 f.strip(10, tr)
1287 f.strip(10, tr)
1288
1288
1289 self.assertEqual(len(f), 2)
1289 self.assertEqual(len(f), 2)
1290
1290
1291 with self.assertRaises(error.LookupError):
1291 with self.assertRaises(error.LookupError):
1292 f.rev(node2)
1292 f.rev(node2)
1293
1293
1294 with self._maketransactionfn() as tr:
1294 with self._maketransactionfn() as tr:
1295 f.strip(6, tr)
1295 f.strip(6, tr)
1296
1296
1297 self.assertEqual(len(f), 2)
1297 self.assertEqual(len(f), 2)
1298
1298
1299 with self._maketransactionfn() as tr:
1299 with self._maketransactionfn() as tr:
1300 f.strip(3, tr)
1300 f.strip(3, tr)
1301
1301
1302 self.assertEqual(len(f), 1)
1302 self.assertEqual(len(f), 1)
1303
1303
1304 with self.assertRaises(error.LookupError):
1304 with self.assertRaises(error.LookupError):
1305 f.rev(node1)
1305 f.rev(node1)
1306
1306
1307 def makeifileindextests(makefilefn, maketransactionfn, addrawrevisionfn):
1307 def makeifileindextests(makefilefn, maketransactionfn, addrawrevisionfn):
1308 """Create a unittest.TestCase class suitable for testing file storage.
1308 """Create a unittest.TestCase class suitable for testing file storage.
1309
1309
1310 ``makefilefn`` is a callable which receives the test case as an
1310 ``makefilefn`` is a callable which receives the test case as an
1311 argument and returns an object implementing the ``ifilestorage`` interface.
1311 argument and returns an object implementing the ``ifilestorage`` interface.
1312
1312
1313 ``maketransactionfn`` is a callable which receives the test case as an
1313 ``maketransactionfn`` is a callable which receives the test case as an
1314 argument and returns a transaction object.
1314 argument and returns a transaction object.
1315
1315
1316 ``addrawrevisionfn`` is a callable which receives arguments describing a
1316 ``addrawrevisionfn`` is a callable which receives arguments describing a
1317 low-level revision to add. This callable allows the insertion of
1317 low-level revision to add. This callable allows the insertion of
1318 potentially bad data into the store in order to facilitate testing.
1318 potentially bad data into the store in order to facilitate testing.
1319
1319
1320 Returns a type that is a ``unittest.TestCase`` that can be used for
1320 Returns a type that is a ``unittest.TestCase`` that can be used for
1321 testing the object implementing the file storage interface. Simply
1321 testing the object implementing the file storage interface. Simply
1322 assign the returned value to a module-level attribute and a test loader
1322 assign the returned value to a module-level attribute and a test loader
1323 should find and run it automatically.
1323 should find and run it automatically.
1324 """
1324 """
1325 d = {
1325 d = {
1326 r'_makefilefn': makefilefn,
1326 r'_makefilefn': makefilefn,
1327 r'_maketransactionfn': maketransactionfn,
1327 r'_maketransactionfn': maketransactionfn,
1328 r'_addrawrevisionfn': addrawrevisionfn,
1328 r'_addrawrevisionfn': addrawrevisionfn,
1329 }
1329 }
1330 return type(r'ifileindextests', (ifileindextests,), d)
1330 return type(r'ifileindextests', (ifileindextests,), d)
1331
1331
1332 def makeifiledatatests(makefilefn, maketransactionfn, addrawrevisionfn):
1332 def makeifiledatatests(makefilefn, maketransactionfn, addrawrevisionfn):
1333 d = {
1333 d = {
1334 r'_makefilefn': makefilefn,
1334 r'_makefilefn': makefilefn,
1335 r'_maketransactionfn': maketransactionfn,
1335 r'_maketransactionfn': maketransactionfn,
1336 r'_addrawrevisionfn': addrawrevisionfn,
1336 r'_addrawrevisionfn': addrawrevisionfn,
1337 }
1337 }
1338 return type(r'ifiledatatests', (ifiledatatests,), d)
1338 return type(r'ifiledatatests', (ifiledatatests,), d)
1339
1339
1340 def makeifilemutationtests(makefilefn, maketransactionfn, addrawrevisionfn):
1340 def makeifilemutationtests(makefilefn, maketransactionfn, addrawrevisionfn):
1341 d = {
1341 d = {
1342 r'_makefilefn': makefilefn,
1342 r'_makefilefn': makefilefn,
1343 r'_maketransactionfn': maketransactionfn,
1343 r'_maketransactionfn': maketransactionfn,
1344 r'_addrawrevisionfn': addrawrevisionfn,
1344 r'_addrawrevisionfn': addrawrevisionfn,
1345 }
1345 }
1346 return type(r'ifilemutationtests', (ifilemutationtests,), d)
1346 return type(r'ifilemutationtests', (ifilemutationtests,), d)
General Comments 0
You need to be logged in to leave comments. Login now