##// END OF EJS Templates
test-manifest.py: separate out test for double-free after copy()...
Martin von Zweigbergk -
r24465:bb8e2b1a default
parent child Browse files
Show More
@@ -1,232 +1,236 b''
1 1 import binascii
2 2 import unittest
3 3 import itertools
4 4
5 5 import silenttestrunner
6 6
7 7 from mercurial import manifest as manifestmod
8 8
9 9 HASH_1 = '1' * 40
10 10 HASH_2 = 'f' * 40
11 11 HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe'
12 12 A_SHORT_MANIFEST = (
13 13 'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
14 14 'foo\0%(hash1)s%(flag1)s\n'
15 15 ) % {'hash1': HASH_1,
16 16 'flag1': '',
17 17 'hash2': HASH_2,
18 18 'flag2': 'l',
19 19 }
20 20
21 21 HUGE_MANIFEST_ENTRIES = 200001
22 22
23 23 A_HUGE_MANIFEST = ''.join(sorted(
24 24 'file%d\0%s%s\n' % (i, h, f) for i, h, f in
25 25 itertools.izip(xrange(200001),
26 26 itertools.cycle((HASH_1, HASH_2)),
27 27 itertools.cycle(('', 'x', 'l')))))
28 28
29 29 class testmanifest(unittest.TestCase):
30 30
31 31 def assertIn(self, thing, container, msg=None):
32 32 # assertIn new in 2.7, use it if available, otherwise polyfill
33 33 sup = getattr(unittest.TestCase, 'assertIn', False)
34 34 if sup:
35 35 return sup(self, thing, container, msg=msg)
36 36 if not msg:
37 37 msg = 'Expected %r in %r' % (thing, container)
38 38 self.assert_(thing in container, msg)
39 39
40 40 def testEmptyManifest(self):
41 41 m = manifestmod._lazymanifest('')
42 42 self.assertEqual(0, len(m))
43 43 self.assertEqual([], list(m.iterentries()))
44 44
45 45 def testManifest(self):
46 46 m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
47 47 want = [
48 48 ('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'),
49 49 ('foo', binascii.unhexlify(HASH_1), ''),
50 50 ]
51 51 self.assertEqual(len(want), len(m))
52 52 self.assertEqual(want, list(m.iterentries()))
53 53 self.assertEqual((binascii.unhexlify(HASH_1), ''), m['foo'])
54 54 self.assertRaises(KeyError, lambda : m['wat'])
55 55 self.assertEqual((binascii.unhexlify(HASH_2), 'l'),
56 56 m['bar/baz/qux.py'])
57 57
58 58 def testSetItem(self):
59 59 want = binascii.unhexlify(HASH_1), ''
60 60
61 61 m = manifestmod._lazymanifest('')
62 62 m['a'] = want
63 63 self.assertIn('a', m)
64 64 self.assertEqual(want, m['a'])
65 65 self.assertEqual('a\0' + HASH_1 + '\n', m.text())
66 66
67 67 m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
68 68 m['a'] = want
69 69 self.assertEqual(want, m['a'])
70 70 self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
71 71 m.text())
72
73 def testCopy(self):
74 m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
75 m['a'] = binascii.unhexlify(HASH_1), ''
72 76 m2 = m.copy()
73 77 del m
74 78 del m2 # make sure we don't double free() anything
75 79
76 80 def testCompaction(self):
77 81 unhex = binascii.unhexlify
78 82 h1, h2 = unhex(HASH_1), unhex(HASH_2)
79 83 m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
80 84 m['alpha'] = h1, ''
81 85 m['beta'] = h2, ''
82 86 del m['foo']
83 87 want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
84 88 HASH_1, HASH_2, HASH_2)
85 89 self.assertEqual(want, m.text())
86 90 self.assertEqual(3, len(m))
87 91 self.assertEqual((h1, ''), m['alpha'])
88 92 self.assertEqual((h2, ''), m['beta'])
89 93 self.assertRaises(KeyError, lambda : m['foo'])
90 94 w = [('alpha', h1, ''), ('bar/baz/qux.py', h2, 'l'), ('beta', h2, '')]
91 95 self.assertEqual(w, list(m.iterentries()))
92 96
93 97 def testSetGetNodeSuffix(self):
94 98 clean = manifestmod._lazymanifest(A_SHORT_MANIFEST)
95 99 m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
96 100 h, f = m['foo']
97 101 want = h + 'a', f
98 102 # Merge code wants to set 21-byte fake hashes at times
99 103 m['foo'] = want
100 104 self.assertEqual(want, m['foo'])
101 105 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'),
102 106 ('foo', binascii.unhexlify(HASH_1) + 'a', '')],
103 107 list(m.iterentries()))
104 108 # Sometimes it even tries a 22-byte fake hash, but we can
105 109 # return 21 and it'll work out
106 110 m['foo'] = want[0] + '+', f
107 111 self.assertEqual(want, m['foo'])
108 112 # make sure the suffix survives a copy
109 113 m2 = m.filtercopy(lambda x: x == 'foo')
110 114 self.assertEqual(want, m2['foo'])
111 115 self.assertEqual(1, len(m2))
112 116 self.assertEqual(('foo\0%s\n' % HASH_1), m2.text())
113 117 m2 = m.copy()
114 118 self.assertEqual(want, m2['foo'])
115 119 # suffix with iteration
116 120 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'),
117 121 ('foo', want[0], '')], list(m.iterentries()))
118 122 # shows up in diff
119 123 self.assertEqual({'foo': (want, (h, ''))}, m.diff(clean))
120 124 self.assertEqual({'foo': ((h, ''), want)}, clean.diff(m))
121 125
122 126 def testFilterCopyException(self):
123 127 m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
124 128 def filt(path):
125 129 if path == 'foo':
126 130 assert False
127 131 return True
128 132 self.assertRaises(AssertionError, m.filtercopy, filt)
129 133
130 134 def testRemoveItem(self):
131 135 m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
132 136 del m['foo']
133 137 self.assertRaises(KeyError, lambda : m['foo'])
134 138 self.assertEqual(1, len(m))
135 139 self.assertEqual(1, len(list(m)))
136 140 # now restore and make sure everything works right
137 141 m['foo'] = 'a' * 20, ''
138 142 self.assertEqual(2, len(m))
139 143 self.assertEqual(2, len(list(m)))
140 144
141 145 def testManifestDiff(self):
142 146 MISSING = (None, '')
143 147 addl = 'z-only-in-left\0' + HASH_1 + '\n'
144 148 addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
145 149 left = manifestmod._lazymanifest(
146 150 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
147 151 right = manifestmod._lazymanifest(A_SHORT_MANIFEST + addr)
148 152 want = {
149 153 'foo': ((binascii.unhexlify(HASH_3), 'x'),
150 154 (binascii.unhexlify(HASH_1), '')),
151 155 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
152 156 'z-only-in-right': (MISSING, (binascii.unhexlify(HASH_2), 'x')),
153 157 }
154 158 self.assertEqual(want, left.diff(right))
155 159
156 160 want = {
157 161 'bar/baz/qux.py': (MISSING, (binascii.unhexlify(HASH_2), 'l')),
158 162 'foo': (MISSING, (binascii.unhexlify(HASH_3), 'x')),
159 163 'z-only-in-left': (MISSING, (binascii.unhexlify(HASH_1), '')),
160 164 }
161 165 self.assertEqual(want, manifestmod._lazymanifest('').diff(left))
162 166
163 167 want = {
164 168 'bar/baz/qux.py': ((binascii.unhexlify(HASH_2), 'l'), MISSING),
165 169 'foo': ((binascii.unhexlify(HASH_3), 'x'), MISSING),
166 170 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
167 171 }
168 172 self.assertEqual(want, left.diff(manifestmod._lazymanifest('')))
169 173 copy = right.copy()
170 174 del copy['z-only-in-right']
171 175 del right['foo']
172 176 want = {
173 177 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
174 178 'z-only-in-right': ((binascii.unhexlify(HASH_2), 'x'), MISSING),
175 179 }
176 180 self.assertEqual(want, right.diff(copy))
177 181
178 182 short = manifestmod._lazymanifest(A_SHORT_MANIFEST)
179 183 pruned = short.copy()
180 184 del pruned['foo']
181 185 want = {
182 186 'foo': ((binascii.unhexlify(HASH_1), ''), MISSING),
183 187 }
184 188 self.assertEqual(want, short.diff(pruned))
185 189 want = {
186 190 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
187 191 }
188 192 self.assertEqual(want, pruned.diff(short))
189 193 want = {
190 194 'bar/baz/qux.py': None,
191 195 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
192 196 }
193 197 self.assertEqual(want, pruned.diff(short, True))
194 198
195 199 def testReversedLines(self):
196 200 backwards = ''.join(
197 201 l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
198 202 try:
199 203 manifestmod._lazymanifest(backwards)
200 204 self.fail('Should have raised ValueError')
201 205 except ValueError, v:
202 206 self.assertIn('Manifest lines not in sorted order.', str(v))
203 207
204 208 def testNoTerminalNewline(self):
205 209 try:
206 210 manifestmod._lazymanifest(A_SHORT_MANIFEST + 'wat')
207 211 self.fail('Should have raised ValueError')
208 212 except ValueError, v:
209 213 self.assertIn('Manifest did not end in a newline.', str(v))
210 214
211 215 def testNoNewLineAtAll(self):
212 216 try:
213 217 manifestmod._lazymanifest('wat')
214 218 self.fail('Should have raised ValueError')
215 219 except ValueError, v:
216 220 self.assertIn('Manifest did not end in a newline.', str(v))
217 221
218 222 def testHugeManifest(self):
219 223 m = manifestmod._lazymanifest(A_HUGE_MANIFEST)
220 224 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m))
221 225 self.assertEqual(len(m), len(list(m)))
222 226
223 227 def testIntersectFiles(self):
224 228 m = manifestmod.manifestdict(A_HUGE_MANIFEST)
225 229 m2 = m.intersectfiles(['file1', 'file200', 'file300'])
226 230 w = ('file1\0%sx\n'
227 231 'file200\0%sl\n'
228 232 'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
229 233 self.assertEqual(w, m2.text())
230 234
231 235 if __name__ == '__main__':
232 236 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now