test-manifest.py
232 lines
| 8.6 KiB
| text/x-python
|
PythonLexer
/ tests / test-manifest.py
Augie Fackler
|
r24214 | import binascii | ||
import unittest | ||||
import itertools | ||||
import silenttestrunner | ||||
Augie Fackler
|
r24225 | from mercurial import manifest as manifestmod | ||
Augie Fackler
|
r24214 | |||
HASH_1 = '1' * 40 | ||||
HASH_2 = 'f' * 40 | ||||
HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe' | ||||
A_SHORT_MANIFEST = ( | ||||
'bar/baz/qux.py\0%(hash2)s%(flag2)s\n' | ||||
'foo\0%(hash1)s%(flag1)s\n' | ||||
) % {'hash1': HASH_1, | ||||
'flag1': '', | ||||
'hash2': HASH_2, | ||||
'flag2': 'l', | ||||
} | ||||
HUGE_MANIFEST_ENTRIES = 200001 | ||||
A_HUGE_MANIFEST = ''.join(sorted( | ||||
'file%d\0%s%s\n' % (i, h, f) for i, h, f in | ||||
itertools.izip(xrange(200001), | ||||
itertools.cycle((HASH_1, HASH_2)), | ||||
itertools.cycle(('', 'x', 'l'))))) | ||||
class testmanifest(unittest.TestCase): | ||||
def assertIn(self, thing, container, msg=None): | ||||
# assertIn new in 2.7, use it if available, otherwise polyfill | ||||
sup = getattr(unittest.TestCase, 'assertIn', False) | ||||
if sup: | ||||
return sup(self, thing, container, msg=msg) | ||||
if not msg: | ||||
msg = 'Expected %r in %r' % (thing, container) | ||||
self.assert_(thing in container, msg) | ||||
def testEmptyManifest(self): | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest('') | ||
Augie Fackler
|
r24214 | self.assertEqual(0, len(m)) | ||
Martin von Zweigbergk
|
r24298 | self.assertEqual([], list(m.iterentries())) | ||
Augie Fackler
|
r24214 | |||
def testManifest(self): | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||
Augie Fackler
|
r24214 | want = [ | ||
('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'), | ||||
('foo', binascii.unhexlify(HASH_1), ''), | ||||
] | ||||
self.assertEqual(len(want), len(m)) | ||||
Martin von Zweigbergk
|
r24298 | self.assertEqual(want, list(m.iterentries())) | ||
Augie Fackler
|
r24214 | self.assertEqual((binascii.unhexlify(HASH_1), ''), m['foo']) | ||
self.assertRaises(KeyError, lambda : m['wat']) | ||||
self.assertEqual((binascii.unhexlify(HASH_2), 'l'), | ||||
m['bar/baz/qux.py']) | ||||
def testSetItem(self): | ||||
want = binascii.unhexlify(HASH_1), '' | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest('') | ||
Augie Fackler
|
r24214 | m['a'] = want | ||
self.assertIn('a', m) | ||||
self.assertEqual(want, m['a']) | ||||
self.assertEqual('a\0' + HASH_1 + '\n', m.text()) | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||
Augie Fackler
|
r24214 | m['a'] = want | ||
self.assertEqual(want, m['a']) | ||||
self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST, | ||||
m.text()) | ||||
m2 = m.copy() | ||||
del m | ||||
del m2 # make sure we don't double free() anything | ||||
def testCompaction(self): | ||||
unhex = binascii.unhexlify | ||||
h1, h2 = unhex(HASH_1), unhex(HASH_2) | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||
Augie Fackler
|
r24214 | m['alpha'] = h1, '' | ||
m['beta'] = h2, '' | ||||
del m['foo'] | ||||
want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % ( | ||||
HASH_1, HASH_2, HASH_2) | ||||
self.assertEqual(want, m.text()) | ||||
self.assertEqual(3, len(m)) | ||||
self.assertEqual((h1, ''), m['alpha']) | ||||
self.assertEqual((h2, ''), m['beta']) | ||||
self.assertRaises(KeyError, lambda : m['foo']) | ||||
w = [('alpha', h1, ''), ('bar/baz/qux.py', h2, 'l'), ('beta', h2, '')] | ||||
Martin von Zweigbergk
|
r24298 | self.assertEqual(w, list(m.iterentries())) | ||
Augie Fackler
|
r24214 | |||
def testSetGetNodeSuffix(self): | ||||
Augie Fackler
|
r24225 | clean = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||
m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||||
Augie Fackler
|
r24214 | h, f = m['foo'] | ||
want = h + 'a', f | ||||
# Merge code wants to set 21-byte fake hashes at times | ||||
m['foo'] = want | ||||
self.assertEqual(want, m['foo']) | ||||
self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'), | ||||
('foo', binascii.unhexlify(HASH_1) + 'a', '')], | ||||
Martin von Zweigbergk
|
r24298 | list(m.iterentries())) | ||
Augie Fackler
|
r24214 | # Sometimes it even tries a 22-byte fake hash, but we can | ||
# return 21 and it'll work out | ||||
m['foo'] = want[0] + '+', f | ||||
self.assertEqual(want, m['foo']) | ||||
# make sure the suffix survives a copy | ||||
m2 = m.filtercopy(lambda x: x == 'foo') | ||||
self.assertEqual(want, m2['foo']) | ||||
self.assertEqual(1, len(m2)) | ||||
self.assertEqual(('foo\0%s\n' % HASH_1), m2.text()) | ||||
m2 = m.copy() | ||||
self.assertEqual(want, m2['foo']) | ||||
# suffix with iteration | ||||
self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'), | ||||
Martin von Zweigbergk
|
r24298 | ('foo', want[0], '')], list(m.iterentries())) | ||
Augie Fackler
|
r24214 | # shows up in diff | ||
self.assertEqual({'foo': (want, (h, ''))}, m.diff(clean)) | ||||
self.assertEqual({'foo': ((h, ''), want)}, clean.diff(m)) | ||||
def testFilterCopyException(self): | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||
Augie Fackler
|
r24214 | def filt(path): | ||
if path == 'foo': | ||||
assert False | ||||
return True | ||||
self.assertRaises(AssertionError, m.filtercopy, filt) | ||||
def testRemoveItem(self): | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||
Augie Fackler
|
r24214 | del m['foo'] | ||
self.assertRaises(KeyError, lambda : m['foo']) | ||||
self.assertEqual(1, len(m)) | ||||
self.assertEqual(1, len(list(m))) | ||||
Augie Fackler
|
r24228 | # now restore and make sure everything works right | ||
m['foo'] = 'a' * 20, '' | ||||
self.assertEqual(2, len(m)) | ||||
self.assertEqual(2, len(list(m))) | ||||
Augie Fackler
|
r24214 | |||
def testManifestDiff(self): | ||||
MISSING = (None, '') | ||||
addl = 'z-only-in-left\0' + HASH_1 + '\n' | ||||
addr = 'z-only-in-right\0' + HASH_2 + 'x\n' | ||||
Augie Fackler
|
r24225 | left = manifestmod._lazymanifest( | ||
Augie Fackler
|
r24214 | A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl) | ||
Augie Fackler
|
r24225 | right = manifestmod._lazymanifest(A_SHORT_MANIFEST + addr) | ||
Augie Fackler
|
r24214 | want = { | ||
'foo': ((binascii.unhexlify(HASH_3), 'x'), | ||||
(binascii.unhexlify(HASH_1), '')), | ||||
'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING), | ||||
'z-only-in-right': (MISSING, (binascii.unhexlify(HASH_2), 'x')), | ||||
} | ||||
self.assertEqual(want, left.diff(right)) | ||||
want = { | ||||
'bar/baz/qux.py': (MISSING, (binascii.unhexlify(HASH_2), 'l')), | ||||
'foo': (MISSING, (binascii.unhexlify(HASH_3), 'x')), | ||||
'z-only-in-left': (MISSING, (binascii.unhexlify(HASH_1), '')), | ||||
} | ||||
Augie Fackler
|
r24225 | self.assertEqual(want, manifestmod._lazymanifest('').diff(left)) | ||
Augie Fackler
|
r24214 | |||
want = { | ||||
'bar/baz/qux.py': ((binascii.unhexlify(HASH_2), 'l'), MISSING), | ||||
'foo': ((binascii.unhexlify(HASH_3), 'x'), MISSING), | ||||
'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING), | ||||
} | ||||
Augie Fackler
|
r24225 | self.assertEqual(want, left.diff(manifestmod._lazymanifest(''))) | ||
Augie Fackler
|
r24214 | copy = right.copy() | ||
del copy['z-only-in-right'] | ||||
del right['foo'] | ||||
want = { | ||||
'foo': (MISSING, (binascii.unhexlify(HASH_1), '')), | ||||
'z-only-in-right': ((binascii.unhexlify(HASH_2), 'x'), MISSING), | ||||
} | ||||
self.assertEqual(want, right.diff(copy)) | ||||
Augie Fackler
|
r24225 | short = manifestmod._lazymanifest(A_SHORT_MANIFEST) | ||
Augie Fackler
|
r24214 | pruned = short.copy() | ||
del pruned['foo'] | ||||
want = { | ||||
'foo': ((binascii.unhexlify(HASH_1), ''), MISSING), | ||||
} | ||||
self.assertEqual(want, short.diff(pruned)) | ||||
want = { | ||||
'foo': (MISSING, (binascii.unhexlify(HASH_1), '')), | ||||
} | ||||
self.assertEqual(want, pruned.diff(short)) | ||||
want = { | ||||
'bar/baz/qux.py': None, | ||||
'foo': (MISSING, (binascii.unhexlify(HASH_1), '')), | ||||
} | ||||
self.assertEqual(want, pruned.diff(short, True)) | ||||
def testReversedLines(self): | ||||
backwards = ''.join( | ||||
l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l) | ||||
try: | ||||
Augie Fackler
|
r24225 | manifestmod._lazymanifest(backwards) | ||
Augie Fackler
|
r24214 | self.fail('Should have raised ValueError') | ||
except ValueError, v: | ||||
self.assertIn('Manifest lines not in sorted order.', str(v)) | ||||
def testNoTerminalNewline(self): | ||||
try: | ||||
Augie Fackler
|
r24225 | manifestmod._lazymanifest(A_SHORT_MANIFEST + 'wat') | ||
Augie Fackler
|
r24214 | self.fail('Should have raised ValueError') | ||
except ValueError, v: | ||||
self.assertIn('Manifest did not end in a newline.', str(v)) | ||||
def testNoNewLineAtAll(self): | ||||
try: | ||||
Augie Fackler
|
r24225 | manifestmod._lazymanifest('wat') | ||
Augie Fackler
|
r24214 | self.fail('Should have raised ValueError') | ||
except ValueError, v: | ||||
self.assertIn('Manifest did not end in a newline.', str(v)) | ||||
def testHugeManifest(self): | ||||
Augie Fackler
|
r24225 | m = manifestmod._lazymanifest(A_HUGE_MANIFEST) | ||
Augie Fackler
|
r24214 | self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m)) | ||
self.assertEqual(len(m), len(list(m))) | ||||
Augie Fackler
|
r24225 | def testIntersectFiles(self): | ||
m = manifestmod.manifestdict(A_HUGE_MANIFEST) | ||||
m2 = m.intersectfiles(['file1', 'file200', 'file300']) | ||||
w = ('file1\0%sx\n' | ||||
'file200\0%sl\n' | ||||
'file300\0%s\n') % (HASH_2, HASH_1, HASH_1) | ||||
self.assertEqual(w, m2.text()) | ||||
Augie Fackler
|
r24214 | |||
if __name__ == '__main__': | ||||
silenttestrunner.main(__name__) | ||||