Mercurial > hg
comparison tests/test-manifest.py @ 47043:12450fbea288
manifests: push down expected node length into the parser
This strictly enforces the node length in the manifest lines according
to what the repository expects. One test case moves large hash testing
into the non-treemanifest part as treemanifests don't provide an
interface for overriding just the node length for now.
Differential Revision: https://phab.mercurial-scm.org/D10533
author | Joerg Sonnenberger <joerg@bec.de> |
---|---|
date | Fri, 30 Apr 2021 02:11:58 +0200 |
parents | 6266d19556ad |
children | 6000f5b25c9b |
comparison
equal
deleted
inserted
replaced
47042:c5e1cc0b4c77 | 47043:12450fbea288 |
---|---|
79 class basemanifesttests(object): | 79 class basemanifesttests(object): |
80 def parsemanifest(self, text): | 80 def parsemanifest(self, text): |
81 raise NotImplementedError('parsemanifest not implemented by test case') | 81 raise NotImplementedError('parsemanifest not implemented by test case') |
82 | 82 |
83 def testEmptyManifest(self): | 83 def testEmptyManifest(self): |
84 m = self.parsemanifest(EMTPY_MANIFEST) | 84 m = self.parsemanifest(20, EMTPY_MANIFEST) |
85 self.assertEqual(0, len(m)) | 85 self.assertEqual(0, len(m)) |
86 self.assertEqual([], list(m)) | 86 self.assertEqual([], list(m)) |
87 | 87 |
88 def testManifest(self): | 88 def testManifest(self): |
89 m = self.parsemanifest(A_SHORT_MANIFEST) | 89 m = self.parsemanifest(20, A_SHORT_MANIFEST) |
90 self.assertEqual([b'bar/baz/qux.py', b'foo'], list(m)) | 90 self.assertEqual([b'bar/baz/qux.py', b'foo'], list(m)) |
91 self.assertEqual(BIN_HASH_2, m[b'bar/baz/qux.py']) | 91 self.assertEqual(BIN_HASH_2, m[b'bar/baz/qux.py']) |
92 self.assertEqual(b'l', m.flags(b'bar/baz/qux.py')) | 92 self.assertEqual(b'l', m.flags(b'bar/baz/qux.py')) |
93 self.assertEqual(BIN_HASH_1, m[b'foo']) | 93 self.assertEqual(BIN_HASH_1, m[b'foo']) |
94 self.assertEqual(b'', m.flags(b'foo')) | 94 self.assertEqual(b'', m.flags(b'foo')) |
95 with self.assertRaises(KeyError): | 95 with self.assertRaises(KeyError): |
96 m[b'wat'] | 96 m[b'wat'] |
97 | 97 |
98 def testManifestLongHashes(self): | |
99 m = self.parsemanifest(b'a\0' + b'f' * 64 + b'\n') | |
100 self.assertEqual(binascii.unhexlify(b'f' * 64), m[b'a']) | |
101 | |
102 def testSetItem(self): | 98 def testSetItem(self): |
103 want = BIN_HASH_1 | 99 want = BIN_HASH_1 |
104 | 100 |
105 m = self.parsemanifest(EMTPY_MANIFEST) | 101 m = self.parsemanifest(20, EMTPY_MANIFEST) |
106 m[b'a'] = want | 102 m[b'a'] = want |
107 self.assertIn(b'a', m) | 103 self.assertIn(b'a', m) |
108 self.assertEqual(want, m[b'a']) | 104 self.assertEqual(want, m[b'a']) |
109 self.assertEqual(b'a\0' + HASH_1 + b'\n', m.text()) | 105 self.assertEqual(b'a\0' + HASH_1 + b'\n', m.text()) |
110 | 106 |
111 m = self.parsemanifest(A_SHORT_MANIFEST) | 107 m = self.parsemanifest(20, A_SHORT_MANIFEST) |
112 m[b'a'] = want | 108 m[b'a'] = want |
113 self.assertEqual(want, m[b'a']) | 109 self.assertEqual(want, m[b'a']) |
114 self.assertEqual(b'a\0' + HASH_1 + b'\n' + A_SHORT_MANIFEST, m.text()) | 110 self.assertEqual(b'a\0' + HASH_1 + b'\n' + A_SHORT_MANIFEST, m.text()) |
115 | 111 |
116 def testSetFlag(self): | 112 def testSetFlag(self): |
117 want = b'x' | 113 want = b'x' |
118 | 114 |
119 m = self.parsemanifest(EMTPY_MANIFEST) | 115 m = self.parsemanifest(20, EMTPY_MANIFEST) |
120 # first add a file; a file-less flag makes no sense | 116 # first add a file; a file-less flag makes no sense |
121 m[b'a'] = BIN_HASH_1 | 117 m[b'a'] = BIN_HASH_1 |
122 m.setflag(b'a', want) | 118 m.setflag(b'a', want) |
123 self.assertEqual(want, m.flags(b'a')) | 119 self.assertEqual(want, m.flags(b'a')) |
124 self.assertEqual(b'a\0' + HASH_1 + want + b'\n', m.text()) | 120 self.assertEqual(b'a\0' + HASH_1 + want + b'\n', m.text()) |
125 | 121 |
126 m = self.parsemanifest(A_SHORT_MANIFEST) | 122 m = self.parsemanifest(20, A_SHORT_MANIFEST) |
127 # first add a file; a file-less flag makes no sense | 123 # first add a file; a file-less flag makes no sense |
128 m[b'a'] = BIN_HASH_1 | 124 m[b'a'] = BIN_HASH_1 |
129 m.setflag(b'a', want) | 125 m.setflag(b'a', want) |
130 self.assertEqual(want, m.flags(b'a')) | 126 self.assertEqual(want, m.flags(b'a')) |
131 self.assertEqual( | 127 self.assertEqual( |
132 b'a\0' + HASH_1 + want + b'\n' + A_SHORT_MANIFEST, m.text() | 128 b'a\0' + HASH_1 + want + b'\n' + A_SHORT_MANIFEST, m.text() |
133 ) | 129 ) |
134 | 130 |
135 def testCopy(self): | 131 def testCopy(self): |
136 m = self.parsemanifest(A_SHORT_MANIFEST) | 132 m = self.parsemanifest(20, A_SHORT_MANIFEST) |
137 m[b'a'] = BIN_HASH_1 | 133 m[b'a'] = BIN_HASH_1 |
138 m2 = m.copy() | 134 m2 = m.copy() |
139 del m | 135 del m |
140 del m2 # make sure we don't double free() anything | 136 del m2 # make sure we don't double free() anything |
141 | 137 |
142 def testCompaction(self): | 138 def testCompaction(self): |
143 unhex = binascii.unhexlify | 139 unhex = binascii.unhexlify |
144 h1, h2 = unhex(HASH_1), unhex(HASH_2) | 140 h1, h2 = unhex(HASH_1), unhex(HASH_2) |
145 m = self.parsemanifest(A_SHORT_MANIFEST) | 141 m = self.parsemanifest(20, A_SHORT_MANIFEST) |
146 m[b'alpha'] = h1 | 142 m[b'alpha'] = h1 |
147 m[b'beta'] = h2 | 143 m[b'beta'] = h2 |
148 del m[b'foo'] | 144 del m[b'foo'] |
149 want = b'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % ( | 145 want = b'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % ( |
150 HASH_1, | 146 HASH_1, |
162 self.assertEqual(b'', m.flags(b'beta')) | 158 self.assertEqual(b'', m.flags(b'beta')) |
163 with self.assertRaises(KeyError): | 159 with self.assertRaises(KeyError): |
164 m[b'foo'] | 160 m[b'foo'] |
165 | 161 |
166 def testMatchException(self): | 162 def testMatchException(self): |
167 m = self.parsemanifest(A_SHORT_MANIFEST) | 163 m = self.parsemanifest(20, A_SHORT_MANIFEST) |
168 match = matchmod.match(util.localpath(b'/repo'), b'', [b're:.*']) | 164 match = matchmod.match(util.localpath(b'/repo'), b'', [b're:.*']) |
169 | 165 |
170 def filt(path): | 166 def filt(path): |
171 if path == b'foo': | 167 if path == b'foo': |
172 assert False | 168 assert False |
175 match.matchfn = filt | 171 match.matchfn = filt |
176 with self.assertRaises(AssertionError): | 172 with self.assertRaises(AssertionError): |
177 m._matches(match) | 173 m._matches(match) |
178 | 174 |
179 def testRemoveItem(self): | 175 def testRemoveItem(self): |
180 m = self.parsemanifest(A_SHORT_MANIFEST) | 176 m = self.parsemanifest(20, A_SHORT_MANIFEST) |
181 del m[b'foo'] | 177 del m[b'foo'] |
182 with self.assertRaises(KeyError): | 178 with self.assertRaises(KeyError): |
183 m[b'foo'] | 179 m[b'foo'] |
184 self.assertEqual(1, len(m)) | 180 self.assertEqual(1, len(m)) |
185 self.assertEqual(1, len(list(m))) | 181 self.assertEqual(1, len(list(m))) |
191 def testManifestDiff(self): | 187 def testManifestDiff(self): |
192 MISSING = (None, b'') | 188 MISSING = (None, b'') |
193 addl = b'z-only-in-left\0' + HASH_1 + b'\n' | 189 addl = b'z-only-in-left\0' + HASH_1 + b'\n' |
194 addr = b'z-only-in-right\0' + HASH_2 + b'x\n' | 190 addr = b'z-only-in-right\0' + HASH_2 + b'x\n' |
195 left = self.parsemanifest( | 191 left = self.parsemanifest( |
196 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + b'x') + addl | 192 20, A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + b'x') + addl |
197 ) | 193 ) |
198 right = self.parsemanifest(A_SHORT_MANIFEST + addr) | 194 right = self.parsemanifest(20, A_SHORT_MANIFEST + addr) |
199 want = { | 195 want = { |
200 b'foo': ((BIN_HASH_3, b'x'), (BIN_HASH_1, b'')), | 196 b'foo': ((BIN_HASH_3, b'x'), (BIN_HASH_1, b'')), |
201 b'z-only-in-left': ((BIN_HASH_1, b''), MISSING), | 197 b'z-only-in-left': ((BIN_HASH_1, b''), MISSING), |
202 b'z-only-in-right': (MISSING, (BIN_HASH_2, b'x')), | 198 b'z-only-in-right': (MISSING, (BIN_HASH_2, b'x')), |
203 } | 199 } |
206 want = { | 202 want = { |
207 b'bar/baz/qux.py': (MISSING, (BIN_HASH_2, b'l')), | 203 b'bar/baz/qux.py': (MISSING, (BIN_HASH_2, b'l')), |
208 b'foo': (MISSING, (BIN_HASH_3, b'x')), | 204 b'foo': (MISSING, (BIN_HASH_3, b'x')), |
209 b'z-only-in-left': (MISSING, (BIN_HASH_1, b'')), | 205 b'z-only-in-left': (MISSING, (BIN_HASH_1, b'')), |
210 } | 206 } |
211 self.assertEqual(want, self.parsemanifest(EMTPY_MANIFEST).diff(left)) | 207 self.assertEqual( |
208 want, self.parsemanifest(20, EMTPY_MANIFEST).diff(left) | |
209 ) | |
212 | 210 |
213 want = { | 211 want = { |
214 b'bar/baz/qux.py': ((BIN_HASH_2, b'l'), MISSING), | 212 b'bar/baz/qux.py': ((BIN_HASH_2, b'l'), MISSING), |
215 b'foo': ((BIN_HASH_3, b'x'), MISSING), | 213 b'foo': ((BIN_HASH_3, b'x'), MISSING), |
216 b'z-only-in-left': ((BIN_HASH_1, b''), MISSING), | 214 b'z-only-in-left': ((BIN_HASH_1, b''), MISSING), |
217 } | 215 } |
218 self.assertEqual(want, left.diff(self.parsemanifest(EMTPY_MANIFEST))) | 216 self.assertEqual( |
217 want, left.diff(self.parsemanifest(20, EMTPY_MANIFEST)) | |
218 ) | |
219 copy = right.copy() | 219 copy = right.copy() |
220 del copy[b'z-only-in-right'] | 220 del copy[b'z-only-in-right'] |
221 del right[b'foo'] | 221 del right[b'foo'] |
222 want = { | 222 want = { |
223 b'foo': (MISSING, (BIN_HASH_1, b'')), | 223 b'foo': (MISSING, (BIN_HASH_1, b'')), |
224 b'z-only-in-right': ((BIN_HASH_2, b'x'), MISSING), | 224 b'z-only-in-right': ((BIN_HASH_2, b'x'), MISSING), |
225 } | 225 } |
226 self.assertEqual(want, right.diff(copy)) | 226 self.assertEqual(want, right.diff(copy)) |
227 | 227 |
228 short = self.parsemanifest(A_SHORT_MANIFEST) | 228 short = self.parsemanifest(20, A_SHORT_MANIFEST) |
229 pruned = short.copy() | 229 pruned = short.copy() |
230 del pruned[b'foo'] | 230 del pruned[b'foo'] |
231 want = { | 231 want = { |
232 b'foo': ((BIN_HASH_1, b''), MISSING), | 232 b'foo': ((BIN_HASH_1, b''), MISSING), |
233 } | 233 } |
245 def testReversedLines(self): | 245 def testReversedLines(self): |
246 backwards = b''.join( | 246 backwards = b''.join( |
247 l + b'\n' for l in reversed(A_SHORT_MANIFEST.split(b'\n')) if l | 247 l + b'\n' for l in reversed(A_SHORT_MANIFEST.split(b'\n')) if l |
248 ) | 248 ) |
249 try: | 249 try: |
250 self.parsemanifest(backwards) | 250 self.parsemanifest(20, backwards) |
251 self.fail('Should have raised ValueError') | 251 self.fail('Should have raised ValueError') |
252 except ValueError as v: | 252 except ValueError as v: |
253 self.assertIn('Manifest lines not in sorted order.', str(v)) | 253 self.assertIn('Manifest lines not in sorted order.', str(v)) |
254 | 254 |
255 def testNoTerminalNewline(self): | 255 def testNoTerminalNewline(self): |
256 try: | 256 try: |
257 self.parsemanifest(A_SHORT_MANIFEST + b'wat') | 257 self.parsemanifest(20, A_SHORT_MANIFEST + b'wat') |
258 self.fail('Should have raised ValueError') | 258 self.fail('Should have raised ValueError') |
259 except ValueError as v: | 259 except ValueError as v: |
260 self.assertIn('Manifest did not end in a newline.', str(v)) | 260 self.assertIn('Manifest did not end in a newline.', str(v)) |
261 | 261 |
262 def testNoNewLineAtAll(self): | 262 def testNoNewLineAtAll(self): |
263 try: | 263 try: |
264 self.parsemanifest(b'wat') | 264 self.parsemanifest(20, b'wat') |
265 self.fail('Should have raised ValueError') | 265 self.fail('Should have raised ValueError') |
266 except ValueError as v: | 266 except ValueError as v: |
267 self.assertIn('Manifest did not end in a newline.', str(v)) | 267 self.assertIn('Manifest did not end in a newline.', str(v)) |
268 | 268 |
269 def testHugeManifest(self): | 269 def testHugeManifest(self): |
270 m = self.parsemanifest(A_HUGE_MANIFEST) | 270 m = self.parsemanifest(20, A_HUGE_MANIFEST) |
271 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m)) | 271 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m)) |
272 self.assertEqual(len(m), len(list(m))) | 272 self.assertEqual(len(m), len(list(m))) |
273 | 273 |
274 def testMatchesMetadata(self): | 274 def testMatchesMetadata(self): |
275 """Tests matches() for a few specific files to make sure that both | 275 """Tests matches() for a few specific files to make sure that both |
276 the set of files as well as their flags and nodeids are correct in | 276 the set of files as well as their flags and nodeids are correct in |
277 the resulting manifest.""" | 277 the resulting manifest.""" |
278 m = self.parsemanifest(A_HUGE_MANIFEST) | 278 m = self.parsemanifest(20, A_HUGE_MANIFEST) |
279 | 279 |
280 match = matchmod.exact([b'file1', b'file200', b'file300']) | 280 match = matchmod.exact([b'file1', b'file200', b'file300']) |
281 m2 = m._matches(match) | 281 m2 = m._matches(match) |
282 | 282 |
283 w = (b'file1\0%sx\n' b'file200\0%sl\n' b'file300\0%s\n') % ( | 283 w = (b'file1\0%sx\n' b'file200\0%sl\n' b'file300\0%s\n') % ( |
289 | 289 |
290 def testMatchesNonexistentFile(self): | 290 def testMatchesNonexistentFile(self): |
291 """Tests matches() for a small set of specific files, including one | 291 """Tests matches() for a small set of specific files, including one |
292 nonexistent file to make sure in only matches against existing files. | 292 nonexistent file to make sure in only matches against existing files. |
293 """ | 293 """ |
294 m = self.parsemanifest(A_DEEPER_MANIFEST) | 294 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
295 | 295 |
296 match = matchmod.exact( | 296 match = matchmod.exact( |
297 [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt', b'nonexistent'] | 297 [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt', b'nonexistent'] |
298 ) | 298 ) |
299 m2 = m._matches(match) | 299 m2 = m._matches(match) |
303 ) | 303 ) |
304 | 304 |
305 def testMatchesNonexistentDirectory(self): | 305 def testMatchesNonexistentDirectory(self): |
306 """Tests matches() for a relpath match on a directory that doesn't | 306 """Tests matches() for a relpath match on a directory that doesn't |
307 actually exist.""" | 307 actually exist.""" |
308 m = self.parsemanifest(A_DEEPER_MANIFEST) | 308 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
309 | 309 |
310 match = matchmod.match( | 310 match = matchmod.match( |
311 util.localpath(b'/repo'), b'', [b'a/f'], default=b'relpath' | 311 util.localpath(b'/repo'), b'', [b'a/f'], default=b'relpath' |
312 ) | 312 ) |
313 m2 = m._matches(match) | 313 m2 = m._matches(match) |
314 | 314 |
315 self.assertEqual([], m2.keys()) | 315 self.assertEqual([], m2.keys()) |
316 | 316 |
317 def testMatchesExactLarge(self): | 317 def testMatchesExactLarge(self): |
318 """Tests matches() for files matching a large list of exact files.""" | 318 """Tests matches() for files matching a large list of exact files.""" |
319 m = self.parsemanifest(A_HUGE_MANIFEST) | 319 m = self.parsemanifest(20, A_HUGE_MANIFEST) |
320 | 320 |
321 flist = m.keys()[80:300] | 321 flist = m.keys()[80:300] |
322 match = matchmod.exact(flist) | 322 match = matchmod.exact(flist) |
323 m2 = m._matches(match) | 323 m2 = m._matches(match) |
324 | 324 |
325 self.assertEqual(flist, m2.keys()) | 325 self.assertEqual(flist, m2.keys()) |
326 | 326 |
327 def testMatchesFull(self): | 327 def testMatchesFull(self): |
328 '''Tests matches() for what should be a full match.''' | 328 '''Tests matches() for what should be a full match.''' |
329 m = self.parsemanifest(A_DEEPER_MANIFEST) | 329 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
330 | 330 |
331 match = matchmod.match(util.localpath(b'/repo'), b'', [b'']) | 331 match = matchmod.match(util.localpath(b'/repo'), b'', [b'']) |
332 m2 = m._matches(match) | 332 m2 = m._matches(match) |
333 | 333 |
334 self.assertEqual(m.keys(), m2.keys()) | 334 self.assertEqual(m.keys(), m2.keys()) |
335 | 335 |
336 def testMatchesDirectory(self): | 336 def testMatchesDirectory(self): |
337 """Tests matches() on a relpath match on a directory, which should | 337 """Tests matches() on a relpath match on a directory, which should |
338 match against all files within said directory.""" | 338 match against all files within said directory.""" |
339 m = self.parsemanifest(A_DEEPER_MANIFEST) | 339 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
340 | 340 |
341 match = matchmod.match( | 341 match = matchmod.match( |
342 util.localpath(b'/repo'), b'', [b'a/b'], default=b'relpath' | 342 util.localpath(b'/repo'), b'', [b'a/b'], default=b'relpath' |
343 ) | 343 ) |
344 m2 = m._matches(match) | 344 m2 = m._matches(match) |
360 | 360 |
361 def testMatchesExactPath(self): | 361 def testMatchesExactPath(self): |
362 """Tests matches() on an exact match on a directory, which should | 362 """Tests matches() on an exact match on a directory, which should |
363 result in an empty manifest because you can't perform an exact match | 363 result in an empty manifest because you can't perform an exact match |
364 against a directory.""" | 364 against a directory.""" |
365 m = self.parsemanifest(A_DEEPER_MANIFEST) | 365 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
366 | 366 |
367 match = matchmod.exact([b'a/b']) | 367 match = matchmod.exact([b'a/b']) |
368 m2 = m._matches(match) | 368 m2 = m._matches(match) |
369 | 369 |
370 self.assertEqual([], m2.keys()) | 370 self.assertEqual([], m2.keys()) |
371 | 371 |
372 def testMatchesCwd(self): | 372 def testMatchesCwd(self): |
373 """Tests matches() on a relpath match with the current directory ('.') | 373 """Tests matches() on a relpath match with the current directory ('.') |
374 when not in the root directory.""" | 374 when not in the root directory.""" |
375 m = self.parsemanifest(A_DEEPER_MANIFEST) | 375 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
376 | 376 |
377 match = matchmod.match( | 377 match = matchmod.match( |
378 util.localpath(b'/repo'), b'a/b', [b'.'], default=b'relpath' | 378 util.localpath(b'/repo'), b'a/b', [b'.'], default=b'relpath' |
379 ) | 379 ) |
380 m2 = m._matches(match) | 380 m2 = m._matches(match) |
395 ) | 395 ) |
396 | 396 |
397 def testMatchesWithPattern(self): | 397 def testMatchesWithPattern(self): |
398 """Tests matches() for files matching a pattern that reside | 398 """Tests matches() for files matching a pattern that reside |
399 deeper than the specified directory.""" | 399 deeper than the specified directory.""" |
400 m = self.parsemanifest(A_DEEPER_MANIFEST) | 400 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
401 | 401 |
402 match = matchmod.match(util.localpath(b'/repo'), b'', [b'a/b/*/*.txt']) | 402 match = matchmod.match(util.localpath(b'/repo'), b'', [b'a/b/*/*.txt']) |
403 m2 = m._matches(match) | 403 m2 = m._matches(match) |
404 | 404 |
405 self.assertEqual( | 405 self.assertEqual( |
406 [b'a/b/c/bar.txt', b'a/b/c/foo.txt', b'a/b/d/ten.txt'], m2.keys() | 406 [b'a/b/c/bar.txt', b'a/b/c/foo.txt', b'a/b/d/ten.txt'], m2.keys() |
407 ) | 407 ) |
408 | 408 |
409 | 409 |
410 class testmanifestdict(unittest.TestCase, basemanifesttests): | 410 class testmanifestdict(unittest.TestCase, basemanifesttests): |
411 def parsemanifest(self, text): | 411 def parsemanifest(self, nodelen, text): |
412 return manifestmod.manifestdict(text) | 412 return manifestmod.manifestdict(nodelen, text) |
413 | |
414 def testManifestLongHashes(self): | |
415 m = self.parsemanifest(32, b'a\0' + b'f' * 64 + b'\n') | |
416 self.assertEqual(binascii.unhexlify(b'f' * 64), m[b'a']) | |
413 | 417 |
414 def testObviouslyBogusManifest(self): | 418 def testObviouslyBogusManifest(self): |
415 # This is a 163k manifest that came from oss-fuzz. It was a | 419 # This is a 163k manifest that came from oss-fuzz. It was a |
416 # timeout there, but when run normally it doesn't seem to | 420 # timeout there, but when run normally it doesn't seem to |
417 # present any particular slowness. | 421 # present any particular slowness. |
431 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | 435 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |
432 b'\x00\x00\xc0\x8aey\x1d}\x01\xd8\xe0\xb9\xf3\xde\x1b\xcf\x17' | 436 b'\x00\x00\xc0\x8aey\x1d}\x01\xd8\xe0\xb9\xf3\xde\x1b\xcf\x17' |
433 b'\xac\xbe' | 437 b'\xac\xbe' |
434 ) | 438 ) |
435 with self.assertRaises(ValueError): | 439 with self.assertRaises(ValueError): |
436 self.parsemanifest(data) | 440 self.parsemanifest(20, data) |
437 | 441 |
438 | 442 |
439 class testtreemanifest(unittest.TestCase, basemanifesttests): | 443 class testtreemanifest(unittest.TestCase, basemanifesttests): |
440 def parsemanifest(self, text): | 444 def parsemanifest(self, nodelen, text): |
441 return manifestmod.treemanifest(sha1nodeconstants, b'', text) | 445 return manifestmod.treemanifest(sha1nodeconstants, b'', text) |
442 | 446 |
443 def testWalkSubtrees(self): | 447 def testWalkSubtrees(self): |
444 m = self.parsemanifest(A_DEEPER_MANIFEST) | 448 m = self.parsemanifest(20, A_DEEPER_MANIFEST) |
445 | 449 |
446 dirs = [s._dir for s in m.walksubtrees()] | 450 dirs = [s._dir for s in m.walksubtrees()] |
447 self.assertEqual( | 451 self.assertEqual( |
448 sorted( | 452 sorted( |
449 [b'', b'a/', b'a/c/', b'a/d/', b'a/b/', b'a/b/c/', b'a/b/d/'] | 453 [b'', b'a/', b'a/c/', b'a/d/', b'a/b/', b'a/b/c/', b'a/b/d/'] |